Merge pull request #2441 from arik-so/2023-07-taproot-signer-wrapped
[rust-lightning] / lightning / src / onion_message / messenger.rs
index 07cb0bc1e9896df5241c05a0b80a2b03e89eb995..7d5f4a22ec8573e17764c31017f5804083161b21 100644 (file)
@@ -152,6 +152,17 @@ pub trait MessageRouter {
        ) -> Result<OnionMessagePath, ()>;
 }
 
+/// A [`MessageRouter`] that always fails.
+pub struct DefaultMessageRouter;
+
+impl MessageRouter for DefaultMessageRouter {
+       fn find_path(
+               &self, _sender: PublicKey, _peers: Vec<PublicKey>, _destination: Destination
+       ) -> Result<OnionMessagePath, ()> {
+               Err(())
+       }
+}
+
 /// A path for sending an [`msgs::OnionMessage`].
 #[derive(Clone)]
 pub struct OnionMessagePath {
@@ -224,8 +235,10 @@ 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>;
@@ -320,6 +333,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();
@@ -364,7 +427,7 @@ where
        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
@@ -400,12 +463,23 @@ where
                        Ok((Payload::Receive::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
                                message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
                        }, None)) => {
-                               log_info!(self.logger,
+                               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" });
-                               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 {
@@ -416,7 +490,7 @@ where
                                // unwrapping the onion layers to get to the final payload. Since we don't have the option
                                // of creating blinded paths with dummy hops currently, we should be ok to not handle this
                                // for now.
-                               let new_pubkey = match onion_utils::next_hop_packet_pubkey(&self.secp_ctx, msg.onion_routing_packet.public_key, &onion_decode_ss) {
+                               let new_pubkey = match onion_utils::next_hop_pubkey(&self.secp_ctx, msg.onion_routing_packet.public_key, &onion_decode_ss) {
                                        Ok(pk) => pk,
                                        Err(e) => {
                                                log_trace!(self.logger, "Failed to compute next hop packet pubkey: {}", e);
@@ -433,21 +507,16 @@ where
                                        blinding_point: match next_blinding_override {
                                                Some(blinding_point) => blinding_point,
                                                None => {
-                                                       let blinding_factor = {
-                                                               let mut sha = Sha256::engine();
-                                                               sha.input(&msg.blinding_point.serialize()[..]);
-                                                               sha.input(control_tlvs_ss.as_ref());
-                                                               Sha256::from_engine(sha).into_inner()
-                                                       };
-                                                       let next_blinding_point = msg.blinding_point;
-                                                       match next_blinding_point.mul_tweak(&self.secp_ctx, &Scalar::from_be_bytes(blinding_factor).unwrap()) {
+                                                       match onion_utils::next_hop_pubkey(
+                                                               &self.secp_ctx, msg.blinding_point, control_tlvs_ss.as_ref()
+                                                       ) {
                                                                Ok(bp) => bp,
                                                                Err(e) => {
                                                                        log_trace!(self.logger, "Failed to compute next blinding point: {}", e);
                                                                        return
                                                                }
                                                        }
-                                               },
+                                               }
                                        },
                                        onion_routing_packet: outgoing_packet,
                                };
@@ -535,11 +604,11 @@ where
 ///
 /// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
 /// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
-pub type SimpleArcOnionMessenger<L, R> = OnionMessenger<
+pub type SimpleArcOnionMessenger<L> = OnionMessenger<
        Arc<KeysManager>,
        Arc<KeysManager>,
        Arc<L>,
-       Arc<R>,
+       Arc<DefaultMessageRouter>,
        IgnoringMessageHandler,
        IgnoringMessageHandler
 >;
@@ -551,11 +620,11 @@ pub type SimpleArcOnionMessenger<L, R> = OnionMessenger<
 ///
 /// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
 /// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
-pub type SimpleRefOnionMessenger<'a, 'b, 'c, L, R> = OnionMessenger<
+pub type SimpleRefOnionMessenger<'a, 'b, 'c, L> = OnionMessenger<
        &'a KeysManager,
        &'a KeysManager,
        &'b L,
-       &'c R,
+       &'c DefaultMessageRouter,
        IgnoringMessageHandler,
        IgnoringMessageHandler
 >;