@@ -15,15 +15,15 @@ use bitcoin::hashes::hmac::{Hmac, HmacEngine};
15
15
use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
16
16
use bitcoin:: secp256k1:: { self , PublicKey , Scalar , Secp256k1 , SecretKey } ;
17
17
18
- use crate :: blinded_path:: { BlindedPath , IntroductionNode } ;
18
+ use crate :: blinded_path:: { BlindedPath , Direction , IntroductionNode } ;
19
19
use crate :: blinded_path:: message:: { advance_path_by_one, ForwardTlvs , NextHop , ReceiveTlvs } ;
20
20
use crate :: blinded_path:: utils;
21
21
use crate :: events:: { Event , EventHandler , EventsProvider } ;
22
22
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,41 @@ 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
+ let introduction_node = & mut path. introduction_node ;
449
+ if let IntroductionNode :: DirectedShortChannelId ( direction, scid) = introduction_node {
450
+ let pubkey = network_graph
451
+ . channel ( * scid)
452
+ . map ( |c| match direction {
453
+ Direction :: NodeOne => c. node_one ,
454
+ Direction :: NodeTwo => c. node_two ,
455
+ } )
456
+ . and_then ( |node_id| node_id. as_pubkey ( ) . ok ( ) ) ;
457
+ if let Some ( pubkey) = pubkey {
458
+ * introduction_node = IntroductionNode :: NodeId ( pubkey) ;
459
+ }
460
+ }
461
+ }
462
+ }
463
+
437
464
pub ( super ) fn num_hops ( & self ) -> usize {
438
465
match self {
439
466
Destination :: Node ( _) => 1 ,
440
467
Destination :: BlindedPath ( BlindedPath { blinded_hops, .. } ) => blinded_hops. len ( ) ,
441
468
}
442
469
}
443
470
444
- fn first_node ( & self ) -> PublicKey {
471
+ fn first_node ( & self ) -> Option < PublicKey > {
445
472
match self {
446
- Destination :: Node ( node_id) => * node_id,
473
+ Destination :: Node ( node_id) => Some ( * node_id) ,
447
474
Destination :: BlindedPath ( BlindedPath { introduction_node, .. } ) => {
448
475
match introduction_node {
449
- IntroductionNode :: NodeId ( pubkey) => * pubkey,
450
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
476
+ IntroductionNode :: NodeId ( pubkey) => Some ( * pubkey) ,
477
+ IntroductionNode :: DirectedShortChannelId ( ..) => None ,
451
478
}
452
479
} ,
453
480
}
@@ -492,6 +519,10 @@ pub enum SendError {
492
519
///
493
520
/// [`NodeSigner`]: crate::sign::NodeSigner
494
521
GetNodeIdFailed ,
522
+ /// The provided [`Destination`] has a blinded path with an unresolved introduction node. An
523
+ /// attempt to resolved it in the [`MessageRouter`] when finding an [`OnionMessagePath`] likely
524
+ /// failed.
525
+ UnresolvedIntroductionNode ,
495
526
/// We attempted to send to a blinded path where we are the introduction node, and failed to
496
527
/// advance the blinded path to make the second hop the new introduction node. Either
497
528
/// [`NodeSigner::ecdh`] failed, we failed to tweak the current blinding point to get the
@@ -576,7 +607,9 @@ where
576
607
if let Destination :: BlindedPath ( ref mut blinded_path) = destination {
577
608
let introduction_node_id = match blinded_path. introduction_node {
578
609
IntroductionNode :: NodeId ( pubkey) => pubkey,
579
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
610
+ IntroductionNode :: DirectedShortChannelId ( ..) => {
611
+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
612
+ } ,
580
613
} ;
581
614
let our_node_id = node_signer. get_node_id ( Recipient :: Node )
582
615
. map_err ( |( ) | SendError :: GetNodeIdFailed ) ?;
@@ -597,14 +630,16 @@ where
597
630
Destination :: BlindedPath ( BlindedPath { introduction_node, blinding_point, .. } ) => {
598
631
match introduction_node {
599
632
IntroductionNode :: NodeId ( pubkey) => ( * pubkey, * blinding_point) ,
600
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
633
+ IntroductionNode :: DirectedShortChannelId ( ..) => {
634
+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
635
+ } ,
601
636
}
602
637
}
603
638
}
604
639
} ;
605
640
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 ) ) ?;
641
+ & secp_ctx, & intermediate_nodes, destination, contents, reply_path, & blinding_secret
642
+ ) ?;
608
643
609
644
let prng_seed = entropy_source. get_secure_random_bytes ( ) ;
610
645
let onion_routing_packet = construct_onion_message_packet (
@@ -1131,7 +1166,7 @@ pub type SimpleRefOnionMessenger<
1131
1166
fn packet_payloads_and_keys < T : OnionMessageContents , S : secp256k1:: Signing + secp256k1:: Verification > (
1132
1167
secp_ctx : & Secp256k1 < S > , unblinded_path : & [ PublicKey ] , destination : Destination , message : T ,
1133
1168
mut reply_path : Option < BlindedPath > , session_priv : & SecretKey
1134
- ) -> Result < ( Vec < ( Payload < T > , [ u8 ; 32 ] ) > , Vec < onion_utils:: OnionKeys > ) , secp256k1 :: Error > {
1169
+ ) -> Result < ( Vec < ( Payload < T > , [ u8 ; 32 ] ) > , Vec < onion_utils:: OnionKeys > ) , SendError > {
1135
1170
let num_hops = unblinded_path. len ( ) + destination. num_hops ( ) ;
1136
1171
let mut payloads = Vec :: with_capacity ( num_hops) ;
1137
1172
let mut onion_packet_keys = Vec :: with_capacity ( num_hops) ;
@@ -1141,7 +1176,9 @@ fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + sec
1141
1176
Destination :: BlindedPath ( BlindedPath { introduction_node, blinding_point, blinded_hops } ) => {
1142
1177
let introduction_node_id = match introduction_node {
1143
1178
IntroductionNode :: NodeId ( pubkey) => pubkey,
1144
- IntroductionNode :: DirectedShortChannelId ( ..) => todo ! ( ) ,
1179
+ IntroductionNode :: DirectedShortChannelId ( ..) => {
1180
+ return Err ( SendError :: UnresolvedIntroductionNode ) ;
1181
+ } ,
1145
1182
} ;
1146
1183
( Some ( ( * introduction_node_id, * blinding_point) ) , blinded_hops. len ( ) )
1147
1184
} ,
@@ -1193,7 +1230,7 @@ fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + sec
1193
1230
mu,
1194
1231
} ) ;
1195
1232
}
1196
- ) ?;
1233
+ ) . map_err ( |e| SendError :: Secp256k1 ( e ) ) ?;
1197
1234
1198
1235
if let Some ( control_tlvs) = final_control_tlvs {
1199
1236
payloads. push ( ( Payload :: Receive {
0 commit comments