Skip to content

Commit 5eb9aa0

Browse files
f321xf321x
authored andcommitted
change to separate exception class for too low fees
store exception in variable instead of using a bool flag add default str to routing exceptions Add separate exception class to handle fee related payment errors
1 parent 41e3214 commit 5eb9aa0

File tree

4 files changed

+22
-22
lines changed

4 files changed

+22
-22
lines changed

electrum/lnpeer.py

Lines changed: 4 additions & 6 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, NoPathFound)
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,8 @@ async def maybe_forward_trampoline(
20632064
)
20642065
except OnionRoutingFailure as e:
20652066
raise
2066-
except NoPathFound as e:
2067-
failure_code = (OnionFailureCode.TRAMPOLINE_FEE_INSUFFICIENT
2068-
if e.maybe_fee_related
2069-
else OnionFailureCode.UNKNOWN_NEXT_PEER)
2070-
raise OnionRoutingFailure(code=failure_code, data=b'')
2067+
except FeeBudgetExceeded:
2068+
raise OnionRoutingFailure(code=OnionFailureCode.TRAMPOLINE_FEE_INSUFFICIENT, data=b'')
20712069
except PaymentFailure as e:
20722070
self.logger.debug(
20732071
f"maybe_forward_trampoline. PaymentFailure for {payment_hash.hex()=}, {payment_secret.hex()=}: {e!r}")

electrum/lnutil.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -450,13 +450,11 @@ class InvalidGossipMsg(Exception):
450450

451451
class PaymentFailure(UserFacingException): pass
452452
class NoPathFound(PaymentFailure):
453-
def __init__(self, message: Optional[str] = None, *, maybe_fee_related: Optional[bool] = False):
454-
self.maybe_fee_related = maybe_fee_related
455-
self._message = message
456-
super().__init__(message)
457-
458453
def __str__(self):
459-
return self._message or _('No path found')
454+
return _('No path found')
455+
class FeeBudgetExceeded(PaymentFailure):
456+
def __str__(self):
457+
return _('Fee budget exceeded')
460458

461459

462460
class LNProtocolError(Exception):

electrum/lnworker.py

Lines changed: 11 additions & 7 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,7 +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 = False
1883+
fee_related_error = None # type: Optional[FeeBudgetExceeded]
18841884
if channels:
18851885
my_active_channels = channels
18861886
else:
@@ -1973,7 +1973,7 @@ async def create_routes_for_payment(
19731973
if per_trampoline_fees != 0:
19741974
e = 'not enough margin to pay trampoline fee'
19751975
self.logger.info(e)
1976-
raise NoPathFound(e, maybe_fee_related=True)
1976+
raise FeeBudgetExceeded(e)
19771977
else:
19781978
# We atomically loop through a split configuration. If there was
19791979
# a failure to find a path for a single part, we try the next configuration
@@ -2004,13 +2004,17 @@ async def create_routes_for_payment(
20042004
trampoline_route=None,
20052005
)
20062006
routes.append((shi, paysession.min_final_cltv_delta, fwd_trampoline_onion))
2007-
except NoPathFound as e:
2008-
fee_related_error = e.maybe_fee_related
2007+
except NoPathFound:
2008+
continue
2009+
except FeeBudgetExceeded as e:
2010+
fee_related_error = e
20092011
continue
20102012
for route in routes:
20112013
yield route
20122014
return
2013-
raise NoPathFound(maybe_fee_related=fee_related_error)
2015+
if fee_related_error is not None:
2016+
raise fee_related_error
2017+
raise NoPathFound()
20142018

20152019
@profiler
20162020
def create_route_for_single_htlc(
@@ -2082,7 +2086,7 @@ def create_route_for_single_htlc(
20822086
route, budget=budget, amount_msat_for_dest=amount_msat, cltv_delta_for_dest=min_final_cltv_delta,
20832087
):
20842088
self.logger.info(f"rejecting route (exceeds budget): {route=}. {budget=}")
2085-
raise NoPathFound(maybe_fee_related=True)
2089+
raise FeeBudgetExceeded()
20862090
assert len(route) > 0
20872091
if route[-1].end_node != invoice_pubkey:
20882092
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("highest trampoline fee level reached", maybe_fee_related=True)
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", maybe_fee_related=True)
267+
raise FeeBudgetExceeded(f"route exceeds budget: budget: {budget}")
268268
return route
269269

270270

0 commit comments

Comments
 (0)