@@ -23,7 +23,7 @@ use crate::sign::{EntropySource, NodeSigner, Recipient};
2323use crate :: ln:: features:: { InitFeatures , NodeFeatures } ;
2424use crate :: ln:: msgs:: { self , OnionMessage , OnionMessageHandler , SocketAddress } ;
2525use crate :: ln:: onion_utils;
26- use crate :: routing:: gossip:: { NetworkGraph , NodeId } ;
26+ use crate :: routing:: gossip:: { NetworkGraph , NodeId , ReadOnlyNetworkGraph } ;
2727use super :: packet:: OnionMessageContents ;
2828use super :: packet:: ParsedOnionMessageContents ;
2929use super :: offers:: OffersMessageHandler ;
@@ -318,15 +318,21 @@ where
318318 ES :: Target : EntropySource ,
319319{
320320 fn find_path (
321- & self , sender : PublicKey , peers : Vec < PublicKey > , destination : Destination
321+ & self , sender : PublicKey , peers : Vec < PublicKey > , mut destination : Destination
322322 ) -> Result < OnionMessagePath , ( ) > {
323- let first_node = destination. first_node ( ) ;
323+ let network_graph = self . network_graph . deref ( ) . read_only ( ) ;
324+ destination. resolve ( & network_graph) ;
325+
326+ let first_node = match destination. first_node ( ) {
327+ Some ( first_node) => first_node,
328+ None => return Err ( ( ) ) ,
329+ } ;
330+
324331 if peers. contains ( & first_node) || sender == first_node {
325332 Ok ( OnionMessagePath {
326333 intermediate_nodes : vec ! [ ] , destination, first_node_addresses : None
327334 } )
328335 } else {
329- let network_graph = self . network_graph . deref ( ) . read_only ( ) ;
330336 let node_announcement = network_graph
331337 . node ( & NodeId :: from_pubkey ( & first_node) )
332338 . and_then ( |node_info| node_info. announcement_info . as_ref ( ) )
@@ -416,11 +422,11 @@ pub struct OnionMessagePath {
416422
417423impl OnionMessagePath {
418424 /// Returns the first node in the path.
419- pub fn first_node ( & self ) -> PublicKey {
425+ pub fn first_node ( & self ) -> Option < PublicKey > {
420426 self . intermediate_nodes
421427 . first ( )
422428 . copied ( )
423- . unwrap_or_else ( || self . destination . first_node ( ) )
429+ . or_else ( || self . destination . first_node ( ) )
424430 }
425431}
426432
@@ -434,20 +440,36 @@ pub enum Destination {
434440}
435441
436442impl Destination {
443+ /// Attempts to resolve the [`IntroductionNode::DirectedShortChannelId`] of a
444+ /// [`Destination::BlindedPath`] to a [`IntroductionNode::NodeId`], if applicable, using the
445+ /// provided [`ReadOnlyNetworkGraph`].
446+ pub fn resolve ( & mut self , network_graph : & ReadOnlyNetworkGraph ) {
447+ if let Destination :: BlindedPath ( path) = self {
448+ if let IntroductionNode :: DirectedShortChannelId ( ..) = path. introduction_node {
449+ if let Some ( pubkey) = path
450+ . public_introduction_node_id ( network_graph)
451+ . and_then ( |node_id| node_id. as_pubkey ( ) . ok ( ) )
452+ {
453+ path. introduction_node = IntroductionNode :: NodeId ( pubkey) ;
454+ }
455+ }
456+ }
457+ }
458+
437459 pub ( super ) fn num_hops ( & self ) -> usize {
438460 match self {
439461 Destination :: Node ( _) => 1 ,
440462 Destination :: BlindedPath ( BlindedPath { blinded_hops, .. } ) => blinded_hops. len ( ) ,
441463 }
442464 }
443465
444- fn first_node ( & self ) -> PublicKey {
466+ fn first_node ( & self ) -> Option < PublicKey > {
445467 match self {
446- Destination :: Node ( node_id) => * node_id,
468+ Destination :: Node ( node_id) => Some ( * node_id) ,
447469 Destination :: BlindedPath ( BlindedPath { introduction_node, .. } ) => {
448470 match introduction_node {
449- IntroductionNode :: NodeId ( pubkey) => * pubkey,
450- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
471+ IntroductionNode :: NodeId ( pubkey) => Some ( * pubkey) ,
472+ IntroductionNode :: DirectedShortChannelId ( ..) => None ,
451473 }
452474 } ,
453475 }
@@ -492,6 +514,10 @@ pub enum SendError {
492514 ///
493515 /// [`NodeSigner`]: crate::sign::NodeSigner
494516 GetNodeIdFailed ,
517+ /// The provided [`Destination`] has a blinded path with an unresolved introduction node. An
518+ /// attempt to resolve it in the [`MessageRouter`] when finding an [`OnionMessagePath`] likely
519+ /// failed.
520+ UnresolvedIntroductionNode ,
495521 /// We attempted to send to a blinded path where we are the introduction node, and failed to
496522 /// advance the blinded path to make the second hop the new introduction node. Either
497523 /// [`NodeSigner::ecdh`] failed, we failed to tweak the current blinding point to get the
@@ -576,7 +602,9 @@ where
576602 if let Destination :: BlindedPath ( ref mut blinded_path) = destination {
577603 let introduction_node_id = match blinded_path. introduction_node {
578604 IntroductionNode :: NodeId ( pubkey) => pubkey,
579- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
605+ IntroductionNode :: DirectedShortChannelId ( ..) => {
606+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
607+ } ,
580608 } ;
581609 let our_node_id = node_signer. get_node_id ( Recipient :: Node )
582610 . map_err ( |( ) | SendError :: GetNodeIdFailed ) ?;
@@ -597,14 +625,16 @@ where
597625 Destination :: BlindedPath ( BlindedPath { introduction_node, blinding_point, .. } ) => {
598626 match introduction_node {
599627 IntroductionNode :: NodeId ( pubkey) => ( * pubkey, * blinding_point) ,
600- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
628+ IntroductionNode :: DirectedShortChannelId ( ..) => {
629+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
630+ } ,
601631 }
602632 }
603633 }
604634 } ;
605635 let ( packet_payloads, packet_keys) = packet_payloads_and_keys (
606- & secp_ctx, & intermediate_nodes, destination, contents, reply_path, & blinding_secret)
607- . map_err ( |e| SendError :: Secp256k1 ( e ) ) ?;
636+ & secp_ctx, & intermediate_nodes, destination, contents, reply_path, & blinding_secret
637+ ) ?;
608638
609639 let prng_seed = entropy_source. get_secure_random_bytes ( ) ;
610640 let onion_routing_packet = construct_onion_message_packet (
@@ -1144,7 +1174,7 @@ pub type SimpleRefOnionMessenger<
11441174fn packet_payloads_and_keys < T : OnionMessageContents , S : secp256k1:: Signing + secp256k1:: Verification > (
11451175 secp_ctx : & Secp256k1 < S > , unblinded_path : & [ PublicKey ] , destination : Destination , message : T ,
11461176 mut reply_path : Option < BlindedPath > , session_priv : & SecretKey
1147- ) -> Result < ( Vec < ( Payload < T > , [ u8 ; 32 ] ) > , Vec < onion_utils:: OnionKeys > ) , secp256k1 :: Error > {
1177+ ) -> Result < ( Vec < ( Payload < T > , [ u8 ; 32 ] ) > , Vec < onion_utils:: OnionKeys > ) , SendError > {
11481178 let num_hops = unblinded_path. len ( ) + destination. num_hops ( ) ;
11491179 let mut payloads = Vec :: with_capacity ( num_hops) ;
11501180 let mut onion_packet_keys = Vec :: with_capacity ( num_hops) ;
@@ -1154,7 +1184,9 @@ fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + sec
11541184 Destination :: BlindedPath ( BlindedPath { introduction_node, blinding_point, blinded_hops } ) => {
11551185 let introduction_node_id = match introduction_node {
11561186 IntroductionNode :: NodeId ( pubkey) => pubkey,
1157- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
1187+ IntroductionNode :: DirectedShortChannelId ( ..) => {
1188+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
1189+ } ,
11581190 } ;
11591191 ( Some ( ( * introduction_node_id, * blinding_point) ) , blinded_hops. len ( ) )
11601192 } ,
@@ -1206,7 +1238,7 @@ fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + sec
12061238 mu,
12071239 } ) ;
12081240 }
1209- ) ?;
1241+ ) . map_err ( |e| SendError :: Secp256k1 ( e ) ) ?;
12101242
12111243 if let Some ( control_tlvs) = final_control_tlvs {
12121244 payloads. push ( ( Payload :: Receive {
0 commit comments