@@ -265,14 +265,23 @@ impl Responder {
265265 }
266266 }
267267
268- /// Creates the appropriate [`ResponseInstruction`] for a given response.
268+ /// Creates a [`ResponseInstruction::WithoutReplyPath `] for a given response.
269269 pub fn respond < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
270270 ResponseInstruction :: WithoutReplyPath ( OnionMessageResponse {
271271 message : response,
272272 reply_path : self . reply_path ,
273273 path_id : self . path_id ,
274274 } )
275275 }
276+
277+ /// Creates a [`ResponseInstruction::WithReplyPath`] for a given response.
278+ pub fn respond_with_reply_path < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
279+ ResponseInstruction :: WithReplyPath ( OnionMessageResponse {
280+ message : response,
281+ reply_path : self . reply_path ,
282+ path_id : self . path_id ,
283+ } )
284+ }
276285}
277286
278287/// This struct contains the information needed to reply to a received message.
@@ -284,6 +293,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
284293
285294/// `ResponseInstruction` represents instructions for responding to received messages.
286295pub enum ResponseInstruction < T : OnionMessageContents > {
296+ /// Indicates that a response should be sent including a reply path for
297+ /// the recipient to respond back.
298+ WithReplyPath ( OnionMessageResponse < T > ) ,
287299 /// Indicates that a response should be sent without including a reply path
288300 /// for the recipient to respond back.
289301 WithoutReplyPath ( OnionMessageResponse < T > ) ,
@@ -926,6 +938,24 @@ where
926938 . map_err ( |_| SendError :: PathNotFound )
927939 }
928940
941+ fn create_blinded_path ( & self ) -> Result < BlindedPath , SendError > {
942+ let recipient = self . node_signer
943+ . get_node_id ( Recipient :: Node )
944+ . map_err ( |_| SendError :: GetNodeIdFailed ) ?;
945+ let secp_ctx = & self . secp_ctx ;
946+
947+ let peers = self . message_recipients . lock ( ) . unwrap ( )
948+ . iter ( )
949+ . filter ( |( _, peer) | matches ! ( peer, OnionMessageRecipient :: ConnectedPeer ( _) ) )
950+ . map ( |( node_id, _) | * node_id)
951+ . collect ( ) ;
952+
953+ self . message_router
954+ . create_blinded_paths ( recipient, peers, secp_ctx)
955+ . and_then ( |paths| paths. into_iter ( ) . next ( ) . ok_or ( ( ) ) )
956+ . map_err ( |_| SendError :: PathNotFound )
957+ }
958+
929959 fn enqueue_onion_message < T : OnionMessageContents > (
930960 & self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
931961 log_suffix : fmt:: Arguments
@@ -981,18 +1011,35 @@ where
9811011 /// enqueueing any response for sending.
9821012 pub fn handle_onion_message_response < T : OnionMessageContents > (
9831013 & self , response : ResponseInstruction < T >
984- ) {
985- if let ResponseInstruction :: WithoutReplyPath ( response) = response {
986- let message_type = response. message . msg_type ( ) ;
987- let _ = self . find_path_and_enqueue_onion_message (
988- response. message , Destination :: BlindedPath ( response. reply_path ) , None ,
989- format_args ! (
990- "when responding with {} to an onion message with path_id {:02x?}" ,
991- message_type,
992- response. path_id
993- )
994- ) ;
995- }
1014+ ) -> Result < Option < SendSuccess > , SendError > {
1015+ let ( response, create_reply_path) = match response {
1016+ ResponseInstruction :: WithReplyPath ( response) => ( response, true ) ,
1017+ ResponseInstruction :: WithoutReplyPath ( response) => ( response, false ) ,
1018+ ResponseInstruction :: NoResponse => return Ok ( None ) ,
1019+ } ;
1020+ let logger = WithContext :: from ( & self . logger , None , None ) ;
1021+ let message_type = response. message . msg_type ( ) ;
1022+ let log_suffix = format ! (
1023+ "when responding with {} to an onion message with path_id {:02x?}" ,
1024+ message_type,
1025+ response. path_id
1026+ ) ;
1027+
1028+ let reply_path = if create_reply_path {
1029+ let reply_path = self . create_blinded_path ( ) ;
1030+ match reply_path. as_ref ( ) {
1031+ Err ( SendError :: PathNotFound ) => log_trace ! (
1032+ logger, "Failed to create blinded_path {}" , format_args!( "{}" , log_suffix)
1033+ ) ,
1034+ _ => ( ) ,
1035+ }
1036+ Some ( reply_path?)
1037+ } else { None } ;
1038+
1039+ self . find_path_and_enqueue_onion_message (
1040+ response. message , Destination :: BlindedPath ( response. reply_path ) , reply_path,
1041+ format_args ! ( "{}" , log_suffix)
1042+ ) . map ( |result| Some ( result) )
9961043 }
9971044
9981045 #[ cfg( test) ]
@@ -1079,14 +1126,14 @@ where
10791126 |reply_path| Responder :: new ( reply_path, path_id)
10801127 ) ;
10811128 let response_instructions = self . offers_handler . handle_message ( msg, responder) ;
1082- self . handle_onion_message_response ( response_instructions) ;
1129+ let _ = self . handle_onion_message_response ( response_instructions) ;
10831130 } ,
10841131 ParsedOnionMessageContents :: Custom ( msg) => {
10851132 let responder = reply_path. map (
10861133 |reply_path| Responder :: new ( reply_path, path_id)
10871134 ) ;
10881135 let response_instructions = self . custom_handler . handle_custom_message ( msg, responder) ;
1089- self . handle_onion_message_response ( response_instructions) ;
1136+ let _ = self . handle_onion_message_response ( response_instructions) ;
10901137 } ,
10911138 }
10921139 } ,
0 commit comments