Skip to content

Commit 75353cf

Browse files
committed
Check for duplicate HTLC events having matured
1 parent 5f48163 commit 75353cf

File tree

2 files changed

+46
-21
lines changed

2 files changed

+46
-21
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ impl OnchainEventEntry {
480480
}
481481

482482
fn has_reached_confirmation_threshold(&self, height: u32) -> bool {
483-
self.confirmation_threshold() == height
483+
height >= self.confirmation_threshold()
484484
}
485485
}
486486

@@ -1874,9 +1874,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
18741874
let mut watch_outputs = Vec::new();
18751875

18761876
macro_rules! wait_threshold_conf {
1877-
($height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1877+
($source: expr, $commitment_tx: expr, $payment_hash: expr) => {
18781878
self.onchain_events_waiting_threshold_conf.retain(|ref entry| {
1879-
if entry.height != $height { return true; }
1879+
if entry.height != height { return true; }
18801880
match entry.event {
18811881
OnchainEvent::HTLCUpdate { ref htlc_update } => {
18821882
htlc_update.0 != $source
@@ -1925,7 +1925,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
19251925
for &(ref htlc, _, ref source) in &$holder_tx.htlc_outputs {
19261926
if htlc.transaction_output_index.is_none() {
19271927
if let &Some(ref source) = source {
1928-
wait_threshold_conf!(height, source.clone(), "lastest", htlc.payment_hash.clone());
1928+
wait_threshold_conf!(source.clone(), "lastest", htlc.payment_hash.clone());
19291929
}
19301930
}
19311931
}
@@ -2065,31 +2065,56 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
20652065
claimable_outpoints.append(&mut new_outpoints);
20662066
}
20672067

2068+
// Find which on-chain events have reached their confirmation threshold.
20682069
let onchain_events_waiting_threshold_conf =
20692070
self.onchain_events_waiting_threshold_conf.drain(..).collect::<Vec<_>>();
2071+
let mut onchain_events_reaching_threshold_conf = Vec::new();
20702072
for entry in onchain_events_waiting_threshold_conf {
20712073
if entry.has_reached_confirmation_threshold(height) {
2072-
match entry.event {
2073-
OnchainEvent::HTLCUpdate { htlc_update } => {
2074-
log_trace!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!((htlc_update.1).0));
2075-
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
2076-
payment_hash: htlc_update.1,
2077-
payment_preimage: None,
2078-
source: htlc_update.0,
2079-
}));
2080-
},
2081-
OnchainEvent::MaturingOutput { descriptor } => {
2082-
log_trace!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor));
2083-
self.pending_events.push(Event::SpendableOutputs {
2084-
outputs: vec![descriptor]
2085-
});
2086-
}
2087-
}
2074+
onchain_events_reaching_threshold_conf.push(entry);
20882075
} else {
20892076
self.onchain_events_waiting_threshold_conf.push(entry);
20902077
}
20912078
}
20922079

2080+
// Used to check for duplicate HTLC resolutions.
2081+
#[cfg(debug_assertions)]
2082+
let unconfirmed_htlcs: Vec<_> = self.onchain_events_waiting_threshold_conf
2083+
.iter()
2084+
.filter_map(|entry| match &entry.event {
2085+
OnchainEvent::HTLCUpdate { htlc_update } => Some(htlc_update.0.clone()),
2086+
OnchainEvent::MaturingOutput { .. } => None,
2087+
})
2088+
.collect();
2089+
#[cfg(debug_assertions)]
2090+
let mut confirmed_htlcs = Vec::new();
2091+
2092+
// Produce actionable events from on-chain events having reached their threshold.
2093+
for entry in onchain_events_reaching_threshold_conf.drain(..) {
2094+
match entry.event {
2095+
OnchainEvent::HTLCUpdate { htlc_update } => {
2096+
// Check for duplicate HTLC resolutions.
2097+
debug_assert!(unconfirmed_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none());
2098+
debug_assert!(confirmed_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none());
2099+
#[cfg(debug_assertions)]
2100+
confirmed_htlcs.push(htlc_update.0.clone());
2101+
2102+
log_trace!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!((htlc_update.1).0));
2103+
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
2104+
payment_hash: htlc_update.1,
2105+
payment_preimage: None,
2106+
source: htlc_update.0,
2107+
}));
2108+
},
2109+
OnchainEvent::MaturingOutput { descriptor } => {
2110+
log_trace!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor));
2111+
self.pending_events.push(Event::SpendableOutputs {
2112+
outputs: vec![descriptor]
2113+
});
2114+
}
2115+
}
2116+
}
2117+
20932118
self.onchain_tx_handler.update_claims_view(&txn_matched, claimable_outpoints, Some(height), &&*broadcaster, &&*fee_estimator, &&*logger);
20942119
self.last_block_hash = block_hash;
20952120

lightning/src/ln/onchaintx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl OnchainEventEntry {
5454
}
5555

5656
fn has_reached_confirmation_threshold(&self, height: u32) -> bool {
57-
self.confirmation_threshold() == height
57+
height >= self.confirmation_threshold()
5858
}
5959
}
6060

0 commit comments

Comments
 (0)