//! A bunch of useful utilities for building networks of nodes and exchanging messages between
//! nodes for functional tests.
-use chain::Watch;
+use chain::{Listen, Watch};
use chain::channelmonitor::ChannelMonitor;
use chain::transaction::OutPoint;
use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
/// top, giving the given transaction CHAN_CONFIRM_DEPTH confirmations.
pub fn confirm_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
confirm_transaction_at(node, tx, node.best_block_info().1 + 1);
- connect_blocks(node, CHAN_CONFIRM_DEPTH - 1, node.best_block_info().1, false, Default::default());
+ connect_blocks(node, CHAN_CONFIRM_DEPTH - 1);
}
/// Mine a signle block containing the given transaction
pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
};
let height = starting_block.1 + 1;
assert!(height <= conf_height);
- for i in height..conf_height {
- connect_block(node, &block, i);
+ for _ in height..conf_height {
+ connect_block(node, &block);
block = Block {
header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
txdata: vec![],
block.txdata.push(Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() });
}
block.txdata.push(tx.clone());
- connect_block(node, &block, conf_height);
+ connect_block(node, &block);
}
-pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32, height: u32, parent: bool, prev_blockhash: BlockHash) -> BlockHash {
+pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32) -> BlockHash {
let mut block = Block {
- 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 },
+ header: BlockHeader { version: 0x2000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
txdata: vec![],
};
- connect_block(node, &block, height + 1);
- for i in 2..depth + 1 {
+ connect_block(node, &block);
+ for _ in 2..depth + 1 {
block = Block {
header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 },
txdata: vec![],
};
- connect_block(node, &block, height + i);
+ connect_block(node, &block);
}
block.header.block_hash()
}
-pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, height: u32) {
+pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block) {
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
+ let height = node.best_block_info().1 + 1;
node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height);
- node.node.block_connected(&block.header, &txdata, height);
+ node.node.block_connected(&block, height);
node.node.test_process_background_events();
node.blocks.borrow_mut().push((block.header, height));
}
-pub fn disconnect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, header: &BlockHeader, height: u32) {
- node.chain_monitor.chain_monitor.block_disconnected(header, height);
- node.node.block_disconnected(header);
- node.blocks.borrow_mut().pop();
-}
pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) {
- assert!(node.blocks.borrow_mut().len() as u32 > count); // Cannot disconnect genesis
for _ in 0..count {
- let (block_header, height) = {
- let blocks = node.blocks.borrow_mut();
- (blocks[blocks.len() - 1].0, blocks[blocks.len() - 1].1)
- };
- disconnect_block(&node, &block_header, height);
+ let orig_header = node.blocks.borrow_mut().pop().unwrap();
+ assert!(orig_header.1 > 0); // Cannot disconnect genesis
+ node.chain_monitor.chain_monitor.block_disconnected(&orig_header.0, orig_header.1);
+ node.node.block_disconnected(&orig_header.0);
}
}
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) {
confirm_transaction_at(node_conf, tx, conf_height);
- connect_blocks(node_conf, CHAN_CONFIRM_DEPTH - 1, node_conf.best_block_info().1, false, Default::default());
+ connect_blocks(node_conf, CHAN_CONFIRM_DEPTH - 1);
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()));
}
let conf_height = std::cmp::max(node_a.best_block_info().1 + 1, node_b.best_block_info().1 + 1);
create_chan_between_nodes_with_value_confirm_first(node_a, node_b, tx, conf_height);
confirm_transaction_at(node_a, tx, conf_height);
- connect_blocks(node_a, CHAN_CONFIRM_DEPTH - 1, node_a.best_block_info().1, false, Default::default());
+ connect_blocks(node_a, CHAN_CONFIRM_DEPTH - 1);
create_chan_between_nodes_with_value_confirm_second(node_b, node_a)
}
pub fn get_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, 'b, 'c>>, a: usize, b: usize) {
let events_1 = nodes[a].node.get_and_clear_pending_msg_events();
- assert_eq!(events_1.len(), 1);
+ assert_eq!(events_1.len(), 2);
let as_update = match events_1[0] {
MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
msg.clone()
},
_ => panic!("Unexpected event"),
};
+ match events_1[1] {
+ MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::SendErrorMessage { ref msg } } => {
+ assert_eq!(node_id, nodes[b].node.get_our_node_id());
+ assert_eq!(msg.data, "Commitment or closing transaction was confirmed on chain.");
+ },
+ _ => panic!("Unexpected event"),
+ }
let events_2 = nodes[b].node.get_and_clear_pending_msg_events();
- assert_eq!(events_2.len(), 1);
+ assert_eq!(events_2.len(), 2);
let bs_update = match events_2[0] {
MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
msg.clone()
},
_ => panic!("Unexpected event"),
};
+ match events_2[1] {
+ MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::SendErrorMessage { ref msg } } => {
+ assert_eq!(node_id, nodes[a].node.get_our_node_id());
+ assert_eq!(msg.data, "Commitment or closing transaction was confirmed on chain.");
+ },
+ _ => panic!("Unexpected event"),
+ }
for node in nodes {
node.net_graph_msg_handler.handle_channel_update(&as_update).unwrap();