X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fonion_message%2Ffunctional_tests.rs;h=9850e53642c705ac21b950db1e6f68cf4e7822db;hb=a8bd4c097f7ae6620eee66c1cb49144e38568439;hp=b0031a6c3f4e05cd41823ceb9fa785ab3fb91722;hpb=97049daac211b65cf6113960059fedaad12397b4;p=rust-lightning diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index b0031a6c..9850e536 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -9,68 +9,73 @@ //! Onion message testing and test utilities live here. -use crate::blinded_path::BlindedPath; +use crate::blinded_path::{BlindedPath, EmptyNodeIdLookUp}; +use crate::blinded_path::message::ForwardNode; use crate::events::{Event, EventsProvider}; -use crate::ln::features::InitFeatures; -use crate::ln::msgs::{self, DecodeError, OnionMessageHandler, SocketAddress}; -use crate::sign::{EntropySource, NodeSigner, Recipient}; +use crate::ln::features::{ChannelFeatures, InitFeatures}; +use crate::ln::msgs::{self, DecodeError, OnionMessageHandler}; +use crate::routing::gossip::{NetworkGraph, P2PGossipSync}; +use crate::routing::test_utils::{add_channel, add_or_update_node}; +use crate::sign::{NodeSigner, Recipient}; use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer}; use crate::util::test_utils; -use super::{CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger, PendingOnionMessage, SendError}; +use super::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, OnionMessagePath, OnionMessenger, PendingOnionMessage, Responder, ResponseInstruction, SendError}; +use super::offers::{OffersMessage, OffersMessageHandler}; +use super::packet::{OnionMessageContents, Packet}; -use bitcoin::network::constants::Network; +use bitcoin::network::Network; use bitcoin::hashes::hex::FromHex; -use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self}; +use bitcoin::secp256k1::{All, PublicKey, Secp256k1, SecretKey}; use crate::io; use crate::io_extras::read_to_end; use crate::sync::{Arc, Mutex}; +use core::ops::Deref; + use crate::prelude::*; struct MessengerNode { node_id: PublicKey, + privkey: SecretKey, entropy_source: Arc, messenger: OnionMessenger< Arc, Arc, Arc, - Arc, + Arc, + Arc>>, + Arc, + Arc + >>, Arc, Arc >, custom_message_handler: Arc, + gossip_sync: Arc>>, + Arc, + Arc + >> } -struct TestMessageRouter {} - -impl MessageRouter for TestMessageRouter { - fn find_path( - &self, _sender: PublicKey, _peers: Vec, destination: Destination - ) -> Result { - Ok(OnionMessagePath { - intermediate_nodes: vec![], - destination, - first_node_addresses: - Some(vec![SocketAddress::TcpIpV4 { addr: [127, 0, 0, 1], port: 1000 }]), - }) - } - - fn create_blinded_paths< - ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification - >( - &self, _recipient: PublicKey, _peers: Vec, _entropy_source: &ES, - _secp_ctx: &Secp256k1 - ) -> Result, ()> { - unreachable!() +impl Drop for MessengerNode { + fn drop(&mut self) { + #[cfg(feature = "std")] { + if std::thread::panicking() { + return; + } + } + assert!(release_events(self).is_empty()); } } struct TestOffersMessageHandler {} impl OffersMessageHandler for TestOffersMessageHandler { - fn handle_message(&self, _message: OffersMessage) -> Option { - None + fn handle_message(&self, _message: OffersMessage, _responder: Option) -> ResponseInstruction { + ResponseInstruction::NoResponse } } @@ -92,6 +97,9 @@ impl OnionMessageContents for TestCustomMessage { TestCustomMessage::Response => CUSTOM_RESPONSE_MESSAGE_TYPE, } } + fn msg_type(&self) -> &'static str { + "Custom Message" + } } impl Writeable for TestCustomMessage { @@ -130,15 +138,19 @@ impl Drop for TestCustomMessageHandler { impl CustomOnionMessageHandler for TestCustomMessageHandler { type CustomMessage = TestCustomMessage; - fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option { + fn handle_custom_message(&self, msg: Self::CustomMessage, responder: Option) -> ResponseInstruction { match self.expected_messages.lock().unwrap().pop_front() { Some(expected_msg) => assert_eq!(expected_msg, msg), None => panic!("Unexpected message: {:?}", msg), } - - match msg { + let response_option = match msg { TestCustomMessage::Request => Some(TestCustomMessage::Response), TestCustomMessage::Response => None, + }; + if let (Some(response), Some(responder)) = (response_option, responder) { + responder.respond(response) + } else { + ResponseInstruction::NoResponse } } fn read_custom_message(&self, message_type: u64, buffer: &mut R) -> Result, DecodeError> where Self: Sized { @@ -162,32 +174,72 @@ impl CustomOnionMessageHandler for TestCustomMessageHandler { } fn create_nodes(num_messengers: u8) -> Vec { - let secrets = (1..=num_messengers) + let cfgs = (1..=num_messengers) .into_iter() - .map(|i| SecretKey::from_slice(&[i; 32]).unwrap()) + .map(|_| MessengerCfg::new()) .collect(); - create_nodes_using_secrets(secrets) + create_nodes_using_cfgs(cfgs) +} + +struct MessengerCfg { + secret_override: Option, + intercept_offline_peer_oms: bool, +} +impl MessengerCfg { + fn new() -> Self { + Self { secret_override: None, intercept_offline_peer_oms: false } + } + fn with_node_secret(mut self, secret: SecretKey) -> Self { + self.secret_override = Some(secret); + self + } + fn with_offline_peer_interception(mut self) -> Self { + self.intercept_offline_peer_oms = true; + self + } } -fn create_nodes_using_secrets(secrets: Vec) -> Vec { +fn create_nodes_using_cfgs(cfgs: Vec) -> Vec { + let gossip_logger = Arc::new(test_utils::TestLogger::with_id("gossip".to_string())); + let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, gossip_logger.clone())); + let gossip_sync = Arc::new( + P2PGossipSync::new(network_graph.clone(), None, gossip_logger) + ); + let mut nodes = Vec::new(); - for (i, secret_key) in secrets.into_iter().enumerate() { + for (i, cfg) in cfgs.into_iter().enumerate() { + let secret_key = cfg.secret_override.unwrap_or(SecretKey::from_slice(&[(i + 1) as u8; 32]).unwrap()); let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i))); let seed = [i as u8; 32]; let entropy_source = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet)); let node_signer = Arc::new(test_utils::TestNodeSigner::new(secret_key)); - let message_router = Arc::new(TestMessageRouter {}); + let node_id_lookup = Arc::new(EmptyNodeIdLookUp {}); + let message_router = Arc::new( + DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone()) + ); let offers_message_handler = Arc::new(TestOffersMessageHandler {}); let custom_message_handler = Arc::new(TestCustomMessageHandler::new()); + let messenger = if cfg.intercept_offline_peer_oms { + OnionMessenger::new_with_offline_peer_interception( + entropy_source.clone(), node_signer.clone(), logger.clone(), + node_id_lookup, message_router, offers_message_handler, + custom_message_handler.clone() + ) + } else { + OnionMessenger::new( + entropy_source.clone(), node_signer.clone(), logger.clone(), + node_id_lookup, message_router, offers_message_handler, + custom_message_handler.clone() + ) + }; nodes.push(MessengerNode { + privkey: secret_key, node_id: node_signer.get_node_id(Recipient::Node).unwrap(), - entropy_source: entropy_source.clone(), - messenger: OnionMessenger::new( - entropy_source, node_signer, logger.clone(), message_router, - offers_message_handler, custom_message_handler.clone() - ), + entropy_source, + messenger, custom_message_handler, + gossip_sync: gossip_sync.clone(), }); } for i in 0..nodes.len() - 1 { @@ -215,6 +267,20 @@ fn release_events(node: &MessengerNode) -> Vec { events.into_inner() } +fn add_channel_to_graph( + node_a: &MessengerNode, node_b: &MessengerNode, secp_ctx: &Secp256k1, short_channel_id: u64 +) { + let gossip_sync = node_a.gossip_sync.deref(); + let privkey_a = &node_a.privkey; + let privkey_b = &node_b.privkey; + let channel_features = ChannelFeatures::empty(); + let node_features_a = node_a.messenger.provided_node_features(); + let node_features_b = node_b.messenger.provided_node_features(); + add_channel(gossip_sync, secp_ctx, privkey_a, privkey_b, channel_features, short_channel_id); + add_or_update_node(gossip_sync, secp_ctx, privkey_a, node_features_a, 1); + add_or_update_node(gossip_sync, secp_ctx, privkey_b, node_features_b, 1); +} + fn pass_along_path(path: &Vec) { let mut prev_node = &path[0]; for node in path.into_iter().skip(1) { @@ -234,12 +300,8 @@ fn one_unblinded_hop() { let nodes = create_nodes(2); let test_msg = TestCustomMessage::Response; - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::Node(nodes[1].node_id), - first_node_addresses: None, - }; - nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); + let destination = Destination::Node(nodes[1].node_id); + nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response); pass_along_path(&nodes); } @@ -254,6 +316,7 @@ fn two_unblinded_hops() { destination: Destination::Node(nodes[2].node_id), first_node_addresses: None, }; + nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response); pass_along_path(&nodes); @@ -265,13 +328,9 @@ fn one_blinded_hop() { let test_msg = TestCustomMessage::Response; let secp_ctx = Secp256k1::new(); - let blinded_path = BlindedPath::new_for_message(&[nodes[1].node_id], &*nodes[1].entropy_source, &secp_ctx).unwrap(); - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::BlindedPath(blinded_path), - first_node_addresses: None, - }; - nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); + let blinded_path = BlindedPath::new_for_message(&[], nodes[1].node_id, &*nodes[1].entropy_source, &secp_ctx).unwrap(); + let destination = Destination::BlindedPath(blinded_path); + nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response); pass_along_path(&nodes); } @@ -282,7 +341,8 @@ fn two_unblinded_two_blinded() { let test_msg = TestCustomMessage::Response; let secp_ctx = Secp256k1::new(); - let blinded_path = BlindedPath::new_for_message(&[nodes[3].node_id, nodes[4].node_id], &*nodes[4].entropy_source, &secp_ctx).unwrap(); + let intermediate_nodes = [ForwardNode { node_id: nodes[3].node_id, short_channel_id: None }]; + let blinded_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[4].node_id, &*nodes[4].entropy_source, &secp_ctx).unwrap(); let path = OnionMessagePath { intermediate_nodes: vec![nodes[1].node_id, nodes[2].node_id], destination: Destination::BlindedPath(blinded_path), @@ -300,14 +360,14 @@ fn three_blinded_hops() { let test_msg = TestCustomMessage::Response; let secp_ctx = Secp256k1::new(); - let blinded_path = BlindedPath::new_for_message(&[nodes[1].node_id, nodes[2].node_id, nodes[3].node_id], &*nodes[3].entropy_source, &secp_ctx).unwrap(); - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::BlindedPath(blinded_path), - first_node_addresses: None, - }; + let intermediate_nodes = [ + ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, + ForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, + ]; + let blinded_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[3].node_id, &*nodes[3].entropy_source, &secp_ctx).unwrap(); + let destination = Destination::BlindedPath(blinded_path); - nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); + nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); nodes[3].custom_message_handler.expect_message(TestCustomMessage::Response); pass_along_path(&nodes); } @@ -337,25 +397,22 @@ fn we_are_intro_node() { let test_msg = TestCustomMessage::Response; let secp_ctx = Secp256k1::new(); - let blinded_path = BlindedPath::new_for_message(&[nodes[0].node_id, nodes[1].node_id, nodes[2].node_id], &*nodes[2].entropy_source, &secp_ctx).unwrap(); - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::BlindedPath(blinded_path), - first_node_addresses: None, - }; + let intermediate_nodes = [ + ForwardNode { node_id: nodes[0].node_id, short_channel_id: None }, + ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, + ]; + let blinded_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[2].node_id, &*nodes[2].entropy_source, &secp_ctx).unwrap(); + let destination = Destination::BlindedPath(blinded_path); - nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), None).unwrap(); + nodes[0].messenger.send_onion_message(test_msg.clone(), destination, None).unwrap(); nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response); pass_along_path(&nodes); // Try with a two-hop blinded path where we are the introduction node. - let blinded_path = BlindedPath::new_for_message(&[nodes[0].node_id, nodes[1].node_id], &*nodes[1].entropy_source, &secp_ctx).unwrap(); - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::BlindedPath(blinded_path), - first_node_addresses: None, - }; - nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); + let intermediate_nodes = [ForwardNode { node_id: nodes[0].node_id, short_channel_id: None }]; + let blinded_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[1].node_id, &*nodes[1].entropy_source, &secp_ctx).unwrap(); + let destination = Destination::BlindedPath(blinded_path); + nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response); nodes.remove(2); pass_along_path(&nodes); @@ -363,20 +420,16 @@ fn we_are_intro_node() { #[test] fn invalid_blinded_path_error() { - // Make sure we error as expected if a provided blinded path has 0 or 1 hops. + // Make sure we error as expected if a provided blinded path has 0 hops. let nodes = create_nodes(3); let test_msg = TestCustomMessage::Response; - // 0 hops let secp_ctx = Secp256k1::new(); - let mut blinded_path = BlindedPath::new_for_message(&[nodes[1].node_id, nodes[2].node_id], &*nodes[2].entropy_source, &secp_ctx).unwrap(); + let intermediate_nodes = [ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; + let mut blinded_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[2].node_id, &*nodes[2].entropy_source, &secp_ctx).unwrap(); blinded_path.blinded_hops.clear(); - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::BlindedPath(blinded_path), - first_node_addresses: None, - }; - let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), None).unwrap_err(); + let destination = Destination::BlindedPath(blinded_path); + let err = nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap_err(); assert_eq!(err, SendError::TooFewBlindedHops); } @@ -392,7 +445,11 @@ fn reply_path() { destination: Destination::Node(nodes[3].node_id), first_node_addresses: None, }; - let reply_path = BlindedPath::new_for_message(&[nodes[2].node_id, nodes[1].node_id, nodes[0].node_id], &*nodes[0].entropy_source, &secp_ctx).unwrap(); + let intermediate_nodes = [ + ForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, + ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, + ]; + let reply_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[0].node_id, &*nodes[0].entropy_source, &secp_ctx).unwrap(); nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), Some(reply_path)).unwrap(); nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request); pass_along_path(&nodes); @@ -402,15 +459,19 @@ fn reply_path() { pass_along_path(&nodes); // Destination::BlindedPath - let blinded_path = BlindedPath::new_for_message(&[nodes[1].node_id, nodes[2].node_id, nodes[3].node_id], &*nodes[3].entropy_source, &secp_ctx).unwrap(); - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::BlindedPath(blinded_path), - first_node_addresses: None, - }; - let reply_path = BlindedPath::new_for_message(&[nodes[2].node_id, nodes[1].node_id, nodes[0].node_id], &*nodes[0].entropy_source, &secp_ctx).unwrap(); + let intermediate_nodes = [ + ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, + ForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, + ]; + let blinded_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[3].node_id, &*nodes[3].entropy_source, &secp_ctx).unwrap(); + let destination = Destination::BlindedPath(blinded_path); + let intermediate_nodes = [ + ForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, + ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, + ]; + let reply_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[0].node_id, &*nodes[0].entropy_source, &secp_ctx).unwrap(); - nodes[0].messenger.send_onion_message_using_path(path, test_msg, Some(reply_path)).unwrap(); + nodes[0].messenger.send_onion_message(test_msg, destination, Some(reply_path)).unwrap(); nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request); pass_along_path(&nodes); @@ -431,6 +492,9 @@ fn invalid_custom_message_type() { // Onion message contents must have a TLV >= 64. 63 } + fn msg_type(&self) -> &'static str { + "Invalid Message" + } } impl Writeable for InvalidCustomMessage { @@ -438,12 +502,8 @@ fn invalid_custom_message_type() { } let test_msg = InvalidCustomMessage {}; - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::Node(nodes[1].node_id), - first_node_addresses: None, - }; - let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap_err(); + let destination = Destination::Node(nodes[1].node_id); + let err = nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap_err(); assert_eq!(err, SendError::InvalidMessage); } @@ -451,15 +511,11 @@ fn invalid_custom_message_type() { fn peer_buffer_full() { let nodes = create_nodes(2); let test_msg = TestCustomMessage::Request; - let path = OnionMessagePath { - intermediate_nodes: vec![], - destination: Destination::Node(nodes[1].node_id), - first_node_addresses: None, - }; + let destination = Destination::Node(nodes[1].node_id); for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger - nodes[0].messenger.send_onion_message_using_path(path.clone(), test_msg.clone(), None).unwrap(); + nodes[0].messenger.send_onion_message(test_msg.clone(), destination.clone(), None).unwrap(); } - let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap_err(); + let err = nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap_err(); assert_eq!(err, SendError::BufferFull); } @@ -491,8 +547,11 @@ fn requests_peer_connection_for_buffered_messages() { let nodes = create_nodes(3); let message = TestCustomMessage::Request; let secp_ctx = Secp256k1::new(); + add_channel_to_graph(&nodes[0], &nodes[1], &secp_ctx, 42); + + let intermediate_nodes = [ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; let blinded_path = BlindedPath::new_for_message( - &[nodes[1].node_id, nodes[2].node_id], &*nodes[0].entropy_source, &secp_ctx + &intermediate_nodes, nodes[2].node_id, &*nodes[0].entropy_source, &secp_ctx ).unwrap(); let destination = Destination::BlindedPath(blinded_path); @@ -526,8 +585,11 @@ fn drops_buffered_messages_waiting_for_peer_connection() { let nodes = create_nodes(3); let message = TestCustomMessage::Request; let secp_ctx = Secp256k1::new(); + add_channel_to_graph(&nodes[0], &nodes[1], &secp_ctx, 42); + + let intermediate_nodes = [ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; let blinded_path = BlindedPath::new_for_message( - &[nodes[1].node_id, nodes[2].node_id], &*nodes[0].entropy_source, &secp_ctx + &intermediate_nodes, nodes[2].node_id, &*nodes[0].entropy_source, &secp_ctx ).unwrap(); let destination = Destination::BlindedPath(blinded_path); @@ -552,18 +614,84 @@ fn drops_buffered_messages_waiting_for_peer_connection() { assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none()); } +#[test] +fn intercept_offline_peer_oms() { + // Ensure that if OnionMessenger is initialized with + // new_with_offline_peer_interception, we will intercept OMs for offline + // peers, generate the right events, and forward OMs when they are re-injected + // by the user. + let node_cfgs = vec![MessengerCfg::new(), MessengerCfg::new().with_offline_peer_interception(), MessengerCfg::new()]; + let mut nodes = create_nodes_using_cfgs(node_cfgs); + + let peer_conn_evs = release_events(&nodes[1]); + assert_eq!(peer_conn_evs.len(), 2); + for (i, ev) in peer_conn_evs.iter().enumerate() { + match ev { + Event::OnionMessagePeerConnected { peer_node_id } => { + let node_idx = if i == 0 { 0 } else { 2 }; + assert_eq!(peer_node_id, &nodes[node_idx].node_id); + }, + _ => panic!() + } + } + + let message = TestCustomMessage::Response; + let secp_ctx = Secp256k1::new(); + let intermediate_nodes = [ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }]; + let blinded_path = BlindedPath::new_for_message( + &intermediate_nodes, nodes[2].node_id, &*nodes[2].entropy_source, &secp_ctx + ).unwrap(); + let destination = Destination::BlindedPath(blinded_path); + + // Disconnect the peers to ensure we intercept the OM. + disconnect_peers(&nodes[1], &nodes[2]); + nodes[0].messenger.send_onion_message(message, destination, None).unwrap(); + let mut final_node_vec = nodes.split_off(2); + pass_along_path(&nodes); + + let mut events = release_events(&nodes[1]); + assert_eq!(events.len(), 1); + let onion_message = match events.remove(0) { + Event::OnionMessageIntercepted { peer_node_id, message } => { + assert_eq!(peer_node_id, final_node_vec[0].node_id); + message + }, + _ => panic!() + }; + + // Ensure that we'll refuse to forward the re-injected OM until after the + // outbound peer comes back online. + let err = nodes[1].messenger.forward_onion_message(onion_message.clone(), &final_node_vec[0].node_id).unwrap_err(); + assert_eq!(err, SendError::InvalidFirstHop(final_node_vec[0].node_id)); + + connect_peers(&nodes[1], &final_node_vec[0]); + let peer_conn_ev = release_events(&nodes[1]); + assert_eq!(peer_conn_ev.len(), 1); + match peer_conn_ev[0] { + Event::OnionMessagePeerConnected { peer_node_id } => { + assert_eq!(peer_node_id, final_node_vec[0].node_id); + }, + _ => panic!() + } + + nodes[1].messenger.forward_onion_message(onion_message, &final_node_vec[0].node_id).unwrap(); + final_node_vec[0].custom_message_handler.expect_message(TestCustomMessage::Response); + pass_along_path(&vec![nodes.remove(1), final_node_vec.remove(0)]); +} + #[test] fn spec_test_vector() { - let secret_keys = [ + let node_cfgs = [ "4141414141414141414141414141414141414141414141414141414141414141", // Alice "4242424242424242424242424242424242424242424242424242424242424242", // Bob "4343434343434343434343434343434343434343434343434343434343434343", // Carol "4444444444444444444444444444444444444444444444444444444444444444", // Dave ] .iter() - .map(|secret| SecretKey::from_slice(&>::from_hex(secret).unwrap()).unwrap()) + .map(|secret_hex| SecretKey::from_slice(&>::from_hex(secret_hex).unwrap()).unwrap()) + .map(|secret| MessengerCfg::new().with_node_secret(secret)) .collect(); - let nodes = create_nodes_using_secrets(secret_keys); + let nodes = create_nodes_using_cfgs(node_cfgs); // Hardcode the sender->Alice onion message, because it includes an unknown TLV of type 1, which // LDK doesn't support constructing. @@ -571,8 +699,8 @@ fn spec_test_vector() { let sender_to_alice_packet_bytes_len = sender_to_alice_packet_bytes.len() as u64; let mut reader = io::Cursor::new(sender_to_alice_packet_bytes); let mut packet_reader = FixedLengthReader::new(&mut reader, sender_to_alice_packet_bytes_len); - let sender_to_alice_packet: super::Packet = - ::read(&mut packet_reader).unwrap(); + let sender_to_alice_packet: Packet = + ::read(&mut packet_reader).unwrap(); let secp_ctx = Secp256k1::new(); let sender_to_alice_om = msgs::OnionMessage { blinding_point: PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&>::from_hex("6363636363636363636363636363636363636363636363636363636363636363").unwrap()).unwrap()),