@@ -224,8 +224,10 @@ pub trait CustomOnionMessageHandler {
224
224
/// The message known to the handler. To support multiple message types, you may want to make this
225
225
/// an enum with a variant for each supported message.
226
226
type CustomMessage : CustomOnionMessageContents ;
227
- /// Called with the custom message that was received.
228
- fn handle_custom_message ( & self , msg : Self :: CustomMessage ) ;
227
+
228
+ /// Called with the custom message that was received, returning a response to send, if any.
229
+ fn handle_custom_message ( & self , msg : Self :: CustomMessage ) -> Option < Self :: CustomMessage > ;
230
+
229
231
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
230
232
/// message type is unknown.
231
233
fn read_custom_message < R : io:: Read > ( & self , message_type : u64 , buffer : & mut R ) -> Result < Option < Self :: CustomMessage > , msgs:: DecodeError > ;
@@ -320,6 +322,56 @@ where
320
322
}
321
323
}
322
324
325
+ fn respond_with_onion_message < T : CustomOnionMessageContents > (
326
+ & self , response : OnionMessageContents < T > , path_id : Option < [ u8 ; 32 ] > ,
327
+ reply_path : Option < BlindedPath >
328
+ ) {
329
+ let sender = match self . node_signer . get_node_id ( Recipient :: Node ) {
330
+ Ok ( node_id) => node_id,
331
+ Err ( _) => {
332
+ log_warn ! (
333
+ self . logger, "Unable to retrieve node id when responding to onion message with \
334
+ path_id {:02x?}", path_id
335
+ ) ;
336
+ return ;
337
+ }
338
+ } ;
339
+
340
+ let peers = self . pending_messages . lock ( ) . unwrap ( ) . keys ( ) . copied ( ) . collect ( ) ;
341
+
342
+ let destination = match reply_path {
343
+ Some ( reply_path) => Destination :: BlindedPath ( reply_path) ,
344
+ None => {
345
+ log_trace ! (
346
+ self . logger, "Missing reply path when responding to onion message with path_id \
347
+ {:02x?}", path_id
348
+ ) ;
349
+ return ;
350
+ } ,
351
+ } ;
352
+
353
+ let path = match self . message_router . find_path ( sender, peers, destination) {
354
+ Ok ( path) => path,
355
+ Err ( ( ) ) => {
356
+ log_trace ! (
357
+ self . logger, "Failed to find path when responding to onion message with \
358
+ path_id {:02x?}", path_id
359
+ ) ;
360
+ return ;
361
+ } ,
362
+ } ;
363
+
364
+ log_trace ! ( self . logger, "Responding to onion message with path_id {:02x?}" , path_id) ;
365
+
366
+ if let Err ( e) = self . send_onion_message ( path, response, None ) {
367
+ log_trace ! (
368
+ self . logger, "Failed responding to onion message with path_id {:02x?}: {:?}" ,
369
+ path_id, e
370
+ ) ;
371
+ return ;
372
+ }
373
+ }
374
+
323
375
#[ cfg( test) ]
324
376
pub ( super ) fn release_pending_msgs ( & self ) -> HashMap < PublicKey , VecDeque < msgs:: OnionMessage > > {
325
377
let mut pending_msgs = self . pending_messages . lock ( ) . unwrap ( ) ;
@@ -403,9 +455,20 @@ where
403
455
log_info!( self . logger,
404
456
"Received an onion message with path_id {:02x?} and {} reply_path" ,
405
457
path_id, if reply_path. is_some ( ) { "a" } else { "no" } ) ;
406
- match message {
407
- OnionMessageContents :: Offers ( msg) => self . offers_handler . handle_message ( msg) ,
408
- OnionMessageContents :: Custom ( msg) => self . custom_handler . handle_custom_message ( msg) ,
458
+
459
+ let response = match message {
460
+ OnionMessageContents :: Offers ( msg) => {
461
+ self . offers_handler . handle_message ( msg)
462
+ . map ( |msg| OnionMessageContents :: Offers ( msg) )
463
+ } ,
464
+ OnionMessageContents :: Custom ( msg) => {
465
+ self . custom_handler . handle_custom_message ( msg)
466
+ . map ( |msg| OnionMessageContents :: Custom ( msg) )
467
+ } ,
468
+ } ;
469
+
470
+ if let Some ( response) = response {
471
+ self. respond_with_onion_message ( response, path_id, reply_path) ;
409
472
}
410
473
} ,
411
474
Ok ( ( Payload :: Forward ( ForwardControlTlvs :: Unblinded ( ForwardTlvs {
0 commit comments