Skip to content

Commit 3b6d039

Browse files
committed
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.
1 parent 8deac89 commit 3b6d039

File tree

6 files changed

+98
-14
lines changed

6 files changed

+98
-14
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
1919
use crate::ln::channelmanager::{AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA};
2020
use crate::ln::features::InitFeatures;
2121
use crate::ln::msgs;
22-
use crate::ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
22+
use crate::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler};
23+
use crate::ln::peer_handler::IgnoringMessageHandler;
24+
use crate::onion_message::messenger::OnionMessenger;
2325
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
2426
use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
25-
use crate::sign::EntropySource;
27+
use crate::sign::{EntropySource, RandomBytes};
2628
use crate::util::config::{UserConfig, MaxDustHTLCExposure};
2729
use crate::util::errors::APIError;
2830
#[cfg(test)]
@@ -47,6 +49,7 @@ use alloc::rc::Rc;
4749
use core::cell::RefCell;
4850
use core::iter::repeat;
4951
use core::mem;
52+
use core::ops::Deref;
5053
use crate::io;
5154
use crate::prelude::*;
5255
use crate::sync::{Arc, Mutex, LockTestExt, RwLock};
@@ -388,6 +391,7 @@ pub struct NodeCfg<'a> {
388391
pub tx_broadcaster: &'a test_utils::TestBroadcaster,
389392
pub fee_estimator: &'a test_utils::TestFeeEstimator,
390393
pub router: test_utils::TestRouter<'a>,
394+
pub message_router: test_utils::TestMessageRouter<'a>,
391395
pub chain_monitor: test_utils::TestChainMonitor<'a>,
392396
pub keys_manager: &'a test_utils::TestKeysInterface,
393397
pub logger: &'a test_utils::TestLogger,
@@ -407,6 +411,26 @@ type TestChannelManager<'node_cfg, 'chan_mon_cfg> = ChannelManager<
407411
&'chan_mon_cfg test_utils::TestLogger,
408412
>;
409413

414+
type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger<
415+
DedicatedEntropy,
416+
&'node_cfg test_utils::TestKeysInterface,
417+
&'chan_mon_cfg test_utils::TestLogger,
418+
&'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>,
419+
&'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
420+
IgnoringMessageHandler,
421+
>;
422+
423+
/// For use with [`OnionMessenger`] otherwise `test_restored_packages_retry` will fail. This is
424+
/// because that test uses older serialized data produced by calling [`EntropySource`] in a specific
425+
/// manner. Using the same [`EntropySource`] with [`OnionMessenger`] would introduce another call,
426+
/// causing the produced data to no longer match.
427+
pub struct DedicatedEntropy(RandomBytes);
428+
429+
impl Deref for DedicatedEntropy {
430+
type Target = RandomBytes;
431+
fn deref(&self) -> &Self::Target { &self.0 }
432+
}
433+
410434
pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> {
411435
pub chain_source: &'chan_mon_cfg test_utils::TestChainSource,
412436
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> {
415439
pub chain_monitor: &'node_cfg test_utils::TestChainMonitor<'chan_mon_cfg>,
416440
pub keys_manager: &'chan_mon_cfg test_utils::TestKeysInterface,
417441
pub node: &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
442+
pub onion_messenger: TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg>,
418443
pub network_graph: &'node_cfg NetworkGraph<&'chan_mon_cfg test_utils::TestLogger>,
419444
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>,
420445
pub node_seed: [u8; 32],
@@ -432,6 +457,14 @@ pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> {
432457
&'chan_mon_cfg test_utils::TestLogger,
433458
>,
434459
}
460+
461+
impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
462+
pub fn init_features(&self, peer_node_id: &PublicKey) -> InitFeatures {
463+
self.override_init_features.borrow().clone()
464+
.unwrap_or_else(|| self.node.init_features() | self.onion_messenger.provided_init_features(peer_node_id))
465+
}
466+
}
467+
435468
#[cfg(feature = "std")]
436469
impl<'a, 'b, 'c> std::panic::UnwindSafe for Node<'a, 'b, 'c> {}
437470
#[cfg(feature = "std")]
@@ -1054,6 +1087,7 @@ macro_rules! reload_node {
10541087

10551088
$new_channelmanager = _reload_node(&$node, $new_config, &chanman_encoded, $monitors_encoded);
10561089
$node.node = &$new_channelmanager;
1090+
$node.onion_messenger.set_offers_handler(&$new_channelmanager);
10571091
};
10581092
($node: expr, $chanman_encoded: expr, $monitors_encoded: expr, $persister: ident, $new_chain_monitor: ident, $new_channelmanager: ident) => {
10591093
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
28982932
tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster,
28992933
fee_estimator: &chanmon_cfgs[i].fee_estimator,
29002934
router: test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[i].scorer),
2935+
message_router: test_utils::TestMessageRouter::new(network_graph.clone()),
29012936
chain_monitor,
29022937
keys_manager: &chanmon_cfgs[i].keys_manager,
29032938
node_seed: seed,
@@ -2951,14 +2986,19 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
29512986
let connect_style = Rc::new(RefCell::new(ConnectStyle::random_style()));
29522987

29532988
for i in 0..node_count {
2989+
let dedicated_entropy = DedicatedEntropy(RandomBytes::new([i as u8; 32]));
2990+
let onion_messenger = OnionMessenger::new(
2991+
dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &cfgs[i].message_router,
2992+
&chan_mgrs[i], IgnoringMessageHandler {},
2993+
);
29542994
let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger);
29552995
let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap()));
29562996
nodes.push(Node{
29572997
chain_source: cfgs[i].chain_source, tx_broadcaster: cfgs[i].tx_broadcaster,
29582998
fee_estimator: cfgs[i].fee_estimator, router: &cfgs[i].router,
29592999
chain_monitor: &cfgs[i].chain_monitor, keys_manager: &cfgs[i].keys_manager,
29603000
node: &chan_mgrs[i], network_graph: cfgs[i].network_graph.as_ref(), gossip_sync,
2961-
node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),
3001+
node_seed: cfgs[i].node_seed, onion_messenger, network_chan_count: chan_count.clone(),
29623002
network_payment_count: payment_count.clone(), logger: cfgs[i].logger,
29633003
blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
29643004
connect_style: Rc::clone(&connect_style),
@@ -2973,16 +3013,24 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
29733013

29743014
for i in 0..node_count {
29753015
for j in (i+1)..node_count {
2976-
nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init {
2977-
features: nodes[j].override_init_features.borrow().clone().unwrap_or_else(|| nodes[j].node.init_features()),
3016+
let node_id_i = nodes[i].node.get_our_node_id();
3017+
let node_id_j = nodes[j].node.get_our_node_id();
3018+
3019+
let init_i = msgs::Init {
3020+
features: nodes[i].init_features(&node_id_j),
29783021
networks: None,
29793022
remote_network_address: None,
2980-
}, true).unwrap();
2981-
nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init {
2982-
features: nodes[i].override_init_features.borrow().clone().unwrap_or_else(|| nodes[i].node.init_features()),
3023+
};
3024+
let init_j = msgs::Init {
3025+
features: nodes[j].init_features(&node_id_i),
29833026
networks: None,
29843027
remote_network_address: None,
2985-
}, false).unwrap();
3028+
};
3029+
3030+
nodes[i].node.peer_connected(&node_id_j, &init_j, true).unwrap();
3031+
nodes[j].node.peer_connected(&node_id_i, &init_i, false).unwrap();
3032+
nodes[i].onion_messenger.peer_connected(&node_id_j, &init_j, true).unwrap();
3033+
nodes[j].onion_messenger.peer_connected(&node_id_i, &init_i, false).unwrap();
29863034
}
29873035
}
29883036

lightning/src/ln/functional_tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5534,7 +5534,8 @@ fn test_key_derivation_params() {
55345534
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[0].logger));
55355535
let scorer = RwLock::new(test_utils::TestScorer::new());
55365536
let router = test_utils::TestRouter::new(network_graph.clone(), &scorer);
5537-
let node = NodeCfg { chain_source: &chanmon_cfgs[0].chain_source, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, router, chain_monitor, keys_manager: &keys_manager, network_graph, node_seed: seed, override_init_features: alloc::rc::Rc::new(core::cell::RefCell::new(None)) };
5537+
let message_router = test_utils::TestMessageRouter::new(network_graph.clone());
5538+
let node = NodeCfg { chain_source: &chanmon_cfgs[0].chain_source, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, router, message_router, chain_monitor, keys_manager: &keys_manager, network_graph, node_seed: seed, override_init_features: alloc::rc::Rc::new(core::cell::RefCell::new(None)) };
55385539
let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
55395540
node_cfgs.remove(0);
55405541
node_cfgs.insert(0, node);

lightning/src/onion_message/messenger.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,11 @@ where
714714
}
715715
}
716716

717+
#[cfg(test)]
718+
pub(crate) fn set_offers_handler(&mut self, offers_handler: OMH) {
719+
self.offers_handler = offers_handler;
720+
}
721+
717722
/// Sends an [`OnionMessage`] with the given `contents` to `destination`.
718723
///
719724
/// See [`OnionMessenger`] for example usage.

lightning/src/routing/scoring.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl<'a, T: Score + 'a> LockableScore<'a> for RefCell<T> {
251251
}
252252
}
253253

254-
#[cfg(not(c_bindings))]
254+
#[cfg(any(not(c_bindings), feature = "_test_utils", test))]
255255
impl<'a, T: Score + 'a> LockableScore<'a> for RwLock<T> {
256256
type ScoreUpdate = T;
257257
type ScoreLookUp = T;

lightning/src/sign/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,9 +1874,9 @@ impl PhantomKeysManager {
18741874
}
18751875
}
18761876

1877-
/// An implementation of [`EntropySource`] using [`ChaCha20`].
1877+
/// An implementation of [`EntropySource`] using ChaCha20.
18781878
#[derive(Debug)]
1879-
struct RandomBytes {
1879+
pub struct RandomBytes {
18801880
/// Seed from which all randomness produced is derived from.
18811881
seed: [u8; 32],
18821882
/// Tracks the number of times we've produced randomness to ensure we don't return the same

lightning/src/util/test_utils.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::ln::msgs::LightningError;
3232
use crate::ln::script::ShutdownScript;
3333
use crate::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice};
3434
use crate::offers::invoice_request::UnsignedInvoiceRequest;
35-
use crate::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath};
35+
use crate::onion_message::messenger::{DefaultMessageRouter, Destination, MessageRouter, OnionMessagePath};
3636
use crate::routing::gossip::{EffectiveCapacity, NetworkGraph, NodeId, RoutingFees};
3737
use crate::routing::utxo::{UtxoLookup, UtxoLookupError, UtxoResult};
3838
use crate::routing::router::{find_route, InFlightHtlcs, Path, Route, RouteParameters, RouteHintHop, Router, ScorerAccountingForInFlightHtlcs};
@@ -231,6 +231,33 @@ impl<'a> Drop for TestRouter<'a> {
231231
}
232232
}
233233

234+
pub struct TestMessageRouter<'a> {
235+
inner: DefaultMessageRouter<Arc<NetworkGraph<&'a TestLogger>>, &'a TestLogger>,
236+
}
237+
238+
impl<'a> TestMessageRouter<'a> {
239+
pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>) -> Self {
240+
Self { inner: DefaultMessageRouter::new(network_graph) }
241+
}
242+
}
243+
244+
impl<'a> MessageRouter for TestMessageRouter<'a> {
245+
fn find_path(
246+
&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
247+
) -> Result<OnionMessagePath, ()> {
248+
self.inner.find_path(sender, peers, destination)
249+
}
250+
251+
fn create_blinded_paths<
252+
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
253+
>(
254+
&self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
255+
secp_ctx: &Secp256k1<T>
256+
) -> Result<Vec<BlindedPath>, ()> {
257+
self.inner.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
258+
}
259+
}
260+
234261
pub struct OnlyReadsKeysInterface {}
235262

236263
impl EntropySource for OnlyReadsKeysInterface {
@@ -1390,6 +1417,9 @@ impl ScoreUpdate for TestScorer {
13901417
fn time_passed(&mut self, _duration_since_epoch: Duration) {}
13911418
}
13921419

1420+
#[cfg(c_bindings)]
1421+
impl crate::routing::scoring::Score for TestScorer {}
1422+
13931423
impl Drop for TestScorer {
13941424
fn drop(&mut self) {
13951425
#[cfg(feature = "std")] {

0 commit comments

Comments
 (0)