X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=inline;f=lightning%2Fsrc%2Fln%2Ffunctional_test_utils.rs;h=bc8351e4da09e333b5bcc481d8a94e079187753e;hb=4e82003261e11ece5d5fb3b13f686c9f7a0d2aaf;hp=44430a6453b4a3c52180218360f15aa57c666e94;hpb=1599a13643d893277eb3921c1bb15297547eb030;p=rust-lightning diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 44430a64..bc8351e4 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -10,11 +10,10 @@ //! A bunch of useful utilities for building networks of nodes and exchanging messages between //! nodes for functional tests. -use chain; use chain::Watch; +use chain::channelmonitor::ChannelMonitor; use chain::transaction::OutPoint; use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure}; -use ln::channelmonitor::ChannelMonitor; use routing::router::{Route, get_route}; use routing::network_graph::{NetGraphMsgHandler, NetworkGraph}; use ln::features::InitFeatures; @@ -81,28 +80,11 @@ pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32, he } pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, height: u32) { - use chain::WatchEventProvider; - - let watch_events = node.chain_monitor.chain_monitor.release_pending_watch_events(); - process_chain_watch_events(&watch_events); - let txdata: Vec<_> = block.txdata.iter().enumerate().collect(); - loop { - node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height); - - let watch_events = node.chain_monitor.chain_monitor.release_pending_watch_events(); - process_chain_watch_events(&watch_events); - - if watch_events.is_empty() { - break; - } - } - + node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height); node.node.block_connected(&block.header, &txdata, height); } -fn process_chain_watch_events(_events: &Vec) {} - 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); @@ -112,6 +94,7 @@ pub struct TestChanMonCfg { pub tx_broadcaster: test_utils::TestBroadcaster, pub fee_estimator: test_utils::TestFeeEstimator, pub chain_source: test_utils::TestChainSource, + pub persister: test_utils::TestPersister, pub logger: test_utils::TestLogger, } @@ -187,7 +170,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { let old_monitors = self.chain_monitor.chain_monitor.monitors.lock().unwrap(); for (_, old_monitor) in old_monitors.iter() { let mut w = test_utils::TestVecWriter(Vec::new()); - old_monitor.write_for_disk(&mut w).unwrap(); + old_monitor.serialize_for_disk(&mut w).unwrap(); let (_, deserialized_monitor) = <(BlockHash, ChannelMonitor)>::read( &mut ::std::io::Cursor::new(&w.0)).unwrap(); deserialized_monitors.push(deserialized_monitor); @@ -209,18 +192,27 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { keys_manager: self.keys_manager, fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: 253 }, chain_monitor: self.chain_monitor, - tx_broadcaster: self.tx_broadcaster.clone(), + tx_broadcaster: &test_utils::TestBroadcaster { + txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()) + }, logger: &test_utils::TestLogger::new(), channel_monitors, }).unwrap(); } - let channel_monitor = test_utils::TestChainMonitor::new(self.tx_broadcaster.clone(), &self.logger, &feeest); + let persister = test_utils::TestPersister::new(); + let broadcaster = test_utils::TestBroadcaster { + txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()) + }; + let chain_source = test_utils::TestChainSource::new(Network::Testnet); + let chain_monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &broadcaster, &self.logger, &feeest, &persister); for deserialized_monitor in deserialized_monitors.drain(..) { - if let Err(_) = channel_monitor.watch_channel(deserialized_monitor.get_funding_txo().0, deserialized_monitor) { + if let Err(_) = chain_monitor.watch_channel(deserialized_monitor.get_funding_txo().0, deserialized_monitor) { panic!(); } } + assert_eq!(*chain_source.watched_txn.lock().unwrap(), *self.chain_source.watched_txn.lock().unwrap()); + assert_eq!(*chain_source.watched_outputs.lock().unwrap(), *self.chain_source.watched_outputs.lock().unwrap()); } } } @@ -262,6 +254,8 @@ macro_rules! get_revoke_commit_msgs { } } +/// Get an specific event message from the pending events queue. +#[macro_export] macro_rules! get_event_msg { ($node: expr, $event_type: path, $node_id: expr) => { { @@ -278,6 +272,7 @@ macro_rules! get_event_msg { } } +#[cfg(test)] macro_rules! get_htlc_update_msgs { ($node: expr, $node_id: expr) => { { @@ -294,6 +289,7 @@ macro_rules! get_htlc_update_msgs { } } +#[cfg(test)] macro_rules! get_feerate { ($node: expr, $channel_id: expr) => { { @@ -304,6 +300,7 @@ macro_rules! get_feerate { } } +#[cfg(test)] macro_rules! get_local_commitment_txn { ($node: expr, $channel_id: expr) => { { @@ -320,6 +317,8 @@ macro_rules! get_local_commitment_txn { } } +/// Check the error from attempting a payment. +#[macro_export] macro_rules! unwrap_send_err { ($res: expr, $all_failed: expr, $type: pat, $check: expr) => { match &$res { @@ -342,6 +341,8 @@ macro_rules! unwrap_send_err { } } +/// Check whether N channel monitor(s) have been added. +#[macro_export] macro_rules! check_added_monitors { ($node: expr, $count: expr) => { { @@ -520,14 +521,26 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a macro_rules! check_spends { ($tx: expr, $($spends_txn: expr),*) => { { - $tx.verify(|out_point| { + let get_output = |out_point: &bitcoin::blockdata::transaction::OutPoint| { $( if out_point.txid == $spends_txn.txid() { return $spends_txn.output.get(out_point.vout as usize).cloned() } )* None - }).unwrap(); + }; + let mut total_value_in = 0; + for input in $tx.input.iter() { + total_value_in += get_output(&input.previous_output).unwrap().value; + } + let mut total_value_out = 0; + for output in $tx.output.iter() { + total_value_out += output.value; + } + let min_fee = ($tx.get_weight() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up) + // Input amount - output amount = fee, so check that out + min_fee is smaller than input + assert!(total_value_out + min_fee <= total_value_in); + $tx.verify(get_output).unwrap(); } } } @@ -556,6 +569,9 @@ macro_rules! get_closing_signed_broadcast { } } +/// Check that a channel's closing channel update has been broadcasted, and optionally +/// check whether an error message event has occurred. +#[macro_export] macro_rules! check_closed_broadcast { ($node: expr, $with_error_msg: expr) => {{ let events = $node.node.get_and_clear_pending_msg_events(); @@ -753,6 +769,8 @@ macro_rules! commitment_signed_dance { } } +/// Get a payment preimage and hash. +#[macro_export] macro_rules! get_payment_preimage_hash { ($node: expr) => { { @@ -782,6 +800,7 @@ macro_rules! expect_pending_htlcs_forwardable { }} } +#[cfg(test)] macro_rules! expect_payment_received { ($node: expr, $expected_payment_hash: expr, $expected_recv_value: expr) => { let events = $node.node.get_and_clear_pending_events(); @@ -810,6 +829,7 @@ macro_rules! expect_payment_sent { } } +#[cfg(test)] macro_rules! expect_payment_failed { ($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr $(, $expected_error_code: expr, $expected_error_data: expr)*) => { let events = $node.node.get_and_clear_pending_events(); @@ -1108,7 +1128,8 @@ pub fn create_chanmon_cfgs(node_count: usize) -> Vec { let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; let chain_source = test_utils::TestChainSource::new(Network::Testnet); let logger = test_utils::TestLogger::with_id(format!("node {}", i)); - chan_mon_cfgs.push(TestChanMonCfg{ tx_broadcaster, fee_estimator, chain_source, logger }); + let persister = test_utils::TestPersister::new(); + chan_mon_cfgs.push(TestChanMonCfg{ tx_broadcaster, fee_estimator, chain_source, logger, persister }); } chan_mon_cfgs @@ -1120,7 +1141,7 @@ pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec(node_count: usize, cfgs: &'a Vec default_config.channel_options.announced_channel = true; default_config.peer_channel_config_limits.force_announced_channel_preference = false; default_config.own_channel_config.our_htlc_minimum_msat = 1000; // sanitization being done by the sender, to exerce receiver logic we need to lift of limit - let node = ChannelManager::new(Network::Testnet, cfgs[i].fee_estimator, &cfgs[i].chain_monitor, cfgs[i].tx_broadcaster, cfgs[i].logger.clone(), &cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { default_config }, 0); + let node = ChannelManager::new(Network::Testnet, 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 }, 0); chanmgrs.push(node); } @@ -1287,6 +1308,7 @@ pub fn get_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec {{ let chan_lock = $node.node.channel_state.lock().unwrap();