Skip to content

Commit 5cd1857

Browse files
committed
Allow changing the way we [dis]connect blocks in funtional tests
1 parent c88b707 commit 5cd1857

File tree

1 file changed

+73
-19
lines changed

1 file changed

+73
-19
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,59 +60,110 @@ pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transac
6060
/// Mine the given transaction at the given height, mining blocks as required to build to that
6161
/// height
6262
pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction, conf_height: u32) {
63-
let starting_block = node.best_block_info();
63+
let first_connect_height = node.best_block_info().1 + 1;
64+
assert!(first_connect_height <= conf_height);
65+
if conf_height - first_connect_height >= 1 {
66+
connect_blocks(node, conf_height - first_connect_height);
67+
}
6468
let mut block = Block {
65-
header: BlockHeader { version: 0x20000000, prev_blockhash: starting_block.0, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
69+
header: BlockHeader { version: 0x20000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
6670
txdata: Vec::new(),
6771
};
68-
let height = starting_block.1 + 1;
69-
assert!(height <= conf_height);
70-
for _ in height..conf_height {
71-
connect_block(node, &block);
72-
block = Block {
73-
header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
74-
txdata: vec![],
75-
};
76-
}
77-
7872
for _ in 0..*node.network_chan_count.borrow() { // Make sure we don't end up with channels at the same short id by offsetting by chan_count
7973
block.txdata.push(Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() });
8074
}
8175
block.txdata.push(tx.clone());
8276
connect_block(node, &block);
8377
}
8478

79+
/// The possible ways we may notify a ChannelManager of a new block
80+
pub enum ConnectStyle {
81+
/// Calls update_best_block first, detecting transactions in the block only after receiving the
82+
/// header and height information.
83+
BestBlockFirst,
84+
/// The same as BestBlockFirst, however when we have multiple blocks to connect, we only
85+
/// make a single update_best_block call.
86+
BestBlockFirstSkippingBlocks,
87+
/// Calls transactions_confirmed first, detecting transactions in the block before updating the
88+
/// header and height information.
89+
TransactionsFirst,
90+
/// The same as TransactionsFirst, however when we have multiple blocks to connect, we only
91+
/// make a single update_best_block call.
92+
TransactionsFirstSkippingBlocks,
93+
/// Provides the full block via the chain::Listen interface. In the current code this is
94+
/// equivalent to TransactionsFirst with some additional assertions.
95+
FullBlockViaListen,
96+
}
97+
8598
pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32) -> BlockHash {
99+
let skip_intermediaries = match *node.connect_style.borrow() {
100+
ConnectStyle::BestBlockFirstSkippingBlocks|ConnectStyle::TransactionsFirstSkippingBlocks => true,
101+
_ => false,
102+
};
103+
86104
let mut block = Block {
87105
header: BlockHeader { version: 0x2000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
88106
txdata: vec![],
89107
};
90-
connect_block(node, &block);
91-
for _ in 2..depth + 1 {
108+
assert!(depth >= 1);
109+
for _ in 0..depth - 1 {
110+
do_connect_block(node, &block, skip_intermediaries);
92111
block = Block {
93112
header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
94113
txdata: vec![],
95114
};
96-
connect_block(node, &block);
97115
}
116+
connect_block(node, &block);
98117
block.header.block_hash()
99118
}
100119

101120
pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block) {
121+
do_connect_block(node, block, false);
122+
}
123+
124+
fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, skip_manager: bool) {
102125
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
103126
let height = node.best_block_info().1 + 1;
104127
node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height);
105-
node.node.block_connected(&block, height);
128+
if !skip_manager {
129+
match *node.connect_style.borrow() {
130+
ConnectStyle::BestBlockFirst|ConnectStyle::BestBlockFirstSkippingBlocks => {
131+
node.node.update_best_block(&block.header, height);
132+
node.node.transactions_confirmed(&block.header, height, &block.txdata.iter().enumerate().collect::<Vec<_>>());
133+
},
134+
ConnectStyle::TransactionsFirst|ConnectStyle::TransactionsFirstSkippingBlocks => {
135+
node.node.transactions_confirmed(&block.header, height, &block.txdata.iter().enumerate().collect::<Vec<_>>());
136+
node.node.update_best_block(&block.header, height);
137+
},
138+
ConnectStyle::FullBlockViaListen => {
139+
Listen::block_connected(node.node, &block, height);
140+
}
141+
}
142+
}
106143
node.node.test_process_background_events();
107144
node.blocks.borrow_mut().push((block.header, height));
108145
}
109146

110147
pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) {
111-
for _ in 0..count {
148+
for i in 0..count {
112149
let orig_header = node.blocks.borrow_mut().pop().unwrap();
113150
assert!(orig_header.1 > 0); // Cannot disconnect genesis
151+
let prev_header = node.blocks.borrow().last().unwrap().clone();
152+
114153
node.chain_monitor.chain_monitor.block_disconnected(&orig_header.0, orig_header.1);
115-
node.node.block_disconnected(&orig_header.0, orig_header.1);
154+
match *node.connect_style.borrow() {
155+
ConnectStyle::FullBlockViaListen => {
156+
Listen::block_disconnected(node.node, &orig_header.0, orig_header.1);
157+
},
158+
ConnectStyle::BestBlockFirstSkippingBlocks|ConnectStyle::TransactionsFirstSkippingBlocks => {
159+
if i == count - 1 {
160+
node.node.update_best_block(&prev_header.0, prev_header.1);
161+
}
162+
},
163+
_ => {
164+
node.node.update_best_block(&prev_header.0, prev_header.1);
165+
},
166+
}
116167
}
117168
}
118169

@@ -152,6 +203,7 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
152203
pub network_chan_count: Rc<RefCell<u32>>,
153204
pub logger: &'c test_utils::TestLogger,
154205
pub blocks: RefCell<Vec<(BlockHeader, u32)>>,
206+
pub connect_style: Rc<RefCell<ConnectStyle>>,
155207
}
156208
impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
157209
pub fn best_block_hash(&self) -> BlockHash {
@@ -1224,6 +1276,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
12241276
let mut nodes = Vec::new();
12251277
let chan_count = Rc::new(RefCell::new(0));
12261278
let payment_count = Rc::new(RefCell::new(0));
1279+
let connect_style = Rc::new(RefCell::new(ConnectStyle::FullBlockViaListen));
12271280

12281281
for i in 0..node_count {
12291282
let net_graph_msg_handler = NetGraphMsgHandler::new(cfgs[i].chain_source.genesis_hash, None, cfgs[i].logger);
@@ -1232,7 +1285,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
12321285
keys_manager: &cfgs[i].keys_manager, node: &chan_mgrs[i], net_graph_msg_handler,
12331286
node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),
12341287
network_payment_count: payment_count.clone(), logger: cfgs[i].logger,
1235-
blocks: RefCell::new(vec![(genesis_block(Network::Testnet).header, 0)])
1288+
blocks: RefCell::new(vec![(genesis_block(Network::Testnet).header, 0)]),
1289+
connect_style: Rc::clone(&connect_style),
12361290
})
12371291
}
12381292

0 commit comments

Comments
 (0)