Skip to content

Commit d35c728

Browse files
On initial send retries, avoid previously failed scids
Previously, we could have tried the same failed channels over and over until retries are exhausted.
1 parent c9722bf commit d35c728

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

lightning/src/ln/outbound_payment.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -732,8 +732,8 @@ impl OutboundPayments {
732732

733733
fn handle_pay_route_err<R: Deref, NS: Deref, ES: Deref, IH, SP, L: Deref>(
734734
&self, err: PaymentSendFailure, payment_id: PaymentId, payment_hash: PaymentHash, route: Route,
735-
route_params: RouteParameters, router: &R, first_hops: Vec<ChannelDetails>, inflight_htlcs: &IH,
736-
entropy_source: &ES, node_signer: &NS, best_block_height: u32, logger: &L,
735+
mut route_params: RouteParameters, router: &R, first_hops: Vec<ChannelDetails>,
736+
inflight_htlcs: &IH, entropy_source: &ES, node_signer: &NS, best_block_height: u32, logger: &L,
737737
pending_events: &Mutex<Vec<events::Event>>, send_payment_along_path: &SP,
738738
)
739739
where
@@ -747,11 +747,11 @@ impl OutboundPayments {
747747
{
748748
match err {
749749
PaymentSendFailure::AllFailedResendSafe(errs) => {
750-
Self::push_payment_path_failed_evs(payment_id, payment_hash, route.paths, errs.into_iter().map(|e| Err(e)), pending_events);
750+
Self::push_payment_path_failed_evs(payment_id, payment_hash, Some(&mut route_params), route.paths, errs.into_iter().map(|e| Err(e)), pending_events);
751751
self.retry_payment_internal(payment_id, route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path);
752752
},
753753
PaymentSendFailure::PartialFailure { failed_paths_retry: Some(retry), results, .. } => {
754-
Self::push_payment_path_failed_evs(payment_id, payment_hash, route.paths, results.into_iter(), pending_events);
754+
Self::push_payment_path_failed_evs(payment_id, payment_hash, None, route.paths, results.into_iter(), pending_events);
755755
// Some paths were sent, even if we failed to send the full MPP value our recipient may
756756
// misbehave and claim the funds, at which point we have to consider the payment sent, so
757757
// return `Ok()` here, ignoring any retry errors.
@@ -763,7 +763,7 @@ impl OutboundPayments {
763763
// initial HTLC-Add messages yet.
764764
},
765765
PaymentSendFailure::PathParameterError(results) => {
766-
Self::push_payment_path_failed_evs(payment_id, payment_hash, route.paths, results.into_iter(), pending_events);
766+
Self::push_payment_path_failed_evs(payment_id, payment_hash, None, route.paths, results.into_iter(), pending_events);
767767
self.abandon_payment(payment_id, pending_events);
768768
},
769769
PaymentSendFailure::ParameterError(e) => {
@@ -775,7 +775,8 @@ impl OutboundPayments {
775775
}
776776

777777
fn push_payment_path_failed_evs<I: ExactSizeIterator + Iterator<Item = Result<(), APIError>>>(
778-
payment_id: PaymentId, payment_hash: PaymentHash, paths: Vec<Vec<RouteHop>>, path_results: I,
778+
payment_id: PaymentId, payment_hash: PaymentHash,
779+
mut route_params: Option<&mut RouteParameters>, paths: Vec<Vec<RouteHop>>, path_results: I,
779780
pending_events: &Mutex<Vec<events::Event>>
780781
) {
781782
let mut events = pending_events.lock().unwrap();
@@ -785,7 +786,11 @@ impl OutboundPayments {
785786
let failed_scid = if let APIError::InvalidRoute { .. } = e {
786787
None
787788
} else {
788-
Some(path[0].short_channel_id)
789+
let scid = path[0].short_channel_id;
790+
if let Some(ref mut params) = route_params {
791+
params.payment_params.previously_failed_channels.push(scid);
792+
}
793+
Some(scid)
789794
};
790795
events.push(events::Event::PaymentPathFailed {
791796
payment_id: Some(payment_id),

lightning/src/ln/payment_tests.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,9 +2196,11 @@ fn immediate_retry_on_failure() {
21962196
route.paths[0][0].short_channel_id = chans[1].short_channel_id.unwrap();
21972197
route.paths[0][0].fee_msat = 50_000_000;
21982198
route.paths[1][0].fee_msat = 50_000_001;
2199+
let mut pay_params = route_params.payment_params.clone();
2200+
pay_params.previously_failed_channels.push(chans[0].short_channel_id.unwrap());
21992201
nodes[0].router.expect_find_route(RouteParameters {
2200-
payment_params: route_params.payment_params.clone(),
2201-
final_value_msat: amt_msat, final_cltv_expiry_delta: TEST_FINAL_CLTV
2202+
payment_params: pay_params, final_value_msat: amt_msat,
2203+
final_cltv_expiry_delta: TEST_FINAL_CLTV
22022204
}, Ok(route.clone()));
22032205

22042206
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();

0 commit comments

Comments
 (0)