Skip to content

Commit 3a29e4b

Browse files
Persist retryable HTLCs in ChannelManager
Used in upcoming commits to store retries when payment paths fail, then retry when processing pending HTLC forwards.
1 parent 0c10e67 commit 3a29e4b

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use crate::ln::channel::{Channel, ChannelError, ChannelUpdateStatus, UpdateFulfi
4646
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
4747
#[cfg(any(feature = "_test_utils", test))]
4848
use crate::ln::features::InvoiceFeatures;
49-
use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RoutePath, Router};
49+
use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, RoutePath, Router};
5050
use crate::ln::msgs;
5151
use crate::ln::onion_utils;
5252
use crate::ln::onion_utils::HTLCFailReason;
@@ -6517,12 +6517,19 @@ where
65176517
debug_assert!(false, "While we have code to serialize pending_claiming_payments, the map should always be empty until a later PR");
65186518
}
65196519

6520+
let mut retryable_htlcs = None;
6521+
let our_retryable_htlcs = self.pending_outbound_payments.retryable_htlcs.lock().unwrap();
6522+
if our_retryable_htlcs.len() != 0 {
6523+
retryable_htlcs = Some(our_retryable_htlcs);
6524+
}
6525+
65206526
write_tlv_fields!(writer, {
65216527
(1, pending_outbound_payments_no_retry, required),
65226528
(2, pending_intercepted_htlcs, option),
65236529
(3, pending_outbound_payments, required),
65246530
(4, pending_claiming_payments, option),
65256531
(5, self.our_network_pubkey, required),
6532+
(6, retryable_htlcs, option),
65266533
(7, self.fake_scid_rand_bytes, required),
65276534
(9, htlc_purposes, vec_type),
65286535
(11, self.probing_cookie_secret, required),
@@ -6857,6 +6864,7 @@ where
68576864
let mut pending_outbound_payments_no_retry: Option<HashMap<PaymentId, HashSet<[u8; 32]>>> = None;
68586865
let mut pending_outbound_payments = None;
68596866
let mut pending_intercepted_htlcs: Option<HashMap<InterceptId, PendingAddHTLCInfo>> = Some(HashMap::new());
6867+
let mut retryable_htlcs: Option<Vec<(PaymentId, RouteParameters)>> = Some(Vec::new());
68606868
let mut received_network_pubkey: Option<PublicKey> = None;
68616869
let mut fake_scid_rand_bytes: Option<[u8; 32]> = None;
68626870
let mut probing_cookie_secret: Option<[u8; 32]> = None;
@@ -6868,6 +6876,7 @@ where
68686876
(3, pending_outbound_payments, option),
68696877
(4, pending_claiming_payments, option),
68706878
(5, received_network_pubkey, option),
6879+
(6, retryable_htlcs, option),
68716880
(7, fake_scid_rand_bytes, option),
68726881
(9, claimable_htlc_purposes, vec_type),
68736882
(11, probing_cookie_secret, option),
@@ -7136,7 +7145,9 @@ where
71367145
}),
71377146
inbound_payment_key: expanded_inbound_key,
71387147
pending_inbound_payments: Mutex::new(pending_inbound_payments),
7139-
pending_outbound_payments: OutboundPayments { pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()) },
7148+
pending_outbound_payments: OutboundPayments::from_outbounds(
7149+
pending_outbound_payments.unwrap(),
7150+
retryable_htlcs.unwrap()),
71407151
pending_intercepted_htlcs: Mutex::new(pending_intercepted_htlcs.unwrap()),
71417152

71427153
forward_htlcs: Mutex::new(forward_htlcs),

lightning/src/ln/outbound_payment.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,12 +341,25 @@ pub enum PaymentSendFailure {
341341

342342
pub(super) struct OutboundPayments {
343343
pub(super) pending_outbound_payments: Mutex<HashMap<PaymentId, PendingOutboundPayment>>,
344+
/// HTLCs that may be retried using the given `RouteParameters`.
345+
pub(super) retryable_htlcs: Mutex<Vec<(PaymentId, RouteParameters)>>,
344346
}
345347

346348
impl OutboundPayments {
347349
pub(super) fn new() -> Self {
348350
Self {
349-
pending_outbound_payments: Mutex::new(HashMap::new())
351+
pending_outbound_payments: Mutex::new(HashMap::new()),
352+
retryable_htlcs: Mutex::new(Vec::new()),
353+
}
354+
}
355+
356+
pub(super) fn from_outbounds(
357+
pending_outbound_payments: HashMap<PaymentId, PendingOutboundPayment>,
358+
retryable_htlcs: Vec<(PaymentId, RouteParameters)>)
359+
-> Self {
360+
Self {
361+
pending_outbound_payments: Mutex::new(pending_outbound_payments),
362+
retryable_htlcs: Mutex::new(retryable_htlcs),
350363
}
351364
}
352365

lightning/src/util/ser.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,30 @@ impl Readable for Vec<u8> {
665665
Ok(ret)
666666
}
667667
}
668+
669+
impl<A: Writeable, B: Writeable> Writeable for Vec<(A, B)> {
670+
#[inline]
671+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
672+
(self.len() as u16).write(w)?;
673+
for item in self.iter() {
674+
item.write(w)?;
675+
}
676+
Ok(())
677+
}
678+
}
679+
680+
impl<A: Readable, B: Readable> Readable for Vec<(A, B)> {
681+
#[inline]
682+
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
683+
let len: u16 = Readable::read(r)?;
684+
let mut ret = Vec::with_capacity(len as usize);
685+
for _ in 0..len {
686+
ret.push(<(A, B) as Readable>::read(r)?);
687+
}
688+
Ok(ret)
689+
}
690+
}
691+
668692
impl Writeable for Vec<ecdsa::Signature> {
669693
#[inline]
670694
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {

0 commit comments

Comments
 (0)