Skip to content

Commit 220a51d

Browse files
committed
Provide a redundant Event::PaymentClaimed on restart if needed
If we crashed during a payment claim and then detected a partial claim on restart, we should ensure the user is aware that the payment has been claimed. We do so here by using the new partial-claim detection logic to create a `PaymentClaimed` event.
1 parent 5aba1b7 commit 220a51d

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6837,9 +6837,12 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
68376837

68386838
for (_, monitor) in args.channel_monitors.iter() {
68396839
for (payment_hash, payment_preimage) in monitor.get_stored_preimages() {
6840-
if let Some(claimable_htlcs) = claimable_htlcs.remove(&payment_hash) {
6840+
if let Some((payment_purpose, claimable_htlcs)) = claimable_htlcs.remove(&payment_hash) {
68416841
log_info!(args.logger, "Re-claiming HTLCs with payment hash {} as we've released the preimage to a ChannelMonitor!", log_bytes!(payment_hash.0));
6842-
for claimable_htlc in claimable_htlcs.1 {
6842+
let mut claimable_amt_msat = 0;
6843+
for claimable_htlc in claimable_htlcs {
6844+
claimable_amt_msat += claimable_htlc.value;
6845+
68436846
// Add a holding-cell claim of the payment to the Channel, which should be
68446847
// applied ~immediately on peer reconnection. Because it won't generate a
68456848
// new commitment transaction we can just provide the payment preimage to
@@ -6863,6 +6866,11 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
68636866
previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &args.fee_estimator, &args.logger);
68646867
}
68656868
}
6869+
pending_events_read.push(events::Event::PaymentClaimed {
6870+
payment_hash,
6871+
purpose: payment_purpose,
6872+
amt: claimable_amt_msat,
6873+
});
68666874
}
68676875
}
68686876
}

lightning/src/ln/functional_tests.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9881,6 +9881,9 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
98819881
// To get to the correct state, on startup we should propagate the preimage to the
98829882
// still-off-chain channel, claiming the HTLC as soon as the peer connects, with the monitor
98839883
// receiving the preimage without a state update.
9884+
//
9885+
// Further, we should generate a `PaymentClaimed` event to inform the user that the payment was
9886+
// definitely claimed.
98849887
let chanmon_cfgs = create_chanmon_cfgs(4);
98859888
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
98869889
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
@@ -9998,13 +10001,19 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
999810001
// commitment transaction. We should also still have the original PaymentReceived event we
999910002
// never finished processing.
1000010003
let events = nodes[3].node.get_and_clear_pending_events();
10001-
assert_eq!(events.len(), if persist_both_monitors { 3 } else { 2 });
10004+
assert_eq!(events.len(), if persist_both_monitors { 4 } else { 3 });
1000210005
if let Event::PaymentReceived { amt: 15_000_000, .. } = events[0] { } else { panic!(); }
1000310006
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[1] { } else { panic!(); }
1000410007
if persist_both_monitors {
1000510008
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[2] { } else { panic!(); }
1000610009
}
1000710010

10011+
// On restart, we should also get a duplicate PaymentClaimed event as we persisted the
10012+
// ChannelManager prior to handling the original one.
10013+
if let Event::PaymentClaimed { payment_hash: our_payment_hash, amt: 15_000_000, .. } = events[if persist_both_monitors { 3 } else { 2 }] {
10014+
assert_eq!(payment_hash, our_payment_hash);
10015+
} else { panic!(); }
10016+
1000810017
assert_eq!(nodes[3].node.list_channels().len(), if persist_both_monitors { 0 } else { 1 });
1000910018
if !persist_both_monitors {
1001010019
// If one of the two channels is still live, reveal the payment preimage over it.

0 commit comments

Comments
 (0)