Skip to content

Commit e479317

Browse files
Unify session_priv removal on PaymentSendFailure
When an outbound payment fails while paying to a route, we need to remove the session_privs for each failed path in the outbound payment. Previously we were sometimes removing in pay_route_internal and sometimes in handle_pay_route_err, so refactor this so we always remove in handle_pay_route_err.
1 parent b2269f4 commit e479317

File tree

1 file changed

+21
-25
lines changed

1 file changed

+21
-25
lines changed

lightning/src/ln/outbound_payment.rs

+21-25
Original file line numberDiff line numberDiff line change
@@ -1460,10 +1460,24 @@ impl OutboundPayments {
14601460
{
14611461
match err {
14621462
PaymentSendFailure::AllFailedResendSafe(errs) => {
1463+
self.remove_session_privs(payment_id, route.paths.iter().zip(onion_session_privs.iter()));
14631464
Self::push_path_failed_evs_and_scids(payment_id, payment_hash, &mut route_params, route.paths, errs.into_iter().map(|e| Err(e)), logger, pending_events);
14641465
self.find_route_and_send_payment(payment_hash, payment_id, route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path);
14651466
},
14661467
PaymentSendFailure::PartialFailure { failed_paths_retry: Some(mut retry), results, .. } => {
1468+
debug_assert_eq!(results.len(), route.paths.len());
1469+
debug_assert_eq!(results.len(), onion_session_privs.len());
1470+
let failed_paths = results.iter().zip(route.paths.iter().zip(onion_session_privs.iter()))
1471+
.filter_map(|(path_res, (path, session_priv))| {
1472+
match path_res {
1473+
// While a MonitorUpdateInProgress is an Err(_), the payment is still
1474+
// considered "in flight" and we shouldn't remove it from the
1475+
// PendingOutboundPayment set.
1476+
Ok(_) | Err(APIError::MonitorUpdateInProgress) => None,
1477+
_ => Some((path, session_priv))
1478+
}
1479+
});
1480+
self.remove_session_privs(payment_id, failed_paths);
14671481
Self::push_path_failed_evs_and_scids(payment_id, payment_hash, &mut retry, route.paths, results.into_iter(), logger, pending_events);
14681482
// Some paths were sent, even if we failed to send the full MPP value our recipient may
14691483
// misbehave and claim the funds, at which point we have to consider the payment sent, so
@@ -1477,13 +1491,13 @@ impl OutboundPayments {
14771491
},
14781492
PaymentSendFailure::PathParameterError(results) => {
14791493
log_error!(logger, "Failed to send to route due to parameter error in a single path. Your router is buggy");
1480-
self.remove_session_privs(payment_id, &route, onion_session_privs);
1494+
self.remove_session_privs(payment_id, route.paths.iter().zip(onion_session_privs.iter()));
14811495
Self::push_path_failed_evs_and_scids(payment_id, payment_hash, &mut route_params, route.paths, results.into_iter(), logger, pending_events);
14821496
self.abandon_payment(payment_id, PaymentFailureReason::UnexpectedError, pending_events);
14831497
},
14841498
PaymentSendFailure::ParameterError(e) => {
14851499
log_error!(logger, "Failed to send to route due to parameter error: {:?}. Your router is buggy", e);
1486-
self.remove_session_privs(payment_id, &route, onion_session_privs);
1500+
self.remove_session_privs(payment_id, route.paths.iter().zip(onion_session_privs.iter()));
14871501
self.abandon_payment(payment_id, PaymentFailureReason::UnexpectedError, pending_events);
14881502
},
14891503
PaymentSendFailure::DuplicatePayment => debug_assert!(false), // unreachable
@@ -1525,12 +1539,12 @@ impl OutboundPayments {
15251539

15261540
// If a payment fails after adding the pending payment but before any HTLCs are locked into
15271541
// channels, we need to clear the session_privs in order for abandoning the payment to succeed.
1528-
fn remove_session_privs(
1529-
&self, payment_id: PaymentId, route: &Route, onion_session_privs: Vec<[u8; 32]>
1542+
fn remove_session_privs<'a, I: Iterator<Item = (&'a Path, &'a [u8; 32])>>(
1543+
&self, payment_id: PaymentId, path_session_priv: I
15301544
) {
15311545
if let Some(payment) = self.pending_outbound_payments.lock().unwrap().get_mut(&payment_id) {
1532-
for (path, session_priv_bytes) in route.paths.iter().zip(onion_session_privs.into_iter()) {
1533-
let removed = payment.remove(&session_priv_bytes, Some(path));
1546+
for (path, session_priv_bytes) in path_session_priv {
1547+
let removed = payment.remove(session_priv_bytes, Some(path));
15341548
debug_assert!(removed, "This can't happen as the payment has an entry for this path added by callers");
15351549
}
15361550
} else {
@@ -1812,29 +1826,11 @@ impl OutboundPayments {
18121826
let mut results = Vec::new();
18131827
debug_assert_eq!(route.paths.len(), onion_session_privs.len());
18141828
for (path, session_priv_bytes) in route.paths.iter().zip(onion_session_privs.iter()) {
1815-
let mut path_res = send_payment_along_path(SendAlongPathArgs {
1829+
let path_res = send_payment_along_path(SendAlongPathArgs {
18161830
path: &path, payment_hash: &payment_hash, recipient_onion, total_value,
18171831
cur_height, payment_id, keysend_preimage: &keysend_preimage, invoice_request,
18181832
session_priv_bytes: *session_priv_bytes
18191833
});
1820-
match path_res {
1821-
Ok(_) => {},
1822-
Err(APIError::MonitorUpdateInProgress) => {
1823-
// While a MonitorUpdateInProgress is an Err(_), the payment is still
1824-
// considered "in flight" and we shouldn't remove it from the
1825-
// PendingOutboundPayment set.
1826-
},
1827-
Err(_) => {
1828-
let mut pending_outbounds = self.pending_outbound_payments.lock().unwrap();
1829-
if let Some(payment) = pending_outbounds.get_mut(&payment_id) {
1830-
let removed = payment.remove(&session_priv_bytes, Some(path));
1831-
debug_assert!(removed, "This can't happen as the payment has an entry for this path added by callers");
1832-
} else {
1833-
debug_assert!(false, "This can't happen as the payment was added by callers");
1834-
path_res = Err(APIError::APIMisuseError { err: "Internal error: payment disappeared during processing. Please report this bug!".to_owned() });
1835-
}
1836-
}
1837-
}
18381834
results.push(path_res);
18391835
}
18401836
let mut has_ok = false;

0 commit comments

Comments
 (0)