diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 64486598005..f5a2bb02f83 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -84,7 +84,6 @@ use crate::ln::onion_utils::{ }; use crate::ln::onion_utils::{process_fulfill_attribution_data, AttributionData}; use crate::ln::our_peer_storage::{EncryptedOurPeerStorage, PeerStorageMonitorHolder}; -#[cfg(test)] use crate::ln::outbound_payment; #[cfg(any(test, feature = "_externalize_tests"))] use crate::ln::outbound_payment::PaymentSendFailure; @@ -3289,6 +3288,8 @@ pub enum RecentPaymentDetails { /// Total amount (in msat, excluding fees) across all paths for this payment, /// not just the amount currently inflight. total_msat: u64, + /// Whether this payment is a liquidity probe. + is_probe: bool, }, /// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have /// been resolved. Upon receiving [`Event::PaymentSent`], we delay for a few minutes before the @@ -3316,6 +3317,8 @@ pub enum RecentPaymentDetails { payment_id: PaymentId, /// Hash of the payment that we have given up trying to send. payment_hash: PaymentHash, + /// Whether this payment is a liquidity probe. + is_probe: bool, }, } @@ -4102,14 +4105,21 @@ impl< Some(RecentPaymentDetails::AwaitingInvoice { payment_id: *payment_id }) }, PendingOutboundPayment::Retryable { payment_hash, total_msat, .. } => { + let is_probe = outbound_payment::payment_is_probe(payment_hash, payment_id, self.probing_cookie_secret); Some(RecentPaymentDetails::Pending { payment_id: *payment_id, payment_hash: *payment_hash, total_msat: *total_msat, + is_probe, }) }, PendingOutboundPayment::Abandoned { payment_hash, .. } => { - Some(RecentPaymentDetails::Abandoned { payment_id: *payment_id, payment_hash: *payment_hash }) + let is_probe = outbound_payment::payment_is_probe(payment_hash, payment_id, self.probing_cookie_secret); + Some(RecentPaymentDetails::Abandoned { + payment_id: *payment_id, + payment_hash: *payment_hash, + is_probe, + }) }, PendingOutboundPayment::Fulfilled { payment_hash, .. } => { Some(RecentPaymentDetails::Fulfilled { payment_id: *payment_id, payment_hash: *payment_hash }) diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 5b4f5f93d71..f2ab44f8fe3 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -1591,17 +1591,32 @@ fn sent_probe_is_probe_of_sending_node() { // Then build an actual two-hop probing path let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], 100_000); - match nodes[0].node.send_probe(route.paths[0].clone()) { - Ok((payment_hash, payment_id)) => { - assert!(nodes[0].node.payment_is_probe(&payment_hash, &payment_id)); - assert!(!nodes[1].node.payment_is_probe(&payment_hash, &payment_id)); - assert!(!nodes[2].node.payment_is_probe(&payment_hash, &payment_id)); - }, - _ => panic!(), - } + let (payment_hash, payment_id) = nodes[0].node.send_probe(route.paths[0].clone()).unwrap(); + assert!(nodes[0].node.payment_is_probe(&payment_hash, &payment_id)); + assert!(!nodes[1].node.payment_is_probe(&payment_hash, &payment_id)); + assert!(!nodes[2].node.payment_is_probe(&payment_hash, &payment_id)); + assert!(matches!( + nodes[0].node.list_recent_payments().as_slice(), + [RecentPaymentDetails::Pending { + payment_id: listed_payment_id, + payment_hash: listed_payment_hash, + is_probe: true, + .. + }] if *listed_payment_id == payment_id && *listed_payment_hash == payment_hash + )); get_htlc_update_msgs(&nodes[0], &node_b_id); check_added_monitors(&nodes[0], 1); + + nodes[0].node.abandon_payment(payment_id); + assert!(matches!( + nodes[0].node.list_recent_payments().as_slice(), + [RecentPaymentDetails::Abandoned { + payment_id: listed_payment_id, + payment_hash: listed_payment_hash, + is_probe: true, + }] if *listed_payment_id == payment_id && *listed_payment_hash == payment_hash + )); } #[test] @@ -2142,7 +2157,12 @@ fn test_trivial_inflight_htlc_tracking() { } let pending_payments = nodes[0].node.list_recent_payments(); assert_eq!(pending_payments.len(), 1); - let details = RecentPaymentDetails::Pending { payment_id, payment_hash, total_msat: 500000 }; + let details = RecentPaymentDetails::Pending { + payment_id, + payment_hash, + total_msat: 500000, + is_probe: false, + }; assert_eq!(pending_payments[0], details); // Now, let's claim the payment. This should result in the used liquidity to return `None`.