@@ -267,14 +267,23 @@ impl Responder {
267267 }
268268 }
269269
270- /// Creates the appropriate [`ResponseInstruction`] for a given response.
270+ /// Creates a [`ResponseInstruction::WithoutReplyPath `] for a given response.
271271 pub fn respond < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
272272 ResponseInstruction :: WithoutReplyPath ( OnionMessageResponse {
273273 message : response,
274274 reply_path : self . reply_path ,
275275 path_id : self . path_id ,
276276 } )
277277 }
278+
279+ /// Creates a [`ResponseInstruction::WithReplyPath`] for a given response.
280+ pub fn respond_with_reply_path < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
281+ ResponseInstruction :: WithReplyPath ( OnionMessageResponse {
282+ message : response,
283+ reply_path : self . reply_path ,
284+ path_id : self . path_id ,
285+ } )
286+ }
278287}
279288
280289/// This struct contains the information needed to reply to a received message.
@@ -286,6 +295,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
286295
287296/// `ResponseInstruction` represents instructions for responding to received messages.
288297pub enum ResponseInstruction < T : OnionMessageContents > {
298+ /// Indicates that a response should be sent including a reply path for
299+ /// the recipient to respond back.
300+ WithReplyPath ( OnionMessageResponse < T > ) ,
289301 /// Indicates that a response should be sent without including a reply path
290302 /// for the recipient to respond back.
291303 WithoutReplyPath ( OnionMessageResponse < T > ) ,
@@ -971,6 +983,24 @@ where
971983 . map_err ( |_| SendError :: PathNotFound )
972984 }
973985
986+ fn create_blinded_path ( & self ) -> Result < BlindedPath , SendError > {
987+ let recipient = self . node_signer
988+ . get_node_id ( Recipient :: Node )
989+ . map_err ( |_| SendError :: GetNodeIdFailed ) ?;
990+ let secp_ctx = & self . secp_ctx ;
991+
992+ let peers = self . message_recipients . lock ( ) . unwrap ( )
993+ . iter ( )
994+ . filter ( |( _, peer) | matches ! ( peer, OnionMessageRecipient :: ConnectedPeer ( _) ) )
995+ . map ( |( node_id, _) | * node_id)
996+ . collect ( ) ;
997+
998+ self . message_router
999+ . create_blinded_paths ( recipient, peers, secp_ctx)
1000+ . and_then ( |paths| paths. into_iter ( ) . next ( ) . ok_or ( ( ) ) )
1001+ . map_err ( |_| SendError :: PathNotFound )
1002+ }
1003+
9741004 fn enqueue_onion_message < T : OnionMessageContents > (
9751005 & self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
9761006 log_suffix : fmt:: Arguments
@@ -1047,18 +1077,35 @@ where
10471077 /// enqueueing any response for sending.
10481078 pub fn handle_onion_message_response < T : OnionMessageContents > (
10491079 & 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- }
1080+ ) -> Result < Option < SendSuccess > , SendError > {
1081+ let ( response, create_reply_path) = match response {
1082+ ResponseInstruction :: WithReplyPath ( response) => ( response, true ) ,
1083+ ResponseInstruction :: WithoutReplyPath ( response) => ( response, false ) ,
1084+ ResponseInstruction :: NoResponse => return Ok ( None ) ,
1085+ } ;
1086+ let logger = WithContext :: from ( & self . logger , None , None , None ) ;
1087+ let message_type = response. message . msg_type ( ) ;
1088+ let log_suffix = format ! (
1089+ "when responding with {} to an onion message with path_id {:02x?}" ,
1090+ message_type,
1091+ response. path_id
1092+ ) ;
1093+
1094+ let reply_path = if create_reply_path {
1095+ let reply_path = self . create_blinded_path ( ) ;
1096+ match reply_path. as_ref ( ) {
1097+ Err ( SendError :: PathNotFound ) => log_trace ! (
1098+ logger, "Failed to create blinded_path {}" , format_args!( "{}" , log_suffix)
1099+ ) ,
1100+ _ => ( ) ,
1101+ }
1102+ Some ( reply_path?)
1103+ } else { None } ;
1104+
1105+ self . find_path_and_enqueue_onion_message (
1106+ response. message , Destination :: BlindedPath ( response. reply_path ) , reply_path,
1107+ format_args ! ( "{}" , log_suffix)
1108+ ) . map ( |result| Some ( result) )
10621109 }
10631110
10641111 #[ cfg( test) ]
@@ -1164,14 +1211,14 @@ where
11641211 |reply_path| Responder :: new ( reply_path, path_id)
11651212 ) ;
11661213 let response_instructions = self . offers_handler . handle_message ( msg, responder) ;
1167- self . handle_onion_message_response ( response_instructions) ;
1214+ let _ = self . handle_onion_message_response ( response_instructions) ;
11681215 } ,
11691216 ParsedOnionMessageContents :: Custom ( msg) => {
11701217 let responder = reply_path. map (
11711218 |reply_path| Responder :: new ( reply_path, path_id)
11721219 ) ;
11731220 let response_instructions = self . custom_handler . handle_custom_message ( msg, responder) ;
1174- self . handle_onion_message_response ( response_instructions) ;
1221+ let _ = self . handle_onion_message_response ( response_instructions) ;
11751222 } ,
11761223 }
11771224 } ,
0 commit comments