Skip to content

Commit 66da9f7

Browse files
author
tnull
committed
Treat replayed LSPS2 HTLCs idempotently
Replayed intercepted HTLC events should not duplicate queued payments or panic after restart. Ignore already-queued intercept IDs so persisted queues remain stable across event replay. Co-Authored-By: HAL 9000
1 parent 76eac43 commit 66da9f7

1 file changed

Lines changed: 25 additions & 8 deletions

File tree

lightning-liquidity/src/lsps2/payment_queue.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,29 @@ impl PaymentQueue {
2626
PaymentQueue { payments: Vec::new() }
2727
}
2828

29+
fn payment_status(entry: &PaymentQueueEntry) -> (u64, usize) {
30+
let total_expected_outbound_amount_msat =
31+
entry.htlcs.iter().map(|htlc| htlc.expected_outbound_amount_msat).sum();
32+
(total_expected_outbound_amount_msat, entry.htlcs.len())
33+
}
34+
2935
pub(crate) fn add_htlc(&mut self, new_htlc: InterceptedHTLC) -> (u64, usize) {
36+
if let Some(entry) = self
37+
.payments
38+
.iter()
39+
.find(|entry| entry.htlcs.iter().any(|htlc| htlc.intercept_id == new_htlc.intercept_id))
40+
{
41+
debug_assert_eq!(entry.payment_hash, new_htlc.payment_hash);
42+
return Self::payment_status(entry);
43+
}
44+
3045
let payment =
3146
self.payments.iter_mut().find(|entry| entry.payment_hash == new_htlc.payment_hash);
3247
if let Some(entry) = payment {
3348
// HTLCs within a payment should have the same payment hash.
3449
debug_assert!(entry.htlcs.iter().all(|htlc| htlc.payment_hash == entry.payment_hash));
35-
// The given HTLC should not already be present.
36-
debug_assert!(entry
37-
.htlcs
38-
.iter()
39-
.all(|htlc| htlc.intercept_id != new_htlc.intercept_id));
4050
entry.htlcs.push(new_htlc);
41-
let total_expected_outbound_amount_msat =
42-
entry.htlcs.iter().map(|htlc| htlc.expected_outbound_amount_msat).sum();
43-
(total_expected_outbound_amount_msat, entry.htlcs.len())
51+
Self::payment_status(entry)
4452
} else {
4553
let expected_outbound_amount_msat = new_htlc.expected_outbound_amount_msat;
4654
let entry =
@@ -127,6 +135,15 @@ mod tests {
127135
(500_000_000, 2),
128136
);
129137

138+
assert_eq!(
139+
payment_queue.add_htlc(InterceptedHTLC {
140+
intercept_id: InterceptId([2; 32]),
141+
expected_outbound_amount_msat: 300_000_000,
142+
payment_hash: PaymentHash([100; 32]),
143+
}),
144+
(500_000_000, 2),
145+
);
146+
130147
let expected_entry = PaymentQueueEntry {
131148
payment_hash: PaymentHash([100; 32]),
132149
htlcs: vec![

0 commit comments

Comments
 (0)