mirror of
https://github.com/aljazceru/lnd-manageJ.git
synced 2025-12-17 06:04:25 +01:00
replace DirectedChannelEdge by Edge
This commit is contained in:
@@ -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<PubkeyAndFeeRate> getNodesWithHighFeeRate() {
|
||||
Set<DirectedChannelEdge> edges = grpcGraph.getChannelEdges().orElse(null);
|
||||
Set<Edge> edges = grpcGraph.getChannelEdges().orElse(null);
|
||||
if (edges == null) {
|
||||
return List.of();
|
||||
}
|
||||
Map<Pubkey, Set<DirectedChannelEdge>> candidates = getCandidateEdges(edges);
|
||||
Map<Pubkey, Set<Edge>> candidates = getCandidateEdges(edges);
|
||||
return candidates.entrySet().parallelStream()
|
||||
.map(this::withAverageFeeRate)
|
||||
.sorted(Comparator.comparing(PubkeyAndFeeRate::feeRate).reversed())
|
||||
.toList();
|
||||
}
|
||||
|
||||
private Map<Pubkey, Set<DirectedChannelEdge>> getCandidateEdges(Set<DirectedChannelEdge> edges) {
|
||||
Map<Pubkey, Set<DirectedChannelEdge>> candidates = edges.parallelStream()
|
||||
private Map<Pubkey, Set<Edge>> getCandidateEdges(Set<Edge> edges) {
|
||||
Map<Pubkey, Set<Edge>> 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<Pubkey, Set<DirectedChannelEdge>> first,
|
||||
Map<Pubkey, Set<DirectedChannelEdge>> second
|
||||
Map<Pubkey, Set<Edge>> first,
|
||||
Map<Pubkey, Set<Edge>> second
|
||||
) {
|
||||
for (Map.Entry<Pubkey, Set<DirectedChannelEdge>> entry : second.entrySet()) {
|
||||
for (Map.Entry<Pubkey, Set<Edge>> entry : second.entrySet()) {
|
||||
Pubkey pubkey = entry.getKey();
|
||||
first.computeIfAbsent(pubkey, k -> new LinkedHashSet<>()).addAll(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void add(Map<Pubkey, Set<DirectedChannelEdge>> map, DirectedChannelEdge edge) {
|
||||
map.compute(edge.target(), (p, s) -> {
|
||||
private void add(Map<Pubkey, Set<Edge>> 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<Pubkey, Set<DirectedChannelEdge>> entry) {
|
||||
private PubkeyAndFeeRate withAverageFeeRate(Map.Entry<Pubkey, Set<Edge>> entry) {
|
||||
Pubkey pubkey = entry.getKey();
|
||||
long feeRateSum = entry.getValue().stream().mapToLong(e -> e.policy().feeRate()).sum();
|
||||
int average = (int) (feeRateSum / entry.getValue().size());
|
||||
|
||||
@@ -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<DirectedChannelEdge> getEdgesFromPaymentHints() {
|
||||
public Set<Edge> 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DirectedChannelEdge> edges = Set.of();
|
||||
Set<Edge> 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<DirectedChannelEdge> edges = edges(9, 200, PUBKEY_2);
|
||||
Set<Edge> 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<DirectedChannelEdge> edges = edges(9, 200, PUBKEY_2);
|
||||
Set<Edge> 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<DirectedChannelEdge> edges = edges(9, 200, PUBKEY_2);
|
||||
Set<Edge> 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<DirectedChannelEdge> edges = edges(9, 200, PUBKEY_2);
|
||||
Set<Edge> 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<DirectedChannelEdge> edges = new LinkedHashSet<>();
|
||||
Set<Edge> 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<DirectedChannelEdge> edges(int count, int feeRate, Pubkey target) {
|
||||
Set<DirectedChannelEdge> edges = new LinkedHashSet<>();
|
||||
private Set<Edge> edges(int count, int feeRate, Pubkey target) {
|
||||
Set<Edge> 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
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Object, Optional<Set<DirectedChannelEdge>>> channelEdgeCache;
|
||||
private final LoadingCache<Object, Optional<Set<Edge>>> channelEdgeCache;
|
||||
private final GrpcPolicy grpcPolicy;
|
||||
|
||||
public GrpcGraph(GrpcService grpcService, GrpcPolicy grpcPolicy) {
|
||||
@@ -33,7 +33,7 @@ public class GrpcGraph {
|
||||
.build(this::getChannelEdgesWithoutCache);
|
||||
}
|
||||
|
||||
public Optional<Set<DirectedChannelEdge>> getChannelEdges() {
|
||||
public Optional<Set<Edge>> getChannelEdges() {
|
||||
return channelEdgeCache.get("");
|
||||
}
|
||||
|
||||
@@ -41,12 +41,12 @@ public class GrpcGraph {
|
||||
channelEdgeCache.invalidateAll();
|
||||
}
|
||||
|
||||
private Optional<Set<DirectedChannelEdge>> getChannelEdgesWithoutCache() {
|
||||
private Optional<Set<Edge>> getChannelEdgesWithoutCache() {
|
||||
ChannelGraph channelGraph = grpcService.describeGraph().orElse(null);
|
||||
if (channelGraph == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
Set<DirectedChannelEdge> channelEdges = new LinkedHashSet<>();
|
||||
Set<Edge> 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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package de.cotto.lndmanagej.model;
|
||||
|
||||
public record DirectedChannelEdge(
|
||||
ChannelId channelId,
|
||||
Coins capacity,
|
||||
Pubkey source,
|
||||
Pubkey target,
|
||||
Policy policy,
|
||||
Policy reversePolicy
|
||||
) {
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
@@ -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<DirectedChannelEdge> channelEdges = grpcGraph.getChannelEdges().orElse(null);
|
||||
Set<Edge> channelEdges = grpcGraph.getChannelEdges().orElse(null);
|
||||
if (channelEdges == null) {
|
||||
logger.error("Unable to get graph");
|
||||
return EdgesWithLiquidityInformation.EMPTY;
|
||||
}
|
||||
Set<EdgeWithLiquidityInformation> edgesWithLiquidityInformation = new LinkedHashSet<>();
|
||||
Pubkey ownPubkey = grpcGetInfo.getPubkey();
|
||||
Set<DirectedChannelEdge> edgesFromPaymentHints = routeHintService.getEdgesFromPaymentHints();
|
||||
for (DirectedChannelEdge channelEdge : Sets.union(channelEdges, edgesFromPaymentHints)) {
|
||||
if (shouldIgnore(channelEdge, paymentOptions, ownPubkey, maximumTimeLockDeltaPerEdge)) {
|
||||
Set<Edge> 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<Coins> getKnownLiquidity(Edge edge, Pubkey ownPubKey) {
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user