@@ -271,14 +271,27 @@ impl Responder {
271271 }
272272 }
273273
274- /// Creates the appropriate [`ResponseInstruction`] for a given response.
274+ /// Creates a [`ResponseInstruction::WithoutReplyPath`] for a given response.
275+ ///
276+ /// Use when the recipient doesn't need to send back a reply to us.
275277 pub fn respond < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
276278 ResponseInstruction :: WithoutReplyPath ( OnionMessageResponse {
277279 message : response,
278280 reply_path : self . reply_path ,
279281 path_id : self . path_id ,
280282 } )
281283 }
284+
285+ /// Creates a [`ResponseInstruction::WithReplyPath`] for a given response.
286+ ///
287+ /// Use when the recipient needs to send back a reply to us.
288+ pub fn respond_with_reply_path < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
289+ ResponseInstruction :: WithReplyPath ( OnionMessageResponse {
290+ message : response,
291+ reply_path : self . reply_path ,
292+ path_id : self . path_id ,
293+ } )
294+ }
282295}
283296
284297/// This struct contains the information needed to reply to a received message.
@@ -290,6 +303,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
290303
291304/// `ResponseInstruction` represents instructions for responding to received messages.
292305pub enum ResponseInstruction < T : OnionMessageContents > {
306+ /// Indicates that a response should be sent including a reply path for
307+ /// the recipient to respond back.
308+ WithReplyPath ( OnionMessageResponse < T > ) ,
293309 /// Indicates that a response should be sent without including a reply path
294310 /// for the recipient to respond back.
295311 WithoutReplyPath ( OnionMessageResponse < T > ) ,
@@ -564,7 +580,11 @@ pub enum SendError {
564580 TooFewBlindedHops ,
565581 /// The first hop is not a peer and doesn't have a known [`SocketAddress`].
566582 InvalidFirstHop ( PublicKey ) ,
567- /// A path from the sender to the destination could not be found by the [`MessageRouter`].
583+ /// Indicates that a path could not be found by the [`MessageRouter`].
584+ ///
585+ /// This occurs when either:
586+ /// - No path from the sender to the destination was found to send the onion message
587+ /// - No reply path to the sender could be created when responding to an onion message
568588 PathNotFound ,
569589 /// Onion message contents must have a TLV type >= 64.
570590 InvalidMessage ,
@@ -981,6 +1001,27 @@ where
9811001 . map_err ( |_| SendError :: PathNotFound )
9821002 }
9831003
1004+ fn create_blinded_path ( & self ) -> Result < BlindedPath , SendError > {
1005+ let recipient = self . node_signer
1006+ . get_node_id ( Recipient :: Node )
1007+ . map_err ( |_| SendError :: GetNodeIdFailed ) ?;
1008+ let secp_ctx = & self . secp_ctx ;
1009+
1010+ let peers = self . message_recipients . lock ( ) . unwrap ( )
1011+ . iter ( )
1012+ . filter ( |( _, peer) | matches ! ( peer, OnionMessageRecipient :: ConnectedPeer ( _) ) )
1013+ . map ( |( node_id, _ ) | ForwardNode {
1014+ node_id : * node_id,
1015+ short_channel_id : None ,
1016+ } )
1017+ . collect :: < Vec < _ > > ( ) ;
1018+
1019+ self . message_router
1020+ . create_blinded_paths ( recipient, peers, secp_ctx)
1021+ . and_then ( |paths| paths. into_iter ( ) . next ( ) . ok_or ( ( ) ) )
1022+ . map_err ( |_| SendError :: PathNotFound )
1023+ }
1024+
9841025 fn enqueue_onion_message < T : OnionMessageContents > (
9851026 & self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
9861027 log_suffix : fmt:: Arguments
@@ -1064,18 +1105,37 @@ where
10641105 /// the response for delivery.
10651106 pub fn handle_onion_message_response < T : OnionMessageContents > (
10661107 & self , response : ResponseInstruction < T >
1067- ) {
1068- if let ResponseInstruction :: WithoutReplyPath ( response) = response {
1069- let message_type = response. message . msg_type ( ) ;
1070- let _ = self . find_path_and_enqueue_onion_message (
1071- response. message , Destination :: BlindedPath ( response. reply_path ) , None ,
1072- format_args ! (
1073- "when responding with {} to an onion message with path_id {:02x?}" ,
1074- message_type,
1075- response. path_id
1076- )
1077- ) ;
1078- }
1108+ ) -> Result < Option < SendSuccess > , SendError > {
1109+ let ( response, create_reply_path) = match response {
1110+ ResponseInstruction :: WithReplyPath ( response) => ( response, true ) ,
1111+ ResponseInstruction :: WithoutReplyPath ( response) => ( response, false ) ,
1112+ ResponseInstruction :: NoResponse => return Ok ( None ) ,
1113+ } ;
1114+
1115+ let message_type = response. message . msg_type ( ) ;
1116+ let reply_path = if create_reply_path {
1117+ match self . create_blinded_path ( ) {
1118+ Ok ( reply_path) => Some ( reply_path) ,
1119+ Err ( err) => {
1120+ log_trace ! (
1121+ self . logger,
1122+ "Failed to create reply path when responding with {} to an onion message \
1123+ with path_id {:02x?}: {:?}",
1124+ message_type, response. path_id, err
1125+ ) ;
1126+ return Err ( err) ;
1127+ }
1128+ }
1129+ } else { None } ;
1130+
1131+ self . find_path_and_enqueue_onion_message (
1132+ response. message , Destination :: BlindedPath ( response. reply_path ) , reply_path,
1133+ format_args ! (
1134+ "when responding with {} to an onion message with path_id {:02x?}" ,
1135+ message_type,
1136+ response. path_id
1137+ )
1138+ ) . map ( |result| Some ( result) )
10791139 }
10801140
10811141 #[ cfg( test) ]
@@ -1181,14 +1241,14 @@ where
11811241 |reply_path| Responder :: new ( reply_path, path_id)
11821242 ) ;
11831243 let response_instructions = self . offers_handler . handle_message ( msg, responder) ;
1184- self . handle_onion_message_response ( response_instructions) ;
1244+ let _ = self . handle_onion_message_response ( response_instructions) ;
11851245 } ,
11861246 ParsedOnionMessageContents :: Custom ( msg) => {
11871247 let responder = reply_path. map (
11881248 |reply_path| Responder :: new ( reply_path, path_id)
11891249 ) ;
11901250 let response_instructions = self . custom_handler . handle_custom_message ( msg, responder) ;
1191- self . handle_onion_message_response ( response_instructions) ;
1251+ let _ = self . handle_onion_message_response ( response_instructions) ;
11921252 } ,
11931253 }
11941254 } ,
0 commit comments