Skip to content

Commit 9644d2c

Browse files
Deduplicate PendingHTLCsForwardable events when generating
1 parent a067ae8 commit 9644d2c

File tree

3 files changed

+29
-30
lines changed

3 files changed

+29
-30
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,16 +3748,18 @@ where
37483748
// being fully configured. See the docs for `ChannelManagerReadArgs` for more.
37493749
match source {
37503750
HTLCSource::OutboundRoute { ref path, ref session_priv, ref payment_id, ref payment_params, .. } => {
3751-
self.pending_outbound_payments.fail_htlc(source, payment_hash, onion_error, path, session_priv, payment_id, payment_params, self.probing_cookie_secret, &self.secp_ctx, &self.pending_events, &self.logger);
3751+
if self.pending_outbound_payments.fail_htlc(source, payment_hash, onion_error, path,
3752+
session_priv, payment_id, payment_params, self.probing_cookie_secret, &self.secp_ctx,
3753+
&self.pending_events, &self.logger).is_some()
3754+
{ self.push_pending_forwards_ev(); }
37523755
},
37533756
HTLCSource::PreviousHopData(HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint }) => {
37543757
log_trace!(self.logger, "Failing HTLC with payment_hash {} backwards from us with {:?}", log_bytes!(payment_hash.0), onion_error);
37553758
let err_packet = onion_error.get_encrypted_failure_packet(incoming_packet_shared_secret, phantom_shared_secret);
37563759

3757-
let mut forward_event = None;
37583760
let mut forward_htlcs = self.forward_htlcs.lock().unwrap();
37593761
if forward_htlcs.is_empty() {
3760-
forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS));
3762+
self.push_pending_forwards_ev();
37613763
}
37623764
match forward_htlcs.entry(*short_channel_id) {
37633765
hash_map::Entry::Occupied(mut entry) => {
@@ -3769,11 +3771,6 @@ where
37693771
}
37703772
mem::drop(forward_htlcs);
37713773
let mut pending_events = self.pending_events.lock().unwrap();
3772-
if let Some(time) = forward_event {
3773-
pending_events.push(events::Event::PendingHTLCsForwardable {
3774-
time_forwardable: time
3775-
});
3776-
}
37773774
pending_events.push(events::Event::HTLCHandlingFailed {
37783775
prev_channel_id: outpoint.to_channel_id(),
37793776
failed_next_destination: destination,
@@ -3782,6 +3779,19 @@ where
37823779
}
37833780
}
37843781

3782+
// We only want to push a PendingHTLCsForwardable event if no others are queued.
3783+
fn push_pending_forwards_ev(&self) {
3784+
let mut pending_events = self.pending_events.lock().unwrap();
3785+
let forward_ev_exists = pending_events.iter()
3786+
.find(|ev| if let events::Event::PendingHTLCsForwardable { .. } = ev { true } else { false })
3787+
.is_some();
3788+
if !forward_ev_exists {
3789+
pending_events.push(events::Event::PendingHTLCsForwardable {
3790+
time_forwardable: Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS),
3791+
});
3792+
}
3793+
}
3794+
37853795
/// Provides a payment preimage in response to [`Event::PaymentClaimable`], generating any
37863796
/// [`MessageSendEvent`]s needed to claim the payment.
37873797
///
@@ -4908,7 +4918,7 @@ where
49084918
// We don't want to generate a PendingHTLCsForwardable event if only intercepted
49094919
// payments are being processed.
49104920
if forward_htlcs_empty {
4911-
forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS));
4921+
forward_event = Some(());
49124922
}
49134923
entry.insert(vec!(HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
49144924
prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, prev_user_channel_id, forward_info })));
@@ -4928,12 +4938,7 @@ where
49284938
}
49294939

49304940
match forward_event {
4931-
Some(time) => {
4932-
let mut pending_events = self.pending_events.lock().unwrap();
4933-
pending_events.push(events::Event::PendingHTLCsForwardable {
4934-
time_forwardable: time
4935-
});
4936-
}
4941+
Some(()) => self.push_pending_forwards_ev(),
49374942
None => {},
49384943
}
49394944
}

lightning/src/ln/outbound_payment.rs

Lines changed: 8 additions & 10 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::{ChannelDetails, HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, MIN_HTLC_RELAY_HOLDING_CELL_MILLIS, PaymentId};
18+
use crate::ln::channelmanager::{ChannelDetails, HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, PaymentId};
1919
use crate::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA as LDK_DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA;
2020
use crate::ln::msgs::DecodeError;
2121
use crate::ln::onion_utils::HTLCFailReason;
@@ -30,7 +30,6 @@ use crate::util::time::tests::SinceEpoch;
3030
use core::cmp;
3131
use core::fmt::{self, Display, Formatter};
3232
use core::ops::Deref;
33-
use core::time::Duration;
3433

3534
use crate::prelude::*;
3635
use crate::sync::Mutex;
@@ -990,12 +989,13 @@ impl OutboundPayments {
990989
});
991990
}
992991

992+
// Returns a bool indicating whether a PendingHTLCsForwardable event should be generated.
993993
pub(super) fn fail_htlc<L: Deref>(
994994
&self, source: &HTLCSource, payment_hash: &PaymentHash, onion_error: &HTLCFailReason,
995995
path: &Vec<RouteHop>, session_priv: &SecretKey, payment_id: &PaymentId,
996996
payment_params: &Option<PaymentParameters>, probing_cookie_secret: [u8; 32],
997997
secp_ctx: &Secp256k1<secp256k1::All>, pending_events: &Mutex<Vec<events::Event>>, logger: &L
998-
) where L::Target: Logger {
998+
) -> Option<()> where L::Target: Logger {
999999
#[cfg(test)]
10001000
let (network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
10011001
#[cfg(not(test))]
@@ -1011,11 +1011,11 @@ impl OutboundPayments {
10111011
let attempts_remaining = if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(*payment_id) {
10121012
if !payment.get_mut().remove(&session_priv_bytes, Some(&path)) {
10131013
log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
1014-
return
1014+
return None
10151015
}
10161016
if payment.get().is_fulfilled() {
10171017
log_trace!(logger, "Received failure of HTLC with payment_hash {} after payment completion", log_bytes!(payment_hash.0));
1018-
return
1018+
return None
10191019
}
10201020
let is_retryable_now = payment.get().is_auto_retryable_now();
10211021
if let Some(scid) = short_channel_id {
@@ -1061,7 +1061,7 @@ impl OutboundPayments {
10611061
is_retryable_now
10621062
} else {
10631063
log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
1064-
return
1064+
return None
10651065
};
10661066
core::mem::drop(outbounds);
10671067
log_trace!(logger, "Failing outbound payment HTLC with payment_hash {}", log_bytes!(payment_hash.0));
@@ -1091,9 +1091,7 @@ impl OutboundPayments {
10911091
}
10921092
if payment_retryable && attempts_remaining && retry.is_some() {
10931093
debug_assert!(full_failure_ev.is_none());
1094-
pending_retry_ev = Some(events::Event::PendingHTLCsForwardable {
1095-
time_forwardable: Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS),
1096-
});
1094+
pending_retry_ev = Some(());
10971095
}
10981096
events::Event::PaymentPathFailed {
10991097
payment_id: Some(*payment_id),
@@ -1114,7 +1112,7 @@ impl OutboundPayments {
11141112
let mut pending_events = pending_events.lock().unwrap();
11151113
pending_events.push(path_failure);
11161114
if let Some(ev) = full_failure_ev { pending_events.push(ev); }
1117-
if let Some(ev) = pending_retry_ev { pending_events.push(ev); }
1115+
pending_retry_ev
11181116
}
11191117

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

lightning/src/ln/payment_tests.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,7 +2404,7 @@ fn no_extra_retries_on_back_to_back_fail() {
24042404
// Because we now retry payments as a batch, we simply return a single-path route in the
24052405
// second, batched, request, have that fail, then complete the payment via `abandon_payment`.
24062406
let mut events = nodes[0].node.get_and_clear_pending_events();
2407-
assert_eq!(events.len(), 4);
2407+
assert_eq!(events.len(), 3);
24082408
match events[0] {
24092409
Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, .. } => {
24102410
assert_eq!(payment_hash, ev_payment_hash);
@@ -2423,10 +2423,6 @@ fn no_extra_retries_on_back_to_back_fail() {
24232423
},
24242424
_ => panic!("Unexpected event"),
24252425
}
2426-
match events[3] {
2427-
Event::PendingHTLCsForwardable { .. } => {},
2428-
_ => panic!("Unexpected event"),
2429-
}
24302426

24312427
nodes[0].node.process_pending_htlc_forwards();
24322428
let retry_htlc_updates = SendEvent::from_node(&nodes[0]);

0 commit comments

Comments
 (0)