export "min_htlc" as part of channel details

This commit is contained in:
Carsten Otto
2023-09-10 14:47:31 +02:00
parent 2a8b782481
commit 5e61301e15
20 changed files with 73 additions and 45 deletions

View File

@@ -19,6 +19,7 @@ import java.util.stream.Collectors;
@Component
public class RouteHintService {
private static final Coins ONE_MILLI_SATOSHI = Coins.ofMilliSatoshis(1);
private static final Coins FIFTY_COINS = Coins.ofSatoshis(5_000_000_000L);
private static final Duration MAX_AGE = Duration.ofHours(1);
@@ -55,7 +56,14 @@ public class RouteHintService {
}
private Policy toPolicy(RouteHint routeHint) {
return new Policy(routeHint.feeRate(), routeHint.baseFee(), true, routeHint.cltvExpiryDelta(), FIFTY_COINS);
return new Policy(
routeHint.feeRate(),
routeHint.baseFee(),
true,
routeHint.cltvExpiryDelta(),
ONE_MILLI_SATOSHI,
FIFTY_COINS
);
}
@SuppressWarnings("UnusedVariable")

View File

@@ -77,7 +77,7 @@ class GraphServiceTest {
@Test
void getNodesWithHighFeeRate_ignores_disabled_channels() {
Set<DirectedChannelEdge> edges = edges(9, 200, PUBKEY_2);
Policy policy = new Policy(2_000, Coins.NONE, false, 40, Coins.ofSatoshis(10_000));
Policy policy = new Policy(2_000, Coins.NONE, false, 40, Coins.ofMilliSatoshis(1), Coins.ofSatoshis(10_000));
edges.add(edge(policy, Coins.ofSatoshis(10_000_000), PUBKEY_2));
assertThat(graphService.getNodesWithHighFeeRate()).isEmpty();
}
@@ -135,7 +135,7 @@ class GraphServiceTest {
}
private DirectedChannelEdge edge(long feeRate, long capacityMillionSat, Pubkey target) {
Policy policy = new Policy(feeRate, Coins.NONE, true, 40, Coins.ofSatoshis(10_000));
Policy policy = new Policy(feeRate, Coins.NONE, true, 40, Coins.ofMilliSatoshis(1), Coins.ofSatoshis(10_000));
Coins capacity = Coins.ofSatoshis(capacityMillionSat * 1_000_000);
return edge(policy, capacity, target);
}

View File

@@ -108,8 +108,9 @@ class PolicyServiceTest {
}
private void mockPolicy(ChannelId channelId, int feeRate) {
Policy policy = new Policy(feeRate, Coins.NONE, false, 0, Coins.NONE, Coins.NONE);
when(grpcChannelPolicy.getPolicyFrom(channelId, PUBKEY))
.thenReturn(Optional.of(new Policy(feeRate, Coins.NONE, false, 0, Coins.NONE)));
.thenReturn(Optional.of(policy));
}
}
@@ -137,8 +138,9 @@ class PolicyServiceTest {
}
private void mockPolicy(ChannelId channelId, int feeRate) {
Policy policy = new Policy(feeRate, Coins.NONE, false, 0, Coins.NONE, Coins.NONE);
when(grpcChannelPolicy.getPolicyTo(channelId, PUBKEY))
.thenReturn(Optional.of(new Policy(feeRate, Coins.NONE, false, 0, Coins.NONE)));
.thenReturn(Optional.of(policy));
}
}
}

View File

@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThatCode;
@ExtendWith(MockitoExtension.class)
class RouteHintServiceTest {
private static final Coins ONE_MILLI_SATOSHI = Coins.ofMilliSatoshis(1);
private static final Coins FIFTY_COINS = Coins.ofSatoshis(5_000_000_000L);
@InjectMocks
@@ -36,8 +37,8 @@ class RouteHintServiceTest {
@Test
void get_after_adding_decoded_payment_request() {
routeHintService.addDecodedPaymentRequest(DECODED_PAYMENT_REQUEST);
Policy policy1 = new Policy(123, Coins.NONE, true, 9, FIFTY_COINS);
Policy policy2 = new Policy(1234, Coins.ofMilliSatoshis(1), true, 40, FIFTY_COINS);
Policy policy1 = new Policy(123, Coins.NONE, true, 9, ONE_MILLI_SATOSHI, FIFTY_COINS);
Policy policy2 = new Policy(1234, ONE_MILLI_SATOSHI, true, 40, ONE_MILLI_SATOSHI, FIFTY_COINS);
DirectedChannelEdge edge1 = new DirectedChannelEdge(CHANNEL_ID, FIFTY_COINS, PUBKEY, PUBKEY_4, policy1);
DirectedChannelEdge edge2 = new DirectedChannelEdge(CHANNEL_ID_2, FIFTY_COINS, PUBKEY_3, PUBKEY_4, policy2);
assertThat(routeHintService.getEdgesFromPaymentHints()).contains(edge1, edge2);

View File

@@ -18,7 +18,7 @@ import java.util.Set;
@Component
public class GrpcGraph {
private static final Policy DEFAULT_DISABLED_POLICY = new Policy(0, Coins.NONE, false, 0, Coins.NONE);
private static final Policy DEFAULT_DISABLED_POLICY = new Policy(0, Coins.NONE, false, 0, Coins.NONE, Coins.NONE);
private final GrpcService grpcService;
private final LoadingCache<Object, Optional<Set<DirectedChannelEdge>>> channelEdgeCache;
private final GrpcPolicy grpcPolicy;

View File

@@ -17,6 +17,7 @@ public class GrpcPolicy {
Coins.ofMilliSatoshis(routingPolicy.getFeeBaseMsat()),
!routingPolicy.getDisabled(),
routingPolicy.getTimeLockDelta(),
Coins.ofMilliSatoshis(routingPolicy.getMinHtlc()),
Coins.ofMilliSatoshis(routingPolicy.getMaxHtlcMsat())
);
}

View File

@@ -29,6 +29,7 @@ class GrpcChannelPolicyTest {
private static final int FEE_RATE_FIRST = 123;
private static final int FEE_RATE_SECOND = 456;
private static final int TIME_LOCK_DELTA = 40;
private static final Coins MIN_HTLC = Coins.ofMilliSatoshis(159);
private static final Coins MAX_HTLC = Coins.ofMilliSatoshis(5_432);
@InjectMocks
@@ -53,14 +54,14 @@ class GrpcChannelPolicyTest {
void getLocalPolicy_local_first() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY, PUBKEY_2)));
assertThat(grpcChannelPolicy.getLocalPolicy(CHANNEL_ID))
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
void getLocalPolicy_local_second() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY)));
assertThat(grpcChannelPolicy.getLocalPolicy(CHANNEL_ID))
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
@@ -78,14 +79,14 @@ class GrpcChannelPolicyTest {
void getRemotePolicy_local_first() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY, PUBKEY_2)));
assertThat(grpcChannelPolicy.getRemotePolicy(CHANNEL_ID))
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
void getRemotePolicy_local_second() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY)));
assertThat(grpcChannelPolicy.getRemotePolicy(CHANNEL_ID))
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
@@ -98,14 +99,14 @@ class GrpcChannelPolicyTest {
void getPolicyFrom_first() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
assertThat(grpcChannelPolicy.getPolicyFrom(CHANNEL_ID, PUBKEY_2))
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
void getPolicyFrom_second() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
assertThat(grpcChannelPolicy.getPolicyFrom(CHANNEL_ID, PUBKEY_3))
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
@@ -118,14 +119,14 @@ class GrpcChannelPolicyTest {
void getPolicyTo_first() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
assertThat(grpcChannelPolicy.getPolicyTo(CHANNEL_ID, PUBKEY_3))
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_FIRST, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
void getPolicyTo_second() {
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
assertThat(grpcChannelPolicy.getPolicyTo(CHANNEL_ID, PUBKEY_2))
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MAX_HTLC));
.contains(new Policy(FEE_RATE_SECOND, Coins.NONE, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC));
}
@Test
@@ -175,7 +176,8 @@ class GrpcChannelPolicyTest {
return RoutingPolicy.newBuilder()
.setFeeRateMilliMsat(feeRate)
.setTimeLockDelta(TIME_LOCK_DELTA)
.setMaxHtlcMsat(5_432)
.setMinHtlc(MIN_HTLC.milliSatoshis())
.setMaxHtlcMsat(MAX_HTLC.milliSatoshis())
.build();
}
}

View File

@@ -33,6 +33,7 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class GrpcGraphTest {
private static final Coins MIN_HTLC = Coins.ofMilliSatoshis(159);
private static final Coins MAX_HTLC = Coins.ofMilliSatoshis(5_432);
@InjectMocks
private GrpcGraph grpcGraph;
@@ -76,14 +77,14 @@ class GrpcGraphTest {
CAPACITY,
PUBKEY,
PUBKEY_2,
new Policy(0, Coins.NONE, false, 40, MAX_HTLC)
new Policy(0, Coins.NONE, false, 40, MIN_HTLC, MAX_HTLC)
);
DirectedChannelEdge expectedEdge2 = new DirectedChannelEdge(
CHANNEL_ID,
CAPACITY,
PUBKEY_2,
PUBKEY,
new Policy(1, Coins.NONE, true, 144, MAX_HTLC)
new Policy(1, Coins.NONE, true, 144, MIN_HTLC, MAX_HTLC)
);
ChannelEdge edge2 = ChannelEdge.newBuilder()
.setChannelId(CHANNEL_ID_2.getShortChannelId())
@@ -98,14 +99,14 @@ class GrpcGraphTest {
CAPACITY_2,
PUBKEY_3,
PUBKEY_4,
new Policy(456, Coins.NONE, true, 123, MAX_HTLC)
new Policy(456, Coins.NONE, true, 123, MIN_HTLC, MAX_HTLC)
);
DirectedChannelEdge expectedEdge4 = new DirectedChannelEdge(
CHANNEL_ID_2,
CAPACITY_2,
PUBKEY_4,
PUBKEY_3,
new Policy(123, Coins.ofMilliSatoshis(1), true, 456, MAX_HTLC)
new Policy(123, Coins.ofMilliSatoshis(1), true, 456, MIN_HTLC, MAX_HTLC)
);
ChannelGraph channelGraph = ChannelGraph.newBuilder()
.addEdges(edge1)
@@ -130,14 +131,14 @@ class GrpcGraphTest {
CAPACITY,
PUBKEY,
PUBKEY_2,
new Policy(0, Coins.NONE, false, 0, Coins.NONE)
new Policy(0, Coins.NONE, false, 0, Coins.NONE, Coins.NONE)
);
DirectedChannelEdge expectedPolicyForNode2 = new DirectedChannelEdge(
CHANNEL_ID,
CAPACITY,
PUBKEY_2,
PUBKEY,
new Policy(0, Coins.NONE, false, 0, Coins.NONE)
new Policy(0, Coins.NONE, false, 0, Coins.NONE, Coins.NONE)
);
ChannelGraph channelGraph = ChannelGraph.newBuilder().addEdges(edgeWithMissingPolicy).build();
when(grpcService.describeGraph()).thenReturn(Optional.of(channelGraph));
@@ -160,7 +161,8 @@ class GrpcGraphTest {
.setFeeBaseMsat(baseFee)
.setDisabled(disabled)
.setTimeLockDelta(timeLockDelta)
.setMaxHtlcMsat(5_432)
.setMinHtlc(MIN_HTLC.milliSatoshis())
.setMaxHtlcMsat(MAX_HTLC.milliSatoshis())
.build();
}
}

View File

@@ -1,7 +1,7 @@
package de.cotto.lndmanagej.model;
public record Policy(long feeRate, Coins baseFee, boolean enabled, int timeLockDelta, Coins maxHtlc) {
public static final Policy UNKNOWN = new Policy(0, Coins.NONE, false, 0, Coins.NONE);
public record Policy(long feeRate, Coins baseFee, boolean enabled, int timeLockDelta, Coins minHtlc, Coins maxHtlc) {
public static final Policy UNKNOWN = new Policy(0, Coins.NONE, false, 0, Coins.NONE, Coins.NONE);
public boolean disabled() {
return !enabled;

View File

@@ -30,6 +30,11 @@ class PolicyTest {
assertThat(POLICY_DISABLED.disabled()).isTrue();
}
@Test
void minHtlc() {
assertThat(POLICY_1.minHtlc()).isEqualTo(Coins.ofSatoshis(159));
}
@Test
void maxHtlc() {
assertThat(POLICY_1.maxHtlc()).isEqualTo(Coins.ofSatoshis(10_000));
@@ -37,6 +42,6 @@ class PolicyTest {
@Test
void unknown() {
assertThat(Policy.UNKNOWN).isEqualTo(new Policy(0, Coins.NONE, false, 0, Coins.NONE));
assertThat(Policy.UNKNOWN).isEqualTo(new Policy(0, Coins.NONE, false, 0, Coins.NONE, Coins.NONE));
}
}

View File

@@ -29,6 +29,7 @@ class RouteTest {
private static final int ONE_MILLION = 1_000_000;
private static final int TIME_LOCK_DELTA = 40;
private static final int BLOCK_HEIGHT = 700_000;
private static final Coins MIN_HTLC = Coins.ofSatoshis(159);
private static final Coins MAX_HTLC = Coins.ofSatoshis(12_345);
@Test
@@ -495,12 +496,12 @@ class RouteTest {
private List<Edge> edgesWithTimeLockDeltas(int... timeLockDeltas) {
return Arrays.stream(timeLockDeltas)
.mapToObj(timeLockDelta -> new Policy(0, Coins.NONE, true, timeLockDelta, MAX_HTLC))
.mapToObj(timeLockDelta -> new Policy(0, Coins.NONE, true, timeLockDelta, MIN_HTLC, MAX_HTLC))
.map(policy -> new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policy))
.toList();
}
private Policy policy(Coins baseFee, int ppm) {
return new Policy(ppm, baseFee, true, TIME_LOCK_DELTA, MAX_HTLC);
return new Policy(ppm, baseFee, true, TIME_LOCK_DELTA, MIN_HTLC, MAX_HTLC);
}
}

View File

@@ -2,13 +2,13 @@ package de.cotto.lndmanagej.model;
public class PolicyFixtures {
public static final Policy POLICY_1 =
new Policy(200, Coins.NONE, true, 40, Coins.ofSatoshis(10_000));
new Policy(200, Coins.NONE, true, 40, Coins.ofSatoshis(159), Coins.ofSatoshis(10_000));
public static final Policy POLICY_WITH_BASE_FEE =
new Policy(200, Coins.ofMilliSatoshis(10), true, 40, Coins.ofSatoshis(10_000));
new Policy(200, Coins.ofMilliSatoshis(10), true, 40, Coins.ofSatoshis(159), Coins.ofSatoshis(10_000));
public static final Policy POLICY_DISABLED =
new Policy(200, Coins.NONE, false, 40, Coins.ofSatoshis(0));
new Policy(200, Coins.NONE, false, 40, Coins.NONE, Coins.NONE);
public static final Policy POLICY_2 =
new Policy(300, Coins.ofMilliSatoshis(0), true, 144, Coins.ofSatoshis(22_222));
new Policy(300, Coins.ofMilliSatoshis(0), true, 144, Coins.ofSatoshis(159), Coins.ofSatoshis(22_222));
public static final PoliciesForLocalChannel POLICIES_FOR_LOCAL_CHANNEL =
new PoliciesForLocalChannel(POLICY_DISABLED, POLICY_2);

View File

@@ -324,7 +324,7 @@ class ArcInitializerTest {
ArcInitializer arcInitializer = getArcInitializer(quantization, feeRateWeight);
addEdgeWithBaseFee(baseFee, quantization, arcInitializer);
long expectedFeeRate = (long) Math.ceil(200 + 10);
long expectedFeeRate = 210;
assertThat(minCostFlow.getUnitCost(0)).isEqualTo(expectedFeeRate);
}
@@ -337,12 +337,12 @@ class ArcInitializerTest {
ArcInitializer arcInitializer = getArcInitializer(quantization, feeRateWeight);
addEdgeWithBaseFee(baseFee, quantization, arcInitializer);
long expectedFeeRate = (long) Math.ceil(200 + 12);
long expectedFeeRate = 212;
assertThat(minCostFlow.getUnitCost(0)).isEqualTo(expectedFeeRate);
}
private void addEdgeWithBaseFee(Coins baseFee, int quantization, ArcInitializer arcInitializer) {
Policy policy = new Policy(200, baseFee, true, 40, Coins.ofSatoshis(10_000));
Policy policy = new Policy(200, baseFee, true, 40, Coins.ofMilliSatoshis(1), Coins.ofSatoshis(10_000));
EdgeWithLiquidityInformation edge = EdgeWithLiquidityInformation.forKnownLiquidity(
new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policy),
Coins.ofSatoshis(30L * quantization)

View File

@@ -117,7 +117,7 @@ class EdgeComputationTest {
void does_not_add_edge_exceeding_maximum_time_lock_delta() {
int edgeDelta = 40;
int maximumTimeLockDelta = edgeDelta - 1;
Policy policy = new Policy(0, Coins.NONE, true, edgeDelta, Coins.ofSatoshis(10_000));
Policy policy = new Policy(0, Coins.NONE, true, edgeDelta, Coins.ofMilliSatoshis(1), Coins.ofSatoshis(10_000));
DirectedChannelEdge edge = new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, policy);
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge)));
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS, maximumTimeLockDelta).edges()).isEmpty();
@@ -228,8 +228,9 @@ class EdgeComputationTest {
@Test
void adds_edge_from_route_hint_service() {
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of()));
Coins oneMilliSatoshi = Coins.ofMilliSatoshis(1);
Coins fiftyCoins = Coins.ofSatoshis(5_000_000_000L);
Policy policy = new Policy(200, Coins.NONE, true, 40, fiftyCoins);
Policy policy = new Policy(200, Coins.NONE, true, 40, oneMilliSatoshi, fiftyCoins);
Edge edge = new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, fiftyCoins, policy);
when(routeHintService.getEdgesFromPaymentHints()).thenReturn(Set.of(
new DirectedChannelEdge(
@@ -447,7 +448,7 @@ class EdgeComputationTest {
}
private static Policy policy(int feeRate) {
return new Policy(feeRate, Coins.NONE, true, 40, Coins.ofSatoshis(0));
return new Policy(feeRate, Coins.NONE, true, 40, Coins.NONE, Coins.NONE);
}
private void mockInactiveChannel() {

View File

@@ -626,7 +626,7 @@ class MultiPathPaymentSplitterTest {
private Edge mockExtensionEdge(Pubkey destination, int feeRate) {
Policy policyExtension =
new Policy(feeRate, Coins.NONE, true, 40, Coins.ofSatoshis(10_000));
new Policy(feeRate, Coins.NONE, true, 40, Coins.ofMilliSatoshis(1), Coins.ofSatoshis(10_000));
when(channelService.getOpenChannelsWith(PUBKEY_2)).thenReturn(Set.of(LOCAL_OPEN_CHANNEL));
when(policyService.getPolicyFrom(CHANNEL_ID, PUBKEY_2)).thenReturn(Optional.of(policyExtension));
Edge extensionEdge =
@@ -637,7 +637,7 @@ class MultiPathPaymentSplitterTest {
}
private static Policy policyFor(int feeRate) {
return new Policy(feeRate, Coins.NONE, true, 40, Coins.ofSatoshis(10_000));
return new Policy(feeRate, Coins.NONE, true, 40, Coins.ofMilliSatoshis(1), Coins.ofSatoshis(10_000));
}
private EdgeWithLiquidityInformation noInformationFor(Edge edgeSmallCapacity) {

View File

@@ -25,6 +25,7 @@ import static de.cotto.lndmanagej.model.OpenInitiator.REMOTE;
@SuppressWarnings("PMD.TooManyMethods")
public final class DeriveDataUtil {
private static final Coins MIN_HTLC = Coins.ofMilliSatoshis(1);
private static final Coins MAX_HTLC = Coins.ofSatoshis(1_000_000);
private DeriveDataUtil() {
@@ -98,7 +99,7 @@ public final class DeriveDataUtil {
Coins baseFee = Coins.ofMilliSatoshis(rand.nextLong(2) * 1000);
boolean enabled = rand.nextInt(10) != 0;
int timeLockDelta = (rand.nextInt(5) + 1) * 10;
return new Policy(feeRate, baseFee, enabled, timeLockDelta, MAX_HTLC);
return new Policy(feeRate, baseFee, enabled, timeLockDelta, MIN_HTLC, MAX_HTLC);
}
static ChannelStatusDto deriveChannelStatus(ChannelId channelId) {

View File

@@ -397,7 +397,7 @@ class PageServiceTest {
}
private static PolicyDto policy(int feeRate, int baseFee) {
return new PolicyDto(feeRate, String.valueOf(baseFee), true, 0, "0");
return new PolicyDto(feeRate, String.valueOf(baseFee), true, 0, "0", "0");
}
private BalanceInformation balanceWithRemoteSat(int satoshis) {

View File

@@ -170,11 +170,13 @@ class ChannelControllerIT {
.jsonPath("$.policies.local.feeRatePpm").value(is(200))
.jsonPath("$.policies.local.baseFeeMilliSat").value(is("0"))
.jsonPath("$.policies.local.timeLockDelta").value(is(40))
.jsonPath("$.policies.local.minHtlcMilliSat").value(is("0"))
.jsonPath("$.policies.local.maxHtlcMilliSat").value(is("0"))
.jsonPath("$.policies.remote.enabled").value(is(true))
.jsonPath("$.policies.remote.feeRatePpm").value(is(300))
.jsonPath("$.policies.remote.baseFeeMilliSat").value(is("0"))
.jsonPath("$.policies.remote.timeLockDelta").value(is(144))
.jsonPath("$.policies.remote.minHtlcMilliSat").value(is("159000"))
.jsonPath("$.policies.remote.maxHtlcMilliSat").value(is("22222000"))
.jsonPath("$.feeReport.earnedMilliSat").value(is("1234"))
.jsonPath("$.feeReport.sourcedMilliSat").value(is("567"))

View File

@@ -7,6 +7,7 @@ public record PolicyDto(
String baseFeeMilliSat,
boolean enabled,
int timeLockDelta,
String minHtlcMilliSat,
String maxHtlcMilliSat
) {
public static PolicyDto createFromModel(Policy policy) {
@@ -15,6 +16,7 @@ public record PolicyDto(
String.valueOf(policy.baseFee().milliSatoshis()),
policy.enabled(),
policy.timeLockDelta(),
String.valueOf(policy.minHtlc().milliSatoshis()),
String.valueOf(policy.maxHtlc().milliSatoshis())
);
}

View File

@@ -9,14 +9,14 @@ import static org.assertj.core.api.Assertions.assertThat;
class PolicyDtoTest {
@Test
void createFromModel_disabled() {
PolicyDto expected = new PolicyDto(200, "0", false, 40, "0");
PolicyDto expected = new PolicyDto(200, "0", false, 40, "0", "0");
PolicyDto dto = PolicyDto.createFromModel(POLICY_DISABLED);
assertThat(dto).isEqualTo(expected);
}
@Test
void createFromModel_with_base_fee() {
PolicyDto expected = new PolicyDto(200, "10", true, 40, "10000000");
PolicyDto expected = new PolicyDto(200, "10", true, 40, "159000", "10000000");
PolicyDto dto = PolicyDto.createFromModel(POLICY_WITH_BASE_FEE);
assertThat(dto).isEqualTo(expected);
}