Skip to content

Commit 19191b4

Browse files
authored
Merge pull request #1178 from jkczyz/2021-11-payment-path-successful
Generate PaymentPathSuccessful event for each path
2 parents 2b78957 + 2c4f16d commit 19191b4

10 files changed

+244
-128
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
841841
}
842842
},
843843
events::Event::PaymentSent { .. } => {},
844+
events::Event::PaymentPathSuccessful { .. } => {},
844845
events::Event::PaymentPathFailed { .. } => {},
845846
events::Event::PaymentForwarded { .. } if $node == 1 => {},
846847
events::Event::PendingHTLCsForwardable { .. } => {

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
551551
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke_and_ack);
552552
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
553553
check_added_monitors!(nodes[0], 1);
554+
expect_payment_path_successful!(nodes[0]);
554555

555556
expect_pending_htlcs_forwardable!(nodes[1]);
556557

@@ -1090,12 +1091,12 @@ fn test_monitor_update_fail_reestablish() {
10901091
let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
10911092
create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
10921093

1093-
let (our_payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
1094+
let (payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
10941095

10951096
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
10961097
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
10971098

1098-
assert!(nodes[2].node.claim_funds(our_payment_preimage));
1099+
assert!(nodes[2].node.claim_funds(payment_preimage));
10991100
check_added_monitors!(nodes[2], 1);
11001101
let mut updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
11011102
assert!(updates.update_add_htlcs.is_empty());
@@ -1159,13 +1160,7 @@ fn test_monitor_update_fail_reestablish() {
11591160
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
11601161
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
11611162
commitment_signed_dance!(nodes[0], nodes[1], updates.commitment_signed, false);
1162-
1163-
let events = nodes[0].node.get_and_clear_pending_events();
1164-
assert_eq!(events.len(), 1);
1165-
match events[0] {
1166-
Event::PaymentSent { payment_preimage, .. } => assert_eq!(payment_preimage, our_payment_preimage),
1167-
_ => panic!("Unexpected event"),
1168-
}
1163+
expect_payment_sent!(nodes[0], payment_preimage);
11691164
}
11701165

11711166
#[test]
@@ -1300,7 +1295,7 @@ fn claim_while_disconnected_monitor_update_fail() {
13001295
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
13011296

13021297
// Forward a payment for B to claim
1303-
let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
1298+
let (payment_preimage_1, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
13041299

13051300
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
13061301
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
@@ -1395,16 +1390,7 @@ fn claim_while_disconnected_monitor_update_fail() {
13951390

13961391
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_raa);
13971392
check_added_monitors!(nodes[0], 1);
1398-
1399-
let events = nodes[0].node.get_and_clear_pending_events();
1400-
assert_eq!(events.len(), 1);
1401-
match events[0] {
1402-
Event::PaymentSent { ref payment_preimage, ref payment_hash, .. } => {
1403-
assert_eq!(*payment_preimage, payment_preimage_1);
1404-
assert_eq!(*payment_hash, payment_hash_1);
1405-
},
1406-
_ => panic!("Unexpected event"),
1407-
}
1393+
expect_payment_sent!(nodes[0], payment_preimage_1);
14081394

14091395
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
14101396
}
@@ -1766,7 +1752,7 @@ fn monitor_update_claim_fail_no_response() {
17661752
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
17671753

17681754
// Forward a payment for B to claim
1769-
let (payment_preimage_1, payment_hash_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
1755+
let (payment_preimage_1, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
17701756

17711757
// Now start forwarding a second payment, skipping the last RAA so B is in AwaitingRAA
17721758
let (route, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
@@ -1802,16 +1788,7 @@ fn monitor_update_claim_fail_no_response() {
18021788
let bs_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
18031789
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_updates.update_fulfill_htlcs[0]);
18041790
commitment_signed_dance!(nodes[0], nodes[1], bs_updates.commitment_signed, false);
1805-
1806-
let events = nodes[0].node.get_and_clear_pending_events();
1807-
assert_eq!(events.len(), 1);
1808-
match events[0] {
1809-
Event::PaymentSent { ref payment_preimage, ref payment_hash, .. } => {
1810-
assert_eq!(*payment_preimage, payment_preimage_1);
1811-
assert_eq!(*payment_hash, payment_hash_1);
1812-
},
1813-
_ => panic!("Unexpected event"),
1814-
}
1791+
expect_payment_sent!(nodes[0], payment_preimage_1);
18151792

18161793
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
18171794
}
@@ -2323,7 +2300,7 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
23232300
assert!(updates.update_fee.is_none());
23242301
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
23252302
nodes[1].node.handle_update_fulfill_htlc(&nodes[0].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
2326-
expect_payment_sent!(nodes[1], payment_preimage_0);
2303+
expect_payment_sent_without_paths!(nodes[1], payment_preimage_0);
23272304
assert_eq!(updates.update_add_htlcs.len(), 1);
23282305
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
23292306
updates.commitment_signed
@@ -2342,7 +2319,18 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
23422319

23432320
commitment_signed_dance!(nodes[1], nodes[0], (), false, true, false);
23442321

2345-
expect_pending_htlcs_forwardable!(nodes[1]);
2322+
let events = nodes[1].node.get_and_clear_pending_events();
2323+
assert_eq!(events.len(), 2);
2324+
match events[0] {
2325+
Event::PendingHTLCsForwardable { .. } => { },
2326+
_ => panic!("Unexpected event"),
2327+
};
2328+
match events[1] {
2329+
Event::PaymentPathSuccessful { .. } => { },
2330+
_ => panic!("Unexpected event"),
2331+
};
2332+
2333+
nodes[1].node.process_pending_htlc_forwards();
23462334
expect_payment_received!(nodes[1], payment_hash_2, payment_secret_2, 100000);
23472335

23482336
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
@@ -2427,9 +2415,10 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f
24272415
bs_updates = Some(get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()));
24282416
assert_eq!(bs_updates.as_ref().unwrap().update_fulfill_htlcs.len(), 1);
24292417
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_updates.as_ref().unwrap().update_fulfill_htlcs[0]);
2430-
expect_payment_sent!(nodes[0], payment_preimage);
2418+
expect_payment_sent_without_paths!(nodes[0], payment_preimage);
24312419
if htlc_status == HTLCStatusAtDupClaim::Cleared {
24322420
commitment_signed_dance!(nodes[0], nodes[1], &bs_updates.as_ref().unwrap().commitment_signed, false);
2421+
expect_payment_path_successful!(nodes[0]);
24332422
}
24342423
} else {
24352424
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
@@ -2453,10 +2442,11 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f
24532442
bs_updates = Some(get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()));
24542443
assert_eq!(bs_updates.as_ref().unwrap().update_fulfill_htlcs.len(), 1);
24552444
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_updates.as_ref().unwrap().update_fulfill_htlcs[0]);
2456-
expect_payment_sent!(nodes[0], payment_preimage);
2445+
expect_payment_sent_without_paths!(nodes[0], payment_preimage);
24572446
}
24582447
if htlc_status != HTLCStatusAtDupClaim::Cleared {
24592448
commitment_signed_dance!(nodes[0], nodes[1], &bs_updates.as_ref().unwrap().commitment_signed, false);
2449+
expect_payment_path_successful!(nodes[0]);
24602450
}
24612451
}
24622452

@@ -2620,7 +2610,7 @@ fn double_temp_error() {
26202610
assert_eq!(node_id, nodes[0].node.get_our_node_id());
26212611
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_fulfill_1);
26222612
check_added_monitors!(nodes[0], 0);
2623-
expect_payment_sent!(nodes[0], payment_preimage_1);
2613+
expect_payment_sent_without_paths!(nodes[0], payment_preimage_1);
26242614
nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed_b1);
26252615
check_added_monitors!(nodes[0], 1);
26262616
nodes[0].node.process_pending_htlc_forwards();
@@ -2658,6 +2648,7 @@ fn double_temp_error() {
26582648
};
26592649
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &raa_b2);
26602650
check_added_monitors!(nodes[0], 1);
2651+
expect_payment_path_successful!(nodes[0]);
26612652

26622653
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_fulfill_2);
26632654
check_added_monitors!(nodes[0], 0);

lightning/src/ln/channelmanager.rs

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ pub(crate) enum PendingOutboundPayment {
452452
/// and add a pending payment that was already fulfilled.
453453
Fulfilled {
454454
session_privs: HashSet<[u8; 32]>,
455+
payment_hash: Option<PaymentHash>,
455456
},
456457
}
457458

@@ -475,23 +476,32 @@ impl PendingOutboundPayment {
475476
}
476477
}
477478

479+
fn payment_hash(&self) -> Option<PaymentHash> {
480+
match self {
481+
PendingOutboundPayment::Legacy { .. } => None,
482+
PendingOutboundPayment::Retryable { payment_hash, .. } => Some(*payment_hash),
483+
PendingOutboundPayment::Fulfilled { payment_hash, .. } => *payment_hash,
484+
}
485+
}
486+
478487
fn mark_fulfilled(&mut self) {
479488
let mut session_privs = HashSet::new();
480489
core::mem::swap(&mut session_privs, match self {
481490
PendingOutboundPayment::Legacy { session_privs } |
482491
PendingOutboundPayment::Retryable { session_privs, .. } |
483-
PendingOutboundPayment::Fulfilled { session_privs }
492+
PendingOutboundPayment::Fulfilled { session_privs, .. }
484493
=> session_privs
485494
});
486-
*self = PendingOutboundPayment::Fulfilled { session_privs };
495+
let payment_hash = self.payment_hash();
496+
*self = PendingOutboundPayment::Fulfilled { session_privs, payment_hash };
487497
}
488498

489499
/// panics if path is None and !self.is_fulfilled
490500
fn remove(&mut self, session_priv: &[u8; 32], path: Option<&Vec<RouteHop>>) -> bool {
491501
let remove_res = match self {
492502
PendingOutboundPayment::Legacy { session_privs } |
493503
PendingOutboundPayment::Retryable { session_privs, .. } |
494-
PendingOutboundPayment::Fulfilled { session_privs } => {
504+
PendingOutboundPayment::Fulfilled { session_privs, .. } => {
495505
session_privs.remove(session_priv)
496506
}
497507
};
@@ -532,7 +542,7 @@ impl PendingOutboundPayment {
532542
match self {
533543
PendingOutboundPayment::Legacy { session_privs } |
534544
PendingOutboundPayment::Retryable { session_privs, .. } |
535-
PendingOutboundPayment::Fulfilled { session_privs } => {
545+
PendingOutboundPayment::Fulfilled { session_privs, .. } => {
536546
session_privs.len()
537547
}
538548
}
@@ -3493,14 +3503,23 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
34933503
}
34943504

34953505
fn finalize_claims(&self, mut sources: Vec<HTLCSource>) {
3506+
let mut pending_events = self.pending_events.lock().unwrap();
34963507
for source in sources.drain(..) {
3497-
if let HTLCSource::OutboundRoute { session_priv, payment_id, .. } = source {
3508+
if let HTLCSource::OutboundRoute { session_priv, payment_id, path, .. } = source {
34983509
let mut session_priv_bytes = [0; 32];
34993510
session_priv_bytes.copy_from_slice(&session_priv[..]);
35003511
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
35013512
if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(payment_id) {
35023513
assert!(payment.get().is_fulfilled());
3503-
payment.get_mut().remove(&session_priv_bytes, None);
3514+
if payment.get_mut().remove(&session_priv_bytes, None) {
3515+
pending_events.push(
3516+
events::Event::PaymentPathSuccessful {
3517+
payment_id,
3518+
payment_hash: payment.get().payment_hash(),
3519+
path,
3520+
}
3521+
);
3522+
}
35043523
if payment.get().remaining_parts() == 0 {
35053524
payment.remove();
35063525
}
@@ -3517,32 +3536,43 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
35173536
session_priv_bytes.copy_from_slice(&session_priv[..]);
35183537
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
35193538
if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(payment_id) {
3520-
let found_payment = !payment.get().is_fulfilled();
3521-
let fee_paid_msat = payment.get().get_pending_fee_msat();
3522-
payment.get_mut().mark_fulfilled();
3539+
let mut pending_events = self.pending_events.lock().unwrap();
3540+
if !payment.get().is_fulfilled() {
3541+
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
3542+
let fee_paid_msat = payment.get().get_pending_fee_msat();
3543+
pending_events.push(
3544+
events::Event::PaymentSent {
3545+
payment_id: Some(payment_id),
3546+
payment_preimage,
3547+
payment_hash,
3548+
fee_paid_msat,
3549+
}
3550+
);
3551+
payment.get_mut().mark_fulfilled();
3552+
}
3553+
35233554
if from_onchain {
35243555
// We currently immediately remove HTLCs which were fulfilled on-chain.
35253556
// This could potentially lead to removing a pending payment too early,
35263557
// with a reorg of one block causing us to re-add the fulfilled payment on
35273558
// restart.
35283559
// TODO: We should have a second monitor event that informs us of payments
35293560
// irrevocably fulfilled.
3530-
payment.get_mut().remove(&session_priv_bytes, Some(&path));
3561+
if payment.get_mut().remove(&session_priv_bytes, Some(&path)) {
3562+
let payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0).into_inner()));
3563+
pending_events.push(
3564+
events::Event::PaymentPathSuccessful {
3565+
payment_id,
3566+
payment_hash,
3567+
path,
3568+
}
3569+
);
3570+
}
3571+
35313572
if payment.get().remaining_parts() == 0 {
35323573
payment.remove();
35333574
}
35343575
}
3535-
if found_payment {
3536-
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
3537-
self.pending_events.lock().unwrap().push(
3538-
events::Event::PaymentSent {
3539-
payment_id: Some(payment_id),
3540-
payment_preimage,
3541-
payment_hash: payment_hash,
3542-
fee_paid_msat,
3543-
}
3544-
);
3545-
}
35463576
} else {
35473577
log_trace!(self.logger, "Received duplicative fulfill for HTLC with payment_preimage {}", log_bytes!(payment_preimage.0));
35483578
}
@@ -4631,6 +4661,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
46314661
pub fn has_pending_payments(&self) -> bool {
46324662
!self.pending_outbound_payments.lock().unwrap().is_empty()
46334663
}
4664+
4665+
#[cfg(test)]
4666+
pub fn clear_pending_payments(&self) {
4667+
self.pending_outbound_payments.lock().unwrap().clear()
4668+
}
46344669
}
46354670

46364671
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<Signer, M, T, K, F, L>
@@ -5555,6 +5590,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
55555590
},
55565591
(1, Fulfilled) => {
55575592
(0, session_privs, required),
5593+
(1, payment_hash, option),
55585594
},
55595595
(2, Retryable) => {
55605596
(0, session_privs, required),
@@ -6323,9 +6359,10 @@ mod tests {
63236359
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_third_raa);
63246360
check_added_monitors!(nodes[0], 1);
63256361

6326-
// Note that successful MPP payments will generate 1 event upon the first path's success. No
6327-
// further events will be generated for subsequence path successes.
6362+
// Note that successful MPP payments will generate a single PaymentSent event upon the first
6363+
// path's success and a PaymentPathSuccessful event for each path's success.
63286364
let events = nodes[0].node.get_and_clear_pending_events();
6365+
assert_eq!(events.len(), 3);
63296366
match events[0] {
63306367
Event::PaymentSent { payment_id: ref id, payment_preimage: ref preimage, payment_hash: ref hash, .. } => {
63316368
assert_eq!(Some(payment_id), *id);
@@ -6334,6 +6371,22 @@ mod tests {
63346371
},
63356372
_ => panic!("Unexpected event"),
63366373
}
6374+
match events[1] {
6375+
Event::PaymentPathSuccessful { payment_id: ref actual_payment_id, ref payment_hash, ref path } => {
6376+
assert_eq!(payment_id, *actual_payment_id);
6377+
assert_eq!(our_payment_hash, *payment_hash.as_ref().unwrap());
6378+
assert_eq!(route.paths[0], *path);
6379+
},
6380+
_ => panic!("Unexpected event"),
6381+
}
6382+
match events[2] {
6383+
Event::PaymentPathSuccessful { payment_id: ref actual_payment_id, ref payment_hash, ref path } => {
6384+
assert_eq!(payment_id, *actual_payment_id);
6385+
assert_eq!(our_payment_hash, *payment_hash.as_ref().unwrap());
6386+
assert_eq!(route.paths[0], *path);
6387+
},
6388+
_ => panic!("Unexpected event"),
6389+
}
63376390
}
63386391

63396392
#[test]

0 commit comments

Comments
 (0)