From a71000f35dd23949d26fffd421d6f6478f0cd6b5 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Wed, 22 Feb 2023 22:22:42 -0600 Subject: [PATCH] MessageRouter trait for OnionMessenger Add a trait for finding routes for onion messages and parameterize OnionMessenger with it. This allows OnionMessenger to reply to messages that it handles via one of its handlers (e.g., OffersMessageHandler). --- fuzz/src/onion_message.rs | 16 +++++- lightning-background-processor/src/lib.rs | 3 +- lightning/src/ln/peer_handler.rs | 22 +++++++- .../src/onion_message/functional_tests.rs | 27 ++++++++-- lightning/src/onion_message/messenger.rs | 54 +++++++++++++++---- lightning/src/onion_message/mod.rs | 2 +- 6 files changed, 104 insertions(+), 20 deletions(-) diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index ec467e22..fd19a611 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -11,7 +11,7 @@ use lightning::ln::script::ShutdownScript; use lightning::util::enforcing_trait_impls::EnforcingSigner; use lightning::util::logger::Logger; use lightning::util::ser::{Readable, Writeable, Writer}; -use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, OnionMessenger}; +use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessagePath, OnionMessenger}; use crate::utils::test_logger; @@ -29,10 +29,12 @@ pub fn do_test(data: &[u8], logger: &L) { node_secret: secret, counter: AtomicU64::new(0), }; + let message_router = TestMessageRouter {}; let offers_msg_handler = TestOffersMessageHandler {}; let custom_msg_handler = TestCustomMessageHandler {}; let onion_messenger = OnionMessenger::new( - &keys_manager, &keys_manager, logger, &offers_msg_handler, &custom_msg_handler + &keys_manager, &keys_manager, logger, &message_router, &offers_msg_handler, + &custom_msg_handler ); let mut pk = [2; 33]; pk[1] = 0xff; let peer_node_id_not_used = PublicKey::from_slice(&pk).unwrap(); @@ -53,6 +55,16 @@ pub extern "C" fn onion_message_run(data: *const u8, datalen: usize) { do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, &logger); } +struct TestMessageRouter {} + +impl MessageRouter for TestMessageRouter { + fn find_path( + &self, _sender: PublicKey, _peers: Vec, _destination: Destination + ) -> Result { + unreachable!() + } +} + struct TestOffersMessageHandler {} impl OffersMessageHandler for TestOffersMessageHandler { diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 248f79dd..0cfa9801 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -519,8 +519,9 @@ use core::task; /// # type MyUtxoLookup = dyn lightning::routing::utxo::UtxoLookup + Send + Sync; /// # type MyFilter = dyn lightning::chain::Filter + Send + Sync; /// # type MyLogger = dyn lightning::util::logger::Logger + Send + Sync; +/// # type MyMessageRouter = dyn lightning::onion_message::MessageRouter + Send + Sync; /// # type MyChainMonitor = lightning::chain::chainmonitor::ChainMonitor, Arc, Arc, Arc, Arc>; -/// # type MyPeerManager = lightning::ln::peer_handler::SimpleArcPeerManager; +/// # type MyPeerManager = lightning::ln::peer_handler::SimpleArcPeerManager; /// # type MyNetworkGraph = lightning::routing::gossip::NetworkGraph>; /// # type MyGossipSync = lightning::routing::gossip::P2PGossipSync, Arc, Arc>; /// # type MyChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager; diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index f5c6341b..56e0a1e0 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -607,7 +607,15 @@ impl Peer { /// issues such as overly long function definitions. /// /// This is not exported to bindings users as `Arc`s don't make sense in bindings. -pub type SimpleArcPeerManager = PeerManager>, Arc>>, Arc, Arc>>, Arc>, Arc, IgnoringMessageHandler, Arc>; +pub type SimpleArcPeerManager = PeerManager< + SD, + Arc>, + Arc>>, Arc, Arc>>, + Arc>, + Arc, + IgnoringMessageHandler, + Arc +>; /// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference /// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't @@ -617,7 +625,17 @@ pub type SimpleArcPeerManager = PeerManager = PeerManager, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler, &'c KeysManager>; +pub type SimpleRefPeerManager< + 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, SD, M, T, F, C, L, R +> = PeerManager< + SD, + &'n SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, + &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, + &'i SimpleRefOnionMessenger<'g, 'm, 'n, L, R>, + &'f L, + IgnoringMessageHandler, + &'c KeysManager +>; /// A generic trait which is implemented for all [`PeerManager`]s. This makes bounding functions or diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 90243f35..a5effdd9 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -13,7 +13,7 @@ use crate::blinded_path::BlindedPath; use crate::sign::{NodeSigner, Recipient}; use crate::ln::features::InitFeatures; use crate::ln::msgs::{self, DecodeError, OnionMessageHandler}; -use super::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger, SendError}; +use super::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger, SendError}; use crate::util::ser::{Writeable, Writer}; use crate::util::test_utils; @@ -27,7 +27,14 @@ use crate::sync::Arc; struct MessengerNode { keys_manager: Arc, - messenger: OnionMessenger, Arc, Arc, Arc, Arc>, + messenger: OnionMessenger< + Arc, + Arc, + Arc, + Arc, + Arc, + Arc + >, custom_message_handler: Arc, logger: Arc, } @@ -38,6 +45,16 @@ impl MessengerNode { } } +struct TestMessageRouter {} + +impl MessageRouter for TestMessageRouter { + fn find_path( + &self, _sender: PublicKey, _peers: Vec, _destination: Destination + ) -> Result { + todo!() + } +} + struct TestOffersMessageHandler {} impl OffersMessageHandler for TestOffersMessageHandler { @@ -106,11 +123,15 @@ fn create_nodes(num_messengers: u8) -> Vec { let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i))); let seed = [i as u8; 32]; let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet)); + let message_router = Arc::new(TestMessageRouter {}); let offers_message_handler = Arc::new(TestOffersMessageHandler {}); let custom_message_handler = Arc::new(TestCustomMessageHandler::new()); nodes.push(MessengerNode { keys_manager: keys_manager.clone(), - messenger: OnionMessenger::new(keys_manager.clone(), keys_manager, logger.clone(), offers_message_handler, custom_message_handler.clone()), + messenger: OnionMessenger::new( + keys_manager.clone(), keys_manager, logger.clone(), message_router, + offers_message_handler, custom_message_handler.clone() + ), custom_message_handler, logger, }); diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 09a23075..07cb0bc1 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -46,7 +46,7 @@ use crate::prelude::*; /// # use lightning::blinded_path::BlindedPath; /// # use lightning::sign::KeysManager; /// # use lightning::ln::peer_handler::IgnoringMessageHandler; -/// # use lightning::onion_message::{CustomOnionMessageContents, Destination, OnionMessageContents, OnionMessagePath, OnionMessenger}; +/// # use lightning::onion_message::{CustomOnionMessageContents, Destination, MessageRouter, OnionMessageContents, OnionMessagePath, OnionMessenger}; /// # use lightning::util::logger::{Logger, Record}; /// # use lightning::util::ser::{Writeable, Writer}; /// # use lightning::io; @@ -55,6 +55,12 @@ use crate::prelude::*; /// # impl Logger for FakeLogger { /// # fn log(&self, record: &Record) { unimplemented!() } /// # } +/// # struct FakeMessageRouter {} +/// # impl MessageRouter for FakeMessageRouter { +/// # fn find_path(&self, sender: PublicKey, peers: Vec, destination: Destination) -> Result { +/// # unimplemented!() +/// # } +/// # } /// # let seed = [42u8; 32]; /// # let time = Duration::from_secs(123456); /// # let keys_manager = KeysManager::new(&seed, time.as_secs(), time.subsec_nanos()); @@ -64,11 +70,15 @@ use crate::prelude::*; /// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret); /// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1); /// # let destination_node_id = hop_node_id1; +/// # let message_router = Arc::new(FakeMessageRouter {}); /// # let custom_message_handler = IgnoringMessageHandler {}; /// # let offers_message_handler = IgnoringMessageHandler {}; /// // Create the onion messenger. This must use the same `keys_manager` as is passed to your /// // ChannelManager. -/// let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &offers_message_handler, &custom_message_handler); +/// let onion_messenger = OnionMessenger::new( +/// &keys_manager, &keys_manager, logger, message_router, &offers_message_handler, +/// &custom_message_handler +/// ); /// /// # struct YourCustomMessage {} /// impl Writeable for YourCustomMessage { @@ -111,11 +121,12 @@ use crate::prelude::*; /// /// [offers]: /// [`OnionMessenger`]: crate::onion_message::OnionMessenger -pub struct OnionMessenger +pub struct OnionMessenger where ES::Target: EntropySource, NS::Target: NodeSigner, L::Target: Logger, + MR::Target: MessageRouter, OMH::Target: OffersMessageHandler, CMH:: Target: CustomOnionMessageHandler, { @@ -124,10 +135,23 @@ where logger: L, pending_messages: Mutex>>, secp_ctx: Secp256k1, + message_router: MR, offers_handler: OMH, custom_handler: CMH, } +/// A trait defining behavior for routing an [`OnionMessage`]. +/// +/// [`OnionMessage`]: msgs::OnionMessage +pub trait MessageRouter { + /// Returns a route for sending an [`OnionMessage`] to the given [`Destination`]. + /// + /// [`OnionMessage`]: msgs::OnionMessage + fn find_path( + &self, sender: PublicKey, peers: Vec, destination: Destination + ) -> Result; +} + /// A path for sending an [`msgs::OnionMessage`]. #[derive(Clone)] pub struct OnionMessagePath { @@ -207,18 +231,21 @@ pub trait CustomOnionMessageHandler { fn read_custom_message(&self, message_type: u64, buffer: &mut R) -> Result, msgs::DecodeError>; } -impl OnionMessenger +impl +OnionMessenger where ES::Target: EntropySource, NS::Target: NodeSigner, L::Target: Logger, + MR::Target: MessageRouter, OMH::Target: OffersMessageHandler, CMH::Target: CustomOnionMessageHandler, { /// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to /// their respective handlers. pub fn new( - entropy_source: ES, node_signer: NS, logger: L, offers_handler: OMH, custom_handler: CMH + entropy_source: ES, node_signer: NS, logger: L, message_router: MR, offers_handler: OMH, + custom_handler: CMH ) -> Self { let mut secp_ctx = Secp256k1::new(); secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes()); @@ -228,6 +255,7 @@ where pending_messages: Mutex::new(HashMap::new()), secp_ctx, logger, + message_router, offers_handler, custom_handler, } @@ -328,12 +356,13 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap OnionMessageHandler -for OnionMessenger +impl OnionMessageHandler +for OnionMessenger where ES::Target: EntropySource, NS::Target: NodeSigner, L::Target: Logger, + MR::Target: MessageRouter, OMH::Target: OffersMessageHandler, CMH::Target: CustomOnionMessageHandler + Sized, { @@ -478,12 +507,13 @@ where } } -impl OnionMessageProvider -for OnionMessenger +impl OnionMessageProvider +for OnionMessenger where ES::Target: EntropySource, NS::Target: NodeSigner, L::Target: Logger, + MR::Target: MessageRouter, OMH::Target: OffersMessageHandler, CMH::Target: CustomOnionMessageHandler, { @@ -505,10 +535,11 @@ where /// /// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager /// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager -pub type SimpleArcOnionMessenger = OnionMessenger< +pub type SimpleArcOnionMessenger = OnionMessenger< Arc, Arc, Arc, + Arc, IgnoringMessageHandler, IgnoringMessageHandler >; @@ -520,10 +551,11 @@ pub type SimpleArcOnionMessenger = OnionMessenger< /// /// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager /// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager -pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger< +pub type SimpleRefOnionMessenger<'a, 'b, 'c, L, R> = OnionMessenger< &'a KeysManager, &'a KeysManager, &'b L, + &'c R, IgnoringMessageHandler, IgnoringMessageHandler >; diff --git a/lightning/src/onion_message/mod.rs b/lightning/src/onion_message/mod.rs index 35bf6a99..556ae898 100644 --- a/lightning/src/onion_message/mod.rs +++ b/lightning/src/onion_message/mod.rs @@ -27,6 +27,6 @@ mod packet; mod functional_tests; // Re-export structs so they can be imported with just the `onion_message::` module prefix. -pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessagePath, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger}; +pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, MessageRouter, OnionMessageContents, OnionMessagePath, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger}; pub use self::offers::{OffersMessage, OffersMessageHandler}; pub(crate) use self::packet::{ControlTlvs, Packet}; -- 2.30.2