X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=lightning%2Fsrc%2Fln%2Ffunctional_test_utils.rs;h=4dadd054ce219bef867e09f9ac01e91e4613665b;hb=9bd1cc76609e14c286477522cf2b56f17bd4346d;hp=c9b1c52d5c08d547ff6ed9e2268df7598a303042;hpb=a38bdbe7bc466156846a2b359d162e3d71f68959;p=rust-lightning diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index c9b1c52d..4dadd054 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -30,6 +30,8 @@ use crate::util::test_utils::{panicking, TestChainMonitor, TestScorer, TestKeysI use crate::util::errors::APIError; use crate::util::config::{UserConfig, MaxDustHTLCExposure}; use crate::util::ser::{ReadableArgs, Writeable}; +#[cfg(test)] +use crate::util::logger::Logger; use bitcoin::blockdata::block::{Block, BlockHeader}; use bitcoin::blockdata::transaction::{Transaction, TxOut}; @@ -436,6 +438,25 @@ impl<'a, 'b, 'c> Node<'a, 'b, 'c> { pub fn get_block_header(&self, height: u32) -> BlockHeader { self.blocks.lock().unwrap()[height as usize].0.header } + /// Changes the channel signer's availability for the specified peer and channel. + /// + /// When `available` is set to `true`, the channel signer will behave normally. When set to + /// `false`, the channel signer will act like an off-line remote signer and will return `Err` for + /// several of the signing methods. Currently, only `get_per_commitment_point` and + /// `release_commitment_secret` are affected by this setting. + #[cfg(test)] + pub fn set_channel_signer_available(&self, peer_id: &PublicKey, chan_id: &ChannelId, available: bool) { + let per_peer_state = self.node.per_peer_state.read().unwrap(); + let chan_lock = per_peer_state.get(peer_id).unwrap().lock().unwrap(); + let signer = (|| { + match chan_lock.channel_by_id.get(chan_id) { + Some(phase) => phase.context().get_signer(), + None => panic!("Couldn't find a channel with id {}", chan_id), + } + })(); + log_debug!(self.logger, "Setting channel signer for {} as available={}", chan_id, available); + signer.as_ecdsa().unwrap().set_available(available); + } } /// If we need an unsafe pointer to a `Node` (ie to reference it in a thread @@ -665,6 +686,12 @@ pub fn get_err_msg(node: &Node, recipient: &PublicKey) -> msgs::ErrorMessage { assert_eq!(node_id, recipient); (*msg).clone() }, + MessageSendEvent::HandleError { + action: msgs::ErrorAction::DisconnectPeer { ref msg }, ref node_id + } => { + assert_eq!(node_id, recipient); + msg.as_ref().unwrap().clone() + }, _ => panic!("Unexpected event"), } } @@ -787,6 +814,18 @@ pub fn remove_first_msg_event_to_node(msg_node_id: &PublicKey, msg_events: &mut MessageSendEvent::SendOpenChannelV2 { node_id, .. } => { node_id == msg_node_id }, + MessageSendEvent::SendStfu { node_id, .. } => { + node_id == msg_node_id + }, + MessageSendEvent::SendSplice { node_id, .. } => { + node_id == msg_node_id + }, + MessageSendEvent::SendSpliceAck { node_id, .. } => { + node_id == msg_node_id + }, + MessageSendEvent::SendSpliceLocked { node_id, .. } => { + node_id == msg_node_id + }, MessageSendEvent::SendTxAddInput { node_id, .. } => { node_id == msg_node_id }, @@ -918,7 +957,8 @@ macro_rules! unwrap_send_err { pub fn check_added_monitors>(node: &H, count: usize) { if let Some(chain_monitor) = node.chain_monitor() { let mut added_monitors = chain_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), count); + let n = added_monitors.len(); + assert_eq!(n, count, "expected {} monitors to be added, not {}", count, n); added_monitors.clear(); } } @@ -1098,7 +1138,7 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r let initiator_channels = initiator.node.list_usable_channels().len(); let receiver_channels = receiver.node.list_usable_channels().len(); - initiator.node.create_channel(receiver.node.get_our_node_id(), 100_000, 10_001, 42, initiator_config).unwrap(); + initiator.node.create_channel(receiver.node.get_our_node_id(), 100_000, 10_001, 42, None, initiator_config).unwrap(); let open_channel = get_event_msg!(initiator, MessageSendEvent::SendOpenChannel, receiver.node.get_our_node_id()); receiver.node.handle_open_channel(&initiator.node.get_our_node_id(), &open_channel); @@ -1164,7 +1204,7 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r } pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64) -> Transaction { - let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap(); + let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None, None).unwrap(); let open_channel_msg = get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id()); assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id); assert_eq!(node_a.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 42); @@ -1281,7 +1321,7 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c: 'd, 'd>(nodes: pub fn create_unannounced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a Vec>, a: usize, b: usize, channel_value: u64, push_msat: u64) -> (msgs::ChannelReady, Transaction) { let mut no_announce_cfg = test_default_channel_config(); no_announce_cfg.channel_handshake_config.announced_channel = false; - nodes[a].node.create_channel(nodes[b].node.get_our_node_id(), channel_value, push_msat, 42, Some(no_announce_cfg)).unwrap(); + nodes[a].node.create_channel(nodes[b].node.get_our_node_id(), channel_value, push_msat, 42, None, Some(no_announce_cfg)).unwrap(); let open_channel = get_event_msg!(nodes[a], MessageSendEvent::SendOpenChannel, nodes[b].node.get_our_node_id()); nodes[b].node.handle_open_channel(&nodes[a].node.get_our_node_id(), &open_channel); let accept_channel = get_event_msg!(nodes[b], MessageSendEvent::SendAcceptChannel, nodes[a].node.get_our_node_id()); @@ -1446,10 +1486,15 @@ pub fn check_closed_broadcast(node: &Node, num_channels: usize, with_error_msg: assert_eq!(msg.contents.flags & 2, 2); None }, - MessageSendEvent::HandleError { action: msgs::ErrorAction::SendErrorMessage { ref msg }, node_id: _ } => { + MessageSendEvent::HandleError { action: msgs::ErrorAction::SendErrorMessage { msg }, node_id: _ } => { assert!(with_error_msg); // TODO: Check node_id - Some(msg.clone()) + Some(msg) + }, + MessageSendEvent::HandleError { action: msgs::ErrorAction::DisconnectPeer { msg }, node_id: _ } => { + assert!(with_error_msg); + // TODO: Check node_id + Some(msg.unwrap()) }, _ => panic!("Unexpected event"), } @@ -1467,27 +1512,61 @@ macro_rules! check_closed_broadcast { } } +#[derive(Default)] +pub struct ExpectedCloseEvent { + pub channel_capacity_sats: Option, + pub channel_id: Option, + pub counterparty_node_id: Option, + pub discard_funding: bool, + pub reason: Option, +} + +/// Check that multiple channel closing events have been issued. +pub fn check_closed_events(node: &Node, expected_close_events: &[ExpectedCloseEvent]) { + let closed_events_count = expected_close_events.len(); + let discard_events_count = expected_close_events.iter().filter(|e| e.discard_funding).count(); + let events = node.node.get_and_clear_pending_events(); + assert_eq!(events.len(), closed_events_count + discard_events_count, "{:?}", events); + for expected_event in expected_close_events { + assert!(events.iter().any(|e| matches!( + e, + Event::ChannelClosed { + channel_id, + reason, + counterparty_node_id, + channel_capacity_sats, + .. + } if ( + expected_event.channel_id.map(|expected| *channel_id == expected).unwrap_or(true) && + expected_event.reason.as_ref().map(|expected| reason == expected).unwrap_or(true) && + expected_event.counterparty_node_id.map(|expected| *counterparty_node_id == Some(expected)).unwrap_or(true) && + expected_event.channel_capacity_sats.map(|expected| *channel_capacity_sats == Some(expected)).unwrap_or(true) + ) + ))); + } + assert_eq!(events.iter().filter(|e| matches!( + e, + Event::DiscardFunding { .. }, + )).count(), discard_events_count); +} + /// Check that a channel's closing channel events has been issued pub fn check_closed_event(node: &Node, events_count: usize, expected_reason: ClosureReason, is_check_discard_funding: bool, expected_counterparty_node_ids: &[PublicKey], expected_channel_capacity: u64) { - let events = node.node.get_and_clear_pending_events(); - assert_eq!(events.len(), events_count, "{:?}", events); - let mut issues_discard_funding = false; - for event in events { - match event { - Event::ChannelClosed { ref reason, counterparty_node_id, - channel_capacity_sats, .. } => { - assert_eq!(*reason, expected_reason); - assert!(expected_counterparty_node_ids.iter().any(|id| id == &counterparty_node_id.unwrap())); - assert_eq!(channel_capacity_sats.unwrap(), expected_channel_capacity); - }, - Event::DiscardFunding { .. } => { - issues_discard_funding = true; - } - _ => panic!("Unexpected event"), - } - } - assert_eq!(is_check_discard_funding, issues_discard_funding); + let expected_events_count = if is_check_discard_funding { + 2 * expected_counterparty_node_ids.len() + } else { + expected_counterparty_node_ids.len() + }; + assert_eq!(events_count, expected_events_count); + let expected_close_events = expected_counterparty_node_ids.iter().map(|node_id| ExpectedCloseEvent { + channel_capacity_sats: Some(expected_channel_capacity), + channel_id: None, + counterparty_node_id: Some(*node_id), + discard_funding: is_check_discard_funding, + reason: Some(expected_reason.clone()), + }).collect::>(); + check_closed_events(node, expected_close_events.as_slice()); } /// Check that a channel's closing channel events has been issued @@ -1893,7 +1972,7 @@ macro_rules! get_route { 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(), TEST_FINAL_CLTV) - .with_bolt11_features($recv_node.node.invoice_features()).unwrap(); + .with_bolt11_features($recv_node.node.bolt11_invoice_features()).unwrap(); $crate::get_route_and_payment_hash!($send_node, $recv_node, payment_params, $recv_value) }}; ($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr) => {{ @@ -2074,12 +2153,13 @@ macro_rules! expect_channel_shutdown_state { } #[cfg(any(test, ldk_bench, feature = "_test_utils"))] -pub fn expect_channel_pending_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) { +pub fn expect_channel_pending_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) -> ChannelId { let events = node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); - match events[0] { - crate::events::Event::ChannelPending { ref counterparty_node_id, .. } => { + match &events[0] { + crate::events::Event::ChannelPending { channel_id, counterparty_node_id, .. } => { assert_eq!(*expected_counterparty_node_id, *counterparty_node_id); + *channel_id }, _ => panic!("Unexpected event"), } @@ -2563,7 +2643,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, PaymentId) { let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV) - .with_bolt11_features(expected_route.last().unwrap().node.invoice_features()).unwrap(); + .with_bolt11_features(expected_route.last().unwrap().node.bolt11_invoice_features()).unwrap(); let route_params = RouteParameters::from_payment_params_and_value(payment_params, recv_value); let route = get_route(origin_node, &route_params).unwrap(); assert_eq!(route.paths.len(), 1); @@ -2578,7 +2658,7 @@ 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 payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV) - .with_bolt11_features(expected_route.last().unwrap().node.invoice_features()).unwrap(); + .with_bolt11_features(expected_route.last().unwrap().node.bolt11_invoice_features()).unwrap(); let route_params = RouteParameters::from_payment_params_and_value(payment_params, recv_value); let network_graph = origin_node.network_graph.read_only(); let scorer = test_utils::TestScorer::new(); @@ -2978,6 +3058,13 @@ pub fn handle_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec { + assert_eq!(node_id, nodes[b].node.get_our_node_id()); + assert_eq!(msg.as_ref().unwrap().data, expected_error); + if needs_err_handle { + nodes[b].node.handle_error(&nodes[a].node.get_our_node_id(), msg.as_ref().unwrap()); + } + }, _ => panic!("Unexpected event"), } @@ -2995,6 +3082,10 @@ pub fn handle_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec { + assert_eq!(node_id, nodes[a].node.get_our_node_id()); + assert_eq!(msg.as_ref().unwrap().data, expected_error); + }, _ => panic!("Unexpected event"), } } @@ -3176,24 +3267,28 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) { // If a expects a channel_ready, it better not think it has received a revoke_and_ack // from b for reestablish in reestablish_1.iter() { - assert_eq!(reestablish.next_remote_commitment_number, 0); + let n = reestablish.next_remote_commitment_number; + assert_eq!(n, 0, "expected a->b next_remote_commitment_number to be 0, got {}", n); } } if send_channel_ready.1 { // If b expects a channel_ready, it better not think it has received a revoke_and_ack // from a for reestablish in reestablish_2.iter() { - assert_eq!(reestablish.next_remote_commitment_number, 0); + let n = reestablish.next_remote_commitment_number; + assert_eq!(n, 0, "expected b->a next_remote_commitment_number to be 0, got {}", n); } } if send_channel_ready.0 || send_channel_ready.1 { // If we expect any channel_ready's, both sides better have set // next_holder_commitment_number to 1 for reestablish in reestablish_1.iter() { - assert_eq!(reestablish.next_local_commitment_number, 1); + let n = reestablish.next_local_commitment_number; + assert_eq!(n, 1, "expected a->b next_local_commitment_number to be 1, got {}", n); } for reestablish in reestablish_2.iter() { - assert_eq!(reestablish.next_local_commitment_number, 1); + let n = reestablish.next_local_commitment_number; + assert_eq!(n, 1, "expected b->a next_local_commitment_number to be 1, got {}", n); } } @@ -3355,6 +3450,7 @@ pub fn create_batch_channel_funding<'a, 'b, 'c>( // Initialize channel opening. let temp_chan_id = funding_node.node.create_channel( other_node.node.get_our_node_id(), *channel_value_satoshis, *push_msat, *user_channel_id, + None, *override_config, ).unwrap(); let open_channel_msg = get_event_msg!(funding_node, MessageSendEvent::SendOpenChannel, other_node.node.get_our_node_id());