Skip to content

Commit 85e2097

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 27987af commit 85e2097

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;
@@ -6524,12 +6524,19 @@ where
65246524
debug_assert!(false, "While we have code to serialize pending_claiming_payments, the map should always be empty until a later PR");
65256525
}
65266526

6527+
let mut retryable_htlcs = None;
6528+
let our_retryable_htlcs = self.pending_outbound_payments.retryable_htlcs.lock().unwrap();
6529+
if our_retryable_htlcs.len() != 0 {
6530+
retryable_htlcs = Some(our_retryable_htlcs);
6531+
}
6532+
65276533
write_tlv_fields!(writer, {
65286534
(1, pending_outbound_payments_no_retry, required),
65296535
(2, pending_intercepted_htlcs, option),
65306536
(3, pending_outbound_payments, required),
65316537
(4, pending_claiming_payments, option),
65326538
(5, self.our_network_pubkey, required),
6539+
(6, retryable_htlcs, option),
65336540
(7, self.fake_scid_rand_bytes, required),
65346541
(9, htlc_purposes, vec_type),
65356542
(11, self.probing_cookie_secret, required),
@@ -6864,6 +6871,7 @@ where
68646871
let mut pending_outbound_payments_no_retry: Option<HashMap<PaymentId, HashSet<[u8; 32]>>> = None;
68656872
let mut pending_outbound_payments = None;
68666873
let mut pending_intercepted_htlcs: Option<HashMap<InterceptId, PendingAddHTLCInfo>> = Some(HashMap::new());
6874+
let mut retryable_htlcs: Option<Vec<(PaymentId, RouteParameters)>> = Some(Vec::new());
68676875
let mut received_network_pubkey: Option<PublicKey> = None;
68686876
let mut fake_scid_rand_bytes: Option<[u8; 32]> = None;
68696877
let mut probing_cookie_secret: Option<[u8; 32]> = None;
@@ -6875,6 +6883,7 @@ where
68756883
(3, pending_outbound_payments, option),
68766884
(4, pending_claiming_payments, option),
68776885
(5, received_network_pubkey, option),
6886+
(6, retryable_htlcs, option),
68786887
(7, fake_scid_rand_bytes, option),
68796888
(9, claimable_htlc_purposes, vec_type),
68806889
(11, probing_cookie_secret, option),
@@ -7143,7 +7152,9 @@ where
71437152
}),
71447153
inbound_payment_key: expanded_inbound_key,
71457154
pending_inbound_payments: Mutex::new(pending_inbound_payments),
7146-
pending_outbound_payments: OutboundPayments { pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()) },
7155+
pending_outbound_payments: OutboundPayments::from_outbounds(
7156+
pending_outbound_payments.unwrap(),
7157+
retryable_htlcs.unwrap()),
71477158
pending_intercepted_htlcs: Mutex::new(pending_intercepted_htlcs.unwrap()),
71487159

71497160
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)