Skip to content

Commit 8106dbf

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. If we send an MPP payment across different chanels, the result may be that we'll iterate the loop, and in each iteration add a pending payment with only one known path, then claim/fail it and remove the pending apyment (at least for the claim case). This may result in spurious extra events, or even both a `PaymentFailed` and `PaymentSent` event on startup for the same payment.
1 parent a8ec966 commit 8106dbf

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16451,6 +16451,9 @@ where
1645116451
// payments which are still in-flight via their on-chain state.
1645216452
// We only rebuild the pending payments map if we were most recently serialized by
1645316453
// 0.0.102+
16454+
//
16455+
// First we rebuild all pending payments, then separately re-claim and re-fail pending
16456+
// payments. This avoids edge-cases around MPP payments resulting in redundant actions.
1645416457
for (channel_id, monitor) in args.channel_monitors.iter() {
1645516458
let mut is_channel_closed = false;
1645616459
let counterparty_node_id = monitor.get_counterparty_node_id();
@@ -16489,6 +16492,18 @@ where
1648916492
);
1649016493
}
1649116494
}
16495+
}
16496+
}
16497+
for (channel_id, monitor) in args.channel_monitors.iter() {
16498+
let mut is_channel_closed = false;
16499+
let counterparty_node_id = monitor.get_counterparty_node_id();
16500+
if let Some(peer_state_mtx) = per_peer_state.get(&counterparty_node_id) {
16501+
let mut peer_state_lock = peer_state_mtx.lock().unwrap();
16502+
let peer_state = &mut *peer_state_lock;
16503+
is_channel_closed = !peer_state.channel_by_id.contains_key(channel_id);
16504+
}
16505+
16506+
if is_channel_closed {
1649216507
for (htlc_source, (htlc, preimage_opt)) in
1649316508
monitor.get_all_current_outbound_htlcs()
1649416509
{

0 commit comments

Comments
 (0)