Skip to content

Commit 78c90a2

Browse files
Fix block connection ordering in a number of functional tests
Many functional tests rely on being able to call block_connected arbitrarily, jumping back in time to confirm a transaction at a specific height. Instead, this takes us one step towards having a well-formed blockchain in the functional tests. We also take this opportunity to reduce the number of blocks connected during tests, requiring a number of constant tweaks in various functional tests. Co-authored-by: Valentine Wallace <[email protected]> Co-authored-by: Matt Corallo <[email protected]>
1 parent 0661623 commit 78c90a2

File tree

4 files changed

+153
-116
lines changed

4 files changed

+153
-116
lines changed

lightning-persister/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ mod tests {
248248
assert_eq!(node_txn.len(), 1);
249249

250250
let header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[0].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
251-
connect_block(&nodes[1], &Block { header, txdata: vec![node_txn[0].clone(), node_txn[0].clone()]}, CHAN_CONFIRM_DEPTH);
251+
connect_block(&nodes[1], &Block { header, txdata: vec![node_txn[0].clone(), node_txn[0].clone()]}, CHAN_CONFIRM_DEPTH + 1);
252252
check_closed_broadcast!(nodes[1], false);
253253
check_added_monitors!(nodes[1], 1);
254254

lightning/src/ln/functional_test_utils.rs

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,47 @@ use std::sync::Mutex;
4444
use std::mem;
4545
use std::collections::HashMap;
4646

47-
pub const CHAN_CONFIRM_DEPTH: u32 = 100;
47+
pub const CHAN_CONFIRM_DEPTH: u32 = 10;
4848

49+
/// Mine the given transaction in the next block and then mine CHAN_CONFIRM_DEPTH - 1 blocks on
50+
/// top, giving the given transaction CHAN_CONFIRM_DEPTH confirmations.
4951
pub fn confirm_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
50-
let dummy_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
51-
let dummy_tx_count = tx.version as usize;
52+
confirm_transaction_at(node, tx, node.best_block_info().1 + 1);
53+
connect_blocks(node, CHAN_CONFIRM_DEPTH - 1, node.best_block_info().1, false, Default::default());
54+
}
55+
/// Mine a signle block containing the given transaction
56+
pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
57+
let height = node.best_block_info().1 + 1;
58+
confirm_transaction_at(node, tx, height);
59+
}
60+
/// Mine the given transaction at the given height, mining blocks as required to build to that
61+
/// height
62+
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();
5264
let mut block = Block {
53-
header: BlockHeader { version: 0x20000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
54-
txdata: vec![dummy_tx; dummy_tx_count],
65+
header: BlockHeader { version: 0x20000000, prev_blockhash: starting_block.0, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
66+
txdata: Vec::new(),
5567
};
56-
block.txdata.push(tx.clone());
57-
connect_block(node, &block, 1);
58-
for i in 2..CHAN_CONFIRM_DEPTH {
68+
let height = starting_block.1 + 1;
69+
assert!(height <= conf_height);
70+
for i in height..conf_height {
71+
connect_block(node, &block, i);
5972
block = Block {
6073
header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
6174
txdata: vec![],
6275
};
63-
connect_block(node, &block, i);
6476
}
77+
78+
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
79+
block.txdata.push(Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() });
80+
}
81+
block.txdata.push(tx.clone());
82+
connect_block(node, &block, conf_height);
6583
}
6684

6785
pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32, height: u32, parent: bool, prev_blockhash: BlockHash) -> BlockHash {
6886
let mut block = Block {
69-
header: BlockHeader { version: 0x2000000, prev_blockhash: if parent { prev_blockhash } else { Default::default() }, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
87+
header: BlockHeader { version: 0x2000000, prev_blockhash: if parent { prev_blockhash } else { node.best_block_hash() }, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
7088
txdata: vec![],
7189
};
7290
connect_block(node, &block, height + 1);
@@ -94,6 +112,21 @@ pub fn disconnect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, header: &Blo
94112
node.node.test_process_background_events();
95113
node.blocks.borrow_mut().pop();
96114
}
115+
pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) {
116+
assert!(node.blocks.borrow_mut().len() as u32 > count); // Cannot disconnect genesis
117+
for _ in 0..count {
118+
let (block_header, height) = {
119+
let blocks = node.blocks.borrow_mut();
120+
(blocks[blocks.len() - 1].0, blocks[blocks.len() - 1].1)
121+
};
122+
disconnect_block(&node, &block_header, height);
123+
}
124+
}
125+
126+
pub fn disconnect_all_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>) {
127+
let count = node.blocks.borrow_mut().len() as u32 - 1;
128+
disconnect_blocks(node, count);
129+
}
97130

98131
pub struct TestChanMonCfg {
99132
pub tx_broadcaster: test_utils::TestBroadcaster,
@@ -427,8 +460,9 @@ pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, '
427460
tx
428461
}
429462

430-
pub fn create_chan_between_nodes_with_value_confirm_first<'a, 'b, 'c, 'd>(node_recv: &'a Node<'b, 'c, 'c>, node_conf: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
431-
confirm_transaction(node_conf, tx);
463+
pub fn create_chan_between_nodes_with_value_confirm_first<'a, 'b, 'c, 'd>(node_recv: &'a Node<'b, 'c, 'c>, node_conf: &'a Node<'b, 'c, 'd>, tx: &Transaction, conf_height: u32) {
464+
confirm_transaction_at(node_conf, tx, conf_height);
465+
connect_blocks(node_conf, CHAN_CONFIRM_DEPTH - 1, node_conf.best_block_info().1, false, Default::default());
432466
node_recv.node.handle_funding_locked(&node_conf.node.get_our_node_id(), &get_event_msg!(node_conf, MessageSendEvent::SendFundingLocked, node_recv.node.get_our_node_id()));
433467
}
434468

@@ -453,8 +487,10 @@ pub fn create_chan_between_nodes_with_value_confirm_second<'a, 'b, 'c>(node_recv
453487
}
454488

455489
pub fn create_chan_between_nodes_with_value_confirm<'a, 'b, 'c, 'd>(node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, tx: &Transaction) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32]) {
456-
create_chan_between_nodes_with_value_confirm_first(node_a, node_b, tx);
457-
confirm_transaction(node_a, tx);
490+
let conf_height = std::cmp::max(node_a.best_block_info().1 + 1, node_b.best_block_info().1 + 1);
491+
create_chan_between_nodes_with_value_confirm_first(node_a, node_b, tx, conf_height);
492+
confirm_transaction_at(node_a, tx, conf_height);
493+
connect_blocks(node_a, CHAN_CONFIRM_DEPTH - 1, node_a.best_block_info().1, false, Default::default());
458494
create_chan_between_nodes_with_value_confirm_second(node_b, node_a)
459495
}
460496

@@ -854,13 +890,13 @@ macro_rules! expect_payment_failed {
854890
assert_eq!(events.len(), 1);
855891
match events[0] {
856892
Event::PaymentFailed { ref payment_hash, rejected_by_dest, ref error_code, ref error_data } => {
857-
assert_eq!(*payment_hash, $expected_payment_hash);
858-
assert_eq!(rejected_by_dest, $rejected_by_dest);
859-
assert!(error_code.is_some());
860-
assert!(error_data.is_some());
893+
assert_eq!($expected_payment_hash, *payment_hash, "unexpected payment_hash");
894+
assert_eq!($rejected_by_dest, rejected_by_dest, "unexpected rejected_by_dest value");
895+
assert!(error_code.is_some(), "expected error_code.is_some() = true");
896+
assert!(error_data.is_some(), "expected error_data.is_some() = true");
861897
$(
862-
assert_eq!(error_code.unwrap(), $expected_error_code);
863-
assert_eq!(&error_data.as_ref().unwrap()[..], $expected_error_data);
898+
assert_eq!($expected_error_code, error_code.unwrap(), "unexpected error code");
899+
assert_eq!($expected_error_data, &error_data.as_ref().unwrap()[..], "unexpected error data");
864900
)*
865901
},
866902
_ => panic!("Unexpected event"),
@@ -1031,7 +1067,7 @@ pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
10311067
claim_payment_along_route(origin_node, expected_route, false, our_payment_preimage, expected_amount);
10321068
}
10331069

1034-
pub const TEST_FINAL_CLTV: u32 = 32;
1070+
pub const TEST_FINAL_CLTV: u32 = 50;
10351071

10361072
pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
10371073
let net_graph_msg_handler = &origin_node.net_graph_msg_handler;
@@ -1207,7 +1243,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
12071243
nodes
12081244
}
12091245

1210-
pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 138; //Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
1246+
// Note that the following only works for CLTV values up to 128
1247+
pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 137; //Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
12111248
pub const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
12121249

12131250
#[derive(PartialEq)]

0 commit comments

Comments
 (0)