]> git.bitcoin.ninja Git - rust-lightning/commitdiff
MessageRouter trait for OnionMessenger
authorJeffrey Czyz <jkczyz@gmail.com>
Thu, 23 Feb 2023 04:22:42 +0000 (22:22 -0600)
committerJeffrey Czyz <jkczyz@gmail.com>
Tue, 13 Jun 2023 18:07:47 +0000 (13:07 -0500)
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
lightning-background-processor/src/lib.rs
lightning/src/ln/peer_handler.rs
lightning/src/onion_message/functional_tests.rs
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/mod.rs

index ec467e22dda5dd86d0c654a863f557093bae74cb..fd19a6114581183560f9d7433a92baf699c374db 100644 (file)
@@ -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<L: Logger>(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<PublicKey>, _destination: Destination
+       ) -> Result<OnionMessagePath, ()> {
+               unreachable!()
+       }
+}
+
 struct TestOffersMessageHandler {}
 
 impl OffersMessageHandler for TestOffersMessageHandler {
index 248f79dd59ea5060a0239f566c308cd882120984..0cfa9801badb3a8d31a30cbdce81b93cbaab1f5a 100644 (file)
@@ -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<lightning::sign::InMemorySigner, Arc<MyFilter>, Arc<MyBroadcaster>, Arc<MyFeeEstimator>, Arc<MyLogger>, Arc<MyPersister>>;
-/// # type MyPeerManager = lightning::ln::peer_handler::SimpleArcPeerManager<MySocketDescriptor, MyChainMonitor, MyBroadcaster, MyFeeEstimator, MyUtxoLookup, MyLogger>;
+/// # type MyPeerManager = lightning::ln::peer_handler::SimpleArcPeerManager<MySocketDescriptor, MyChainMonitor, MyBroadcaster, MyFeeEstimator, MyUtxoLookup, MyLogger, MyMessageRouter>;
 /// # type MyNetworkGraph = lightning::routing::gossip::NetworkGraph<Arc<MyLogger>>;
 /// # type MyGossipSync = lightning::routing::gossip::P2PGossipSync<Arc<MyNetworkGraph>, Arc<MyUtxoLookup>, Arc<MyLogger>>;
 /// # type MyChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager<MyChainMonitor, MyBroadcaster, MyFeeEstimator, MyLogger>;
index f5c6341bb3ebde548c907636336d3edf90606cc0..56e0a1e0a444a04f6b9521119ab304066672159f 100644 (file)
@@ -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<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler, Arc<KeysManager>>;
+pub type SimpleArcPeerManager<SD, M, T, F, C, L, R> = PeerManager<
+       SD,
+       Arc<SimpleArcChannelManager<M, T, F, L>>,
+       Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>,
+       Arc<SimpleArcOnionMessenger<L, R>>,
+       Arc<L>,
+       IgnoringMessageHandler,
+       Arc<KeysManager>
+>;
 
 /// 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<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArc
 /// helps with issues such as long function definitions.
 ///
 /// This is not exported to bindings users as general type aliases don't make sense in bindings.
-pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, 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<'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
index 90243f357c36d9d3d1c9f54a88cdef375483e8e7..a5effdd92fe49d1df9ee122b7516523c392b66cc 100644 (file)
@@ -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<test_utils::TestKeysInterface>,
-       messenger: OnionMessenger<Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestLogger>, Arc<TestOffersMessageHandler>, Arc<TestCustomMessageHandler>>,
+       messenger: OnionMessenger<
+               Arc<test_utils::TestKeysInterface>,
+               Arc<test_utils::TestKeysInterface>,
+               Arc<test_utils::TestLogger>,
+               Arc<TestMessageRouter>,
+               Arc<TestOffersMessageHandler>,
+               Arc<TestCustomMessageHandler>
+       >,
        custom_message_handler: Arc<TestCustomMessageHandler>,
        logger: Arc<test_utils::TestLogger>,
 }
@@ -38,6 +45,16 @@ impl MessengerNode {
        }
 }
 
+struct TestMessageRouter {}
+
+impl MessageRouter for TestMessageRouter {
+       fn find_path(
+               &self, _sender: PublicKey, _peers: Vec<PublicKey>, _destination: Destination
+       ) -> Result<OnionMessagePath, ()> {
+               todo!()
+       }
+}
+
 struct TestOffersMessageHandler {}
 
 impl OffersMessageHandler for TestOffersMessageHandler {
@@ -106,11 +123,15 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
                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,
                });
index 09a2307591673ce4c01dc1dfd990249c24befc92..07cb0bc1e9896df5241c05a0b80a2b03e89eb995 100644 (file)
@@ -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<PublicKey>, destination: Destination) -> Result<OnionMessagePath, ()> {
+/// #         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]: <https://github.com/lightning/bolts/pull/798>
 /// [`OnionMessenger`]: crate::onion_message::OnionMessenger
-pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref>
+pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref>
 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<HashMap<PublicKey, VecDeque<msgs::OnionMessage>>>,
        secp_ctx: Secp256k1<secp256k1::All>,
+       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<PublicKey>, destination: Destination
+       ) -> Result<OnionMessagePath, ()>;
+}
+
 /// A path for sending an [`msgs::OnionMessage`].
 #[derive(Clone)]
 pub struct OnionMessagePath {
@@ -207,18 +231,21 @@ pub trait CustomOnionMessageHandler {
        fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessenger<ES, NS, L, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref>
+OnionMessenger<ES, NS, L, MR, OMH, CMH>
 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<PublicKey, Ve
        false
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
-for OnionMessenger<ES, NS, L, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
+for OnionMessenger<ES, NS, L, MR, OMH, CMH>
 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<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessageProvider
-for OnionMessenger<ES, NS, L, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref> OnionMessageProvider
+for OnionMessenger<ES, NS, L, MR, OMH, CMH>
 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<L> = OnionMessenger<
+pub type SimpleArcOnionMessenger<L, R> = OnionMessenger<
        Arc<KeysManager>,
        Arc<KeysManager>,
        Arc<L>,
+       Arc<R>,
        IgnoringMessageHandler,
        IgnoringMessageHandler
 >;
@@ -520,10 +551,11 @@ pub type SimpleArcOnionMessenger<L> = 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
 >;
index 35bf6a99e6d572dd4800f69524d63356f500ab1d..556ae89820bd33116ec672535a35ea3a79cd1fc4 100644 (file)
@@ -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};