Browse Source

If trampoline is enabled, do not add non-trampoline nodes to invoices

Rationale: The sender should not assume that they share the same list of
hardcoded trampolines as the receiver.
master
ThomasV 2 years ago
parent
commit
120faa480e
  1. 3
      electrum/gui/messages.py
  2. 15
      electrum/gui/qt/channels_list.py
  3. 2
      electrum/lnchannel.py
  4. 2
      electrum/lnworker.py
  5. 2
      electrum/trampoline.py

3
electrum/gui/messages.py

@ -41,7 +41,6 @@ MSG_CAPITAL_GAINS = _(
)
MSG_NON_TRAMPOLINE_CHANNEL_FROZEN_WITHOUT_GOSSIP = _(
"""Trampoline routing is enabled, but this channel is with a non-trampoline node.
This channel may still be used for receiving, but it is frozen for sending.
"""This channel is with a non-trampoline node; it cannot be used if trampoline is enabled.
If you want to keep using this channel, you need to disable trampoline routing in your preferences."""
)

15
electrum/gui/qt/channels_list.py

@ -193,9 +193,12 @@ class ChannelsList(MyTreeView):
return self.network.run_from_another_thread(coro)
WaitingDialog(self, 'please wait..', task, self.on_request_sent, self.on_failure)
def freeze_channel_for_sending(self, chan, b):
def set_frozen(self, chan, *, for_sending, value):
if not self.lnworker.uses_trampoline() or self.lnworker.is_trampoline_peer(chan.node_id):
chan.set_frozen_for_sending(b)
if for_sending:
chan.set_frozen_for_sending(value)
else:
chan.set_frozen_for_receiving(value)
else:
msg = messages.MSG_NON_TRAMPOLINE_CHANNEL_FROZEN_WITHOUT_GOSSIP
self.main_window.show_warning(msg, title=_('Channel is frozen for sending'))
@ -258,13 +261,13 @@ class ChannelsList(MyTreeView):
if not chan.is_backup() and not chan.is_closed():
fm = menu.addMenu(_("Freeze"))
if not chan.is_frozen_for_sending():
fm.addAction(_("Freeze for sending"), lambda: self.freeze_channel_for_sending(chan, True))
fm.addAction(_("Freeze for sending"), lambda: self.set_frozen(chan, for_sending=True, value=True))
else:
fm.addAction(_("Unfreeze for sending"), lambda: self.freeze_channel_for_sending(chan, False))
fm.addAction(_("Unfreeze for sending"), lambda: self.set_frozen(chan, for_sending=True, value=False))
if not chan.is_frozen_for_receiving():
fm.addAction(_("Freeze for receiving"), lambda: chan.set_frozen_for_receiving(True))
fm.addAction(_("Freeze for receiving"), lambda: self.set_frozen(chan, for_sending=False, value=True))
else:
fm.addAction(_("Unfreeze for receiving"), lambda: chan.set_frozen_for_receiving(False))
fm.addAction(_("Unfreeze for receiving"), lambda: self.set_frozen(chan, for_sending=False, value=False))
if close_opts := chan.get_close_options():
cm = menu.addMenu(_("Close"))
if ChanCloseOption.COOP_CLOSE in close_opts:

2
electrum/lnchannel.py

@ -921,6 +921,8 @@ class Channel(AbstractChannel):
util.trigger_callback('channel', self.lnworker.wallet, self)
def is_frozen_for_receiving(self) -> bool:
if self.lnworker and self.lnworker.uses_trampoline() and not self.lnworker.is_trampoline_peer(self.node_id):
return True
return self.storage.get('frozen_for_receiving', False)
def set_frozen_for_receiving(self, b: bool) -> None:

2
electrum/lnworker.py

@ -2068,6 +2068,8 @@ class LNWallet(LNWorker):
routing_hints = self.calc_routing_hints_for_invoice(amount_msat, channels=channels)
self.logger.info(f"creating bolt11 invoice with routing_hints: {routing_hints}")
invoice_features = self.features.for_invoice()
if not self.uses_trampoline():
invoice_features &= ~ LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM
payment_secret = self.get_payment_secret(payment_hash)
amount_btc = amount_msat/Decimal(COIN*1000) if amount_msat else None
if expiry == 0:

2
electrum/trampoline.py

@ -143,7 +143,7 @@ def is_legacy_relay(invoice_features, r_tags) -> Tuple[bool, Set[bytes]]:
# endpoints connected to T1 and T2, and sender only has send-capacity with T1, while
# recipient only has recv-capacity with T2.
singlehop_r_tags = [x for x in r_tags if len(x) == 1]
invoice_trampolines = [x[0][0] for x in singlehop_r_tags if is_hardcoded_trampoline(x[0][0])]
invoice_trampolines = [x[0][0] for x in singlehop_r_tags]
invoice_trampolines = set(invoice_trampolines)
if invoice_trampolines:
return False, invoice_trampolines

Loading…
Cancel
Save