Merge branch 'main' into fix-5746

This commit is contained in:
Carsten Otto
2022-05-22 19:00:24 +02:00
4 changed files with 55 additions and 4 deletions

View File

@@ -73,6 +73,9 @@ public class MultiPathPaymentSplitter {
}
List<Route> routes = getWithLiquidityInformation(extendedBasicRoutes);
List<Route> fixedRoutes = Routes.getFixedWithTotalAmount(routes, amount);
if (fixedRoutes.isEmpty()) {
return MultiPathPayment.FAILURE;
}
if (isTooExpensive(paymentOptions, fixedRoutes)) {
return MultiPathPayment.FAILURE;

View File

@@ -1,6 +1,7 @@
package de.cotto.lndmanagej.pickhardtpayments.model;
import de.cotto.lndmanagej.model.Coins;
import de.cotto.lndmanagej.model.EdgeWithLiquidityInformation;
import de.cotto.lndmanagej.model.Route;
import java.util.ArrayList;
@@ -21,6 +22,24 @@ public final class Routes {
routesCopy.remove(highProbabilityRoute);
Route fixedRoute = highProbabilityRoute.getForAmount(highProbabilityRoute.getAmount().add(remainder));
routesCopy.add(fixedRoute);
if (isAboveAvailableLiquidity(routesCopy)) {
return List.of();
}
return routesCopy;
}
private static boolean isAboveAvailableLiquidity(List<Route> routes) {
for (Route route : routes) {
List<EdgeWithLiquidityInformation> edgesWithLiquidityInformation = route.getEdgesWithLiquidityInformation();
for (int index = 0; index < edgesWithLiquidityInformation.size(); index++) {
EdgeWithLiquidityInformation edge = edgesWithLiquidityInformation.get(index);
Coins requiredAmount = route.getForwardAmountForHop(index);
Coins availableAmountUpperBound = edge.availableLiquidityUpperBound();
if (availableAmountUpperBound.compareTo(requiredAmount) < 0) {
return true;
}
}
}
return false;
}
}

View File

@@ -325,6 +325,20 @@ class MultiPathPaymentSplitterTest {
assertThat(multiPathPayment.routes().iterator().next().getAmount()).isEqualTo(AMOUNT);
}
@Test
void unable_to_add_remainder() {
Coins largeAmount = Coins.ofSatoshis(100_000_000_000L);
when(flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, largeAmount, DEFAULT_PAYMENT_OPTIONS))
.thenReturn(new Flows(FLOW));
MultiPathPayment multiPathPayment = multiPathPaymentSplitter.getMultiPathPayment(
PUBKEY,
PUBKEY_2,
largeAmount,
DEFAULT_PAYMENT_OPTIONS
);
assertThat(multiPathPayment.isFailure()).isTrue();
}
@Test
void adds_hop_if_peer_is_specified_in_payment_options() {
Edge extensionEdge = mockExtensionEdge(PUBKEY_3, 0);
@@ -372,6 +386,7 @@ class MultiPathPaymentSplitterTest {
@Test
void adds_remainder_to_most_probable_route_due_to_liquidity_information() {
Coins oneSat = Coins.ofSatoshis(1);
Coins amount = Coins.ofSatoshis(3);
Coins largeCapacity = Coins.ofSatoshis(10);
Coins smallCapacity = Coins.ofSatoshis(5);
@@ -386,20 +401,20 @@ class MultiPathPaymentSplitterTest {
when(edgeComputation.getEdgeWithLiquidityInformation(edgeSmallCapacity))
.thenReturn(liquidityInformationSmall);
when(flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, AMOUNT, DEFAULT_PAYMENT_OPTIONS))
when(flowComputation.getOptimalFlows(PUBKEY, PUBKEY_2, amount, DEFAULT_PAYMENT_OPTIONS))
.thenReturn(new Flows(
new Flow(edgeLargeCapacity, oneSat),
new Flow(edgeSmallCapacity, oneSat)
));
assumeThat(FLOW.amount()).isLessThan(AMOUNT);
assumeThat(FLOW.amount()).isLessThan(amount);
MultiPathPayment multiPathPayment = multiPathPaymentSplitter.getMultiPathPayment(
PUBKEY,
PUBKEY_2,
AMOUNT,
amount,
DEFAULT_PAYMENT_OPTIONS
);
Route route1 = new Route(List.of(liquidityInformationLarge), oneSat);
Route route2 = new Route(List.of(liquidityInformationSmall), AMOUNT.subtract(oneSat));
Route route2 = new Route(List.of(liquidityInformationSmall), amount.subtract(oneSat));
assertThat(multiPathPayment.routes()).containsExactlyInAnyOrder(route1, route2);
}

View File

@@ -3,6 +3,7 @@ package de.cotto.lndmanagej.pickhardtpayments.model;
import de.cotto.lndmanagej.model.BasicRoute;
import de.cotto.lndmanagej.model.Coins;
import de.cotto.lndmanagej.model.Edge;
import de.cotto.lndmanagej.model.EdgeWithLiquidityInformation;
import de.cotto.lndmanagej.model.Route;
import org.junit.jupiter.api.Test;
@@ -53,4 +54,17 @@ class RoutesTest {
new Route(basicRoute3)
);
}
@Test
void getFixedWithTotalAmount_does_not_add_if_amount_exceeds_available_balance() {
Edge edge = new Edge(CHANNEL_ID, PUBKEY, PUBKEY_2, CAPACITY, POLICY_1);
EdgeWithLiquidityInformation withLiquidityInformation =
EdgeWithLiquidityInformation.forKnownLiquidity(edge, Coins.ofSatoshis(199));
List<Route> routes = List.of(new Route(List.of(withLiquidityInformation), Coins.ofSatoshis(150)));
List<Route> fixedRoutes = Routes.getFixedWithTotalAmount(routes, Coins.ofSatoshis(200));
assertThat(fixedRoutes).isEmpty();
}
}