Skip to content

Commit

Permalink
Support OnionMessenger in functional_test_utils
Browse files Browse the repository at this point in the history
OnionMessenger is needed to write functional tests for ChannelManager's
OffersMessageHandler implementation. Also adds a TestMessageRouter,
which simply wraps DefaultMessageRouter for now.
  • Loading branch information
jkczyz committed Dec 16, 2023
1 parent ff2fc23 commit d70279d
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 10 deletions.
50 changes: 42 additions & 8 deletions lightning/src/ln/functional_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ 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::OnionMessenger;
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
use crate::sign::EntropySource;
Expand Down Expand Up @@ -388,6 +390,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,
Expand All @@ -407,6 +410,15 @@ type TestChannelManager<'node_cfg, 'chan_mon_cfg> = ChannelManager<
&'chan_mon_cfg test_utils::TestLogger,
>;

type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger<
&'node_cfg test_utils::TestKeysInterface,
&'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,
>;

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,
Expand All @@ -415,6 +427,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],
Expand All @@ -432,6 +445,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")]
Expand Down Expand Up @@ -2879,6 +2900,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,
Expand Down Expand Up @@ -2932,14 +2954,18 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
let connect_style = Rc::new(RefCell::new(ConnectStyle::random_style()));

for i in 0..node_count {
let onion_messenger = OnionMessenger::new(
cfgs[i].keys_manager, cfgs[i].keys_manager, cfgs[i].logger, &cfgs[i].message_router,
&chan_mgrs[i], IgnoringMessageHandler {},
);
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()));
nodes.push(Node{
chain_source: cfgs[i].chain_source, tx_broadcaster: cfgs[i].tx_broadcaster,
fee_estimator: cfgs[i].fee_estimator, router: &cfgs[i].router,
chain_monitor: &cfgs[i].chain_monitor, keys_manager: &cfgs[i].keys_manager,
node: &chan_mgrs[i], network_graph: cfgs[i].network_graph.as_ref(), gossip_sync,
node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),
node_seed: cfgs[i].node_seed, onion_messenger, network_chan_count: chan_count.clone(),
network_payment_count: payment_count.clone(), logger: cfgs[i].logger,
blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
connect_style: Rc::clone(&connect_style),
Expand All @@ -2954,16 +2980,24 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC

for i in 0..node_count {
for j in (i+1)..node_count {
nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init {
features: nodes[j].override_init_features.borrow().clone().unwrap_or_else(|| nodes[j].node.init_features()),
let node_id_i = nodes[i].node.get_our_node_id();
let node_id_j = nodes[j].node.get_our_node_id();

let init_i = msgs::Init {
features: nodes[i].init_features(&node_id_j),
networks: None,
remote_network_address: None,
}, true).unwrap();
nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init {
features: nodes[i].override_init_features.borrow().clone().unwrap_or_else(|| nodes[i].node.init_features()),
};
let init_j = msgs::Init {
features: nodes[j].init_features(&node_id_i),
networks: None,
remote_network_address: None,
}, false).unwrap();
};

nodes[i].node.peer_connected(&node_id_j, &init_j, true).unwrap();
nodes[j].node.peer_connected(&node_id_i, &init_i, false).unwrap();
nodes[i].onion_messenger.peer_connected(&node_id_j, &init_j, true).unwrap();
nodes[j].onion_messenger.peer_connected(&node_id_i, &init_i, false).unwrap();
}
}

Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5538,7 +5538,8 @@ fn test_key_derivation_params() {
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[0].logger));
let scorer = RwLock::new(test_utils::TestScorer::new());
let router = test_utils::TestRouter::new(network_graph.clone(), &scorer);
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)) };
let message_router = test_utils::TestMessageRouter::new(network_graph.clone());
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)) };
let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
node_cfgs.remove(0);
node_cfgs.insert(0, node);
Expand Down
30 changes: 29 additions & 1 deletion lightning/src/util/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{Destination, MessageRouter, OnionMessagePath};
use crate::onion_message::{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};
Expand Down Expand Up @@ -231,6 +231,34 @@ impl<'a> Drop for TestRouter<'a> {
}
}

pub struct TestMessageRouter<'a>{
inner: DefaultMessageRouter<Arc<NetworkGraph<&'a TestLogger>>, &'a TestLogger>,
}

impl<'a> TestMessageRouter<'a> {
pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>) -> Self {
Self { inner: DefaultMessageRouter::new(network_graph) }
}
}

impl<'a> MessageRouter for TestMessageRouter<'a> {
fn find_path(
&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
) -> Result<OnionMessagePath, ()> {
self.inner.find_path(sender, peers, destination)
}

fn create_blinded_paths<
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
>(
&self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
secp_ctx: &Secp256k1<T>
) -> Result<Vec<BlindedPath>, ()> {
self.inner.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
}
}


pub struct OnlyReadsKeysInterface {}

impl EntropySource for OnlyReadsKeysInterface {
Expand Down

0 comments on commit d70279d

Please sign in to comment.