1
0

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.
This commit is contained in:
f321x
2025-09-16 10:52:26 +02:00
committed by SomberNight
parent 6a4ad9e67c
commit 32aa6ab20c
6 changed files with 15 additions and 15 deletions

View File

@@ -1438,7 +1438,7 @@ class Commands(Logger):
assert payment_hash in wallet.lnworker.payment_info, \ assert payment_hash in wallet.lnworker.payment_info, \
f"Couldn't find lightning invoice for {payment_hash=}" 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 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" f"MPP incomplete, cannot settle hold invoice {payment_hash} yet"
info: Optional['PaymentInfo'] = wallet.lnworker.get_payment_info(bfh(payment_hash)) 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) 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.set_payment_status(bfh(payment_hash), PR_UNPAID)
wallet.lnworker.delete_payment_info(payment_hash) wallet.lnworker.delete_payment_info(payment_hash)
wallet.set_label(payment_hash, None) 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 # wait until the htlcs got failed so the payment won't get settled accidentally in a race
await asyncio.sleep(0.1) await asyncio.sleep(0.1)
del wallet.lnworker.dont_settle_htlcs[payment_hash] 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" 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)) 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 amount_sat = (wallet.lnworker.get_payment_mpp_amount_msat(bfh(payment_hash)) or 0) // 1000
result = { result = {
"status": "unknown", "status": "unknown",
@@ -1498,10 +1498,10 @@ class Commands(Logger):
} }
if info is None: if info is None:
pass pass
elif not is_accepted_mpp and not wallet.lnworker.get_preimage_hex(payment_hash): elif not is_complete_mpp and not wallet.lnworker.get_preimage_hex(payment_hash):
# is_accepted_mpp is False for settled payments # is_complete_mpp is False for settled payments
result["status"] = "unpaid" 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" result["status"] = "paid"
payment_key: str = wallet.lnworker._get_payment_key(bfh(payment_hash)).hex() payment_key: str = wallet.lnworker._get_payment_key(bfh(payment_hash)).hex()
htlc_status = wallet.lnworker.received_mpp_htlcs[payment_key] htlc_status = wallet.lnworker.received_mpp_htlcs[payment_key]

View File

@@ -2480,7 +2480,7 @@ class Peer(Logger, EventListener):
elif mpp_resolution == RecvMPPResolution.FAILED: elif mpp_resolution == RecvMPPResolution.FAILED:
log_fail_reason(f"mpp_resolution is FAILED") log_fail_reason(f"mpp_resolution is FAILED")
raise exc_incorrect_or_unknown_pd raise exc_incorrect_or_unknown_pd
elif mpp_resolution == RecvMPPResolution.ACCEPTED: elif mpp_resolution == RecvMPPResolution.COMPLETE:
return False return False
else: else:
raise Exception(f"unexpected {mpp_resolution=}") raise Exception(f"unexpected {mpp_resolution=}")

View File

@@ -432,7 +432,7 @@ def sweep_our_ctx(
ctn=ctn) ctn=ctn)
for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items(): for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items():
if direction == RECEIVED: 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 # do not redeem this, it might publish the preimage of an incomplete MPP
continue continue
preimage = chan.lnworker.get_preimage(htlc.payment_hash) 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(): for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items():
is_received_htlc = direction == RECEIVED is_received_htlc = direction == RECEIVED
if not is_received_htlc and not is_revocation: 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 # do not redeem this, it might publish the preimage of an incomplete MPP
continue continue
preimage = chan.lnworker.get_preimage(htlc.payment_hash) preimage = chan.lnworker.get_preimage(htlc.payment_hash)

View File

@@ -1935,7 +1935,7 @@ class UpdateAddHtlc:
class RecvMPPResolution(IntEnum): class RecvMPPResolution(IntEnum):
WAITING = 0 WAITING = 0
EXPIRED = 1 EXPIRED = 1
ACCEPTED = 2 COMPLETE = 2
FAILED = 3 FAILED = 3

View File

@@ -2444,12 +2444,12 @@ class LNWallet(LNWorker):
payment_keys = [payment_key] payment_keys = [payment_key]
first_timestamp = min([self.get_first_timestamp_of_mpp(pkey) for pkey in payment_keys]) first_timestamp = min([self.get_first_timestamp_of_mpp(pkey) for pkey in payment_keys])
if self.get_payment_status(payment_hash) == PR_PAID: if self.get_payment_status(payment_hash) == PR_PAID:
mpp_resolution = RecvMPPResolution.ACCEPTED mpp_resolution = RecvMPPResolution.COMPLETE
elif self.stopping_soon: elif self.stopping_soon:
# try to time out pending HTLCs before shutting down # try to time out pending HTLCs before shutting down
mpp_resolution = RecvMPPResolution.EXPIRED mpp_resolution = RecvMPPResolution.EXPIRED
elif all([self.is_mpp_amount_reached(pkey) for pkey in payment_keys]): 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: elif time.time() - first_timestamp > self.MPP_EXPIRY:
mpp_resolution = RecvMPPResolution.EXPIRED mpp_resolution = RecvMPPResolution.EXPIRED
# save resolution, if any. # save resolution, if any.
@@ -2497,10 +2497,10 @@ class LNWallet(LNWorker):
total, expected = amounts total, expected = amounts
return total >= expected 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) payment_key = self._get_payment_key(payment_hash)
status = self.received_mpp_htlcs.get(payment_key.hex()) 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]: def get_payment_mpp_amount_msat(self, payment_hash: bytes) -> Optional[int]:
"""Returns the received mpp amount for given payment hash.""" """Returns the received mpp amount for given payment hash."""

View File

@@ -547,7 +547,7 @@ class TestCommandsTestnet(ElectrumTestCase):
mock_htlc2.amount_msat = 5_500_000 mock_htlc2.amount_msat = 5_500_000
mock_htlc_status = mock.Mock() mock_htlc_status = mock.Mock()
mock_htlc_status.htlc_set = [(None, mock_htlc1), (None, mock_htlc2)] 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() 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}): with mock.patch.dict(wallet.lnworker.received_mpp_htlcs, {payment_key: mock_htlc_status}):