Skip to content

Commit 6b0b69a

Browse files
Prevent duplicate PaymentSent events
by removing all pending outbound payments associated with the same MPP payment after the preimage is received
1 parent ce5dcba commit 6b0b69a

File tree

3 files changed

+18
-19
lines changed

3 files changed

+18
-19
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3140,18 +3140,18 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31403140
let mut session_priv_bytes = [0; 32];
31413141
session_priv_bytes.copy_from_slice(&session_priv[..]);
31423142
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
3143-
if let Some(sessions) = outbounds.get_mut(&mpp_id) {
3144-
if sessions.remove(&session_priv_bytes) {
3145-
self.pending_events.lock().unwrap().push(
3146-
events::Event::PaymentSent { payment_preimage }
3147-
);
3148-
if sessions.len() == 0 {
3149-
outbounds.remove(&mpp_id);
3143+
let found_payment = loop {
3144+
if let Some(mut sessions) = outbounds.remove(&mpp_id) {
3145+
if sessions.remove(&session_priv_bytes) {
3146+
self.pending_events.lock().unwrap().push(
3147+
events::Event::PaymentSent { payment_preimage }
3148+
);
3149+
break true
31503150
}
3151-
} else {
3152-
log_trace!(self.logger, "Received duplicative fulfill for HTLC with payment_preimage {}", log_bytes!(payment_preimage.0));
31533151
}
3154-
} else {
3152+
break false
3153+
};
3154+
if !found_payment {
31553155
log_trace!(self.logger, "Received duplicative fulfill for HTLC with payment_preimage {}", log_bytes!(payment_preimage.0));
31563156
}
31573157
},
@@ -5692,20 +5692,13 @@ mod tests {
56925692
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_third_raa);
56935693
check_added_monitors!(nodes[0], 1);
56945694

5695-
// There's an existing bug that generates a PaymentSent event for each MPP path, so handle that here.
56965695
let events = nodes[0].node.get_and_clear_pending_events();
56975696
match events[0] {
56985697
Event::PaymentSent { payment_preimage: ref preimage } => {
56995698
assert_eq!(payment_preimage, *preimage);
57005699
},
57015700
_ => panic!("Unexpected event"),
57025701
}
5703-
match events[1] {
5704-
Event::PaymentSent { payment_preimage: ref preimage } => {
5705-
assert_eq!(payment_preimage, *preimage);
5706-
},
5707-
_ => panic!("Unexpected event"),
5708-
}
57095702
}
57105703

57115704
#[test]

lightning/src/ln/functional_test_utils.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1242,9 +1242,11 @@ pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, exp
12421242

12431243
if !skip_last {
12441244
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
1245-
expect_payment_sent!(origin_node, our_payment_preimage);
12461245
}
12471246
}
1247+
if !skip_last {
1248+
expect_payment_sent!(origin_node, our_payment_preimage);
1249+
}
12481250
}
12491251

12501252
pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage) {

lightning/src/util/events.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,12 @@ pub enum Event {
112112
/// payment is to pay an invoice or to send a spontaneous payment.
113113
purpose: PaymentPurpose,
114114
},
115-
/// Indicates an outbound payment we made succeeded (ie it made it all the way to its target
115+
/// Indicates an outbound payment we made succeeded (i.e. it made it all the way to its target
116116
/// and we got back the payment preimage for it).
117+
///
118+
/// Note for MPP payments: we generate this event as soon as one of the payment paths succeeds. In
119+
/// the case of a buggy payee, this may be followed by a PaymentFailed event if subsequent path(s)
120+
/// fail. However, this case should be extremely rare.
117121
PaymentSent {
118122
/// The preimage to the hash given to ChannelManager::send_payment.
119123
/// Note that this serves as a payment receipt, if you wish to have such a thing, you must

0 commit comments

Comments
 (0)