@@ -23,7 +23,7 @@ use crate::sign::{EntropySource, NodeSigner, Recipient};
23
23
use crate :: ln:: features:: { InitFeatures , NodeFeatures } ;
24
24
use crate :: ln:: msgs:: { self , OnionMessage , OnionMessageHandler , SocketAddress } ;
25
25
use crate :: ln:: onion_utils;
26
- use crate :: routing:: gossip:: { NetworkGraph , NodeId } ;
26
+ use crate :: routing:: gossip:: { NetworkGraph , NodeId , ReadOnlyNetworkGraph } ;
27
27
use super :: packet:: OnionMessageContents ;
28
28
use super :: packet:: ParsedOnionMessageContents ;
29
29
use super :: offers:: OffersMessageHandler ;
@@ -318,15 +318,21 @@ where
318
318
ES :: Target : EntropySource ,
319
319
{
320
320
fn find_path (
321
- & self , sender : PublicKey , peers : Vec < PublicKey > , destination : Destination
321
+ & self , sender : PublicKey , peers : Vec < PublicKey > , mut destination : Destination
322
322
) -> 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
+
324
331
if peers. contains ( & first_node) || sender == first_node {
325
332
Ok ( OnionMessagePath {
326
333
intermediate_nodes : vec ! [ ] , destination, first_node_addresses : None
327
334
} )
328
335
} else {
329
- let network_graph = self . network_graph . deref ( ) . read_only ( ) ;
330
336
let node_announcement = network_graph
331
337
. node ( & NodeId :: from_pubkey ( & first_node) )
332
338
. and_then ( |node_info| node_info. announcement_info . as_ref ( ) )
@@ -416,11 +422,11 @@ pub struct OnionMessagePath {
416
422
417
423
impl OnionMessagePath {
418
424
/// Returns the first node in the path.
419
- pub fn first_node ( & self ) -> PublicKey {
425
+ pub fn first_node ( & self ) -> Option < PublicKey > {
420
426
self . intermediate_nodes
421
427
. first ( )
422
428
. copied ( )
423
- . unwrap_or_else ( || self . destination . first_node ( ) )
429
+ . or_else ( || self . destination . first_node ( ) )
424
430
}
425
431
}
426
432
@@ -434,20 +440,36 @@ pub enum Destination {
434
440
}
435
441
436
442
impl 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
+
437
459
pub ( super ) fn num_hops ( & self ) -> usize {
438
460
match self {
439
461
Destination :: Node ( _) => 1 ,
440
462
Destination :: BlindedPath ( BlindedPath { blinded_hops, .. } ) => blinded_hops. len ( ) ,
441
463
}
442
464
}
443
465
444
- fn first_node ( & self ) -> PublicKey {
466
+ fn first_node ( & self ) -> Option < PublicKey > {
445
467
match self {
446
- Destination :: Node ( node_id) => * node_id,
468
+ Destination :: Node ( node_id) => Some ( * node_id) ,
447
469
Destination :: BlindedPath ( BlindedPath { introduction_node, .. } ) => {
448
470
match introduction_node {
449
- IntroductionNode :: NodeId ( pubkey) => * pubkey,
450
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
471
+ IntroductionNode :: NodeId ( pubkey) => Some ( * pubkey) ,
472
+ IntroductionNode :: DirectedShortChannelId ( ..) => None ,
451
473
}
452
474
} ,
453
475
}
@@ -492,6 +514,10 @@ pub enum SendError {
492
514
///
493
515
/// [`NodeSigner`]: crate::sign::NodeSigner
494
516
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 ,
495
521
/// We attempted to send to a blinded path where we are the introduction node, and failed to
496
522
/// advance the blinded path to make the second hop the new introduction node. Either
497
523
/// [`NodeSigner::ecdh`] failed, we failed to tweak the current blinding point to get the
@@ -576,7 +602,9 @@ where
576
602
if let Destination :: BlindedPath ( ref mut blinded_path) = destination {
577
603
let introduction_node_id = match blinded_path. introduction_node {
578
604
IntroductionNode :: NodeId ( pubkey) => pubkey,
579
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
605
+ IntroductionNode :: DirectedShortChannelId ( ..) => {
606
+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
607
+ } ,
580
608
} ;
581
609
let our_node_id = node_signer. get_node_id ( Recipient :: Node )
582
610
. map_err ( |( ) | SendError :: GetNodeIdFailed ) ?;
@@ -597,14 +625,16 @@ where
597
625
Destination :: BlindedPath ( BlindedPath { introduction_node, blinding_point, .. } ) => {
598
626
match introduction_node {
599
627
IntroductionNode :: NodeId ( pubkey) => ( * pubkey, * blinding_point) ,
600
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
628
+ IntroductionNode :: DirectedShortChannelId ( ..) => {
629
+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
630
+ } ,
601
631
}
602
632
}
603
633
}
604
634
} ;
605
635
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
+ ) ?;
608
638
609
639
let prng_seed = entropy_source. get_secure_random_bytes ( ) ;
610
640
let onion_routing_packet = construct_onion_message_packet (
@@ -1144,7 +1174,7 @@ pub type SimpleRefOnionMessenger<
1144
1174
fn packet_payloads_and_keys < T : OnionMessageContents , S : secp256k1:: Signing + secp256k1:: Verification > (
1145
1175
secp_ctx : & Secp256k1 < S > , unblinded_path : & [ PublicKey ] , destination : Destination , message : T ,
1146
1176
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 > {
1148
1178
let num_hops = unblinded_path. len ( ) + destination. num_hops ( ) ;
1149
1179
let mut payloads = Vec :: with_capacity ( num_hops) ;
1150
1180
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
1154
1184
Destination :: BlindedPath ( BlindedPath { introduction_node, blinding_point, blinded_hops } ) => {
1155
1185
let introduction_node_id = match introduction_node {
1156
1186
IntroductionNode :: NodeId ( pubkey) => pubkey,
1157
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
1187
+ IntroductionNode :: DirectedShortChannelId ( ..) => {
1188
+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
1189
+ } ,
1158
1190
} ;
1159
1191
( Some ( ( * introduction_node_id, * blinding_point) ) , blinded_hops. len ( ) )
1160
1192
} ,
@@ -1206,7 +1238,7 @@ fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + sec
1206
1238
mu,
1207
1239
} ) ;
1208
1240
}
1209
- ) ?;
1241
+ ) . map_err ( |e| SendError :: Secp256k1 ( e ) ) ?;
1210
1242
1211
1243
if let Some ( control_tlvs) = final_control_tlvs {
1212
1244
payloads. push ( ( Payload :: Receive {
0 commit comments