Skip to content

Commit 0fe237f

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. Backport of 8106dbf Resolved substantial conflcits in: * lightning/src/ln/channelmanager.rs by simply rewriting the patch. Note that the `is_channel_closed` variable used in the upstream version of this commit replaced simply checking if the `outpoint_to_peer` map had an entry for the channel's funding outpoint. Note that the next upstream commit in this series (3239d67) is unnecessary on this branch as we use `outpoint_to_peer` rather than `per_peer_state` to detect channel closure here.
1 parent cf42bf7 commit 0fe237f

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13869,6 +13869,9 @@ where
1386913869
// payments which are still in-flight via their on-chain state.
1387013870
// We only rebuild the pending payments map if we were most recently serialized by
1387113871
// 0.0.102+
13872+
//
13873+
// First we rebuild all pending payments, then separately re-claim and re-fail pending
13874+
// payments. This avoids edge-cases around MPP payments resulting in redundant actions.
1387213875
for (_, monitor) in args.channel_monitors.iter() {
1387313876
let counterparty_opt = outpoint_to_peer.get(&monitor.get_funding_txo().0);
1387413877
if counterparty_opt.is_none() {
@@ -13887,6 +13890,11 @@ where
1388713890
);
1388813891
}
1388913892
}
13893+
}
13894+
}
13895+
for (_, monitor) in args.channel_monitors.iter() {
13896+
let counterparty_opt = outpoint_to_peer.get(&monitor.get_funding_txo().0);
13897+
if counterparty_opt.is_none() {
1389013898
for (htlc_source, (htlc, preimage_opt)) in monitor.get_all_current_outbound_htlcs() {
1389113899
let logger = WithChannelMonitor::from(&args.logger, monitor, Some(htlc.payment_hash));
1389213900
match htlc_source {

0 commit comments

Comments
 (0)