Skip to content

Commit 686ef08

Browse files
Generate PendingHTLCsForwardable upon retryable payment
1 parent 6351a99 commit 686ef08

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ impl MsgHandleErrInternal {
388388
/// Event::PendingHTLCsForwardable for the API guidelines indicating how long should be waited).
389389
/// This provides some limited amount of privacy. Ideally this would range from somewhere like one
390390
/// second to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly.
391-
const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u64 = 100;
391+
pub(super) const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u64 = 100;
392392

393393
/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should
394394
/// be sent in the order they appear in the return value, however sometimes the order needs to be

lightning/src/ln/outbound_payment.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use bitcoin::secp256k1::{self, Secp256k1, SecretKey};
1515

1616
use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient};
1717
use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
18-
use crate::ln::channelmanager::{HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, PaymentId};
18+
use crate::ln::channelmanager::{HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, MIN_HTLC_RELAY_HOLDING_CELL_MILLIS, PaymentId};
1919
use crate::ln::msgs::DecodeError;
2020
use crate::ln::onion_utils::HTLCFailReason;
2121
use crate::routing::router::{PaymentParameters, Route, RouteHop, RouteParameters, RoutePath};
@@ -29,6 +29,7 @@ use crate::util::time::tests::SinceEpoch;
2929
use core::cmp;
3030
use core::fmt::{self, Display, Formatter};
3131
use core::ops::Deref;
32+
use core::time::Duration;
3233

3334
use crate::prelude::*;
3435
use crate::sync::Mutex;
@@ -87,6 +88,11 @@ impl PendingOutboundPayment {
8788
}
8889
false
8990
}
91+
pub fn insert_previously_failed_scid(&mut self, scid: u64) {
92+
if let PendingOutboundPayment::Retryable { route_params: Some(params), .. } = self {
93+
params.payment_params.previously_failed_channels.push(scid);
94+
}
95+
}
9096
pub(super) fn is_fulfilled(&self) -> bool {
9197
match self {
9298
PendingOutboundPayment::Fulfilled { .. } => true,
@@ -793,7 +799,8 @@ impl OutboundPayments {
793799
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
794800
let mut all_paths_failed = false;
795801
let mut full_failure_ev = None;
796-
if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(*payment_id) {
802+
let mut pending_retry_ev = None;
803+
let attempts_remaining = if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(*payment_id) {
797804
if !payment.get_mut().remove(&session_priv_bytes, Some(&path)) {
798805
log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
799806
return
@@ -802,6 +809,10 @@ impl OutboundPayments {
802809
log_trace!(logger, "Received failure of HTLC with payment_hash {} after payment completion", log_bytes!(payment_hash.0));
803810
return
804811
}
812+
let is_retryable_now = payment.get().is_retryable_now();
813+
if let Some(scid) = short_channel_id {
814+
payment.get_mut().insert_previously_failed_scid(scid);
815+
}
805816
if payment.get().remaining_parts() == 0 {
806817
all_paths_failed = true;
807818
if payment.get().abandoned() {
@@ -812,10 +823,11 @@ impl OutboundPayments {
812823
payment.remove();
813824
}
814825
}
826+
is_retryable_now
815827
} else {
816828
log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
817829
return
818-
}
830+
};
819831
core::mem::drop(outbounds);
820832
let mut retry = if let Some(payment_params_data) = payment_params {
821833
let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
@@ -850,6 +862,12 @@ impl OutboundPayments {
850862
if let Some(scid) = short_channel_id {
851863
retry.as_mut().map(|r| r.payment_params.previously_failed_channels.push(scid));
852864
}
865+
if payment_retryable && attempts_remaining && retry.is_some() {
866+
debug_assert!(full_failure_ev.is_none());
867+
pending_retry_ev = Some(events::Event::PendingHTLCsForwardable {
868+
time_forwardable: Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS),
869+
});
870+
}
853871
events::Event::PaymentPathFailed {
854872
payment_id: Some(*payment_id),
855873
payment_hash: payment_hash.clone(),
@@ -869,6 +887,7 @@ impl OutboundPayments {
869887
let mut pending_events = pending_events.lock().unwrap();
870888
pending_events.push(path_failure);
871889
if let Some(ev) = full_failure_ev { pending_events.push(ev); }
890+
if let Some(ev) = pending_retry_ev { pending_events.push(ev); }
872891
}
873892

874893
pub(super) fn abandon_payment(&self, payment_id: PaymentId) -> Option<events::Event> {

0 commit comments

Comments
 (0)