Add more robust functional test of `Listen::blocks_disconnected`
What changed, and why it matters
This commit only adds a new test mode to the Lightning Dev Kit's internal functional test framework. It exercises the existing ability to report multiple block disconnections at once through the chain::Listen interface. There is no change to production code, no bug fix, and no security-relevant behavior change.
No action required; this is a test-only change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces a new ConnectStyle variant, FullBlockDisconnectionsSkippingViaListen, in the functional test utilities. When this style is selected, disconnect_blocks() skips per-block disconnection callbacks and instead issues a single blocks_disconnected() call at the end of the reorg. It also updates a test that relies on redundant block connections to skip this new style. The change is purely additive to test infrastructure and exercises already-merged Listen behavior.
Changed components
lightning/src/ln/functional_test_utils.rslightning/src/ln/functional_tests.rsInspect captured patch +25 / −7
diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs
index 68d73c7..d343292 100644
--- a/lightning/src/ln/functional_test_utils.rs
+++ b/lightning/src/ln/functional_test_utils.rs
@@ -196,6 +196,9 @@ pub enum ConnectStyle {
/// Provides the full block via the `chain::Listen` interface. In the current code this is
/// equivalent to `TransactionsFirst` with some additional assertions.
FullBlockViaListen,
+ /// Provides the full block via the `chain::Listen` interface, condensing multiple block
+ /// disconnections into a single `blocks_disconnected` call.
+ FullBlockDisconnectionsSkippingViaListen,
}
impl ConnectStyle {
@@ -210,6 +213,7 @@ impl ConnectStyle {
ConnectStyle::HighlyRedundantTransactionsFirstSkippingBlocks => true,
ConnectStyle::TransactionsFirstReorgsOnlyTip => true,
ConnectStyle::FullBlockViaListen => false,
+ ConnectStyle::FullBlockDisconnectionsSkippingViaListen => false,
}
}
@@ -224,6 +228,7 @@ impl ConnectStyle {
ConnectStyle::HighlyRedundantTransactionsFirstSkippingBlocks => false,
ConnectStyle::TransactionsFirstReorgsOnlyTip => false,
ConnectStyle::FullBlockViaListen => false,
+ ConnectStyle::FullBlockDisconnectionsSkippingViaListen => false,
}
}
@@ -231,7 +236,7 @@ impl ConnectStyle {
use core::hash::{BuildHasher, Hasher};
// Get a random value using the only std API to do so - the DefaultHasher
let rand_val = std::collections::hash_map::RandomState::new().build_hasher().finish();
- let res = match rand_val % 9 {
+ let res = match rand_val % 10 {
0 => ConnectStyle::BestBlockFirst,
1 => ConnectStyle::BestBlockFirstSkippingBlocks,
2 => ConnectStyle::BestBlockFirstReorgsOnlyTip,
@@ -241,6 +246,7 @@ impl ConnectStyle {
6 => ConnectStyle::HighlyRedundantTransactionsFirstSkippingBlocks,
7 => ConnectStyle::TransactionsFirstReorgsOnlyTip,
8 => ConnectStyle::FullBlockViaListen,
+ 9 => ConnectStyle::FullBlockDisconnectionsSkippingViaListen,
_ => unreachable!(),
};
eprintln!("Using Block Connection Style: {:?}", res);
@@ -371,7 +377,8 @@ fn do_connect_block_without_consistency_checks<'a, 'b, 'c, 'd>(
node.node.transactions_confirmed(&block.header, &txdata, height);
node.node.best_block_updated(&block.header, height);
},
- ConnectStyle::FullBlockViaListen => {
+ ConnectStyle::FullBlockViaListen
+ | ConnectStyle::FullBlockDisconnectionsSkippingViaListen => {
node.chain_monitor.chain_monitor.block_connected(&block, height);
node.node.block_connected(&block, height);
},
@@ -432,6 +439,13 @@ pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32)
node.chain_monitor.chain_monitor.blocks_disconnected(best_block);
Listen::blocks_disconnected(node.node, best_block);
},
+ ConnectStyle::FullBlockDisconnectionsSkippingViaListen => {
+ if i == count - 1 {
+ let best_block = BestBlock::new(orig.0.header.prev_blockhash, orig.1 - 1);
+ node.chain_monitor.chain_monitor.blocks_disconnected(best_block);
+ Listen::blocks_disconnected(node.node, best_block);
+ }
+ },
ConnectStyle::BestBlockFirstSkippingBlocks
| ConnectStyle::TransactionsFirstSkippingBlocks
| ConnectStyle::HighlyRedundantTransactionsFirstSkippingBlocks
diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs
index 5e78049..03fd816 100644
--- a/lightning/src/ln/functional_tests.rs
+++ b/lightning/src/ln/functional_tests.rs
@@ -2328,11 +2328,15 @@ pub fn test_htlc_ignore_latest_remote_commitment() {
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
- if *nodes[1].connect_style.borrow() == ConnectStyle::FullBlockViaListen {
- // We rely on the ability to connect a block redundantly, which isn't allowed via
- // `chain::Listen`, so we never run the test if we randomly get assigned that
- // connect_style.
- return;
+ match *nodes[1].connect_style.borrow() {
+ ConnectStyle::FullBlockViaListen
+ | ConnectStyle::FullBlockDisconnectionsSkippingViaListen => {
+ // We rely on the ability to connect a block redundantly, which isn't allowed via
+ // `chain::Listen`, so we never run the test if we randomly get assigned that
+ // connect_style.
+ return;
+ },
+ _ => {},
}
let funding_tx = create_announced_chan_between_nodes(&nodes, 0, 1).3;
let message = "Channel force-closed".to_owned();
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.