Skip to content

Commit e1a31e1

Browse files
authored
Merge pull request #4008 from tnull/2025-08-liquidity-persistence-prefactors
`lightning-liquidity`: Pre-/Refactors to prepare for persistence
2 parents 66a4932 + f95ba69 commit e1a31e1

File tree

10 files changed

+359
-182
lines changed

10 files changed

+359
-182
lines changed

lightning-liquidity/src/lsps1/msgs.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
9+
110
//! Message, request, and other primitive types used to implement bLIP-51 / LSPS1.
211
312
use alloc::string::String;

lightning-liquidity/src/lsps2/client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
//
44
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
55
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6-
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. You may not use this file except in accordance with one or both of these
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
78
// licenses.
89

910
//! Contains the main bLIP-52 / LSPS2 client object, [`LSPS2ClientHandler`].

lightning-liquidity/src/lsps2/msgs.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
9+
110
//! Message, request, and other primitive types used to implement bLIP-52 / LSPS2.
211
312
use alloc::string::String;

lightning-liquidity/src/lsps2/payment_queue.rs

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
9+
110
use alloc::vec::Vec;
211

312
use lightning::ln::channelmanager::InterceptId;
@@ -8,7 +17,7 @@ use lightning_types::payment::PaymentHash;
817
/// remaining payments forwarded.
918
#[derive(Clone, Default, PartialEq, Eq, Debug)]
1019
pub(crate) struct PaymentQueue {
11-
payments: Vec<(PaymentHash, Vec<InterceptedHTLC>)>,
20+
payments: Vec<PaymentQueueEntry>,
1221
}
1322

1423
impl PaymentQueue {
@@ -17,37 +26,48 @@ impl PaymentQueue {
1726
}
1827

1928
pub(crate) fn add_htlc(&mut self, new_htlc: InterceptedHTLC) -> (u64, usize) {
20-
let payment = self.payments.iter_mut().find(|(p, _)| p == &new_htlc.payment_hash);
21-
if let Some((payment_hash, htlcs)) = payment {
29+
let payment =
30+
self.payments.iter_mut().find(|entry| entry.payment_hash == new_htlc.payment_hash);
31+
if let Some(entry) = payment {
2232
// HTLCs within a payment should have the same payment hash.
23-
debug_assert!(htlcs.iter().all(|htlc| htlc.payment_hash == *payment_hash));
33+
debug_assert!(entry.htlcs.iter().all(|htlc| htlc.payment_hash == entry.payment_hash));
2434
// The given HTLC should not already be present.
25-
debug_assert!(htlcs.iter().all(|htlc| htlc.intercept_id != new_htlc.intercept_id));
26-
htlcs.push(new_htlc);
35+
debug_assert!(entry
36+
.htlcs
37+
.iter()
38+
.all(|htlc| htlc.intercept_id != new_htlc.intercept_id));
39+
entry.htlcs.push(new_htlc);
2740
let total_expected_outbound_amount_msat =
28-
htlcs.iter().map(|htlc| htlc.expected_outbound_amount_msat).sum();
29-
(total_expected_outbound_amount_msat, htlcs.len())
41+
entry.htlcs.iter().map(|htlc| htlc.expected_outbound_amount_msat).sum();
42+
(total_expected_outbound_amount_msat, entry.htlcs.len())
3043
} else {
3144
let expected_outbound_amount_msat = new_htlc.expected_outbound_amount_msat;
32-
self.payments.push((new_htlc.payment_hash, vec![new_htlc]));
45+
let entry =
46+
PaymentQueueEntry { payment_hash: new_htlc.payment_hash, htlcs: vec![new_htlc] };
47+
self.payments.push(entry);
3348
(expected_outbound_amount_msat, 1)
3449
}
3550
}
3651

37-
pub(crate) fn pop_greater_than_msat(
38-
&mut self, amount_msat: u64,
39-
) -> Option<(PaymentHash, Vec<InterceptedHTLC>)> {
40-
let position = self.payments.iter().position(|(_payment_hash, htlcs)| {
41-
htlcs.iter().map(|htlc| htlc.expected_outbound_amount_msat).sum::<u64>() >= amount_msat
52+
pub(crate) fn pop_greater_than_msat(&mut self, amount_msat: u64) -> Option<PaymentQueueEntry> {
53+
let position = self.payments.iter().position(|entry| {
54+
entry.htlcs.iter().map(|htlc| htlc.expected_outbound_amount_msat).sum::<u64>()
55+
>= amount_msat
4256
});
4357
position.map(|position| self.payments.remove(position))
4458
}
4559

4660
pub(crate) fn clear(&mut self) -> Vec<InterceptedHTLC> {
47-
self.payments.drain(..).map(|(_k, v)| v).flatten().collect()
61+
self.payments.drain(..).map(|entry| entry.htlcs).flatten().collect()
4862
}
4963
}
5064

65+
#[derive(Clone, PartialEq, Eq, Debug)]
66+
pub(crate) struct PaymentQueueEntry {
67+
pub(crate) payment_hash: PaymentHash,
68+
pub(crate) htlcs: Vec<InterceptedHTLC>,
69+
}
70+
5171
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
5272
pub(crate) struct InterceptedHTLC {
5373
pub(crate) intercept_id: InterceptId,
@@ -90,24 +110,23 @@ mod tests {
90110
}),
91111
(500_000_000, 2),
92112
);
93-
assert_eq!(
94-
payment_queue.pop_greater_than_msat(500_000_000),
95-
Some((
96-
PaymentHash([100; 32]),
97-
vec![
98-
InterceptedHTLC {
99-
intercept_id: InterceptId([0; 32]),
100-
expected_outbound_amount_msat: 200_000_000,
101-
payment_hash: PaymentHash([100; 32]),
102-
},
103-
InterceptedHTLC {
104-
intercept_id: InterceptId([2; 32]),
105-
expected_outbound_amount_msat: 300_000_000,
106-
payment_hash: PaymentHash([100; 32]),
107-
},
108-
]
109-
))
110-
);
113+
114+
let expected_entry = PaymentQueueEntry {
115+
payment_hash: PaymentHash([100; 32]),
116+
htlcs: vec![
117+
InterceptedHTLC {
118+
intercept_id: InterceptId([0; 32]),
119+
expected_outbound_amount_msat: 200_000_000,
120+
payment_hash: PaymentHash([100; 32]),
121+
},
122+
InterceptedHTLC {
123+
intercept_id: InterceptId([2; 32]),
124+
expected_outbound_amount_msat: 300_000_000,
125+
payment_hash: PaymentHash([100; 32]),
126+
},
127+
],
128+
};
129+
assert_eq!(payment_queue.pop_greater_than_msat(500_000_000), Some(expected_entry),);
111130
assert_eq!(
112131
payment_queue.clear(),
113132
vec![InterceptedHTLC {

lightning-liquidity/src/lsps2/service.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,10 @@ impl OutboundJITChannelState {
242242
} => {
243243
let mut payment_queue = core::mem::take(payment_queue);
244244
payment_queue.add_htlc(htlc);
245-
if let Some((_payment_hash, htlcs)) =
246-
payment_queue.pop_greater_than_msat(*opening_fee_msat)
247-
{
245+
if let Some(entry) = payment_queue.pop_greater_than_msat(*opening_fee_msat) {
248246
let forward_payment = HTLCInterceptedAction::ForwardPayment(
249247
*channel_id,
250-
FeePayment { htlcs, opening_fee_msat: *opening_fee_msat },
248+
FeePayment { htlcs: entry.htlcs, opening_fee_msat: *opening_fee_msat },
251249
);
252250
*self = OutboundJITChannelState::PendingPaymentForward {
253251
payment_queue,
@@ -277,12 +275,10 @@ impl OutboundJITChannelState {
277275
) -> Result<ForwardPaymentAction, ChannelStateError> {
278276
match self {
279277
OutboundJITChannelState::PendingChannelOpen { payment_queue, opening_fee_msat } => {
280-
if let Some((_payment_hash, htlcs)) =
281-
payment_queue.pop_greater_than_msat(*opening_fee_msat)
282-
{
278+
if let Some(entry) = payment_queue.pop_greater_than_msat(*opening_fee_msat) {
283279
let forward_payment = ForwardPaymentAction(
284280
channel_id,
285-
FeePayment { opening_fee_msat: *opening_fee_msat, htlcs },
281+
FeePayment { htlcs: entry.htlcs, opening_fee_msat: *opening_fee_msat },
286282
);
287283
*self = OutboundJITChannelState::PendingPaymentForward {
288284
payment_queue: core::mem::take(payment_queue),
@@ -311,12 +307,10 @@ impl OutboundJITChannelState {
311307
opening_fee_msat,
312308
channel_id,
313309
} => {
314-
if let Some((_payment_hash, htlcs)) =
315-
payment_queue.pop_greater_than_msat(*opening_fee_msat)
316-
{
310+
if let Some(entry) = payment_queue.pop_greater_than_msat(*opening_fee_msat) {
317311
let forward_payment = ForwardPaymentAction(
318312
*channel_id,
319-
FeePayment { htlcs, opening_fee_msat: *opening_fee_msat },
313+
FeePayment { htlcs: entry.htlcs, opening_fee_msat: *opening_fee_msat },
320314
);
321315
*self = OutboundJITChannelState::PendingPaymentForward {
322316
payment_queue: core::mem::take(payment_queue),

lightning-liquidity/src/lsps2/utils.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// This file is Copyright its original authors, visible in version control history.
2+
//
3+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5+
// http://opensource.org/licenses/MIT>, at your option.
6+
// You may not use this file except in accordance with one or both of these licenses.
7+
18
//! Utilities for implementing the bLIP-52 / LSPS2 standard.
29
310
use crate::lsps2::msgs::LSPS2OpeningFeeParams;

0 commit comments

Comments
 (0)