X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_test_utils.rs;h=00168fdfb0ca0252c3c54117ad6a05533cbdd794;hb=88e1b56d66ff550b36a6d422f47c9b9729406f61;hp=c0f3458b3d6246969f3525123ec3cd4d302f7031;hpb=bfda1b683bb5a87b123c3986a029e043addef159;p=rust-lightning diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index c0f3458b..00168fdf 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -31,6 +31,8 @@ use crate::util::errors::APIError; use crate::util::logger::Logger; use crate::util::scid_utils; use crate::util::test_channel_signer::TestChannelSigner; +#[cfg(test)] +use crate::util::test_channel_signer::SignerOp; use crate::util::test_utils; use crate::util::test_utils::{panicking, TestChainMonitor, TestScorer, TestKeysInterface}; use crate::util::ser::{ReadableArgs, Writeable}; @@ -421,6 +423,7 @@ type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger< &'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>, &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>, IgnoringMessageHandler, + IgnoringMessageHandler, >; /// For use with [`OnionMessenger`] otherwise `test_restored_packages_retry` will fail. This is @@ -482,46 +485,74 @@ impl<'a, 'b, 'c> Node<'a, 'b, 'c> { pub fn get_block_header(&self, height: u32) -> Header { self.blocks.lock().unwrap()[height as usize].0.header } - /// Changes the channel signer's availability for the specified peer and channel. + + /// Toggles this node's signer to be available for the given signer operation. + /// This is useful for testing behavior for restoring an async signer that previously + /// could not return a signature immediately. + #[cfg(test)] + pub fn enable_channel_signer_op(&self, peer_id: &PublicKey, chan_id: &ChannelId, signer_op: SignerOp) { + self.set_channel_signer_ops(peer_id, chan_id, signer_op, true); + } + + /// Toggles this node's signer to be unavailable, returning `Err` for the given signer operation. + /// This is useful for testing behavior for an async signer that cannot return a signature + /// immediately. + #[cfg(test)] + pub fn disable_channel_signer_op(&self, peer_id: &PublicKey, chan_id: &ChannelId, signer_op: SignerOp) { + self.set_channel_signer_ops(peer_id, chan_id, signer_op, false); + } + + /// Changes the channel signer's availability for the specified peer, channel, and signer + /// operation. /// - /// 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. + /// For the specified signer operation, when `available` is set to `true`, the channel signer + /// will behave normally, returning `Ok`. When set to `false`, and the channel signer will + /// act like an off-line remote signer, returning `Err`. This applies to the signer in all + /// relevant places, i.e. the channel manager, chain monitor, and the keys manager. #[cfg(test)] - pub fn set_channel_signer_available(&self, peer_id: &PublicKey, chan_id: &ChannelId, available: bool) { + fn set_channel_signer_ops(&self, peer_id: &PublicKey, chan_id: &ChannelId, signer_op: SignerOp, available: bool) { use crate::sign::ChannelSigner; log_debug!(self.logger, "Setting channel signer for {} as available={}", chan_id, available); let per_peer_state = self.node.per_peer_state.read().unwrap(); - let chan_lock = per_peer_state.get(peer_id).unwrap().lock().unwrap(); + let mut chan_lock = per_peer_state.get(peer_id).unwrap().lock().unwrap(); let mut channel_keys_id = None; - if let Some(chan) = chan_lock.channel_by_id.get(chan_id).map(|phase| phase.context()) { - chan.get_signer().as_ecdsa().unwrap().set_available(available); + if let Some(chan) = chan_lock.channel_by_id.get_mut(chan_id).map(|phase| phase.context_mut()) { + let signer = chan.get_mut_signer().as_mut_ecdsa().unwrap(); + if available { + signer.enable_op(signer_op); + } else { + signer.disable_op(signer_op); + } channel_keys_id = Some(chan.channel_keys_id); } - let mut monitor = None; - for (funding_txo, channel_id) in self.chain_monitor.chain_monitor.list_monitors() { - if *chan_id == channel_id { - monitor = self.chain_monitor.chain_monitor.get_monitor(funding_txo).ok(); - } - } + let monitor = self.chain_monitor.chain_monitor.list_monitors().into_iter() + .find(|(_, channel_id)| *channel_id == *chan_id) + .and_then(|(funding_txo, _)| self.chain_monitor.chain_monitor.get_monitor(funding_txo).ok()); if let Some(monitor) = monitor { - monitor.do_signer_call(|signer| { + monitor.do_mut_signer_call(|signer| { channel_keys_id = channel_keys_id.or(Some(signer.inner.channel_keys_id())); - signer.set_available(available) + if available { + signer.enable_op(signer_op); + } else { + signer.disable_op(signer_op); + } }); } + let channel_keys_id = channel_keys_id.unwrap(); + let mut unavailable_signers_ops = self.keys_manager.unavailable_signers_ops.lock().unwrap(); + let entry = unavailable_signers_ops.entry(channel_keys_id).or_insert(new_hash_set()); if available { - self.keys_manager.unavailable_signers.lock().unwrap() - .remove(channel_keys_id.as_ref().unwrap()); + entry.remove(&signer_op); + if entry.is_empty() { + unavailable_signers_ops.remove(&channel_keys_id); + } } else { - self.keys_manager.unavailable_signers.lock().unwrap() - .insert(channel_keys_id.unwrap()); - } + entry.insert(signer_op); + }; } } @@ -2455,18 +2486,11 @@ pub fn expect_payment_failed_conditions_event<'a, 'b, 'c, 'd, 'e>( if let Some(chan_closed) = conditions.expected_blamed_chan_closed { if let PathFailure::OnPath { network_update: Some(upd) } = failure { match upd { - NetworkUpdate::ChannelUpdateMessage { ref msg } if !chan_closed => { - if let Some(scid) = conditions.expected_blamed_scid { - assert_eq!(msg.contents.short_channel_id, scid); - } - const CHAN_DISABLED_FLAG: u8 = 2; - assert_eq!(msg.contents.flags & CHAN_DISABLED_FLAG, 0); - }, - NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } if chan_closed => { + NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } => { if let Some(scid) = conditions.expected_blamed_scid { assert_eq!(*short_channel_id, scid); } - assert!(is_permanent); + assert_eq!(*is_permanent, chan_closed); }, _ => panic!("Unexpected update type"), } @@ -3235,7 +3259,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec(node_count: usize, cfgs: &'b Vec(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>) { + let node_id_a = node_a.node.get_our_node_id(); + let node_id_b = node_b.node.get_our_node_id(); + + let init_a = msgs::Init { + features: node_a.init_features(&node_id_b), + networks: None, + remote_network_address: None, + }; + let init_b = msgs::Init { + features: node_b.init_features(&node_id_a), + networks: None, + remote_network_address: None, + }; + + node_a.node.peer_connected(&node_id_b, &init_b, true).unwrap(); + node_b.node.peer_connected(&node_id_a, &init_a, false).unwrap(); + node_a.onion_messenger.peer_connected(&node_id_b, &init_b, true).unwrap(); + node_b.onion_messenger.peer_connected(&node_id_a, &init_a, false).unwrap(); +} + pub fn connect_dummy_node<'a, 'b: 'a, 'c: 'b>(node: &Node<'a, 'b, 'c>) { let node_id_dummy = PublicKey::from_slice(&[2; 33]).unwrap(); @@ -3643,13 +3671,8 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) { pending_cell_htlc_claims, pending_cell_htlc_fails, pending_raa, pending_responding_commitment_signed, pending_responding_commitment_signed_dup_monitor, } = args; - node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { - features: node_b.node.init_features(), networks: None, remote_network_address: None - }, true).unwrap(); + connect_nodes(node_a, node_b); 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: node_a.node.init_features(), networks: None, remote_network_address: None - }, false).unwrap(); let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a); if send_channel_ready.0 {