From 67736b7480051e624a8c69bf61d15f22beecd38f Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Fri, 3 Jun 2022 21:35:37 -0700 Subject: [PATCH] Parameterize NetworkGraph with Logger P2PGossipSync logs before delegating to NetworkGraph in its EventHandler. In order to share this handling with RapidGossipSync, NetworkGraph needs to take a logger so that it can implement EventHandler instead. --- fuzz/src/full_stack.rs | 8 +- fuzz/src/process_network_graph.rs | 15 ++- fuzz/src/router.rs | 4 +- lightning-background-processor/src/lib.rs | 16 ++-- lightning-invoice/src/utils.rs | 17 ++-- lightning-rapid-gossip-sync/src/lib.rs | 26 ++++-- lightning-rapid-gossip-sync/src/processing.rs | 22 +++-- lightning/src/ln/channelmanager.rs | 20 ++-- lightning/src/ln/functional_test_utils.rs | 18 ++-- lightning/src/ln/functional_tests.rs | 10 +- lightning/src/ln/peer_handler.rs | 4 +- lightning/src/routing/gossip.rs | 86 +++++++++-------- lightning/src/routing/router.rs | 92 +++++++++++-------- lightning/src/routing/scoring.rs | 66 ++++++------- lightning/src/util/persist.rs | 4 +- 15 files changed, 225 insertions(+), 183 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index a59d78e1c..eb270f679 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -163,7 +163,7 @@ type ChannelMan = ChannelManager< EnforcingSigner, Arc, Arc, Arc, Arc, Arc>>, Arc, Arc, Arc, Arc>; -type PeerMan<'a> = PeerManager, Arc, Arc, Arc, Arc>>, Arc, IgnoringMessageHandler>; +type PeerMan<'a> = PeerManager, Arc, Arc>>, Arc, Arc>>, Arc, IgnoringMessageHandler>; struct MoneyLossDetector<'a> { manager: Arc, @@ -395,7 +395,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { // it's easier to just increment the counter here so the keys don't change. keys_manager.counter.fetch_sub(1, Ordering::AcqRel); let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret(Recipient::Node).unwrap()); - let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash())); + let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash(), Arc::clone(&logger))); let gossip_sync = Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger))); let scorer = FixedPenaltyScorer::with_penalty(0); @@ -460,7 +460,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { final_cltv_expiry_delta: 42, }; let random_seed_bytes: [u8; 32] = keys_manager.get_secure_random_bytes(); - let route = match find_route(&our_id, ¶ms, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) { + let route = match find_route(&our_id, ¶ms, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &random_seed_bytes) { Ok(route) => route, Err(_) => return, }; @@ -484,7 +484,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { final_cltv_expiry_delta: 42, }; let random_seed_bytes: [u8; 32] = keys_manager.get_secure_random_bytes(); - let mut route = match find_route(&our_id, ¶ms, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) { + let mut route = match find_route(&our_id, ¶ms, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &random_seed_bytes) { Ok(route) => route, Err(_) => return, }; diff --git a/fuzz/src/process_network_graph.rs b/fuzz/src/process_network_graph.rs index 118862569..ae38d678a 100644 --- a/fuzz/src/process_network_graph.rs +++ b/fuzz/src/process_network_graph.rs @@ -1,22 +1,27 @@ // Imports that need to be added manually +use lightning::util::logger::Logger; use lightning_rapid_gossip_sync::RapidGossipSync; + use utils::test_logger; +use std::sync::Arc; + /// Actual fuzz test, method signature and name are fixed -fn do_test(data: &[u8]) { +fn do_test(data: &[u8], out: Out) { let block_hash = bitcoin::BlockHash::default(); - let network_graph = lightning::routing::gossip::NetworkGraph::new(block_hash); + let logger: Arc = Arc::new(test_logger::TestLogger::new("".to_owned(), out)); + let network_graph = lightning::routing::gossip::NetworkGraph::new(block_hash, logger); let rapid_sync = RapidGossipSync::new(&network_graph); let _ = rapid_sync.update_network_graph(data); } /// Method that needs to be added manually, {name}_test -pub fn process_network_graph_test(data: &[u8], _out: Out) { - do_test(data); +pub fn process_network_graph_test(data: &[u8], out: Out) { + do_test(data, out); } /// Method that needs to be added manually, {name}_run #[no_mangle] pub extern "C" fn process_network_graph_run(data: *const u8, datalen: usize) { - do_test(unsafe { std::slice::from_raw_parts(data, datalen) }); + do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {}); } diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index ec12ff7e1..21fb2dc15 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -162,7 +162,7 @@ pub fn do_test(data: &[u8], out: Out) { let logger: Arc = Arc::new(test_logger::TestLogger::new("".to_owned(), out)); let our_pubkey = get_pubkey!(); - let net_graph = NetworkGraph::new(genesis_block(Network::Bitcoin).header.block_hash()); + let net_graph = NetworkGraph::new(genesis_block(Network::Bitcoin).header.block_hash(), Arc::clone(&logger)); let mut node_pks = HashSet::new(); let mut scid = 42; @@ -267,7 +267,7 @@ pub fn do_test(data: &[u8], out: Out) { final_value_msat: slice_to_be64(get_slice!(8)), final_cltv_expiry_delta: slice_to_be32(get_slice!(4)), }; - let _ = find_route(&our_pubkey, &route_params, &net_graph, + let _ = find_route(&our_pubkey, &route_params, &net_graph.read_only(), first_hops.map(|c| c.iter().collect::>()).as_ref().map(|a| a.as_slice()), Arc::clone(&logger), &scorer, &random_seed_bytes); } diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 2e947a704..3c891768d 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -94,7 +94,7 @@ const FIRST_NETWORK_PRUNE_TIMER: u64 = 1; struct DecoratingEventHandler< E: EventHandler, P: Deref>, - G: Deref, + G: Deref>, A: Deref, L: Deref, > @@ -106,7 +106,7 @@ where A::Target: chain::Access, L::Target: Logger { impl< E: EventHandler, P: Deref>, - G: Deref, + G: Deref>, A: Deref, L: Deref, > EventHandler for DecoratingEventHandler @@ -173,7 +173,7 @@ impl BackgroundProcessor { T: 'static + Deref + Send + Sync, K: 'static + Deref + Send + Sync, F: 'static + Deref + Send + Sync, - G: 'static + Deref + Send + Sync, + G: 'static + Deref> + Send + Sync, L: 'static + Deref + Send + Sync, P: 'static + Deref + Send + Sync, Descriptor: 'static + SocketDescriptor + Send + Sync, @@ -188,7 +188,7 @@ impl BackgroundProcessor { PM: 'static + Deref> + Send + Sync, S: 'static + Deref + Send + Sync, SC: WriteableScore<'a>, - RGS: 'static + Deref> + Send + RGS: 'static + Deref> + Send >( persister: PS, event_handler: EH, chain_monitor: M, channel_manager: CM, p2p_gossip_sync: Option, peer_manager: PM, logger: L, scorer: Option, @@ -442,16 +442,16 @@ mod tests { struct Node { node: Arc>, - p2p_gossip_sync: Option, Arc, Arc>>>, + p2p_gossip_sync: Option>>, Arc, Arc>>>, peer_manager: Arc, Arc, Arc, IgnoringMessageHandler>>, chain_monitor: Arc, persister: Arc, tx_broadcaster: Arc, - network_graph: Arc, + network_graph: Arc>>, logger: Arc, best_block: BestBlock, scorer: Arc>, - rapid_gossip_sync: Option>>> + rapid_gossip_sync: Option>>, Arc>>>, } impl Drop for Node { @@ -546,7 +546,7 @@ mod tests { let best_block = BestBlock::from_genesis(network); let params = ChainParameters { network, best_block }; let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster.clone(), logger.clone(), keys_manager.clone(), UserConfig::default(), params)); - let network_graph = Arc::new(NetworkGraph::new(genesis_block.header.block_hash())); + let network_graph = Arc::new(NetworkGraph::new(genesis_block.header.block_hash(), logger.clone())); let p2p_gossip_sync = Some(Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()))); let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new() )}; let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), &seed, logger.clone(), IgnoringMessageHandler{})); diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 04cfb3f14..d42bc503f 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -440,13 +440,13 @@ fn filter_channels(channels: Vec, min_inbound_capacity_msat: Opt } /// A [`Router`] implemented using [`find_route`]. -pub struct DefaultRouter, L: Deref> where L::Target: Logger { +pub struct DefaultRouter>, L: Deref> where L::Target: Logger { network_graph: G, logger: L, random_seed_bytes: Mutex<[u8; 32]>, } -impl, L: Deref> DefaultRouter where L::Target: Logger { +impl>, L: Deref> DefaultRouter where L::Target: Logger { /// Creates a new router using the given [`NetworkGraph`], a [`Logger`], and a randomness source /// `random_seed_bytes`. pub fn new(network_graph: G, logger: L, random_seed_bytes: [u8; 32]) -> Self { @@ -455,18 +455,19 @@ impl, L: Deref> DefaultRouter where L::Tar } } -impl, L: Deref, S: Score> Router for DefaultRouter +impl>, L: Deref, S: Score> Router for DefaultRouter where L::Target: Logger { fn find_route( &self, payer: &PublicKey, params: &RouteParameters, _payment_hash: &PaymentHash, first_hops: Option<&[&ChannelDetails]>, scorer: &S ) -> Result { + let network_graph = self.network_graph.read_only(); let random_seed_bytes = { let mut locked_random_seed_bytes = self.random_seed_bytes.lock().unwrap(); *locked_random_seed_bytes = sha256::Hash::hash(&*locked_random_seed_bytes).into_inner(); *locked_random_seed_bytes }; - find_route(payer, params, &*self.network_graph, first_hops, &*self.logger, scorer, &random_seed_bytes) + find_route(payer, params, &network_graph, first_hops, &*self.logger, scorer, &random_seed_bytes) } } @@ -566,12 +567,12 @@ mod test { final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32, }; let first_hops = nodes[0].node.list_usable_channels(); - let network_graph = node_cfgs[0].network_graph; + let network_graph = &node_cfgs[0].network_graph; let logger = test_utils::TestLogger::new(); let scorer = test_utils::TestScorer::with_penalty(0); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); let route = find_route( - &nodes[0].node.get_our_node_id(), &route_params, network_graph, + &nodes[0].node.get_our_node_id(), &route_params, &network_graph.read_only(), Some(&first_hops.iter().collect::>()), &logger, &scorer, &random_seed_bytes ).unwrap(); @@ -842,12 +843,12 @@ mod test { final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32, }; let first_hops = nodes[0].node.list_usable_channels(); - let network_graph = node_cfgs[0].network_graph; + let network_graph = &node_cfgs[0].network_graph; let logger = test_utils::TestLogger::new(); let scorer = test_utils::TestScorer::with_penalty(0); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); let route = find_route( - &nodes[0].node.get_our_node_id(), ¶ms, network_graph, + &nodes[0].node.get_our_node_id(), ¶ms, &network_graph.read_only(), Some(&first_hops.iter().collect::>()), &logger, &scorer, &random_seed_bytes ).unwrap(); let (payment_event, fwd_idx) = { diff --git a/lightning-rapid-gossip-sync/src/lib.rs b/lightning-rapid-gossip-sync/src/lib.rs index 278cede39..7880e11a6 100644 --- a/lightning-rapid-gossip-sync/src/lib.rs +++ b/lightning-rapid-gossip-sync/src/lib.rs @@ -32,8 +32,15 @@ //! use lightning::routing::gossip::NetworkGraph; //! use lightning_rapid_gossip_sync::RapidGossipSync; //! +//! # use lightning::util::logger::{Logger, Record}; +//! # struct FakeLogger {} +//! # impl Logger for FakeLogger { +//! # fn log(&self, record: &Record) { unimplemented!() } +//! # } +//! # let logger = FakeLogger {}; +//! //! let block_hash = genesis_block(Network::Bitcoin).header.block_hash(); -//! let network_graph = NetworkGraph::new(block_hash); +//! let network_graph = NetworkGraph::new(block_hash, &logger); //! let rapid_sync = RapidGossipSync::new(&network_graph); //! let new_last_sync_timestamp_result = rapid_sync.sync_network_graph_with_file_path("./rapid_sync.lngossip"); //! ``` @@ -63,6 +70,7 @@ use std::ops::Deref; use std::sync::atomic::{AtomicBool, Ordering}; use lightning::routing::gossip::NetworkGraph; +use lightning::util::logger::Logger; use crate::error::GraphSyncError; @@ -76,12 +84,13 @@ pub mod processing; /// See [crate-level documentation] for usage. /// /// [crate-level documentation]: crate -pub struct RapidGossipSync> { +pub struct RapidGossipSync>, L: Deref> +where L::Target: Logger { network_graph: NG, is_initial_sync_complete: AtomicBool } -impl> RapidGossipSync { +impl>, L: Deref> RapidGossipSync where L::Target: Logger { /// Instantiate a new [`RapidGossipSync`] instance pub fn new(network_graph: NG) -> Self { Self { @@ -128,6 +137,7 @@ mod tests { use lightning::ln::msgs::DecodeError; use lightning::routing::gossip::NetworkGraph; + use lightning::util::test_utils::TestLogger; use crate::RapidGossipSync; #[test] @@ -187,7 +197,8 @@ mod tests { let graph_sync_test_file = sync_test.get_test_file_path(); let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); assert_eq!(network_graph.read_only().channels().len(), 0); @@ -219,7 +230,8 @@ mod tests { #[test] fn measure_native_read_from_file() { let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); assert_eq!(network_graph.read_only().channels().len(), 0); @@ -254,14 +266,16 @@ pub mod bench { use lightning::ln::msgs::DecodeError; use lightning::routing::gossip::NetworkGraph; + use lightning::util::test_utils::TestLogger; use crate::RapidGossipSync; #[bench] fn bench_reading_full_graph_from_file(b: &mut Bencher) { let block_hash = genesis_block(Network::Bitcoin).block_hash(); + let logger = TestLogger::new(); b.iter(|| { - let network_graph = NetworkGraph::new(block_hash); + let network_graph = NetworkGraph::new(block_hash, &logger); let rapid_sync = RapidGossipSync::new(&network_graph); let sync_result = rapid_sync.sync_network_graph_with_file_path("./res/full_graph.lngossip"); if let Err(crate::error::GraphSyncError::DecodeError(DecodeError::Io(io_error))) = &sync_result { diff --git a/lightning-rapid-gossip-sync/src/processing.rs b/lightning-rapid-gossip-sync/src/processing.rs index 21c1ce29a..09693a76d 100644 --- a/lightning-rapid-gossip-sync/src/processing.rs +++ b/lightning-rapid-gossip-sync/src/processing.rs @@ -11,6 +11,7 @@ use lightning::ln::msgs::{ DecodeError, ErrorAction, LightningError, OptionalField, UnsignedChannelUpdate, }; use lightning::routing::gossip::NetworkGraph; +use lightning::util::logger::Logger; use lightning::util::ser::{BigSize, Readable}; use crate::error::GraphSyncError; @@ -26,7 +27,7 @@ const GOSSIP_PREFIX: [u8; 4] = [76, 68, 75, 1]; /// avoid malicious updates being able to trigger excessive memory allocation. const MAX_INITIAL_NODE_ID_VECTOR_CAPACITY: u32 = 50_000; -impl> RapidGossipSync { +impl>, L: Deref> RapidGossipSync where L::Target: Logger { /// Update network graph from binary data. /// Returns the last sync timestamp to be used the next time rapid sync data is queried. /// @@ -236,6 +237,7 @@ mod tests { use lightning::ln::msgs::DecodeError; use lightning::routing::gossip::NetworkGraph; + use lightning::util::test_utils::TestLogger; use crate::error::GraphSyncError; use crate::RapidGossipSync; @@ -243,7 +245,8 @@ mod tests { #[test] fn network_graph_fails_to_update_from_clipped_input() { let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); let example_input = vec![ 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247, @@ -282,7 +285,8 @@ mod tests { ]; let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); assert_eq!(network_graph.read_only().channels().len(), 0); @@ -315,7 +319,8 @@ mod tests { ]; let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); assert_eq!(network_graph.read_only().channels().len(), 0); @@ -351,7 +356,8 @@ mod tests { ]; let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); assert_eq!(network_graph.read_only().channels().len(), 0); @@ -417,7 +423,8 @@ mod tests { ]; let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); assert_eq!(network_graph.read_only().channels().len(), 0); @@ -476,7 +483,8 @@ mod tests { ]; let block_hash = genesis_block(Network::Bitcoin).block_hash(); - let network_graph = NetworkGraph::new(block_hash); + let logger = TestLogger::new(); + let network_graph = NetworkGraph::new(block_hash, &logger); assert_eq!(network_graph.read_only().channels().len(), 0); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index c787cedfa..990621c22 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -7358,8 +7358,8 @@ mod tests { final_cltv_expiry_delta: TEST_FINAL_CLTV, }; let route = find_route( - &nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None, - nodes[0].logger, &scorer, &random_seed_bytes + &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(), + None, nodes[0].logger, &scorer, &random_seed_bytes ).unwrap(); nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -7389,8 +7389,8 @@ mod tests { // To start (2), send a keysend payment but don't claim it. let payment_preimage = PaymentPreimage([42; 32]); let route = find_route( - &nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None, - nodes[0].logger, &scorer, &random_seed_bytes + &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(), + None, nodes[0].logger, &scorer, &random_seed_bytes ).unwrap(); let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -7453,8 +7453,9 @@ mod tests { let scorer = test_utils::TestScorer::with_penalty(0); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); let route = find_route( - &payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::>()), - nodes[0].logger, &scorer, &random_seed_bytes + &payer_pubkey, &route_params, &network_graph.read_only(), + Some(&first_hops.iter().collect::>()), nodes[0].logger, &scorer, + &random_seed_bytes ).unwrap(); let test_preimage = PaymentPreimage([42; 32]); @@ -7497,8 +7498,9 @@ mod tests { let scorer = test_utils::TestScorer::with_penalty(0); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); let route = find_route( - &payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::>()), - nodes[0].logger, &scorer, &random_seed_bytes + &payer_pubkey, &route_params, &network_graph.read_only(), + Some(&first_hops.iter().collect::>()), nodes[0].logger, &scorer, + &random_seed_bytes ).unwrap(); let test_preimage = PaymentPreimage([42; 32]); @@ -7690,7 +7692,7 @@ pub mod bench { _ => panic!(), } - let dummy_graph = NetworkGraph::new(genesis_hash); + let dummy_graph = NetworkGraph::new(genesis_hash, &logger_a); let mut payment_count: u64 = 0; macro_rules! send_payment { diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 594f02fc5..087312717 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -27,7 +27,7 @@ use util::test_utils::{panicking, TestChainMonitor}; use util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose}; use util::errors::APIError; use util::config::UserConfig; -use util::ser::{ReadableArgs, Writeable, Readable}; +use util::ser::{ReadableArgs, Writeable}; use bitcoin::blockdata::block::{Block, BlockHeader}; use bitcoin::blockdata::constants::genesis_block; @@ -257,7 +257,6 @@ pub struct TestChanMonCfg { pub persister: test_utils::TestPersister, pub logger: test_utils::TestLogger, pub keys_manager: test_utils::TestKeysInterface, - pub network_graph: NetworkGraph, } pub struct NodeCfg<'a> { @@ -267,7 +266,7 @@ pub struct NodeCfg<'a> { pub chain_monitor: test_utils::TestChainMonitor<'a>, pub keys_manager: &'a test_utils::TestKeysInterface, pub logger: &'a test_utils::TestLogger, - pub network_graph: &'a NetworkGraph, + pub network_graph: NetworkGraph<&'a test_utils::TestLogger>, pub node_seed: [u8; 32], pub features: InitFeatures, } @@ -278,8 +277,8 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> { pub chain_monitor: &'b test_utils::TestChainMonitor<'c>, pub keys_manager: &'b test_utils::TestKeysInterface, pub node: &'a ChannelManager, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestLogger>, - pub network_graph: &'c NetworkGraph, - pub gossip_sync: P2PGossipSync<&'c NetworkGraph, &'c test_utils::TestChainSource, &'c test_utils::TestLogger>, + pub network_graph: &'b NetworkGraph<&'c test_utils::TestLogger>, + pub gossip_sync: P2PGossipSync<&'b NetworkGraph<&'c test_utils::TestLogger>, &'c test_utils::TestChainSource, &'c test_utils::TestLogger>, pub node_seed: [u8; 32], pub network_payment_count: Rc>, pub network_chan_count: Rc>, @@ -311,7 +310,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { { let mut w = test_utils::TestVecWriter(Vec::new()); self.network_graph.write(&mut w).unwrap(); - let network_graph_deser = ::read(&mut io::Cursor::new(&w.0)).unwrap(); + let network_graph_deser = >::read(&mut io::Cursor::new(&w.0), self.logger).unwrap(); assert!(network_graph_deser == *self.network_graph); let gossip_sync = P2PGossipSync::new( &network_graph_deser, Some(self.chain_source), self.logger @@ -1923,9 +1922,8 @@ pub fn create_chanmon_cfgs(node_count: usize) -> Vec { let persister = test_utils::TestPersister::new(); let seed = [i as u8; 32]; let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet); - let network_graph = NetworkGraph::new(chain_source.genesis_hash); - chan_mon_cfgs.push(TestChanMonCfg{ tx_broadcaster, fee_estimator, chain_source, logger, persister, keys_manager, network_graph }); + chan_mon_cfgs.push(TestChanMonCfg{ tx_broadcaster, fee_estimator, chain_source, logger, persister, keys_manager }); } chan_mon_cfgs @@ -1946,7 +1944,7 @@ pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec(node_count: usize, cfgs: &'b Vec>()), - nodes[0].logger, &scorer, &random_seed_bytes + &payer_pubkey, &route_params, &network_graph.read_only(), + Some(&first_hops.iter().collect::>()), nodes[0].logger, &scorer, &random_seed_bytes ).unwrap(); let test_preimage = PaymentPreimage([42; 32]); diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index d86cddb13..2a026821f 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -387,7 +387,7 @@ impl Peer { /// issues such as overly long function definitions. /// /// (C-not exported) as Arcs don't make sense in bindings -pub type SimpleArcPeerManager = PeerManager>, Arc, Arc, Arc>>, Arc, Arc>; +pub type SimpleArcPeerManager = PeerManager>, Arc>>, Arc, Arc>>, Arc, 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 @@ -397,7 +397,7 @@ pub type SimpleArcPeerManager = PeerManager = PeerManager, &'e P2PGossipSync<&'g NetworkGraph, &'h C, &'f L>, &'f L, IgnoringMessageHandler>; +pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, SD, M, T, F, C, L> = PeerManager, &'e P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'f L, IgnoringMessageHandler>; /// A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls /// socket events into messages which it passes on to its [`MessageHandler`]. diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 903071993..e7cf2c330 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -28,7 +28,7 @@ use ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHan use ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, OptionalField, GossipTimestampFilter}; use ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, ReplyShortChannelIdsEnd}; use ln::msgs; -use util::ser::{Writeable, Readable, Writer}; +use util::ser::{Readable, ReadableArgs, Writeable, Writer}; use util::logger::{Logger, Level}; use util::events::{Event, EventHandler, MessageSendEvent, MessageSendEventsProvider}; use util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK}; @@ -122,30 +122,16 @@ impl Readable for NodeId { } /// Represents the network as nodes and channels between them -pub struct NetworkGraph { +pub struct NetworkGraph where L::Target: Logger { secp_ctx: Secp256k1, last_rapid_gossip_sync_timestamp: Mutex>, genesis_hash: BlockHash, + _logger: L, // Lock order: channels -> nodes channels: RwLock>, nodes: RwLock>, } -impl Clone for NetworkGraph { - fn clone(&self) -> Self { - let channels = self.channels.read().unwrap(); - let nodes = self.nodes.read().unwrap(); - let last_rapid_gossip_sync_timestamp = self.get_last_rapid_gossip_sync_timestamp(); - Self { - secp_ctx: Secp256k1::verification_only(), - genesis_hash: self.genesis_hash.clone(), - channels: RwLock::new(channels.clone()), - nodes: RwLock::new(nodes.clone()), - last_rapid_gossip_sync_timestamp: Mutex::new(last_rapid_gossip_sync_timestamp) - } - } -} - /// A read-only view of [`NetworkGraph`]. pub struct ReadOnlyNetworkGraph<'a> { channels: RwLockReadGuard<'a, BTreeMap>, @@ -198,7 +184,7 @@ impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate, }, ); -impl, C: Deref, L: Deref> EventHandler for P2PGossipSync +impl>, C: Deref, L: Deref> EventHandler for P2PGossipSync where C::Target: chain::Access, L::Target: Logger { fn handle_event(&self, event: &Event) { if let Event::PaymentPathFailed { payment_hash: _, rejected_by_dest: _, network_update, .. } = event { @@ -217,7 +203,7 @@ where C::Target: chain::Access, L::Target: Logger { /// /// Serves as an [`EventHandler`] for applying updates from [`Event::PaymentPathFailed`] to the /// [`NetworkGraph`]. -pub struct P2PGossipSync, C: Deref, L: Deref> +pub struct P2PGossipSync>, C: Deref, L: Deref> where C::Target: chain::Access, L::Target: Logger { network_graph: G, @@ -227,7 +213,7 @@ where C::Target: chain::Access, L::Target: Logger logger: L, } -impl, C: Deref, L: Deref> P2PGossipSync +impl>, C: Deref, L: Deref> P2PGossipSync where C::Target: chain::Access, L::Target: Logger { /// Creates a new tracker of the actual state of the network of channels and nodes, @@ -316,7 +302,7 @@ macro_rules! secp_verify_sig { }; } -impl, C: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync +impl>, C: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync where C::Target: chain::Access, L::Target: Logger { fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result { @@ -605,7 +591,7 @@ where C::Target: chain::Access, L::Target: Logger } } -impl, C: Deref, L: Deref> MessageSendEventsProvider for P2PGossipSync +impl>, C: Deref, L: Deref> MessageSendEventsProvider for P2PGossipSync where C::Target: chain::Access, L::Target: Logger, @@ -975,7 +961,7 @@ impl_writeable_tlv_based!(NodeInfo, { const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; -impl Writeable for NetworkGraph { +impl Writeable for NetworkGraph where L::Target: Logger { fn write(&self, writer: &mut W) -> Result<(), io::Error> { write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION); @@ -1001,8 +987,8 @@ impl Writeable for NetworkGraph { } } -impl Readable for NetworkGraph { - fn read(reader: &mut R) -> Result { +impl ReadableArgs for NetworkGraph where L::Target: Logger { + fn read(reader: &mut R, _logger: L) -> Result, DecodeError> { let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION); let genesis_hash: BlockHash = Readable::read(reader)?; @@ -1029,6 +1015,7 @@ impl Readable for NetworkGraph { Ok(NetworkGraph { secp_ctx: Secp256k1::verification_only(), genesis_hash, + _logger, channels: RwLock::new(channels), nodes: RwLock::new(nodes), last_rapid_gossip_sync_timestamp: Mutex::new(last_rapid_gossip_sync_timestamp), @@ -1036,7 +1023,7 @@ impl Readable for NetworkGraph { } } -impl fmt::Display for NetworkGraph { +impl fmt::Display for NetworkGraph where L::Target: Logger { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { writeln!(f, "Network map\n[Channels]")?; for (key, val) in self.channels.read().unwrap().iter() { @@ -1050,7 +1037,7 @@ impl fmt::Display for NetworkGraph { } } -impl PartialEq for NetworkGraph { +impl PartialEq for NetworkGraph where L::Target: Logger { fn eq(&self, other: &Self) -> bool { self.genesis_hash == other.genesis_hash && *self.channels.read().unwrap() == *other.channels.read().unwrap() && @@ -1058,12 +1045,13 @@ impl PartialEq for NetworkGraph { } } -impl NetworkGraph { +impl NetworkGraph where L::Target: Logger { /// Creates a new, empty, network graph. - pub fn new(genesis_hash: BlockHash) -> NetworkGraph { + pub fn new(genesis_hash: BlockHash, _logger: L) -> NetworkGraph { Self { secp_ctx: Secp256k1::verification_only(), genesis_hash, + _logger, channels: RwLock::new(BTreeMap::new()), nodes: RwLock::new(BTreeMap::new()), last_rapid_gossip_sync_timestamp: Mutex::new(None), @@ -1651,7 +1639,7 @@ mod tests { ReplyChannelRange, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT}; use util::test_utils; use util::logger::Logger; - use util::ser::{Readable, Writeable}; + use util::ser::{ReadableArgs, Writeable}; use util::events::{Event, EventHandler, MessageSendEvent, MessageSendEventsProvider}; use util::scid_utils::scid_from_parts; @@ -1675,13 +1663,15 @@ mod tests { use prelude::*; use sync::Arc; - fn create_network_graph() -> NetworkGraph { + fn create_network_graph() -> NetworkGraph> { let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); - NetworkGraph::new(genesis_hash) + let logger = Arc::new(test_utils::TestLogger::new()); + NetworkGraph::new(genesis_hash, logger) } - fn create_gossip_sync(network_graph: &NetworkGraph) -> ( - Secp256k1, P2PGossipSync<&NetworkGraph, Arc, Arc> + fn create_gossip_sync(network_graph: &NetworkGraph>) -> ( + Secp256k1, P2PGossipSync<&NetworkGraph>, + Arc, Arc> ) { let secp_ctx = Secp256k1::new(); let logger = Arc::new(test_utils::TestLogger::new()); @@ -1854,7 +1844,8 @@ mod tests { let valid_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); // Test if the UTXO lookups were not supported - let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); + let network_graph = NetworkGraph::new(genesis_hash, Arc::clone(&logger)); let mut gossip_sync = P2PGossipSync::new(&network_graph, None, Arc::clone(&logger)); match gossip_sync.handle_channel_announcement(&valid_announcement) { Ok(res) => assert!(res), @@ -1878,7 +1869,7 @@ mod tests { // Test if an associated transaction were not on-chain (or not confirmed). let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); *chain_source.utxo_ret.lock().unwrap() = Err(chain::AccessError::UnknownTx); - let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let network_graph = NetworkGraph::new(genesis_hash, Arc::clone(&logger)); gossip_sync = P2PGossipSync::new(&network_graph, Some(chain_source.clone()), Arc::clone(&logger)); let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| { @@ -1962,7 +1953,8 @@ mod tests { let secp_ctx = Secp256k1::new(); let logger: Arc = Arc::new(test_utils::TestLogger::new()); let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); - let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); + let network_graph = NetworkGraph::new(genesis_hash, Arc::clone(&logger)); let gossip_sync = P2PGossipSync::new(&network_graph, Some(chain_source.clone()), Arc::clone(&logger)); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); @@ -2065,7 +2057,7 @@ mod tests { let logger = test_utils::TestLogger::new(); let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); - let network_graph = NetworkGraph::new(genesis_hash); + let network_graph = NetworkGraph::new(genesis_hash, &logger); let gossip_sync = P2PGossipSync::new(&network_graph, Some(chain_source.clone()), &logger); let secp_ctx = Secp256k1::new(); @@ -2169,7 +2161,7 @@ mod tests { let logger = test_utils::TestLogger::new(); let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); - let network_graph = NetworkGraph::new(genesis_hash); + let network_graph = NetworkGraph::new(genesis_hash, &logger); let gossip_sync = P2PGossipSync::new(&network_graph, Some(chain_source.clone()), &logger); let secp_ctx = Secp256k1::new(); @@ -2382,7 +2374,9 @@ mod tests { assert!(!network_graph.read_only().nodes().is_empty()); assert!(!network_graph.read_only().channels().is_empty()); network_graph.write(&mut w).unwrap(); - assert!(::read(&mut io::Cursor::new(&w.0)).unwrap() == network_graph); + + let logger = Arc::new(test_utils::TestLogger::new()); + assert!(>::read(&mut io::Cursor::new(&w.0), logger).unwrap() == network_graph); } #[test] @@ -2392,7 +2386,9 @@ mod tests { let mut w = test_utils::TestVecWriter(Vec::new()); network_graph.write(&mut w).unwrap(); - let reassembled_network_graph: NetworkGraph = Readable::read(&mut io::Cursor::new(&w.0)).unwrap(); + + let logger = Arc::new(test_utils::TestLogger::new()); + let reassembled_network_graph: NetworkGraph<_> = ReadableArgs::read(&mut io::Cursor::new(&w.0), logger).unwrap(); assert!(reassembled_network_graph == network_graph); assert_eq!(reassembled_network_graph.get_last_rapid_gossip_sync_timestamp().unwrap(), 42); } @@ -2681,7 +2677,7 @@ mod tests { } fn do_handling_query_channel_range( - gossip_sync: &P2PGossipSync<&NetworkGraph, Arc, Arc>, + gossip_sync: &P2PGossipSync<&NetworkGraph>, Arc, Arc>, test_node_id: &PublicKey, msg: QueryChannelRange, expected_ok: bool, @@ -2754,18 +2750,20 @@ mod benches { #[bench] fn read_network_graph(bench: &mut Bencher) { + let logger = ::util::test_utils::TestLogger::new(); let mut d = ::routing::router::test_utils::get_route_file().unwrap(); let mut v = Vec::new(); d.read_to_end(&mut v).unwrap(); bench.iter(|| { - let _ = NetworkGraph::read(&mut std::io::Cursor::new(&v)).unwrap(); + let _ = NetworkGraph::read(&mut std::io::Cursor::new(&v), &logger).unwrap(); }); } #[bench] fn write_network_graph(bench: &mut Bencher) { + let logger = ::util::test_utils::TestLogger::new(); let mut d = ::routing::router::test_utils::get_route_file().unwrap(); - let net_graph = NetworkGraph::read(&mut d).unwrap(); + let net_graph = NetworkGraph::read(&mut d, &logger).unwrap(); bench.iter(|| { let _ = net_graph.encode(); }); diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 301ae76dd..90e658604 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -17,7 +17,7 @@ use bitcoin::secp256k1::PublicKey; use ln::channelmanager::ChannelDetails; use ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures}; use ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT}; -use routing::gossip::{DirectedChannelInfoWithUpdate, EffectiveCapacity, NetworkGraph, ReadOnlyNetworkGraph, NodeId, RoutingFees}; +use routing::gossip::{DirectedChannelInfoWithUpdate, EffectiveCapacity, ReadOnlyNetworkGraph, NodeId, RoutingFees}; use routing::scoring::{ChannelUsage, Score}; use util::ser::{Writeable, Readable, Writer}; use util::logger::{Level, Logger}; @@ -369,7 +369,7 @@ enum CandidateRouteHop<'a> { FirstHop { details: &'a ChannelDetails, }, - /// A hop found in the [`NetworkGraph`], where the channel capacity may or may not be known. + /// A hop found in the [`ReadOnlyNetworkGraph`], where the channel capacity may be unknown. PublicHop { info: DirectedChannelInfoWithUpdate<'a>, short_channel_id: u64, @@ -650,8 +650,8 @@ fn default_node_features() -> NodeFeatures { /// Private routing paths between a public node and the target may be included in `params.payee`. /// /// If some channels aren't announced, it may be useful to fill in `first_hops` with the results -/// from [`ChannelManager::list_usable_channels`]. If it is filled in, the view of our local -/// channels from [`NetworkGraph`] will be ignored, and only those in `first_hops` will be used. +/// from [`ChannelManager::list_usable_channels`]. If it is filled in, the view of these channels +/// from `network_graph` will be ignored, and only those in `first_hops` will be used. /// /// The fees on channels from us to the next hop are ignored as they are assumed to all be equal. /// However, the enabled/disabled bit on such channels as well as the `htlc_minimum_msat` / @@ -670,16 +670,17 @@ fn default_node_features() -> NodeFeatures { /// /// [`ChannelManager::list_usable_channels`]: crate::ln::channelmanager::ChannelManager::list_usable_channels /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed +/// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph pub fn find_route( - our_node_pubkey: &PublicKey, route_params: &RouteParameters, network: &NetworkGraph, - first_hops: Option<&[&ChannelDetails]>, logger: L, scorer: &S, random_seed_bytes: &[u8; 32] + our_node_pubkey: &PublicKey, route_params: &RouteParameters, + network_graph: &ReadOnlyNetworkGraph, first_hops: Option<&[&ChannelDetails]>, logger: L, + scorer: &S, random_seed_bytes: &[u8; 32] ) -> Result where L::Target: Logger { - let network_graph = network.read_only(); - let mut route = get_route(our_node_pubkey, &route_params.payment_params, &network_graph, first_hops, + let mut route = get_route(our_node_pubkey, &route_params.payment_params, network_graph, first_hops, route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, scorer, random_seed_bytes)?; - add_random_cltv_offset(&mut route, &route_params.payment_params, &network_graph, random_seed_bytes); + add_random_cltv_offset(&mut route, &route_params.payment_params, network_graph, random_seed_bytes); Ok(route) } @@ -1787,11 +1788,10 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters, /// /// Re-uses logic from `find_route`, so the restrictions described there also apply here. pub fn build_route_from_hops( - our_node_pubkey: &PublicKey, hops: &[PublicKey], route_params: &RouteParameters, network: &NetworkGraph, - logger: L, random_seed_bytes: &[u8; 32] + our_node_pubkey: &PublicKey, hops: &[PublicKey], route_params: &RouteParameters, + network_graph: &ReadOnlyNetworkGraph, logger: L, random_seed_bytes: &[u8; 32] ) -> Result where L::Target: Logger { - let network_graph = network.read_only(); let mut route = build_route_from_hops_internal( our_node_pubkey, hops, &route_params.payment_params, &network_graph, route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, random_seed_bytes)?; @@ -1926,7 +1926,7 @@ mod tests { // Using the same keys for LN and BTC ids fn add_channel( - gossip_sync: &P2PGossipSync, Arc, Arc>, + gossip_sync: &P2PGossipSync>>, Arc, Arc>, secp_ctx: &Secp256k1, node_1_privkey: &SecretKey, node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64 ) { let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); @@ -1958,7 +1958,7 @@ mod tests { } fn update_channel( - gossip_sync: &P2PGossipSync, Arc, Arc>, + gossip_sync: &P2PGossipSync>>, Arc, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, update: UnsignedChannelUpdate ) { let msghash = hash_to_message!(&Sha256dHash::hash(&update.encode()[..])[..]); @@ -1974,7 +1974,7 @@ mod tests { } fn add_or_update_node( - gossip_sync: &P2PGossipSync, Arc, Arc>, + gossip_sync: &P2PGossipSync>>, Arc, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, features: NodeFeatures, timestamp: u32 ) { let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey); @@ -2029,14 +2029,15 @@ mod tests { } fn build_line_graph() -> ( - Secp256k1, sync::Arc, P2PGossipSync, - sync::Arc, sync::Arc>, + Secp256k1, sync::Arc>>, + P2PGossipSync>>, sync::Arc, sync::Arc>, sync::Arc, sync::Arc, ) { let secp_ctx = Secp256k1::new(); let logger = Arc::new(test_utils::TestLogger::new()); let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); - let network_graph = Arc::new(NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash())); + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); + let network_graph = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger))); let gossip_sync = P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)); // Build network from our_id to node 19: @@ -2081,15 +2082,16 @@ mod tests { fn build_graph() -> ( Secp256k1, - sync::Arc, - P2PGossipSync, sync::Arc, sync::Arc>, + sync::Arc>>, + P2PGossipSync>>, sync::Arc, sync::Arc>, sync::Arc, sync::Arc, ) { let secp_ctx = Secp256k1::new(); let logger = Arc::new(test_utils::TestLogger::new()); let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); - let network_graph = Arc::new(NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash())); + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); + let network_graph = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger))); let gossip_sync = P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)); // Build network from our_id to node6: // @@ -3489,8 +3491,12 @@ mod tests { let scorer = test_utils::TestScorer::with_penalty(0); let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - get_route(&source_node_id, &payment_params, &NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()).read_only(), - Some(&our_chans.iter().collect::>()), route_val, 42, &test_utils::TestLogger::new(), &scorer, &random_seed_bytes) + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); + let logger = test_utils::TestLogger::new(); + let network_graph = NetworkGraph::new(genesis_hash, &logger); + let route = get_route(&source_node_id, &payment_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), route_val, 42, &logger, &scorer, &random_seed_bytes); + route } #[test] @@ -4882,8 +4888,9 @@ mod tests { // payment) htlc_minimum_msat. In the original algorithm, this resulted in node4's // "previous hop" being set to node 3, creating a loop in the path. let secp_ctx = Secp256k1::new(); + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); let logger = Arc::new(test_utils::TestLogger::new()); - let network = Arc::new(NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash())); + let network = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger))); let gossip_sync = P2PGossipSync::new(Arc::clone(&network), None, Arc::clone(&logger)); let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx); let scorer = test_utils::TestScorer::with_penalty(0); @@ -5148,8 +5155,9 @@ mod tests { // route over multiple channels with the same first hop. let secp_ctx = Secp256k1::new(); let (_, our_id, _, nodes) = get_nodes(&secp_ctx); + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); let logger = Arc::new(test_utils::TestLogger::new()); - let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let network_graph = NetworkGraph::new(genesis_hash, Arc::clone(&logger)); let scorer = test_utils::TestScorer::with_penalty(0); let payment_params = PaymentParameters::from_node_id(nodes[0]).with_features(InvoiceFeatures::known()); let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); @@ -5587,7 +5595,7 @@ mod tests { seed } #[cfg(not(feature = "no-std"))] - use util::ser::Readable; + use util::ser::ReadableArgs; #[test] #[cfg(not(feature = "no-std"))] @@ -5601,7 +5609,8 @@ mod tests { return; }, }; - let graph = NetworkGraph::read(&mut d).unwrap(); + let logger = test_utils::TestLogger::new(); + let graph = NetworkGraph::read(&mut d, &logger).unwrap(); let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); @@ -5617,7 +5626,6 @@ mod tests { let payment_params = PaymentParameters::from_node_id(dst); let amt = seed as u64 % 200_000_000; let params = ProbabilisticScoringParameters::default(); - let logger = test_utils::TestLogger::new(); let scorer = ProbabilisticScorer::new(params, &graph, &logger); if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() { continue 'load_endpoints; @@ -5638,7 +5646,8 @@ mod tests { return; }, }; - let graph = NetworkGraph::read(&mut d).unwrap(); + let logger = test_utils::TestLogger::new(); + let graph = NetworkGraph::read(&mut d, &logger).unwrap(); let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); @@ -5654,7 +5663,6 @@ mod tests { let payment_params = PaymentParameters::from_node_id(dst).with_features(InvoiceFeatures::known()); let amt = seed as u64 % 200_000_000; let params = ProbabilisticScoringParameters::default(); - let logger = test_utils::TestLogger::new(); let scorer = ProbabilisticScorer::new(params, &graph, &logger); if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() { continue 'load_endpoints; @@ -5700,9 +5708,10 @@ mod benches { use chain::keysinterface::{KeysManager,KeysInterface}; use ln::channelmanager::{ChannelCounterparty, ChannelDetails}; use ln::features::{InitFeatures, InvoiceFeatures}; + use routing::gossip::NetworkGraph; use routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters}; use util::logger::{Logger, Record}; - use util::test_utils::TestLogger; + use util::ser::ReadableArgs; use test::Bencher; @@ -5711,9 +5720,9 @@ mod benches { fn log(&self, _record: &Record) {} } - fn read_network_graph() -> NetworkGraph { + fn read_network_graph(logger: &DummyLogger) -> NetworkGraph<&DummyLogger> { let mut d = test_utils::get_route_file().unwrap(); - NetworkGraph::read(&mut d).unwrap() + NetworkGraph::read(&mut d, logger).unwrap() } fn payer_pubkey() -> PublicKey { @@ -5760,22 +5769,24 @@ mod benches { #[bench] fn generate_routes_with_zero_penalty_scorer(bench: &mut Bencher) { - let network_graph = read_network_graph(); + let logger = DummyLogger {}; + let network_graph = read_network_graph(&logger); let scorer = FixedPenaltyScorer::with_penalty(0); generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty()); } #[bench] fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Bencher) { - let network_graph = read_network_graph(); + let logger = DummyLogger {}; + let network_graph = read_network_graph(&logger); let scorer = FixedPenaltyScorer::with_penalty(0); generate_routes(bench, &network_graph, scorer, InvoiceFeatures::known()); } #[bench] fn generate_routes_with_probabilistic_scorer(bench: &mut Bencher) { - let logger = TestLogger::new(); - let network_graph = read_network_graph(); + let logger = DummyLogger {}; + let network_graph = read_network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let scorer = ProbabilisticScorer::new(params, &network_graph, &logger); generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty()); @@ -5783,15 +5794,16 @@ mod benches { #[bench] fn generate_mpp_routes_with_probabilistic_scorer(bench: &mut Bencher) { - let logger = TestLogger::new(); - let network_graph = read_network_graph(); + let logger = DummyLogger {}; + let network_graph = read_network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let scorer = ProbabilisticScorer::new(params, &network_graph, &logger); generate_routes(bench, &network_graph, scorer, InvoiceFeatures::known()); } fn generate_routes( - bench: &mut Bencher, graph: &NetworkGraph, mut scorer: S, features: InvoiceFeatures + bench: &mut Bencher, graph: &NetworkGraph<&DummyLogger>, mut scorer: S, + features: InvoiceFeatures ) { let nodes = graph.read_only().nodes().clone(); let payer = payer_pubkey(); diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index 7bf07ca45..bfcefc96f 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -28,7 +28,7 @@ //! # impl Logger for FakeLogger { //! # fn log(&self, record: &Record) { unimplemented!() } //! # } -//! # fn find_scored_route(payer: PublicKey, route_params: RouteParameters, network_graph: NetworkGraph) { +//! # fn find_scored_route(payer: PublicKey, route_params: RouteParameters, network_graph: NetworkGraph<&FakeLogger>) { //! # let logger = FakeLogger {}; //! # //! // Use the default channel penalties. @@ -43,7 +43,7 @@ //! let scorer = ProbabilisticScorer::new(params, &network_graph, &logger); //! # let random_seed_bytes = [42u8; 32]; //! -//! let route = find_route(&payer, &route_params, &network_graph, None, &logger, &scorer, &random_seed_bytes); +//! let route = find_route(&payer, &route_params, &network_graph.read_only(), None, &logger, &scorer, &random_seed_bytes); //! # } //! ``` //! @@ -293,7 +293,8 @@ pub type ProbabilisticScorer = ProbabilisticScorerUsingTime::, L: Deref, T: Time> where L::Target: Logger { +pub struct ProbabilisticScorerUsingTime>, L: Deref, T: Time> +where L::Target: Logger { params: ProbabilisticScoringParameters, network_graph: G, logger: L, @@ -389,7 +390,7 @@ struct DirectedChannelLiquidity, T: Time, U: Deref, L: Deref, T: Time> ProbabilisticScorerUsingTime where L::Target: Logger { +impl>, L: Deref, T: Time> ProbabilisticScorerUsingTime where L::Target: Logger { /// Creates a new scorer using the given scoring parameters for sending payments from a node /// through a network graph. pub fn new(params: ProbabilisticScoringParameters, network_graph: G, logger: L) -> Self { @@ -650,7 +651,7 @@ impl, T: Time, U: DerefMut> DirectedChanne } } -impl, L: Deref, T: Time> Score for ProbabilisticScorerUsingTime where L::Target: Logger { +impl>, L: Deref, T: Time> Score for ProbabilisticScorerUsingTime where L::Target: Logger { fn channel_penalty_msat( &self, short_channel_id: u64, source: &NodeId, target: &NodeId, usage: ChannelUsage ) -> u64 { @@ -1050,7 +1051,7 @@ mod approx { } } -impl, L: Deref, T: Time> Writeable for ProbabilisticScorerUsingTime where L::Target: Logger { +impl>, L: Deref, T: Time> Writeable for ProbabilisticScorerUsingTime where L::Target: Logger { #[inline] fn write(&self, w: &mut W) -> Result<(), io::Error> { write_tlv_fields!(w, { @@ -1060,7 +1061,7 @@ impl, L: Deref, T: Time> Writeable for Probabili } } -impl, L: Deref, T: Time> +impl>, L: Deref, T: Time> ReadableArgs<(ProbabilisticScoringParameters, G, L)> for ProbabilisticScorerUsingTime where L::Target: Logger { #[inline] fn read( @@ -1163,7 +1164,7 @@ mod tests { // `ProbabilisticScorer` tests /// A probabilistic scorer for testing with time that can be manually advanced. - type ProbabilisticScorer<'a> = ProbabilisticScorerUsingTime::<&'a NetworkGraph, &'a TestLogger, SinceEpoch>; + type ProbabilisticScorer<'a> = ProbabilisticScorerUsingTime::<&'a NetworkGraph<&'a TestLogger>, &'a TestLogger, SinceEpoch>; fn sender_privkey() -> SecretKey { SecretKey::from_slice(&[41; 32]).unwrap() @@ -1191,9 +1192,9 @@ mod tests { NodeId::from_pubkey(&recipient_pubkey()) } - fn network_graph() -> NetworkGraph { + fn network_graph(logger: &TestLogger) -> NetworkGraph<&TestLogger> { let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); - let mut network_graph = NetworkGraph::new(genesis_hash); + let mut network_graph = NetworkGraph::new(genesis_hash, logger); add_channel(&mut network_graph, 42, source_privkey(), target_privkey()); add_channel(&mut network_graph, 43, target_privkey(), recipient_privkey()); @@ -1201,7 +1202,7 @@ mod tests { } fn add_channel( - network_graph: &mut NetworkGraph, short_channel_id: u64, node_1_key: SecretKey, + network_graph: &mut NetworkGraph<&TestLogger>, short_channel_id: u64, node_1_key: SecretKey, node_2_key: SecretKey ) { let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); @@ -1234,7 +1235,8 @@ mod tests { } fn update_channel( - network_graph: &mut NetworkGraph, short_channel_id: u64, node_key: SecretKey, flags: u8 + network_graph: &mut NetworkGraph<&TestLogger>, short_channel_id: u64, node_key: SecretKey, + flags: u8 ) { let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); let secp_ctx = Secp256k1::new(); @@ -1291,7 +1293,7 @@ mod tests { fn liquidity_bounds_directed_from_lowest_node_id() { let logger = TestLogger::new(); let last_updated = SinceEpoch::now(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let mut scorer = ProbabilisticScorer::new(params, &network_graph, &logger) .with_channel(42, @@ -1366,7 +1368,7 @@ mod tests { fn resets_liquidity_upper_bound_when_crossed_by_lower_bound() { let logger = TestLogger::new(); let last_updated = SinceEpoch::now(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let mut scorer = ProbabilisticScorer::new(params, &network_graph, &logger) .with_channel(42, @@ -1424,7 +1426,7 @@ mod tests { fn resets_liquidity_lower_bound_when_crossed_by_upper_bound() { let logger = TestLogger::new(); let last_updated = SinceEpoch::now(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let mut scorer = ProbabilisticScorer::new(params, &network_graph, &logger) .with_channel(42, @@ -1481,7 +1483,7 @@ mod tests { #[test] fn increased_penalty_nearing_liquidity_upper_bound() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, ..ProbabilisticScoringParameters::zero_penalty() @@ -1527,7 +1529,7 @@ mod tests { fn constant_penalty_outside_liquidity_bounds() { let logger = TestLogger::new(); let last_updated = SinceEpoch::now(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, ..ProbabilisticScoringParameters::zero_penalty() @@ -1556,7 +1558,7 @@ mod tests { #[test] fn does_not_further_penalize_own_channel() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, ..ProbabilisticScoringParameters::zero_penalty() @@ -1584,7 +1586,7 @@ mod tests { #[test] fn sets_liquidity_lower_bound_on_downstream_failure() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, ..ProbabilisticScoringParameters::zero_penalty() @@ -1618,7 +1620,7 @@ mod tests { #[test] fn sets_liquidity_upper_bound_on_failure() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, ..ProbabilisticScoringParameters::zero_penalty() @@ -1652,7 +1654,7 @@ mod tests { #[test] fn reduces_liquidity_upper_bound_along_path_on_success() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, ..ProbabilisticScoringParameters::zero_penalty() @@ -1683,7 +1685,7 @@ mod tests { #[test] fn decays_liquidity_bounds_over_time() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, liquidity_offset_half_life: Duration::from_secs(10), @@ -1762,7 +1764,7 @@ mod tests { #[test] fn decays_liquidity_bounds_without_shift_overflow() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, liquidity_offset_half_life: Duration::from_secs(10), @@ -1793,7 +1795,7 @@ mod tests { #[test] fn restricts_liquidity_bounds_after_decay() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, liquidity_offset_half_life: Duration::from_secs(10), @@ -1837,7 +1839,7 @@ mod tests { #[test] fn restores_persisted_liquidity_bounds() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, liquidity_offset_half_life: Duration::from_secs(10), @@ -1873,7 +1875,7 @@ mod tests { #[test] fn decays_persisted_liquidity_bounds() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters { liquidity_penalty_multiplier_msat: 1_000, liquidity_offset_half_life: Duration::from_secs(10), @@ -1913,7 +1915,7 @@ mod tests { // Shows the scores of "realistic" sends of 100k sats over channels of 1-10m sats (with a // 50k sat reserve). let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let scorer = ProbabilisticScorer::new(params, &network_graph, &logger); let source = source_node_id(); @@ -1970,7 +1972,7 @@ mod tests { #[test] fn adds_base_penalty_to_liquidity_penalty() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let source = source_node_id(); let target = target_node_id(); let usage = ChannelUsage { @@ -1996,7 +1998,7 @@ mod tests { #[test] fn adds_amount_penalty_to_liquidity_penalty() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let source = source_node_id(); let target = target_node_id(); let usage = ChannelUsage { @@ -2025,7 +2027,7 @@ mod tests { #[test] fn calculates_log10_without_overflowing_u64_max_value() { let logger = TestLogger::new(); - let network_graph = network_graph(); + let network_graph = network_graph(&logger); let source = source_node_id(); let target = target_node_id(); let usage = ChannelUsage { @@ -2044,8 +2046,8 @@ mod tests { #[test] fn accounts_for_inflight_htlc_usage() { - let network_graph = network_graph(); let logger = TestLogger::new(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let scorer = ProbabilisticScorer::new(params, &network_graph, &logger); let source = source_node_id(); @@ -2064,8 +2066,8 @@ mod tests { #[test] fn removes_uncertainity_when_exact_liquidity_known() { - let network_graph = network_graph(); let logger = TestLogger::new(); + let network_graph = network_graph(&logger); let params = ProbabilisticScoringParameters::default(); let scorer = ProbabilisticScorer::new(params, &network_graph, &logger); let source = source_node_id(); diff --git a/lightning/src/util/persist.rs b/lightning/src/util/persist.rs index 117eff491..522c1c92a 100644 --- a/lightning/src/util/persist.rs +++ b/lightning/src/util/persist.rs @@ -38,7 +38,7 @@ pub trait Persister<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: fn persist_manager(&self, channel_manager: &ChannelManager) -> Result<(), io::Error>; /// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed. - fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), io::Error>; + fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), io::Error>; /// Persist the given [`WriteableScore`] to disk, returning an error if persistence failed. fn persist_scorer(&self, scorer: &S) -> Result<(), io::Error>; @@ -58,7 +58,7 @@ impl<'a, A: KVStorePersister, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Der } /// Persist the given [`NetworkGraph`] to disk with the name "network_graph", returning an error if persistence failed. - fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), io::Error> { + fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), io::Error> { self.persist("network_graph", network_graph) } -- 2.39.5