@@ -271,14 +271,27 @@ impl Responder {
271
271
}
272
272
}
273
273
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.
275
277
pub fn respond < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
276
278
ResponseInstruction :: WithoutReplyPath ( OnionMessageResponse {
277
279
message : response,
278
280
reply_path : self . reply_path ,
279
281
path_id : self . path_id ,
280
282
} )
281
283
}
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
+ }
282
295
}
283
296
284
297
/// This struct contains the information needed to reply to a received message.
@@ -290,6 +303,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
290
303
291
304
/// `ResponseInstruction` represents instructions for responding to received messages.
292
305
pub 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 > ) ,
293
309
/// Indicates that a response should be sent without including a reply path
294
310
/// for the recipient to respond back.
295
311
WithoutReplyPath ( OnionMessageResponse < T > ) ,
@@ -564,7 +580,11 @@ pub enum SendError {
564
580
TooFewBlindedHops ,
565
581
/// The first hop is not a peer and doesn't have a known [`SocketAddress`].
566
582
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
568
588
PathNotFound ,
569
589
/// Onion message contents must have a TLV type >= 64.
570
590
InvalidMessage ,
@@ -981,6 +1001,33 @@ where
981
1001
. map_err ( |_| SendError :: PathNotFound )
982
1002
}
983
1003
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, _)| *node_id)
1014
+ // .collect();
1015
+
1016
+ let peers = self . message_recipients . lock ( ) . unwrap ( )
1017
+ . iter ( )
1018
+ . filter ( |( _, peer) | matches ! ( peer, OnionMessageRecipient :: ConnectedPeer ( _) ) )
1019
+ . map ( |( node_id, _ ) | ForwardNode {
1020
+ node_id : * node_id,
1021
+ short_channel_id : None ,
1022
+ } )
1023
+ . collect :: < Vec < _ > > ( ) ;
1024
+
1025
+ self . message_router
1026
+ . create_blinded_paths ( recipient, peers, secp_ctx)
1027
+ . and_then ( |paths| paths. into_iter ( ) . next ( ) . ok_or ( ( ) ) )
1028
+ . map_err ( |_| SendError :: PathNotFound )
1029
+ }
1030
+
984
1031
fn enqueue_onion_message < T : OnionMessageContents > (
985
1032
& self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
986
1033
log_suffix : fmt:: Arguments
@@ -1065,18 +1112,37 @@ where
1065
1112
/// the response for delivery.
1066
1113
pub fn handle_onion_message_response < T : OnionMessageContents > (
1067
1114
& self , response : ResponseInstruction < T >
1068
- ) {
1069
- if let ResponseInstruction :: WithoutReplyPath ( response) = response {
1070
- let message_type = response. message . msg_type ( ) ;
1071
- let _ = self . find_path_and_enqueue_onion_message (
1072
- response. message , Destination :: BlindedPath ( response. reply_path ) , None ,
1073
- format_args ! (
1074
- "when responding with {} to an onion message with path_id {:02x?}" ,
1075
- message_type,
1076
- response. path_id
1077
- )
1078
- ) ;
1079
- }
1115
+ ) -> Result < Option < SendSuccess > , SendError > {
1116
+ let ( response, create_reply_path) = match response {
1117
+ ResponseInstruction :: WithReplyPath ( response) => ( response, true ) ,
1118
+ ResponseInstruction :: WithoutReplyPath ( response) => ( response, false ) ,
1119
+ ResponseInstruction :: NoResponse => return Ok ( None ) ,
1120
+ } ;
1121
+
1122
+ let message_type = response. message . msg_type ( ) ;
1123
+ let reply_path = if create_reply_path {
1124
+ match self . create_blinded_path ( ) {
1125
+ Ok ( reply_path) => Some ( reply_path) ,
1126
+ Err ( err) => {
1127
+ log_trace ! (
1128
+ self . logger,
1129
+ "Failed to create reply path when responding with {} to an onion message \
1130
+ with path_id {:02x?}: {:?}",
1131
+ message_type, response. path_id, err
1132
+ ) ;
1133
+ return Err ( err) ;
1134
+ }
1135
+ }
1136
+ } else { None } ;
1137
+
1138
+ self . find_path_and_enqueue_onion_message (
1139
+ response. message , Destination :: BlindedPath ( response. reply_path ) , reply_path,
1140
+ format_args ! (
1141
+ "when responding with {} to an onion message with path_id {:02x?}" ,
1142
+ message_type,
1143
+ response. path_id
1144
+ )
1145
+ ) . map ( |result| Some ( result) )
1080
1146
}
1081
1147
1082
1148
#[ cfg( test) ]
@@ -1182,14 +1248,14 @@ where
1182
1248
|reply_path| Responder :: new ( reply_path, path_id)
1183
1249
) ;
1184
1250
let response_instructions = self . offers_handler . handle_message ( msg, responder) ;
1185
- self . handle_onion_message_response ( response_instructions) ;
1251
+ let _ = self . handle_onion_message_response ( response_instructions) ;
1186
1252
} ,
1187
1253
ParsedOnionMessageContents :: Custom ( msg) => {
1188
1254
let responder = reply_path. map (
1189
1255
|reply_path| Responder :: new ( reply_path, path_id)
1190
1256
) ;
1191
1257
let response_instructions = self . custom_handler . handle_custom_message ( msg, responder) ;
1192
- self . handle_onion_message_response ( response_instructions) ;
1258
+ let _ = self . handle_onion_message_response ( response_instructions) ;
1193
1259
} ,
1194
1260
}
1195
1261
} ,
0 commit comments