Skip to content

Commit 206f47e

Browse files
committed
Resolve IntroductionNode::DirectedShortChannelId
When OnionMessenger creates an OnionMessage to a Destination, the latter may contain an IntroductionNode::DirectedShortChannelId inside a BlindedPath. Resolve these in DefaultMessageRouter and handle unresolved ones in OnionMessenger.
1 parent eda709f commit 206f47e

File tree

1 file changed

+55
-18
lines changed

1 file changed

+55
-18
lines changed

lightning/src/onion_message/messenger.rs

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ use bitcoin::hashes::hmac::{Hmac, HmacEngine};
1515
use bitcoin::hashes::sha256::Hash as Sha256;
1616
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
1717

18-
use crate::blinded_path::{BlindedPath, IntroductionNode};
18+
use crate::blinded_path::{BlindedPath, Direction, IntroductionNode};
1919
use crate::blinded_path::message::{advance_path_by_one, ForwardTlvs, NextHop, ReceiveTlvs};
2020
use crate::blinded_path::utils;
2121
use crate::events::{Event, EventHandler, EventsProvider};
2222
use crate::sign::{EntropySource, NodeSigner, Recipient};
2323
use crate::ln::features::{InitFeatures, NodeFeatures};
2424
use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler, SocketAddress};
2525
use crate::ln::onion_utils;
26-
use crate::routing::gossip::{NetworkGraph, NodeId};
26+
use crate::routing::gossip::{NetworkGraph, NodeId, ReadOnlyNetworkGraph};
2727
use super::packet::OnionMessageContents;
2828
use super::packet::ParsedOnionMessageContents;
2929
use 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

417423
impl 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,41 @@ pub enum Destination {
434440
}
435441

436442
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+
437464
pub(super) fn num_hops(&self) -> usize {
438465
match self {
439466
Destination::Node(_) => 1,
440467
Destination::BlindedPath(BlindedPath { blinded_hops, .. }) => blinded_hops.len(),
441468
}
442469
}
443470

444-
fn first_node(&self) -> PublicKey {
471+
fn first_node(&self) -> Option<PublicKey> {
445472
match self {
446-
Destination::Node(node_id) => *node_id,
473+
Destination::Node(node_id) => Some(*node_id),
447474
Destination::BlindedPath(BlindedPath { introduction_node, .. }) => {
448475
match introduction_node {
449-
IntroductionNode::NodeId(pubkey) => *pubkey,
450-
IntroductionNode::DirectedShortChannelId(..) => todo!(),
476+
IntroductionNode::NodeId(pubkey) => Some(*pubkey),
477+
IntroductionNode::DirectedShortChannelId(..) => None,
451478
}
452479
},
453480
}
@@ -492,6 +519,10 @@ pub enum SendError {
492519
///
493520
/// [`NodeSigner`]: crate::sign::NodeSigner
494521
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,
495526
/// We attempted to send to a blinded path where we are the introduction node, and failed to
496527
/// advance the blinded path to make the second hop the new introduction node. Either
497528
/// [`NodeSigner::ecdh`] failed, we failed to tweak the current blinding point to get the
@@ -576,7 +607,9 @@ where
576607
if let Destination::BlindedPath(ref mut blinded_path) = destination {
577608
let introduction_node_id = match blinded_path.introduction_node {
578609
IntroductionNode::NodeId(pubkey) => pubkey,
579-
IntroductionNode::DirectedShortChannelId(..) => todo!(),
610+
IntroductionNode::DirectedShortChannelId(..) => {
611+
return Err(SendError::UnresolvedIntroductionNode);
612+
},
580613
};
581614
let our_node_id = node_signer.get_node_id(Recipient::Node)
582615
.map_err(|()| SendError::GetNodeIdFailed)?;
@@ -597,14 +630,16 @@ where
597630
Destination::BlindedPath(BlindedPath { introduction_node, blinding_point, .. }) => {
598631
match introduction_node {
599632
IntroductionNode::NodeId(pubkey) => (*pubkey, *blinding_point),
600-
IntroductionNode::DirectedShortChannelId(..) => todo!(),
633+
IntroductionNode::DirectedShortChannelId(..) => {
634+
return Err(SendError::UnresolvedIntroductionNode);
635+
},
601636
}
602637
}
603638
}
604639
};
605640
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+
)?;
608643

609644
let prng_seed = entropy_source.get_secure_random_bytes();
610645
let onion_routing_packet = construct_onion_message_packet(
@@ -1131,7 +1166,7 @@ pub type SimpleRefOnionMessenger<
11311166
fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
11321167
secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination, message: T,
11331168
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> {
11351170
let num_hops = unblinded_path.len() + destination.num_hops();
11361171
let mut payloads = Vec::with_capacity(num_hops);
11371172
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
11411176
Destination::BlindedPath(BlindedPath { introduction_node, blinding_point, blinded_hops }) => {
11421177
let introduction_node_id = match introduction_node {
11431178
IntroductionNode::NodeId(pubkey) => pubkey,
1144-
IntroductionNode::DirectedShortChannelId(..) => todo!(),
1179+
IntroductionNode::DirectedShortChannelId(..) => {
1180+
return Err(SendError::UnresolvedIntroductionNode);
1181+
},
11451182
};
11461183
(Some((*introduction_node_id, *blinding_point)), blinded_hops.len())
11471184
},
@@ -1193,7 +1230,7 @@ fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + sec
11931230
mu,
11941231
});
11951232
}
1196-
)?;
1233+
).map_err(|e| SendError::Secp256k1(e))?;
11971234

11981235
if let Some(control_tlvs) = final_control_tlvs {
11991236
payloads.push((Payload::Receive {

0 commit comments

Comments
 (0)