@@ -267,14 +267,27 @@ impl Responder {
267267 }
268268 }
269269
270- /// Creates the appropriate [`ResponseInstruction`] for a given response.
270+ /// Creates a [`ResponseInstruction::WithoutReplyPath`] for a given response.
271+ ///
272+ /// Use when the recipient doesn't need to send back a reply to us.
271273 pub fn respond < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
272274 ResponseInstruction :: WithoutReplyPath ( OnionMessageResponse {
273275 message : response,
274276 reply_path : self . reply_path ,
275277 path_id : self . path_id ,
276278 } )
277279 }
280+
281+ /// Creates a [`ResponseInstruction::WithReplyPath`] for a given response.
282+ ///
283+ /// Use when the recipient needs to send back a reply to us.
284+ pub fn respond_with_reply_path < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
285+ ResponseInstruction :: WithReplyPath ( OnionMessageResponse {
286+ message : response,
287+ reply_path : self . reply_path ,
288+ path_id : self . path_id ,
289+ } )
290+ }
278291}
279292
280293/// This struct contains the information needed to reply to a received message.
@@ -286,6 +299,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
286299
287300/// `ResponseInstruction` represents instructions for responding to received messages.
288301pub enum ResponseInstruction < T : OnionMessageContents > {
302+ /// Indicates that a response should be sent including a reply path for
303+ /// the recipient to respond back.
304+ WithReplyPath ( OnionMessageResponse < T > ) ,
289305 /// Indicates that a response should be sent without including a reply path
290306 /// for the recipient to respond back.
291307 WithoutReplyPath ( OnionMessageResponse < T > ) ,
@@ -554,7 +570,11 @@ pub enum SendError {
554570 TooFewBlindedHops ,
555571 /// The first hop is not a peer and doesn't have a known [`SocketAddress`].
556572 InvalidFirstHop ( PublicKey ) ,
557- /// A path from the sender to the destination could not be found by the [`MessageRouter`].
573+ /// Indicates that a path could not be found by the [`MessageRouter`].
574+ ///
575+ /// This occurs when either:
576+ /// - No path from the sender to the destination was found to send the onion message
577+ /// - No reply path to the sender could be created when responding to an onion message
558578 PathNotFound ,
559579 /// Onion message contents must have a TLV type >= 64.
560580 InvalidMessage ,
@@ -971,6 +991,24 @@ where
971991 . map_err ( |_| SendError :: PathNotFound )
972992 }
973993
994+ fn create_blinded_path ( & self ) -> Result < BlindedPath , SendError > {
995+ let recipient = self . node_signer
996+ . get_node_id ( Recipient :: Node )
997+ . map_err ( |_| SendError :: GetNodeIdFailed ) ?;
998+ let secp_ctx = & self . secp_ctx ;
999+
1000+ let peers = self . message_recipients . lock ( ) . unwrap ( )
1001+ . iter ( )
1002+ . filter ( |( _, peer) | matches ! ( peer, OnionMessageRecipient :: ConnectedPeer ( _) ) )
1003+ . map ( |( node_id, _) | * node_id)
1004+ . collect ( ) ;
1005+
1006+ self . message_router
1007+ . create_blinded_paths ( recipient, peers, secp_ctx)
1008+ . and_then ( |paths| paths. into_iter ( ) . next ( ) . ok_or ( ( ) ) )
1009+ . map_err ( |_| SendError :: PathNotFound )
1010+ }
1011+
9741012 fn enqueue_onion_message < T : OnionMessageContents > (
9751013 & self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
9761014 log_suffix : fmt:: Arguments
@@ -1047,18 +1085,37 @@ where
10471085 /// enqueueing any response for sending.
10481086 pub fn handle_onion_message_response < T : OnionMessageContents > (
10491087 & self , response : ResponseInstruction < T >
1050- ) {
1051- if let ResponseInstruction :: WithoutReplyPath ( response) = response {
1052- let message_type = response. message . msg_type ( ) ;
1053- let _ = self . find_path_and_enqueue_onion_message (
1054- response. message , Destination :: BlindedPath ( response. reply_path ) , None ,
1055- format_args ! (
1056- "when responding with {} to an onion message with path_id {:02x?}" ,
1057- message_type,
1058- response. path_id
1059- )
1060- ) ;
1061- }
1088+ ) -> Result < Option < SendSuccess > , SendError > {
1089+ let ( response, create_reply_path) = match response {
1090+ ResponseInstruction :: WithReplyPath ( response) => ( response, true ) ,
1091+ ResponseInstruction :: WithoutReplyPath ( response) => ( response, false ) ,
1092+ ResponseInstruction :: NoResponse => return Ok ( None ) ,
1093+ } ;
1094+
1095+ let message_type = response. message . msg_type ( ) ;
1096+ let reply_path = if create_reply_path {
1097+ match self . create_blinded_path ( ) {
1098+ Ok ( reply_path) => Some ( reply_path) ,
1099+ Err ( err) => {
1100+ log_trace ! (
1101+ self . logger,
1102+ "Failed to create reply path when responding with {} to an onion message \
1103+ with path_id {:02x?}: {:?}",
1104+ message_type, response. path_id, err
1105+ ) ;
1106+ return Err ( err) ;
1107+ }
1108+ }
1109+ } else { None } ;
1110+
1111+ self . find_path_and_enqueue_onion_message (
1112+ response. message , Destination :: BlindedPath ( response. reply_path ) , reply_path,
1113+ format_args ! (
1114+ "when responding with {} to an onion message with path_id {:02x?}" ,
1115+ message_type,
1116+ response. path_id
1117+ )
1118+ ) . map ( |result| Some ( result) )
10621119 }
10631120
10641121 #[ cfg( test) ]
@@ -1164,14 +1221,14 @@ where
11641221 |reply_path| Responder :: new ( reply_path, path_id)
11651222 ) ;
11661223 let response_instructions = self . offers_handler . handle_message ( msg, responder) ;
1167- self . handle_onion_message_response ( response_instructions) ;
1224+ let _ = self . handle_onion_message_response ( response_instructions) ;
11681225 } ,
11691226 ParsedOnionMessageContents :: Custom ( msg) => {
11701227 let responder = reply_path. map (
11711228 |reply_path| Responder :: new ( reply_path, path_id)
11721229 ) ;
11731230 let response_instructions = self . custom_handler . handle_custom_message ( msg, responder) ;
1174- self . handle_onion_message_response ( response_instructions) ;
1231+ let _ = self . handle_onion_message_response ( response_instructions) ;
11751232 } ,
11761233 }
11771234 } ,
0 commit comments