Merge pull request #1496 from TheBlueMatt/2022-05-macro-function-bonus
authorArik Sosman <arik-so@users.noreply.github.com>
Thu, 9 Jun 2022 16:10:27 +0000 (12:10 -0400)
committerGitHub <noreply@github.com>
Thu, 9 Jun 2022 16:10:27 +0000 (12:10 -0400)
Make `expect_payment_failed_conditions` a function

26 files changed:
CHANGELOG.md
README.md
fuzz/src/full_stack.rs
fuzz/src/process_network_graph.rs
fuzz/src/router.rs
lightning-background-processor/Cargo.toml
lightning-background-processor/src/lib.rs
lightning-block-sync/Cargo.toml
lightning-invoice/Cargo.toml
lightning-invoice/src/utils.rs
lightning-net-tokio/Cargo.toml
lightning-persister/Cargo.toml
lightning-rapid-gossip-sync/Cargo.toml
lightning-rapid-gossip-sync/src/lib.rs
lightning-rapid-gossip-sync/src/processing.rs
lightning/Cargo.toml
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/peer_handler.rs
lightning/src/routing/gossip.rs
lightning/src/routing/router.rs
lightning/src/routing/scoring.rs
lightning/src/util/events.rs
lightning/src/util/persist.rs

index 84d5529d88be1a885405bc29c469067b95ad7e7d..1cae3010f4e3c62143a6ab04d23e8200875c5d71 100644 (file)
@@ -1,3 +1,151 @@
+# 0.0.107 - 2022-06-08
+
+## API Updates
+ * Channels larger than 16777215 sats (Wumbo!) are now supported and can be
+   enabled for inbound channels using
+   `ChannelHandshakeLimits::max_funding_satoshis` (#1425).
+ * Support for feature `option_zeroconf`, allowing immediate forwarding of
+   payments after channel opening. This is configured for outbound channels
+   using `ChannelHandshakeLimits::trust_own_funding_0conf` whereas
+   `ChannelManager::accept_inbound_channel_from_trusted_peer_0conf` has to be
+   used for accepting inbound channels (#1401, #1505).
+ * `ChannelManager::claim_funds` no longer returns a `bool` to indicate success.
+   Instead, an `Event::PaymentClaimed` is generated if the claim was successful.
+   Likewise, `ChannelManager::fail_htlc_backwards` no longer has a return value
+   (#1434).
+ * `lightning-rapid-gossip-sync` is a new crate for syncing gossip data from a
+   server, primarily aimed at mobile devices (#1155).
+ * `RapidGossipSync` can be passed to `BackgroundProcessor` in order to persist
+   the `NetworkGraph` and handle `NetworkUpdate`s during event handling (#1433,
+   #1517).
+ * `NetGraphMsgHandler` has been renamed to `P2PGossipSync`, the `network_graph`
+    module has been renamed to `gossip`, and `NetworkUpdate::ChannelClosed` has
+   been renamed `NetworkUpdate::ChannelFailure` (#1159).
+ * Added a `filtered_block_connected` method to `chain::Listen` and a default
+   implementation of `block_connected` for those fetching filtered instead of
+   full blocks (#1453).
+ * The `lightning-block-sync` crate's `BlockSource` trait methods now take
+   `&self` instead of `&mut self` (#1307).
+ * `inbound_payment` module is now public to allow for creating invoices without
+   a `ChannelManager` (#1384).
+ * `lightning-block-sync`'s `init` and `poll` modules support `&dyn BlockSource`
+   which can be determined at runtime (#1423).
+ * `lightning-invoice` crate's `utils` now accept an expiration time (#1422,
+   #1474).
+ * `Event::PaymentForwarded` includes `prev_channel_id` and `next_channel_id`
+   (#1419, #1475).
+ * `chain::Watch::release_pending_monitor_events`' return type now associates
+   `MonitorEvent`s with funding `OutPoints` (#1475).
+ * `lightning-background-processor` crate's `Persister` trait has been moved to
+   `lightning` crate's `util::persist` module, which now has a general
+   `KVStorePersister` trait. Blanket implementations of `Persister` and
+   `chainmonitor::Persist` are given for types implementing `KVStorePersister`.
+   ` lightning-persister`'s `FilesystemPersister` implements `KVStorePersister`
+   (#1417).
+ * `ChannelDetails` and `ChannelCounterparty` include fields for HTLC minimum
+   and maximum values (#1378).
+ * Added a `max_inbound_htlc_value_in_flight_percent_of_channel` field to
+   `ChannelHandshakeConfig`, capping the total value of outstanding inbound
+   HTLCs for a channel (#1444).
+ * `ProbabilisticScorer` is parameterized by a `Logger`, which it uses to log
+   channel liquidity updates or lack thereof (#1405).
+ * `ChannelDetails` has an `outbound_htlc_limit_msat` field, which should be
+   used in routing instead of `outbound_capacity_msat` (#1435).
+ * `ProbabilisticScorer`'s channel liquidities can be logged via
+   `debug_log_liquidity_stats` (#1460).
+ * `BackgroundProcessor` now takes an optional `WriteableScore` which it will
+   persist using the `Persister` trait's new `persist_scorer` method (#1416).
+ * Upgraded to `bitcoin` crate version 0.28.1 (#1389).
+ * `ShutdownScript::new_witness_program` now takes a `WitnessVersion` instead of
+   a `NonZeroU8` (#1389).
+ * Channels will no longer be automatically force closed when the counterparty
+   is disconnected due to incompatibility (#1429).
+ * `ChannelManager` methods for funding, accepting, and closing channels now
+   take a `counterparty_node_id` parameter, which has also been added as a field
+   to `Event::FundingGenerationReady` (#1479, #1485).
+ * `InvoicePayer::new` now takes a `Retry` enum (replacing the `RetryAttempts`
+   struct), which supports both attempt- and timeout-based retrying (#1418).
+ * `Score::channel_penalty_msat` takes a `ChannelUsage` struct, which contains
+   the capacity as an `EffectiveCapacity` enum and any potential in-flight HTLC
+   value, rather than a single `u64`. Used by `ProbabilisticScorer` for more
+   accurate penalties (#1456).
+ * `build_route_from_hops` is a new function useful for constructing a `Route`
+   given a specific list of public keys (#1491).
+ * `FundingLocked` message has been renamed `ChannelReady`, and related
+   identifiers have been renamed accordingly (#1506).
+ * `core2::io` or `std::io` (depending on feature flags `no-std` or `std`) is
+   exported as a `lightning::io` module (#1504).
+ * The deprecated `Scorer` has been removed in favor or `ProbabilisticScorer`
+   (#1512).
+
+## Performance Improvements
+ * `lightning-persister` crate's `FilesystemPersister` is faster by 15x (#1404).
+ * Log gossip query messages at `GOSSIP` instead of `TRACE` to avoid
+   overwhelming default logging (#1421).
+ * `PeerManager` supports processing messages from different peers in parallel,
+   and this is taken advantage of in gossip processing (#1023).
+ * Greatly reduced per-channel and per-node memory usage due to upgrade of
+   `secp256k1` crate to 0.22.1 and `bitcoin` crate to 0.28.1
+ * Reduced per-peer memory usage in `PeerManager` (#1472).
+
+## Spec Compliance
+ * `find_route` now assumes variable-length onions by default for nodes where
+   support for the feature is unknown (#1414).
+ * A `warn` message is now sent when receiving a `channel_reestablish` with an
+   old commitment transaction number rather than immediately force-closing the
+   channel (#1430).
+ * When a `channel_update` message is included in an onion error's `failuremsg`,
+   its message type is now encoded. Reading such messages is also supported
+   (#1465).
+
+## Bug Fixes
+ * Fixed a bug where crashing while persisting a `ChannelMonitorUpdate` for a
+   part of a multi-path payment could cause loss of funds due to a partial
+   payment claim on restart (#1434).
+ * `BackgroundProcessor` has been fixed to improve serialization reliability on
+   slow systems which can avoid force-closes (#1436).
+ * `gossip_timestamp_filter` filters are now honored when sending gossip to
+   peers (#1452).
+ * During a reorg, only force-close a channel if its funding transaction is
+   unconfirmed rather than as it loses confirmations (#1461).
+ * Fixed a rare panic in `lightning-net-tokio` when fetching a peer's socket
+   address after the connection has been closed caused by a race condition
+   (#1449).
+ * `find_route` will no longer return routes that would cause onion construction
+   to fail in some cases (#1476).
+ * `ProbabilisticScorer` uses more precision when approximating `log10` (#1406).
+
+## Serialization Compatibility
+ * All above new events/fields are ignored by prior clients. All above new
+   events/fields are not present when reading objects serialized by prior
+   versions of the library.
+ * `ChannelManager` serialization is no longer compatible with versions prior to
+   0.0.99 (#1401).
+ * Channels with `option_zeroconf` feature enabled (not required for 0-conf
+   channel use) will be unreadable by versions prior to 0.0.107 (#1401, #1505).
+
+In total, this release features 96 files changed, 9304 insertions, 4503
+deletions in 153 commits from 18 authors, in alphabetical order:
+ * Arik Sosman
+ * Devrandom
+ * Duncan Dean
+ * Elias Rohrer
+ * Jeffrey Czyz
+ * John Cantrell
+ * John Corser
+ * Jurvis Tan
+ * Justin Moon
+ * KaFai Choi
+ * Mateusz Faltyn
+ * Matt Corallo
+ * Valentine Wallace
+ * Viktor Tigerström
+ * Vincenzo Palazzo
+ * atalw
+ * dependabot[bot]
+ * shamardy
+
+
 # 0.0.106 - 2022-04-03
 
 ## API Updates
index dad0b39241576094ed5fe45d601d000bd0c3516d..3c34335c244af9d04734f2be010d424b06c498fd 100644 (file)
--- a/README.md
+++ b/README.md
@@ -50,6 +50,8 @@ Crates
   this is a simple alternative to implementing the required network stack, especially for those already using Tokio.
 6. [lightning-persister](./lightning-persister)
   Utilities to manage Rust-Lightning channel data persistence and retrieval.
+7. [lightning-rapid-gossip-sync](./lightning-rapid-gossip-sync)
+  Client for rapid gossip graph syncing, aimed primarily at mobile clients.
 
 About
 -----------
index a59d78e1c54cc35507b2ec4d0f3a66fb0753a01a..eb270f6794d60b52eb19e5fce6765f9724e87312 100644 (file)
@@ -163,7 +163,7 @@ type ChannelMan = ChannelManager<
        EnforcingSigner,
        Arc<chainmonitor::ChainMonitor<EnforcingSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
        Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>;
-type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan>, Arc<P2PGossipSync<Arc<NetworkGraph>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, Arc<dyn Logger>, IgnoringMessageHandler>;
+type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, Arc<dyn Logger>, IgnoringMessageHandler>;
 
 struct MoneyLossDetector<'a> {
        manager: Arc<ChannelMan>,
@@ -395,7 +395,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        // 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<dyn Logger>) {
                                        final_cltv_expiry_delta: 42,
                                };
                                let random_seed_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();
-                               let route = match find_route(&our_id, &params, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) {
+                               let route = match find_route(&our_id, &params, &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<dyn Logger>) {
                                        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, &params, &network_graph, None, Arc::clone(&logger), &scorer, &random_seed_bytes) {
+                               let mut route = match find_route(&our_id, &params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &random_seed_bytes) {
                                        Ok(route) => route,
                                        Err(_) => return,
                                };
index 118862569d039b47ea967c79207c463bbbe837f6..ae38d678a4d25aa127567216e761912feb434df3 100644 (file)
@@ -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<Out: test_logger::Output>(data: &[u8], out: Out) {
        let block_hash = bitcoin::BlockHash::default();
-       let network_graph = lightning::routing::gossip::NetworkGraph::new(block_hash);
+       let logger: Arc<dyn Logger> = 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<Out: test_logger::Output>(data: &[u8], _out: Out) {
-       do_test(data);
+pub fn process_network_graph_test<Out: test_logger::Output>(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 {});
 }
index ec12ff7e144e4708670ccc3aea79cd91d1201247..21fb2dc152a5fa9aa72f0b79dbca24ef63fad2a3 100644 (file)
@@ -162,7 +162,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
        let logger: Arc<dyn Logger> = 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<Out: test_logger::Output>(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::<Vec<_>>()).as_ref().map(|a| a.as_slice()),
                                                Arc::clone(&logger), &scorer, &random_seed_bytes);
                                }
index 5558eaaa67c43f49248fba1a4838c6a6143bdf41..7f8fff7bb5cced1c592c1bc6b0d554770e4a0b4b 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-background-processor"
-version = "0.0.106"
+version = "0.0.107"
 authors = ["Valentine Wallace <vwallace@protonmail.com>"]
 license = "MIT OR Apache-2.0"
 repository = "http://github.com/lightningdevkit/rust-lightning"
@@ -15,10 +15,10 @@ rustdoc-args = ["--cfg", "docsrs"]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning", features = ["std"] }
-lightning-rapid-gossip-sync = { version = "0.0.106", path = "../lightning-rapid-gossip-sync" }
+lightning = { version = "0.0.107", path = "../lightning", features = ["std"] }
+lightning-rapid-gossip-sync = { version = "0.0.107", path = "../lightning-rapid-gossip-sync" }
 
 [dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", features = ["_test_utils"] }
-lightning-invoice = { version = "0.14.0", path = "../lightning-invoice" }
-lightning-persister = { version = "0.0.106", path = "../lightning-persister" }
+lightning = { version = "0.0.107", path = "../lightning", features = ["_test_utils"] }
+lightning-invoice = { version = "0.15.0", path = "../lightning-invoice" }
+lightning-persister = { version = "0.0.107", path = "../lightning-persister" }
index 2e947a7041afdd92c4c8ac86c053c6781de24f26..b2edc2301efda2b39224cf557b82b313ef46890f 100644 (file)
@@ -40,8 +40,8 @@ use std::ops::Deref;
 ///   [`ChannelManager`] persistence should be done in the background.
 /// * Calling [`ChannelManager::timer_tick_occurred`] and [`PeerManager::timer_tick_occurred`]
 ///   at the appropriate intervals.
-/// * Calling [`NetworkGraph::remove_stale_channels`] (if a [`P2PGossipSync`] is provided to
-///   [`BackgroundProcessor::start`]).
+/// * Calling [`NetworkGraph::remove_stale_channels`] (if a [`GossipSync`] with a [`NetworkGraph`]
+///   is provided to [`BackgroundProcessor::start`]).
 ///
 /// It will also call [`PeerManager::process_events`] periodically though this shouldn't be relied
 /// upon as doing so may result in high latency.
@@ -89,31 +89,82 @@ const FIRST_NETWORK_PRUNE_TIMER: u64 = 60;
 #[cfg(test)]
 const FIRST_NETWORK_PRUNE_TIMER: u64 = 1;
 
+/// Either [`P2PGossipSync`] or [`RapidGossipSync`].
+pub enum GossipSync<
+       P: Deref<Target = P2PGossipSync<G, A, L>>,
+       R: Deref<Target = RapidGossipSync<G, L>>,
+       G: Deref<Target = NetworkGraph<L>>,
+       A: Deref,
+       L: Deref,
+>
+where A::Target: chain::Access, L::Target: Logger {
+       /// Gossip sync via the lightning peer-to-peer network as defined by BOLT 7.
+       P2P(P),
+       /// Rapid gossip sync from a trusted server.
+       Rapid(R),
+       /// No gossip sync.
+       None,
+}
+
+impl<
+       P: Deref<Target = P2PGossipSync<G, A, L>>,
+       R: Deref<Target = RapidGossipSync<G, L>>,
+       G: Deref<Target = NetworkGraph<L>>,
+       A: Deref,
+       L: Deref,
+> GossipSync<P, R, G, A, L>
+where A::Target: chain::Access, L::Target: Logger {
+       fn network_graph(&self) -> Option<&G> {
+               match self {
+                       GossipSync::P2P(gossip_sync) => Some(gossip_sync.network_graph()),
+                       GossipSync::Rapid(gossip_sync) => Some(gossip_sync.network_graph()),
+                       GossipSync::None => None,
+               }
+       }
+
+       fn prunable_network_graph(&self) -> Option<&G> {
+               match self {
+                       GossipSync::P2P(gossip_sync) => Some(gossip_sync.network_graph()),
+                       GossipSync::Rapid(gossip_sync) => {
+                               if gossip_sync.is_initial_sync_complete() {
+                                       Some(gossip_sync.network_graph())
+                               } else {
+                                       None
+                               }
+                       },
+                       GossipSync::None => None,
+               }
+       }
+}
 
 /// Decorates an [`EventHandler`] with common functionality provided by standard [`EventHandler`]s.
 struct DecoratingEventHandler<
+       'a,
        E: EventHandler,
-       P: Deref<Target = P2PGossipSync<G, A, L>>,
-       G: Deref<Target = NetworkGraph>,
+       PGS: Deref<Target = P2PGossipSync<G, A, L>>,
+       RGS: Deref<Target = RapidGossipSync<G, L>>,
+       G: Deref<Target = NetworkGraph<L>>,
        A: Deref,
        L: Deref,
 >
 where A::Target: chain::Access, L::Target: Logger {
        event_handler: E,
-       p2p_gossip_sync: Option<P>,
+       gossip_sync: &'a GossipSync<PGS, RGS, G, A, L>,
 }
 
 impl<
+       'a,
        E: EventHandler,
-       P: Deref<Target = P2PGossipSync<G, A, L>>,
-       G: Deref<Target = NetworkGraph>,
+       PGS: Deref<Target = P2PGossipSync<G, A, L>>,
+       RGS: Deref<Target = RapidGossipSync<G, L>>,
+       G: Deref<Target = NetworkGraph<L>>,
        A: Deref,
        L: Deref,
-> EventHandler for DecoratingEventHandler<E, P, G, A, L>
+> EventHandler for DecoratingEventHandler<'a, E, PGS, RGS, G, A, L>
 where A::Target: chain::Access, L::Target: Logger {
        fn handle_event(&self, event: &Event) {
-               if let Some(event_handler) = &self.p2p_gossip_sync {
-                       event_handler.handle_event(event);
+               if let Some(network_graph) = self.gossip_sync.network_graph() {
+                       network_graph.handle_event(event);
                }
                self.event_handler.handle_event(event);
        }
@@ -134,9 +185,9 @@ impl BackgroundProcessor {
        /// [`ChannelManager`]. See the `lightning-persister` crate for LDK's
        /// provided implementation.
        ///
-       /// [`Persister::persist_graph`] is responsible for writing out the [`NetworkGraph`] to disk. See
-       /// [`NetworkGraph::write`] for writing out a [`NetworkGraph`]. See the `lightning-persister` crate
-       /// for LDK's provided implementation.
+       /// [`Persister::persist_graph`] is responsible for writing out the [`NetworkGraph`] to disk, if
+       /// [`GossipSync`] is supplied. See [`NetworkGraph::write`] for writing out a [`NetworkGraph`].
+       /// See the `lightning-persister` crate for LDK's provided implementation.
        ///
        /// Typically, users should either implement [`Persister::persist_manager`] to never return an
        /// error or call [`join`] and handle any error that may arise. For the latter case,
@@ -151,9 +202,9 @@ impl BackgroundProcessor {
        ///
        /// # Rapid Gossip Sync
        ///
-       /// If rapid gossip sync is meant to run at startup, pass an optional [`RapidGossipSync`]
-       /// to `rapid_gossip_sync` to indicate to [`BackgroundProcessor`] not to prune the
-       /// [`NetworkGraph`] instance until the [`RapidGossipSync`] instance completes its first sync.
+       /// If rapid gossip sync is meant to run at startup, pass a [`RapidGossipSync`] to `gossip_sync`
+       /// to indicate that the [`BackgroundProcessor`] should not prune the [`NetworkGraph`] instance
+       /// until the [`RapidGossipSync`] instance completes its first sync.
        ///
        /// [top-level documentation]: BackgroundProcessor
        /// [`join`]: Self::join
@@ -173,7 +224,7 @@ impl BackgroundProcessor {
                T: 'static + Deref + Send + Sync,
                K: 'static + Deref + Send + Sync,
                F: 'static + Deref + Send + Sync,
-               G: 'static + Deref<Target = NetworkGraph> + Send + Sync,
+               G: 'static + Deref<Target = NetworkGraph<L>> + Send + Sync,
                L: 'static + Deref + Send + Sync,
                P: 'static + Deref + Send + Sync,
                Descriptor: 'static + SocketDescriptor + Send + Sync,
@@ -184,15 +235,14 @@ impl BackgroundProcessor {
                M: 'static + Deref<Target = ChainMonitor<Signer, CF, T, F, L, P>> + Send + Sync,
                CM: 'static + Deref<Target = ChannelManager<Signer, CW, T, K, F, L>> + Send + Sync,
                PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
+               RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
                UMH: 'static + Deref + Send + Sync,
                PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, L, UMH>> + Send + Sync,
                S: 'static + Deref<Target = SC> + Send + Sync,
                SC: WriteableScore<'a>,
-               RGS: 'static + Deref<Target = RapidGossipSync<G>> + Send
        >(
                persister: PS, event_handler: EH, chain_monitor: M, channel_manager: CM,
-               p2p_gossip_sync: Option<PGS>, peer_manager: PM, logger: L, scorer: Option<S>,
-               rapid_gossip_sync: Option<RGS>
+               gossip_sync: GossipSync<PGS, RGS, G, CA, L>, peer_manager: PM, logger: L, scorer: Option<S>,
        ) -> Self
        where
                CA::Target: 'static + chain::Access,
@@ -211,7 +261,10 @@ impl BackgroundProcessor {
                let stop_thread = Arc::new(AtomicBool::new(false));
                let stop_thread_clone = stop_thread.clone();
                let handle = thread::spawn(move || -> Result<(), std::io::Error> {
-                       let event_handler = DecoratingEventHandler { event_handler, p2p_gossip_sync: p2p_gossip_sync.as_ref().map(|t| t.deref()) };
+                       let event_handler = DecoratingEventHandler {
+                               event_handler,
+                               gossip_sync: &gossip_sync,
+                       };
 
                        log_trace!(logger, "Calling ChannelManager's timer_tick_occurred on startup");
                        channel_manager.timer_tick_occurred();
@@ -290,21 +343,10 @@ impl BackgroundProcessor {
                                if last_prune_call.elapsed().as_secs() > if have_pruned { NETWORK_PRUNE_TIMER } else { FIRST_NETWORK_PRUNE_TIMER } {
                                        // The network graph must not be pruned while rapid sync completion is pending
                                        log_trace!(logger, "Assessing prunability of network graph");
-                                       let graph_to_prune = match rapid_gossip_sync.as_ref() {
-                                               Some(rapid_sync) => {
-                                                       if rapid_sync.is_initial_sync_complete() {
-                                                               Some(rapid_sync.network_graph())
-                                                       } else {
-                                                               None
-                                                       }
-                                               },
-                                               None => p2p_gossip_sync.as_ref().map(|sync| sync.network_graph())
-                                       };
+                                       if let Some(network_graph) = gossip_sync.prunable_network_graph() {
+                                               network_graph.remove_stale_channels();
 
-                                       if let Some(network_graph_reference) = graph_to_prune {
-                                               network_graph_reference.remove_stale_channels();
-
-                                               if let Err(e) = persister.persist_graph(network_graph_reference) {
+                                               if let Err(e) = persister.persist_graph(network_graph) {
                                                        log_error!(logger, "Error: Failed to persist network graph, check your disk and permissions {}", e)
                                                }
 
@@ -337,8 +379,8 @@ impl BackgroundProcessor {
                        }
 
                        // Persist NetworkGraph on exit
-                       if let Some(ref gossip_sync) = p2p_gossip_sync {
-                               persister.persist_graph(gossip_sync.network_graph())?;
+                       if let Some(network_graph) = gossip_sync.network_graph() {
+                               persister.persist_graph(network_graph)?;
                        }
 
                        Ok(())
@@ -424,7 +466,7 @@ mod tests {
        use std::time::Duration;
        use lightning::routing::scoring::{FixedPenaltyScorer};
        use lightning_rapid_gossip_sync::RapidGossipSync;
-       use super::{BackgroundProcessor, FRESHNESS_TIMER};
+       use super::{BackgroundProcessor, GossipSync, FRESHNESS_TIMER};
 
        const EVENT_DEADLINE: u64 = 5 * FRESHNESS_TIMER;
 
@@ -440,18 +482,35 @@ mod tests {
 
        type ChainMonitor = chainmonitor::ChainMonitor<InMemorySigner, Arc<test_utils::TestChainSource>, Arc<test_utils::TestBroadcaster>, Arc<test_utils::TestFeeEstimator>, Arc<test_utils::TestLogger>, Arc<FilesystemPersister>>;
 
+       type PGS = Arc<P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>>;
+       type RGS = Arc<RapidGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestLogger>>>;
+
        struct Node {
                node: Arc<SimpleArcChannelManager<ChainMonitor, test_utils::TestBroadcaster, test_utils::TestFeeEstimator, test_utils::TestLogger>>,
-               p2p_gossip_sync: Option<Arc<P2PGossipSync<Arc<NetworkGraph>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>>>,
+               p2p_gossip_sync: PGS,
+               rapid_gossip_sync: RGS,
                peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, Arc<test_utils::TestLogger>, IgnoringMessageHandler>>,
                chain_monitor: Arc<ChainMonitor>,
                persister: Arc<FilesystemPersister>,
                tx_broadcaster: Arc<test_utils::TestBroadcaster>,
-               network_graph: Arc<NetworkGraph>,
+               network_graph: Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
                logger: Arc<test_utils::TestLogger>,
                best_block: BestBlock,
                scorer: Arc<Mutex<FixedPenaltyScorer>>,
-               rapid_gossip_sync: Option<Arc<RapidGossipSync<Arc<NetworkGraph>>>>
+       }
+
+       impl Node {
+               fn p2p_gossip_sync(&self) -> GossipSync<PGS, RGS, Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>> {
+                       GossipSync::P2P(self.p2p_gossip_sync.clone())
+               }
+
+               fn rapid_gossip_sync(&self) -> GossipSync<PGS, RGS, Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>> {
+                       GossipSync::Rapid(self.rapid_gossip_sync.clone())
+               }
+
+               fn no_gossip_sync(&self) -> GossipSync<PGS, RGS, Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>> {
+                       GossipSync::None
+               }
        }
 
        impl Drop for Node {
@@ -546,13 +605,13 @@ 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 p2p_gossip_sync = Some(Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone())));
+                       let network_graph = Arc::new(NetworkGraph::new(genesis_block.header.block_hash(), logger.clone()));
+                       let p2p_gossip_sync = Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()));
+                       let rapid_gossip_sync = Arc::new(RapidGossipSync::new(network_graph.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{}));
                        let scorer = Arc::new(Mutex::new(test_utils::TestScorer::with_penalty(0)));
-                       let rapid_gossip_sync = None;
-                       let node = Node { node: manager, p2p_gossip_sync, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block, scorer, rapid_gossip_sync };
+                       let node = Node { node: manager, p2p_gossip_sync, rapid_gossip_sync, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block, scorer };
                        nodes.push(node);
                }
 
@@ -650,7 +709,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(),  nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                macro_rules! check_persisted_data {
                        ($node: expr, $filepath: expr) => {
@@ -695,10 +754,7 @@ mod tests {
 
                // Check network graph is persisted
                let filepath = get_full_filepath("test_background_processor_persister_0".to_string(), "network_graph".to_string());
-               if let Some(ref handler) = nodes[0].p2p_gossip_sync {
-                       let network_graph = handler.network_graph();
-                       check_persisted_data!(network_graph, filepath.clone());
-               }
+               check_persisted_data!(nodes[0].network_graph, filepath.clone());
 
                // Check scorer is persisted
                let filepath = get_full_filepath("test_background_processor_persister_0".to_string(), "scorer".to_string());
@@ -715,7 +771,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
                loop {
                        let log_entries = nodes[0].logger.lines.lock().unwrap();
                        let desired_log = "Calling ChannelManager's timer_tick_occurred".to_string();
@@ -738,7 +794,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir).with_manager_error(std::io::ErrorKind::Other, "test"));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
                match bg_processor.join() {
                        Ok(_) => panic!("Expected error persisting manager"),
                        Err(e) => {
@@ -755,7 +811,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir).with_graph_error(std::io::ErrorKind::Other, "test"));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                match bg_processor.stop() {
                        Ok(_) => panic!("Expected error persisting network graph"),
@@ -773,7 +829,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir).with_scorer_error(std::io::ErrorKind::Other, "test"));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(),  nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(),  nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                match bg_processor.stop() {
                        Ok(_) => panic!("Expected error persisting scorer"),
@@ -796,7 +852,7 @@ mod tests {
                let event_handler = move |event: &Event| {
                        sender.send(handle_funding_generation_ready!(event, channel_value)).unwrap();
                };
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                // Open a channel and check that the FundingGenerationReady event was handled.
                begin_open_channel!(nodes[0], nodes[1], channel_value);
@@ -821,7 +877,7 @@ mod tests {
                let (sender, receiver) = std::sync::mpsc::sync_channel(1);
                let event_handler = move |event: &Event| sender.send(event.clone()).unwrap();
                let persister = Arc::new(Persister::new(data_dir));
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                // Force close the channel and check that the SpendableOutputs event was handled.
                nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id, &nodes[1].node.get_our_node_id()).unwrap();
@@ -845,7 +901,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(),  nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                loop {
                        let log_entries = nodes[0].logger.lines.lock().unwrap();
@@ -865,7 +921,6 @@ mod tests {
                let (sender, receiver) = std::sync::mpsc::sync_channel(1);
                let persister = Arc::new(Persister::new(data_dir.clone()).with_graph_persistence_notifier(sender));
                let network_graph = nodes[0].network_graph.clone();
-               let rapid_sync = Arc::new(RapidGossipSync::new(network_graph.clone()));
                let features = ChannelFeatures::empty();
                network_graph.add_channel_from_partial_announcement(42, 53, features, nodes[0].node.get_our_node_id(), nodes[1].node.get_our_node_id())
                        .expect("Failed to update channel from partial announcement");
@@ -874,7 +929,7 @@ mod tests {
                assert_eq!(network_graph.read_only().channels().len(), 1);
 
                let event_handler = |_: &_| {};
-               let background_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), Some(rapid_sync.clone()));
+               let background_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].rapid_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                loop {
                        let log_entries = nodes[0].logger.lines.lock().unwrap();
@@ -901,7 +956,7 @@ mod tests {
                        0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
                        0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
                ];
-               rapid_sync.update_network_graph(&initialization_input[..]).unwrap();
+               nodes[0].rapid_gossip_sync.update_network_graph(&initialization_input[..]).unwrap();
 
                // this should have added two channels
                assert_eq!(network_graph.read_only().channels().len(), 3);
@@ -928,7 +983,7 @@ mod tests {
                let router = DefaultRouter::new(Arc::clone(&nodes[0].network_graph), Arc::clone(&nodes[0].logger), random_seed_bytes);
                let invoice_payer = Arc::new(InvoicePayer::new(Arc::clone(&nodes[0].node), router, Arc::clone(&nodes[0].scorer), Arc::clone(&nodes[0].logger), |_: &_| {}, Retry::Attempts(2)));
                let event_handler = Arc::clone(&invoice_payer);
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].p2p_gossip_sync.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()), nodes[0].rapid_gossip_sync.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].no_gossip_sync(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
                assert!(bg_processor.stop().is_ok());
        }
 }
index 1d6e7f40accd8410ac0c7c42bb78f56665da4b7c..f67364807d958e73903b2755aaf5f3e7b6c0bc30 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-block-sync"
-version = "0.0.106"
+version = "0.0.107"
 authors = ["Jeffrey Czyz", "Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "http://github.com/lightningdevkit/rust-lightning"
@@ -19,7 +19,7 @@ rpc-client = [ "serde", "serde_json", "chunked_transfer" ]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.107", path = "../lightning" }
 futures = { version = "0.3" }
 tokio = { version = "1.0", features = [ "io-util", "net", "time" ], optional = true }
 serde = { version = "1.0", features = ["derive"], optional = true }
index 9382d66303f05fae9947549b12b0ddbba8e21b16..7f3d14391d4650edc859b76c075654c2df976377 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "lightning-invoice"
 description = "Data structures to parse and serialize BOLT11 lightning invoices"
-version = "0.14.0"
+version = "0.15.0"
 authors = ["Sebastian Geisler <sgeisler@wh2.tu-dresden.de>"]
 documentation = "https://docs.rs/lightning-invoice/"
 license = "MIT OR Apache-2.0"
@@ -20,7 +20,7 @@ std = ["bitcoin_hashes/std", "num-traits/std", "lightning/std", "bech32/std"]
 
 [dependencies]
 bech32 = { version = "0.8", default-features = false }
-lightning = { version = "0.0.106", path = "../lightning", default-features = false }
+lightning = { version = "0.0.107", path = "../lightning", default-features = false }
 secp256k1 = { version = "0.22", default-features = false, features = ["recovery", "alloc"] }
 num-traits = { version = "0.2.8", default-features = false }
 bitcoin_hashes = { version = "0.10", default-features = false }
@@ -28,5 +28,5 @@ hashbrown = { version = "0.11", optional = true }
 core2 = { version = "0.3.0", default-features = false, optional = true }
 
 [dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", default-features = false, features = ["_test_utils"] }
+lightning = { version = "0.0.107", path = "../lightning", default-features = false, features = ["_test_utils"] }
 hex = "0.4"
index 04cfb3f147099181b37ed8e6dee70d989f983233..d42bc503f05df6679db447ac0ddf9c29ee927320 100644 (file)
@@ -440,13 +440,13 @@ fn filter_channels(channels: Vec<ChannelDetails>, min_inbound_capacity_msat: Opt
 }
 
 /// A [`Router`] implemented using [`find_route`].
-pub struct DefaultRouter<G: Deref<Target = NetworkGraph>, L: Deref> where L::Target: Logger {
+pub struct DefaultRouter<G: Deref<Target = NetworkGraph<L>>, L: Deref> where L::Target: Logger {
        network_graph: G,
        logger: L,
        random_seed_bytes: Mutex<[u8; 32]>,
 }
 
-impl<G: Deref<Target = NetworkGraph>, L: Deref> DefaultRouter<G, L> where L::Target: Logger {
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> DefaultRouter<G, L> 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<G: Deref<Target = NetworkGraph>, L: Deref> DefaultRouter<G, L> where L::Tar
        }
 }
 
-impl<G: Deref<Target = NetworkGraph>, L: Deref, S: Score> Router<S> for DefaultRouter<G, L>
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Score> Router<S> for DefaultRouter<G, L>
 where L::Target: Logger {
        fn find_route(
                &self, payer: &PublicKey, params: &RouteParameters, _payment_hash: &PaymentHash,
                first_hops: Option<&[&ChannelDetails]>, scorer: &S
        ) -> Result<Route, LightningError> {
+               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::<Vec<_>>()), &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(), &params, network_graph,
+                       &nodes[0].node.get_our_node_id(), &params, &network_graph.read_only(),
                        Some(&first_hops.iter().collect::<Vec<_>>()), &logger, &scorer, &random_seed_bytes
                ).unwrap();
                let (payment_event, fwd_idx) = {
index 08c649f79bc1f885e3dabe06a17c7b250733cdb7..24b9821b15cee0f4d0bb4d0f84703e6aed66d116 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-net-tokio"
-version = "0.0.106"
+version = "0.0.107"
 authors = ["Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning/"
@@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.107", path = "../lightning" }
 tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net", "time" ] }
 
 [dev-dependencies]
index 1bf4c5d2e75f87a1b759963b09adad28cadb838e..1b62de987b743aa78a62e2a6a95a874ba4bbe893 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-persister"
-version = "0.0.106"
+version = "0.0.107"
 authors = ["Valentine Wallace", "Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning/"
@@ -17,11 +17,11 @@ _bench_unstable = ["lightning/_bench_unstable"]
 
 [dependencies]
 bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.107", path = "../lightning" }
 libc = "0.2"
 
 [target.'cfg(windows)'.dependencies]
 winapi = { version = "0.3", features = ["winbase"] }
 
 [dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", features = ["_test_utils"] }
+lightning = { version = "0.0.107", path = "../lightning", features = ["_test_utils"] }
index 58446a46e7d8f02c64941296f00d8c6e1d4f1818..734749caec53d0174fba5bef0d9bd7183442855b 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning-rapid-gossip-sync"
-version = "0.0.106"
+version = "0.0.107"
 authors = ["Arik Sosman <git@arik.io>"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning"
@@ -13,8 +13,8 @@ Utility to process gossip routing data from Rapid Gossip Sync Server.
 _bench_unstable = []
 
 [dependencies]
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.107", path = "../lightning" }
 bitcoin = { version = "0.28.1", default-features = false }
 
 [dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", features = ["_test_utils"] }
+lightning = { version = "0.0.107", path = "../lightning", features = ["_test_utils"] }
index 278cede397411720415b89d20a6c9ccaecb1160d..7880e11a60ea45c824dfceb3e75d6ee9d48610c8 100644 (file)
 //! 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<NG: Deref<Target=NetworkGraph>> {
+pub struct RapidGossipSync<NG: Deref<Target=NetworkGraph<L>>, L: Deref>
+where L::Target: Logger {
        network_graph: NG,
        is_initial_sync_complete: AtomicBool
 }
 
-impl<NG: Deref<Target=NetworkGraph>> RapidGossipSync<NG> {
+impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> 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 {
index 21c1ce29a99142f427dd8f9947f8fe0c94cfbcfa..09693a76d6f3b4868424d863ddd97399802974f9 100644 (file)
@@ -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<NG: Deref<Target=NetworkGraph>> RapidGossipSync<NG> {
+impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> 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);
 
index f9321c7b649fceaf7ae1ccfbabfe0231733f2a72..cec724cf6cd9fb9f8f4cb95808995705a374df05 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lightning"
-version = "0.0.106"
+version = "0.0.107"
 authors = ["Matt Corallo"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/lightningdevkit/rust-lightning/"
index 4daaf630ac4e57bd7c96ed73e401badf986236d1..9737738afb5ae653cf63b035820a9740a674392b 100644 (file)
@@ -4658,9 +4658,17 @@ impl<Signer: Sign> Channel<Signer> {
                } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurChannelReady as u32) {
                        // We got a reorg but not enough to trigger a force close, just ignore.
                        false
-               } else if self.channel_state < ChannelState::ChannelFunded as u32 {
-                       panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
                } else {
+                       if self.channel_state < ChannelState::ChannelFunded as u32 {
+                               // We should never see a funding transaction on-chain until we've received
+                               // funding_signed (if we're an outbound channel), or seen funding_generated (if we're
+                               // an inbound channel - before that we have no known funding TXID). The fuzzer,
+                               // however, may do this and we shouldn't treat it as a bug.
+                               #[cfg(not(fuzzing))]
+                               panic!("Started confirming a channel in a state pre-FundingSent: {}.\n\
+                                       Do NOT broadcast a funding transaction manually - let LDK do it for you!",
+                                       self.channel_state);
+                       }
                        // We got a reorg but not enough to trigger a force close, just ignore.
                        false
                };
index c787cedfad3a7da3a47e719c842689ee94f62545..3fa136e9af862403f5957dd245c53d6951ccf3b1 100644 (file)
@@ -3620,7 +3620,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        // Fail a list of HTLCs that were just freed from the holding cell. The HTLCs need to be
        // failed backwards or, if they were one of our outgoing HTLCs, then their failure needs to
        // be surfaced to the user.
-       fn fail_holding_cell_htlcs(&self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32]) {
+       fn fail_holding_cell_htlcs(
+               &self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32],
+               _counterparty_node_id: &PublicKey
+       ) {
                for (htlc_src, payment_hash) in htlcs_to_fail.drain(..) {
                        match htlc_src {
                                HTLCSource::PreviousHopData(HTLCPreviousHopData { .. }) => {
@@ -4828,7 +4831,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
                        }
                };
-               self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id);
+               self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id, counterparty_node_id);
                match res {
                        Ok((pending_forwards, mut pending_failures, finalized_claim_htlcs,
                                short_channel_id, channel_outpoint)) =>
@@ -4968,7 +4971,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        }
                };
                post_handle_chan_restoration!(self, chan_restoration_res);
-               self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id);
+               self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id, counterparty_node_id);
 
                if let Some(channel_ready_msg) = need_lnd_workaround {
                        self.internal_channel_ready(counterparty_node_id, &channel_ready_msg)?;
@@ -5066,7 +5069,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                match chan.maybe_free_holding_cell_htlcs(&self.logger) {
                                        Ok((commitment_opt, holding_cell_failed_htlcs)) => {
                                                if !holding_cell_failed_htlcs.is_empty() {
-                                                       failed_htlcs.push((holding_cell_failed_htlcs, *channel_id));
+                                                       failed_htlcs.push((
+                                                               holding_cell_failed_htlcs,
+                                                               *channel_id,
+                                                               chan.get_counterparty_node_id()
+                                                       ));
                                                }
                                                if let Some((commitment_update, monitor_update)) = commitment_opt {
                                                        if let Err(e) = self.chain_monitor.update_channel(chan.get_funding_txo().unwrap(), monitor_update) {
@@ -5094,8 +5101,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                }
 
                let has_update = has_monitor_update || !failed_htlcs.is_empty() || !handle_errors.is_empty();
-               for (failures, channel_id) in failed_htlcs.drain(..) {
-                       self.fail_holding_cell_htlcs(failures, channel_id);
+               for (failures, channel_id, counterparty_node_id) in failed_htlcs.drain(..) {
+                       self.fail_holding_cell_htlcs(failures, channel_id, &counterparty_node_id);
                }
 
                for (counterparty_node_id, err) in handle_errors.drain(..) {
@@ -7358,8 +7365,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 +7396,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 +7460,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::<Vec<_>>()),
-                       nodes[0].logger, &scorer, &random_seed_bytes
+                       &payer_pubkey, &route_params, &network_graph.read_only(),
+                       Some(&first_hops.iter().collect::<Vec<_>>()), nodes[0].logger, &scorer,
+                       &random_seed_bytes
                ).unwrap();
 
                let test_preimage = PaymentPreimage([42; 32]);
@@ -7497,8 +7505,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::<Vec<_>>()),
-                       nodes[0].logger, &scorer, &random_seed_bytes
+                       &payer_pubkey, &route_params, &network_graph.read_only(),
+                       Some(&first_hops.iter().collect::<Vec<_>>()), nodes[0].logger, &scorer,
+                       &random_seed_bytes
                ).unwrap();
 
                let test_preimage = PaymentPreimage([42; 32]);
@@ -7690,7 +7699,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 {
index 2cada934e56cab6515a58f6f00ef3bc08c56f7f2..abd17740356b8621a44f56b9efc4cafe3092a893 100644 (file)
@@ -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<EnforcingSigner, &'b TestChainMonitor<'c>, &'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<RefCell<u8>>,
        pub network_chan_count: Rc<RefCell<u32>>,
@@ -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 = <NetworkGraph>::read(&mut io::Cursor::new(&w.0)).unwrap();
+                               let network_graph_deser = <NetworkGraph<_>>::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
@@ -1933,9 +1932,8 @@ pub fn create_chanmon_cfgs(node_count: usize) -> Vec<TestChanMonCfg> {
                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
@@ -1956,7 +1954,7 @@ pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec<TestChanMon
                        keys_manager: &chanmon_cfgs[i].keys_manager,
                        node_seed: seed,
                        features: InitFeatures::known(),
-                       network_graph: &chanmon_cfgs[i].network_graph,
+                       network_graph: NetworkGraph::new(chanmon_cfgs[i].chain_source.genesis_hash, &chanmon_cfgs[i].logger),
                });
        }
 
@@ -2002,7 +2000,7 @@ 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 gossip_sync = P2PGossipSync::new(cfgs[i].network_graph, None, cfgs[i].logger);
+               let gossip_sync = P2PGossipSync::new(&cfgs[i].network_graph, None, cfgs[i].logger);
                nodes.push(Node{
                        chain_source: cfgs[i].chain_source, tx_broadcaster: cfgs[i].tx_broadcaster,
                        chain_monitor: &cfgs[i].chain_monitor, keys_manager: &cfgs[i].keys_manager,
index db41777f9957611bb02b556111297033ed4b1ad3..3298db0dbd4ef582add1f81f95ba1eacab3734bb 100644 (file)
@@ -23,6 +23,7 @@ use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId, RAAC
 use ln::channel::{Channel, ChannelError};
 use ln::{chan_utils, onion_utils};
 use ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight, HTLCOutputInCommitment};
+use routing::gossip::NetworkGraph;
 use routing::router::{PaymentParameters, Route, RouteHop, RouteParameters, find_route, get_route};
 use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
 use ln::msgs;
@@ -5802,7 +5803,8 @@ fn test_key_derivation_params() {
        let seed = [42; 32];
        let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
        let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[0].chain_source), &chanmon_cfgs[0].tx_broadcaster, &chanmon_cfgs[0].logger, &chanmon_cfgs[0].fee_estimator, &chanmon_cfgs[0].persister, &keys_manager);
-       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, chain_monitor, keys_manager: &keys_manager, network_graph: &chanmon_cfgs[0].network_graph, node_seed: seed, features: InitFeatures::known() };
+       let network_graph = NetworkGraph::new(chanmon_cfgs[0].chain_source.genesis_hash, &chanmon_cfgs[0].logger);
+       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, chain_monitor, keys_manager: &keys_manager, network_graph, node_seed: seed, features: InitFeatures::known() };
        let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        node_cfgs.remove(0);
        node_cfgs.insert(0, node);
@@ -9860,7 +9862,7 @@ fn test_keysend_payments_to_public_node() {
        };
        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, None, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
+       let route = find_route(&payer_pubkey, &route_params, &network_graph.read_only(), None, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
 
        let test_preimage = PaymentPreimage([42; 32]);
        let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(test_preimage)).unwrap();
@@ -9896,8 +9898,8 @@ fn test_keysend_payments_to_private_node() {
        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::<Vec<_>>()),
-               nodes[0].logger, &scorer, &random_seed_bytes
+               &payer_pubkey, &route_params, &network_graph.read_only(),
+               Some(&first_hops.iter().collect::<Vec<_>>()), nodes[0].logger, &scorer, &random_seed_bytes
        ).unwrap();
 
        let test_preimage = PaymentPreimage([42; 32]);
index d86cddb13dbc66162c52af7128f0c3c180688532..2a026821f8adf91a9f0d2ba9bfdacbc861e1db48 100644 (file)
@@ -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<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph>, Arc<C>, Arc<L>>>, Arc<L>, Arc<IgnoringMessageHandler>>;
+pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<L>, Arc<IgnoringMessageHandler>>;
 
 /// 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<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArc
 /// helps with issues such as long function definitions.
 ///
 /// (C-not exported) as Arcs don't make sense in bindings
-pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'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<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'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`].
index 52cda7173ad486baa006747d97a809d8ab9cf8e8..f404e77b2b825ba894e4a193d693eb222cbbf769 100644 (file)
@@ -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,28 +122,16 @@ impl Readable for NodeId {
 }
 
 /// Represents the network as nodes and channels between them
-pub struct NetworkGraph {
+pub struct NetworkGraph<L: Deref> where L::Target: Logger {
+       secp_ctx: Secp256k1<secp256k1::VerifyOnly>,
        last_rapid_gossip_sync_timestamp: Mutex<Option<u32>>,
        genesis_hash: BlockHash,
+       logger: L,
        // Lock order: channels -> nodes
        channels: RwLock<BTreeMap<u64, ChannelInfo>>,
        nodes: RwLock<BTreeMap<NodeId, NodeInfo>>,
 }
 
-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 {
-                       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<u64, ChannelInfo>>,
@@ -196,17 +184,6 @@ impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate,
        },
 );
 
-impl<G: Deref<Target=NetworkGraph>, C: Deref, L: Deref> EventHandler for P2PGossipSync<G, C, L>
-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 {
-                       if let Some(network_update) = network_update {
-                               self.handle_network_update(network_update);
-                       }
-               }
-       }
-}
-
 /// Receives and validates network updates from peers,
 /// stores authentic and relevant data as a network graph.
 /// This network graph is then used for routing payments.
@@ -215,10 +192,9 @@ where C::Target: chain::Access, L::Target: Logger {
 ///
 /// Serves as an [`EventHandler`] for applying updates from [`Event::PaymentPathFailed`] to the
 /// [`NetworkGraph`].
-pub struct P2PGossipSync<G: Deref<Target=NetworkGraph>, C: Deref, L: Deref>
+pub struct P2PGossipSync<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref>
 where C::Target: chain::Access, L::Target: Logger
 {
-       secp_ctx: Secp256k1<secp256k1::VerifyOnly>,
        network_graph: G,
        chain_access: Option<C>,
        full_syncs_requested: AtomicUsize,
@@ -226,7 +202,7 @@ where C::Target: chain::Access, L::Target: Logger
        logger: L,
 }
 
-impl<G: Deref<Target=NetworkGraph>, C: Deref, L: Deref> P2PGossipSync<G, C, L>
+impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> P2PGossipSync<G, C, L>
 where C::Target: chain::Access, L::Target: Logger
 {
        /// Creates a new tracker of the actual state of the network of channels and nodes,
@@ -236,7 +212,6 @@ where C::Target: chain::Access, L::Target: Logger
        /// channel owners' keys.
        pub fn new(network_graph: G, chain_access: Option<C>, logger: L) -> Self {
                P2PGossipSync {
-                       secp_ctx: Secp256k1::verification_only(),
                        network_graph,
                        full_syncs_requested: AtomicUsize::new(0),
                        chain_access,
@@ -271,27 +246,32 @@ where C::Target: chain::Access, L::Target: Logger
                        false
                }
        }
+}
 
-       /// Applies changes to the [`NetworkGraph`] from the given update.
-       fn handle_network_update(&self, update: &NetworkUpdate) {
-               match *update {
-                       NetworkUpdate::ChannelUpdateMessage { ref msg } => {
-                               let short_channel_id = msg.contents.short_channel_id;
-                               let is_enabled = msg.contents.flags & (1 << 1) != (1 << 1);
-                               let status = if is_enabled { "enabled" } else { "disabled" };
-                               log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}.", short_channel_id, status);
-                               let _ = self.network_graph.update_channel(msg, &self.secp_ctx);
-                       },
-                       NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } => {
-                               let action = if is_permanent { "Removing" } else { "Disabling" };
-                               log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", action, short_channel_id);
-                               self.network_graph.channel_failed(short_channel_id, is_permanent);
-                       },
-                       NetworkUpdate::NodeFailure { ref node_id, is_permanent } => {
-                               let action = if is_permanent { "Removing" } else { "Disabling" };
-                               log_debug!(self.logger, "{} node graph entry for {} due to a payment failure.", action, node_id);
-                               self.network_graph.node_failed(node_id, is_permanent);
-                       },
+impl<L: Deref> EventHandler for NetworkGraph<L> where L::Target: Logger {
+       fn handle_event(&self, event: &Event) {
+               if let Event::PaymentPathFailed { payment_hash: _, rejected_by_dest: _, network_update, .. } = event {
+                       if let Some(network_update) = network_update {
+                               match *network_update {
+                                       NetworkUpdate::ChannelUpdateMessage { ref msg } => {
+                                               let short_channel_id = msg.contents.short_channel_id;
+                                               let is_enabled = msg.contents.flags & (1 << 1) != (1 << 1);
+                                               let status = if is_enabled { "enabled" } else { "disabled" };
+                                               log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}.", short_channel_id, status);
+                                               let _ = self.update_channel(msg);
+                                       },
+                                       NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } => {
+                                               let action = if is_permanent { "Removing" } else { "Disabling" };
+                                               log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", action, short_channel_id);
+                                               self.channel_failed(short_channel_id, is_permanent);
+                                       },
+                                       NetworkUpdate::NodeFailure { ref node_id, is_permanent } => {
+                                               let action = if is_permanent { "Removing" } else { "Disabling" };
+                                               log_debug!(self.logger, "{} node graph entry for {} due to a payment failure.", action, node_id);
+                                               self.node_failed(node_id, is_permanent);
+                                       },
+                               }
+                       }
                }
        }
 }
@@ -316,24 +296,24 @@ macro_rules! secp_verify_sig {
        };
 }
 
-impl<G: Deref<Target=NetworkGraph>, C: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync<G, C, L>
+impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync<G, C, L>
 where C::Target: chain::Access, L::Target: Logger
 {
        fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<bool, LightningError> {
-               self.network_graph.update_node_from_announcement(msg, &self.secp_ctx)?;
+               self.network_graph.update_node_from_announcement(msg)?;
                Ok(msg.contents.excess_data.len() <=  MAX_EXCESS_BYTES_FOR_RELAY &&
                   msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY &&
                   msg.contents.excess_data.len() + msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
        }
 
        fn handle_channel_announcement(&self, msg: &msgs::ChannelAnnouncement) -> Result<bool, LightningError> {
-               self.network_graph.update_channel_from_announcement(msg, &self.chain_access, &self.secp_ctx)?;
+               self.network_graph.update_channel_from_announcement(msg, &self.chain_access)?;
                log_gossip!(self.logger, "Added channel_announcement for {}{}", msg.contents.short_channel_id, if !msg.contents.excess_data.is_empty() { " with excess uninterpreted data!" } else { "" });
                Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
        }
 
        fn handle_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result<bool, LightningError> {
-               self.network_graph.update_channel(msg, &self.secp_ctx)?;
+               self.network_graph.update_channel(msg)?;
                Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
        }
 
@@ -605,7 +585,7 @@ where C::Target: chain::Access, L::Target: Logger
        }
 }
 
-impl<G: Deref<Target=NetworkGraph>, C: Deref, L: Deref> MessageSendEventsProvider for P2PGossipSync<G, C, L>
+impl<G: Deref<Target=NetworkGraph<L>>, C: Deref, L: Deref> MessageSendEventsProvider for P2PGossipSync<G, C, L>
 where
        C::Target: chain::Access,
        L::Target: Logger,
@@ -975,7 +955,7 @@ impl_writeable_tlv_based!(NodeInfo, {
 const SERIALIZATION_VERSION: u8 = 1;
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
-impl Writeable for NetworkGraph {
+impl<L: Deref> Writeable for NetworkGraph<L> where L::Target: Logger {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
 
@@ -1001,8 +981,8 @@ impl Writeable for NetworkGraph {
        }
 }
 
-impl Readable for NetworkGraph {
-       fn read<R: io::Read>(reader: &mut R) -> Result<NetworkGraph, DecodeError> {
+impl<L: Deref> ReadableArgs<L> for NetworkGraph<L> where L::Target: Logger {
+       fn read<R: io::Read>(reader: &mut R, logger: L) -> Result<NetworkGraph<L>, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let genesis_hash: BlockHash = Readable::read(reader)?;
@@ -1027,7 +1007,9 @@ 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),
@@ -1035,7 +1017,7 @@ impl Readable for NetworkGraph {
        }
 }
 
-impl fmt::Display for NetworkGraph {
+impl<L: Deref> fmt::Display for NetworkGraph<L> 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() {
@@ -1049,7 +1031,7 @@ impl fmt::Display for NetworkGraph {
        }
 }
 
-impl PartialEq for NetworkGraph {
+impl<L: Deref> PartialEq for NetworkGraph<L> where L::Target: Logger {
        fn eq(&self, other: &Self) -> bool {
                self.genesis_hash == other.genesis_hash &&
                        *self.channels.read().unwrap() == *other.channels.read().unwrap() &&
@@ -1057,11 +1039,13 @@ impl PartialEq for NetworkGraph {
        }
 }
 
-impl NetworkGraph {
+impl<L: Deref> NetworkGraph<L> 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<L> {
                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),
@@ -1105,9 +1089,9 @@ impl NetworkGraph {
        /// You probably don't want to call this directly, instead relying on a P2PGossipSync's
        /// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept
        /// routing messages from a source using a protocol other than the lightning P2P protocol.
-       pub fn update_node_from_announcement<T: secp256k1::Verification>(&self, msg: &msgs::NodeAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<(), LightningError> {
+       pub fn update_node_from_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<(), LightningError> {
                let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
-               secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id, "node_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id, "node_announcement");
                self.update_node_from_announcement_intern(&msg.contents, Some(&msg))
        }
 
@@ -1160,17 +1144,17 @@ impl NetworkGraph {
        ///
        /// If a `chain::Access` object is provided via `chain_access`, it will be called to verify
        /// the corresponding UTXO exists on chain and is correctly-formatted.
-       pub fn update_channel_from_announcement<T: secp256k1::Verification, C: Deref>(
-               &self, msg: &msgs::ChannelAnnouncement, chain_access: &Option<C>, secp_ctx: &Secp256k1<T>
+       pub fn update_channel_from_announcement<C: Deref>(
+               &self, msg: &msgs::ChannelAnnouncement, chain_access: &Option<C>,
        ) -> Result<(), LightningError>
        where
                C::Target: chain::Access,
        {
                let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
-               secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1, "channel_announcement");
-               secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2, "channel_announcement");
-               secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &msg.contents.bitcoin_key_1, "channel_announcement");
-               secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &msg.contents.bitcoin_key_2, "channel_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1, "channel_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2, "channel_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &msg.contents.bitcoin_key_1, "channel_announcement");
+               secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &msg.contents.bitcoin_key_2, "channel_announcement");
                self.update_channel_from_unsigned_announcement_intern(&msg.contents, Some(msg), chain_access)
        }
 
@@ -1432,8 +1416,8 @@ impl NetworkGraph {
        ///
        /// If built with `no-std`, any updates with a timestamp more than two weeks in the past or
        /// materially in the future will be rejected.
-       pub fn update_channel<T: secp256k1::Verification>(&self, msg: &msgs::ChannelUpdate, secp_ctx: &Secp256k1<T>) -> Result<(), LightningError> {
-               self.update_channel_intern(&msg.contents, Some(&msg), Some((&msg.signature, secp_ctx)))
+       pub fn update_channel(&self, msg: &msgs::ChannelUpdate) -> Result<(), LightningError> {
+               self.update_channel_intern(&msg.contents, Some(&msg), Some(&msg.signature))
        }
 
        /// For an already known (from announcement) channel, update info about one of the directions
@@ -1443,10 +1427,10 @@ impl NetworkGraph {
        /// If built with `no-std`, any updates with a timestamp more than two weeks in the past or
        /// materially in the future will be rejected.
        pub fn update_channel_unsigned(&self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> {
-               self.update_channel_intern(msg, None, None::<(&secp256k1::ecdsa::Signature, &Secp256k1<secp256k1::VerifyOnly>)>)
+               self.update_channel_intern(msg, None, None)
        }
 
-       fn update_channel_intern<T: secp256k1::Verification>(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig_info: Option<(&secp256k1::ecdsa::Signature, &Secp256k1<T>)>) -> Result<(), LightningError> {
+       fn update_channel_intern(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig: Option<&secp256k1::ecdsa::Signature>) -> Result<(), LightningError> {
                let dest_node_id;
                let chan_enabled = msg.flags & (1 << 1) != (1 << 1);
                let chan_was_enabled;
@@ -1527,8 +1511,8 @@ impl NetworkGraph {
                                if msg.flags & 1 == 1 {
                                        dest_node_id = channel.node_one.clone();
                                        check_update_latest!(channel.two_to_one);
-                                       if let Some((sig, ctx)) = sig_info {
-                                               secp_verify_sig!(ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_two.as_slice()).map_err(|_| LightningError{
+                                       if let Some(sig) = sig {
+                                               secp_verify_sig!(self.secp_ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_two.as_slice()).map_err(|_| LightningError{
                                                        err: "Couldn't parse source node pubkey".to_owned(),
                                                        action: ErrorAction::IgnoreAndLog(Level::Debug)
                                                })?, "channel_update");
@@ -1537,8 +1521,8 @@ impl NetworkGraph {
                                } else {
                                        dest_node_id = channel.node_two.clone();
                                        check_update_latest!(channel.one_to_two);
-                                       if let Some((sig, ctx)) = sig_info {
-                                               secp_verify_sig!(ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_one.as_slice()).map_err(|_| LightningError{
+                                       if let Some(sig) = sig {
+                                               secp_verify_sig!(self.secp_ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_one.as_slice()).map_err(|_| LightningError{
                                                        err: "Couldn't parse destination node pubkey".to_owned(),
                                                        action: ErrorAction::IgnoreAndLog(Level::Debug)
                                                })?, "channel_update");
@@ -1649,7 +1633,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;
 
@@ -1673,13 +1657,15 @@ mod tests {
        use prelude::*;
        use sync::Arc;
 
-       fn create_network_graph() -> NetworkGraph {
+       fn create_network_graph() -> NetworkGraph<Arc<test_utils::TestLogger>> {
                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<All>, P2PGossipSync<&NetworkGraph, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>
+       fn create_gossip_sync(network_graph: &NetworkGraph<Arc<test_utils::TestLogger>>) -> (
+               Secp256k1<All>, P2PGossipSync<&NetworkGraph<Arc<test_utils::TestLogger>>,
+               Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>
        ) {
                let secp_ctx = Secp256k1::new();
                let logger = Arc::new(test_utils::TestLogger::new());
@@ -1852,7 +1838,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),
@@ -1876,7 +1863,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| {
@@ -1960,7 +1947,8 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let logger: Arc<Logger> = 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();
@@ -2061,10 +2049,8 @@ mod tests {
        #[test]
        fn handling_network_update() {
                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 gossip_sync = P2PGossipSync::new(&network_graph, Some(chain_source.clone()), &logger);
+               let network_graph = NetworkGraph::new(genesis_hash, &logger);
                let secp_ctx = Secp256k1::new();
 
                let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
@@ -2081,13 +2067,13 @@ mod tests {
                        let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
                        short_channel_id = valid_channel_announcement.contents.short_channel_id;
                        let chain_source: Option<&test_utils::TestChainSource> = None;
-                       assert!(network_graph.update_channel_from_announcement(&valid_channel_announcement, &chain_source, &secp_ctx).is_ok());
+                       assert!(network_graph.update_channel_from_announcement(&valid_channel_announcement, &chain_source).is_ok());
                        assert!(network_graph.read_only().channels().get(&short_channel_id).is_some());
 
                        let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx);
                        assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none());
 
-                       gossip_sync.handle_event(&Event::PaymentPathFailed {
+                       network_graph.handle_event(&Event::PaymentPathFailed {
                                payment_id: None,
                                payment_hash: PaymentHash([0; 32]),
                                rejected_by_dest: false,
@@ -2114,7 +2100,7 @@ mod tests {
                                }
                        };
 
-                       gossip_sync.handle_event(&Event::PaymentPathFailed {
+                       network_graph.handle_event(&Event::PaymentPathFailed {
                                payment_id: None,
                                payment_hash: PaymentHash([0; 32]),
                                rejected_by_dest: false,
@@ -2139,7 +2125,7 @@ mod tests {
                }
 
                // Permanent closing deletes a channel
-               gossip_sync.handle_event(&Event::PaymentPathFailed {
+               network_graph.handle_event(&Event::PaymentPathFailed {
                        payment_id: None,
                        payment_hash: PaymentHash([0; 32]),
                        rejected_by_dest: false,
@@ -2167,7 +2153,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();
 
@@ -2177,7 +2163,7 @@ mod tests {
                let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
                let short_channel_id = valid_channel_announcement.contents.short_channel_id;
                let chain_source: Option<&test_utils::TestChainSource> = None;
-               assert!(network_graph.update_channel_from_announcement(&valid_channel_announcement, &chain_source, &secp_ctx).is_ok());
+               assert!(network_graph.update_channel_from_announcement(&valid_channel_announcement, &chain_source).is_ok());
                assert!(network_graph.read_only().channels().get(&short_channel_id).is_some());
 
                let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx);
@@ -2380,7 +2366,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!(<NetworkGraph>::read(&mut io::Cursor::new(&w.0)).unwrap() == network_graph);
+
+               let logger = Arc::new(test_utils::TestLogger::new());
+               assert!(<NetworkGraph<_>>::read(&mut io::Cursor::new(&w.0), logger).unwrap() == network_graph);
        }
 
        #[test]
@@ -2390,7 +2378,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);
        }
@@ -2679,7 +2669,7 @@ mod tests {
        }
 
        fn do_handling_query_channel_range(
-               gossip_sync: &P2PGossipSync<&NetworkGraph, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+               gossip_sync: &P2PGossipSync<&NetworkGraph<Arc<test_utils::TestLogger>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
                test_node_id: &PublicKey,
                msg: QueryChannelRange,
                expected_ok: bool,
@@ -2752,18 +2742,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();
                });
index 301ae76ddbb315e4aa02cec072e394f0bf87924f..90e658604ad1058040643e5b6be48fd93cfe29a8 100644 (file)
@@ -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<L: Deref, S: Score>(
-       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<Route, LightningError>
 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<L: Deref>(
-       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<Route, LightningError>
 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<NetworkGraph>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+               gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
                secp_ctx: &Secp256k1<All>, 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<NetworkGraph>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+               gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
                secp_ctx: &Secp256k1<All>, 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<NetworkGraph>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+               gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
                secp_ctx: &Secp256k1<All>, 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<All>, sync::Arc<NetworkGraph>, P2PGossipSync<sync::Arc<NetworkGraph>,
-               sync::Arc<test_utils::TestChainSource>, sync::Arc<crate::util::test_utils::TestLogger>>,
+               Secp256k1<All>, sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
+               P2PGossipSync<sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, sync::Arc<test_utils::TestChainSource>, sync::Arc<test_utils::TestLogger>>,
                sync::Arc<test_utils::TestChainSource>, sync::Arc<test_utils::TestLogger>,
        ) {
                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<All>,
-               sync::Arc<NetworkGraph>,
-               P2PGossipSync<sync::Arc<NetworkGraph>, sync::Arc<test_utils::TestChainSource>, sync::Arc<crate::util::test_utils::TestLogger>>,
+               sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
+               P2PGossipSync<sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, sync::Arc<test_utils::TestChainSource>, sync::Arc<test_utils::TestLogger>>,
                sync::Arc<test_utils::TestChainSource>,
                sync::Arc<test_utils::TestLogger>,
        ) {
                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::<Vec<_>>()), 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::<Vec<_>>()), 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<S: Score>(
-               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();
index 54400624dce63a30ec0e506bfc1c87800a6bac4a..bfcefc96f5b21b56a3d205d501948a7c9651a686 100644 (file)
@@ -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<G, L> = ProbabilisticScorerUsingTime::<G, L, Config
 /// Probabilistic [`Score`] implementation.
 ///
 /// (C-not exported) generally all users should use the [`ProbabilisticScorer`] type alias.
-pub struct ProbabilisticScorerUsingTime<G: Deref<Target = NetworkGraph>, L: Deref, T: Time> where L::Target: Logger {
+pub struct ProbabilisticScorerUsingTime<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time>
+where L::Target: Logger {
        params: ProbabilisticScoringParameters,
        network_graph: G,
        logger: L,
@@ -389,7 +390,7 @@ struct DirectedChannelLiquidity<L: Deref<Target = u64>, T: Time, U: Deref<Target
        half_life: Duration,
 }
 
-impl<G: Deref<Target = NetworkGraph>, L: Deref, T: Time> ProbabilisticScorerUsingTime<G, L, T> where L::Target: Logger {
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> ProbabilisticScorerUsingTime<G, L, T> 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<L: DerefMut<Target = u64>, T: Time, U: DerefMut<Target = T>> DirectedChanne
        }
 }
 
-impl<G: Deref<Target = NetworkGraph>, L: Deref, T: Time> Score for ProbabilisticScorerUsingTime<G, L, T> where L::Target: Logger {
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for ProbabilisticScorerUsingTime<G, L, T> 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<G: Deref<Target = NetworkGraph>, L: Deref, T: Time> Writeable for ProbabilisticScorerUsingTime<G, L, T> where L::Target: Logger {
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Writeable for ProbabilisticScorerUsingTime<G, L, T> where L::Target: Logger {
        #[inline]
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                write_tlv_fields!(w, {
@@ -1060,7 +1061,7 @@ impl<G: Deref<Target = NetworkGraph>, L: Deref, T: Time> Writeable for Probabili
        }
 }
 
-impl<G: Deref<Target = NetworkGraph>, L: Deref, T: Time>
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time>
 ReadableArgs<(ProbabilisticScoringParameters, G, L)> for ProbabilisticScorerUsingTime<G, L, T> where L::Target: Logger {
        #[inline]
        fn read<R: 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();
@@ -1228,13 +1229,14 @@ mod tests {
                };
                let chain_source: Option<&::util::test_utils::TestChainSource> = None;
                network_graph.update_channel_from_announcement(
-                       &signed_announcement, &chain_source, &secp_ctx).unwrap();
+                       &signed_announcement, &chain_source).unwrap();
                update_channel(network_graph, short_channel_id, node_1_key, 0);
                update_channel(network_graph, short_channel_id, node_2_key, 1);
        }
 
        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();
@@ -1255,7 +1257,7 @@ mod tests {
                        signature: secp_ctx.sign_ecdsa(&msghash, &node_key),
                        contents: unsigned_update,
                };
-               network_graph.update_channel(&signed_update, &secp_ctx).unwrap();
+               network_graph.update_channel(&signed_update).unwrap();
        }
 
        fn payment_path_for_amount(amount_msat: u64) -> Vec<RouteHop> {
@@ -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();
index a2794c329a26d827c214846d7cd571274e481b7e..14ab5ee3c4b83ebd3dff5e00d05daf5e597ea1e4 100644 (file)
@@ -337,10 +337,9 @@ pub enum Event {
                /// payment route.
                ///
                /// Should be applied to the [`NetworkGraph`] so that routing decisions can take into
-               /// account the update. [`P2PGossipSync`] is capable of doing this.
+               /// account the update.
                ///
                /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph
-               /// [`P2PGossipSync`]: crate::routing::gossip::P2PGossipSync
                network_update: Option<NetworkUpdate>,
                /// For both single-path and multi-path payments, this is set if all paths of the payment have
                /// failed. This will be set to false if (1) this is an MPP payment and (2) other parts of the
index 117eff491b343d4ae6cdfd0d0af7cd7a1df5ae91..522c1c92ac3460773436f0dd037eb24ee8018f03 100644 (file)
@@ -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<Signer, M, T, K, F, L>) -> 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<L>) -> 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<L>) -> Result<(), io::Error> {
                self.persist("network_graph", network_graph)
        }