]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Add Option<Vec<SocketAddress>> to OnionMessagePath
authorJeffrey Czyz <jkczyz@gmail.com>
Tue, 14 Nov 2023 21:30:17 +0000 (15:30 -0600)
committerJeffrey Czyz <jkczyz@gmail.com>
Wed, 6 Dec 2023 14:47:33 +0000 (08:47 -0600)
MessageRouter::find_path is given a Destination to reach via a set of
peers. If a path cannot be found, it may return a partial path such that
OnionMessenger can signal a direct connection to the first node in the
path is needed. Include a list of socket addresses in the returned
OnionMessagePath to allow OnionMessenger to know how to connect to the
node.

This allows DefaultMessageRouter to use its NetworkGraph to return
socket addresses for gossiped nodes.

fuzz/src/onion_message.rs
lightning/src/onion_message/functional_tests.rs
lightning/src/onion_message/messenger.rs

index afa416a4044872fabb84c3eab0f91aecea28133d..76cd98cea2dfb68abc8c6af4a37f96da1f2177f0 100644 (file)
@@ -79,6 +79,7 @@ impl MessageRouter for TestMessageRouter {
                Ok(OnionMessagePath {
                        intermediate_nodes: vec![],
                        destination,
+                       addresses: None,
                })
        }
 }
index 482e5ea8cc5525bf40b42a49c32d170902c86448..fcf209cda65fe7cd17586bb82840eb67a87854dc 100644 (file)
@@ -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);
index e507f0a21aaa81f662c6cfdb789b8f3e4f93c52b..eb309b622e817766fa53a3707287c1f0ec85b33d 100644 (file)
@@ -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<PublicKey>, destination: Destination
        ) -> Result<OnionMessagePath, ()> {
                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<Vec<SocketAddress>>,
+}
+
+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);