Skip to content

Commit 2806be6

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 1709a1f commit 2806be6

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,39 +540,22 @@ 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::AllFailedRetrySafe(_) => {
570548
let mut payment_cache = self.payment_cache.lock().unwrap();
571-
let payment_info = payment_cache.get_mut(&payment_hash).unwrap();
572-
payment_info.attempts.count += 1;
573-
if self.retry.is_retryable_now(&payment_info.attempts) {
549+
let payment_attempts = payment_cache.get_mut(&payment_hash).unwrap();
550+
payment_attempts.count += 1;
551+
if self.retry.is_retryable_now(payment_attempts) {
574552
core::mem::drop(payment_cache);
575553
Ok(self.pay_internal(params, payment_hash, send_payment)?)
576554
} else {
577555
Err(e)
578556
}
579557
},
580-
PaymentSendFailure::PartialFailure { failed_paths_retry, payment_id, results } => {
581-
// If a `PartialFailure` event returns a result that is an `Ok()`, it means that
582-
// part of our payment is retried. When we receive `MonitorUpdateInProgress`, it
583-
// means that we are still waiting for our channel monitor update to be completed.
584-
for (result, path) in results.iter().zip(route.paths.into_iter()) {
585-
match result {
586-
Ok(_) | Err(APIError::MonitorUpdateInProgress) => {
587-
self.process_path_inflight_htlcs(payment_hash, path);
588-
},
589-
_ => {},
590-
}
591-
}
592-
558+
PaymentSendFailure::PartialFailure { failed_paths_retry, payment_id, .. } => {
593559
if let Some(retry_data) = failed_paths_retry {
594560
// Some paths were sent, even if we failed to send the full MPP value our
595561
// recipient may misbehave and claim the funds, at which point we have to
@@ -609,36 +575,16 @@ where
609575
}.map_err(|e| PaymentError::Sending(e))
610576
}
611577

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

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

668614
match self.payer.retry_payment(&route.as_ref().unwrap(), payment_id) {
669-
Ok(()) => {
670-
for path in route.unwrap().paths.into_iter() {
671-
self.process_path_inflight_htlcs(payment_hash, path);
672-
}
673-
Ok(())
674-
},
615+
Ok(()) => { Ok(()) },
675616
Err(PaymentSendFailure::ParameterError(_)) |
676617
Err(PaymentSendFailure::PathParameterError(_)) => {
677618
log_trace!(self.logger, "Failed to retry for payment {} due to bogus route/payment data, not retrying.", log_bytes!(payment_hash.0));
@@ -680,19 +621,7 @@ where
680621
Err(PaymentSendFailure::AllFailedRetrySafe(_)) => {
681622
self.retry_payment(payment_id, payment_hash, params)
682623
},
683-
Err(PaymentSendFailure::PartialFailure { failed_paths_retry, results, .. }) => {
684-
// If a `PartialFailure` error contains a result that is an `Ok()`, it means that
685-
// part of our payment is retried. When we receive `MonitorUpdateInProgress`, it
686-
// means that we are still waiting for our channel monitor update to complete.
687-
for (result, path) in results.iter().zip(route.unwrap().paths.into_iter()) {
688-
match result {
689-
Ok(_) | Err(APIError::MonitorUpdateInProgress) => {
690-
self.process_path_inflight_htlcs(payment_hash, path);
691-
},
692-
_ => {},
693-
}
694-
}
695-
624+
Err(PaymentSendFailure::PartialFailure { failed_paths_retry, .. }) => {
696625
if let Some(retry) = failed_paths_retry {
697626
// Always return Ok for the same reason as noted in pay_internal.
698627
let _ = self.retry_payment(payment_id, payment_hash, &retry);
@@ -731,16 +660,6 @@ where
731660
/// Returns a bool indicating whether the processed event should be forwarded to a user-provided
732661
/// event handler.
733662
fn handle_event_internal(&self, event: &Event) -> bool {
734-
match event {
735-
Event::PaymentPathFailed { payment_hash, path, .. }
736-
| Event::PaymentPathSuccessful { path, payment_hash: Some(payment_hash), .. }
737-
| Event::ProbeSuccessful { payment_hash, path, .. }
738-
| Event::ProbeFailed { payment_hash, path, .. } => {
739-
self.remove_path_inflight_htlcs(*payment_hash, path);
740-
},
741-
_ => {},
742-
}
743-
744663
match event {
745664
Event::PaymentPathFailed {
746665
payment_id, payment_hash, payment_failed_permanently, path, short_channel_id, retry, ..
@@ -776,7 +695,7 @@ where
776695
let mut payment_cache = self.payment_cache.lock().unwrap();
777696
let attempts = payment_cache
778697
.remove(payment_hash)
779-
.map_or(1, |payment_info| payment_info.attempts.count + 1);
698+
.map_or(1, |attempts| attempts.count + 1);
780699
log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts);
781700
},
782701
Event::ProbeSuccessful { payment_hash, path, .. } => {

0 commit comments

Comments
 (0)