Manual capture: a hold failed back at its claim deadline stays Pending forever #21
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
LDK Node fails a held (manual-claim) payment back at its claim deadline, but leaves the inbound payment record
Pending; it never becomesFailed. satsettle treats onlyFailedas proof that a hold is gone. So a hold that passed its deadline:authorizations()as funded (hold_statusreturnsPending);capture_paymentcallsBolt11ClaimForId, which returns OK without funds becauseclaim_fundsis a no-op. The status staysPendingandclaim()returnsUnavailableforever.The README tells applications to keep their reservation "until the selected intent is definitively Failed", so the resource (for example a username) stays reserved permanently.
Evidence
179b4b2(behind LDK Server21a903c):LdkEvent::HTLCHandlingFailedis only passed to the LSPS2 service, and no code path marks the inbound paymentFailedwhen held HTLCs time out atclaim_deadline. The same is true atf375e4d(LDK Server08316de).Bolt11Payment::claim_for_idchecks only the stored record, preimage and amount beforechannel_manager.claim_funds(preimage), which does nothing when the HTLCs are gone.payments:claimreserved a name; the payer's HTLC was failed back after mining past the deadline (the payer sawFailed). The receiving node's record stayedPendingindefinitely.satsettle at
1e9e7230f3storesAuthorization::claim_deadlinebut never compares it with the node's block height.Suggested fix
GetNodeInfo, permissionnode:read) is at or past itsclaim_deadline. Inauthorizations(), exclude it and mark it failed. Incapture_paymentand recovery, mark itFailedinstead of retrying. Claiming "will necessarily fail after the claim_deadline has been reached", per LDK Node's docs.ListPaymentscatch-up, where there's no event and so no deadline, use a conservative bound such as the current height plus LDK's maximum HTLC lock (2016 blocks). Or refuse to authorize payments whose invoice is already past its payment window, since their funds may already be gone.node:readto the documented macaroon permissions.npub.cash does the first and second; its regtest end-to-end check covers a claim released after mining past the deadline.