Skip to content

Commit d62eb7a

Browse files
committed
disable mpp flags in invoice creation if jit channel is required, check against available liquidity if we need a jit channel
1 parent 4917f7e commit d62eb7a

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

electrum/lnpeer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,7 @@ def log_fail_reason(reason: str):
18701870
next_chan = self.lnworker.get_channel_by_short_id(next_chan_scid)
18711871

18721872
if self.lnworker.features.supports(LnFeatures.OPTION_ZEROCONF_OPT):
1873-
next_peer = self.lnworker.get_peer_by_scid_alias(next_chan_scid)
1873+
next_peer = self.lnworker.get_peer_by_static_jit_scid_alias(next_chan_scid)
18741874
else:
18751875
next_peer = None
18761876

electrum/lnworker.py

+27-8
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@ async def handle_onchain_state(self, chan: Channel):
11521152
self.logger.info('REBROADCASTING CLOSING TX')
11531153
await self.network.try_broadcasting(force_close_tx, 'force-close')
11541154

1155-
def get_peer_by_scid_alias(self, scid_alias: bytes) -> Optional[Peer]:
1155+
def get_peer_by_static_jit_scid_alias(self, scid_alias: bytes) -> Optional[Peer]:
11561156
for nodeid, peer in self.peers.items():
11571157
if scid_alias == self._scid_alias_of_node(nodeid):
11581158
return peer
@@ -1161,7 +1161,7 @@ def _scid_alias_of_node(self, nodeid: bytes) -> bytes:
11611161
# scid alias for just-in-time channels
11621162
return sha256(b'Electrum' + nodeid)[0:8]
11631163

1164-
def get_scid_alias(self) -> bytes:
1164+
def get_static_jit_scid_alias(self) -> bytes:
11651165
return self._scid_alias_of_node(self.node_keypair.pubkey)
11661166

11671167
@log_exceptions
@@ -2112,11 +2112,15 @@ def get_bolt11_invoice(
21122112

21132113
assert amount_msat is None or amount_msat > 0
21142114
timestamp = int(time.time())
2115-
routing_hints = self.calc_routing_hints_for_invoice(amount_msat, channels=channels)
2116-
self.logger.info(f"creating bolt11 invoice with routing_hints: {routing_hints}")
2115+
needs_jit: bool = self.receive_requires_jit_channel(amount_msat)
2116+
routing_hints = self.calc_routing_hints_for_invoice(amount_msat, channels=channels, needs_jit=needs_jit)
2117+
self.logger.info(f"creating bolt11 invoice with routing_hints: {routing_hints}, jit: {needs_jit}")
21172118
invoice_features = self.features.for_invoice()
21182119
if not self.uses_trampoline():
21192120
invoice_features &= ~ LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM
2121+
if needs_jit:
2122+
# jit only works with single htlcs, mpp will cause LSP to open channels for each htlc
2123+
invoice_features &= ~ LnFeatures.BASIC_MPP_OPT & ~ LnFeatures.BASIC_MPP_REQ
21202124
payment_secret = self.get_payment_secret(payment_hash)
21212125
amount_btc = amount_msat/Decimal(COIN*1000) if amount_msat else None
21222126
if expiry == 0:
@@ -2505,14 +2509,14 @@ def htlc_failed(
25052509
else:
25062510
self.logger.info(f"waiting for other htlcs to fail (phash={payment_hash.hex()})")
25072511

2508-
def calc_routing_hints_for_invoice(self, amount_msat: Optional[int], channels=None):
2512+
def calc_routing_hints_for_invoice(self, amount_msat: Optional[int], channels=None, needs_jit=False):
25092513
"""calculate routing hints (BOLT-11 'r' field)"""
25102514
routing_hints = []
2511-
if self.config.ZEROCONF_TRUSTED_NODE:
2515+
if needs_jit:
25122516
node_id, rest = extract_nodeid(self.config.ZEROCONF_TRUSTED_NODE)
2513-
alias_or_scid = self.get_scid_alias()
2517+
alias_or_scid = self.get_static_jit_scid_alias()
25142518
routing_hints.append(('r', [(node_id, alias_or_scid, 0, 0, 144)]))
2515-
# no need for more
2519+
# no need for more because we cannot receive enough through the others and mpp is disabled for jit
25162520
channels = []
25172521
else:
25182522
if channels is None:
@@ -2665,6 +2669,21 @@ def recv_capacity(chan):
26652669
can_receive_msat = max(recv_chan_msats)
26662670
return Decimal(can_receive_msat) / 1000
26672671

2672+
def receive_requires_jit_channel(self, amount_msat: Optional[int]) -> bool:
2673+
"""Returns true if we cannot receive the amount and have set up a trusted LSP node.
2674+
Cannot work reliably with 0 amount invoices as we don't know if we are able to receive it.
2675+
"""
2676+
# a trusted zeroconf node is configured
2677+
if (self.config.ZEROCONF_TRUSTED_NODE
2678+
# the zeroconf node is a peer, it doesn't make sense to request a channel from an offline LSP
2679+
and extract_nodeid(self.config.ZEROCONF_TRUSTED_NODE)[0] in self.peers
2680+
# we cannot receive the amount specified
2681+
and ((amount_msat and self.num_sats_can_receive() < (amount_msat // 1000))
2682+
# or we cannot receive anything, and it's a 0 amount invoice
2683+
or (not amount_msat and self.num_sats_can_receive() < 1))):
2684+
return True
2685+
return False
2686+
26682687
def _suggest_channels_for_rebalance(self, direction, amount_sat) -> Sequence[Tuple[Channel, int]]:
26692688
"""
26702689
Suggest a channel and amount to send/receive with that channel, so that we will be able to receive/send amount_sat

0 commit comments

Comments
 (0)