diff --git a/backend/src/main/java/de/cotto/lndmanagej/service/GraphService.java b/backend/src/main/java/de/cotto/lndmanagej/service/GraphService.java index 1f52a1dc..fc5607bd 100644 --- a/backend/src/main/java/de/cotto/lndmanagej/service/GraphService.java +++ b/backend/src/main/java/de/cotto/lndmanagej/service/GraphService.java @@ -2,7 +2,7 @@ package de.cotto.lndmanagej.service; import de.cotto.lndmanagej.grpc.GrpcGraph; import de.cotto.lndmanagej.model.Coins; -import de.cotto.lndmanagej.model.DirectedChannelEdge; +import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.Pubkey; import de.cotto.lndmanagej.model.PubkeyAndFeeRate; import org.springframework.stereotype.Service; @@ -35,19 +35,19 @@ public class GraphService { } public List getNodesWithHighFeeRate() { - Set edges = grpcGraph.getChannelEdges().orElse(null); + Set edges = grpcGraph.getChannelEdges().orElse(null); if (edges == null) { return List.of(); } - Map> candidates = getCandidateEdges(edges); + Map> candidates = getCandidateEdges(edges); return candidates.entrySet().parallelStream() .map(this::withAverageFeeRate) .sorted(Comparator.comparing(PubkeyAndFeeRate::feeRate).reversed()) .toList(); } - private Map> getCandidateEdges(Set edges) { - Map> candidates = edges.parallelStream() + private Map> getCandidateEdges(Set edges) { + Map> candidates = edges.parallelStream() .filter(e -> e.policy().enabled()) .filter(e -> e.policy().feeRate() <= MAX_FEE_RATE) .filter(e -> e.policy().feeRate() > 0) @@ -58,17 +58,17 @@ public class GraphService { } private void combine( - Map> first, - Map> second + Map> first, + Map> second ) { - for (Map.Entry> entry : second.entrySet()) { + for (Map.Entry> entry : second.entrySet()) { Pubkey pubkey = entry.getKey(); first.computeIfAbsent(pubkey, k -> new LinkedHashSet<>()).addAll(entry.getValue()); } } - private void add(Map> map, DirectedChannelEdge edge) { - map.compute(edge.target(), (p, s) -> { + private void add(Map> map, Edge edge) { + map.compute(edge.endNode(), (p, s) -> { if (s == null) { s = new LinkedHashSet<>(); } @@ -77,7 +77,7 @@ public class GraphService { }); } - private PubkeyAndFeeRate withAverageFeeRate(Map.Entry> entry) { + private PubkeyAndFeeRate withAverageFeeRate(Map.Entry> entry) { Pubkey pubkey = entry.getKey(); long feeRateSum = entry.getValue().stream().mapToLong(e -> e.policy().feeRate()).sum(); int average = (int) (feeRateSum / entry.getValue().size()); diff --git a/backend/src/main/java/de/cotto/lndmanagej/service/RouteHintService.java b/backend/src/main/java/de/cotto/lndmanagej/service/RouteHintService.java index 7ded9021..a9429e5a 100644 --- a/backend/src/main/java/de/cotto/lndmanagej/service/RouteHintService.java +++ b/backend/src/main/java/de/cotto/lndmanagej/service/RouteHintService.java @@ -3,7 +3,7 @@ package de.cotto.lndmanagej.service; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.Coins; import de.cotto.lndmanagej.model.DecodedPaymentRequest; -import de.cotto.lndmanagej.model.DirectedChannelEdge; +import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.Policy; import de.cotto.lndmanagej.model.RouteHint; import org.springframework.scheduling.annotation.Scheduled; @@ -31,11 +31,11 @@ public class RouteHintService { public void addDecodedPaymentRequest(DecodedPaymentRequest decodedPaymentRequest) { decodedPaymentRequest.routeHints().stream() - .map(this::toDirectedChannelEdge) + .map(this::toEdge) .forEach(edge -> edges.put(edge.channelId(), new EdgeWithInstant(edge))); } - public Set getEdgesFromPaymentHints() { + public Set getEdgesFromPaymentHints() { return edges.values().stream().map(EdgeWithInstant::edge).collect(Collectors.toSet()); } @@ -45,12 +45,12 @@ public class RouteHintService { edges.values().removeIf(edgeWithInstant -> edgeWithInstant.instant().isBefore(cutoff)); } - private DirectedChannelEdge toDirectedChannelEdge(RouteHint routeHint) { - return new DirectedChannelEdge( + private Edge toEdge(RouteHint routeHint) { + return new Edge( routeHint.channelId(), - FIFTY_COINS, routeHint.sourceNode(), routeHint.endNode(), + FIFTY_COINS, toPolicy(routeHint), Policy.UNKNOWN ); @@ -68,8 +68,8 @@ public class RouteHintService { } @SuppressWarnings("UnusedVariable") - private record EdgeWithInstant(DirectedChannelEdge edge, Instant instant) { - private EdgeWithInstant(DirectedChannelEdge edge) { + private record EdgeWithInstant(Edge edge, Instant instant) { + private EdgeWithInstant(Edge edge) { this(edge, Instant.now()); } } diff --git a/backend/src/test/java/de/cotto/lndmanagej/service/GraphServiceTest.java b/backend/src/test/java/de/cotto/lndmanagej/service/GraphServiceTest.java index 74a0587f..6d720eb9 100644 --- a/backend/src/test/java/de/cotto/lndmanagej/service/GraphServiceTest.java +++ b/backend/src/test/java/de/cotto/lndmanagej/service/GraphServiceTest.java @@ -2,7 +2,7 @@ package de.cotto.lndmanagej.service; import de.cotto.lndmanagej.grpc.GrpcGraph; import de.cotto.lndmanagej.model.Coins; -import de.cotto.lndmanagej.model.DirectedChannelEdge; +import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.Policy; import de.cotto.lndmanagej.model.Pubkey; import de.cotto.lndmanagej.model.PubkeyAndFeeRate; @@ -17,7 +17,7 @@ import java.util.Optional; import java.util.Set; import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; -import static de.cotto.lndmanagej.model.DirectedChannelEdgeFixtures.CHANNEL_EDGE_WITH_POLICY; +import static de.cotto.lndmanagej.model.EdgeFixtures.EDGE; import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2; import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_3; @@ -41,7 +41,7 @@ class GraphServiceTest { @Test void getNumberOfEdges() { - when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(CHANNEL_EDGE_WITH_POLICY))); + when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(EDGE))); assertThat(graphService.getNumberOfChannels()).isEqualTo(1); } @@ -63,7 +63,7 @@ class GraphServiceTest { @Test void getNodesWithHighFeeRate_no_edge() { - Set edges = Set.of(); + Set edges = Set.of(); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(edges)); assertThat(graphService.getNodesWithHighFeeRate()).isEmpty(); } @@ -76,7 +76,7 @@ class GraphServiceTest { @Test void getNodesWithHighFeeRate_ignores_disabled_channels() { - Set edges = edges(9, 200, PUBKEY_2); + Set edges = edges(9, 200, PUBKEY_2); 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(); @@ -84,21 +84,21 @@ class GraphServiceTest { @Test void getNodesWithHighFeeRate_ignores_absurd_fee_rates() { - Set edges = edges(9, 200, PUBKEY_2); + Set edges = edges(9, 200, PUBKEY_2); edges.add(edge(20_000, 20, PUBKEY_2)); assertThat(graphService.getNodesWithHighFeeRate()).isEmpty(); } @Test void getNodesWithHighFeeRate_ignores_zero_fee_rate() { - Set edges = edges(9, 200, PUBKEY_2); + Set edges = edges(9, 200, PUBKEY_2); edges.add(edge(0, 20, PUBKEY_2)); assertThat(graphService.getNodesWithHighFeeRate()).isEmpty(); } @Test void getNodesWithHighFeeRate_ignores_low_capacity_channels() { - Set edges = edges(9, 200, PUBKEY_2); + Set edges = edges(9, 200, PUBKEY_2); edges.add(edge(200, 9, PUBKEY_2)); assertThat(graphService.getNodesWithHighFeeRate()).isEmpty(); } @@ -113,7 +113,7 @@ class GraphServiceTest { @Test void getNodesWithHighFeeRate_average() { - Set edges = new LinkedHashSet<>(); + Set edges = new LinkedHashSet<>(); for (int i = 0; i < 10; i++) { edges.add(edge(300 + i * 10, 20, PUBKEY_4)); edges.add(edge(200, 20 + i, PUBKEY_3)); @@ -125,8 +125,8 @@ class GraphServiceTest { ); } - private Set edges(int count, int feeRate, Pubkey target) { - Set edges = new LinkedHashSet<>(); + private Set edges(int count, int feeRate, Pubkey target) { + Set edges = new LinkedHashSet<>(); for (int i = 0; i < count; i++) { edges.add(edge(feeRate, 20 + i, target)); } @@ -134,18 +134,18 @@ class GraphServiceTest { return edges; } - private DirectedChannelEdge edge(long feeRate, long capacityMillionSat, Pubkey target) { + private Edge edge(long feeRate, long capacityMillionSat, Pubkey target) { 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); } - private DirectedChannelEdge edge(Policy policy, Coins capacity, Pubkey target) { - return new DirectedChannelEdge( + private Edge edge(Policy policy, Coins capacity, Pubkey target) { + return new Edge( CHANNEL_ID, - capacity, PUBKEY, target, + capacity, policy, Policy.UNKNOWN ); diff --git a/backend/src/test/java/de/cotto/lndmanagej/service/RouteHintServiceTest.java b/backend/src/test/java/de/cotto/lndmanagej/service/RouteHintServiceTest.java index 311329ce..4f6fb3cf 100644 --- a/backend/src/test/java/de/cotto/lndmanagej/service/RouteHintServiceTest.java +++ b/backend/src/test/java/de/cotto/lndmanagej/service/RouteHintServiceTest.java @@ -2,7 +2,7 @@ package de.cotto.lndmanagej.service; import de.cotto.lndmanagej.model.Coins; import de.cotto.lndmanagej.model.DecodedPaymentRequest; -import de.cotto.lndmanagej.model.DirectedChannelEdge; +import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.Policy; import de.cotto.lndmanagej.model.RouteHint; import org.junit.jupiter.api.Test; @@ -39,10 +39,10 @@ class RouteHintServiceTest { routeHintService.addDecodedPaymentRequest(DECODED_PAYMENT_REQUEST); 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, Policy.UNKNOWN); - DirectedChannelEdge edge2 = - new DirectedChannelEdge(CHANNEL_ID_2, FIFTY_COINS, PUBKEY_3, PUBKEY_4, policy2, Policy.UNKNOWN); + Edge edge1 = + new Edge(CHANNEL_ID, PUBKEY, PUBKEY_4, FIFTY_COINS, policy1, Policy.UNKNOWN); + Edge edge2 = + new Edge(CHANNEL_ID_2, PUBKEY_3, PUBKEY_4, FIFTY_COINS, policy2, Policy.UNKNOWN); assertThat(routeHintService.getEdgesFromPaymentHints()).contains(edge1, edge2); } diff --git a/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcGraph.java b/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcGraph.java index 411b1667..cf70dfd0 100644 --- a/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcGraph.java +++ b/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcGraph.java @@ -4,7 +4,7 @@ import com.github.benmanes.caffeine.cache.LoadingCache; import de.cotto.lndmanagej.caching.CacheBuilder; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.Coins; -import de.cotto.lndmanagej.model.DirectedChannelEdge; +import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.Policy; import de.cotto.lndmanagej.model.Pubkey; import lnrpc.ChannelEdge; @@ -20,7 +20,7 @@ import java.util.Set; public class GrpcGraph { 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>> channelEdgeCache; + private final LoadingCache>> channelEdgeCache; private final GrpcPolicy grpcPolicy; public GrpcGraph(GrpcService grpcService, GrpcPolicy grpcPolicy) { @@ -33,7 +33,7 @@ public class GrpcGraph { .build(this::getChannelEdgesWithoutCache); } - public Optional> getChannelEdges() { + public Optional> getChannelEdges() { return channelEdgeCache.get(""); } @@ -41,12 +41,12 @@ public class GrpcGraph { channelEdgeCache.invalidateAll(); } - private Optional> getChannelEdgesWithoutCache() { + private Optional> getChannelEdgesWithoutCache() { ChannelGraph channelGraph = grpcService.describeGraph().orElse(null); if (channelGraph == null) { return Optional.empty(); } - Set channelEdges = new LinkedHashSet<>(); + Set channelEdges = new LinkedHashSet<>(); for (ChannelEdge channelEdge : channelGraph.getEdgesList()) { ChannelId channelId = ChannelId.fromShortChannelId(channelEdge.getChannelId()); Coins capacity = Coins.ofSatoshis(channelEdge.getCapacity()); @@ -54,24 +54,24 @@ public class GrpcGraph { Pubkey node2Pubkey = Pubkey.create(channelEdge.getNode2Pub()); Policy node1Policy = getNode1Policy(channelEdge); Policy node2Policy = getNode2Policy(channelEdge); - DirectedChannelEdge directedChannelEdge1 = new DirectedChannelEdge( + Edge edge1 = new Edge( channelId, - capacity, node1Pubkey, node2Pubkey, + capacity, node1Policy, node2Policy ); - DirectedChannelEdge directedChannelEdge2 = new DirectedChannelEdge( + Edge edge2 = new Edge( channelId, - capacity, node2Pubkey, node1Pubkey, + capacity, node2Policy, node1Policy ); - channelEdges.add(directedChannelEdge1); - channelEdges.add(directedChannelEdge2); + channelEdges.add(edge1); + channelEdges.add(edge2); } return Optional.of(channelEdges); } diff --git a/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcGraphTest.java b/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcGraphTest.java index 6c63beac..40b5e650 100644 --- a/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcGraphTest.java +++ b/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcGraphTest.java @@ -1,7 +1,7 @@ package de.cotto.lndmanagej.grpc; import de.cotto.lndmanagej.model.Coins; -import de.cotto.lndmanagej.model.DirectedChannelEdge; +import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.Policy; import lnrpc.ChannelEdge; import lnrpc.ChannelGraph; @@ -74,19 +74,19 @@ class GrpcGraphTest { .build(); Policy policy1 = new Policy(0, Coins.NONE, false, 40, MIN_HTLC, MAX_HTLC); Policy policy2 = new Policy(1, Coins.NONE, true, 144, MIN_HTLC, MAX_HTLC); - DirectedChannelEdge expectedEdge1 = new DirectedChannelEdge( + Edge expectedEdge1 = new Edge( CHANNEL_ID, - CAPACITY, PUBKEY, PUBKEY_2, + CAPACITY, policy1, policy2 ); - DirectedChannelEdge expectedEdge2 = new DirectedChannelEdge( + Edge expectedEdge2 = new Edge( CHANNEL_ID, - CAPACITY, PUBKEY_2, PUBKEY, + CAPACITY, policy2, policy1 ); @@ -100,19 +100,19 @@ class GrpcGraphTest { .build(); Policy policy3 = new Policy(456, Coins.NONE, true, 123, MIN_HTLC, MAX_HTLC); Policy policy4 = new Policy(123, Coins.ofMilliSatoshis(1), true, 456, MIN_HTLC, MAX_HTLC); - DirectedChannelEdge expectedEdge3 = new DirectedChannelEdge( + Edge expectedEdge3 = new Edge( CHANNEL_ID_2, - CAPACITY_2, PUBKEY_3, PUBKEY_4, + CAPACITY_2, policy3, policy4 ); - DirectedChannelEdge expectedEdge4 = new DirectedChannelEdge( + Edge expectedEdge4 = new Edge( CHANNEL_ID_2, - CAPACITY_2, PUBKEY_4, PUBKEY_3, + CAPACITY_2, policy4, policy3 ); @@ -134,19 +134,19 @@ class GrpcGraphTest { .setNode1Pub(PUBKEY.toString()) .setNode2Pub(PUBKEY_2.toString()) .build(); - DirectedChannelEdge expectedPolicyForNode1 = new DirectedChannelEdge( + Edge expectedPolicyForNode1 = new Edge( CHANNEL_ID, - CAPACITY, PUBKEY, PUBKEY_2, + CAPACITY, Policy.UNKNOWN, Policy.UNKNOWN ); - DirectedChannelEdge expectedPolicyForNode2 = new DirectedChannelEdge( + Edge expectedPolicyForNode2 = new Edge( CHANNEL_ID, - CAPACITY, PUBKEY_2, PUBKEY, + CAPACITY, Policy.UNKNOWN, Policy.UNKNOWN ); diff --git a/model/src/main/java/de/cotto/lndmanagej/model/DirectedChannelEdge.java b/model/src/main/java/de/cotto/lndmanagej/model/DirectedChannelEdge.java deleted file mode 100644 index 5b529ec6..00000000 --- a/model/src/main/java/de/cotto/lndmanagej/model/DirectedChannelEdge.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.cotto.lndmanagej.model; - -public record DirectedChannelEdge( - ChannelId channelId, - Coins capacity, - Pubkey source, - Pubkey target, - Policy policy, - Policy reversePolicy -) { -} diff --git a/model/src/test/java/de/cotto/lndmanagej/model/DirectedChannelEdgeTest.java b/model/src/test/java/de/cotto/lndmanagej/model/DirectedChannelEdgeTest.java deleted file mode 100644 index 89dc4edf..00000000 --- a/model/src/test/java/de/cotto/lndmanagej/model/DirectedChannelEdgeTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.cotto.lndmanagej.model; - -import org.junit.jupiter.api.Test; - -import static de.cotto.lndmanagej.model.ChannelFixtures.CAPACITY; -import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; -import static de.cotto.lndmanagej.model.DirectedChannelEdgeFixtures.CHANNEL_EDGE_WITH_POLICY; -import static de.cotto.lndmanagej.model.PolicyFixtures.POLICY_1; -import static de.cotto.lndmanagej.model.PolicyFixtures.POLICY_2; -import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; -import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2; -import static org.assertj.core.api.Assertions.assertThat; - -class DirectedChannelEdgeTest { - @Test - void channelId() { - assertThat(CHANNEL_EDGE_WITH_POLICY.channelId()).isEqualTo(CHANNEL_ID); - } - - @Test - void capacity() { - assertThat(CHANNEL_EDGE_WITH_POLICY.capacity()).isEqualTo(CAPACITY); - } - - @Test - void source() { - assertThat(CHANNEL_EDGE_WITH_POLICY.source()).isEqualTo(PUBKEY); - } - - @Test - void target() { - assertThat(CHANNEL_EDGE_WITH_POLICY.target()).isEqualTo(PUBKEY_2); - } - - @Test - void policy() { - assertThat(CHANNEL_EDGE_WITH_POLICY.policy()).isEqualTo(POLICY_1); - } - - @Test - void reversePolicy() { - assertThat(CHANNEL_EDGE_WITH_POLICY.reversePolicy()).isEqualTo(POLICY_2); - } -} diff --git a/model/src/testFixtures/java/de/cotto/lndmanagej/model/DirectedChannelEdgeFixtures.java b/model/src/testFixtures/java/de/cotto/lndmanagej/model/DirectedChannelEdgeFixtures.java deleted file mode 100644 index 8fc435f2..00000000 --- a/model/src/testFixtures/java/de/cotto/lndmanagej/model/DirectedChannelEdgeFixtures.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.cotto.lndmanagej.model; - -import static de.cotto.lndmanagej.model.ChannelFixtures.CAPACITY; -import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; -import static de.cotto.lndmanagej.model.PolicyFixtures.POLICY_1; -import static de.cotto.lndmanagej.model.PolicyFixtures.POLICY_2; -import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; -import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2; - -public class DirectedChannelEdgeFixtures { - public static final DirectedChannelEdge CHANNEL_EDGE_WITH_POLICY = new DirectedChannelEdge( - CHANNEL_ID, - CAPACITY, - PUBKEY, - PUBKEY_2, - POLICY_1, - POLICY_2 - ); -} diff --git a/pickhardt-payments/src/main/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputation.java b/pickhardt-payments/src/main/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputation.java index 0c64cde9..fd7315db 100644 --- a/pickhardt-payments/src/main/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputation.java +++ b/pickhardt-payments/src/main/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputation.java @@ -6,7 +6,6 @@ import de.cotto.lndmanagej.grpc.GrpcGraph; import de.cotto.lndmanagej.grpc.middleware.GrpcMiddlewareService; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.Coins; -import de.cotto.lndmanagej.model.DirectedChannelEdge; import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.EdgeWithLiquidityInformation; import de.cotto.lndmanagej.model.LocalOpenChannel; @@ -63,30 +62,19 @@ public class EdgeComputation { logger.error("Middleware needs to be connected, see requirements section in PickhardtPayments.md"); return EdgesWithLiquidityInformation.EMPTY; } - Set channelEdges = grpcGraph.getChannelEdges().orElse(null); + Set channelEdges = grpcGraph.getChannelEdges().orElse(null); if (channelEdges == null) { logger.error("Unable to get graph"); return EdgesWithLiquidityInformation.EMPTY; } Set edgesWithLiquidityInformation = new LinkedHashSet<>(); Pubkey ownPubkey = grpcGetInfo.getPubkey(); - Set edgesFromPaymentHints = routeHintService.getEdgesFromPaymentHints(); - for (DirectedChannelEdge channelEdge : Sets.union(channelEdges, edgesFromPaymentHints)) { - if (shouldIgnore(channelEdge, paymentOptions, ownPubkey, maximumTimeLockDeltaPerEdge)) { + Set edgesFromPaymentHints = routeHintService.getEdgesFromPaymentHints(); + for (Edge edge : Sets.union(channelEdges, edgesFromPaymentHints)) { + if (shouldIgnore(edge, paymentOptions, ownPubkey, maximumTimeLockDeltaPerEdge)) { continue; } - ChannelId channelId = channelEdge.channelId(); - Pubkey pubkey1 = channelEdge.source(); - Pubkey pubkey2 = channelEdge.target(); - Edge edge = new Edge( - channelId, - pubkey1, - pubkey2, - channelEdge.capacity(), - channelEdge.policy(), - channelEdge.reversePolicy() - ); - if (edgesFromPaymentHints.contains(channelEdge)) { + if (edgesFromPaymentHints.contains(edge)) { edgesWithLiquidityInformation.add( EdgeWithLiquidityInformation.forLowerAndUpperBound(edge, edge.capacity(), edge.capacity()) ); @@ -115,7 +103,7 @@ public class EdgeComputation { @SuppressWarnings("PMD.SimplifyBooleanReturns") private boolean shouldIgnore( - DirectedChannelEdge channelEdge, + Edge channelEdge, PaymentOptions paymentOptions, Pubkey pubkey, int maximumTimeLockDeltaPerEdge @@ -133,7 +121,7 @@ public class EdgeComputation { } long feeRate = policy.feeRate(); boolean hopIsRelevantForFeeCheck = - !pubkey.equals(channelEdge.source()) || !paymentOptions.ignoreFeesForOwnChannels(); + !pubkey.equals(channelEdge.startNode()) || !paymentOptions.ignoreFeesForOwnChannels(); if (feeRate >= feeRateLimit && hopIsRelevantForFeeCheck) { return true; } @@ -152,16 +140,16 @@ public class EdgeComputation { @SuppressWarnings("PMD.SimplifyBooleanReturns") private boolean isEdgeToUnwantedFirstHop( - DirectedChannelEdge channelEdge, + Edge channelEdge, PaymentOptions paymentOptions, Pubkey pubkey ) { - boolean isOutgoingEdge = pubkey.equals(channelEdge.source()); + boolean isOutgoingEdge = pubkey.equals(channelEdge.startNode()); if (!isOutgoingEdge) { return false; } Pubkey peerForFirstHop = paymentOptions.peerForFirstHop().orElse(null); - boolean firstHopIsUnexpected = peerForFirstHop != null && !peerForFirstHop.equals(channelEdge.target()); + boolean firstHopIsUnexpected = peerForFirstHop != null && !peerForFirstHop.equals(channelEdge.endNode()); if (firstHopIsUnexpected) { return true; } @@ -169,11 +157,11 @@ public class EdgeComputation { if (peerForLastHop == null) { return false; } - return peerForLastHop.equals(channelEdge.target()); + return peerForLastHop.equals(channelEdge.endNode()); } - private boolean isIncomingEdge(DirectedChannelEdge channelEdge, Pubkey ownPubkey) { - return ownPubkey.equals(channelEdge.target()); + private boolean isIncomingEdge(Edge channelEdge, Pubkey ownPubkey) { + return ownPubkey.equals(channelEdge.endNode()); } private Optional getKnownLiquidity(Edge edge, Pubkey ownPubKey) { diff --git a/pickhardt-payments/src/test/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputationTest.java b/pickhardt-payments/src/test/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputationTest.java index 379845f7..a5af0cff 100644 --- a/pickhardt-payments/src/test/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputationTest.java +++ b/pickhardt-payments/src/test/java/de/cotto/lndmanagej/pickhardtpayments/EdgeComputationTest.java @@ -6,7 +6,6 @@ import de.cotto.lndmanagej.grpc.middleware.GrpcMiddlewareService; import de.cotto.lndmanagej.model.ChannelCoreInformation; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.Coins; -import de.cotto.lndmanagej.model.DirectedChannelEdge; import de.cotto.lndmanagej.model.Edge; import de.cotto.lndmanagej.model.EdgeWithLiquidityInformation; import de.cotto.lndmanagej.model.LocalOpenChannel; @@ -112,8 +111,8 @@ class EdgeComputationTest { @Test void does_not_add_edge_for_disabled_channel() { - DirectedChannelEdge edge = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, POLICY_DISABLED, Policy.UNKNOWN); + Edge edge = + new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, POLICY_DISABLED, Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge))); assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS, MAX_TIME_LOCK_DELTA).edges()).isEmpty(); } @@ -124,8 +123,8 @@ class EdgeComputationTest { int maximumTimeLockDelta = edgeDelta - 1; 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, Policy.UNKNOWN); + Edge edge = + new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policy, Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge))); assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS, maximumTimeLockDelta).edges()).isEmpty(); } @@ -138,12 +137,12 @@ class EdgeComputationTest { // needs to be excluded to avoid sending top-up payments in a tiny loop: S-X-S Policy policyAtLimit = policy(199); Policy policyOk = policy(198); - DirectedChannelEdge edgeExpensive = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, policyExpensive, Policy.UNKNOWN); - DirectedChannelEdge edgeAtLimit = - new DirectedChannelEdge(CHANNEL_ID_2, CAPACITY, PUBKEY, PUBKEY_2, policyAtLimit, Policy.UNKNOWN); - DirectedChannelEdge edgeOk = - new DirectedChannelEdge(CHANNEL_ID_3, CAPACITY, PUBKEY, PUBKEY_2, policyOk, Policy.UNKNOWN); + Edge edgeExpensive = + new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policyExpensive, Policy.UNKNOWN); + Edge edgeAtLimit = + new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policyAtLimit, Policy.UNKNOWN); + Edge edgeOk = + new Edge(CHANNEL_ID_3, PUBKEY, PUBKEY_2, CAPACITY, policyOk, Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edgeExpensive, edgeAtLimit, edgeOk))); assertThat( edgeComputation.getEdges(paymentOptions, MAX_TIME_LOCK_DELTA).edges().stream() @@ -155,8 +154,8 @@ class EdgeComputationTest { void adds_edge_with_fee_rate_at_limit_if_first_hop_and_fee_is_ignored() { int feeRateLimit = 1000; PaymentOptions paymentOptions = PaymentOptions.forFeeRateLimit(feeRateLimit); - DirectedChannelEdge edge = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY_4, PUBKEY_2, policy(feeRateLimit), Policy.UNKNOWN); + Edge edge = + new Edge(CHANNEL_ID, PUBKEY_4, PUBKEY_2, CAPACITY, policy(feeRateLimit), Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge))); assertThat(edgeComputation.getEdges(paymentOptions, MAX_TIME_LOCK_DELTA).edges()).isNotEmpty(); } @@ -172,8 +171,8 @@ class EdgeComputationTest { Optional.empty(), Optional.empty() ); - DirectedChannelEdge edge = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY_4, PUBKEY, policy(feeRateLimit), Policy.UNKNOWN); + Edge edge = + new Edge(CHANNEL_ID, PUBKEY_4, PUBKEY, CAPACITY, policy(feeRateLimit), Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge))); assertThat(edgeComputation.getEdges(paymentOptions, MAX_TIME_LOCK_DELTA).edges()).isEmpty(); } @@ -191,27 +190,27 @@ class EdgeComputationTest { Policy lastHopPolicy = policy(199); Policy firstHopPolicyExpensive = policy(100); Policy firstHopPolicyOk = policy(99); - DirectedChannelEdge lastHop = new DirectedChannelEdge( + Edge lastHop = new Edge( CHANNEL_ID, - CAPACITY, topUpPeer, ownPubkey, + CAPACITY, lastHopPolicy, Policy.UNKNOWN ); - DirectedChannelEdge firstHopExpensive = new DirectedChannelEdge( + Edge firstHopExpensive = new Edge( CHANNEL_ID_2, - CAPACITY, ownPubkey, PUBKEY_2, + CAPACITY, firstHopPolicyExpensive, Policy.UNKNOWN ); - DirectedChannelEdge firstHopOk = new DirectedChannelEdge( + Edge firstHopOk = new Edge( CHANNEL_ID_3, - CAPACITY, ownPubkey, PUBKEY_2, + CAPACITY, firstHopPolicyOk, Policy.UNKNOWN ); @@ -230,11 +229,11 @@ class EdgeComputationTest { when(grpcGetInfo.getPubkey()).thenReturn(ownPubkey); PaymentOptions paymentOptions = PaymentOptions.forFeeRateLimit(feeRateLimit); Policy firstHopPolicyExpensive = policy(100); - DirectedChannelEdge firstHopExpensiveButOk = new DirectedChannelEdge( + Edge firstHopExpensiveButOk = new Edge( CHANNEL_ID_2, - CAPACITY, ownPubkey, PUBKEY_2, + CAPACITY, firstHopPolicyExpensive, Policy.UNKNOWN ); @@ -247,8 +246,8 @@ class EdgeComputationTest { @Test void adds_edge_for_channel_with_base_fee() { - DirectedChannelEdge edge = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, POLICY_WITH_BASE_FEE, Policy.UNKNOWN); + Edge edge = + new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, POLICY_WITH_BASE_FEE, Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge))); assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS, MAX_TIME_LOCK_DELTA).edges()).isNotEmpty(); } @@ -291,11 +290,11 @@ class EdgeComputationTest { Policy policy = new Policy(200, Coins.NONE, true, 40, oneMilliSatoshi, fiftyCoins); Edge edge = new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, fiftyCoins, policy, Policy.UNKNOWN); when(routeHintService.getEdgesFromPaymentHints()).thenReturn(Set.of( - new DirectedChannelEdge( + new Edge( edge.channelId(), - edge.capacity(), edge.startNode(), edge.endNode(), + edge.capacity(), edge.policy(), edge.reversePolicy() ) @@ -379,10 +378,10 @@ class EdgeComputationTest { Pubkey ownNode = PUBKEY_4; Pubkey peerForFirstHop = PUBKEY_3; - DirectedChannelEdge edgeToFirstHop = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, ownNode, peerForFirstHop, POLICY_1, Policy.UNKNOWN); - DirectedChannelEdge otherEdge = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, ownNode, PUBKEY, POLICY_1, Policy.UNKNOWN); + Edge edgeToFirstHop = + new Edge(CHANNEL_ID, ownNode, peerForFirstHop, CAPACITY, POLICY_1, Policy.UNKNOWN); + Edge otherEdge = + new Edge(CHANNEL_ID, ownNode, PUBKEY, CAPACITY, POLICY_1, Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edgeToFirstHop, otherEdge))); PaymentOptions paymentOptions = @@ -397,10 +396,10 @@ class EdgeComputationTest { Pubkey ownNode = PUBKEY_4; Pubkey lastHopNode = PUBKEY_2; - DirectedChannelEdge edgeToLastHop = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, ownNode, lastHopNode, POLICY_1, Policy.UNKNOWN); - DirectedChannelEdge otherEdge = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, ownNode, PUBKEY, POLICY_1, Policy.UNKNOWN); + Edge edgeToLastHop = + new Edge(CHANNEL_ID, ownNode, lastHopNode, CAPACITY, POLICY_1, Policy.UNKNOWN); + Edge otherEdge = + new Edge(CHANNEL_ID, ownNode, PUBKEY, CAPACITY, POLICY_1, Policy.UNKNOWN); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edgeToLastHop, otherEdge))); PaymentOptions paymentOptions = @@ -504,8 +503,8 @@ class EdgeComputationTest { } private void mockEdge() { - DirectedChannelEdge edge = - new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, POLICY_1, POLICY_2); + Edge edge = + new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, POLICY_1, POLICY_2); when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge))); }