Skip to content

Commit f00a9b0

Browse files
committed
Rebuild pending payments list before replaying pending claims/fails
On `ChannelManager` reload we rebuild the pending outbound payments list by looking for any missing payments in `ChannelMonitor`s. However, in the same loop over `ChannelMonitor`s, we also re-claim any pending payments which we see we have a payment preimage for. In theory this can lead to a pending payment getting re-added and re-claimed multiple times if it was sent as an MPP payment across multiple channels. Worse, if it was claimed on one channel and failed on another, in theory we could get both a `PaymentFailed` and a `PaymentClaimed` event on startup for the same payment.
1 parent 07a3a63 commit f00a9b0

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16297,6 +16297,10 @@ where
1629716297
// payments which are still in-flight via their on-chain state.
1629816298
// We only rebuild the pending payments map if we were most recently serialized by
1629916299
// 0.0.102+
16300+
//
16301+
// First we rebuild the pending payments, and only once we do so we go through and
16302+
// re-claim and re-fail pending payments. This avoids edge-cases around MPP payments
16303+
// resulting in redundant actions.
1630016304
for (channel_id, monitor) in args.channel_monitors.iter() {
1630116305
let mut is_channel_closed = false;
1630216306
let counterparty_node_id = monitor.get_counterparty_node_id();
@@ -16335,6 +16339,18 @@ where
1633516339
);
1633616340
}
1633716341
}
16342+
}
16343+
}
16344+
for (channel_id, monitor) in args.channel_monitors.iter() {
16345+
let mut is_channel_closed = false;
16346+
let counterparty_node_id = monitor.get_counterparty_node_id();
16347+
if let Some(peer_state_mtx) = per_peer_state.get(&counterparty_node_id) {
16348+
let mut peer_state_lock = peer_state_mtx.lock().unwrap();
16349+
let peer_state = &mut *peer_state_lock;
16350+
is_channel_closed = !peer_state.channel_by_id.contains_key(channel_id);
16351+
}
16352+
16353+
if is_channel_closed {
1633816354
for (htlc_source, (htlc, preimage_opt)) in
1633916355
monitor.get_all_current_outbound_htlcs()
1634016356
{

0 commit comments

Comments
 (0)