Skip to content

Commit a2489b1

Browse files
Deduplicate PendingHTLCsForwardable events when queueing
1 parent bf03d4c commit a2489b1

File tree

2 files changed

+32
-30
lines changed

2 files changed

+32
-30
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3737,16 +3737,19 @@ where
37373737
// being fully configured. See the docs for `ChannelManagerReadArgs` for more.
37383738
match source {
37393739
HTLCSource::OutboundRoute { ref path, ref session_priv, ref payment_id, ref payment_params, .. } => {
3740-
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);
3740+
if self.pending_outbound_payments.fail_htlc(source, payment_hash, onion_error, path,
3741+
session_priv, payment_id, payment_params, self.probing_cookie_secret, &self.secp_ctx,
3742+
&self.pending_events, &self.logger)
3743+
{ self.push_pending_forwards_ev(); }
37413744
},
37423745
HTLCSource::PreviousHopData(HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint }) => {
37433746
log_trace!(self.logger, "Failing HTLC with payment_hash {} backwards from us with {:?}", log_bytes!(payment_hash.0), onion_error);
37443747
let err_packet = onion_error.get_encrypted_failure_packet(incoming_packet_shared_secret, phantom_shared_secret);
37453748

3746-
let mut forward_event = None;
3749+
let mut push_forward_ev = false;
37473750
let mut forward_htlcs = self.forward_htlcs.lock().unwrap();
37483751
if forward_htlcs.is_empty() {
3749-
forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS));
3752+
push_forward_ev = true;
37503753
}
37513754
match forward_htlcs.entry(*short_channel_id) {
37523755
hash_map::Entry::Occupied(mut entry) => {
@@ -3757,12 +3760,8 @@ where
37573760
}
37583761
}
37593762
mem::drop(forward_htlcs);
3763+
if push_forward_ev { self.push_pending_forwards_ev(); }
37603764
let mut pending_events = self.pending_events.lock().unwrap();
3761-
if let Some(time) = forward_event {
3762-
pending_events.push(events::Event::PendingHTLCsForwardable {
3763-
time_forwardable: time
3764-
});
3765-
}
37663765
pending_events.push(events::Event::HTLCHandlingFailed {
37673766
prev_channel_id: outpoint.to_channel_id(),
37683767
failed_next_destination: destination,
@@ -4839,7 +4838,7 @@ where
48394838
#[inline]
48404839
fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, OutPoint, u128, Vec<(PendingHTLCInfo, u64)>)]) {
48414840
for &mut (prev_short_channel_id, prev_funding_outpoint, prev_user_channel_id, ref mut pending_forwards) in per_source_pending_forwards {
4842-
let mut forward_event = None;
4841+
let mut push_forward_event = false;
48434842
let mut new_intercept_events = Vec::new();
48444843
let mut failed_intercept_forwards = Vec::new();
48454844
if !pending_forwards.is_empty() {
@@ -4897,7 +4896,7 @@ where
48974896
// We don't want to generate a PendingHTLCsForwardable event if only intercepted
48984897
// payments are being processed.
48994898
if forward_htlcs_empty {
4900-
forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS));
4899+
push_forward_event = true;
49014900
}
49024901
entry.insert(vec!(HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
49034902
prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, prev_user_channel_id, forward_info })));
@@ -4915,16 +4914,21 @@ where
49154914
let mut events = self.pending_events.lock().unwrap();
49164915
events.append(&mut new_intercept_events);
49174916
}
4917+
if push_forward_event { self.push_pending_forwards_ev() }
4918+
}
4919+
}
49184920

4919-
match forward_event {
4920-
Some(time) => {
4921-
let mut pending_events = self.pending_events.lock().unwrap();
4922-
pending_events.push(events::Event::PendingHTLCsForwardable {
4923-
time_forwardable: time
4924-
});
4925-
}
4926-
None => {},
4927-
}
4921+
// We only want to push a PendingHTLCsForwardable event if no others are queued.
4922+
fn push_pending_forwards_ev(&self) {
4923+
let mut pending_events = self.pending_events.lock().unwrap();
4924+
let forward_ev_exists = pending_events.iter()
4925+
.find(|ev| if let events::Event::PendingHTLCsForwardable { .. } = ev { true } else { false })
4926+
.is_some();
4927+
if !forward_ev_exists {
4928+
pending_events.push(events::Event::PendingHTLCsForwardable {
4929+
time_forwardable:
4930+
Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS),
4931+
});
49284932
}
49294933
}
49304934

lightning/src/ln/outbound_payment.rs

Lines changed: 9 additions & 11 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;
@@ -1012,12 +1011,13 @@ impl OutboundPayments {
10121011
});
10131012
}
10141013

1014+
// Returns a bool indicating whether a PendingHTLCsForwardable event should be generated.
10151015
pub(super) fn fail_htlc<L: Deref>(
10161016
&self, source: &HTLCSource, payment_hash: &PaymentHash, onion_error: &HTLCFailReason,
10171017
path: &Vec<RouteHop>, session_priv: &SecretKey, payment_id: &PaymentId,
10181018
payment_params: &Option<PaymentParameters>, probing_cookie_secret: [u8; 32],
10191019
secp_ctx: &Secp256k1<secp256k1::All>, pending_events: &Mutex<Vec<events::Event>>, logger: &L
1020-
) where L::Target: Logger {
1020+
) -> bool where L::Target: Logger {
10211021
#[cfg(test)]
10221022
let (network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
10231023
#[cfg(not(test))]
@@ -1044,16 +1044,16 @@ impl OutboundPayments {
10441044

10451045
let mut all_paths_failed = false;
10461046
let mut full_failure_ev = None;
1047-
let mut pending_retry_ev = None;
1047+
let mut pending_retry_ev = false;
10481048
let mut retry = None;
10491049
let attempts_remaining = if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(*payment_id) {
10501050
if !payment.get_mut().remove(&session_priv_bytes, Some(&path)) {
10511051
log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
1052-
return
1052+
return false
10531053
}
10541054
if payment.get().is_fulfilled() {
10551055
log_trace!(logger, "Received failure of HTLC with payment_hash {} after payment completion", log_bytes!(payment_hash.0));
1056-
return
1056+
return false
10571057
}
10581058
let mut is_retryable_now = payment.get().is_auto_retryable_now();
10591059
if let Some(scid) = short_channel_id {
@@ -1105,7 +1105,7 @@ impl OutboundPayments {
11051105
is_retryable_now
11061106
} else {
11071107
log_trace!(logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
1108-
return
1108+
return false
11091109
};
11101110
core::mem::drop(outbounds);
11111111
log_trace!(logger, "Failing outbound payment HTLC with payment_hash {}", log_bytes!(payment_hash.0));
@@ -1137,9 +1137,7 @@ impl OutboundPayments {
11371137
// payment will sit in our outbounds forever.
11381138
if attempts_remaining && !already_awaiting_retry {
11391139
debug_assert!(full_failure_ev.is_none());
1140-
pending_retry_ev = Some(events::Event::PendingHTLCsForwardable {
1141-
time_forwardable: Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS),
1142-
});
1140+
pending_retry_ev = true;
11431141
}
11441142
events::Event::PaymentPathFailed {
11451143
payment_id: Some(*payment_id),
@@ -1160,7 +1158,7 @@ impl OutboundPayments {
11601158
let mut pending_events = pending_events.lock().unwrap();
11611159
pending_events.push(path_failure);
11621160
if let Some(ev) = full_failure_ev { pending_events.push(ev); }
1163-
if let Some(ev) = pending_retry_ev { pending_events.push(ev); }
1161+
pending_retry_ev
11641162
}
11651163

11661164
pub(super) fn abandon_payment(

0 commit comments

Comments
 (0)