Skip to content

Commit 48e94cd

Browse files
author
Antoine Riard
committed
Implement block_disconnect for pruning of waiting-conf HTLC updates
Modify ChainListener API by adding height field to block_disconnect
1 parent 67d878d commit 48e94cd

File tree

5 files changed

+27
-8
lines changed

5 files changed

+27
-8
lines changed

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ impl<'a> MoneyLossDetector<'a> {
209209
if self.height > 0 && (self.max_height < 6 || self.height >= self.max_height - 6) {
210210
self.height -= 1;
211211
let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
212-
self.manager.block_disconnected(&header);
213-
self.monitor.block_disconnected(&header);
212+
self.manager.block_disconnected(&header, self.height as u32);
213+
self.monitor.block_disconnected(&header, self.height as u32);
214214
let removal_height = self.height;
215215
self.txids_confirmed.retain(|_, height| {
216216
removal_height != *height

src/chain/chaininterface.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ pub trait ChainListener: Sync + Send {
7878
fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]);
7979
/// Notifies a listener that a block was disconnected.
8080
/// Unlike block_connected, this *must* never be called twice for the same disconnect event.
81-
fn block_disconnected(&self, header: &BlockHeader);
81+
///
82+
/// Provide listeners with filtered txn previously registered as watched because channels are
83+
/// driven by onchain events (tx broadcast, height), a cancel of one of them may conduct to
84+
/// rollback state (ChannelMonitor or Channel).
85+
fn block_disconnected(&self, header: &BlockHeader, height: u32);
8286
}
8387

8488
/// An enum that represents the speed at which we want a transaction to confirm used for feerate
@@ -279,11 +283,11 @@ impl ChainWatchInterfaceUtil {
279283
}
280284

281285
/// Notify listeners that a block was disconnected.
282-
pub fn block_disconnected(&self, header: &BlockHeader) {
286+
pub fn block_disconnected(&self, block: &Block, height: u32) {
283287
let listeners = self.listeners.lock().unwrap().clone();
284288
for listener in listeners.iter() {
285289
match listener.upgrade() {
286-
Some(arc) => arc.block_disconnected(header),
290+
Some(arc) => arc.block_disconnected(&block.header, height),
287291
None => ()
288292
}
289293
}

src/ln/channelmanager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2474,7 +2474,7 @@ impl ChainListener for ChannelManager {
24742474
}
24752475

24762476
/// We force-close the channel without letting our counterparty participate in the shutdown
2477-
fn block_disconnected(&self, header: &BlockHeader) {
2477+
fn block_disconnected(&self, header: &BlockHeader, _: u32) {
24782478
let _ = self.total_consistency_lock.read().unwrap();
24792479
let mut failed_channels = Vec::new();
24802480
{

src/ln/channelmonitor.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,13 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
186186
pending_events.append(&mut new_events);
187187
}
188188

189-
fn block_disconnected(&self, _: &BlockHeader) { }
189+
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
190+
let block_hash = header.bitcoin_hash();
191+
let mut monitors = self.monitors.lock().unwrap();
192+
for monitor in monitors.values_mut() {
193+
monitor.block_disconnected(height, &block_hash);
194+
}
195+
}
190196
}
191197

192198
impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key> {
@@ -1796,6 +1802,13 @@ impl ChannelMonitor {
17961802
(watch_outputs, spendable_outputs, htlc_updated)
17971803
}
17981804

1805+
fn block_disconnected(&mut self, height: u32, block_hash: &Sha256dHash) {
1806+
if let Some(_) = self.htlc_updated_waiting_threshold_conf.remove(&(height + HTLC_FAIL_ANTI_REORG_DELAY - 1)) {
1807+
//We discard htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
1808+
}
1809+
self.last_block_hash = block_hash.clone();
1810+
}
1811+
17991812
pub(super) fn would_broadcast_at_height(&self, height: u32) -> bool {
18001813
// We need to consider all HTLCs which are:
18011814
// * in any unrevoked remote commitment transaction, as they could broadcast said

src/ln/functional_tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2674,8 +2674,10 @@ fn test_unconf_chan() {
26742674
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
26752675
headers.push(header.clone());
26762676
}
2677+
let mut height = 99;
26772678
while !headers.is_empty() {
2678-
nodes[0].node.block_disconnected(&headers.pop().unwrap());
2679+
nodes[0].node.block_disconnected(&headers.pop().unwrap(), height);
2680+
height -= 1;
26792681
}
26802682
check_closed_broadcast!(nodes[0]);
26812683
let channel_state = nodes[0].node.channel_state.lock().unwrap();

0 commit comments

Comments
 (0)