Generalize CustomOnionMessageContents trait
authorJeffrey Czyz <jkczyz@gmail.com>
Tue, 19 Sep 2023 17:35:13 +0000 (12:35 -0500)
committerJeffrey Czyz <jkczyz@gmail.com>
Wed, 18 Oct 2023 23:15:05 +0000 (18:15 -0500)
Rename CustomOnionMessageContents to OnionMessageContents and use it as
a trait bound on messages passed to OnionMessenger methods. This allows
using the trait in an upcoming commit as a bound on the contents of
PendingOnionMessage.

Also, make ParsedOnionMessageContent implement OnionMessageContents so
that Payload can be bounded by OnionMessageContents directly, but used
when either reading a ParsedOnionMessageContent or writing a specific
type of OnionMessageContents (e.g., OffersMessage).

fuzz/src/onion_message.rs
lightning/src/ln/peer_handler.rs
lightning/src/onion_message/functional_tests.rs
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/mod.rs
lightning/src/onion_message/offers.rs
lightning/src/onion_message/packet.rs

index 67938aa7c39f3b3c16b920bc6098123a5d4dabbe..57d4f697b3a4abffcefe8e341e25b0cd9437d3e4 100644 (file)
@@ -14,7 +14,7 @@ use lightning::offers::invoice_request::UnsignedInvoiceRequest;
 use lightning::util::test_channel_signer::TestChannelSigner;
 use lightning::util::logger::Logger;
 use lightning::util::ser::{Readable, Writeable, Writer};
-use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessagePath, OnionMessenger};
+use lightning::onion_message::{CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger};
 
 use crate::utils::test_logger;
 
@@ -84,7 +84,7 @@ struct TestCustomMessage {}
 const CUSTOM_MESSAGE_TYPE: u64 = 4242;
 const CUSTOM_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
 
-impl CustomOnionMessageContents for TestCustomMessage {
+impl OnionMessageContents for TestCustomMessage {
        fn tlv_type(&self) -> u64 {
                CUSTOM_MESSAGE_TYPE
        }
@@ -216,9 +216,9 @@ mod tests {
                        assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
                                                "Received an onion message with path_id None and a reply_path".to_string())), Some(&1));
                        assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
-                                               "Sending onion message when responding to onion message with path_id None".to_string())), Some(&1));
+                                               "Sending onion message when responding to Custom onion message with path_id None".to_string())), Some(&1));
                        assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
-                                               "Failed sending onion message when responding to onion message with path_id None: TooFewBlindedHops".to_string())), Some(&1));
+                                               "Failed sending onion message when responding to Custom onion message with path_id None: TooFewBlindedHops".to_string())), Some(&1));
                }
 
                let two_unblinded_hops_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210202020202020202020202020202020202020202020202020202020202020202026d000000000000000000000000000000eb0000000000000000000000000000000000000000000000000000000000000036041096000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000";
index a5a6939e16727424ff06d34689452857585bcc34..84fb9748b4631cd4f49d17c3e2f0f9db680765db 100644 (file)
@@ -29,7 +29,7 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
 use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
 use crate::ln::wire;
 use crate::ln::wire::{Encode, Type};
-use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
+use crate::onion_message::{CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, OnionMessageContents, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
 use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, NodeAlias};
 use crate::util::atomic_counter::AtomicCounter;
 use crate::util::logger::Logger;
@@ -131,7 +131,7 @@ impl CustomOnionMessageHandler for IgnoringMessageHandler {
        }
 }
 
-impl CustomOnionMessageContents for Infallible {
+impl OnionMessageContents for Infallible {
        fn tlv_type(&self) -> u64 { unreachable!(); }
 }
 
index 319417e80655efec98008f86fecedfaaee42c396..0348e4afbf5f4d9ea8eb492e7e67388927f01cc5 100644 (file)
@@ -15,7 +15,7 @@ use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
 use crate::sign::{NodeSigner, Recipient};
 use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
 use crate::util::test_utils;
-use super::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, ParsedOnionMessageContents, OnionMessagePath, OnionMessenger, SendError};
+use super::{CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger, SendError};
 
 use bitcoin::network::constants::Network;
 use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
@@ -77,7 +77,7 @@ const CUSTOM_RESPONSE_MESSAGE_TYPE: u64 = 4343;
 const CUSTOM_REQUEST_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
 const CUSTOM_RESPONSE_MESSAGE_CONTENTS: [u8; 32] = [43; 32];
 
-impl CustomOnionMessageContents for TestCustomMessage {
+impl OnionMessageContents for TestCustomMessage {
        fn tlv_type(&self) -> u64 {
                match self {
                        TestCustomMessage::Request => CUSTOM_REQUEST_MESSAGE_TYPE,
@@ -196,7 +196,7 @@ fn pass_along_path(path: &Vec<MessengerNode>) {
 #[test]
 fn one_hop() {
        let nodes = create_nodes(2);
-       let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
+       let test_msg = TestCustomMessage::Response;
 
        let path = OnionMessagePath {
                intermediate_nodes: vec![],
@@ -210,7 +210,7 @@ fn one_hop() {
 #[test]
 fn two_unblinded_hops() {
        let nodes = create_nodes(3);
-       let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
+       let test_msg = TestCustomMessage::Response;
 
        let path = OnionMessagePath {
                intermediate_nodes: vec![nodes[1].get_node_pk()],
@@ -224,7 +224,7 @@ fn two_unblinded_hops() {
 #[test]
 fn two_unblinded_two_blinded() {
        let nodes = create_nodes(5);
-       let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
+       let test_msg = TestCustomMessage::Response;
 
        let secp_ctx = Secp256k1::new();
        let blinded_path = BlindedPath::new_for_message(&[nodes[3].get_node_pk(), nodes[4].get_node_pk()], &*nodes[4].keys_manager, &secp_ctx).unwrap();
@@ -241,7 +241,7 @@ fn two_unblinded_two_blinded() {
 #[test]
 fn three_blinded_hops() {
        let nodes = create_nodes(4);
-       let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
+       let test_msg = TestCustomMessage::Response;
 
        let secp_ctx = Secp256k1::new();
        let blinded_path = BlindedPath::new_for_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap();
@@ -259,7 +259,7 @@ fn three_blinded_hops() {
 fn too_big_packet_error() {
        // Make sure we error as expected if a packet is too big to send.
        let nodes = create_nodes(2);
-       let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
+       let test_msg = TestCustomMessage::Response;
 
        let hop_node_id = nodes[1].get_node_pk();
        let hops = vec![hop_node_id; 400];
@@ -285,7 +285,7 @@ fn we_are_intro_node() {
                destination: Destination::BlindedPath(blinded_path),
        };
 
-       nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg.clone()), None).unwrap();
+       nodes[0].messenger.send_onion_message(path, test_msg.clone(), None).unwrap();
        nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response);
        pass_along_path(&nodes);
 
@@ -295,7 +295,7 @@ fn we_are_intro_node() {
                intermediate_nodes: vec![],
                destination: Destination::BlindedPath(blinded_path),
        };
-       nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap();
+       nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
        nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response);
        nodes.remove(2);
        pass_along_path(&nodes);
@@ -315,7 +315,7 @@ fn invalid_blinded_path_error() {
                intermediate_nodes: vec![],
                destination: Destination::BlindedPath(blinded_path),
        };
-       let err = nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg.clone()), None).unwrap_err();
+       let err = nodes[0].messenger.send_onion_message(path, test_msg.clone(), None).unwrap_err();
        assert_eq!(err, SendError::TooFewBlindedHops);
 
        // 1 hop
@@ -326,7 +326,7 @@ fn invalid_blinded_path_error() {
                intermediate_nodes: vec![],
                destination: Destination::BlindedPath(blinded_path),
        };
-       let err = nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap_err();
+       let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
        assert_eq!(err, SendError::TooFewBlindedHops);
 }
 
@@ -342,7 +342,7 @@ fn reply_path() {
                destination: Destination::Node(nodes[3].get_node_pk()),
        };
        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(path, ParsedOnionMessageContents::Custom(test_msg.clone()), Some(reply_path)).unwrap();
+       nodes[0].messenger.send_onion_message(path, test_msg.clone(), Some(reply_path)).unwrap();
        nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
        pass_along_path(&nodes);
        // Make sure the last node successfully decoded the reply path.
@@ -358,7 +358,7 @@ fn reply_path() {
        };
        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(path, ParsedOnionMessageContents::Custom(test_msg), Some(reply_path)).unwrap();
+       nodes[0].messenger.send_onion_message(path, test_msg, Some(reply_path)).unwrap();
        nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
        pass_along_path(&nodes);
 
@@ -373,7 +373,7 @@ fn invalid_custom_message_type() {
        let nodes = create_nodes(2);
 
        struct InvalidCustomMessage{}
-       impl CustomOnionMessageContents for InvalidCustomMessage {
+       impl OnionMessageContents for InvalidCustomMessage {
                fn tlv_type(&self) -> u64 {
                        // Onion message contents must have a TLV >= 64.
                        63
@@ -384,7 +384,7 @@ fn invalid_custom_message_type() {
                fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() }
        }
 
-       let test_msg = ParsedOnionMessageContents::Custom(InvalidCustomMessage {});
+       let test_msg = InvalidCustomMessage {};
        let path = OnionMessagePath {
                intermediate_nodes: vec![],
                destination: Destination::Node(nodes[1].get_node_pk()),
@@ -402,9 +402,9 @@ fn peer_buffer_full() {
                destination: Destination::Node(nodes[1].get_node_pk()),
        };
        for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger
-               nodes[0].messenger.send_onion_message(path.clone(), ParsedOnionMessageContents::Custom(test_msg.clone()), None).unwrap();
+               nodes[0].messenger.send_onion_message(path.clone(), test_msg.clone(), None).unwrap();
        }
-       let err = nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap_err();
+       let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
        assert_eq!(err, SendError::BufferFull);
 }
 
@@ -425,7 +425,7 @@ fn many_hops() {
                intermediate_nodes,
                destination: Destination::Node(nodes[num_nodes-1].get_node_pk()),
        };
-       nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap();
+       nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
        nodes[num_nodes-1].custom_message_handler.expect_message(TestCustomMessage::Response);
        pass_along_path(&nodes);
 }
index 074a1790f028975ad3ce383614bc358e49025106..d6aa5c82ca5bc526118b539c53b95eedbeb37688 100644 (file)
@@ -23,7 +23,8 @@ use crate::ln::features::{InitFeatures, NodeFeatures};
 use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler};
 use crate::ln::onion_utils;
 use crate::ln::peer_handler::IgnoringMessageHandler;
-pub use super::packet::{CustomOnionMessageContents, ParsedOnionMessageContents};
+pub use super::packet::OnionMessageContents;
+use super::packet::ParsedOnionMessageContents;
 use super::offers::OffersMessageHandler;
 use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN};
 use crate::util::logger::Logger;
@@ -60,7 +61,7 @@ use crate::prelude::*;
 /// # use lightning::blinded_path::BlindedPath;
 /// # use lightning::sign::KeysManager;
 /// # use lightning::ln::peer_handler::IgnoringMessageHandler;
-/// # use lightning::onion_message::{CustomOnionMessageContents, Destination, MessageRouter, ParsedOnionMessageContents, OnionMessagePath, OnionMessenger};
+/// # use lightning::onion_message::{OnionMessageContents, Destination, MessageRouter, OnionMessagePath, OnionMessenger};
 /// # use lightning::util::logger::{Logger, Record};
 /// # use lightning::util::ser::{Writeable, Writer};
 /// # use lightning::io;
@@ -101,7 +102,7 @@ use crate::prelude::*;
 ///            // Write your custom onion message to `w`
 ///    }
 /// }
-/// impl CustomOnionMessageContents for YourCustomMessage {
+/// impl OnionMessageContents for YourCustomMessage {
 ///    fn tlv_type(&self) -> u64 {
 ///            # let your_custom_message_type = 42;
 ///            your_custom_message_type
@@ -113,8 +114,7 @@ use crate::prelude::*;
 ///    destination: Destination::Node(destination_node_id),
 /// };
 /// let reply_path = None;
-/// # let your_custom_message = YourCustomMessage {};
-/// let message = ParsedOnionMessageContents::Custom(your_custom_message);
+/// # let message = YourCustomMessage {};
 /// onion_messenger.send_onion_message(path, message, reply_path);
 ///
 /// // Create a blinded path to yourself, for someone to send an onion message to.
@@ -128,8 +128,7 @@ use crate::prelude::*;
 ///    destination: Destination::BlindedPath(blinded_path),
 /// };
 /// let reply_path = None;
-/// # let your_custom_message = YourCustomMessage {};
-/// let message = ParsedOnionMessageContents::Custom(your_custom_message);
+/// # let message = YourCustomMessage {};
 /// onion_messenger.send_onion_message(path, message, reply_path);
 /// ```
 ///
@@ -244,7 +243,7 @@ pub enum SendError {
 pub trait CustomOnionMessageHandler {
        /// The message known to the handler. To support multiple message types, you may want to make this
        /// an enum with a variant for each supported message.
-       type CustomMessage: CustomOnionMessageContents;
+       type CustomMessage: OnionMessageContents;
 
        /// Called with the custom message that was received, returning a response to send, if any.
        fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage>;
@@ -256,21 +255,20 @@ pub trait CustomOnionMessageHandler {
 
 /// A processed incoming onion message, containing either a Forward (another onion message)
 /// or a Receive payload with decrypted contents.
-pub enum PeeledOnion<CM: CustomOnionMessageContents> {
+pub enum PeeledOnion<T: OnionMessageContents> {
        /// Forwarded onion, with the next node id and a new onion
        Forward(PublicKey, OnionMessage),
        /// Received onion message, with decrypted contents, path_id, and reply path
-       Receive(ParsedOnionMessageContents<CM>, Option<[u8; 32]>, Option<BlindedPath>)
+       Receive(ParsedOnionMessageContents<T>, Option<[u8; 32]>, Option<BlindedPath>)
 }
 
 /// Creates an [`OnionMessage`] with the given `contents` for sending to the destination of
 /// `path`.
 ///
 /// Returns both the node id of the peer to send the message to and the message itself.
-pub fn create_onion_message<ES: Deref, NS: Deref, T: CustomOnionMessageContents>(
+pub fn create_onion_message<ES: Deref, NS: Deref, T: OnionMessageContents>(
        entropy_source: &ES, node_signer: &NS, secp_ctx: &Secp256k1<secp256k1::All>,
-       path: OnionMessagePath, contents: ParsedOnionMessageContents<T>,
-       reply_path: Option<BlindedPath>,
+       path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>,
 ) -> Result<(PublicKey, OnionMessage), SendError>
 where
        ES::Target: EntropySource,
@@ -361,7 +359,7 @@ where
                onion_decode_ss, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
                (control_tlvs_ss, custom_handler.deref(), logger.deref())
        ) {
-               Ok((Payload::Receive::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
+               Ok((Payload::Receive::<ParsedOnionMessageContents<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage>> {
                        message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
                }, None)) => {
                        Ok(PeeledOnion::Receive(message, path_id, reply_path))
@@ -452,9 +450,8 @@ where
        /// `path`.
        ///
        /// See [`OnionMessenger`] for example usage.
-       pub fn send_onion_message<T: CustomOnionMessageContents>(
-               &self, path: OnionMessagePath, contents: ParsedOnionMessageContents<T>,
-               reply_path: Option<BlindedPath>
+       pub fn send_onion_message<T: OnionMessageContents>(
+               &self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>
        ) -> Result<(), SendError> {
                let (first_node_id, onion_msg) = create_onion_message(
                        &self.entropy_source, &self.node_signer, &self.secp_ctx, path, contents, reply_path
@@ -471,9 +468,25 @@ where
                }
        }
 
-       fn find_path_and_enqueue_onion_message<T: CustomOnionMessageContents>(
-               &self, contents: ParsedOnionMessageContents<T>, destination: Destination,
-               log_suffix: fmt::Arguments
+       fn handle_onion_message_response<T: OnionMessageContents>(
+               &self, response: Option<T>, reply_path: Option<BlindedPath>, log_suffix: fmt::Arguments
+       ) {
+               if let Some(response) = response {
+                       match reply_path {
+                               Some(reply_path) => {
+                                       self.find_path_and_enqueue_onion_message(
+                                               response, Destination::BlindedPath(reply_path), log_suffix
+                                       );
+                               },
+                               None => {
+                                       log_trace!(self.logger, "Missing reply path {}", log_suffix);
+                               },
+                       }
+               }
+       }
+
+       fn find_path_and_enqueue_onion_message<T: OnionMessageContents>(
+               &self, contents: T, destination: Destination, log_suffix: fmt::Arguments
        ) {
                let sender = match self.node_signer.get_node_id(Recipient::Node) {
                        Ok(node_id) => node_id,
@@ -557,33 +570,26 @@ where
                                log_trace!(self.logger,
                                        "Received an onion message with path_id {:02x?} and {} reply_path",
                                                path_id, if reply_path.is_some() { "a" } else { "no" });
-                               let response = match message {
+
+                               match message {
                                        ParsedOnionMessageContents::Offers(msg) => {
-                                               self.offers_handler.handle_message(msg)
-                                                       .map(|msg| ParsedOnionMessageContents::Offers(msg))
+                                               let response = self.offers_handler.handle_message(msg);
+                                               self.handle_onion_message_response(
+                                                       response, reply_path, format_args!(
+                                                               "when responding to Offers onion message with path_id {:02x?}",
+                                                               path_id
+                                                       )
+                                               );
                                        },
                                        ParsedOnionMessageContents::Custom(msg) => {
-                                               self.custom_handler.handle_custom_message(msg)
-                                                       .map(|msg| ParsedOnionMessageContents::Custom(msg))
-                                       },
-                               };
-                               if let Some(response) = response {
-                                       match reply_path {
-                                               Some(reply_path) => {
-                                                       self.find_path_and_enqueue_onion_message(
-                                                               response, Destination::BlindedPath(reply_path), format_args!(
-                                                                       "when responding to onion message with path_id {:02x?}", path_id
-                                                               )
-                                                       );
-                                               },
-                                               None => {
-                                                       log_trace!(
-                                                               self.logger,
-                                                               "Missing reply path when responding to onion message with path_id {:02x?}",
+                                               let response = self.custom_handler.handle_custom_message(msg);
+                                               self.handle_onion_message_response(
+                                                       response, reply_path, format_args!(
+                                                               "when responding to Custom onion message with path_id {:02x?}",
                                                                path_id
-                                                       );
-                                               },
-                                       }
+                                                       )
+                                               );
+                                       },
                                }
                        },
                        Ok(PeeledOnion::Forward(next_node_id, onion_message)) => {
@@ -683,9 +689,9 @@ pub type SimpleRefOnionMessenger<'a, 'b, 'c, L> = OnionMessenger<
 
 /// Construct onion packet payloads and keys for sending an onion message along the given
 /// `unblinded_path` to the given `destination`.
-fn packet_payloads_and_keys<T: CustomOnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
-       secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination,
-       message: ParsedOnionMessageContents<T>, mut reply_path: Option<BlindedPath>, session_priv: &SecretKey
+fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
+       secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination, message: T,
+       mut reply_path: Option<BlindedPath>, session_priv: &SecretKey
 ) -> Result<(Vec<(Payload<T>, [u8; 32])>, Vec<onion_utils::OnionKeys>), secp256k1::Error> {
        let num_hops = unblinded_path.len() + destination.num_hops();
        let mut payloads = Vec::with_capacity(num_hops);
@@ -761,7 +767,7 @@ fn packet_payloads_and_keys<T: CustomOnionMessageContents, S: secp256k1::Signing
 }
 
 /// Errors if the serialized payload size exceeds onion_message::BIG_PACKET_HOP_DATA_LEN
-fn construct_onion_message_packet<T: CustomOnionMessageContents>(payloads: Vec<(Payload<T>, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Result<Packet, ()> {
+fn construct_onion_message_packet<T: OnionMessageContents>(payloads: Vec<(Payload<T>, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Result<Packet, ()> {
        // Spec rationale:
        // "`len` allows larger messages to be sent than the standard 1300 bytes allowed for an HTLC
        // onion, but this should be used sparingly as it is reduces anonymity set, hence the
index 59c4672126c0eb051da5d9e1a104fd8dc2a38677..dd92792316dd3272be742003b97e82b833687014 100644 (file)
@@ -27,7 +27,7 @@ mod packet;
 mod functional_tests;
 
 // Re-export structs so they can be imported with just the `onion_message::` module prefix.
-pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, DefaultMessageRouter, Destination, MessageRouter, ParsedOnionMessageContents, OnionMessagePath, OnionMessenger, PeeledOnion, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
+pub use self::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, MessageRouter, OnionMessageContents, OnionMessagePath, OnionMessenger, PeeledOnion, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
 pub use self::offers::{OffersMessage, OffersMessageHandler};
-pub use self::packet::Packet;
+pub use self::packet::{Packet, ParsedOnionMessageContents};
 pub(crate) use self::packet::ControlTlvs;
index de373bda1bce81b104f1cd616be1ea4fb3e0b756..f5945cd55054dc6c368a668fcf4aa777f15d6a21 100644 (file)
@@ -16,6 +16,7 @@ use crate::offers::invoice_error::InvoiceError;
 use crate::offers::invoice_request::InvoiceRequest;
 use crate::offers::invoice::Bolt12Invoice;
 use crate::offers::parse::Bolt12ParseError;
+use crate::onion_message::OnionMessageContents;
 use crate::util::logger::Logger;
 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
 
@@ -63,15 +64,6 @@ impl OffersMessage {
                }
        }
 
-       /// The TLV record type for the message as used in an `onionmsg_tlv` TLV stream.
-       pub fn tlv_type(&self) -> u64 {
-               match self {
-                       OffersMessage::InvoiceRequest(_) => INVOICE_REQUEST_TLV_TYPE,
-                       OffersMessage::Invoice(_) => INVOICE_TLV_TYPE,
-                       OffersMessage::InvoiceError(_) => INVOICE_ERROR_TLV_TYPE,
-               }
-       }
-
        fn parse(tlv_type: u64, bytes: Vec<u8>) -> Result<Self, Bolt12ParseError> {
                match tlv_type {
                        INVOICE_REQUEST_TLV_TYPE => Ok(Self::InvoiceRequest(InvoiceRequest::try_from(bytes)?)),
@@ -81,6 +73,16 @@ impl OffersMessage {
        }
 }
 
+impl OnionMessageContents for OffersMessage {
+       fn tlv_type(&self) -> u64 {
+               match self {
+                       OffersMessage::InvoiceRequest(_) => INVOICE_REQUEST_TLV_TYPE,
+                       OffersMessage::Invoice(_) => INVOICE_TLV_TYPE,
+                       OffersMessage::InvoiceError(_) => INVOICE_ERROR_TLV_TYPE,
+               }
+       }
+}
+
 impl Writeable for OffersMessage {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                match self {
index c5411831ab72b09bc6dd710e25659f8c195407c9..19ca6eb963b2350973e987d58eef6e322605cd4b 100644 (file)
@@ -103,31 +103,33 @@ impl LengthReadable for Packet {
 /// Onion message payloads contain "control" TLVs and "data" TLVs. Control TLVs are used to route
 /// the onion message from hop to hop and for path verification, whereas data TLVs contain the onion
 /// message content itself, such as an invoice request.
-pub(super) enum Payload<T: CustomOnionMessageContents> {
+pub(super) enum Payload<T: OnionMessageContents> {
        /// This payload is for an intermediate hop.
        Forward(ForwardControlTlvs),
        /// This payload is for the final hop.
        Receive {
                control_tlvs: ReceiveControlTlvs,
                reply_path: Option<BlindedPath>,
-               message: ParsedOnionMessageContents<T>,
+               message: T,
        }
 }
 
-/// The contents of an onion message as read from the wire.
+/// The contents of an [`OnionMessage`] as read from the wire.
+///
+/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
 #[derive(Debug)]
-pub enum ParsedOnionMessageContents<T: CustomOnionMessageContents> {
+pub enum ParsedOnionMessageContents<T: OnionMessageContents> {
        /// A message related to BOLT 12 Offers.
        Offers(OffersMessage),
        /// A custom onion message specified by the user.
        Custom(T),
 }
 
-impl<T: CustomOnionMessageContents> ParsedOnionMessageContents<T> {
+impl<T: OnionMessageContents> OnionMessageContents for ParsedOnionMessageContents<T> {
        /// Returns the type that was used to decode the message payload.
        ///
        /// This is not exported to bindings users as methods on non-cloneable enums are not currently exportable
-       pub fn tlv_type(&self) -> u64 {
+       fn tlv_type(&self) -> u64 {
                match self {
                        &ParsedOnionMessageContents::Offers(ref msg) => msg.tlv_type(),
                        &ParsedOnionMessageContents::Custom(ref msg) => msg.tlv_type(),
@@ -136,7 +138,7 @@ impl<T: CustomOnionMessageContents> ParsedOnionMessageContents<T> {
 }
 
 /// This is not exported to bindings users as methods on non-cloneable enums are not currently exportable
-impl<T: CustomOnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
+impl<T: OnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                match self {
                        ParsedOnionMessageContents::Offers(msg) => Ok(msg.write(w)?),
@@ -145,8 +147,8 @@ impl<T: CustomOnionMessageContents> Writeable for ParsedOnionMessageContents<T>
        }
 }
 
-/// The contents of a custom onion message.
-pub trait CustomOnionMessageContents: Writeable {
+/// The contents of an onion message.
+pub trait OnionMessageContents: Writeable {
        /// Returns the TLV type identifying the message contents. MUST be >= 64.
        fn tlv_type(&self) -> u64;
 }
@@ -172,7 +174,7 @@ pub(super) enum ReceiveControlTlvs {
 }
 
 // Uses the provided secret to simultaneously encode and encrypt the unblinded control TLVs.
-impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
+impl<T: OnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                match &self.0 {
                        Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => {
@@ -211,8 +213,8 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
 }
 
 // Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV.
-impl<H: CustomOnionMessageHandler + ?Sized, L: Logger + ?Sized>
-ReadableArgs<(SharedSecret, &H, &L)> for Payload<<H as CustomOnionMessageHandler>::CustomMessage> {
+impl<H: CustomOnionMessageHandler + ?Sized, L: Logger + ?Sized> ReadableArgs<(SharedSecret, &H, &L)>
+for Payload<ParsedOnionMessageContents<<H as CustomOnionMessageHandler>::CustomMessage>> {
        fn read<R: Read>(r: &mut R, args: (SharedSecret, &H, &L)) -> Result<Self, DecodeError> {
                let (encrypted_tlvs_ss, handler, logger) = args;