Skip to content

Commit 30d7805

Browse files
committed
Remove paths from PaymentInfo in payment_cache
In c70bd1f, we implemented tracking HTLCs by adding path information for pending HTLCs to `InvoicePayer`’s `payment_cache` when receiving specific events. Since we can now track inflight HTLCs entirely within ChannelManager, there is no longer a need for this to exist.
1 parent 897ecbf commit 30d7805

File tree

1 file changed

+17
-98
lines changed

1 file changed

+17
-98
lines changed

lightning-invoice/src/payment.rs

Lines changed: 17 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
147147
use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
148148
use lightning::ln::msgs::LightningError;
149149
use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, Router};
150-
use lightning::util::errors::APIError;
151150
use lightning::util::events::{Event, EventHandler};
152151
use lightning::util::logger::Logger;
153152
use crate::time_utils::Time;
@@ -187,26 +186,10 @@ where
187186
logger: L,
188187
event_handler: E,
189188
/// Caches the overall attempts at making a payment, which is updated prior to retrying.
190-
payment_cache: Mutex<HashMap<PaymentHash, PaymentInfo<T>>>,
189+
payment_cache: Mutex<HashMap<PaymentHash, PaymentAttempts<T>>>,
191190
retry: Retry,
192191
}
193192

194-
/// Used by [`InvoicePayerUsingTime::payment_cache`] to track the payments that are either
195-
/// currently being made, or have outstanding paths that need retrying.
196-
struct PaymentInfo<T: Time> {
197-
attempts: PaymentAttempts<T>,
198-
paths: Vec<Vec<RouteHop>>,
199-
}
200-
201-
impl<T: Time> PaymentInfo<T> {
202-
fn new() -> Self {
203-
PaymentInfo {
204-
attempts: PaymentAttempts::new(),
205-
paths: vec![],
206-
}
207-
}
208-
}
209-
210193
/// Storing minimal payment attempts information required for determining if a outbound payment can
211194
/// be retried.
212195
#[derive(Clone, Copy)]
@@ -445,7 +428,7 @@ where
445428
let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
446429
match self.payment_cache.lock().unwrap().entry(payment_hash) {
447430
hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
448-
hash_map::Entry::Vacant(entry) => entry.insert(PaymentInfo::new()),
431+
hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
449432
};
450433

451434
let payment_secret = Some(invoice.payment_secret().clone());
@@ -509,7 +492,7 @@ where
509492
) -> Result<(), PaymentError> {
510493
match self.payment_cache.lock().unwrap().entry(payment_hash) {
511494
hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
512-
hash_map::Entry::Vacant(entry) => entry.insert(PaymentInfo::new()),
495+
hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
513496
};
514497

515498
let route_params = RouteParameters {
@@ -543,39 +526,22 @@ where
543526
).map_err(|e| PaymentError::Routing(e))?;
544527

545528
match send_payment(&route) {
546-
Ok(()) => {
547-
for path in route.paths {
548-
self.process_path_inflight_htlcs(payment_hash, path);
549-
}
550-
Ok(())
551-
},
529+
Ok(()) => { Ok(()) },
552530
Err(e) => match e {
553531
PaymentSendFailure::ParameterError(_) => Err(e),
554532
PaymentSendFailure::PathParameterError(_) => Err(e),
555533
PaymentSendFailure::AllFailedRetrySafe(_) => {
556534
let mut payment_cache = self.payment_cache.lock().unwrap();
557-
let payment_info = payment_cache.get_mut(&payment_hash).unwrap();
558-
payment_info.attempts.count += 1;
559-
if self.retry.is_retryable_now(&payment_info.attempts) {
535+
let payment_attempts = payment_cache.get_mut(&payment_hash).unwrap();
536+
payment_attempts.count += 1;
537+
if self.retry.is_retryable_now(payment_attempts) {
560538
core::mem::drop(payment_cache);
561539
Ok(self.pay_internal(params, payment_hash, send_payment)?)
562540
} else {
563541
Err(e)
564542
}
565543
},
566-
PaymentSendFailure::PartialFailure { failed_paths_retry, payment_id, results } => {
567-
// If a `PartialFailure` event returns a result that is an `Ok()`, it means that
568-
// part of our payment is retried. When we receive `MonitorUpdateInProgress`, it
569-
// means that we are still waiting for our channel monitor update to be completed.
570-
for (result, path) in results.iter().zip(route.paths.into_iter()) {
571-
match result {
572-
Ok(_) | Err(APIError::MonitorUpdateInProgress) => {
573-
self.process_path_inflight_htlcs(payment_hash, path);
574-
},
575-
_ => {},
576-
}
577-
}
578-
544+
PaymentSendFailure::PartialFailure { failed_paths_retry, payment_id, .. } => {
579545
if let Some(retry_data) = failed_paths_retry {
580546
// Some paths were sent, even if we failed to send the full MPP value our
581547
// recipient may misbehave and claim the funds, at which point we have to
@@ -595,36 +561,16 @@ where
595561
}.map_err(|e| PaymentError::Sending(e))
596562
}
597563

598-
// Takes in a path to have its information stored in `payment_cache`. This is done for paths
599-
// that are pending retry.
600-
fn process_path_inflight_htlcs(&self, payment_hash: PaymentHash, path: Vec<RouteHop>) {
601-
self.payment_cache.lock().unwrap().entry(payment_hash)
602-
.or_insert_with(|| PaymentInfo::new())
603-
.paths.push(path);
604-
}
605-
606-
// Find the path we want to remove in `payment_cache`. If it doesn't exist, do nothing.
607-
fn remove_path_inflight_htlcs(&self, payment_hash: PaymentHash, path: &Vec<RouteHop>) {
608-
self.payment_cache.lock().unwrap().entry(payment_hash)
609-
.and_modify(|payment_info| {
610-
if let Some(idx) = payment_info.paths.iter().position(|p| p == path) {
611-
payment_info.paths.swap_remove(idx);
612-
}
613-
});
614-
}
615-
616564
fn retry_payment(
617565
&self, payment_id: PaymentId, payment_hash: PaymentHash, params: &RouteParameters
618566
) -> Result<(), ()> {
619-
let attempts = self.payment_cache.lock().unwrap().entry(payment_hash)
620-
.and_modify(|info| info.attempts.count += 1 )
621-
.or_insert_with(|| PaymentInfo {
622-
attempts: PaymentAttempts {
567+
let attempts =
568+
*self.payment_cache.lock().unwrap().entry(payment_hash)
569+
.and_modify(|attempts| attempts.count += 1)
570+
.or_insert(PaymentAttempts {
623571
count: 1,
624-
first_attempted_at: T::now(),
625-
},
626-
paths: vec![],
627-
}).attempts;
572+
first_attempted_at: T::now()
573+
});
628574

629575
if !self.retry.is_retryable_now(&attempts) {
630576
log_trace!(self.logger, "Payment {} exceeded maximum attempts; not retrying ({})", log_bytes!(payment_hash.0), attempts);
@@ -652,12 +598,7 @@ where
652598
}
653599

654600
match self.payer.retry_payment(&route.as_ref().unwrap(), payment_id) {
655-
Ok(()) => {
656-
for path in route.unwrap().paths.into_iter() {
657-
self.process_path_inflight_htlcs(payment_hash, path);
658-
}
659-
Ok(())
660-
},
601+
Ok(()) => { Ok(()) },
661602
Err(PaymentSendFailure::ParameterError(_)) |
662603
Err(PaymentSendFailure::PathParameterError(_)) => {
663604
log_trace!(self.logger, "Failed to retry for payment {} due to bogus route/payment data, not retrying.", log_bytes!(payment_hash.0));
@@ -666,19 +607,7 @@ where
666607
Err(PaymentSendFailure::AllFailedRetrySafe(_)) => {
667608
self.retry_payment(payment_id, payment_hash, params)
668609
},
669-
Err(PaymentSendFailure::PartialFailure { failed_paths_retry, results, .. }) => {
670-
// If a `PartialFailure` error contains a result that is an `Ok()`, it means that
671-
// part of our payment is retried. When we receive `MonitorUpdateInProgress`, it
672-
// means that we are still waiting for our channel monitor update to complete.
673-
for (result, path) in results.iter().zip(route.unwrap().paths.into_iter()) {
674-
match result {
675-
Ok(_) | Err(APIError::MonitorUpdateInProgress) => {
676-
self.process_path_inflight_htlcs(payment_hash, path);
677-
},
678-
_ => {},
679-
}
680-
}
681-
610+
Err(PaymentSendFailure::PartialFailure { failed_paths_retry, .. }) => {
682611
if let Some(retry) = failed_paths_retry {
683612
// Always return Ok for the same reason as noted in pay_internal.
684613
let _ = self.retry_payment(payment_id, payment_hash, &retry);
@@ -714,16 +643,6 @@ where
714643
L::Target: Logger,
715644
{
716645
fn handle_event(&self, event: &Event) {
717-
match event {
718-
Event::PaymentPathFailed { payment_hash, path, .. }
719-
| Event::PaymentPathSuccessful { path, payment_hash: Some(payment_hash), .. }
720-
| Event::ProbeSuccessful { payment_hash, path, .. }
721-
| Event::ProbeFailed { payment_hash, path, .. } => {
722-
self.remove_path_inflight_htlcs(*payment_hash, path);
723-
},
724-
_ => {},
725-
}
726-
727646
match event {
728647
Event::PaymentPathFailed {
729648
payment_id, payment_hash, payment_failed_permanently, path, short_channel_id, retry, ..
@@ -759,7 +678,7 @@ where
759678
let mut payment_cache = self.payment_cache.lock().unwrap();
760679
let attempts = payment_cache
761680
.remove(payment_hash)
762-
.map_or(1, |payment_info| payment_info.attempts.count + 1);
681+
.map_or(1, |attempts| attempts.count + 1);
763682
log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts);
764683
},
765684
Event::ProbeSuccessful { payment_hash, path, .. } => {

0 commit comments

Comments
 (0)