Add Option<Vec<SocketAddress>> to OnionMessagePath

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.
This commit is contained in:
Jeffrey Czyz 2023-11-14 15:30:17 -06:00
parent 17af8d5f09
commit 1114c3c5aa
No known key found for this signature in database
GPG key ID: 3A4E08275D5E96D2
3 changed files with 36 additions and 3 deletions

View file

@ -79,6 +79,7 @@ impl MessageRouter for TestMessageRouter {
Ok(OnionMessagePath {
intermediate_nodes: vec![],
destination,
addresses: None,
})
}
}

View 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);

View 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);