Remove unnecessary Sized bound
[rust-lightning] / lightning / src / onion_message / messenger.rs
index 09a2307591673ce4c01dc1dfd990249c24befc92..655fb6e491d181be10487c023a52938be635e7cf 100644 (file)
@@ -46,7 +46,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, OnionMessageContents, OnionMessagePath, OnionMessenger};
+/// # use lightning::onion_message::{CustomOnionMessageContents, Destination, MessageRouter, OnionMessageContents, OnionMessagePath, OnionMessenger};
 /// # use lightning::util::logger::{Logger, Record};
 /// # use lightning::util::ser::{Writeable, Writer};
 /// # use lightning::io;
@@ -55,6 +55,12 @@ use crate::prelude::*;
 /// # impl Logger for FakeLogger {
 /// #     fn log(&self, record: &Record) { unimplemented!() }
 /// # }
+/// # struct FakeMessageRouter {}
+/// # impl MessageRouter for FakeMessageRouter {
+/// #     fn find_path(&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination) -> Result<OnionMessagePath, ()> {
+/// #         unimplemented!()
+/// #     }
+/// # }
 /// # let seed = [42u8; 32];
 /// # let time = Duration::from_secs(123456);
 /// # let keys_manager = KeysManager::new(&seed, time.as_secs(), time.subsec_nanos());
@@ -64,11 +70,15 @@ use crate::prelude::*;
 /// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
 /// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1);
 /// # let destination_node_id = hop_node_id1;
+/// # let message_router = Arc::new(FakeMessageRouter {});
 /// # let custom_message_handler = IgnoringMessageHandler {};
 /// # let offers_message_handler = IgnoringMessageHandler {};
 /// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
 /// // ChannelManager.
-/// let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &offers_message_handler, &custom_message_handler);
+/// let onion_messenger = OnionMessenger::new(
+///     &keys_manager, &keys_manager, logger, message_router, &offers_message_handler,
+///     &custom_message_handler
+/// );
 ///
 /// # struct YourCustomMessage {}
 /// impl Writeable for YourCustomMessage {
@@ -111,11 +121,12 @@ use crate::prelude::*;
 ///
 /// [offers]: <https://github.com/lightning/bolts/pull/798>
 /// [`OnionMessenger`]: crate::onion_message::OnionMessenger
-pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref>
+pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref>
 where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
        L::Target: Logger,
+       MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        CMH:: Target: CustomOnionMessageHandler,
 {
@@ -124,10 +135,23 @@ where
        logger: L,
        pending_messages: Mutex<HashMap<PublicKey, VecDeque<msgs::OnionMessage>>>,
        secp_ctx: Secp256k1<secp256k1::All>,
+       message_router: MR,
        offers_handler: OMH,
        custom_handler: CMH,
 }
 
+/// A trait defining behavior for routing an [`OnionMessage`].
+///
+/// [`OnionMessage`]: msgs::OnionMessage
+pub trait MessageRouter {
+       /// Returns a route for sending an [`OnionMessage`] to the given [`Destination`].
+       ///
+       /// [`OnionMessage`]: msgs::OnionMessage
+       fn find_path(
+               &self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
+       ) -> Result<OnionMessagePath, ()>;
+}
+
 /// A path for sending an [`msgs::OnionMessage`].
 #[derive(Clone)]
 pub struct OnionMessagePath {
@@ -200,25 +224,30 @@ 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;
-       /// Called with the custom message that was received.
-       fn handle_custom_message(&self, msg: Self::CustomMessage);
+
+       /// 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>;
+
        /// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
        /// message type is unknown.
        fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessenger<ES, NS, L, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref>
+OnionMessenger<ES, NS, L, MR, OMH, CMH>
 where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
        L::Target: Logger,
+       MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        CMH::Target: CustomOnionMessageHandler,
 {
        /// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
        /// their respective handlers.
        pub fn new(
-               entropy_source: ES, node_signer: NS, logger: L, offers_handler: OMH, custom_handler: CMH
+               entropy_source: ES, node_signer: NS, logger: L, message_router: MR, offers_handler: OMH,
+               custom_handler: CMH
        ) -> Self {
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
@@ -228,6 +257,7 @@ where
                        pending_messages: Mutex::new(HashMap::new()),
                        secp_ctx,
                        logger,
+                       message_router,
                        offers_handler,
                        custom_handler,
                }
@@ -292,6 +322,56 @@ where
                }
        }
 
+       fn respond_with_onion_message<T: CustomOnionMessageContents>(
+               &self, response: OnionMessageContents<T>, path_id: Option<[u8; 32]>,
+               reply_path: Option<BlindedPath>
+       ) {
+               let sender = match self.node_signer.get_node_id(Recipient::Node) {
+                       Ok(node_id) => node_id,
+                       Err(_) => {
+                               log_warn!(
+                                       self.logger, "Unable to retrieve node id when responding to onion message with \
+                                       path_id {:02x?}", path_id
+                               );
+                               return;
+                       }
+               };
+
+               let peers = self.pending_messages.lock().unwrap().keys().copied().collect();
+
+               let destination = match reply_path {
+                       Some(reply_path) => Destination::BlindedPath(reply_path),
+                       None => {
+                               log_trace!(
+                                       self.logger, "Missing reply path when responding to onion message with path_id \
+                                       {:02x?}", path_id
+                               );
+                               return;
+                       },
+               };
+
+               let path = match self.message_router.find_path(sender, peers, destination) {
+                       Ok(path) => path,
+                       Err(()) => {
+                               log_trace!(
+                                       self.logger, "Failed to find path when responding to onion message with \
+                                       path_id {:02x?}", path_id
+                               );
+                               return;
+                       },
+               };
+
+               log_trace!(self.logger, "Responding to onion message with path_id {:02x?}", path_id);
+
+               if let Err(e) = self.send_onion_message(path, response, None) {
+                       log_trace!(
+                               self.logger, "Failed responding to onion message with path_id {:02x?}: {:?}",
+                               path_id, e
+                       );
+                       return;
+               }
+       }
+
        #[cfg(test)]
        pub(super) fn release_pending_msgs(&self) -> HashMap<PublicKey, VecDeque<msgs::OnionMessage>> {
                let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -328,14 +408,15 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, Ve
        false
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
-for OnionMessenger<ES, NS, L, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
+for OnionMessenger<ES, NS, L, MR, OMH, CMH>
 where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
        L::Target: Logger,
+       MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
-       CMH::Target: CustomOnionMessageHandler + Sized,
+       CMH::Target: CustomOnionMessageHandler,
 {
        /// Handle an incoming onion message. Currently, if a message was destined for us we will log, but
        /// soon we'll delegate the onion message to a handler that can generate invoices or send
@@ -374,9 +455,20 @@ where
                                log_info!(self.logger,
                                        "Received an onion message with path_id {:02x?} and {} reply_path",
                                                path_id, if reply_path.is_some() { "a" } else { "no" });
-                               match message {
-                                       OnionMessageContents::Offers(msg) => self.offers_handler.handle_message(msg),
-                                       OnionMessageContents::Custom(msg) => self.custom_handler.handle_custom_message(msg),
+
+                               let response = match message {
+                                       OnionMessageContents::Offers(msg) => {
+                                               self.offers_handler.handle_message(msg)
+                                                       .map(|msg| OnionMessageContents::Offers(msg))
+                                       },
+                                       OnionMessageContents::Custom(msg) => {
+                                               self.custom_handler.handle_custom_message(msg)
+                                                       .map(|msg| OnionMessageContents::Custom(msg))
+                                       },
+                               };
+
+                               if let Some(response) = response {
+                                       self.respond_with_onion_message(response, path_id, reply_path);
                                }
                        },
                        Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs {
@@ -478,12 +570,13 @@ where
        }
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessageProvider
-for OnionMessenger<ES, NS, L, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> OnionMessageProvider
+for OnionMessenger<ES, NS, L, MR, OMH, CMH>
 where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
        L::Target: Logger,
+       MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        CMH::Target: CustomOnionMessageHandler,
 {
@@ -505,10 +598,11 @@ where
 ///
 /// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
 /// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
-pub type SimpleArcOnionMessenger<L> = OnionMessenger<
+pub type SimpleArcOnionMessenger<L, R> = OnionMessenger<
        Arc<KeysManager>,
        Arc<KeysManager>,
        Arc<L>,
+       Arc<R>,
        IgnoringMessageHandler,
        IgnoringMessageHandler
 >;
@@ -520,10 +614,11 @@ pub type SimpleArcOnionMessenger<L> = OnionMessenger<
 ///
 /// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
 /// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
-pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<
+pub type SimpleRefOnionMessenger<'a, 'b, 'c, L, R> = OnionMessenger<
        &'a KeysManager,
        &'a KeysManager,
        &'b L,
+       &'c R,
        IgnoringMessageHandler,
        IgnoringMessageHandler
 >;