From 72ac35405c94084164c697f54e990c547393722d Mon Sep 17 00:00:00 2001 From: lollerfirst <43107113+lollerfirst@users.noreply.github.com> Date: Thu, 6 Mar 2025 00:05:13 +0100 Subject: [PATCH] [NUT-15] LND: Try Multiple Routes (#692) * try multiple routes * fix * Lnd gRPC --- cashu/lightning/lnd_grpc/lnd_grpc.py | 33 ++++++++++++++----------- cashu/lightning/lndrest.py | 37 +++++++++++++++++----------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/cashu/lightning/lnd_grpc/lnd_grpc.py b/cashu/lightning/lnd_grpc/lnd_grpc.py index b961c56..2a3af2e 100644 --- a/cashu/lightning/lnd_grpc/lnd_grpc.py +++ b/cashu/lightning/lnd_grpc/lnd_grpc.py @@ -245,21 +245,26 @@ class LndRPCWallet(LightningBackend): ) """ # modify the mpp_record in the last hop - route_nr = 0 - r.routes[route_nr].hops[-1].mpp_record.payment_addr = bytes.fromhex( # type: ignore - payer_addr - ) - r.routes[route_nr].hops[ # type: ignore - -1 - ].mpp_record.total_amt_msat = total_amount_msat - - # Send to route request - r = await router_stub.SendToRouteV2( - routerrpc.SendToRouteRequest( - payment_hash=bytes.fromhex(invoice.payment_hash), - route=r.routes[route_nr], # type: ignore + for route_nr in range(len(r.routes)): + r.routes[route_nr].hops[-1].mpp_record.payment_addr = bytes.fromhex( # type: ignore + payer_addr ) - ) + r.routes[route_nr].hops[ # type: ignore + -1 + ].mpp_record.total_amt_msat = total_amount_msat + + # Send to route request + r = await router_stub.SendToRouteV2( + routerrpc.SendToRouteRequest( + payment_hash=bytes.fromhex(invoice.payment_hash), + route=r.routes[route_nr], # type: ignore + ) + ) + if r.status == lnrpc.HTLCAttempt.HTLCStatus.FAILED: + if r.failure.code == lnrpc.Failure.FailureCode.TEMPORARY_CHANNEL_FAILURE: + # Try a different route + continue + break except AioRpcError as e: logger.error(f"QueryRoute or SendToRouteV2 failed: {e}") return PaymentResponse( diff --git a/cashu/lightning/lndrest.py b/cashu/lightning/lndrest.py index 1baa556..2579590 100644 --- a/cashu/lightning/lndrest.py +++ b/cashu/lightning/lndrest.py @@ -259,22 +259,31 @@ class LndRestWallet(LightningBackend): } # add the mpp_record to the last hop - rout_nr = 0 - data["routes"][rout_nr]["hops"][-1].update(mpp_record) + r = None # type: ignore + for route_nr in range(len(data["routes"])): + logger.debug(f"Trying to pay partial amount with route number {route_nr+1}") + data["routes"][route_nr]["hops"][-1].update(mpp_record) - # send to route - r = await self.client.post( - url="/v2/router/route/send", - json={ - "payment_hash": base64.b64encode( - bytes.fromhex(invoice.payment_hash) - ).decode(), - "route": data["routes"][rout_nr], - }, - timeout=None, - ) + # send to route + r = await self.client.post( + url="/v2/router/route/send", + json={ + "payment_hash": base64.b64encode( + bytes.fromhex(invoice.payment_hash) + ).decode(), + "route": data["routes"][route_nr], + }, + timeout=None, + ) + + data = r.json() + failure = data.get("failure") + if failure: + if failure["code"] == 15: + # Try with a different route + continue + break - data = r.json() if r.is_error or data.get("message"): error_message = data.get("message") or r.text return PaymentResponse(