mirror of
https://github.com/aljazceru/lnd-manageJ.git
synced 2025-12-17 14:14:24 +01:00
export "min_htlc" as part of channel details
This commit is contained in:
@@ -19,6 +19,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class RouteHintService {
|
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 Coins FIFTY_COINS = Coins.ofSatoshis(5_000_000_000L);
|
||||||
|
|
||||||
private static final Duration MAX_AGE = Duration.ofHours(1);
|
private static final Duration MAX_AGE = Duration.ofHours(1);
|
||||||
@@ -55,7 +56,14 @@ public class RouteHintService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Policy toPolicy(RouteHint routeHint) {
|
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")
|
@SuppressWarnings("UnusedVariable")
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class GraphServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
void getNodesWithHighFeeRate_ignores_disabled_channels() {
|
void getNodesWithHighFeeRate_ignores_disabled_channels() {
|
||||||
Set<DirectedChannelEdge> edges = edges(9, 200, PUBKEY_2);
|
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));
|
edges.add(edge(policy, Coins.ofSatoshis(10_000_000), PUBKEY_2));
|
||||||
assertThat(graphService.getNodesWithHighFeeRate()).isEmpty();
|
assertThat(graphService.getNodesWithHighFeeRate()).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ class GraphServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DirectedChannelEdge edge(long feeRate, long capacityMillionSat, Pubkey target) {
|
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);
|
Coins capacity = Coins.ofSatoshis(capacityMillionSat * 1_000_000);
|
||||||
return edge(policy, capacity, target);
|
return edge(policy, capacity, target);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,8 +108,9 @@ class PolicyServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void mockPolicy(ChannelId channelId, int feeRate) {
|
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))
|
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) {
|
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))
|
when(grpcChannelPolicy.getPolicyTo(channelId, PUBKEY))
|
||||||
.thenReturn(Optional.of(new Policy(feeRate, Coins.NONE, false, 0, Coins.NONE)));
|
.thenReturn(Optional.of(policy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThatCode;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class RouteHintServiceTest {
|
class RouteHintServiceTest {
|
||||||
|
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 Coins FIFTY_COINS = Coins.ofSatoshis(5_000_000_000L);
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
@@ -36,8 +37,8 @@ class RouteHintServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
void get_after_adding_decoded_payment_request() {
|
void get_after_adding_decoded_payment_request() {
|
||||||
routeHintService.addDecodedPaymentRequest(DECODED_PAYMENT_REQUEST);
|
routeHintService.addDecodedPaymentRequest(DECODED_PAYMENT_REQUEST);
|
||||||
Policy policy1 = new Policy(123, Coins.NONE, true, 9, FIFTY_COINS);
|
Policy policy1 = new Policy(123, Coins.NONE, true, 9, ONE_MILLI_SATOSHI, FIFTY_COINS);
|
||||||
Policy policy2 = new Policy(1234, Coins.ofMilliSatoshis(1), true, 40, 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 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);
|
DirectedChannelEdge edge2 = new DirectedChannelEdge(CHANNEL_ID_2, FIFTY_COINS, PUBKEY_3, PUBKEY_4, policy2);
|
||||||
assertThat(routeHintService.getEdgesFromPaymentHints()).contains(edge1, edge2);
|
assertThat(routeHintService.getEdgesFromPaymentHints()).contains(edge1, edge2);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class GrpcGraph {
|
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 GrpcService grpcService;
|
||||||
private final LoadingCache<Object, Optional<Set<DirectedChannelEdge>>> channelEdgeCache;
|
private final LoadingCache<Object, Optional<Set<DirectedChannelEdge>>> channelEdgeCache;
|
||||||
private final GrpcPolicy grpcPolicy;
|
private final GrpcPolicy grpcPolicy;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ public class GrpcPolicy {
|
|||||||
Coins.ofMilliSatoshis(routingPolicy.getFeeBaseMsat()),
|
Coins.ofMilliSatoshis(routingPolicy.getFeeBaseMsat()),
|
||||||
!routingPolicy.getDisabled(),
|
!routingPolicy.getDisabled(),
|
||||||
routingPolicy.getTimeLockDelta(),
|
routingPolicy.getTimeLockDelta(),
|
||||||
|
Coins.ofMilliSatoshis(routingPolicy.getMinHtlc()),
|
||||||
Coins.ofMilliSatoshis(routingPolicy.getMaxHtlcMsat())
|
Coins.ofMilliSatoshis(routingPolicy.getMaxHtlcMsat())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class GrpcChannelPolicyTest {
|
|||||||
private static final int FEE_RATE_FIRST = 123;
|
private static final int FEE_RATE_FIRST = 123;
|
||||||
private static final int FEE_RATE_SECOND = 456;
|
private static final int FEE_RATE_SECOND = 456;
|
||||||
private static final int TIME_LOCK_DELTA = 40;
|
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);
|
private static final Coins MAX_HTLC = Coins.ofMilliSatoshis(5_432);
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
@@ -53,14 +54,14 @@ class GrpcChannelPolicyTest {
|
|||||||
void getLocalPolicy_local_first() {
|
void getLocalPolicy_local_first() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY, PUBKEY_2)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY, PUBKEY_2)));
|
||||||
assertThat(grpcChannelPolicy.getLocalPolicy(CHANNEL_ID))
|
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
|
@Test
|
||||||
void getLocalPolicy_local_second() {
|
void getLocalPolicy_local_second() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY)));
|
||||||
assertThat(grpcChannelPolicy.getLocalPolicy(CHANNEL_ID))
|
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
|
@Test
|
||||||
@@ -78,14 +79,14 @@ class GrpcChannelPolicyTest {
|
|||||||
void getRemotePolicy_local_first() {
|
void getRemotePolicy_local_first() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY, PUBKEY_2)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY, PUBKEY_2)));
|
||||||
assertThat(grpcChannelPolicy.getRemotePolicy(CHANNEL_ID))
|
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
|
@Test
|
||||||
void getRemotePolicy_local_second() {
|
void getRemotePolicy_local_second() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY)));
|
||||||
assertThat(grpcChannelPolicy.getRemotePolicy(CHANNEL_ID))
|
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
|
@Test
|
||||||
@@ -98,14 +99,14 @@ class GrpcChannelPolicyTest {
|
|||||||
void getPolicyFrom_first() {
|
void getPolicyFrom_first() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
||||||
assertThat(grpcChannelPolicy.getPolicyFrom(CHANNEL_ID, PUBKEY_2))
|
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
|
@Test
|
||||||
void getPolicyFrom_second() {
|
void getPolicyFrom_second() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
||||||
assertThat(grpcChannelPolicy.getPolicyFrom(CHANNEL_ID, 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
|
@Test
|
||||||
@@ -118,14 +119,14 @@ class GrpcChannelPolicyTest {
|
|||||||
void getPolicyTo_first() {
|
void getPolicyTo_first() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
||||||
assertThat(grpcChannelPolicy.getPolicyTo(CHANNEL_ID, 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
|
@Test
|
||||||
void getPolicyTo_second() {
|
void getPolicyTo_second() {
|
||||||
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
when(grpcService.getChannelEdge(CHANNEL_ID)).thenReturn(Optional.of(channelEdge(PUBKEY_2, PUBKEY_3)));
|
||||||
assertThat(grpcChannelPolicy.getPolicyTo(CHANNEL_ID, PUBKEY_2))
|
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
|
@Test
|
||||||
@@ -175,7 +176,8 @@ class GrpcChannelPolicyTest {
|
|||||||
return RoutingPolicy.newBuilder()
|
return RoutingPolicy.newBuilder()
|
||||||
.setFeeRateMilliMsat(feeRate)
|
.setFeeRateMilliMsat(feeRate)
|
||||||
.setTimeLockDelta(TIME_LOCK_DELTA)
|
.setTimeLockDelta(TIME_LOCK_DELTA)
|
||||||
.setMaxHtlcMsat(5_432)
|
.setMinHtlc(MIN_HTLC.milliSatoshis())
|
||||||
|
.setMaxHtlcMsat(MAX_HTLC.milliSatoshis())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class GrpcGraphTest {
|
class GrpcGraphTest {
|
||||||
|
private static final Coins MIN_HTLC = Coins.ofMilliSatoshis(159);
|
||||||
private static final Coins MAX_HTLC = Coins.ofMilliSatoshis(5_432);
|
private static final Coins MAX_HTLC = Coins.ofMilliSatoshis(5_432);
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private GrpcGraph grpcGraph;
|
private GrpcGraph grpcGraph;
|
||||||
@@ -76,14 +77,14 @@ class GrpcGraphTest {
|
|||||||
CAPACITY,
|
CAPACITY,
|
||||||
PUBKEY,
|
PUBKEY,
|
||||||
PUBKEY_2,
|
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(
|
DirectedChannelEdge expectedEdge2 = new DirectedChannelEdge(
|
||||||
CHANNEL_ID,
|
CHANNEL_ID,
|
||||||
CAPACITY,
|
CAPACITY,
|
||||||
PUBKEY_2,
|
PUBKEY_2,
|
||||||
PUBKEY,
|
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()
|
ChannelEdge edge2 = ChannelEdge.newBuilder()
|
||||||
.setChannelId(CHANNEL_ID_2.getShortChannelId())
|
.setChannelId(CHANNEL_ID_2.getShortChannelId())
|
||||||
@@ -98,14 +99,14 @@ class GrpcGraphTest {
|
|||||||
CAPACITY_2,
|
CAPACITY_2,
|
||||||
PUBKEY_3,
|
PUBKEY_3,
|
||||||
PUBKEY_4,
|
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(
|
DirectedChannelEdge expectedEdge4 = new DirectedChannelEdge(
|
||||||
CHANNEL_ID_2,
|
CHANNEL_ID_2,
|
||||||
CAPACITY_2,
|
CAPACITY_2,
|
||||||
PUBKEY_4,
|
PUBKEY_4,
|
||||||
PUBKEY_3,
|
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()
|
ChannelGraph channelGraph = ChannelGraph.newBuilder()
|
||||||
.addEdges(edge1)
|
.addEdges(edge1)
|
||||||
@@ -130,14 +131,14 @@ class GrpcGraphTest {
|
|||||||
CAPACITY,
|
CAPACITY,
|
||||||
PUBKEY,
|
PUBKEY,
|
||||||
PUBKEY_2,
|
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(
|
DirectedChannelEdge expectedPolicyForNode2 = new DirectedChannelEdge(
|
||||||
CHANNEL_ID,
|
CHANNEL_ID,
|
||||||
CAPACITY,
|
CAPACITY,
|
||||||
PUBKEY_2,
|
PUBKEY_2,
|
||||||
PUBKEY,
|
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();
|
ChannelGraph channelGraph = ChannelGraph.newBuilder().addEdges(edgeWithMissingPolicy).build();
|
||||||
when(grpcService.describeGraph()).thenReturn(Optional.of(channelGraph));
|
when(grpcService.describeGraph()).thenReturn(Optional.of(channelGraph));
|
||||||
@@ -160,7 +161,8 @@ class GrpcGraphTest {
|
|||||||
.setFeeBaseMsat(baseFee)
|
.setFeeBaseMsat(baseFee)
|
||||||
.setDisabled(disabled)
|
.setDisabled(disabled)
|
||||||
.setTimeLockDelta(timeLockDelta)
|
.setTimeLockDelta(timeLockDelta)
|
||||||
.setMaxHtlcMsat(5_432)
|
.setMinHtlc(MIN_HTLC.milliSatoshis())
|
||||||
|
.setMaxHtlcMsat(MAX_HTLC.milliSatoshis())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package de.cotto.lndmanagej.model;
|
package de.cotto.lndmanagej.model;
|
||||||
|
|
||||||
public record Policy(long feeRate, Coins baseFee, boolean enabled, int timeLockDelta, Coins maxHtlc) {
|
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);
|
public static final Policy UNKNOWN = new Policy(0, Coins.NONE, false, 0, Coins.NONE, Coins.NONE);
|
||||||
|
|
||||||
public boolean disabled() {
|
public boolean disabled() {
|
||||||
return !enabled;
|
return !enabled;
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ class PolicyTest {
|
|||||||
assertThat(POLICY_DISABLED.disabled()).isTrue();
|
assertThat(POLICY_DISABLED.disabled()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void minHtlc() {
|
||||||
|
assertThat(POLICY_1.minHtlc()).isEqualTo(Coins.ofSatoshis(159));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void maxHtlc() {
|
void maxHtlc() {
|
||||||
assertThat(POLICY_1.maxHtlc()).isEqualTo(Coins.ofSatoshis(10_000));
|
assertThat(POLICY_1.maxHtlc()).isEqualTo(Coins.ofSatoshis(10_000));
|
||||||
@@ -37,6 +42,6 @@ class PolicyTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void unknown() {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class RouteTest {
|
|||||||
private static final int ONE_MILLION = 1_000_000;
|
private static final int ONE_MILLION = 1_000_000;
|
||||||
private static final int TIME_LOCK_DELTA = 40;
|
private static final int TIME_LOCK_DELTA = 40;
|
||||||
private static final int BLOCK_HEIGHT = 700_000;
|
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);
|
private static final Coins MAX_HTLC = Coins.ofSatoshis(12_345);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -495,12 +496,12 @@ class RouteTest {
|
|||||||
|
|
||||||
private List<Edge> edgesWithTimeLockDeltas(int... timeLockDeltas) {
|
private List<Edge> edgesWithTimeLockDeltas(int... timeLockDeltas) {
|
||||||
return Arrays.stream(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))
|
.map(policy -> new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policy))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Policy policy(Coins baseFee, int ppm) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package de.cotto.lndmanagej.model;
|
|||||||
|
|
||||||
public class PolicyFixtures {
|
public class PolicyFixtures {
|
||||||
public static final Policy POLICY_1 =
|
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 =
|
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 =
|
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 =
|
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 =
|
public static final PoliciesForLocalChannel POLICIES_FOR_LOCAL_CHANNEL =
|
||||||
new PoliciesForLocalChannel(POLICY_DISABLED, POLICY_2);
|
new PoliciesForLocalChannel(POLICY_DISABLED, POLICY_2);
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ class ArcInitializerTest {
|
|||||||
ArcInitializer arcInitializer = getArcInitializer(quantization, feeRateWeight);
|
ArcInitializer arcInitializer = getArcInitializer(quantization, feeRateWeight);
|
||||||
addEdgeWithBaseFee(baseFee, quantization, arcInitializer);
|
addEdgeWithBaseFee(baseFee, quantization, arcInitializer);
|
||||||
|
|
||||||
long expectedFeeRate = (long) Math.ceil(200 + 10);
|
long expectedFeeRate = 210;
|
||||||
assertThat(minCostFlow.getUnitCost(0)).isEqualTo(expectedFeeRate);
|
assertThat(minCostFlow.getUnitCost(0)).isEqualTo(expectedFeeRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,12 +337,12 @@ class ArcInitializerTest {
|
|||||||
ArcInitializer arcInitializer = getArcInitializer(quantization, feeRateWeight);
|
ArcInitializer arcInitializer = getArcInitializer(quantization, feeRateWeight);
|
||||||
addEdgeWithBaseFee(baseFee, quantization, arcInitializer);
|
addEdgeWithBaseFee(baseFee, quantization, arcInitializer);
|
||||||
|
|
||||||
long expectedFeeRate = (long) Math.ceil(200 + 12);
|
long expectedFeeRate = 212;
|
||||||
assertThat(minCostFlow.getUnitCost(0)).isEqualTo(expectedFeeRate);
|
assertThat(minCostFlow.getUnitCost(0)).isEqualTo(expectedFeeRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEdgeWithBaseFee(Coins baseFee, int quantization, ArcInitializer arcInitializer) {
|
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(
|
EdgeWithLiquidityInformation edge = EdgeWithLiquidityInformation.forKnownLiquidity(
|
||||||
new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policy),
|
new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policy),
|
||||||
Coins.ofSatoshis(30L * quantization)
|
Coins.ofSatoshis(30L * quantization)
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class EdgeComputationTest {
|
|||||||
void does_not_add_edge_exceeding_maximum_time_lock_delta() {
|
void does_not_add_edge_exceeding_maximum_time_lock_delta() {
|
||||||
int edgeDelta = 40;
|
int edgeDelta = 40;
|
||||||
int maximumTimeLockDelta = edgeDelta - 1;
|
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);
|
DirectedChannelEdge edge = new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, policy);
|
||||||
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge)));
|
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge)));
|
||||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS, maximumTimeLockDelta).edges()).isEmpty();
|
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS, maximumTimeLockDelta).edges()).isEmpty();
|
||||||
@@ -228,8 +228,9 @@ class EdgeComputationTest {
|
|||||||
@Test
|
@Test
|
||||||
void adds_edge_from_route_hint_service() {
|
void adds_edge_from_route_hint_service() {
|
||||||
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of()));
|
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of()));
|
||||||
|
Coins oneMilliSatoshi = Coins.ofMilliSatoshis(1);
|
||||||
Coins fiftyCoins = Coins.ofSatoshis(5_000_000_000L);
|
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);
|
Edge edge = new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, fiftyCoins, policy);
|
||||||
when(routeHintService.getEdgesFromPaymentHints()).thenReturn(Set.of(
|
when(routeHintService.getEdgesFromPaymentHints()).thenReturn(Set.of(
|
||||||
new DirectedChannelEdge(
|
new DirectedChannelEdge(
|
||||||
@@ -447,7 +448,7 @@ class EdgeComputationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Policy policy(int feeRate) {
|
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() {
|
private void mockInactiveChannel() {
|
||||||
|
|||||||
@@ -626,7 +626,7 @@ class MultiPathPaymentSplitterTest {
|
|||||||
|
|
||||||
private Edge mockExtensionEdge(Pubkey destination, int feeRate) {
|
private Edge mockExtensionEdge(Pubkey destination, int feeRate) {
|
||||||
Policy policyExtension =
|
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(channelService.getOpenChannelsWith(PUBKEY_2)).thenReturn(Set.of(LOCAL_OPEN_CHANNEL));
|
||||||
when(policyService.getPolicyFrom(CHANNEL_ID, PUBKEY_2)).thenReturn(Optional.of(policyExtension));
|
when(policyService.getPolicyFrom(CHANNEL_ID, PUBKEY_2)).thenReturn(Optional.of(policyExtension));
|
||||||
Edge extensionEdge =
|
Edge extensionEdge =
|
||||||
@@ -637,7 +637,7 @@ class MultiPathPaymentSplitterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Policy policyFor(int feeRate) {
|
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) {
|
private EdgeWithLiquidityInformation noInformationFor(Edge edgeSmallCapacity) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static de.cotto.lndmanagej.model.OpenInitiator.REMOTE;
|
|||||||
@SuppressWarnings("PMD.TooManyMethods")
|
@SuppressWarnings("PMD.TooManyMethods")
|
||||||
public final class DeriveDataUtil {
|
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 static final Coins MAX_HTLC = Coins.ofSatoshis(1_000_000);
|
||||||
|
|
||||||
private DeriveDataUtil() {
|
private DeriveDataUtil() {
|
||||||
@@ -98,7 +99,7 @@ public final class DeriveDataUtil {
|
|||||||
Coins baseFee = Coins.ofMilliSatoshis(rand.nextLong(2) * 1000);
|
Coins baseFee = Coins.ofMilliSatoshis(rand.nextLong(2) * 1000);
|
||||||
boolean enabled = rand.nextInt(10) != 0;
|
boolean enabled = rand.nextInt(10) != 0;
|
||||||
int timeLockDelta = (rand.nextInt(5) + 1) * 10;
|
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) {
|
static ChannelStatusDto deriveChannelStatus(ChannelId channelId) {
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ class PageServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static PolicyDto policy(int feeRate, int baseFee) {
|
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) {
|
private BalanceInformation balanceWithRemoteSat(int satoshis) {
|
||||||
|
|||||||
@@ -170,11 +170,13 @@ class ChannelControllerIT {
|
|||||||
.jsonPath("$.policies.local.feeRatePpm").value(is(200))
|
.jsonPath("$.policies.local.feeRatePpm").value(is(200))
|
||||||
.jsonPath("$.policies.local.baseFeeMilliSat").value(is("0"))
|
.jsonPath("$.policies.local.baseFeeMilliSat").value(is("0"))
|
||||||
.jsonPath("$.policies.local.timeLockDelta").value(is(40))
|
.jsonPath("$.policies.local.timeLockDelta").value(is(40))
|
||||||
|
.jsonPath("$.policies.local.minHtlcMilliSat").value(is("0"))
|
||||||
.jsonPath("$.policies.local.maxHtlcMilliSat").value(is("0"))
|
.jsonPath("$.policies.local.maxHtlcMilliSat").value(is("0"))
|
||||||
.jsonPath("$.policies.remote.enabled").value(is(true))
|
.jsonPath("$.policies.remote.enabled").value(is(true))
|
||||||
.jsonPath("$.policies.remote.feeRatePpm").value(is(300))
|
.jsonPath("$.policies.remote.feeRatePpm").value(is(300))
|
||||||
.jsonPath("$.policies.remote.baseFeeMilliSat").value(is("0"))
|
.jsonPath("$.policies.remote.baseFeeMilliSat").value(is("0"))
|
||||||
.jsonPath("$.policies.remote.timeLockDelta").value(is(144))
|
.jsonPath("$.policies.remote.timeLockDelta").value(is(144))
|
||||||
|
.jsonPath("$.policies.remote.minHtlcMilliSat").value(is("159000"))
|
||||||
.jsonPath("$.policies.remote.maxHtlcMilliSat").value(is("22222000"))
|
.jsonPath("$.policies.remote.maxHtlcMilliSat").value(is("22222000"))
|
||||||
.jsonPath("$.feeReport.earnedMilliSat").value(is("1234"))
|
.jsonPath("$.feeReport.earnedMilliSat").value(is("1234"))
|
||||||
.jsonPath("$.feeReport.sourcedMilliSat").value(is("567"))
|
.jsonPath("$.feeReport.sourcedMilliSat").value(is("567"))
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ public record PolicyDto(
|
|||||||
String baseFeeMilliSat,
|
String baseFeeMilliSat,
|
||||||
boolean enabled,
|
boolean enabled,
|
||||||
int timeLockDelta,
|
int timeLockDelta,
|
||||||
|
String minHtlcMilliSat,
|
||||||
String maxHtlcMilliSat
|
String maxHtlcMilliSat
|
||||||
) {
|
) {
|
||||||
public static PolicyDto createFromModel(Policy policy) {
|
public static PolicyDto createFromModel(Policy policy) {
|
||||||
@@ -15,6 +16,7 @@ public record PolicyDto(
|
|||||||
String.valueOf(policy.baseFee().milliSatoshis()),
|
String.valueOf(policy.baseFee().milliSatoshis()),
|
||||||
policy.enabled(),
|
policy.enabled(),
|
||||||
policy.timeLockDelta(),
|
policy.timeLockDelta(),
|
||||||
|
String.valueOf(policy.minHtlc().milliSatoshis()),
|
||||||
String.valueOf(policy.maxHtlc().milliSatoshis())
|
String.valueOf(policy.maxHtlc().milliSatoshis())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
class PolicyDtoTest {
|
class PolicyDtoTest {
|
||||||
@Test
|
@Test
|
||||||
void createFromModel_disabled() {
|
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);
|
PolicyDto dto = PolicyDto.createFromModel(POLICY_DISABLED);
|
||||||
assertThat(dto).isEqualTo(expected);
|
assertThat(dto).isEqualTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createFromModel_with_base_fee() {
|
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);
|
PolicyDto dto = PolicyDto.createFromModel(POLICY_WITH_BASE_FEE);
|
||||||
assertThat(dto).isEqualTo(expected);
|
assertThat(dto).isEqualTo(expected);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user