Skip to content

Commit c0d1400

Browse files
author
Antoine Riard
committed
Implement delay channel closing in ChannelManager until maturation
Add pruning of waiting-conf channel closing at block_disconnect Fix tests broken by introduced change
1 parent 7529f7e commit c0d1400

File tree

2 files changed

+210
-118
lines changed

2 files changed

+210
-118
lines changed

src/ln/channelmanager.rs

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ pub(super) struct ChannelHolder {
262262
/// Messages to send to peers - pushed to in the same lock that they are generated in (except
263263
/// for broadcast messages, where ordering isn't as strict).
264264
pub(super) pending_msg_events: Vec<events::MessageSendEvent>,
265+
/// Due to reorgs, we want to be sure that commitment txn has enough depth
266+
/// (HTLC_FAIL_ANTI_REORG_DELAY).
267+
/// before to close channel. Doing it to early would block us to pass backward
268+
/// preimage in case of successful claim on onward channel. Key is block
269+
/// height timer, value is array of channels id, waiting their closing.
270+
pub(super) channel_closing_waiting_threshold_conf: HashMap<u32, Vec<[u8; 32]>>,
265271
}
266272
pub(super) struct MutChannelHolder<'a> {
267273
pub(super) by_id: &'a mut HashMap<[u8; 32], Channel>,
@@ -270,6 +276,7 @@ pub(super) struct MutChannelHolder<'a> {
270276
pub(super) forward_htlcs: &'a mut HashMap<u64, Vec<HTLCForwardInfo>>,
271277
pub(super) claimable_htlcs: &'a mut HashMap<PaymentHash, Vec<(u64, HTLCPreviousHopData)>>,
272278
pub(super) pending_msg_events: &'a mut Vec<events::MessageSendEvent>,
279+
pub(super) channel_closing_waiting_threshold_conf: &'a mut HashMap<u32, Vec<[u8; 32]>>,
273280
}
274281
impl ChannelHolder {
275282
pub(super) fn borrow_parts(&mut self) -> MutChannelHolder {
@@ -280,6 +287,7 @@ impl ChannelHolder {
280287
forward_htlcs: &mut self.forward_htlcs,
281288
claimable_htlcs: &mut self.claimable_htlcs,
282289
pending_msg_events: &mut self.pending_msg_events,
290+
channel_closing_waiting_threshold_conf: &mut self.channel_closing_waiting_threshold_conf,
283291
}
284292
}
285293
}
@@ -553,6 +561,7 @@ impl ChannelManager {
553561
forward_htlcs: HashMap::new(),
554562
claimable_htlcs: HashMap::new(),
555563
pending_msg_events: Vec::new(),
564+
channel_closing_waiting_threshold_conf: HashMap::new(),
556565
}),
557566
our_network_key: keys_manager.get_node_secret(),
558567

@@ -2404,7 +2413,8 @@ impl ChainListener for ChannelManager {
24042413
let channel_state = channel_lock.borrow_parts();
24052414
let short_to_id = channel_state.short_to_id;
24062415
let pending_msg_events = channel_state.pending_msg_events;
2407-
channel_state.by_id.retain(|_, channel| {
2416+
let mut channel_closings = Vec::new();
2417+
channel_state.by_id.retain(|channel_id, channel| {
24082418
let chan_res = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched);
24092419
if let Ok(Some(funding_locked)) = chan_res {
24102420
pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
@@ -2429,20 +2439,8 @@ impl ChainListener for ChannelManager {
24292439
for tx in txn_matched {
24302440
for inp in tx.input.iter() {
24312441
if inp.previous_output == funding_txo.into_bitcoin_outpoint() {
2432-
log_trace!(self, "Detected channel-closing tx {} spending {}:{}, closing channel {}", tx.txid(), inp.previous_output.txid, inp.previous_output.vout, log_bytes!(channel.channel_id()));
2433-
if let Some(short_id) = channel.get_short_channel_id() {
2434-
short_to_id.remove(&short_id);
2435-
}
2436-
// It looks like our counterparty went on-chain. We go ahead and
2437-
// broadcast our latest local state as well here, just in case its
2438-
// some kind of SPV attack, though we expect these to be dropped.
2439-
failed_channels.push(channel.force_shutdown());
2440-
if let Ok(update) = self.get_channel_update(&channel) {
2441-
pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
2442-
msg: update
2443-
});
2444-
}
2445-
return false;
2442+
log_trace!(self, "Detected channel-closing tx {} spending {}:{}, waiting until {} to close channel {}", tx.txid(), inp.previous_output.txid, inp.previous_output.vout, height + HTLC_FAIL_ANTI_REORG_DELAY - 1, log_bytes!(channel_id[..]));
2443+
channel_closings.push((height + HTLC_FAIL_ANTI_REORG_DELAY - 1, *channel_id));
24462444
}
24472445
}
24482446
}
@@ -2465,6 +2463,44 @@ impl ChainListener for ChannelManager {
24652463
}
24662464
true
24672465
});
2466+
for (block_timer, channel_id) in channel_closings.drain(..) {
2467+
match channel_state.channel_closing_waiting_threshold_conf.entry(block_timer) {
2468+
hash_map::Entry::Occupied(mut entry) => {
2469+
let mut duplicate = false;
2470+
for id in entry.get().iter() {
2471+
if *id == channel_id {
2472+
duplicate = true;
2473+
break;
2474+
}
2475+
}
2476+
if !duplicate {
2477+
entry.get_mut().push(channel_id);
2478+
}
2479+
}
2480+
hash_map::Entry::Vacant(entry) => {
2481+
entry.insert(vec![channel_id]);
2482+
}
2483+
}
2484+
}
2485+
if let Some(channel_closings) = channel_state.channel_closing_waiting_threshold_conf.remove(&height) {
2486+
for channel_id in channel_closings {
2487+
log_trace!(self, "Enough confirmations for a broacast commitment tx, channel {} can be closed", log_bytes!(&channel_id[..]));
2488+
if let Some(mut channel) = channel_state.by_id.remove(&channel_id) {
2489+
if let Some(short_id) = channel.get_short_channel_id() {
2490+
short_to_id.remove(&short_id);
2491+
}
2492+
// It looks like our counterparty went on-chain. We go ahead and
2493+
// broadcast our latest local state as well here, just in case its
2494+
// some kind of SPV attack, though we expect these to be dropped.
2495+
failed_channels.push(channel.force_shutdown());
2496+
if let Ok(update) = self.get_channel_update(&channel) {
2497+
pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
2498+
msg: update
2499+
});
2500+
}
2501+
}
2502+
}
2503+
}
24682504
}
24692505
for failure in failed_channels.drain(..) {
24702506
self.finish_force_close_channel(failure);
@@ -2474,7 +2510,7 @@ impl ChainListener for ChannelManager {
24742510
}
24752511

24762512
/// We force-close the channel without letting our counterparty participate in the shutdown
2477-
fn block_disconnected(&self, header: &BlockHeader, _: u32) {
2513+
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
24782514
let _ = self.total_consistency_lock.read().unwrap();
24792515
let mut failed_channels = Vec::new();
24802516
{
@@ -2498,6 +2534,9 @@ impl ChainListener for ChannelManager {
24982534
true
24992535
}
25002536
});
2537+
if let Some(_) = channel_state.channel_closing_waiting_threshold_conf.remove(&(height + HTLC_FAIL_ANTI_REORG_DELAY - 1)) {
2538+
// We discard channel_closing there as brooadcast commitment tx has been disconnected, (and may be replaced by a legit closing_signed)
2539+
}
25012540
}
25022541
for failure in failed_channels.drain(..) {
25032542
self.finish_force_close_channel(failure);
@@ -2936,6 +2975,14 @@ impl Writeable for ChannelManager {
29362975
}
29372976
}
29382977

2978+
(channel_state.channel_closing_waiting_threshold_conf.len() as u64).write(writer)?;
2979+
for (confirmation_height, channel_id) in channel_state.channel_closing_waiting_threshold_conf.iter() {
2980+
confirmation_height.write(writer)?;
2981+
for id in channel_id {
2982+
id.write(writer)?;
2983+
}
2984+
}
2985+
29392986
Ok(())
29402987
}
29412988
}
@@ -3073,6 +3120,21 @@ impl<'a, R : ::std::io::Read> ReadableArgs<R, ChannelManagerReadArgs<'a>> for (S
30733120
claimable_htlcs.insert(payment_hash, previous_hops);
30743121
}
30753122

3123+
let channel_closing_count: u64 = Readable::read(reader)?;
3124+
let mut channel_closing_waiting_threshold_conf: HashMap<u32, Vec<[u8; 32]>> = HashMap::with_capacity(cmp::min(channel_closing_count as usize, 32));
3125+
for _ in 0..channel_closing_count {
3126+
let confirmation_height: u32 = Readable::read(reader)?;
3127+
let channel_id: [u8; 32] = Readable::read(reader)?;
3128+
match channel_closing_waiting_threshold_conf.entry(confirmation_height) {
3129+
hash_map::Entry::Occupied(mut entry) => {
3130+
entry.get_mut().push(channel_id);
3131+
}
3132+
hash_map::Entry::Vacant(entry) => {
3133+
entry.insert(vec![channel_id]);
3134+
}
3135+
}
3136+
}
3137+
30763138
let channel_manager = ChannelManager {
30773139
genesis_hash,
30783140
fee_estimator: args.fee_estimator,
@@ -3091,6 +3153,7 @@ impl<'a, R : ::std::io::Read> ReadableArgs<R, ChannelManagerReadArgs<'a>> for (S
30913153
forward_htlcs,
30923154
claimable_htlcs,
30933155
pending_msg_events: Vec::new(),
3156+
channel_closing_waiting_threshold_conf,
30943157
}),
30953158
our_network_key: args.keys_manager.get_node_secret(),
30963159

0 commit comments

Comments
 (0)