Skip to content

Commit 4c7a57d

Browse files
committed
feat: track in-flight amount for pending payments
1 parent e9ce486 commit 4c7a57d

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3179,6 +3179,11 @@ pub enum RecentPaymentDetails {
31793179
/// Total amount (in msat, excluding fees) across all paths for this payment,
31803180
/// not just the amount currently inflight.
31813181
total_msat: u64,
3182+
/// Amount (in msat) currently locked in HTLCs.
3183+
///
3184+
/// `total_msat - inflight_msat` gives the amount waiting to be retried
3185+
/// Reserve both from spendable balance.
3186+
inflight_msat: u64,
31823187
},
31833188
/// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have
31843189
/// been resolved. Upon receiving [`Event::PaymentSent`], we delay for a few minutes before the
@@ -3884,11 +3889,12 @@ where
38843889
PendingOutboundPayment::StaticInvoiceReceived { .. } => {
38853890
Some(RecentPaymentDetails::AwaitingInvoice { payment_id: *payment_id })
38863891
},
3887-
PendingOutboundPayment::Retryable { payment_hash, total_msat, .. } => {
3892+
PendingOutboundPayment::Retryable { payment_hash, total_msat, pending_amt_msat, .. } => {
38883893
Some(RecentPaymentDetails::Pending {
38893894
payment_id: *payment_id,
38903895
payment_hash: *payment_hash,
38913896
total_msat: *total_msat,
3897+
inflight_msat: *pending_amt_msat,
38923898
})
38933899
},
38943900
PendingOutboundPayment::Abandoned { payment_hash, .. } => {

lightning/src/ln/payment_tests.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,8 +2098,14 @@ fn test_trivial_inflight_htlc_tracking() {
20982098
}
20992099
let pending_payments = nodes[0].node.list_recent_payments();
21002100
assert_eq!(pending_payments.len(), 1);
2101-
let details = RecentPaymentDetails::Pending { payment_id, payment_hash, total_msat: 500000 };
2102-
assert_eq!(pending_payments[0], details);
2101+
match &pending_payments[0] {
2102+
RecentPaymentDetails::Pending { payment_id: pid, payment_hash: ph, total_msat: tm, .. } => {
2103+
assert_eq!(*pid, payment_id);
2104+
assert_eq!(*ph, payment_hash);
2105+
assert_eq!(*tm, 500000);
2106+
},
2107+
_ => panic!("Expected Pending payment details"),
2108+
}
21032109

21042110
// Now, let's claim the payment. This should result in the used liquidity to return `None`.
21052111
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
@@ -2141,6 +2147,39 @@ fn test_trivial_inflight_htlc_tracking() {
21412147
assert_eq!(pending_payments.len(), 0);
21422148
}
21432149

2150+
#[test]
2151+
fn test_pending_payment_tracking() {
2152+
let chanmon_cfgs = create_chanmon_cfgs(3);
2153+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
2154+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
2155+
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
2156+
2157+
create_announced_chan_between_nodes(&nodes, 0, 1);
2158+
create_announced_chan_between_nodes(&nodes, 1, 2);
2159+
2160+
let payment_amt = 100_000;
2161+
let (payment_preimage, _payment_hash, _, payment_id) =
2162+
route_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_amt);
2163+
2164+
let pending_payments = nodes[0].node.list_recent_payments();
2165+
assert_eq!(pending_payments.len(), 1);
2166+
match &pending_payments[0] {
2167+
RecentPaymentDetails::Pending { payment_id: pid, total_msat, inflight_msat, .. } => {
2168+
assert_eq!(*pid, payment_id);
2169+
assert_eq!(*total_msat, payment_amt);
2170+
assert_eq!(*inflight_msat, payment_amt);
2171+
},
2172+
_ => panic!("Expected Pending payment details"),
2173+
}
2174+
2175+
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
2176+
2177+
for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS {
2178+
nodes[0].node.timer_tick_occurred();
2179+
}
2180+
assert!(nodes[0].node.list_recent_payments().is_empty());
2181+
}
2182+
21442183
#[test]
21452184
fn test_holding_cell_inflight_htlcs() {
21462185
let chanmon_cfgs = create_chanmon_cfgs(2);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
## API Updates
2+
3+
* `RecentPaymentDetails::Pending` now includes `inflight_msat`, tracking the
4+
amount currently locked in HTLCs. The difference `total_msat - inflight_msat`
5+
is the amount waiting to retry. Reserve both from spendable balance to avoid
6+
balance flicker during payment retries (#3374).

0 commit comments

Comments
 (0)