From 47b527a656b3d965a63f7871eebb98ebdc9638f0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 22 Aug 2024 01:31:07 +0000 Subject: [PATCH] Add a `MessageSendInstructions::ForReply` In order to allow onion message handlers to reply asynchronously without introducing a circular dependency graph, the message handlers need to be able to send replies described by `MessageSendInstructions`. This allows them to send replies via the normal message queuing (i.e. without making a function call to `OnionMessenger`). Here we enable that by adding a `MessageSendInstructions::ForReply` variant which holds `ReplyInstruction`s. Fixes #3178 --- lightning/src/onion_message/messenger.rs | 29 +++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index d9e36f413..7d215e365 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -367,7 +367,7 @@ impl Responder { /// Use when the recipient doesn't need to send back a reply to us. pub fn respond(self) -> ResponseInstruction { ResponseInstruction { - send_path: self.reply_path, + destination: Destination::BlindedPath(self.reply_path), context: None, } } @@ -377,7 +377,7 @@ impl Responder { /// Use when the recipient needs to send back a reply to us. pub fn respond_with_reply_path(self, context: MessageContext) -> ResponseInstruction { ResponseInstruction { - send_path: self.reply_path, + destination: Destination::BlindedPath(self.reply_path), context: Some(context), } } @@ -386,17 +386,16 @@ impl Responder { /// Instructions for how and where to send the response to an onion message. #[derive(Clone)] pub struct ResponseInstruction { - send_path: BlindedMessagePath, + /// The destination in a response is always a [`Destination::BlindedPath`] but using a + /// [`Destination`] rather than an explicit [`BlindedMessagePath`] simplifies the logic in + /// [`OnionMessenger::send_onion_message_internal`] somewhat. + destination: Destination, context: Option, } impl ResponseInstruction { fn into_instructions(self) -> MessageSendInstructions { - let destination = Destination::BlindedPath(self.send_path); - match self.context { - Some(context) => MessageSendInstructions::WithReplyPath { destination, context }, - None => MessageSendInstructions::WithoutReplyPath { destination }, - } + MessageSendInstructions::ForReply { instructions: self } } } @@ -425,7 +424,12 @@ pub enum MessageSendInstructions { WithoutReplyPath { /// The destination where we need to send our message. destination: Destination, - } + }, + /// Indicates that a message is being sent as a reply to a received message. + ForReply { + /// The instructions provided by the [`Responder`]. + instructions: ResponseInstruction, + }, } /// A trait defining behavior for routing an [`OnionMessage`]. @@ -1158,7 +1162,9 @@ where let (destination, reply_path) = match instructions { MessageSendInstructions::WithSpecifiedReplyPath { destination, reply_path } => (destination, Some(reply_path)), - MessageSendInstructions::WithReplyPath { destination, context } => { + MessageSendInstructions::WithReplyPath { destination, context } + |MessageSendInstructions::ForReply { instructions: ResponseInstruction { destination, context: Some(context) } } => + { match self.create_blinded_path(context) { Ok(reply_path) => (destination, Some(reply_path)), Err(err) => { @@ -1171,7 +1177,8 @@ where } } }, - MessageSendInstructions::WithoutReplyPath { destination } => + MessageSendInstructions::WithoutReplyPath { destination } + |MessageSendInstructions::ForReply { instructions: ResponseInstruction { destination, context: None } } => (destination, None), }; -- 2.39.5