Look up node id from scid in OnionMessenger

When forwarding onion messages, the next node may be represented by a
short channel id instead of a node id. Parameterize OnionMessenger with
a NodeIdLookUp trait to find which node is the next hop. Implement the
trait for ChannelManager for forwarding to channel counterparties.

Also use this trait when advancing a blinded path one hop when the
sender is the introduction node.
This commit is contained in:
Jeffrey Czyz 2024-03-20 14:31:30 -05:00
parent 32a5139eb5
commit 9f1ffab24c
No known key found for this signature in database
GPG key ID: 912EF12EA67705F5
7 changed files with 127 additions and 41 deletions

View file

@ -6,7 +6,7 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1::ecdsa::RecoverableSignature; use bitcoin::secp256k1::ecdsa::RecoverableSignature;
use bitcoin::secp256k1::schnorr; use bitcoin::secp256k1::schnorr;
use lightning::blinded_path::BlindedPath; use lightning::blinded_path::{BlindedPath, EmptyNodeIdLookUp};
use lightning::ln::features::InitFeatures; use lightning::ln::features::InitFeatures;
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler}; use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
use lightning::ln::script::ShutdownScript; use lightning::ln::script::ShutdownScript;
@ -36,12 +36,13 @@ pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
node_secret: secret, node_secret: secret,
counter: AtomicU64::new(0), counter: AtomicU64::new(0),
}; };
let node_id_lookup = EmptyNodeIdLookUp {};
let message_router = TestMessageRouter {}; let message_router = TestMessageRouter {};
let offers_msg_handler = TestOffersMessageHandler {}; let offers_msg_handler = TestOffersMessageHandler {};
let custom_msg_handler = TestCustomMessageHandler {}; let custom_msg_handler = TestCustomMessageHandler {};
let onion_messenger = OnionMessenger::new( let onion_messenger = OnionMessenger::new(
&keys_manager, &keys_manager, logger, &message_router, &offers_msg_handler, &keys_manager, &keys_manager, logger, &node_id_lookup, &message_router,
&custom_msg_handler &offers_msg_handler, &custom_msg_handler
); );
let peer_node_id = { let peer_node_id = {

View file

@ -3,7 +3,7 @@ use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::prelude::*; use crate::prelude::*;
use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode}; use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode, NodeIdLookUp};
use crate::blinded_path::utils; use crate::blinded_path::utils;
use crate::io; use crate::io;
use crate::io::Cursor; use crate::io::Cursor;
@ -84,9 +84,14 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
// Advance the blinded onion message path by one hop, so make the second hop into the new // Advance the blinded onion message path by one hop, so make the second hop into the new
// introduction node. // introduction node.
pub(crate) fn advance_path_by_one<NS: Deref, T: secp256k1::Signing + secp256k1::Verification>( pub(crate) fn advance_path_by_one<NS: Deref, NL: Deref, T>(
path: &mut BlindedPath, node_signer: &NS, secp_ctx: &Secp256k1<T> path: &mut BlindedPath, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1<T>
) -> Result<(), ()> where NS::Target: NodeSigner { ) -> Result<(), ()>
where
NS::Target: NodeSigner,
NL::Target: NodeIdLookUp,
T: secp256k1::Signing + secp256k1::Verification,
{
let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &path.blinding_point, None)?; let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &path.blinding_point, None)?;
let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes()); let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes());
let encrypted_control_tlvs = path.blinded_hops.remove(0).encrypted_payload; let encrypted_control_tlvs = path.blinded_hops.remove(0).encrypted_payload;
@ -98,7 +103,10 @@ pub(crate) fn advance_path_by_one<NS: Deref, T: secp256k1::Signing + secp256k1::
}) => { }) => {
let next_node_id = match next_hop { let next_node_id = match next_hop {
NextHop::NodeId(pubkey) => pubkey, NextHop::NodeId(pubkey) => pubkey,
NextHop::ShortChannelId(_) => todo!(), NextHop::ShortChannelId(scid) => match node_id_lookup.next_node_id(scid) {
Some(pubkey) => pubkey,
None => return Err(()),
},
}; };
let mut new_blinding_point = match next_blinding_override { let mut new_blinding_point = match next_blinding_override {
Some(blinding_point) => blinding_point, Some(blinding_point) => blinding_point,

View file

@ -58,7 +58,7 @@ pub enum IntroductionNode {
/// ///
/// [BOLT 7]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_announcement-message /// [BOLT 7]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_announcement-message
/// [`ChannelAnnouncement`]: crate::ln::msgs::ChannelAnnouncement /// [`ChannelAnnouncement`]: crate::ln::msgs::ChannelAnnouncement
#[derive(Clone, Debug, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum Direction { pub enum Direction {
/// The lesser node id when compared lexicographically in ascending order. /// The lesser node id when compared lexicographically in ascending order.
NodeOne, NodeOne,
@ -66,6 +66,29 @@ pub enum Direction {
NodeTwo, NodeTwo,
} }
/// An interface for looking up the node id of a channel counterparty for the purpose of forwarding
/// an [`OnionMessage`].
///
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
pub trait NodeIdLookUp {
/// Returns the node id of the forwarding node's channel counterparty with `short_channel_id`.
///
/// Here, the forwarding node is referring to the node of the [`OnionMessenger`] parameterized
/// by the [`NodeIdLookUp`] and the counterparty to one of that node's peers.
///
/// [`OnionMessenger`]: crate::onion_message::messenger::OnionMessenger
fn next_node_id(&self, short_channel_id: u64) -> Option<PublicKey>;
}
/// A [`NodeIdLookUp`] that always returns `None`.
pub struct EmptyNodeIdLookUp {}
impl NodeIdLookUp for EmptyNodeIdLookUp {
fn next_node_id(&self, _short_channel_id: u64) -> Option<PublicKey> {
None
}
}
/// An encrypted payload and node id corresponding to a hop in a payment or onion message path, to /// An encrypted payload and node id corresponding to a hop in a payment or onion message path, to
/// be encoded in the sender's onion packet. These hops cannot be identified by outside observers /// be encoded in the sender's onion packet. These hops cannot be identified by outside observers
/// and thus can be used to hide the identity of the recipient. /// and thus can be used to hide the identity of the recipient.
@ -238,4 +261,17 @@ impl Direction {
Direction::NodeTwo => core::cmp::max(node_a, node_b), Direction::NodeTwo => core::cmp::max(node_a, node_b),
} }
} }
/// Returns the [`PublicKey`] from the inputs corresponding to the direction.
pub fn select_pubkey<'a>(&self, node_a: &'a PublicKey, node_b: &'a PublicKey) -> &'a PublicKey {
let (node_one, node_two) = if NodeId::from_pubkey(node_a) < NodeId::from_pubkey(node_b) {
(node_a, node_b)
} else {
(node_b, node_a)
};
match self {
Direction::NodeOne => node_one,
Direction::NodeTwo => node_two,
}
}
} }

View file

@ -31,7 +31,7 @@ use bitcoin::secp256k1::{SecretKey,PublicKey};
use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::Secp256k1;
use bitcoin::{secp256k1, Sequence}; use bitcoin::{secp256k1, Sequence};
use crate::blinded_path::BlindedPath; use crate::blinded_path::{BlindedPath, NodeIdLookUp};
use crate::blinded_path::payment::{PaymentConstraints, ReceiveTlvs}; use crate::blinded_path::payment::{PaymentConstraints, ReceiveTlvs};
use crate::chain; use crate::chain;
use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock}; use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
@ -10433,6 +10433,23 @@ where
} }
} }
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
NodeIdLookUp for ChannelManager<M, T, ES, NS, SP, F, R, L>
where
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
SP::Target: SignerProvider,
F::Target: FeeEstimator,
R::Target: Router,
L::Target: Logger,
{
fn next_node_id(&self, short_channel_id: u64) -> Option<PublicKey> {
self.short_to_chan_info.read().unwrap().get(&short_channel_id).map(|(pubkey, _)| *pubkey)
}
}
/// Fetches the set of [`NodeFeatures`] flags that are provided by or required by /// Fetches the set of [`NodeFeatures`] flags that are provided by or required by
/// [`ChannelManager`]. /// [`ChannelManager`].
pub(crate) fn provided_node_features(config: &UserConfig) -> NodeFeatures { pub(crate) fn provided_node_features(config: &UserConfig) -> NodeFeatures {

View file

@ -415,6 +415,7 @@ type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger<
DedicatedEntropy, DedicatedEntropy,
&'node_cfg test_utils::TestKeysInterface, &'node_cfg test_utils::TestKeysInterface,
&'chan_mon_cfg test_utils::TestLogger, &'chan_mon_cfg test_utils::TestLogger,
&'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
&'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>, &'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>,
&'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>, &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
IgnoringMessageHandler, IgnoringMessageHandler,
@ -3199,8 +3200,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
for i in 0..node_count { for i in 0..node_count {
let dedicated_entropy = DedicatedEntropy(RandomBytes::new([i as u8; 32])); let dedicated_entropy = DedicatedEntropy(RandomBytes::new([i as u8; 32]));
let onion_messenger = OnionMessenger::new( let onion_messenger = OnionMessenger::new(
dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &cfgs[i].message_router, dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &chan_mgrs[i],
&chan_mgrs[i], IgnoringMessageHandler {}, &cfgs[i].message_router, &chan_mgrs[i], IgnoringMessageHandler {},
); );
let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger); let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger);
let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap())); let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap()));

View file

@ -9,7 +9,7 @@
//! Onion message testing and test utilities live here. //! Onion message testing and test utilities live here.
use crate::blinded_path::BlindedPath; use crate::blinded_path::{BlindedPath, EmptyNodeIdLookUp};
use crate::events::{Event, EventsProvider}; use crate::events::{Event, EventsProvider};
use crate::ln::features::{ChannelFeatures, InitFeatures}; use crate::ln::features::{ChannelFeatures, InitFeatures};
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler}; use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
@ -42,6 +42,7 @@ struct MessengerNode {
Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestKeysInterface>,
Arc<test_utils::TestNodeSigner>, Arc<test_utils::TestNodeSigner>,
Arc<test_utils::TestLogger>, Arc<test_utils::TestLogger>,
Arc<EmptyNodeIdLookUp>,
Arc<DefaultMessageRouter< Arc<DefaultMessageRouter<
Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
Arc<test_utils::TestLogger>, Arc<test_utils::TestLogger>,
@ -175,6 +176,7 @@ fn create_nodes_using_secrets(secrets: Vec<SecretKey>) -> Vec<MessengerNode> {
let entropy_source = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet)); let entropy_source = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet));
let node_signer = Arc::new(test_utils::TestNodeSigner::new(secret_key)); let node_signer = Arc::new(test_utils::TestNodeSigner::new(secret_key));
let node_id_lookup = Arc::new(EmptyNodeIdLookUp {});
let message_router = Arc::new( let message_router = Arc::new(
DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone()) DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone())
); );
@ -185,7 +187,7 @@ fn create_nodes_using_secrets(secrets: Vec<SecretKey>) -> Vec<MessengerNode> {
node_id: node_signer.get_node_id(Recipient::Node).unwrap(), node_id: node_signer.get_node_id(Recipient::Node).unwrap(),
entropy_source: entropy_source.clone(), entropy_source: entropy_source.clone(),
messenger: OnionMessenger::new( messenger: OnionMessenger::new(
entropy_source, node_signer, logger.clone(), message_router, entropy_source, node_signer, logger.clone(), node_id_lookup, message_router,
offers_message_handler, custom_message_handler.clone() offers_message_handler, custom_message_handler.clone()
), ),
custom_message_handler, custom_message_handler,

View file

@ -15,7 +15,7 @@ use bitcoin::hashes::hmac::{Hmac, HmacEngine};
use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey}; use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
use crate::blinded_path::{BlindedPath, IntroductionNode}; use crate::blinded_path::{BlindedPath, IntroductionNode, NodeIdLookUp};
use crate::blinded_path::message::{advance_path_by_one, ForwardTlvs, NextHop, ReceiveTlvs}; use crate::blinded_path::message::{advance_path_by_one, ForwardTlvs, NextHop, ReceiveTlvs};
use crate::blinded_path::utils; use crate::blinded_path::utils;
use crate::events::{Event, EventHandler, EventsProvider}; use crate::events::{Event, EventHandler, EventsProvider};
@ -70,7 +70,7 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
/// # use bitcoin::hashes::_export::_core::time::Duration; /// # use bitcoin::hashes::_export::_core::time::Duration;
/// # use bitcoin::hashes::hex::FromHex; /// # use bitcoin::hashes::hex::FromHex;
/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self}; /// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self};
/// # use lightning::blinded_path::BlindedPath; /// # use lightning::blinded_path::{BlindedPath, EmptyNodeIdLookUp};
/// # use lightning::sign::{EntropySource, KeysManager}; /// # use lightning::sign::{EntropySource, KeysManager};
/// # use lightning::ln::peer_handler::IgnoringMessageHandler; /// # use lightning::ln::peer_handler::IgnoringMessageHandler;
/// # use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath, OnionMessenger}; /// # use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath, OnionMessenger};
@ -111,14 +111,15 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret); /// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
/// # let (hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1); /// # let (hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1);
/// # let destination_node_id = hop_node_id1; /// # let destination_node_id = hop_node_id1;
/// # let node_id_lookup = EmptyNodeIdLookUp {};
/// # let message_router = Arc::new(FakeMessageRouter {}); /// # let message_router = Arc::new(FakeMessageRouter {});
/// # let custom_message_handler = IgnoringMessageHandler {}; /// # let custom_message_handler = IgnoringMessageHandler {};
/// # let offers_message_handler = IgnoringMessageHandler {}; /// # let offers_message_handler = IgnoringMessageHandler {};
/// // Create the onion messenger. This must use the same `keys_manager` as is passed to your /// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
/// // ChannelManager. /// // ChannelManager.
/// let onion_messenger = OnionMessenger::new( /// let onion_messenger = OnionMessenger::new(
/// &keys_manager, &keys_manager, logger, message_router, &offers_message_handler, /// &keys_manager, &keys_manager, logger, &node_id_lookup, message_router,
/// &custom_message_handler /// &offers_message_handler, &custom_message_handler
/// ); /// );
/// # #[derive(Debug)] /// # #[derive(Debug)]
@ -155,11 +156,12 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
/// ///
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref>
where where
ES::Target: EntropySource, ES::Target: EntropySource,
NS::Target: NodeSigner, NS::Target: NodeSigner,
L::Target: Logger, L::Target: Logger,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter, MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler, OMH::Target: OffersMessageHandler,
CMH::Target: CustomOnionMessageHandler, CMH::Target: CustomOnionMessageHandler,
@ -169,6 +171,7 @@ where
logger: L, logger: L,
message_recipients: Mutex<HashMap<PublicKey, OnionMessageRecipient>>, message_recipients: Mutex<HashMap<PublicKey, OnionMessageRecipient>>,
secp_ctx: Secp256k1<secp256k1::All>, secp_ctx: Secp256k1<secp256k1::All>,
node_id_lookup: NL,
message_router: MR, message_router: MR,
offers_handler: OMH, offers_handler: OMH,
custom_handler: CMH, custom_handler: CMH,
@ -579,13 +582,15 @@ pub enum PeeledOnion<T: OnionMessageContents> {
/// ///
/// Returns the node id of the peer to send the message to, the message itself, and any addresses /// Returns the node id of the peer to send the message to, the message itself, and any addresses
/// need to connect to the first node. /// need to connect to the first node.
pub fn create_onion_message<ES: Deref, NS: Deref, T: OnionMessageContents>( pub fn create_onion_message<ES: Deref, NS: Deref, NL: Deref, T: OnionMessageContents>(
entropy_source: &ES, node_signer: &NS, secp_ctx: &Secp256k1<secp256k1::All>, entropy_source: &ES, node_signer: &NS, node_id_lookup: &NL,
path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>, secp_ctx: &Secp256k1<secp256k1::All>, path: OnionMessagePath, contents: T,
reply_path: Option<BlindedPath>,
) -> Result<(PublicKey, OnionMessage, Option<Vec<SocketAddress>>), SendError> ) -> Result<(PublicKey, OnionMessage, Option<Vec<SocketAddress>>), SendError>
where where
ES::Target: EntropySource, ES::Target: EntropySource,
NS::Target: NodeSigner, NS::Target: NodeSigner,
NL::Target: NodeIdLookUp,
{ {
let OnionMessagePath { intermediate_nodes, mut destination, first_node_addresses } = path; let OnionMessagePath { intermediate_nodes, mut destination, first_node_addresses } = path;
if let Destination::BlindedPath(BlindedPath { ref blinded_hops, .. }) = destination { if let Destination::BlindedPath(BlindedPath { ref blinded_hops, .. }) = destination {
@ -600,16 +605,19 @@ where
// advance the blinded path by 1 hop so the second hop is the new introduction node. // advance the blinded path by 1 hop so the second hop is the new introduction node.
if intermediate_nodes.len() == 0 { if intermediate_nodes.len() == 0 {
if let Destination::BlindedPath(ref mut blinded_path) = destination { if let Destination::BlindedPath(ref mut blinded_path) = destination {
let introduction_node_id = match blinded_path.introduction_node {
IntroductionNode::NodeId(pubkey) => pubkey,
IntroductionNode::DirectedShortChannelId(..) => {
return Err(SendError::UnresolvedIntroductionNode);
},
};
let our_node_id = node_signer.get_node_id(Recipient::Node) let our_node_id = node_signer.get_node_id(Recipient::Node)
.map_err(|()| SendError::GetNodeIdFailed)?; .map_err(|()| SendError::GetNodeIdFailed)?;
let introduction_node_id = match blinded_path.introduction_node {
IntroductionNode::NodeId(pubkey) => pubkey,
IntroductionNode::DirectedShortChannelId(direction, scid) => {
match node_id_lookup.next_node_id(scid) {
Some(next_node_id) => *direction.select_pubkey(&our_node_id, &next_node_id),
None => return Err(SendError::UnresolvedIntroductionNode),
}
},
};
if introduction_node_id == our_node_id { if introduction_node_id == our_node_id {
advance_path_by_one(blinded_path, node_signer, &secp_ctx) advance_path_by_one(blinded_path, node_signer, node_id_lookup, &secp_ctx)
.map_err(|()| SendError::BlindedPathAdvanceFailed)?; .map_err(|()| SendError::BlindedPathAdvanceFailed)?;
} }
} }
@ -741,12 +749,13 @@ where
} }
} }
impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref>
OnionMessenger<ES, NS, L, MR, OMH, CMH> OnionMessenger<ES, NS, L, NL, MR, OMH, CMH>
where where
ES::Target: EntropySource, ES::Target: EntropySource,
NS::Target: NodeSigner, NS::Target: NodeSigner,
L::Target: Logger, L::Target: Logger,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter, MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler, OMH::Target: OffersMessageHandler,
CMH::Target: CustomOnionMessageHandler, CMH::Target: CustomOnionMessageHandler,
@ -754,8 +763,8 @@ where
/// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to /// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
/// their respective handlers. /// their respective handlers.
pub fn new( pub fn new(
entropy_source: ES, node_signer: NS, logger: L, message_router: MR, offers_handler: OMH, entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL, message_router: MR,
custom_handler: CMH offers_handler: OMH, custom_handler: CMH
) -> Self { ) -> Self {
let mut secp_ctx = Secp256k1::new(); let mut secp_ctx = Secp256k1::new();
secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes()); secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
@ -765,6 +774,7 @@ where
message_recipients: Mutex::new(new_hash_map()), message_recipients: Mutex::new(new_hash_map()),
secp_ctx, secp_ctx,
logger, logger,
node_id_lookup,
message_router, message_router,
offers_handler, offers_handler,
custom_handler, custom_handler,
@ -847,7 +857,8 @@ where
log_trace!(self.logger, "Constructing onion message {}: {:?}", log_suffix, contents); log_trace!(self.logger, "Constructing onion message {}: {:?}", log_suffix, contents);
let (first_node_id, onion_message, addresses) = create_onion_message( let (first_node_id, onion_message, addresses) = create_onion_message(
&self.entropy_source, &self.node_signer, &self.secp_ctx, path, contents, reply_path &self.entropy_source, &self.node_signer, &self.node_id_lookup, &self.secp_ctx, path,
contents, reply_path,
)?; )?;
let mut message_recipients = self.message_recipients.lock().unwrap(); let mut message_recipients = self.message_recipients.lock().unwrap();
@ -943,12 +954,13 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, On
false false
} }
impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> EventsProvider impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref> EventsProvider
for OnionMessenger<ES, NS, L, MR, OMH, CMH> for OnionMessenger<ES, NS, L, NL, MR, OMH, CMH>
where where
ES::Target: EntropySource, ES::Target: EntropySource,
NS::Target: NodeSigner, NS::Target: NodeSigner,
L::Target: Logger, L::Target: Logger,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter, MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler, OMH::Target: OffersMessageHandler,
CMH::Target: CustomOnionMessageHandler, CMH::Target: CustomOnionMessageHandler,
@ -964,12 +976,13 @@ where
} }
} }
impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
for OnionMessenger<ES, NS, L, MR, OMH, CMH> for OnionMessenger<ES, NS, L, NL, MR, OMH, CMH>
where where
ES::Target: EntropySource, ES::Target: EntropySource,
NS::Target: NodeSigner, NS::Target: NodeSigner,
L::Target: Logger, L::Target: Logger,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter, MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler, OMH::Target: OffersMessageHandler,
CMH::Target: CustomOnionMessageHandler, CMH::Target: CustomOnionMessageHandler,
@ -1007,7 +1020,13 @@ where
Ok(PeeledOnion::Forward(next_hop, onion_message)) => { Ok(PeeledOnion::Forward(next_hop, onion_message)) => {
let next_node_id = match next_hop { let next_node_id = match next_hop {
NextHop::NodeId(pubkey) => pubkey, NextHop::NodeId(pubkey) => pubkey,
NextHop::ShortChannelId(_) => todo!(), NextHop::ShortChannelId(scid) => match self.node_id_lookup.next_node_id(scid) {
Some(pubkey) => pubkey,
None => {
log_trace!(self.logger, "Dropping forwarded onion messager: unable to resolve next hop using SCID {}", scid);
return
},
},
}; };
let mut message_recipients = self.message_recipients.lock().unwrap(); let mut message_recipients = self.message_recipients.lock().unwrap();
@ -1145,6 +1164,7 @@ pub type SimpleArcOnionMessenger<M, T, F, L> = OnionMessenger<
Arc<KeysManager>, Arc<KeysManager>,
Arc<KeysManager>, Arc<KeysManager>,
Arc<L>, Arc<L>,
Arc<SimpleArcChannelManager<M, T, F, L>>,
Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<L>>>, Arc<L>, Arc<KeysManager>>>, Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<L>>>, Arc<L>, Arc<KeysManager>>>,
Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<SimpleArcChannelManager<M, T, F, L>>,
IgnoringMessageHandler IgnoringMessageHandler
@ -1164,8 +1184,9 @@ pub type SimpleRefOnionMessenger<
&'a KeysManager, &'a KeysManager,
&'a KeysManager, &'a KeysManager,
&'b L, &'b L,
&'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>, &'i SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>,
&'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>, &'j DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>,
&'i SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>,
IgnoringMessageHandler IgnoringMessageHandler
>; >;