diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index afa416a40..76cd98cea 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -79,6 +79,7 @@ impl MessageRouter for TestMessageRouter { Ok(OnionMessagePath { intermediate_nodes: vec![], destination, + addresses: None, }) } } diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 482e5ea8c..fcf209cda 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -55,6 +55,7 @@ impl MessageRouter for TestMessageRouter { Ok(OnionMessagePath { intermediate_nodes: vec![], destination, + addresses: None, }) } } @@ -205,6 +206,7 @@ fn one_unblinded_hop() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::Node(nodes[1].get_node_pk()), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response); @@ -219,6 +221,7 @@ fn two_unblinded_hops() { let path = OnionMessagePath { intermediate_nodes: vec![nodes[1].get_node_pk()], destination: Destination::Node(nodes[2].get_node_pk()), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response); @@ -235,6 +238,7 @@ fn one_blinded_hop() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::BlindedPath(blinded_path), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response); @@ -251,6 +255,7 @@ fn two_unblinded_two_blinded() { let path = OnionMessagePath { intermediate_nodes: vec![nodes[1].get_node_pk(), nodes[2].get_node_pk()], destination: Destination::BlindedPath(blinded_path), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); @@ -268,6 +273,7 @@ fn three_blinded_hops() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::BlindedPath(blinded_path), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); @@ -286,6 +292,7 @@ fn too_big_packet_error() { let path = OnionMessagePath { intermediate_nodes: hops, destination: Destination::Node(hop_node_id), + addresses: None, }; let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap_err(); assert_eq!(err, SendError::TooBigPacket); @@ -303,6 +310,7 @@ fn we_are_intro_node() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::BlindedPath(blinded_path), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), None).unwrap(); @@ -314,6 +322,7 @@ fn we_are_intro_node() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::BlindedPath(blinded_path), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response); @@ -334,6 +343,7 @@ fn invalid_blinded_path_error() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::BlindedPath(blinded_path), + addresses: None, }; let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), None).unwrap_err(); assert_eq!(err, SendError::TooFewBlindedHops); @@ -349,6 +359,7 @@ fn reply_path() { let path = OnionMessagePath { intermediate_nodes: vec![nodes[1].get_node_pk(), nodes[2].get_node_pk()], destination: Destination::Node(nodes[3].get_node_pk()), + addresses: None, }; let reply_path = BlindedPath::new_for_message(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap(); nodes[0].messenger.send_onion_message_using_path(path, test_msg.clone(), Some(reply_path)).unwrap(); @@ -364,6 +375,7 @@ fn reply_path() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::BlindedPath(blinded_path), + addresses: None, }; let reply_path = BlindedPath::new_for_message(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap(); @@ -398,6 +410,7 @@ fn invalid_custom_message_type() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::Node(nodes[1].get_node_pk()), + addresses: None, }; let err = nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap_err(); assert_eq!(err, SendError::InvalidMessage); @@ -410,6 +423,7 @@ fn peer_buffer_full() { let path = OnionMessagePath { intermediate_nodes: vec![], destination: Destination::Node(nodes[1].get_node_pk()), + addresses: None, }; 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(); @@ -434,6 +448,7 @@ fn many_hops() { let path = OnionMessagePath { intermediate_nodes, destination: Destination::Node(nodes[num_nodes-1].get_node_pk()), + addresses: None, }; nodes[0].messenger.send_onion_message_using_path(path, test_msg, None).unwrap(); nodes[num_nodes-1].custom_message_handler.expect_message(TestCustomMessage::Response); diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index e507f0a21..eb309b622 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -22,7 +22,7 @@ use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient}; #[cfg(not(c_bindings))] use crate::ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}; use crate::ln::features::{InitFeatures, NodeFeatures}; -use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler}; +use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler, SocketAddress}; use crate::ln::onion_utils; use crate::ln::peer_handler::IgnoringMessageHandler; use crate::routing::gossip::NetworkGraph; @@ -84,6 +84,7 @@ use crate::prelude::*; /// # Ok(OnionMessagePath { /// # intermediate_nodes: vec![hop_node_id1, hop_node_id2], /// # destination, +/// # addresses: None, /// # }) /// # } /// # } @@ -282,7 +283,7 @@ where &self, _sender: PublicKey, peers: Vec, destination: Destination ) -> Result { if peers.contains(&destination.first_node()) { - Ok(OnionMessagePath { intermediate_nodes: vec![], destination }) + Ok(OnionMessagePath { intermediate_nodes: vec![], destination, addresses: None }) } else { Err(()) } @@ -297,6 +298,22 @@ pub struct OnionMessagePath { /// The recipient of the message. pub destination: Destination, + + /// Addresses that may be used to connect to [`OnionMessagePath::first_node`]. + /// + /// Only needs to be set if a connection to the node is required. [`OnionMessenger`] may use + /// this to initiate such a connection. + pub addresses: Option>, +} + +impl OnionMessagePath { + /// Returns the first node in the path. + pub fn first_node(&self) -> PublicKey { + self.intermediate_nodes + .first() + .copied() + .unwrap_or_else(|| self.destination.first_node()) + } } /// The destination of an onion message. @@ -427,7 +444,7 @@ where ES::Target: EntropySource, NS::Target: NodeSigner, { - let OnionMessagePath { intermediate_nodes, mut destination } = path; + let OnionMessagePath { intermediate_nodes, mut destination, .. } = path; if let Destination::BlindedPath(BlindedPath { ref blinded_hops, .. }) = destination { if blinded_hops.is_empty() { return Err(SendError::TooFewBlindedHops);