From 32aa6ab20cb7b23a67e9a10b3d9da0cf90542973 Mon Sep 17 00:00:00 2001 From: f321x Date: Tue, 16 Sep 2025 10:52:26 +0200 Subject: [PATCH] lnutil: rename RecvMPPResolution.ACCEPTED Renames RecvMPPResolution.ACCEPTED to .COMPLETE as .ACCEPTED is somewhat misleading. Accepted could imply that the preimage for this set has been revealed or that the set has been settled, however it only means that we have received the full set (it is complete), but the set still can be failed (e.g. through cltv timeout) and has not been claimed yet. --- electrum/commands.py | 12 ++++++------ electrum/lnpeer.py | 2 +- electrum/lnsweep.py | 4 ++-- electrum/lnutil.py | 2 +- electrum/lnworker.py | 8 ++++---- tests/test_commands.py | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/electrum/commands.py b/electrum/commands.py index 6ee60d139..09bc31a14 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -1438,7 +1438,7 @@ class Commands(Logger): assert payment_hash in wallet.lnworker.payment_info, \ f"Couldn't find lightning invoice for {payment_hash=}" assert payment_hash in wallet.lnworker.dont_settle_htlcs, f"Invoice {payment_hash=} not a hold invoice?" - assert wallet.lnworker.is_accepted_mpp(bfh(payment_hash)), \ + assert wallet.lnworker.is_complete_mpp(bfh(payment_hash)), \ f"MPP incomplete, cannot settle hold invoice {payment_hash} yet" info: Optional['PaymentInfo'] = wallet.lnworker.get_payment_info(bfh(payment_hash)) assert (wallet.lnworker.get_payment_mpp_amount_msat(bfh(payment_hash)) or 0) >= (info.amount_msat or 0) @@ -1465,7 +1465,7 @@ class Commands(Logger): wallet.lnworker.set_payment_status(bfh(payment_hash), PR_UNPAID) wallet.lnworker.delete_payment_info(payment_hash) wallet.set_label(payment_hash, None) - while wallet.lnworker.is_accepted_mpp(bfh(payment_hash)): + while wallet.lnworker.is_complete_mpp(bfh(payment_hash)): # wait until the htlcs got failed so the payment won't get settled accidentally in a race await asyncio.sleep(0.1) del wallet.lnworker.dont_settle_htlcs[payment_hash] @@ -1490,7 +1490,7 @@ class Commands(Logger): """ assert len(payment_hash) == 64, f"Invalid payment_hash length: {len(payment_hash)} != 64" info: Optional['PaymentInfo'] = wallet.lnworker.get_payment_info(bfh(payment_hash)) - is_accepted_mpp: bool = wallet.lnworker.is_accepted_mpp(bfh(payment_hash)) + is_complete_mpp: bool = wallet.lnworker.is_complete_mpp(bfh(payment_hash)) amount_sat = (wallet.lnworker.get_payment_mpp_amount_msat(bfh(payment_hash)) or 0) // 1000 result = { "status": "unknown", @@ -1498,10 +1498,10 @@ class Commands(Logger): } if info is None: pass - elif not is_accepted_mpp and not wallet.lnworker.get_preimage_hex(payment_hash): - # is_accepted_mpp is False for settled payments + elif not is_complete_mpp and not wallet.lnworker.get_preimage_hex(payment_hash): + # is_complete_mpp is False for settled payments result["status"] = "unpaid" - elif is_accepted_mpp and payment_hash in wallet.lnworker.dont_settle_htlcs: + elif is_complete_mpp and payment_hash in wallet.lnworker.dont_settle_htlcs: result["status"] = "paid" payment_key: str = wallet.lnworker._get_payment_key(bfh(payment_hash)).hex() htlc_status = wallet.lnworker.received_mpp_htlcs[payment_key] diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py index 01eeddd6c..48b442693 100644 --- a/electrum/lnpeer.py +++ b/electrum/lnpeer.py @@ -2480,7 +2480,7 @@ class Peer(Logger, EventListener): elif mpp_resolution == RecvMPPResolution.FAILED: log_fail_reason(f"mpp_resolution is FAILED") raise exc_incorrect_or_unknown_pd - elif mpp_resolution == RecvMPPResolution.ACCEPTED: + elif mpp_resolution == RecvMPPResolution.COMPLETE: return False else: raise Exception(f"unexpected {mpp_resolution=}") diff --git a/electrum/lnsweep.py b/electrum/lnsweep.py index c7170e1e9..f63064162 100644 --- a/electrum/lnsweep.py +++ b/electrum/lnsweep.py @@ -432,7 +432,7 @@ def sweep_our_ctx( ctn=ctn) for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items(): if direction == RECEIVED: - if not chan.lnworker.is_accepted_mpp(htlc.payment_hash): + if not chan.lnworker.is_complete_mpp(htlc.payment_hash): # do not redeem this, it might publish the preimage of an incomplete MPP continue preimage = chan.lnworker.get_preimage(htlc.payment_hash) @@ -727,7 +727,7 @@ def sweep_their_ctx( for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items(): is_received_htlc = direction == RECEIVED if not is_received_htlc and not is_revocation: - if not chan.lnworker.is_accepted_mpp(htlc.payment_hash): + if not chan.lnworker.is_complete_mpp(htlc.payment_hash): # do not redeem this, it might publish the preimage of an incomplete MPP continue preimage = chan.lnworker.get_preimage(htlc.payment_hash) diff --git a/electrum/lnutil.py b/electrum/lnutil.py index c750c15ed..025cc9ad8 100644 --- a/electrum/lnutil.py +++ b/electrum/lnutil.py @@ -1935,7 +1935,7 @@ class UpdateAddHtlc: class RecvMPPResolution(IntEnum): WAITING = 0 EXPIRED = 1 - ACCEPTED = 2 + COMPLETE = 2 FAILED = 3 diff --git a/electrum/lnworker.py b/electrum/lnworker.py index fe217cb01..98bd12988 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -2444,12 +2444,12 @@ class LNWallet(LNWorker): payment_keys = [payment_key] first_timestamp = min([self.get_first_timestamp_of_mpp(pkey) for pkey in payment_keys]) if self.get_payment_status(payment_hash) == PR_PAID: - mpp_resolution = RecvMPPResolution.ACCEPTED + mpp_resolution = RecvMPPResolution.COMPLETE elif self.stopping_soon: # try to time out pending HTLCs before shutting down mpp_resolution = RecvMPPResolution.EXPIRED elif all([self.is_mpp_amount_reached(pkey) for pkey in payment_keys]): - mpp_resolution = RecvMPPResolution.ACCEPTED + mpp_resolution = RecvMPPResolution.COMPLETE elif time.time() - first_timestamp > self.MPP_EXPIRY: mpp_resolution = RecvMPPResolution.EXPIRED # save resolution, if any. @@ -2497,10 +2497,10 @@ class LNWallet(LNWorker): total, expected = amounts return total >= expected - def is_accepted_mpp(self, payment_hash: bytes) -> bool: + def is_complete_mpp(self, payment_hash: bytes) -> bool: payment_key = self._get_payment_key(payment_hash) status = self.received_mpp_htlcs.get(payment_key.hex()) - return status and status.resolution == RecvMPPResolution.ACCEPTED + return status and status.resolution == RecvMPPResolution.COMPLETE def get_payment_mpp_amount_msat(self, payment_hash: bytes) -> Optional[int]: """Returns the received mpp amount for given payment hash.""" diff --git a/tests/test_commands.py b/tests/test_commands.py index f1169ec40..ccd052b38 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -547,7 +547,7 @@ class TestCommandsTestnet(ElectrumTestCase): mock_htlc2.amount_msat = 5_500_000 mock_htlc_status = mock.Mock() mock_htlc_status.htlc_set = [(None, mock_htlc1), (None, mock_htlc2)] - mock_htlc_status.resolution = RecvMPPResolution.ACCEPTED + mock_htlc_status.resolution = RecvMPPResolution.COMPLETE payment_key = wallet.lnworker._get_payment_key(bytes.fromhex(payment_hash)).hex() with mock.patch.dict(wallet.lnworker.received_mpp_htlcs, {payment_key: mock_htlc_status}):