@@ -265,14 +265,23 @@ impl Responder {
265
265
}
266
266
}
267
267
268
- /// Creates the appropriate [`ResponseInstruction`] for a given response.
268
+ /// Creates a [`ResponseInstruction::WithoutReplyPath `] for a given response.
269
269
pub fn respond < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
270
270
ResponseInstruction :: WithoutReplyPath ( OnionMessageResponse {
271
271
message : response,
272
272
reply_path : self . reply_path ,
273
273
path_id : self . path_id ,
274
274
} )
275
275
}
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
+ }
276
285
}
277
286
278
287
/// This struct contains the information needed to reply to a received message.
@@ -284,6 +293,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
284
293
285
294
/// `ResponseInstruction` represents instructions for responding to received messages.
286
295
pub 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 > ) ,
287
299
/// Indicates that a response should be sent without including a reply path
288
300
/// for the recipient to respond back.
289
301
WithoutReplyPath ( OnionMessageResponse < T > ) ,
@@ -926,6 +938,24 @@ where
926
938
. map_err ( |_| SendError :: PathNotFound )
927
939
}
928
940
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
+
929
959
fn enqueue_onion_message < T : OnionMessageContents > (
930
960
& self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
931
961
log_suffix : fmt:: Arguments
@@ -981,18 +1011,35 @@ where
981
1011
/// enqueueing any response for sending.
982
1012
pub fn handle_onion_message_response < T : OnionMessageContents > (
983
1013
& 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) )
996
1043
}
997
1044
998
1045
#[ cfg( test) ]
@@ -1079,14 +1126,14 @@ where
1079
1126
|reply_path| Responder :: new ( reply_path, path_id)
1080
1127
) ;
1081
1128
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) ;
1083
1130
} ,
1084
1131
ParsedOnionMessageContents :: Custom ( msg) => {
1085
1132
let responder = reply_path. map (
1086
1133
|reply_path| Responder :: new ( reply_path, path_id)
1087
1134
) ;
1088
1135
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) ;
1090
1137
} ,
1091
1138
}
1092
1139
} ,
0 commit comments