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.
for (_, monitor) in args.channel_monitors.iter() {
for (payment_hash, payment_preimage) in monitor.get_stored_preimages() {
for (_, monitor) in args.channel_monitors.iter() {
for (payment_hash, payment_preimage) in monitor.get_stored_preimages() {
- if let Some(claimable_htlcs) = claimable_htlcs.remove(&payment_hash) {
+ if let Some((payment_purpose, claimable_htlcs)) = claimable_htlcs.remove(&payment_hash) {
log_info!(args.logger, "Re-claiming HTLCs with payment hash {} as we've released the preimage to a ChannelMonitor!", log_bytes!(payment_hash.0));
log_info!(args.logger, "Re-claiming HTLCs with payment hash {} as we've released the preimage to a ChannelMonitor!", log_bytes!(payment_hash.0));
- for claimable_htlc in claimable_htlcs.1 {
+ let mut claimable_amt_msat = 0;
+ for claimable_htlc in claimable_htlcs {
+ claimable_amt_msat += claimable_htlc.value;
+
// Add a holding-cell claim of the payment to the Channel, which should be
// applied ~immediately on peer reconnection. Because it won't generate a
// new commitment transaction we can just provide the payment preimage to
// Add a holding-cell claim of the payment to the Channel, which should be
// applied ~immediately on peer reconnection. Because it won't generate a
// new commitment transaction we can just provide the payment preimage to
previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &args.fee_estimator, &args.logger);
}
}
previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &args.fee_estimator, &args.logger);
}
}
+ pending_events_read.push(events::Event::PaymentClaimed {
+ payment_hash,
+ purpose: payment_purpose,
+ amt: claimable_amt_msat,
+ });
// To get to the correct state, on startup we should propagate the preimage to the
// still-off-chain channel, claiming the HTLC as soon as the peer connects, with the monitor
// receiving the preimage without a state update.
// To get to the correct state, on startup we should propagate the preimage to the
// still-off-chain channel, claiming the HTLC as soon as the peer connects, with the monitor
// receiving the preimage without a state update.
+ //
+ // Further, we should generate a `PaymentClaimed` event to inform the user that the payment was
+ // definitely claimed.
let chanmon_cfgs = create_chanmon_cfgs(4);
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
let chanmon_cfgs = create_chanmon_cfgs(4);
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
// commitment transaction. We should also still have the original PaymentReceived event we
// never finished processing.
let events = nodes[3].node.get_and_clear_pending_events();
// commitment transaction. We should also still have the original PaymentReceived event we
// never finished processing.
let events = nodes[3].node.get_and_clear_pending_events();
- assert_eq!(events.len(), if persist_both_monitors { 3 } else { 2 });
+ assert_eq!(events.len(), if persist_both_monitors { 4 } else { 3 });
if let Event::PaymentReceived { amt: 15_000_000, .. } = events[0] { } else { panic!(); }
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[1] { } else { panic!(); }
if persist_both_monitors {
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[2] { } else { panic!(); }
}
if let Event::PaymentReceived { amt: 15_000_000, .. } = events[0] { } else { panic!(); }
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[1] { } else { panic!(); }
if persist_both_monitors {
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[2] { } else { panic!(); }
}
+ // On restart, we should also get a duplicate PaymentClaimed event as we persisted the
+ // ChannelManager prior to handling the original one.
+ if let Event::PaymentClaimed { payment_hash: our_payment_hash, amt: 15_000_000, .. } = events[if persist_both_monitors { 3 } else { 2 }] {
+ assert_eq!(payment_hash, our_payment_hash);
+ } else { panic!(); }
+
assert_eq!(nodes[3].node.list_channels().len(), if persist_both_monitors { 0 } else { 1 });
if !persist_both_monitors {
// If one of the two channels is still live, reveal the payment preimage over it.
assert_eq!(nodes[3].node.list_channels().len(), if persist_both_monitors { 0 } else { 1 });
if !persist_both_monitors {
// If one of the two channels is still live, reveal the payment preimage over it.