Skip to content

Commit 09d4b57

Browse files
committed
Expose probe status in recent payments
Let callers distinguish liquidity probes while they are pending or abandoned. This keeps invoice and fulfilled states focused on real payment flows, where probes are reported through probe events. Co-Authored-By: HAL 9000
1 parent 38f5651 commit 09d4b57

2 files changed

Lines changed: 41 additions & 11 deletions

File tree

lightning/src/ln/channelmanager.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ use crate::ln::onion_utils::{
8484
};
8585
use crate::ln::onion_utils::{process_fulfill_attribution_data, AttributionData};
8686
use crate::ln::our_peer_storage::{EncryptedOurPeerStorage, PeerStorageMonitorHolder};
87-
#[cfg(test)]
8887
use crate::ln::outbound_payment;
8988
#[cfg(any(test, feature = "_externalize_tests"))]
9089
use crate::ln::outbound_payment::PaymentSendFailure;
@@ -3289,6 +3288,8 @@ pub enum RecentPaymentDetails {
32893288
/// Total amount (in msat, excluding fees) across all paths for this payment,
32903289
/// not just the amount currently inflight.
32913290
total_msat: u64,
3291+
/// Whether this payment is a liquidity probe.
3292+
is_probe: bool,
32923293
},
32933294
/// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have
32943295
/// been resolved. Upon receiving [`Event::PaymentSent`], we delay for a few minutes before the
@@ -3316,6 +3317,8 @@ pub enum RecentPaymentDetails {
33163317
payment_id: PaymentId,
33173318
/// Hash of the payment that we have given up trying to send.
33183319
payment_hash: PaymentHash,
3320+
/// Whether this payment is a liquidity probe.
3321+
is_probe: bool,
33193322
},
33203323
}
33213324

@@ -4102,14 +4105,21 @@ impl<
41024105
Some(RecentPaymentDetails::AwaitingInvoice { payment_id: *payment_id })
41034106
},
41044107
PendingOutboundPayment::Retryable { payment_hash, total_msat, .. } => {
4108+
let is_probe = outbound_payment::payment_is_probe(payment_hash, payment_id, self.probing_cookie_secret);
41054109
Some(RecentPaymentDetails::Pending {
41064110
payment_id: *payment_id,
41074111
payment_hash: *payment_hash,
41084112
total_msat: *total_msat,
4113+
is_probe,
41094114
})
41104115
},
41114116
PendingOutboundPayment::Abandoned { payment_hash, .. } => {
4112-
Some(RecentPaymentDetails::Abandoned { payment_id: *payment_id, payment_hash: *payment_hash })
4117+
let is_probe = outbound_payment::payment_is_probe(payment_hash, payment_id, self.probing_cookie_secret);
4118+
Some(RecentPaymentDetails::Abandoned {
4119+
payment_id: *payment_id,
4120+
payment_hash: *payment_hash,
4121+
is_probe,
4122+
})
41134123
},
41144124
PendingOutboundPayment::Fulfilled { payment_hash, .. } => {
41154125
Some(RecentPaymentDetails::Fulfilled { payment_id: *payment_id, payment_hash: *payment_hash })

lightning/src/ln/payment_tests.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,17 +1591,32 @@ fn sent_probe_is_probe_of_sending_node() {
15911591
// Then build an actual two-hop probing path
15921592
let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], 100_000);
15931593

1594-
match nodes[0].node.send_probe(route.paths[0].clone()) {
1595-
Ok((payment_hash, payment_id)) => {
1596-
assert!(nodes[0].node.payment_is_probe(&payment_hash, &payment_id));
1597-
assert!(!nodes[1].node.payment_is_probe(&payment_hash, &payment_id));
1598-
assert!(!nodes[2].node.payment_is_probe(&payment_hash, &payment_id));
1599-
},
1600-
_ => panic!(),
1601-
}
1594+
let (payment_hash, payment_id) = nodes[0].node.send_probe(route.paths[0].clone()).unwrap();
1595+
assert!(nodes[0].node.payment_is_probe(&payment_hash, &payment_id));
1596+
assert!(!nodes[1].node.payment_is_probe(&payment_hash, &payment_id));
1597+
assert!(!nodes[2].node.payment_is_probe(&payment_hash, &payment_id));
1598+
assert!(matches!(
1599+
nodes[0].node.list_recent_payments().as_slice(),
1600+
[RecentPaymentDetails::Pending {
1601+
payment_id: listed_payment_id,
1602+
payment_hash: listed_payment_hash,
1603+
is_probe: true,
1604+
..
1605+
}] if *listed_payment_id == payment_id && *listed_payment_hash == payment_hash
1606+
));
16021607

16031608
get_htlc_update_msgs(&nodes[0], &node_b_id);
16041609
check_added_monitors(&nodes[0], 1);
1610+
1611+
nodes[0].node.abandon_payment(payment_id);
1612+
assert!(matches!(
1613+
nodes[0].node.list_recent_payments().as_slice(),
1614+
[RecentPaymentDetails::Abandoned {
1615+
payment_id: listed_payment_id,
1616+
payment_hash: listed_payment_hash,
1617+
is_probe: true,
1618+
}] if *listed_payment_id == payment_id && *listed_payment_hash == payment_hash
1619+
));
16051620
}
16061621

16071622
#[test]
@@ -2142,7 +2157,12 @@ fn test_trivial_inflight_htlc_tracking() {
21422157
}
21432158
let pending_payments = nodes[0].node.list_recent_payments();
21442159
assert_eq!(pending_payments.len(), 1);
2145-
let details = RecentPaymentDetails::Pending { payment_id, payment_hash, total_msat: 500000 };
2160+
let details = RecentPaymentDetails::Pending {
2161+
payment_id,
2162+
payment_hash,
2163+
total_msat: 500000,
2164+
is_probe: false,
2165+
};
21462166
assert_eq!(pending_payments[0], details);
21472167

21482168
// Now, let's claim the payment. This should result in the used liquidity to return `None`.

0 commit comments

Comments
 (0)