Skip to content

Commit 0e66322

Browse files
committed
Change payment_cache to accept PaymentInfo
Introduces a new `PaymentInfo` struct that contains both the previous `attempts` count that was tracked as well as the paths that are also currently inflight. A new struct, `PaymentInfoRouteHop` is also created as a subset of `RouteHop` so we only store the information we need.
1 parent 36bffb5 commit 0e66322

File tree

1 file changed

+47
-14
lines changed

1 file changed

+47
-14
lines changed

lightning-invoice/src/payment.rs

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,41 @@ where
188188
logger: L,
189189
event_handler: E,
190190
/// Caches the overall attempts at making a payment, which is updated prior to retrying.
191-
payment_cache: Mutex<HashMap<PaymentHash, PaymentAttempts<T>>>,
191+
payment_cache: Mutex<HashMap<PaymentHash, PaymentInfo<T>>>,
192192
retry: Retry,
193193
}
194194

195+
/// Used by [`InvoicePayerUsingTime::payment_cache`] to track the payments that are either
196+
/// currently being made, or have outstanding paths that need retrying.
197+
struct PaymentInfo<T: Time> {
198+
attempts: PaymentAttempts<T>,
199+
paths: Vec<Vec<PaymentInfoRouteHop>>,
200+
}
201+
202+
/// Subset of properties that is represented in `RouteHop`, so we only store what we need in
203+
/// [`InvoicePayerUsingTime::payment_cache`]
204+
///
205+
/// [`RouteHop`]: crate::routing::router::RouteHop
206+
#[derive(Clone, PartialEq, Eq)]
207+
struct PaymentInfoRouteHop {
208+
/// The node_id of the node at this hop.
209+
pub pubkey: PublicKey,
210+
/// The channel that should be used from the previous hop to reach this node.
211+
pub short_channel_id: u64,
212+
/// The fee taken on this hop (for paying for the use of the *next* channel in the path).
213+
/// For the last hop, this should be the full value of the payment (might be more than
214+
/// requested if we had to match htlc_minimum_msat).
215+
pub fee_msat: u64,
216+
}
217+
218+
impl<T: Time> PaymentInfo<T> {
219+
fn new() -> Self {
220+
PaymentInfo {
221+
attempts: PaymentAttempts::new(),
222+
paths: vec![],
223+
}
224+
}
225+
}
195226
/// Storing minimal payment attempts information required for determining if a outbound payment can
196227
/// be retried.
197228
#[derive(Clone, Copy)]
@@ -361,7 +392,7 @@ where
361392
let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
362393
match self.payment_cache.lock().unwrap().entry(payment_hash) {
363394
hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
364-
hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
395+
hash_map::Entry::Vacant(entry) => entry.insert(PaymentInfo::new()),
365396
};
366397

367398
let payment_secret = Some(invoice.payment_secret().clone());
@@ -397,7 +428,7 @@ where
397428
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
398429
match self.payment_cache.lock().unwrap().entry(payment_hash) {
399430
hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
400-
hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
431+
hash_map::Entry::Vacant(entry) => entry.insert(PaymentInfo::new()),
401432
};
402433

403434
let route_params = RouteParameters {
@@ -437,9 +468,9 @@ where
437468
PaymentSendFailure::PathParameterError(_) => Err(e),
438469
PaymentSendFailure::AllFailedRetrySafe(_) => {
439470
let mut payment_cache = self.payment_cache.lock().unwrap();
440-
let payment_attempts = payment_cache.get_mut(&payment_hash).unwrap();
441-
payment_attempts.count += 1;
442-
if self.retry.is_retryable_now(payment_attempts) {
471+
let payment_info = payment_cache.get_mut(&payment_hash).unwrap();
472+
payment_info.attempts.count += 1;
473+
if self.retry.is_retryable_now(&payment_info.attempts) {
443474
core::mem::drop(payment_cache);
444475
Ok(self.pay_internal(params, payment_hash, send_payment)?)
445476
} else {
@@ -469,13 +500,15 @@ where
469500
fn retry_payment(
470501
&self, payment_id: PaymentId, payment_hash: PaymentHash, params: &RouteParameters
471502
) -> Result<(), ()> {
472-
let attempts =
473-
*self.payment_cache.lock().unwrap().entry(payment_hash)
474-
.and_modify(|attempts| attempts.count += 1)
475-
.or_insert(PaymentAttempts {
476-
count: 1,
477-
first_attempted_at: T::now()
478-
});
503+
let attempts = self.payment_cache.lock().unwrap().entry(payment_hash)
504+
.and_modify(|info| info.attempts.count += 1 )
505+
.or_insert_with(|| PaymentInfo {
506+
attempts: PaymentAttempts {
507+
count: 1,
508+
first_attempted_at: T::now(),
509+
},
510+
paths: vec![],
511+
}).attempts;
479512

480513
if !self.retry.is_retryable_now(&attempts) {
481514
log_trace!(self.logger, "Payment {} exceeded maximum attempts; not retrying ({})", log_bytes!(payment_hash.0), attempts);
@@ -583,7 +616,7 @@ where
583616
let mut payment_cache = self.payment_cache.lock().unwrap();
584617
let attempts = payment_cache
585618
.remove(payment_hash)
586-
.map_or(1, |attempts| attempts.count + 1);
619+
.map_or(1, |payment_info| payment_info.attempts.count + 1);
587620
log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts);
588621
},
589622
Event::ProbeSuccessful { payment_hash, path, .. } => {

0 commit comments

Comments
 (0)