From 131ac4f5a86efa3dcfd860c64b2d863478c44900 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 22 Aug 2024 01:47:37 +0000 Subject: [PATCH] Change `send_onion_message` to take a `MessageSendInstructions` This lets callers include a `reply_path` without doing the path-finding at the callsite, utilizing the built-in path-finding logic in `OnionMessenger` --- .../src/onion_message/functional_tests.rs | 48 ++++++++++++------- lightning/src/onion_message/messenger.rs | 35 +++++--------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 8dcbb8099..765c4ba0f 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -345,7 +345,8 @@ fn one_unblinded_hop() { let test_msg = TestCustomMessage::Pong; let destination = Destination::Node(nodes[1].node_id); - nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; + nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Pong); pass_along_path(&nodes); } @@ -375,7 +376,8 @@ fn one_blinded_hop() { let context = MessageContext::Custom(Vec::new()); let blinded_path = BlindedMessagePath::new(&[], nodes[1].node_id, context, &*nodes[1].entropy_source, &secp_ctx).unwrap(); let destination = Destination::BlindedPath(blinded_path); - nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; + nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Pong); pass_along_path(&nodes); } @@ -413,8 +415,9 @@ fn three_blinded_hops() { let context = MessageContext::Custom(Vec::new()); let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[3].node_id, context, &*nodes[3].entropy_source, &secp_ctx).unwrap(); let destination = Destination::BlindedPath(blinded_path); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; - nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); + nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap(); nodes[3].custom_message_handler.expect_message(TestCustomMessage::Pong); pass_along_path(&nodes); } @@ -447,7 +450,7 @@ fn async_response_over_one_blinded_hop() { let (msg, instructions) = response_instruction.unwrap(); assert_eq!( nodes[0].messenger.handle_onion_message_response(msg, instructions), - Ok(Some(SendSuccess::Buffered)), + Ok(SendSuccess::Buffered), ); bob.custom_message_handler.expect_message(TestCustomMessage::Pong); @@ -481,7 +484,7 @@ fn async_response_with_reply_path_succeeds() { let (msg, instructions) = response_instruction.unwrap(); assert_eq!( alice.messenger.handle_onion_message_response(msg, instructions), - Ok(Some(SendSuccess::Buffered)), + Ok(SendSuccess::Buffered), ); // Set Bob's expectation and pass the Onion Message along the path. @@ -557,8 +560,9 @@ fn we_are_intro_node() { let context = MessageContext::Custom(Vec::new()); let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[2].node_id, context, &*nodes[2].entropy_source, &secp_ctx).unwrap(); let destination = Destination::BlindedPath(blinded_path); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; - nodes[0].messenger.send_onion_message(test_msg.clone(), destination, None).unwrap(); + nodes[0].messenger.send_onion_message(test_msg.clone(), instructions).unwrap(); nodes[2].custom_message_handler.expect_message(TestCustomMessage::Pong); pass_along_path(&nodes); @@ -567,7 +571,9 @@ fn we_are_intro_node() { let context = MessageContext::Custom(Vec::new()); let blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[1].node_id, context, &*nodes[1].entropy_source, &secp_ctx).unwrap(); let destination = Destination::BlindedPath(blinded_path); - nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; + + nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap(); nodes[1].custom_message_handler.expect_message(TestCustomMessage::Pong); nodes.remove(2); pass_along_path(&nodes); @@ -585,7 +591,9 @@ fn invalid_blinded_path_error() { let mut blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[2].node_id, context, &*nodes[2].entropy_source, &secp_ctx).unwrap(); blinded_path.clear_blinded_hops(); let destination = Destination::BlindedPath(blinded_path); - let err = nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap_err(); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; + + let err = nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap_err(); assert_eq!(err, SendError::TooFewBlindedHops); } @@ -629,8 +637,9 @@ fn reply_path() { ]; let context = MessageContext::Custom(Vec::new()); let reply_path = BlindedMessagePath::new(&intermediate_nodes, nodes[0].node_id, context, &*nodes[0].entropy_source, &secp_ctx).unwrap(); + let instructions = MessageSendInstructions::WithSpecifiedReplyPath { destination, reply_path }; - nodes[0].messenger.send_onion_message(test_msg, destination, Some(reply_path)).unwrap(); + nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap(); nodes[3].custom_message_handler.expect_message(TestCustomMessage::Ping); pass_along_path(&nodes); @@ -662,7 +671,9 @@ fn invalid_custom_message_type() { let test_msg = InvalidCustomMessage {}; let destination = Destination::Node(nodes[1].node_id); - let err = nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap_err(); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; + + let err = nodes[0].messenger.send_onion_message(test_msg, instructions).unwrap_err(); assert_eq!(err, SendError::InvalidMessage); } @@ -671,10 +682,12 @@ fn peer_buffer_full() { let nodes = create_nodes(2); let test_msg = TestCustomMessage::Ping; let destination = Destination::Node(nodes[1].node_id); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; + for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger - nodes[0].messenger.send_onion_message(test_msg.clone(), destination.clone(), None).unwrap(); + nodes[0].messenger.send_onion_message(test_msg.clone(), instructions.clone()).unwrap(); } - let err = nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap_err(); + let err = nodes[0].messenger.send_onion_message(test_msg, instructions.clone()).unwrap_err(); assert_eq!(err, SendError::BufferFull); } @@ -714,9 +727,10 @@ fn requests_peer_connection_for_buffered_messages() { &intermediate_nodes, nodes[2].node_id, context, &*nodes[0].entropy_source, &secp_ctx ).unwrap(); let destination = Destination::BlindedPath(blinded_path); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; // Buffer an onion message for a connected peer - nodes[0].messenger.send_onion_message(message.clone(), destination.clone(), None).unwrap(); + nodes[0].messenger.send_onion_message(message.clone(), instructions.clone()).unwrap(); assert!(release_events(&nodes[0]).is_empty()); assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_some()); assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none()); @@ -724,7 +738,7 @@ fn requests_peer_connection_for_buffered_messages() { // Buffer an onion message for a disconnected peer disconnect_peers(&nodes[0], &nodes[1]); assert!(nodes[0].messenger.next_onion_message_for_peer(nodes[1].node_id).is_none()); - nodes[0].messenger.send_onion_message(message, destination, None).unwrap(); + nodes[0].messenger.send_onion_message(message, instructions).unwrap(); // Check that a ConnectionNeeded event for the peer is provided let events = release_events(&nodes[0]); @@ -753,10 +767,11 @@ fn drops_buffered_messages_waiting_for_peer_connection() { &intermediate_nodes, nodes[2].node_id, context, &*nodes[0].entropy_source, &secp_ctx ).unwrap(); let destination = Destination::BlindedPath(blinded_path); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; // Buffer an onion message for a disconnected peer disconnect_peers(&nodes[0], &nodes[1]); - nodes[0].messenger.send_onion_message(message, destination, None).unwrap(); + nodes[0].messenger.send_onion_message(message, instructions).unwrap(); // Release the event so the timer can start ticking let events = release_events(&nodes[0]); @@ -804,10 +819,11 @@ fn intercept_offline_peer_oms() { &intermediate_nodes, nodes[2].node_id, context, &*nodes[2].entropy_source, &secp_ctx ).unwrap(); let destination = Destination::BlindedPath(blinded_path); + let instructions = MessageSendInstructions::WithoutReplyPath { destination }; // 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(); + nodes[0].messenger.send_onion_message(message, instructions).unwrap(); let mut final_node_vec = nodes.split_off(2); pass_along_path(&nodes); diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index fd5108d5a..d9e36f413 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -151,7 +151,7 @@ for OnionMessenger where /// # use lightning::blinded_path::message::{BlindedMessagePath, ForwardNode, MessageContext}; /// # use lightning::sign::{EntropySource, KeysManager}; /// # use lightning::ln::peer_handler::IgnoringMessageHandler; -/// # use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath, OnionMessenger}; +/// # use lightning::onion_message::messenger::{Destination, MessageRouter, MessageSendInstructions, OnionMessagePath, OnionMessenger}; /// # use lightning::onion_message::packet::OnionMessageContents; /// # use lightning::util::logger::{Logger, Record}; /// # use lightning::util::ser::{Writeable, Writer}; @@ -218,9 +218,9 @@ for OnionMessenger where /// } /// // Send a custom onion message to a node id. /// let destination = Destination::Node(destination_node_id); -/// let reply_path = None; +/// let instructions = MessageSendInstructions::WithoutReplyPath { destination }; /// # let message = YourCustomMessage {}; -/// onion_messenger.send_onion_message(message, destination, reply_path); +/// onion_messenger.send_onion_message(message, instructions); /// /// // Create a blinded path to yourself, for someone to send an onion message to. /// # let your_node_id = hop_node_id1; @@ -233,9 +233,9 @@ for OnionMessenger where /// /// // Send a custom onion message to a blinded path. /// let destination = Destination::BlindedPath(blinded_path); -/// let reply_path = None; +/// let instructions = MessageSendInstructions::WithoutReplyPath { destination }; /// # let message = YourCustomMessage {}; -/// onion_messenger.send_onion_message(message, destination, reply_path); +/// onion_messenger.send_onion_message(message, instructions); /// ``` /// /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest @@ -1145,20 +1145,16 @@ where self.offers_handler = offers_handler; } - /// Sends an [`OnionMessage`] with the given `contents` to `destination`. - /// - /// See [`OnionMessenger`] for example usage. + /// Sends an [`OnionMessage`] based on its [`MessageSendInstructions`]. pub fn send_onion_message( - &self, contents: T, destination: Destination, reply_path: Option + &self, contents: T, instructions: MessageSendInstructions, ) -> Result { - self.find_path_and_enqueue_onion_message( - contents, destination, reply_path, format_args!("") - ) + self.send_onion_message_internal(contents, instructions, format_args!("")) } fn send_onion_message_internal( - &self, message: T, instructions: MessageSendInstructions, log_suffix: fmt::Arguments, - ) -> Result, SendError> { + &self, contents: T, instructions: MessageSendInstructions, log_suffix: fmt::Arguments, + ) -> Result { let (destination, reply_path) = match instructions { MessageSendInstructions::WithSpecifiedReplyPath { destination, reply_path } => (destination, Some(reply_path)), @@ -1179,15 +1175,6 @@ where (destination, None), }; - self.find_path_and_enqueue_onion_message( - message, destination, reply_path, log_suffix, - ).map(|result| Some(result)) - } - - fn find_path_and_enqueue_onion_message( - &self, contents: T, destination: Destination, reply_path: Option, - log_suffix: fmt::Arguments - ) -> Result { let mut logger = WithContext::from(&self.logger, None, None, None); let result = self.find_path(destination).and_then(|path| { let first_hop = path.intermediate_nodes.get(0).map(|p| *p); @@ -1337,7 +1324,7 @@ where /// ready for sending, that task can invoke this method to enqueue the response for delivery. pub fn handle_onion_message_response( &self, response: T, instructions: ResponseInstruction, - ) -> Result, SendError> { + ) -> Result { let message_type = response.msg_type(); self.send_onion_message_internal( response, instructions.into_instructions(), -- 2.39.5