Skip to content

Commit 053978a

Browse files
joostjagerclaude
andcommitted
chanmon_consistency: fix bogus channel_reestablish infinite loop
Skip delivery of bogus channel_reestablish messages (those with both commitment numbers at 0) in the process_msg_events\! macro. These are generated by the lnd workaround in handle_channel_reestablish's Vacant branch. When both nodes have forgotten a channel, delivering these between LDK nodes creates an infinite ping-pong that hits the 100 iteration limit in process_all_events\!. All fuzzer nodes are LDK and will already force-close via the error message path, so skipping these is safe. Also batch the drain+confirm+sync loop so that fee-bump re-broadcasts are confirmed before proceeding, using confirm_tx's return value to skip already-confirmed transactions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent baa2540 commit 053978a

1 file changed

Lines changed: 33 additions & 15 deletions

File tree

fuzz/src/chanmon_consistency.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,17 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
16651665
}
16661666
},
16671667
MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => {
1668+
if msg.next_local_commitment_number == 0
1669+
&& msg.next_remote_commitment_number == 0
1670+
{
1671+
// Skip bogus reestablish (lnd workaround). All fuzzer
1672+
// nodes are LDK and will already force-close via the
1673+
// error message path. Delivering these between LDK
1674+
// nodes creates an infinite ping-pong since both sides
1675+
// respond with another bogus reestablish for the
1676+
// unknown channel.
1677+
continue;
1678+
}
16681679
for (idx, dest) in nodes.iter().enumerate() {
16691680
if dest.get_our_node_id() == *node_id {
16701681
out.locked_write(format!("Delivering channel_reestablish from node {} to node {}.\n", $node, idx).as_bytes());
@@ -2818,7 +2829,7 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
28182829
let mut last_pass_no_updates = false;
28192830
for i in 0..std::usize::MAX {
28202831
if i == 100 {
2821-
panic!("It may take may iterations to settle the state, but it should not take forever");
2832+
panic!("It may take many iterations to settle the state, but it should not take forever");
28222833
}
28232834
// Next, make sure no monitor updates are pending
28242835
for id in &chan_ab_ids {
@@ -2831,23 +2842,30 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
28312842
}
28322843
// Drain any broadcast transactions (from force-closes) and
28332844
// confirm them so the monitors can process the spends.
2834-
let mut had_txs = false;
2835-
for tx in broadcast_a.txn_broadcasted.borrow_mut().drain(..) {
2836-
chain_state.confirm_tx(tx);
2837-
had_txs = true;
2838-
}
2839-
for tx in broadcast_b.txn_broadcasted.borrow_mut().drain(..) {
2840-
chain_state.confirm_tx(tx);
2841-
had_txs = true;
2842-
}
2843-
for tx in broadcast_c.txn_broadcasted.borrow_mut().drain(..) {
2844-
chain_state.confirm_tx(tx);
2845-
had_txs = true;
2846-
}
2847-
if had_txs {
2845+
// We loop here because syncing can trigger monitors to
2846+
// re-broadcast (fee bumps), which need to be confirmed
2847+
// before proceeding.
2848+
let mut had_new_txs = false;
2849+
loop {
2850+
let mut found = false;
2851+
for tx in broadcast_a.txn_broadcasted.borrow_mut().drain(..) {
2852+
found |= chain_state.confirm_tx(tx);
2853+
}
2854+
for tx in broadcast_b.txn_broadcasted.borrow_mut().drain(..) {
2855+
found |= chain_state.confirm_tx(tx);
2856+
}
2857+
for tx in broadcast_c.txn_broadcasted.borrow_mut().drain(..) {
2858+
found |= chain_state.confirm_tx(tx);
2859+
}
2860+
if !found {
2861+
break;
2862+
}
2863+
had_new_txs = true;
28482864
sync_with_chain_state(&chain_state, &nodes[0], &monitor_a, &mut node_height_a, None);
28492865
sync_with_chain_state(&chain_state, &nodes[1], &monitor_b, &mut node_height_b, None);
28502866
sync_with_chain_state(&chain_state, &nodes[2], &monitor_c, &mut node_height_c, None);
2867+
}
2868+
if had_new_txs {
28512869
last_pass_no_updates = false;
28522870
continue;
28532871
}

0 commit comments

Comments
 (0)