Skip to content

Commit 2e81813

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 89f162c commit 2e81813

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;
@@ -200,26 +199,10 @@ pub struct InvoicePayerUsingTime<
200199
logger: L,
201200
event_handler: E,
202201
/// Caches the overall attempts at making a payment, which is updated prior to retrying.
203-
payment_cache: Mutex<HashMap<PaymentHash, PaymentInfo<T>>>,
202+
payment_cache: Mutex<HashMap<PaymentHash, PaymentAttempts<T>>>,
204203
retry: Retry,
205204
}
206205

207-
/// Used by [`InvoicePayerUsingTime::payment_cache`] to track the payments that are either
208-
/// currently being made, or have outstanding paths that need retrying.
209-
struct PaymentInfo<T: Time> {
210-
attempts: PaymentAttempts<T>,
211-
paths: Vec<Vec<RouteHop>>,
212-
}
213-
214-
impl<T: Time> PaymentInfo<T> {
215-
fn new() -> Self {
216-
PaymentInfo {
217-
attempts: PaymentAttempts::new(),
218-
paths: vec![],
219-
}
220-
}
221-
}
222-
223206
/// Storing minimal payment attempts information required for determining if a outbound payment can
224207
/// be retried.
225208
#[derive(Clone, Copy)]
@@ -459,7 +442,7 @@ where
459442
let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
460443
match self.payment_cache.lock().unwrap().entry(payment_hash) {
461444
hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
462-
hash_map::Entry::Vacant(entry) => entry.insert(PaymentInfo::new()),
445+
hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
463446
};
464447

465448
let payment_secret = Some(invoice.payment_secret().clone());
@@ -523,7 +506,7 @@ where
523506
) -> Result<(), PaymentError> {
524507
match self.payment_cache.lock().unwrap().entry(payment_hash) {
525508
hash_map::Entry::Occupied(_) => return Err(PaymentError::Invoice("payment pending")),
526-
hash_map::Entry::Vacant(entry) => entry.insert(PaymentInfo::new()),
509+
hash_map::Entry::Vacant(entry) => entry.insert(PaymentAttempts::new()),
527510
};
528511

529512
let route_params = RouteParameters {
@@ -557,40 +540,23 @@ where
557540
).map_err(|e| PaymentError::Routing(e))?;
558541

559542
match send_payment(&route) {
560-
Ok(()) => {
561-
for path in route.paths {
562-
self.process_path_inflight_htlcs(payment_hash, path);
563-
}
564-
Ok(())
565-
},
543+
Ok(()) => Ok(()),
566544
Err(e) => match e {
567545
PaymentSendFailure::ParameterError(_) => Err(e),
568546
PaymentSendFailure::PathParameterError(_) => Err(e),
569547
PaymentSendFailure::DuplicatePayment => Err(e),
570548
PaymentSendFailure::AllFailedResendSafe(_) => {
571549
let mut payment_cache = self.payment_cache.lock().unwrap();
572-
let payment_info = payment_cache.get_mut(&payment_hash).unwrap();
573-
payment_info.attempts.count += 1;
574-
if self.retry.is_retryable_now(&payment_info.attempts) {
550+
let payment_attempts = payment_cache.get_mut(&payment_hash).unwrap();
551+
payment_attempts.count += 1;
552+
if self.retry.is_retryable_now(payment_attempts) {
575553
core::mem::drop(payment_cache);
576554
Ok(self.pay_internal(params, payment_hash, send_payment)?)
577555
} else {
578556
Err(e)
579557
}
580558
},
581-
PaymentSendFailure::PartialFailure { failed_paths_retry, payment_id, results } => {
582-
// If a `PartialFailure` event returns a result that is an `Ok()`, it means that
583-
// part of our payment is retried. When we receive `MonitorUpdateInProgress`, it
584-
// means that we are still waiting for our channel monitor update to be completed.
585-
for (result, path) in results.iter().zip(route.paths.into_iter()) {
586-
match result {
587-
Ok(_) | Err(APIError::MonitorUpdateInProgress) => {
588-
self.process_path_inflight_htlcs(payment_hash, path);
589-
},
590-
_ => {},
591-
}
592-
}
593-
559+
PaymentSendFailure::PartialFailure { failed_paths_retry, payment_id, .. } => {
594560
if let Some(retry_data) = failed_paths_retry {
595561
// Some paths were sent, even if we failed to send the full MPP value our
596562
// recipient may misbehave and claim the funds, at which point we have to
@@ -610,36 +576,16 @@ where
610576
}.map_err(|e| PaymentError::Sending(e))
611577
}
612578

613-
// Takes in a path to have its information stored in `payment_cache`. This is done for paths
614-
// that are pending retry.
615-
fn process_path_inflight_htlcs(&self, payment_hash: PaymentHash, path: Vec<RouteHop>) {
616-
self.payment_cache.lock().unwrap().entry(payment_hash)
617-
.or_insert_with(|| PaymentInfo::new())
618-
.paths.push(path);
619-
}
620-
621-
// Find the path we want to remove in `payment_cache`. If it doesn't exist, do nothing.
622-
fn remove_path_inflight_htlcs(&self, payment_hash: PaymentHash, path: &Vec<RouteHop>) {
623-
self.payment_cache.lock().unwrap().entry(payment_hash)
624-
.and_modify(|payment_info| {
625-
if let Some(idx) = payment_info.paths.iter().position(|p| p == path) {
626-
payment_info.paths.swap_remove(idx);
627-
}
628-
});
629-
}
630-
631579
fn retry_payment(
632580
&self, payment_id: PaymentId, payment_hash: PaymentHash, params: &RouteParameters
633581
) -> Result<(), ()> {
634-
let attempts = self.payment_cache.lock().unwrap().entry(payment_hash)
635-
.and_modify(|info| info.attempts.count += 1 )
636-
.or_insert_with(|| PaymentInfo {
637-
attempts: PaymentAttempts {
582+
let attempts =
583+
*self.payment_cache.lock().unwrap().entry(payment_hash)
584+
.and_modify(|attempts| attempts.count += 1)
585+
.or_insert(PaymentAttempts {
638586
count: 1,
639-
first_attempted_at: T::now(),
640-
},
641-
paths: vec![],
642-
}).attempts;
587+
first_attempted_at: T::now()
588+
});
643589

644590
if !self.retry.is_retryable_now(&attempts) {
645591
log_trace!(self.logger, "Payment {} exceeded maximum attempts; not retrying ({})", log_bytes!(payment_hash.0), attempts);
@@ -667,12 +613,7 @@ where
667613
}
668614

669615
match self.payer.retry_payment(&route.as_ref().unwrap(), payment_id) {
670-
Ok(()) => {
671-
for path in route.unwrap().paths.into_iter() {
672-
self.process_path_inflight_htlcs(payment_hash, path);
673-
}
674-
Ok(())
675-
},
616+
Ok(()) => Ok(()),
676617
Err(PaymentSendFailure::ParameterError(_)) |
677618
Err(PaymentSendFailure::PathParameterError(_)) => {
678619
log_trace!(self.logger, "Failed to retry for payment {} due to bogus route/payment data, not retrying.", log_bytes!(payment_hash.0));
@@ -685,19 +626,7 @@ where
685626
log_error!(self.logger, "Got a DuplicatePayment error when attempting to retry a payment, this shouldn't happen.");
686627
Err(())
687628
}
688-
Err(PaymentSendFailure::PartialFailure { failed_paths_retry, results, .. }) => {
689-
// If a `PartialFailure` error contains a result that is an `Ok()`, it means that
690-
// part of our payment is retried. When we receive `MonitorUpdateInProgress`, it
691-
// means that we are still waiting for our channel monitor update to complete.
692-
for (result, path) in results.iter().zip(route.unwrap().paths.into_iter()) {
693-
match result {
694-
Ok(_) | Err(APIError::MonitorUpdateInProgress) => {
695-
self.process_path_inflight_htlcs(payment_hash, path);
696-
},
697-
_ => {},
698-
}
699-
}
700-
629+
Err(PaymentSendFailure::PartialFailure { failed_paths_retry, .. }) => {
701630
if let Some(retry) = failed_paths_retry {
702631
// Always return Ok for the same reason as noted in pay_internal.
703632
let _ = self.retry_payment(payment_id, payment_hash, &retry);
@@ -736,16 +665,6 @@ where
736665
/// Returns a bool indicating whether the processed event should be forwarded to a user-provided
737666
/// event handler.
738667
fn handle_event_internal(&self, event: &Event) -> bool {
739-
match event {
740-
Event::PaymentPathFailed { payment_hash, path, .. }
741-
| Event::PaymentPathSuccessful { path, payment_hash: Some(payment_hash), .. }
742-
| Event::ProbeSuccessful { payment_hash, path, .. }
743-
| Event::ProbeFailed { payment_hash, path, .. } => {
744-
self.remove_path_inflight_htlcs(*payment_hash, path);
745-
},
746-
_ => {},
747-
}
748-
749668
match event {
750669
Event::PaymentPathFailed {
751670
payment_id, payment_hash, payment_failed_permanently, path, short_channel_id, retry, ..
@@ -781,7 +700,7 @@ where
781700
let mut payment_cache = self.payment_cache.lock().unwrap();
782701
let attempts = payment_cache
783702
.remove(payment_hash)
784-
.map_or(1, |payment_info| payment_info.attempts.count + 1);
703+
.map_or(1, |attempts| attempts.count + 1);
785704
log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts);
786705
},
787706
Event::ProbeSuccessful { payment_hash, path, .. } => {

0 commit comments

Comments
 (0)