From: Jeffrey Czyz Date: Fri, 27 Oct 2023 18:27:55 +0000 (-0500) Subject: Support OnionMessenger in functional_test_utils X-Git-Tag: v0.0.123-beta~93^2~15 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=3b6d039f89b75758dda7c5aeedce5e79bbc0d5fa;p=rust-lightning Support OnionMessenger in functional_test_utils OnionMessenger is needed to write functional tests for ChannelManager's OffersMessageHandler implementation. Also adds a TestMessageRouter, which simply wraps DefaultMessageRouter for now. --- diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index dd7b7c2cd..5971fc9ea 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -19,10 +19,12 @@ use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::channelmanager::{AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA}; use crate::ln::features::InitFeatures; use crate::ln::msgs; -use crate::ln::msgs::{ChannelMessageHandler,RoutingMessageHandler}; +use crate::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler}; +use crate::ln::peer_handler::IgnoringMessageHandler; +use crate::onion_message::messenger::OnionMessenger; use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate}; use crate::routing::router::{self, PaymentParameters, Route, RouteParameters}; -use crate::sign::EntropySource; +use crate::sign::{EntropySource, RandomBytes}; use crate::util::config::{UserConfig, MaxDustHTLCExposure}; use crate::util::errors::APIError; #[cfg(test)] @@ -47,6 +49,7 @@ use alloc::rc::Rc; use core::cell::RefCell; use core::iter::repeat; use core::mem; +use core::ops::Deref; use crate::io; use crate::prelude::*; use crate::sync::{Arc, Mutex, LockTestExt, RwLock}; @@ -388,6 +391,7 @@ pub struct NodeCfg<'a> { pub tx_broadcaster: &'a test_utils::TestBroadcaster, pub fee_estimator: &'a test_utils::TestFeeEstimator, pub router: test_utils::TestRouter<'a>, + pub message_router: test_utils::TestMessageRouter<'a>, pub chain_monitor: test_utils::TestChainMonitor<'a>, pub keys_manager: &'a test_utils::TestKeysInterface, pub logger: &'a test_utils::TestLogger, @@ -407,6 +411,26 @@ type TestChannelManager<'node_cfg, 'chan_mon_cfg> = ChannelManager< &'chan_mon_cfg test_utils::TestLogger, >; +type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger< + DedicatedEntropy, + &'node_cfg test_utils::TestKeysInterface, + &'chan_mon_cfg test_utils::TestLogger, + &'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>, + &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>, + IgnoringMessageHandler, +>; + +/// For use with [`OnionMessenger`] otherwise `test_restored_packages_retry` will fail. This is +/// because that test uses older serialized data produced by calling [`EntropySource`] in a specific +/// manner. Using the same [`EntropySource`] with [`OnionMessenger`] would introduce another call, +/// causing the produced data to no longer match. +pub struct DedicatedEntropy(RandomBytes); + +impl Deref for DedicatedEntropy { + type Target = RandomBytes; + fn deref(&self) -> &Self::Target { &self.0 } +} + pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> { pub chain_source: &'chan_mon_cfg test_utils::TestChainSource, pub tx_broadcaster: &'chan_mon_cfg test_utils::TestBroadcaster, @@ -415,6 +439,7 @@ pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> { pub chain_monitor: &'node_cfg test_utils::TestChainMonitor<'chan_mon_cfg>, pub keys_manager: &'chan_mon_cfg test_utils::TestKeysInterface, pub node: &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>, + pub onion_messenger: TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg>, pub network_graph: &'node_cfg NetworkGraph<&'chan_mon_cfg test_utils::TestLogger>, pub gossip_sync: P2PGossipSync<&'node_cfg NetworkGraph<&'chan_mon_cfg test_utils::TestLogger>, &'chan_mon_cfg test_utils::TestChainSource, &'chan_mon_cfg test_utils::TestLogger>, pub node_seed: [u8; 32], @@ -432,6 +457,14 @@ pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> { &'chan_mon_cfg test_utils::TestLogger, >, } + +impl<'a, 'b, 'c> Node<'a, 'b, 'c> { + pub fn init_features(&self, peer_node_id: &PublicKey) -> InitFeatures { + self.override_init_features.borrow().clone() + .unwrap_or_else(|| self.node.init_features() | self.onion_messenger.provided_init_features(peer_node_id)) + } +} + #[cfg(feature = "std")] impl<'a, 'b, 'c> std::panic::UnwindSafe for Node<'a, 'b, 'c> {} #[cfg(feature = "std")] @@ -1054,6 +1087,7 @@ macro_rules! reload_node { $new_channelmanager = _reload_node(&$node, $new_config, &chanman_encoded, $monitors_encoded); $node.node = &$new_channelmanager; + $node.onion_messenger.set_offers_handler(&$new_channelmanager); }; ($node: expr, $chanman_encoded: expr, $monitors_encoded: expr, $persister: ident, $new_chain_monitor: ident, $new_channelmanager: ident) => { reload_node!($node, $crate::util::config::UserConfig::default(), $chanman_encoded, $monitors_encoded, $persister, $new_chain_monitor, $new_channelmanager); @@ -2898,6 +2932,7 @@ pub fn create_node_cfgs_with_persisters<'a>(node_count: usize, chanmon_cfgs: &'a tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster, fee_estimator: &chanmon_cfgs[i].fee_estimator, router: test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[i].scorer), + message_router: test_utils::TestMessageRouter::new(network_graph.clone()), chain_monitor, keys_manager: &chanmon_cfgs[i].keys_manager, node_seed: seed, @@ -2951,6 +2986,11 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec(node_count: usize, cfgs: &'b Vec(node_count: usize, cfgs: &'b Vec LockableScore<'a> for RefCell { } } -#[cfg(not(c_bindings))] +#[cfg(any(not(c_bindings), feature = "_test_utils", test))] impl<'a, T: Score + 'a> LockableScore<'a> for RwLock { type ScoreUpdate = T; type ScoreLookUp = T; diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 312208794..717c05517 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -1874,9 +1874,9 @@ impl PhantomKeysManager { } } -/// An implementation of [`EntropySource`] using [`ChaCha20`]. +/// An implementation of [`EntropySource`] using ChaCha20. #[derive(Debug)] -struct RandomBytes { +pub struct RandomBytes { /// Seed from which all randomness produced is derived from. seed: [u8; 32], /// Tracks the number of times we've produced randomness to ensure we don't return the same diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 1c45c4a4c..c1692f9e3 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -32,7 +32,7 @@ use crate::ln::msgs::LightningError; use crate::ln::script::ShutdownScript; use crate::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice}; use crate::offers::invoice_request::UnsignedInvoiceRequest; -use crate::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath}; +use crate::onion_message::messenger::{DefaultMessageRouter, Destination, MessageRouter, OnionMessagePath}; use crate::routing::gossip::{EffectiveCapacity, NetworkGraph, NodeId, RoutingFees}; use crate::routing::utxo::{UtxoLookup, UtxoLookupError, UtxoResult}; use crate::routing::router::{find_route, InFlightHtlcs, Path, Route, RouteParameters, RouteHintHop, Router, ScorerAccountingForInFlightHtlcs}; @@ -231,6 +231,33 @@ impl<'a> Drop for TestRouter<'a> { } } +pub struct TestMessageRouter<'a> { + inner: DefaultMessageRouter>, &'a TestLogger>, +} + +impl<'a> TestMessageRouter<'a> { + pub fn new(network_graph: Arc>) -> Self { + Self { inner: DefaultMessageRouter::new(network_graph) } + } +} + +impl<'a> MessageRouter for TestMessageRouter<'a> { + fn find_path( + &self, sender: PublicKey, peers: Vec, destination: Destination + ) -> Result { + self.inner.find_path(sender, peers, destination) + } + + fn create_blinded_paths< + ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification + >( + &self, recipient: PublicKey, peers: Vec, entropy_source: &ES, + secp_ctx: &Secp256k1 + ) -> Result, ()> { + self.inner.create_blinded_paths(recipient, peers, entropy_source, secp_ctx) + } +} + pub struct OnlyReadsKeysInterface {} impl EntropySource for OnlyReadsKeysInterface { @@ -1390,6 +1417,9 @@ impl ScoreUpdate for TestScorer { fn time_passed(&mut self, _duration_since_epoch: Duration) {} } +#[cfg(c_bindings)] +impl crate::routing::scoring::Score for TestScorer {} + impl Drop for TestScorer { fn drop(&mut self) { #[cfg(feature = "std")] {