//! A bunch of useful utilities for building networks of nodes and exchanging messages between
//! nodes for functional tests.
-use chain::{Listen, Watch};
+use chain::{Confirm, Listen, Watch};
use chain::channelmonitor::ChannelMonitor;
use chain::transaction::OutPoint;
-use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
+use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
use routing::router::{Route, get_route};
use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
use ln::features::InitFeatures;
}
/// The possible ways we may notify a ChannelManager of a new block
+#[derive(Clone, Copy, PartialEq)]
pub enum ConnectStyle {
- /// Calls update_best_block first, detecting transactions in the block only after receiving the
+ /// Calls best_block_updated first, detecting transactions in the block only after receiving the
/// header and height information.
BestBlockFirst,
/// The same as BestBlockFirst, however when we have multiple blocks to connect, we only
- /// make a single update_best_block call.
+ /// make a single best_block_updated call.
BestBlockFirstSkippingBlocks,
/// Calls transactions_confirmed first, detecting transactions in the block before updating the
/// header and height information.
TransactionsFirst,
/// The same as TransactionsFirst, however when we have multiple blocks to connect, we only
- /// make a single update_best_block call.
+ /// make a single best_block_updated call.
TransactionsFirstSkippingBlocks,
/// Provides the full block via the chain::Listen interface. In the current code this is
/// equivalent to TransactionsFirst with some additional assertions.
do_connect_block(node, block, false);
}
-fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, skip_manager: bool) {
- let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
+fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, skip_intermediaries: bool) {
let height = node.best_block_info().1 + 1;
- node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height);
- if !skip_manager {
+ if !skip_intermediaries {
+ let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
match *node.connect_style.borrow() {
ConnectStyle::BestBlockFirst|ConnectStyle::BestBlockFirstSkippingBlocks => {
- node.node.update_best_block(&block.header, height);
- node.node.transactions_confirmed(&block.header, height, &block.txdata.iter().enumerate().collect::<Vec<_>>());
+ node.chain_monitor.chain_monitor.best_block_updated(&block.header, height);
+ node.chain_monitor.chain_monitor.transactions_confirmed(&block.header, &txdata, height);
+ node.node.best_block_updated(&block.header, height);
+ node.node.transactions_confirmed(&block.header, &txdata, height);
},
ConnectStyle::TransactionsFirst|ConnectStyle::TransactionsFirstSkippingBlocks => {
- node.node.transactions_confirmed(&block.header, height, &block.txdata.iter().enumerate().collect::<Vec<_>>());
- node.node.update_best_block(&block.header, height);
+ node.chain_monitor.chain_monitor.transactions_confirmed(&block.header, &txdata, height);
+ node.chain_monitor.chain_monitor.best_block_updated(&block.header, height);
+ node.node.transactions_confirmed(&block.header, &txdata, height);
+ node.node.best_block_updated(&block.header, height);
},
ConnectStyle::FullBlockViaListen => {
+ node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height);
Listen::block_connected(node.node, &block, height);
}
}
assert!(orig_header.1 > 0); // Cannot disconnect genesis
let prev_header = node.blocks.borrow().last().unwrap().clone();
- node.chain_monitor.chain_monitor.block_disconnected(&orig_header.0, orig_header.1);
match *node.connect_style.borrow() {
ConnectStyle::FullBlockViaListen => {
+ node.chain_monitor.chain_monitor.block_disconnected(&orig_header.0, orig_header.1);
Listen::block_disconnected(node.node, &orig_header.0, orig_header.1);
},
ConnectStyle::BestBlockFirstSkippingBlocks|ConnectStyle::TransactionsFirstSkippingBlocks => {
if i == count - 1 {
- node.node.update_best_block(&prev_header.0, prev_header.1);
+ node.chain_monitor.chain_monitor.best_block_updated(&prev_header.0, prev_header.1);
+ node.node.best_block_updated(&prev_header.0, prev_header.1);
}
},
_ => {
- node.node.update_best_block(&prev_header.0, prev_header.1);
+ node.chain_monitor.chain_monitor.best_block_updated(&prev_header.0, prev_header.1);
+ node.node.best_block_updated(&prev_header.0, prev_header.1);
},
}
}
let network = Network::Testnet;
let params = ChainParameters {
network,
- latest_hash: genesis_block(network).header.block_hash(),
- latest_height: 0,
+ best_block: BestBlock::from_genesis(network),
};
let node = ChannelManager::new(cfgs[i].fee_estimator, &cfgs[i].chain_monitor, cfgs[i].tx_broadcaster, cfgs[i].logger, cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { default_config }, params);
chanmgrs.push(node);
res
}
-pub fn get_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, 'b, 'c>>, a: usize, b: usize) {
+pub fn handle_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, 'b, 'c>>, a: usize, b: usize, needs_err_handle: bool, expected_error: &str) {
let events_1 = nodes[a].node.get_and_clear_pending_msg_events();
assert_eq!(events_1.len(), 2);
let as_update = match events_1[0] {
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.");
+ assert_eq!(msg.data, expected_error);
+ if needs_err_handle {
+ nodes[b].node.handle_error(&nodes[a].node.get_our_node_id(), msg);
+ }
},
_ => panic!("Unexpected event"),
}
let events_2 = nodes[b].node.get_and_clear_pending_msg_events();
- assert_eq!(events_2.len(), 2);
+ assert_eq!(events_2.len(), if needs_err_handle { 1 } else { 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"),
+ if !needs_err_handle {
+ 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, expected_error);
+ },
+ _ => panic!("Unexpected event"),
+ }
}
for node in nodes {
}
}
+pub fn get_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, 'b, 'c>>, a: usize, b: usize) {
+ handle_announce_close_broadcast_events(nodes, a, b, false, "Commitment or closing transaction was confirmed on chain.");
+}
+
#[cfg(test)]
macro_rules! get_channel_value_stat {
($node: expr, $channel_id: expr) => {{