@@ -267,14 +267,27 @@ impl Responder {
267
267
}
268
268
}
269
269
270
- /// Creates the appropriate [`ResponseInstruction`] for a given response.
270
+ /// Creates a [`ResponseInstruction::WithoutReplyPath`] for a given response.
271
+ ///
272
+ /// Use when the recipient doesn't need to send back a reply to us.
271
273
pub fn respond < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
272
274
ResponseInstruction :: WithoutReplyPath ( OnionMessageResponse {
273
275
message : response,
274
276
reply_path : self . reply_path ,
275
277
path_id : self . path_id ,
276
278
} )
277
279
}
280
+
281
+ /// Creates a [`ResponseInstruction::WithReplyPath`] for a given response.
282
+ ///
283
+ /// Use when the recipient needs to send back a reply to us.
284
+ pub fn respond_with_reply_path < T : OnionMessageContents > ( self , response : T ) -> ResponseInstruction < T > {
285
+ ResponseInstruction :: WithReplyPath ( OnionMessageResponse {
286
+ message : response,
287
+ reply_path : self . reply_path ,
288
+ path_id : self . path_id ,
289
+ } )
290
+ }
278
291
}
279
292
280
293
/// This struct contains the information needed to reply to a received message.
@@ -286,6 +299,9 @@ pub struct OnionMessageResponse<T: OnionMessageContents> {
286
299
287
300
/// `ResponseInstruction` represents instructions for responding to received messages.
288
301
pub enum ResponseInstruction < T : OnionMessageContents > {
302
+ /// Indicates that a response should be sent including a reply path for
303
+ /// the recipient to respond back.
304
+ WithReplyPath ( OnionMessageResponse < T > ) ,
289
305
/// Indicates that a response should be sent without including a reply path
290
306
/// for the recipient to respond back.
291
307
WithoutReplyPath ( OnionMessageResponse < T > ) ,
@@ -554,7 +570,11 @@ pub enum SendError {
554
570
TooFewBlindedHops ,
555
571
/// The first hop is not a peer and doesn't have a known [`SocketAddress`].
556
572
InvalidFirstHop ( PublicKey ) ,
557
- /// A path from the sender to the destination could not be found by the [`MessageRouter`].
573
+ /// Indicates that a path could not be found by the [`MessageRouter`].
574
+ ///
575
+ /// This occurs when:
576
+ /// 1. No path from sender to destination is found for sending the onion message.
577
+ /// 2. No reply path from destination to sender is created when responding to the onion message.
558
578
PathNotFound ,
559
579
/// Onion message contents must have a TLV type >= 64.
560
580
InvalidMessage ,
@@ -971,6 +991,24 @@ where
971
991
. map_err ( |_| SendError :: PathNotFound )
972
992
}
973
993
994
+ fn create_blinded_path ( & self ) -> Result < BlindedPath , SendError > {
995
+ let recipient = self . node_signer
996
+ . get_node_id ( Recipient :: Node )
997
+ . map_err ( |_| SendError :: GetNodeIdFailed ) ?;
998
+ let secp_ctx = & self . secp_ctx ;
999
+
1000
+ let peers = self . message_recipients . lock ( ) . unwrap ( )
1001
+ . iter ( )
1002
+ . filter ( |( _, peer) | matches ! ( peer, OnionMessageRecipient :: ConnectedPeer ( _) ) )
1003
+ . map ( |( node_id, _) | * node_id)
1004
+ . collect ( ) ;
1005
+
1006
+ self . message_router
1007
+ . create_blinded_paths ( recipient, peers, secp_ctx)
1008
+ . and_then ( |paths| paths. into_iter ( ) . next ( ) . ok_or ( ( ) ) )
1009
+ . map_err ( |_| SendError :: PathNotFound )
1010
+ }
1011
+
974
1012
fn enqueue_onion_message < T : OnionMessageContents > (
975
1013
& self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
976
1014
log_suffix : fmt:: Arguments
@@ -1047,18 +1085,37 @@ where
1047
1085
/// enqueueing any response for sending.
1048
1086
pub fn handle_onion_message_response < T : OnionMessageContents > (
1049
1087
& 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
- }
1088
+ ) -> Result < Option < SendSuccess > , SendError > {
1089
+ let ( response, create_reply_path) = match response {
1090
+ ResponseInstruction :: WithReplyPath ( response) => ( response, true ) ,
1091
+ ResponseInstruction :: WithoutReplyPath ( response) => ( response, false ) ,
1092
+ ResponseInstruction :: NoResponse => return Ok ( None ) ,
1093
+ } ;
1094
+
1095
+ let message_type = response. message . msg_type ( ) ;
1096
+ let reply_path = if create_reply_path {
1097
+ match self . create_blinded_path ( ) {
1098
+ Ok ( reply_path) => Some ( reply_path) ,
1099
+ Err ( err) => {
1100
+ log_trace ! (
1101
+ self . logger,
1102
+ "Failed to create reply path when responding with {} to an onion message \
1103
+ with path_id {:02x?}: {:?}",
1104
+ message_type, response. path_id, err
1105
+ ) ;
1106
+ return Err ( err) ;
1107
+ }
1108
+ }
1109
+ } else { None } ;
1110
+
1111
+ self . find_path_and_enqueue_onion_message (
1112
+ response. message , Destination :: BlindedPath ( response. reply_path ) , reply_path,
1113
+ format_args ! (
1114
+ "when responding with {} to an onion message with path_id {:02x?}" ,
1115
+ message_type,
1116
+ response. path_id
1117
+ )
1118
+ ) . map ( |result| Some ( result) )
1062
1119
}
1063
1120
1064
1121
#[ cfg( test) ]
@@ -1164,14 +1221,14 @@ where
1164
1221
|reply_path| Responder :: new ( reply_path, path_id)
1165
1222
) ;
1166
1223
let response_instructions = self . offers_handler . handle_message ( msg, responder) ;
1167
- self . handle_onion_message_response ( response_instructions) ;
1224
+ let _ = self . handle_onion_message_response ( response_instructions) ;
1168
1225
} ,
1169
1226
ParsedOnionMessageContents :: Custom ( msg) => {
1170
1227
let responder = reply_path. map (
1171
1228
|reply_path| Responder :: new ( reply_path, path_id)
1172
1229
) ;
1173
1230
let response_instructions = self . custom_handler . handle_custom_message ( msg, responder) ;
1174
- self . handle_onion_message_response ( response_instructions) ;
1231
+ let _ = self . handle_onion_message_response ( response_instructions) ;
1175
1232
} ,
1176
1233
}
1177
1234
} ,
0 commit comments