@@ -76,7 +76,14 @@ use crate::prelude::*;
7676/// # struct FakeMessageRouter {}
7777/// # impl MessageRouter for FakeMessageRouter {
7878/// # fn find_path(&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination) -> Result<OnionMessagePath, ()> {
79- /// # unimplemented!()
79+ /// # let secp_ctx = Secp256k1::new();
80+ /// # let node_secret = SecretKey::from_slice(&<Vec<u8>>::from_hex("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
81+ /// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
82+ /// # let hop_node_id2 = hop_node_id1;
83+ /// # Ok(OnionMessagePath {
84+ /// # intermediate_nodes: vec![hop_node_id1, hop_node_id2],
85+ /// # destination,
86+ /// # })
8087/// # }
8188/// # }
8289/// # let seed = [42u8; 32];
@@ -86,7 +93,7 @@ use crate::prelude::*;
8693/// # let node_secret = SecretKey::from_slice(&<Vec<u8>>::from_hex("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
8794/// # let secp_ctx = Secp256k1::new();
8895/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
89- /// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1);
96+ /// # let (hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1);
9097/// # let destination_node_id = hop_node_id1;
9198/// # let message_router = Arc::new(FakeMessageRouter {});
9299/// # let custom_message_handler = IgnoringMessageHandler {};
@@ -113,27 +120,21 @@ use crate::prelude::*;
113120/// }
114121/// }
115122/// // Send a custom onion message to a node id.
116- /// let path = OnionMessagePath {
117- /// intermediate_nodes: vec![hop_node_id1, hop_node_id2],
118- /// destination: Destination::Node(destination_node_id),
119- /// };
123+ /// let destination = Destination::Node(destination_node_id);
120124/// let reply_path = None;
121125/// # let message = YourCustomMessage {};
122- /// onion_messenger.send_onion_message(path, message , reply_path);
126+ /// onion_messenger.send_onion_message(message, destination , reply_path);
123127///
124128/// // Create a blinded path to yourself, for someone to send an onion message to.
125129/// # let your_node_id = hop_node_id1;
126130/// let hops = [hop_node_id3, hop_node_id4, your_node_id];
127131/// let blinded_path = BlindedPath::new_for_message(&hops, &keys_manager, &secp_ctx).unwrap();
128132///
129133/// // Send a custom onion message to a blinded path.
130- /// let path = OnionMessagePath {
131- /// intermediate_nodes: vec![hop_node_id1, hop_node_id2],
132- /// destination: Destination::BlindedPath(blinded_path),
133- /// };
134+ /// let destination = Destination::BlindedPath(blinded_path);
134135/// let reply_path = None;
135136/// # let message = YourCustomMessage {};
136- /// onion_messenger.send_onion_message(path, message , reply_path);
137+ /// onion_messenger.send_onion_message(message, destination , reply_path);
137138/// ```
138139///
139140/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
@@ -304,6 +305,16 @@ impl Destination {
304305 }
305306}
306307
308+ /// Result of successfully [sending an onion message].
309+ ///
310+ /// [sending an onion message]: OnionMessenger::send_onion_message
311+ #[ derive( Debug , PartialEq , Eq ) ]
312+ pub enum SendSuccess {
313+ /// The message was buffered and will be sent once it is processed by
314+ /// [`OnionMessageHandler::next_onion_message_for_peer`].
315+ Buffered ,
316+ }
317+
307318/// Errors that may occur when [sending an onion message].
308319///
309320/// [sending an onion message]: OnionMessenger::send_onion_message
@@ -319,6 +330,8 @@ pub enum SendError {
319330 TooFewBlindedHops ,
320331 /// Our next-hop peer was offline or does not support onion message forwarding.
321332 InvalidFirstHop ,
333+ /// A path from the sender to the destination could not be found by the [`MessageRouter`].
334+ PathNotFound ,
322335 /// Onion message contents must have a TLV type >= 64.
323336 InvalidMessage ,
324337 /// Our next-hop peer's buffer was full or our total outbound buffer was full.
@@ -568,14 +581,63 @@ where
568581 }
569582 }
570583
571- /// Sends an [`OnionMessage`] with the given `contents` for sending to the destination of
572- /// `path`.
584+ /// Sends an [`OnionMessage`] with the given `contents` to `destination`.
573585 ///
574586 /// See [`OnionMessenger`] for example usage.
575587 pub fn send_onion_message < T : OnionMessageContents > (
576- & self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath >
577- ) -> Result < ( ) , SendError > {
578- log_trace ! ( self . logger, "Sending onion message: {:?}" , contents) ;
588+ & self , contents : T , destination : Destination , reply_path : Option < BlindedPath >
589+ ) -> Result < SendSuccess , SendError > {
590+ self . find_path_and_enqueue_onion_message (
591+ contents, destination, reply_path, format_args ! ( "" )
592+ )
593+ }
594+
595+ fn find_path_and_enqueue_onion_message < T : OnionMessageContents > (
596+ & self , contents : T , destination : Destination , reply_path : Option < BlindedPath > ,
597+ log_suffix : fmt:: Arguments
598+ ) -> Result < SendSuccess , SendError > {
599+ let result = self . find_path ( destination)
600+ . and_then ( |path| self . enqueue_onion_message ( path, contents, reply_path, log_suffix) ) ;
601+
602+ match result. as_ref ( ) {
603+ Err ( SendError :: GetNodeIdFailed ) => {
604+ log_warn ! ( self . logger, "Unable to retrieve node id {}" , log_suffix) ;
605+ } ,
606+ Err ( SendError :: PathNotFound ) => {
607+ log_trace ! ( self . logger, "Failed to find path {}" , log_suffix) ;
608+ } ,
609+ Err ( e) => {
610+ log_trace ! ( self . logger, "Failed sending onion message {}: {:?}" , log_suffix, e) ;
611+ } ,
612+ Ok ( SendSuccess :: Buffered ) => {
613+ log_trace ! ( self . logger, "Buffered onion message {}" , log_suffix) ;
614+ } ,
615+ }
616+
617+ result
618+ }
619+
620+ fn find_path ( & self , destination : Destination ) -> Result < OnionMessagePath , SendError > {
621+ let sender = self . node_signer
622+ . get_node_id ( Recipient :: Node )
623+ . map_err ( |_| SendError :: GetNodeIdFailed ) ?;
624+
625+ let peers = self . message_buffers . lock ( ) . unwrap ( )
626+ . iter ( )
627+ . filter ( |( _, buffer) | matches ! ( buffer, OnionMessageBuffer :: ConnectedPeer ( _) ) )
628+ . map ( |( node_id, _) | * node_id)
629+ . collect ( ) ;
630+
631+ self . message_router
632+ . find_path ( sender, peers, destination)
633+ . map_err ( |_| SendError :: PathNotFound )
634+ }
635+
636+ fn enqueue_onion_message < T : OnionMessageContents > (
637+ & self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath > ,
638+ log_suffix : fmt:: Arguments
639+ ) -> Result < SendSuccess , SendError > {
640+ log_trace ! ( self . logger, "Constructing onion message {}: {:?}" , log_suffix, contents) ;
579641
580642 let ( first_node_id, onion_message) = create_onion_message (
581643 & self . entropy_source , & self . node_signer , & self . secp_ctx , path, contents, reply_path
@@ -590,18 +652,25 @@ where
590652 hash_map:: Entry :: Vacant ( _) => Err ( SendError :: InvalidFirstHop ) ,
591653 hash_map:: Entry :: Occupied ( mut e) => {
592654 e. get_mut ( ) . enqueue_message ( onion_message) ;
593- Ok ( ( ) )
655+ Ok ( SendSuccess :: Buffered )
594656 } ,
595657 }
596658 }
597659
660+ #[ cfg( test) ]
661+ pub ( super ) fn send_onion_message_using_path < T : OnionMessageContents > (
662+ & self , path : OnionMessagePath , contents : T , reply_path : Option < BlindedPath >
663+ ) -> Result < SendSuccess , SendError > {
664+ self . enqueue_onion_message ( path, contents, reply_path, format_args ! ( "" ) )
665+ }
666+
598667 fn handle_onion_message_response < T : OnionMessageContents > (
599668 & self , response : Option < T > , reply_path : Option < BlindedPath > , log_suffix : fmt:: Arguments
600669 ) {
601670 if let Some ( response) = response {
602671 match reply_path {
603672 Some ( reply_path) => {
604- self . find_path_and_enqueue_onion_message (
673+ let _ = self . find_path_and_enqueue_onion_message (
605674 response, Destination :: BlindedPath ( reply_path) , None , log_suffix
606675 ) ;
607676 } ,
@@ -612,34 +681,6 @@ where
612681 }
613682 }
614683
615- fn find_path_and_enqueue_onion_message < T : OnionMessageContents > (
616- & self , contents : T , destination : Destination , reply_path : Option < BlindedPath > ,
617- log_suffix : fmt:: Arguments
618- ) {
619- let sender = match self . node_signer . get_node_id ( Recipient :: Node ) {
620- Ok ( node_id) => node_id,
621- Err ( _) => {
622- log_warn ! ( self . logger, "Unable to retrieve node id {}" , log_suffix) ;
623- return ;
624- }
625- } ;
626-
627- let peers = self . message_buffers . lock ( ) . unwrap ( ) . keys ( ) . copied ( ) . collect ( ) ;
628- let path = match self . message_router . find_path ( sender, peers, destination) {
629- Ok ( path) => path,
630- Err ( ( ) ) => {
631- log_trace ! ( self . logger, "Failed to find path {}" , log_suffix) ;
632- return ;
633- } ,
634- } ;
635-
636- log_trace ! ( self . logger, "Sending onion message {}: {:?}" , log_suffix, contents) ;
637-
638- if let Err ( e) = self . send_onion_message ( path, contents, reply_path) {
639- log_trace ! ( self . logger, "Failed sending onion message {}: {:?}" , log_suffix, e) ;
640- }
641- }
642-
643684 #[ cfg( test) ]
644685 pub ( super ) fn release_pending_msgs ( & self ) -> HashMap < PublicKey , VecDeque < OnionMessage > > {
645686 let mut message_buffers = self . message_buffers . lock ( ) . unwrap ( ) ;
@@ -790,7 +831,7 @@ where
790831 let PendingOnionMessage { contents, destination, reply_path } = message;
791832 #[ cfg( c_bindings) ]
792833 let ( contents, destination, reply_path) = message;
793- self . find_path_and_enqueue_onion_message (
834+ let _ = self . find_path_and_enqueue_onion_message (
794835 contents, destination, reply_path, format_args ! ( "when sending OffersMessage" )
795836 ) ;
796837 }
@@ -801,7 +842,7 @@ where
801842 let PendingOnionMessage { contents, destination, reply_path } = message;
802843 #[ cfg( c_bindings) ]
803844 let ( contents, destination, reply_path) = message;
804- self . find_path_and_enqueue_onion_message (
845+ let _ = self . find_path_and_enqueue_onion_message (
805846 contents, destination, reply_path, format_args ! ( "when sending CustomMessage" )
806847 ) ;
807848 }
0 commit comments