X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_test_utils.rs;h=8bb49ef97d70cdb59a2c21a76bcb7aaf89313cc4;hb=520b53eb1ca3b187b664de02b095f69b37effbd5;hp=dce4e6289b9536352270bcbbe9eb33268192571a;hpb=99e2283aee3fb7ab512ad5688d2eb5e926d6d9f9;p=rust-lightning diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index dce4e628..8bb49ef9 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -10,19 +10,20 @@ //! A bunch of useful utilities for building networks of nodes and exchanging messages between //! nodes for functional tests. -use chain::{Confirm, Listen, Watch}; +use chain::{BestBlock, Confirm, Listen, Watch}; use chain::channelmonitor::ChannelMonitor; use chain::transaction::OutPoint; -use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure}; +use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; +use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure}; use routing::router::{Route, get_route}; use routing::network_graph::{NetGraphMsgHandler, NetworkGraph}; -use ln::features::InitFeatures; +use ln::features::{InitFeatures, InvoiceFeatures}; use ln::msgs; use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler}; use util::enforcing_trait_impls::EnforcingSigner; use util::test_utils; use util::test_utils::TestChainMonitor; -use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider}; +use util::events::{Event, MessageSendEvent, MessageSendEventsProvider}; use util::errors::APIError; use util::config::UserConfig; use util::ser::{ReadableArgs, Writeable, Readable}; @@ -38,11 +39,11 @@ use bitcoin::hash_types::BlockHash; use bitcoin::secp256k1::key::PublicKey; -use std::cell::RefCell; +use prelude::*; +use core::cell::RefCell; use std::rc::Rc; -use std::sync::Mutex; -use std::mem; -use std::collections::HashMap; +use std::sync::{Arc, Mutex}; +use core::mem; pub const CHAN_CONFIRM_DEPTH: u32 = 10; @@ -66,7 +67,7 @@ pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &T connect_blocks(node, conf_height - first_connect_height); } let mut block = Block { - header: BlockHeader { version: 0x20000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }, + header: BlockHeader { version: 0x20000000, prev_blockhash: node.best_block_hash(), merkle_root: Default::default(), time: conf_height, bits: 42, nonce: 42 }, txdata: Vec::new(), }; 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 @@ -102,15 +103,16 @@ pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32) -> _ => false, }; + let height = node.best_block_info().1 + 1; let mut block = Block { - header: BlockHeader { version: 0x2000000, prev_blockhash: 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: height, bits: 42, nonce: 42 }, txdata: vec![], }; assert!(depth >= 1); - for _ in 0..depth - 1 { + for i in 1..depth { do_connect_block(node, &block, skip_intermediaries); block = Block { - header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }, + header: BlockHeader { version: 0x20000000, prev_blockhash: block.header.block_hash(), merkle_root: Default::default(), time: height + i, bits: 42, nonce: 42 }, txdata: vec![], }; } @@ -146,14 +148,14 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, s } } node.node.test_process_background_events(); - node.blocks.borrow_mut().push((block.header, height)); + node.blocks.lock().unwrap().push((block.header, height)); } pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) { for i in 0..count { - let orig_header = node.blocks.borrow_mut().pop().unwrap(); + let orig_header = node.blocks.lock().unwrap().pop().unwrap(); assert!(orig_header.1 > 0); // Cannot disconnect genesis - let prev_header = node.blocks.borrow().last().unwrap().clone(); + let prev_header = node.blocks.lock().unwrap().last().unwrap().clone(); match *node.connect_style.borrow() { ConnectStyle::FullBlockViaListen => { @@ -175,7 +177,7 @@ pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) } pub fn disconnect_all_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>) { - let count = node.blocks.borrow_mut().len() as u32 - 1; + let count = node.blocks.lock().unwrap().len() as u32 - 1; disconnect_blocks(node, count); } @@ -209,15 +211,18 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> { pub network_payment_count: Rc>, pub network_chan_count: Rc>, pub logger: &'c test_utils::TestLogger, - pub blocks: RefCell>, + pub blocks: Arc>>, pub connect_style: Rc>, } impl<'a, 'b, 'c> Node<'a, 'b, 'c> { pub fn best_block_hash(&self) -> BlockHash { - self.blocks.borrow_mut().last().unwrap().0.block_hash() + self.blocks.lock().unwrap().last().unwrap().0.block_hash() } pub fn best_block_info(&self) -> (BlockHash, u32) { - self.blocks.borrow_mut().last().map(|(a, b)| (a.block_hash(), *b)).unwrap() + self.blocks.lock().unwrap().last().map(|(a, b)| (a.block_hash(), *b)).unwrap() + } + pub fn get_block_header(&self, height: u32) -> BlockHeader { + self.blocks.lock().unwrap()[height as usize].0 } } @@ -264,7 +269,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { // Check that if we serialize and then deserialize all our channel monitors we get the // same set of outputs to watch for on chain as we have now. Note that if we write // tests that fully close channels and remove the monitors at some point this may break. - let feeest = test_utils::TestFeeEstimator { sat_per_kw: 253 }; + let feeest = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }; let mut deserialized_monitors = Vec::new(); { let old_monitors = self.chain_monitor.chain_monitor.monitors.read().unwrap(); @@ -290,10 +295,11 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { <(BlockHash, ChannelManager)>::read(&mut ::std::io::Cursor::new(w.0), ChannelManagerReadArgs { default_config: *self.node.get_current_default_configuration(), keys_manager: self.keys_manager, - fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: 253 }, + fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }, chain_monitor: self.chain_monitor, tx_broadcaster: &test_utils::TestBroadcaster { - txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()) + txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()), + blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.lock().unwrap().clone())), }, logger: &test_utils::TestLogger::new(), channel_monitors, @@ -302,7 +308,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { let persister = test_utils::TestPersister::new(); let broadcaster = test_utils::TestBroadcaster { - txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()) + txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()), + blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.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, &self.keys_manager); @@ -555,7 +562,7 @@ pub fn create_chan_between_nodes_with_value_confirm_second<'a, 'b, 'c>(node_recv } 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]) { - let conf_height = std::cmp::max(node_a.best_block_info().1 + 1, node_b.best_block_info().1 + 1); + let conf_height = core::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); @@ -613,8 +620,22 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(nodes: &'a Vec>, a: usize, b: usize, ann: &msgs::ChannelAnnouncement, upd_1: &msgs::ChannelUpdate, upd_2: &msgs::ChannelUpdate) { nodes[a].node.broadcast_node_announcement([0, 0, 0], [0; 32], Vec::new()); let a_events = nodes[a].node.get_and_clear_pending_msg_events(); - assert_eq!(a_events.len(), 1); - let a_node_announcement = match a_events[0] { + assert!(a_events.len() >= 2); + + // ann should be re-generated by broadcast_node_announcement - check that we have it. + let mut found_ann_1 = false; + for event in a_events.iter() { + match event { + MessageSendEvent::BroadcastChannelAnnouncement { ref msg, .. } => { + if msg == ann { found_ann_1 = true; } + }, + MessageSendEvent::BroadcastNodeAnnouncement { .. } => {}, + _ => panic!("Unexpected event {:?}", event), + } + } + assert!(found_ann_1); + + let a_node_announcement = match a_events.last().unwrap() { MessageSendEvent::BroadcastNodeAnnouncement { ref msg } => { (*msg).clone() }, @@ -623,8 +644,22 @@ pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(nodes: &'a Vec= 2); + + // ann should be re-generated by broadcast_node_announcement - check that we have it. + let mut found_ann_2 = false; + for event in b_events.iter() { + match event { + MessageSendEvent::BroadcastChannelAnnouncement { ref msg, .. } => { + if msg == ann { found_ann_2 = true; } + }, + MessageSendEvent::BroadcastNodeAnnouncement { .. } => {}, + _ => panic!("Unexpected event"), + } + } + assert!(found_ann_2); + + let b_node_announcement = match b_events.last().unwrap() { MessageSendEvent::BroadcastNodeAnnouncement { ref msg } => { (*msg).clone() }, @@ -894,16 +929,29 @@ macro_rules! commitment_signed_dance { /// Get a payment preimage and hash. #[macro_export] macro_rules! get_payment_preimage_hash { - ($node: expr) => { + ($dest_node: expr) => { { - let payment_preimage = PaymentPreimage([*$node.network_payment_count.borrow(); 32]); - *$node.network_payment_count.borrow_mut() += 1; + let payment_preimage = PaymentPreimage([*$dest_node.network_payment_count.borrow(); 32]); + *$dest_node.network_payment_count.borrow_mut() += 1; let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()); - (payment_preimage, payment_hash) + let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap(); + (payment_preimage, payment_hash, payment_secret) } } } +#[cfg(test)] +macro_rules! get_route_and_payment_hash { + ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{ + let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!($recv_node); + let net_graph_msg_handler = &$send_node.net_graph_msg_handler; + let route = get_route(&$send_node.node.get_our_node_id(), + &net_graph_msg_handler.network_graph.read().unwrap(), + &$recv_node.node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, $send_node.logger).unwrap(); + (route, payment_hash, payment_preimage, payment_secret) + }} +} + macro_rules! expect_pending_htlcs_forwardable_ignore { ($node: expr) => {{ let events = $node.node.get_and_clear_pending_events(); @@ -924,13 +972,14 @@ macro_rules! expect_pending_htlcs_forwardable { #[cfg(any(test, feature = "unstable"))] macro_rules! expect_payment_received { - ($node: expr, $expected_payment_hash: expr, $expected_recv_value: expr) => { + ($node: expr, $expected_payment_hash: expr, $expected_payment_secret: expr, $expected_recv_value: expr) => { let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => { + Event::PaymentReceived { ref payment_hash, ref payment_preimage, ref payment_secret, amt, user_payment_id: _ } => { assert_eq!($expected_payment_hash, *payment_hash); - assert_eq!(None, *payment_secret); + assert!(payment_preimage.is_none()); + assert_eq!($expected_payment_secret, *payment_secret); assert_eq!($expected_recv_value, amt); }, _ => panic!("Unexpected event"), @@ -951,6 +1000,30 @@ macro_rules! expect_payment_sent { } } +#[cfg(test)] +macro_rules! expect_payment_failure_chan_update { + ($node: expr, $scid: expr, $chan_closed: expr) => { + let events = $node.node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + match events[0] { + MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => { + match update { + &HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } if !$chan_closed => { + assert_eq!(msg.contents.short_channel_id, $scid); + assert_eq!(msg.contents.flags & 2, 0); + }, + &HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent } if $chan_closed => { + assert_eq!(short_channel_id, $scid); + assert!(is_permanent); + }, + _ => panic!("Unexpected update type"), + } + }, + _ => panic!("Unexpected event"), + } + } +} + #[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)*) => { @@ -972,13 +1045,13 @@ macro_rules! expect_payment_failed { } } -pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option) { - origin_node.node.send_payment(&route, our_payment_hash, &our_payment_secret).unwrap(); +pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) { + origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(origin_node, expected_paths.len()); pass_along_route(origin_node, expected_paths, recv_value, our_payment_hash, our_payment_secret); } -pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option, ev: MessageSendEvent, payment_received_expected: bool) { +pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret, ev: MessageSendEvent, payment_received_expected: bool) { let mut payment_event = SendEvent::from_event(ev); let mut prev_node = origin_node; @@ -996,8 +1069,9 @@ pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path if payment_received_expected { assert_eq!(events_2.len(), 1); match events_2[0] { - Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => { + Event::PaymentReceived { ref payment_hash, ref payment_preimage, ref payment_secret, amt, user_payment_id: _ } => { assert_eq!(our_payment_hash, *payment_hash); + assert!(payment_preimage.is_none()); assert_eq!(our_payment_secret, *payment_secret); assert_eq!(amt, recv_value); }, @@ -1018,7 +1092,7 @@ pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path } } -pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option) { +pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) { let mut events = origin_node.node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), expected_route.len()); for (path_idx, (ev, expected_path)) in events.drain(..).zip(expected_route.iter()).enumerate() { @@ -1029,21 +1103,17 @@ pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_rou } } -pub fn send_along_route_with_hash<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash) { - send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None); -} - -pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) { - let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(origin_node); - send_along_route_with_hash(origin_node, route, expected_route, recv_value, our_payment_hash); - (our_payment_preimage, our_payment_hash) +pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) { + let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(expected_route.last().unwrap()); + send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, our_payment_secret); + (our_payment_preimage, our_payment_hash, our_payment_secret) } -pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option, expected_amount: u64) { +pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage) { for path in expected_paths.iter() { assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id()); } - assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount)); + assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage)); check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len()); macro_rules! msgs_from_ev { @@ -1127,20 +1197,19 @@ pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, } } -pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) { - claim_payment_along_route_with_secret(origin_node, &[expected_route], skip_last, our_payment_preimage, None, expected_amount); -} - -pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage, expected_amount: u64) { - claim_payment_along_route(origin_node, expected_route, false, our_payment_preimage, expected_amount); +pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage) { + claim_payment_along_route(origin_node, &[expected_route], false, our_payment_preimage); } -pub const TEST_FINAL_CLTV: u32 = 50; +pub const TEST_FINAL_CLTV: u32 = 70; -pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) { +pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) { let net_graph_msg_handler = &origin_node.net_graph_msg_handler; let logger = test_utils::TestLogger::new(); - let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), + &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), + Some(&origin_node.node.list_usable_channels().iter().collect::>()), &[], + recv_value, TEST_FINAL_CLTV, &logger).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].len(), expected_route.len()); for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) { @@ -1153,25 +1222,25 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) { let logger = test_utils::TestLogger::new(); let net_graph_msg_handler = &origin_node.net_graph_msg_handler; - let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].len(), expected_route.len()); for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) { assert_eq!(hop.pubkey, node.node.get_our_node_id()); } - let (_, our_payment_hash) = get_payment_preimage_hash!(origin_node); - unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { ref err }, + let (_, our_payment_hash, our_payment_preimage) = get_payment_preimage_hash!(expected_route.last().unwrap()); + unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_preimage)), true, APIError::ChannelUnavailable { ref err }, assert!(err.contains("Cannot send value that would put us over the max HTLC value in flight our peer will accept"))); } -pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, expected_value: u64) { +pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) { let our_payment_preimage = route_payment(&origin, expected_route, recv_value).0; - claim_payment(&origin, expected_route, our_payment_preimage, expected_value); + claim_payment(&origin, expected_route, our_payment_preimage); } pub fn fail_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_hash: PaymentHash) { - assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, &None)); + assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash)); expect_pending_htlcs_forwardable!(expected_route.last().unwrap()); check_added_monitors!(expected_route.last().unwrap(), 1); @@ -1246,8 +1315,11 @@ pub fn fail_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: pub fn create_chanmon_cfgs(node_count: usize) -> Vec { let mut chan_mon_cfgs = Vec::new(); for i in 0..node_count { - let tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}; - let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; + let tx_broadcaster = test_utils::TestBroadcaster { + txn_broadcasted: Mutex::new(Vec::new()), + blocks: Arc::new(Mutex::new(vec![(genesis_block(Network::Testnet).header, 0)])), + }; + let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }; let chain_source = test_utils::TestChainSource::new(Network::Testnet); let logger = test_utils::TestLogger::with_id(format!("node {}", i)); let persister = test_utils::TestPersister::new(); @@ -1272,22 +1344,29 @@ pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec UserConfig { + let mut default_config = UserConfig::default(); + // Set cltv_expiry_delta slightly lower to keep the final CLTV values inside one byte in our + // tests so that our script-length checks don't fail (see ACCEPTED_HTLC_SCRIPT_WEIGHT). + default_config.channel_options.cltv_expiry_delta = 6*6; + default_config.channel_options.announced_channel = true; + default_config.peer_channel_config_limits.force_announced_channel_preference = false; + // When most of our tests were written, the default HTLC minimum was fixed at 1000. + // It now defaults to 1, so we simply set it to the expected value here. + default_config.own_channel_config.our_htlc_minimum_msat = 1000; + default_config +} + pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec>, node_config: &[Option]) -> Vec, &'b test_utils::TestBroadcaster, &'a test_utils::TestKeysInterface, &'b test_utils::TestFeeEstimator, &'b test_utils::TestLogger>> { let mut chanmgrs = Vec::new(); for i in 0..node_count { - let mut default_config = UserConfig::default(); - // Set cltv_expiry_delta slightly lower to keep the final CLTV values inside one byte in our - // tests so that our script-length checks don't fail (see ACCEPTED_HTLC_SCRIPT_WEIGHT). - default_config.channel_options.cltv_expiry_delta = 6*6; - 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 network = Network::Testnet; let params = ChainParameters { network, 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); + 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 { test_default_channel_config() }, params); chanmgrs.push(node); } @@ -1307,7 +1386,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec { assert_eq!(*node_id, $dst_node.node.get_our_node_id()); revoke_and_ack = Some(msg.clone()); + idx += 1; RAACommitmentOrder::RevokeAndACKFirst }, &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { assert_eq!(*node_id, $dst_node.node.get_our_node_id()); commitment_update = Some(updates.clone()); + idx += 1; RAACommitmentOrder::CommitmentFirst }, + &MessageSendEvent::SendChannelUpdate { .. } => RAACommitmentOrder::CommitmentFirst, _ => panic!("Unexpected event"), } } else { @@ -1533,16 +1619,24 @@ macro_rules! handle_chan_reestablish_msgs { assert_eq!(*node_id, $dst_node.node.get_our_node_id()); assert!(revoke_and_ack.is_none()); revoke_and_ack = Some(msg.clone()); + idx += 1; }, &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { assert_eq!(*node_id, $dst_node.node.get_our_node_id()); assert!(commitment_update.is_none()); commitment_update = Some(updates.clone()); + idx += 1; }, + &MessageSendEvent::SendChannelUpdate { .. } => {}, _ => panic!("Unexpected event"), } } + if let Some(&MessageSendEvent::SendChannelUpdate { ref node_id, ref msg }) = msg_events.get(idx) { + assert_eq!(*node_id, $dst_node.node.get_our_node_id()); + assert_eq!(msg.contents.flags & 2, 0); // "disabled" flag must not be set as we just reconnected. + } + (funding_locked, revoke_and_ack, commitment_update, order) } }