diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py index d37f39881..1080c54c4 100644 --- a/electrum/lnchannel.py +++ b/electrum/lnchannel.py @@ -41,7 +41,7 @@ from .bitcoin import redeem_script_to_address from .crypto import sha256, sha256d from .transaction import Transaction, PartialTransaction, TxInput, Sighash from .logging import Logger -from .lnonion import decode_onion_error, OnionFailureCode, OnionRoutingFailure +from .lnonion import OnionFailureCode, OnionRoutingFailure from . import lnutil from .lnutil import (Outpoint, LocalConfig, RemoteConfig, Keypair, OnlyPubkeyKeypair, ChannelConstraints, get_per_commitment_secret_from_seed, secret_to_pubkey, derive_privkey, make_closing_tx, @@ -704,8 +704,8 @@ class Channel(AbstractChannel): def set_onion_key(self, key: int, value: bytes): self.onion_keys[key] = value - def get_onion_key(self, key: int) -> bytes: - return self.onion_keys.get(key) + def pop_onion_key(self, key: int) -> bytes: + return self.onion_keys.pop(key) def set_data_loss_protect_remote_pcp(self, key, value): self.data_loss_protect_remote_pcp[key] = value @@ -1437,14 +1437,6 @@ class Channel(AbstractChannel): htlc = self.hm.get_htlc_by_id(LOCAL, htlc_id) return htlc.payment_hash - def decode_onion_error(self, reason: bytes, route: Sequence['RouteEdge'], - htlc_id: int) -> Tuple[OnionRoutingFailure, int]: - failure_msg, sender_idx = decode_onion_error( - reason, - [x.node_id for x in route], - self.onion_keys[htlc_id]) - return failure_msg, sender_idx - def receive_htlc_settle(self, preimage: bytes, htlc_id: int) -> None: """Settle/fulfill a pending offered HTLC. Action must be initiated by REMOTE. diff --git a/electrum/lnworker.py b/electrum/lnworker.py index a6cf3f88c..98b520271 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -68,7 +68,7 @@ from .lnutil import (Outpoint, LNPeerAddr, NoPathFound, InvalidGossipMsg) from .lnutil import ln_compare_features, IncompatibleLightningFeatures from .transaction import PartialTxOutput, PartialTransaction, PartialTxInput -from .lnonion import OnionFailureCode, OnionRoutingFailure, OnionPacket +from .lnonion import decode_onion_error, OnionFailureCode, OnionRoutingFailure, OnionPacket from .lnmsg import decode_msg from .i18n import _ from .lnrouter import (RouteEdge, LNPaymentRoute, LNPaymentPath, is_route_sane_to_use, @@ -2274,6 +2274,7 @@ class LNWallet(LNWorker): self._on_maybe_forwarded_htlc_resolved(chan=chan, htlc_id=htlc_id) q = None if shi := self.sent_htlcs_info.get((payment_hash, chan.short_channel_id, htlc_id)): + chan.pop_onion_key(htlc_id) payment_key = payment_hash + shi.payment_secret_orig paysession = self._paysessions.get(payment_key) if paysession: @@ -2304,6 +2305,7 @@ class LNWallet(LNWorker): self._on_maybe_forwarded_htlc_resolved(chan=chan, htlc_id=htlc_id) q = None if shi := self.sent_htlcs_info.get((payment_hash, chan.short_channel_id, htlc_id)): + onion_key = chan.pop_onion_key(htlc_id) payment_okey = payment_hash + shi.payment_secret_orig paysession = self._paysessions.get(payment_okey) if paysession: @@ -2316,7 +2318,10 @@ class LNWallet(LNWorker): if error_bytes: # TODO "decode_onion_error" might raise, catch and maybe blacklist/penalise someone? try: - failure_message, sender_idx = chan.decode_onion_error(error_bytes, route, htlc_id) + failure_message, sender_idx = decode_onion_error( + error_bytes, + [x.node_id for x in route], + onion_key) except Exception as e: sender_idx = None failure_message = OnionRoutingFailure(-1, str(e))