X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_test_utils.rs;h=b4807ea688629a5a1940a1bb37e9b9ba56aa9760;hb=e5c988e00c515467e76639b5aac47b02a7f7b4a6;hp=5901efbf95cf47fbceabb97d77dcd94abfcd543f;hpb=c244c781f63618c4241324b460e6a6d77f525e73;p=rust-lightning diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 5901efbf..b4807ea6 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -14,7 +14,7 @@ use chain::{BestBlock, Confirm, Listen, Watch, keysinterface::KeysInterface}; use chain::channelmonitor::ChannelMonitor; use chain::transaction::OutPoint; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; -use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId}; +use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA}; use routing::network_graph::{NetGraphMsgHandler, NetworkGraph}; use routing::router::{PaymentParameters, Route, get_route}; use ln::features::{InitFeatures, InvoiceFeatures}; @@ -35,7 +35,7 @@ use bitcoin::network::constants::Network; use bitcoin::hash_types::BlockHash; -use bitcoin::secp256k1::key::PublicKey; +use bitcoin::secp256k1::PublicKey; use io; use prelude::*; @@ -396,6 +396,26 @@ macro_rules! get_event_msg { } } +/// Get an error message from the pending events queue. +#[macro_export] +macro_rules! get_err_msg { + ($node: expr, $node_id: expr) => { + { + let events = $node.node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + match events[0] { + $crate::util::events::MessageSendEvent::HandleError { + action: $crate::ln::msgs::ErrorAction::SendErrorMessage { ref msg }, ref node_id + } => { + assert_eq!(*node_id, $node_id); + (*msg).clone() + }, + _ => panic!("Unexpected event"), + } + } + } +} + /// Get a specific event from the pending events queue. #[macro_export] macro_rules! get_event { @@ -839,7 +859,7 @@ macro_rules! check_spends { 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) + let min_fee = ($tx.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(); @@ -1147,27 +1167,33 @@ macro_rules! get_payment_preimage_hash { } } -#[cfg(test)] #[macro_export] -macro_rules! get_route_and_payment_hash { - ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{ - $crate::get_route_and_payment_hash!($send_node, $recv_node, vec![], $recv_value, TEST_FINAL_CLTV) - }}; - ($send_node: expr, $recv_node: expr, $last_hops: expr, $recv_value: expr, $cltv: expr) => {{ +macro_rules! get_route { + ($send_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{ use $crate::chain::keysinterface::KeysInterface; - let (payment_preimage, payment_hash, payment_secret) = $crate::get_payment_preimage_hash!($recv_node, Some($recv_value)); - let payment_params = $crate::routing::router::PaymentParameters::from_node_id($recv_node.node.get_our_node_id()) - .with_features($crate::ln::features::InvoiceFeatures::known()) - .with_route_hints($last_hops); let scorer = $crate::util::test_utils::TestScorer::with_penalty(0); let keys_manager = $crate::util::test_utils::TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = $crate::routing::router::get_route( - &$send_node.node.get_our_node_id(), &payment_params, &$send_node.network_graph.read_only(), + $crate::routing::router::get_route( + &$send_node.node.get_our_node_id(), &$payment_params, &$send_node.network_graph.read_only(), Some(&$send_node.node.list_usable_channels().iter().collect::>()), $recv_value, $cltv, $send_node.logger, &scorer, &random_seed_bytes - ).unwrap(); - (route, payment_hash, payment_preimage, payment_secret) + ) + }} +} + +#[cfg(test)] +#[macro_export] +macro_rules! get_route_and_payment_hash { + ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{ + let payment_params = $crate::routing::router::PaymentParameters::from_node_id($recv_node.node.get_our_node_id()) + .with_features($crate::ln::features::InvoiceFeatures::known()); + $crate::get_route_and_payment_hash!($send_node, $recv_node, payment_params, $recv_value, TEST_FINAL_CLTV) + }}; + ($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{ + let (payment_preimage, payment_hash, payment_secret) = $crate::get_payment_preimage_hash!($recv_node, Some($recv_value)); + let route = $crate::get_route!($send_node, $payment_params, $recv_value, $cltv); + (route.unwrap(), payment_hash, payment_preimage, payment_secret) }} } @@ -1308,12 +1334,16 @@ macro_rules! expect_payment_path_successful { } macro_rules! expect_payment_forwarded { - ($node: expr, $expected_fee: expr, $upstream_force_closed: expr) => { + ($node: expr, $source_node: expr, $expected_fee: expr, $upstream_force_closed: expr) => { let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx } => { + Event::PaymentForwarded { fee_earned_msat, source_channel_id, claim_from_onchain_tx } => { assert_eq!(fee_earned_msat, $expected_fee); + if fee_earned_msat.is_some() { + // Is the event channel_id in one of the channels between the two nodes? + assert!($node.node.list_channels().iter().any(|x| x.counterparty.node_id == $source_node.node.get_our_node_id() && x.channel_id == source_channel_id.unwrap())); + } assert_eq!(claim_from_onchain_tx, $upstream_force_closed); }, _ => panic!("Unexpected event"), @@ -1552,11 +1582,11 @@ pub fn do_claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, } } macro_rules! mid_update_fulfill_dance { - ($node: expr, $prev_node: expr, $new_msgs: expr) => { + ($node: expr, $prev_node: expr, $next_node: expr, $new_msgs: expr) => { { $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0); let fee = $node.node.channel_state.lock().unwrap().by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap().config.forwarding_fee_base_msat; - expect_payment_forwarded!($node, Some(fee as u64), false); + expect_payment_forwarded!($node, $next_node, Some(fee as u64), false); expected_total_fee_msat += fee as u64; check_added_monitors!($node, 1); let new_next_msgs = if $new_msgs { @@ -1580,7 +1610,14 @@ pub fn do_claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, assert_eq!(expected_next_node, node.node.get_our_node_id()); let update_next_msgs = !skip_last || idx != expected_route.len() - 1; if next_msgs.is_some() { - mid_update_fulfill_dance!(node, prev_node, update_next_msgs); + // Since we are traversing in reverse, next_node is actually the previous node + let next_node: &Node; + if idx == expected_route.len() - 1 { + next_node = origin_node; + } else { + next_node = expected_route[expected_route.len() - 1 - idx - 1]; + } + mid_update_fulfill_dance!(node, prev_node, next_node, update_next_msgs); } else { assert!(!update_next_msgs); assert!(node.node.get_and_clear_pending_msg_events().is_empty()); @@ -1620,15 +1657,7 @@ 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, PaymentSecret) { let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id()) .with_features(InvoiceFeatures::known()); - let network_graph = origin_node.network_graph.read_only(); - let scorer = test_utils::TestScorer::with_penalty(0); - let seed = [0u8; 32]; - let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet); - let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = get_route( - &origin_node.node.get_our_node_id(), &payment_params, &network_graph, - Some(&origin_node.node.list_usable_channels().iter().collect::>()), - recv_value, TEST_FINAL_CLTV, origin_node.logger, &scorer, &random_seed_bytes).unwrap(); + let route = get_route!(origin_node, payment_params, recv_value, TEST_FINAL_CLTV).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()) { @@ -1828,7 +1857,7 @@ pub fn test_default_channel_config() -> 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.cltv_expiry_delta = MIN_CLTV_EXPIRY_DELTA; 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. @@ -1877,8 +1906,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec(node: &Node<'a, 'b, 'c>, prev_txn: &Vec< for tx in prev_txn { if node_txn[0].input[0].previous_output.txid == tx.txid() { check_spends!(node_txn[0], tx); - assert!(node_txn[0].input[0].witness[2].len() > 106); // must spend an htlc output + let mut iter = node_txn[0].input[0].witness.iter(); + iter.next().expect("expected 3 witness items"); + iter.next().expect("expected 3 witness items"); + assert!(iter.next().expect("expected 3 witness items").len() > 106); // must spend an htlc output assert_eq!(tx.input.len(), 1); // must spend a commitment tx found_prev = true; @@ -2137,9 +2169,9 @@ macro_rules! handle_chan_reestablish_msgs { /// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas /// for claims/fails they are separated out. pub fn reconnect_nodes<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, send_funding_locked: (bool, bool), pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_htlc_fails: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool)) { - node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None }); let reestablish_1 = get_chan_reestablish_msgs!(node_a, node_b); - node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None }); let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a); if send_funding_locked.0 {