Skip to content

Commit dc1664a

Browse files
joostjagerclaude
andcommitted
Re-claim inbound payments when preimage is already known
When a PaymentClaimable event arrives for a payment already marked as Succeeded or Spontaneous in the payment store, re-claim using the stored preimage instead of failing the HTLC backwards. This prevents fund loss in scenarios where the channel monitor state was not yet persisted (e.g. with deferred monitor writes) but the payment store already recorded the claim as successful. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9b8d2aa commit dc1664a

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

src/event.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,26 @@ where
673673
if info.status == PaymentStatus::Succeeded
674674
|| matches!(info.kind, PaymentKind::Spontaneous { .. })
675675
{
676+
let stored_preimage = match info.kind {
677+
PaymentKind::Bolt11 { preimage, .. }
678+
| PaymentKind::Bolt11Jit { preimage, .. }
679+
| PaymentKind::Bolt12Offer { preimage, .. }
680+
| PaymentKind::Bolt12Refund { preimage, .. }
681+
| PaymentKind::Spontaneous { preimage, .. } => preimage,
682+
_ => None,
683+
};
684+
685+
if let Some(preimage) = stored_preimage {
686+
log_info!(
687+
self.logger,
688+
"Re-claiming previously succeeded payment with hash {} of {}msat",
689+
hex_utils::to_string(&payment_hash.0),
690+
amount_msat,
691+
);
692+
self.channel_manager.claim_funds(preimage);
693+
return Ok(());
694+
}
695+
676696
log_info!(
677697
self.logger,
678698
"Refused duplicate inbound payment from payment hash {} of {}msat",

0 commit comments

Comments
 (0)