mirror of
https://github.com/aljazceru/lnd-manageJ.git
synced 2026-01-27 09:54:51 +01:00
top-up: impose stricter fee limit for all hops (but not the ones from the top-up peer)
This commit is contained in:
@@ -9,6 +9,7 @@ import de.cotto.lndmanagej.model.EdgeWithLiquidityInformation;
|
||||
import de.cotto.lndmanagej.model.Node;
|
||||
import de.cotto.lndmanagej.model.Policy;
|
||||
import de.cotto.lndmanagej.model.Pubkey;
|
||||
import de.cotto.lndmanagej.pickhardtpayments.model.PaymentOptions;
|
||||
import de.cotto.lndmanagej.service.BalanceService;
|
||||
import de.cotto.lndmanagej.service.ChannelService;
|
||||
import de.cotto.lndmanagej.service.LiquidityBoundsService;
|
||||
@@ -37,6 +38,7 @@ import static de.cotto.lndmanagej.model.PolicyFixtures.POLICY_WITH_BASE_FEE;
|
||||
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_4;
|
||||
import static de.cotto.lndmanagej.pickhardtpayments.model.PaymentOptions.DEFAULT_PAYMENT_OPTIONS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
@@ -79,23 +81,24 @@ class EdgeComputationTest {
|
||||
|
||||
@Test
|
||||
void no_graph() {
|
||||
assertThat(edgeComputation.getEdges().edges()).isEmpty();
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void does_not_add_edge_for_disabled_channel() {
|
||||
DirectedChannelEdge edge = new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, POLICY_DISABLED);
|
||||
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge)));
|
||||
assertThat(edgeComputation.getEdges().edges()).isEmpty();
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void does_not_add_edge_with_fee_rate_at_or_above_limit() {
|
||||
int feeRateLimit = 199;
|
||||
Policy policyExpensive = new Policy(200, Coins.NONE, true, 40, Coins.ofSatoshis(0));
|
||||
PaymentOptions paymentOptions = PaymentOptions.forFeeRateLimit(feeRateLimit);
|
||||
Policy policyExpensive = policy(200);
|
||||
// needs to be excluded to avoid sending top-up payments in a tiny loop: S-X-S
|
||||
Policy policyAtLimit = new Policy(199, Coins.NONE, true, 40, Coins.ofSatoshis(0));
|
||||
Policy policyOk = new Policy(198, Coins.NONE, true, 40, Coins.ofSatoshis(0));
|
||||
Policy policyAtLimit = policy(199);
|
||||
Policy policyOk = policy(198);
|
||||
DirectedChannelEdge edgeExpensive =
|
||||
new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, policyExpensive);
|
||||
DirectedChannelEdge edgeAtLimit =
|
||||
@@ -103,8 +106,33 @@ class EdgeComputationTest {
|
||||
DirectedChannelEdge edgeOk =
|
||||
new DirectedChannelEdge(CHANNEL_ID_3, CAPACITY, PUBKEY, PUBKEY_2, policyOk);
|
||||
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edgeExpensive, edgeAtLimit, edgeOk)));
|
||||
assertThat(edgeComputation.getEdges(feeRateLimit).edges().stream().map(EdgeWithLiquidityInformation::channelId))
|
||||
.containsExactly(CHANNEL_ID_3);
|
||||
assertThat(
|
||||
edgeComputation.getEdges(paymentOptions).edges().stream().map(EdgeWithLiquidityInformation::channelId)
|
||||
).containsExactly(CHANNEL_ID_3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void does_not_add_first_hop_edge_with_fee_rate_at_or_above_limit_for_first_hops() {
|
||||
Pubkey ownPubkey = EDGE.startNode();
|
||||
Pubkey topUpPeer = PUBKEY_4;
|
||||
int feeRateLimit = 200;
|
||||
int feeRateLimitForFirstHops = 100;
|
||||
|
||||
when(grpcGetInfo.getPubkey()).thenReturn(ownPubkey);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRateLimit, feeRateLimitForFirstHops, topUpPeer);
|
||||
Policy lastHopPolicy = policy(199);
|
||||
Policy firstHopPolicyExpensive = policy(100);
|
||||
Policy firstHopPolicyOk = policy(99);
|
||||
DirectedChannelEdge lastHop =
|
||||
new DirectedChannelEdge(CHANNEL_ID, CAPACITY, topUpPeer, ownPubkey, lastHopPolicy);
|
||||
DirectedChannelEdge firstHopExpensive =
|
||||
new DirectedChannelEdge(CHANNEL_ID_2, CAPACITY, ownPubkey, PUBKEY_2, firstHopPolicyExpensive);
|
||||
DirectedChannelEdge firstHopOk =
|
||||
new DirectedChannelEdge(CHANNEL_ID_3, CAPACITY, ownPubkey, PUBKEY_2, firstHopPolicyOk);
|
||||
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(lastHop, firstHopExpensive, firstHopOk)));
|
||||
assertThat(
|
||||
edgeComputation.getEdges(paymentOptions).edges().stream().map(EdgeWithLiquidityInformation::channelId)
|
||||
).containsExactlyInAnyOrder(CHANNEL_ID, CHANNEL_ID_3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,7 +140,7 @@ class EdgeComputationTest {
|
||||
DirectedChannelEdge edge =
|
||||
new DirectedChannelEdge(CHANNEL_ID, CAPACITY, PUBKEY, PUBKEY_2, POLICY_WITH_BASE_FEE);
|
||||
when(grpcGraph.getChannelEdges()).thenReturn(Optional.of(Set.of(edge)));
|
||||
assertThat(edgeComputation.getEdges().edges()).isNotEmpty();
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -124,7 +152,7 @@ class EdgeComputationTest {
|
||||
Coins availableKnownLiquidity = getAvailableKnownLiquidity(knownLiquidity);
|
||||
when(balanceService.getAvailableLocalBalance(EDGE.channelId())).thenReturn(knownLiquidity);
|
||||
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forKnownLiquidity(EDGE, availableKnownLiquidity));
|
||||
}
|
||||
|
||||
@@ -143,7 +171,7 @@ class EdgeComputationTest {
|
||||
edge.policy()
|
||||
)
|
||||
));
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forKnownLiquidity(edge, fiftyCoins));
|
||||
}
|
||||
|
||||
@@ -152,7 +180,7 @@ class EdgeComputationTest {
|
||||
mockEdge();
|
||||
when(grpcGetInfo.getPubkey()).thenReturn(EDGE.startNode());
|
||||
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forKnownLiquidity(EDGE, Coins.NONE));
|
||||
}
|
||||
|
||||
@@ -162,7 +190,7 @@ class EdgeComputationTest {
|
||||
mockOfflinePeer();
|
||||
when(grpcGetInfo.getPubkey()).thenReturn(EDGE.startNode());
|
||||
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forKnownLiquidity(EDGE, Coins.NONE));
|
||||
verify(balanceService, never()).getAvailableLocalBalance(EDGE.channelId());
|
||||
}
|
||||
@@ -176,7 +204,7 @@ class EdgeComputationTest {
|
||||
Coins availableKnownLiquidity = getAvailableKnownLiquidity(knownLiquidity);
|
||||
when(balanceService.getAvailableRemoteBalance(EDGE.channelId())).thenReturn(knownLiquidity);
|
||||
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forKnownLiquidity(EDGE, availableKnownLiquidity));
|
||||
}
|
||||
|
||||
@@ -185,7 +213,7 @@ class EdgeComputationTest {
|
||||
mockEdge();
|
||||
when(grpcGetInfo.getPubkey()).thenReturn(EDGE.endNode());
|
||||
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forKnownLiquidity(EDGE, Coins.NONE));
|
||||
}
|
||||
|
||||
@@ -195,7 +223,7 @@ class EdgeComputationTest {
|
||||
mockOfflinePeer();
|
||||
when(grpcGetInfo.getPubkey()).thenReturn(EDGE.endNode());
|
||||
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forKnownLiquidity(EDGE, Coins.NONE));
|
||||
verify(balanceService, never()).getAvailableLocalBalance(EDGE.channelId());
|
||||
}
|
||||
@@ -211,14 +239,14 @@ class EdgeComputationTest {
|
||||
mockEdge();
|
||||
Coins upperBound = Coins.ofSatoshis(100);
|
||||
mockUpperBound(upperBound);
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forUpperBound(EDGE, upperBound));
|
||||
}
|
||||
|
||||
@Test
|
||||
void default_if_no_liquidity_information_is_known() {
|
||||
mockEdge();
|
||||
assertThat(edgeComputation.getEdges().edges())
|
||||
assertThat(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS).edges())
|
||||
.contains(EdgeWithLiquidityInformation.forUpperBound(EDGE, EDGE.capacity()));
|
||||
}
|
||||
|
||||
@@ -321,4 +349,8 @@ class EdgeComputationTest {
|
||||
Coins withOnChainReserve = withFeeReserve.subtract(Coins.ofSatoshis(1_000));
|
||||
return withOnChainReserve.maximum(Coins.NONE);
|
||||
}
|
||||
|
||||
private static Policy policy(int feeRate) {
|
||||
return new Policy(feeRate, Coins.NONE, true, 40, Coins.ofSatoshis(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_3;
|
||||
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_4;
|
||||
import static de.cotto.lndmanagej.pickhardtpayments.model.PaymentOptions.DEFAULT_PAYMENT_OPTIONS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -62,23 +61,24 @@ class FlowComputationTest {
|
||||
|
||||
@Test
|
||||
void solve_no_edge() {
|
||||
when(edgeComputation.getEdges()).thenReturn(EdgesWithLiquidityInformation.EMPTY);
|
||||
when(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS)).thenReturn(EdgesWithLiquidityInformation.EMPTY);
|
||||
assertThat(flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, Coins.ofSatoshis(1), DEFAULT_PAYMENT_OPTIONS))
|
||||
.isEqualTo(new Flows());
|
||||
}
|
||||
|
||||
@Test
|
||||
void passes_fee_rate_limit_to_get_edges() {
|
||||
when(edgeComputation.getEdges(anyLong())).thenReturn(EdgesWithLiquidityInformation.EMPTY);
|
||||
flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, Coins.ofSatoshis(1), PaymentOptions.forFeeRateLimit(123));
|
||||
verify(edgeComputation).getEdges(123);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forFeeRateLimit(123);
|
||||
when(edgeComputation.getEdges(paymentOptions)).thenReturn(EdgesWithLiquidityInformation.EMPTY);
|
||||
flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, Coins.ofSatoshis(1), paymentOptions);
|
||||
verify(edgeComputation).getEdges(paymentOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
void solve() {
|
||||
Coins amount = Coins.ofSatoshis(1);
|
||||
EdgeWithLiquidityInformation edge = EdgeWithLiquidityInformation.forUpperBound(EDGE, EDGE.capacity());
|
||||
when(edgeComputation.getEdges()).thenReturn(new EdgesWithLiquidityInformation(edge));
|
||||
when(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS)).thenReturn(new EdgesWithLiquidityInformation(edge));
|
||||
Flow expectedFlow = new Flow(EDGE, amount);
|
||||
assertThat(flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, amount, DEFAULT_PAYMENT_OPTIONS))
|
||||
.isEqualTo(new Flows(expectedFlow));
|
||||
@@ -89,7 +89,7 @@ class FlowComputationTest {
|
||||
when(configurationService.getIntegerValue(QUANTIZATION)).thenReturn(Optional.of(10));
|
||||
Coins amount = Coins.ofSatoshis(9);
|
||||
EdgeWithLiquidityInformation edge = EdgeWithLiquidityInformation.forUpperBound(EDGE, EDGE.capacity());
|
||||
when(edgeComputation.getEdges()).thenReturn(new EdgesWithLiquidityInformation(edge));
|
||||
when(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS)).thenReturn(new EdgesWithLiquidityInformation(edge));
|
||||
assertThat(flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, amount, DEFAULT_PAYMENT_OPTIONS))
|
||||
.isEqualTo(new Flows(new Flow(EDGE, amount)));
|
||||
}
|
||||
@@ -98,7 +98,7 @@ class FlowComputationTest {
|
||||
void solve_avoids_sending_from_depleted_local_channel() {
|
||||
Edge edge1 = new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, LARGE, POLICY_1);
|
||||
Edge edge2 = new Edge(CHANNEL_ID_2, PUBKEY, PUBKEY_2, SMALL, POLICY_2);
|
||||
when(edgeComputation.getEdges()).thenReturn(new EdgesWithLiquidityInformation(
|
||||
when(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS)).thenReturn(new EdgesWithLiquidityInformation(
|
||||
EdgeWithLiquidityInformation.forKnownLiquidity(edge1, Coins.NONE),
|
||||
EdgeWithLiquidityInformation.forUpperBound(edge2, SMALL)
|
||||
));
|
||||
@@ -114,7 +114,7 @@ class FlowComputationTest {
|
||||
Edge edge1a = new Edge(CHANNEL_ID, PUBKEY_2, PUBKEY_3, LARGE, POLICY_1);
|
||||
Edge edge1b = new Edge(CHANNEL_ID_2, PUBKEY_3, PUBKEY_4, LARGE, POLICY_1);
|
||||
Edge edge2 = new Edge(CHANNEL_ID_3, PUBKEY_2, PUBKEY_4, SMALL, POLICY_2);
|
||||
when(edgeComputation.getEdges()).thenReturn(new EdgesWithLiquidityInformation(
|
||||
when(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS)).thenReturn(new EdgesWithLiquidityInformation(
|
||||
EdgeWithLiquidityInformation.forUpperBound(edge1a, amount),
|
||||
EdgeWithLiquidityInformation.forUpperBound(edge1b, LARGE),
|
||||
EdgeWithLiquidityInformation.forUpperBound(edge2, SMALL)
|
||||
@@ -130,7 +130,7 @@ class FlowComputationTest {
|
||||
Edge edge1a = new Edge(CHANNEL_ID, PUBKEY_3, PUBKEY_4, LARGE, POLICY_2);
|
||||
Edge edge1b = new Edge(CHANNEL_ID_2, PUBKEY_4, PUBKEY, LARGE, POLICY_2);
|
||||
Edge edge2 = new Edge(CHANNEL_ID_3, PUBKEY_3, PUBKEY, SMALL, POLICY_1);
|
||||
when(edgeComputation.getEdges()).thenReturn(new EdgesWithLiquidityInformation(
|
||||
when(edgeComputation.getEdges(DEFAULT_PAYMENT_OPTIONS)).thenReturn(new EdgesWithLiquidityInformation(
|
||||
EdgeWithLiquidityInformation.forUpperBound(edge1a, Coins.ofSatoshis(5_000_000)),
|
||||
EdgeWithLiquidityInformation.forUpperBound(edge1b, LARGE),
|
||||
EdgeWithLiquidityInformation.forUpperBound(edge2, SMALL)
|
||||
|
||||
@@ -123,7 +123,7 @@ class MultiPathPaymentSplitterTest {
|
||||
int feeRate = 200;
|
||||
Coins amount = Coins.ofSatoshis(1_000_000);
|
||||
Policy policy = policyFor(feeRate);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate - 1, PUBKEY_2);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate - 1, 0, PUBKEY_2);
|
||||
mockFlow(amount, policy, paymentOptions);
|
||||
|
||||
MultiPathPayment multiPathPayment =
|
||||
@@ -137,7 +137,7 @@ class MultiPathPaymentSplitterTest {
|
||||
int feeRate = 200;
|
||||
Coins amount = Coins.ofSatoshis(2_000_000);
|
||||
Policy policy = policyFor(feeRate);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate, PUBKEY_2);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate, 0, PUBKEY_2);
|
||||
mockFlow(amount, policy, paymentOptions);
|
||||
|
||||
MultiPathPayment multiPathPayment =
|
||||
@@ -151,7 +151,7 @@ class MultiPathPaymentSplitterTest {
|
||||
mockExtensionEdge(PUBKEY_3, feeRate);
|
||||
Coins amount = Coins.ofSatoshis(2_000_000);
|
||||
Policy policy = policyFor(0);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate - 1, PUBKEY_2);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate - 1, 0, PUBKEY_2);
|
||||
mockFlow(amount, policy, paymentOptions);
|
||||
|
||||
MultiPathPayment multiPathPayment =
|
||||
@@ -197,11 +197,13 @@ class MultiPathPaymentSplitterTest {
|
||||
|
||||
@Test
|
||||
void one_flow_has_fee_rate_above_limit_but_average_fee_rate_is_below_limit_including_fees_from_first_hop() {
|
||||
// The cheaper flows might fail while the more expensive one settles. This is not what we want, so we have
|
||||
// to disregard all flows.
|
||||
mockExtensionEdge(PUBKEY_4, 0);
|
||||
int feeRate = 200;
|
||||
Coins halfOfAmount = Coins.ofSatoshis(500_000);
|
||||
Coins amount = halfOfAmount.add(halfOfAmount);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate - 1, PUBKEY_2);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(feeRate - 1, 0, PUBKEY_2);
|
||||
Edge edge1 = new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policyFor(0));
|
||||
Edge edge2 = new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, policyFor(feeRate));
|
||||
Flow flow1 = new Flow(edge1, halfOfAmount);
|
||||
@@ -348,7 +350,7 @@ class MultiPathPaymentSplitterTest {
|
||||
}
|
||||
|
||||
private MultiPathPayment attemptTopUpPayment() {
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(500, PUBKEY_2);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(500, 123, PUBKEY_2);
|
||||
when(flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, AMOUNT, paymentOptions)).thenReturn(new Flows(FLOW));
|
||||
return multiPathPaymentSplitter.getMultiPathPayment(PUBKEY, PUBKEY_3, AMOUNT, paymentOptions);
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ class TopUpServiceTest {
|
||||
private void assertTopUp(Coins expectedTopUpAmount, Duration expiry) {
|
||||
PaymentStatus paymentStatus = topUpService.topUp(PUBKEY, AMOUNT);
|
||||
verify(grpcInvoices).createPaymentRequest(expectedTopUpAmount, DESCRIPTION, expiry);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(OUR_FEE_RATE, PUBKEY);
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(OUR_FEE_RATE, PEER_FEE_RATE, PUBKEY);
|
||||
verify(multiPathPaymentSender).payPaymentRequest(DECODED_PAYMENT_REQUEST, paymentOptions);
|
||||
assertThat(paymentStatus.isPending()).isTrue();
|
||||
}
|
||||
|
||||
@@ -12,19 +12,25 @@ class PaymentOptionsTest {
|
||||
@Test
|
||||
void forFeeRateWeight() {
|
||||
assertThat(PaymentOptions.forFeeRateWeight(12))
|
||||
.isEqualTo(new PaymentOptions(12, Optional.empty(), true, Optional.empty()));
|
||||
.isEqualTo(new PaymentOptions(12, Optional.empty(), Optional.empty(), true, Optional.empty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forFeeRateLimit() {
|
||||
assertThat(PaymentOptions.forFeeRateLimit(123))
|
||||
.isEqualTo(new PaymentOptions(0, Optional.of(123L), true, Optional.empty()));
|
||||
.isEqualTo(new PaymentOptions(0, Optional.of(123L), Optional.of(123L), true, Optional.empty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forTopUp() {
|
||||
assertThat(PaymentOptions.forTopUp(123, PUBKEY))
|
||||
.isEqualTo(new PaymentOptions(5, Optional.of(123L), false, Optional.of(PUBKEY)));
|
||||
assertThat(PaymentOptions.forTopUp(123, 100, PUBKEY))
|
||||
.isEqualTo(new PaymentOptions(5, Optional.of(123L), Optional.of(23L), false, Optional.of(PUBKEY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void feeRateLimitFirstHops() {
|
||||
PaymentOptions paymentOptions = PaymentOptions.forTopUp(200, 30, PUBKEY);
|
||||
assertThat(paymentOptions.feeRateLimitExceptIncomingHops()).contains(170L);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user