Skip to content

Commit c725a29

Browse files
authored
Merge pull request #9466 from f321x/improved_trampoline_error
Separate between fee related NoPathFound and other causes when doing lightning payments/forwards
2 parents 8ac27ba + 5eb9aa0 commit c725a29

File tree

4 files changed

+22
-10
lines changed

4 files changed

+22
-10
lines changed

electrum/lnpeer.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
ln_compare_features, MIN_FINAL_CLTV_DELTA_ACCEPTED,
4545
RemoteMisbehaving, ShortChannelID,
4646
IncompatibleLightningFeatures, derive_payment_secret_from_payment_preimage,
47-
ChannelType, LNProtocolWarning, validate_features, IncompatibleOrInsaneFeatures)
47+
ChannelType, LNProtocolWarning, validate_features,
48+
IncompatibleOrInsaneFeatures, FeeBudgetExceeded)
4849
from .lnutil import FeeUpdate, channel_id_from_funding_tx, PaymentFeeBudget
4950
from .lnutil import serialize_htlc_key, Keypair
5051
from .lntransport import LNTransport, LNTransportBase, LightningPeerConnectionClosed, HandshakeFailed
@@ -2063,11 +2064,12 @@ async def maybe_forward_trampoline(
20632064
)
20642065
except OnionRoutingFailure as e:
20652066
raise
2067+
except FeeBudgetExceeded:
2068+
raise OnionRoutingFailure(code=OnionFailureCode.TRAMPOLINE_FEE_INSUFFICIENT, data=b'')
20662069
except PaymentFailure as e:
20672070
self.logger.debug(
20682071
f"maybe_forward_trampoline. PaymentFailure for {payment_hash.hex()=}, {payment_secret.hex()=}: {e!r}")
2069-
# FIXME: adapt the error code
2070-
raise OnionRoutingFailure(code=OnionFailureCode.TRAMPOLINE_FEE_INSUFFICIENT, data=b'')
2072+
raise OnionRoutingFailure(code=OnionFailureCode.UNKNOWN_NEXT_PEER, data=b'')
20712073

20722074
def _maybe_refuse_to_forward_htlc_that_corresponds_to_payreq_we_created(self, payment_hash: bytes) -> bool:
20732075
"""Returns True if the HTLC should be failed.

electrum/lnutil.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,9 @@ class PaymentFailure(UserFacingException): pass
452452
class NoPathFound(PaymentFailure):
453453
def __str__(self):
454454
return _('No path found')
455+
class FeeBudgetExceeded(PaymentFailure):
456+
def __str__(self):
457+
return _('Fee budget exceeded')
455458

456459

457460
class LNProtocolError(Exception):

electrum/lnworker.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
NUM_MAX_EDGES_IN_PAYMENT_PATH, SENT, RECEIVED, HTLCOwner,
6868
UpdateAddHtlc, Direction, LnFeatures, ShortChannelID,
6969
HtlcLog, derive_payment_secret_from_payment_preimage,
70-
NoPathFound, InvalidGossipMsg)
70+
NoPathFound, InvalidGossipMsg, FeeBudgetExceeded)
7171
from .lnutil import ln_compare_features, IncompatibleLightningFeatures, PaymentFeeBudget
7272
from .transaction import PartialTxOutput, PartialTransaction, PartialTxInput
7373
from .lnonion import decode_onion_error, OnionFailureCode, OnionRoutingFailure, OnionPacket
@@ -1880,6 +1880,7 @@ async def create_routes_for_payment(
18801880
and mpp is supported by the receiver, we will split the payment."""
18811881
trampoline_features = LnFeatures.VAR_ONION_OPT
18821882
local_height = self.network.get_local_height()
1883+
fee_related_error = None # type: Optional[FeeBudgetExceeded]
18831884
if channels:
18841885
my_active_channels = channels
18851886
else:
@@ -1970,8 +1971,9 @@ async def create_routes_for_payment(
19701971
)
19711972
routes.append((shi, per_trampoline_cltv_delta, trampoline_onion))
19721973
if per_trampoline_fees != 0:
1973-
self.logger.info('not enough margin to pay trampoline fee')
1974-
raise NoPathFound()
1974+
e = 'not enough margin to pay trampoline fee'
1975+
self.logger.info(e)
1976+
raise FeeBudgetExceeded(e)
19751977
else:
19761978
# We atomically loop through a split configuration. If there was
19771979
# a failure to find a path for a single part, we try the next configuration
@@ -2004,9 +2006,14 @@ async def create_routes_for_payment(
20042006
routes.append((shi, paysession.min_final_cltv_delta, fwd_trampoline_onion))
20052007
except NoPathFound:
20062008
continue
2009+
except FeeBudgetExceeded as e:
2010+
fee_related_error = e
2011+
continue
20072012
for route in routes:
20082013
yield route
20092014
return
2015+
if fee_related_error is not None:
2016+
raise fee_related_error
20102017
raise NoPathFound()
20112018

20122019
@profiler
@@ -2079,7 +2086,7 @@ def create_route_for_single_htlc(
20792086
route, budget=budget, amount_msat_for_dest=amount_msat, cltv_delta_for_dest=min_final_cltv_delta,
20802087
):
20812088
self.logger.info(f"rejecting route (exceeds budget): {route=}. {budget=}")
2082-
raise NoPathFound()
2089+
raise FeeBudgetExceeded()
20832090
assert len(route) > 0
20842091
if route[-1].end_node != invoice_pubkey:
20852092
raise LNPathInconsistent("last node_id != invoice pubkey")

electrum/trampoline.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import random
44
from typing import Mapping, DefaultDict, Tuple, Optional, Dict, List, Iterable, Sequence, Set, Any
55

6-
from .lnutil import LnFeatures, PaymentFeeBudget
6+
from .lnutil import LnFeatures, PaymentFeeBudget, FeeBudgetExceeded
77
from .lnonion import calc_hops_data_for_payment, new_onion_packet, OnionPacket
88
from .lnrouter import RouteEdge, TrampolineEdge, LNPaymentRoute, is_route_within_budget, LNPaymentTRoute
99
from .lnutil import NoPathFound
@@ -161,7 +161,7 @@ def _allocate_fee_along_route(
161161
assert trampoline_fee_level > 0
162162
MAX_LEVEL = 6
163163
if trampoline_fee_level > MAX_LEVEL:
164-
raise NoPathFound()
164+
raise FeeBudgetExceeded("highest trampoline fee level reached")
165165
budget_to_use = budget.fee_msat // (2 ** (MAX_LEVEL - trampoline_fee_level))
166166
_logger.debug(f"_allocate_fee_along_route(). {trampoline_fee_level=}, {budget.fee_msat=}, {budget_to_use=}")
167167
# replace placeholder fees
@@ -264,7 +264,7 @@ def create_trampoline_route(
264264
amount_msat_for_dest=amount_msat,
265265
cltv_delta_for_dest=min_final_cltv_delta,
266266
):
267-
raise NoPathFound("route exceeds budget")
267+
raise FeeBudgetExceeded(f"route exceeds budget: budget: {budget}")
268268
return route
269269

270270

0 commit comments

Comments
 (0)