expose `feerate_sat_per_1000_weight` in `ChannelDetails`
[rust-lightning] / lightning / src / routing / router.rs
index 0e51b2bf86b9d366386b736c5dacc28e82740592..baa2ecce1b7f3dae5037d61b84b67cbcc0723a20 100644 (file)
@@ -19,7 +19,7 @@ use crate::ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures};
 use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
 use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId, RoutingFees};
 use crate::routing::scoring::{ChannelUsage, LockableScore, Score};
-use crate::util::ser::{Writeable, Readable, Writer};
+use crate::util::ser::{Writeable, Readable, ReadableArgs, Writer};
 use crate::util::logger::{Level, Logger};
 use crate::util::chacha20::ChaCha20;
 
@@ -72,22 +72,6 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref> Router for DefaultR
                        &random_seed_bytes
                )
        }
-
-       fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
-               self.scorer.lock().payment_path_failed(path, short_channel_id);
-       }
-
-       fn notify_payment_path_successful(&self, path: &[&RouteHop]) {
-               self.scorer.lock().payment_path_successful(path);
-       }
-
-       fn notify_payment_probe_successful(&self, path: &[&RouteHop]) {
-               self.scorer.lock().probe_successful(path);
-       }
-
-       fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
-               self.scorer.lock().probe_failed(path, short_channel_id);
-       }
 }
 
 /// A trait defining behavior for routing a payment.
@@ -106,14 +90,6 @@ pub trait Router {
        ) -> Result<Route, LightningError> {
                self.find_route(payer, route_params, first_hops, inflight_htlcs)
        }
-       /// Lets the router know that payment through a specific path has failed.
-       fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64);
-       /// Lets the router know that payment through a specific path was successful.
-       fn notify_payment_path_successful(&self, path: &[&RouteHop]);
-       /// Lets the router know that a payment probe was successful.
-       fn notify_payment_probe_successful(&self, path: &[&RouteHop]);
-       /// Lets the router know that a payment probe failed.
-       fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64);
 }
 
 /// [`Score`] implementation that factors in in-flight HTLC liquidity.
@@ -337,18 +313,23 @@ impl Readable for Route {
        fn read<R: io::Read>(reader: &mut R) -> Result<Route, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
                let path_count: u64 = Readable::read(reader)?;
+               if path_count == 0 { return Err(DecodeError::InvalidValue); }
                let mut paths = Vec::with_capacity(cmp::min(path_count, 128) as usize);
+               let mut min_final_cltv_expiry_delta = u32::max_value();
                for _ in 0..path_count {
                        let hop_count: u8 = Readable::read(reader)?;
-                       let mut hops = Vec::with_capacity(hop_count as usize);
+                       let mut hops: Vec<RouteHop> = Vec::with_capacity(hop_count as usize);
                        for _ in 0..hop_count {
                                hops.push(Readable::read(reader)?);
                        }
+                       if hops.is_empty() { return Err(DecodeError::InvalidValue); }
+                       min_final_cltv_expiry_delta =
+                               cmp::min(min_final_cltv_expiry_delta, hops.last().unwrap().cltv_expiry_delta);
                        paths.push(hops);
                }
                let mut payment_params = None;
                read_tlv_fields!(reader, {
-                       (1, payment_params, option),
+                       (1, payment_params, (option: ReadableArgs, min_final_cltv_expiry_delta)),
                });
                Ok(Route { paths, payment_params })
        }
@@ -357,7 +338,7 @@ impl Readable for Route {
 /// Parameters needed to find a [`Route`].
 ///
 /// Passed to [`find_route`] and [`build_route_from_hops`], but also provided in
-/// [`Event::PaymentPathFailed`] for retrying a failed payment path.
+/// [`Event::PaymentPathFailed`].
 ///
 /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -367,19 +348,38 @@ pub struct RouteParameters {
 
        /// The amount in msats sent on the failed payment path.
        pub final_value_msat: u64,
+}
 
-       /// The CLTV on the final hop of the failed payment path.
-       ///
-       /// This field is deprecated, [`PaymentParameters::final_cltv_expiry_delta`] should be used
-       /// instead, if available.
-       pub final_cltv_expiry_delta: u32,
+impl Writeable for RouteParameters {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               write_tlv_fields!(writer, {
+                       (0, self.payment_params, required),
+                       (2, self.final_value_msat, required),
+                       // LDK versions prior to 0.0.114 had the `final_cltv_expiry_delta` parameter in
+                       // `RouteParameters` directly. For compatibility, we write it here.
+                       (4, self.payment_params.final_cltv_expiry_delta, required),
+               });
+               Ok(())
+       }
 }
 
-impl_writeable_tlv_based!(RouteParameters, {
-       (0, payment_params, required),
-       (2, final_value_msat, required),
-       (4, final_cltv_expiry_delta, required),
-});
+impl Readable for RouteParameters {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+               _init_and_read_tlv_fields!(reader, {
+                       (0, payment_params, (required: ReadableArgs, 0)),
+                       (2, final_value_msat, required),
+                       (4, final_cltv_expiry_delta, required),
+               });
+               let mut payment_params: PaymentParameters = payment_params.0.unwrap();
+               if payment_params.final_cltv_expiry_delta == 0 {
+                       payment_params.final_cltv_expiry_delta = final_cltv_expiry_delta.0.unwrap();
+               }
+               Ok(Self {
+                       payment_params,
+                       final_value_msat: final_value_msat.0.unwrap(),
+               })
+       }
+}
 
 /// Maximum total CTLV difference we allow for a full payment path.
 pub const DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA: u32 = 1008;
@@ -453,23 +453,54 @@ pub struct PaymentParameters {
        /// these SCIDs.
        pub previously_failed_channels: Vec<u64>,
 
-       /// The minimum CLTV delta at the end of the route.
-       ///
-       /// This field should always be set to `Some` and may be required in a future release.
-       pub final_cltv_expiry_delta: Option<u32>,
+       /// The minimum CLTV delta at the end of the route. This value must not be zero.
+       pub final_cltv_expiry_delta: u32,
+}
+
+impl Writeable for PaymentParameters {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               write_tlv_fields!(writer, {
+                       (0, self.payee_pubkey, required),
+                       (1, self.max_total_cltv_expiry_delta, required),
+                       (2, self.features, option),
+                       (3, self.max_path_count, required),
+                       (4, self.route_hints, vec_type),
+                       (5, self.max_channel_saturation_power_of_half, required),
+                       (6, self.expiry_time, option),
+                       (7, self.previously_failed_channels, vec_type),
+                       (9, self.final_cltv_expiry_delta, required),
+               });
+               Ok(())
+       }
+}
+
+impl ReadableArgs<u32> for PaymentParameters {
+       fn read<R: io::Read>(reader: &mut R, default_final_cltv_expiry_delta: u32) -> Result<Self, DecodeError> {
+               _init_and_read_tlv_fields!(reader, {
+                       (0, payee_pubkey, required),
+                       (1, max_total_cltv_expiry_delta, (default_value, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA)),
+                       (2, features, option),
+                       (3, max_path_count, (default_value, DEFAULT_MAX_PATH_COUNT)),
+                       (4, route_hints, vec_type),
+                       (5, max_channel_saturation_power_of_half, (default_value, 2)),
+                       (6, expiry_time, option),
+                       (7, previously_failed_channels, vec_type),
+                       (9, final_cltv_expiry_delta, (default_value, default_final_cltv_expiry_delta)),
+               });
+               Ok(Self {
+                       payee_pubkey: _init_tlv_based_struct_field!(payee_pubkey, required),
+                       max_total_cltv_expiry_delta: _init_tlv_based_struct_field!(max_total_cltv_expiry_delta, (default_value, unused)),
+                       features,
+                       max_path_count: _init_tlv_based_struct_field!(max_path_count, (default_value, unused)),
+                       route_hints: route_hints.unwrap_or(Vec::new()),
+                       max_channel_saturation_power_of_half: _init_tlv_based_struct_field!(max_channel_saturation_power_of_half, (default_value, unused)),
+                       expiry_time,
+                       previously_failed_channels: previously_failed_channels.unwrap_or(Vec::new()),
+                       final_cltv_expiry_delta: _init_tlv_based_struct_field!(final_cltv_expiry_delta, (default_value, unused)),
+               })
+       }
 }
 
-impl_writeable_tlv_based!(PaymentParameters, {
-       (0, payee_pubkey, required),
-       (1, max_total_cltv_expiry_delta, (default_value, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA)),
-       (2, features, option),
-       (3, max_path_count, (default_value, DEFAULT_MAX_PATH_COUNT)),
-       (4, route_hints, vec_type),
-       (5, max_channel_saturation_power_of_half, (default_value, 2)),
-       (6, expiry_time, option),
-       (7, previously_failed_channels, vec_type),
-       (9, final_cltv_expiry_delta, option),
-});
 
 impl PaymentParameters {
        /// Creates a payee with the node id of the given `pubkey`.
@@ -486,7 +517,7 @@ impl PaymentParameters {
                        max_path_count: DEFAULT_MAX_PATH_COUNT,
                        max_channel_saturation_power_of_half: 2,
                        previously_failed_channels: Vec::new(),
-                       final_cltv_expiry_delta: Some(final_cltv_expiry_delta),
+                       final_cltv_expiry_delta,
                }
        }
 
@@ -961,9 +992,7 @@ pub fn find_route<L: Deref, GL: Deref, S: Score>(
 ) -> Result<Route, LightningError>
 where L::Target: Logger, GL::Target: Logger {
        let graph_lock = network_graph.read_only();
-       let final_cltv_expiry_delta =
-               if let Some(delta) = route_params.payment_params.final_cltv_expiry_delta { delta }
-               else { route_params.final_cltv_expiry_delta };
+       let final_cltv_expiry_delta = route_params.payment_params.final_cltv_expiry_delta;
        let mut route = get_route(our_node_pubkey, &route_params.payment_params, &graph_lock, first_hops,
                route_params.final_value_msat, final_cltv_expiry_delta, logger, scorer,
                random_seed_bytes)?;
@@ -1002,9 +1031,9 @@ where L::Target: Logger {
        if payment_params.max_total_cltv_expiry_delta <= final_cltv_expiry_delta {
                return Err(LightningError{err: "Can't find a route where the maximum total CLTV expiry delta is below the final CLTV expiry.".to_owned(), action: ErrorAction::IgnoreError});
        }
-       if let Some(delta) = payment_params.final_cltv_expiry_delta {
-               debug_assert_eq!(delta, final_cltv_expiry_delta);
-       }
+
+       // TODO: Remove the explicit final_cltv_expiry_delta parameter
+       debug_assert_eq!(final_cltv_expiry_delta, payment_params.final_cltv_expiry_delta);
 
        // The general routing idea is the following:
        // 1. Fill first/last hops communicated by the caller.
@@ -2043,7 +2072,8 @@ where L::Target: Logger, GL::Target: Logger {
        let graph_lock = network_graph.read_only();
        let mut route = build_route_from_hops_internal(
                our_node_pubkey, hops, &route_params.payment_params, &graph_lock,
-               route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, random_seed_bytes)?;
+               route_params.final_value_msat, route_params.payment_params.final_cltv_expiry_delta,
+               logger, random_seed_bytes)?;
        add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes);
        Ok(route)
 }
@@ -2116,7 +2146,7 @@ mod tests {
        use crate::routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features,
                PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees,
                DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE};
-       use crate::routing::scoring::{ChannelUsage, Score, ProbabilisticScorer, ProbabilisticScoringParameters};
+       use crate::routing::scoring::{ChannelUsage, FixedPenaltyScorer, Score, ProbabilisticScorer, ProbabilisticScoringParameters};
        use crate::routing::test_utils::{add_channel, add_or_update_node, build_graph, build_line_graph, id_to_feature_flags, get_nodes, update_channel};
        use crate::chain::transaction::OutPoint;
        use crate::chain::keysinterface::EntropySource;
@@ -2178,6 +2208,7 @@ mod tests {
                        inbound_htlc_minimum_msat: None,
                        inbound_htlc_maximum_msat: None,
                        config: None,
+                       feerate_sat_per_1000_weight: None
                }
        }
 
@@ -2186,7 +2217,7 @@ mod tests {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2219,7 +2250,7 @@ mod tests {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2241,7 +2272,7 @@ mod tests {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2369,7 +2400,7 @@ mod tests {
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
                let config = UserConfig::default();
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config));
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2507,7 +2538,7 @@ mod tests {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2567,7 +2598,7 @@ mod tests {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2611,7 +2642,7 @@ mod tests {
        fn our_chans_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2742,7 +2773,7 @@ mod tests {
        fn partial_route_hint_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2843,7 +2874,7 @@ mod tests {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(empty_last_hop(&nodes));
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -2923,7 +2954,7 @@ mod tests {
                let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
                let last_hops = multi_hop_last_hops_hint([nodes[2], nodes[3]]);
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone());
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                // Test through channels 2, 3, 0xff00, 0xff01.
@@ -2997,7 +3028,7 @@ mod tests {
 
                let last_hops = multi_hop_last_hops_hint([nodes[2], non_announced_pubkey]);
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone());
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                // Test through channels 2, 3, 0xff00, 0xff01.
                // Test shows that multiple hop hints are considered.
 
@@ -3103,7 +3134,7 @@ mod tests {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_with_public_channel(&nodes));
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                // This test shows that public routes can be present in the invoice
@@ -3154,7 +3185,7 @@ mod tests {
        fn our_chans_last_hop_connect_test() {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -3277,12 +3308,11 @@ mod tests {
                }]);
                let payment_params = PaymentParameters::from_node_id(target_node_id, 42).with_route_hints(vec![last_hops]);
                let our_chans = vec![get_channel_details(Some(42), middle_node_id, InitFeatures::from_le_bytes(vec![0b11]), outbound_capacity_msat)];
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
-               let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
                let logger = ln_test_utils::TestLogger::new();
-               let network_graph = NetworkGraph::new(genesis_hash, &logger);
+               let network_graph = NetworkGraph::new(Network::Testnet, &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
@@ -3338,7 +3368,7 @@ mod tests {
 
                let (secp_ctx, network_graph, mut gossip_sync, chain_monitor, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -3614,7 +3644,7 @@ mod tests {
                // one of the latter hops is limited.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -3740,7 +3770,7 @@ mod tests {
        fn ignore_fee_first_hop_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
@@ -3788,7 +3818,7 @@ mod tests {
        fn simple_mpp_route_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -3948,7 +3978,7 @@ mod tests {
        fn long_mpp_route_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -4113,7 +4143,7 @@ mod tests {
        fn mpp_cheaper_route_test() {
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -4283,7 +4313,7 @@ mod tests {
                // if the fee is not properly accounted for, the behavior is different.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -4465,7 +4495,7 @@ mod tests {
                // This bug appeared in production in some specific channel configurations.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -4557,7 +4587,7 @@ mod tests {
                // path finding we realize that we found more capacity than we need.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -4714,12 +4744,11 @@ 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(ln_test_utils::TestLogger::new());
-               let network = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger)));
+               let network = Arc::new(NetworkGraph::new(Network::Testnet, 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 = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42);
@@ -4850,7 +4879,7 @@ mod tests {
                // we calculated fees on a higher value, resulting in us ignoring such paths.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, _, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
@@ -4914,7 +4943,7 @@ mod tests {
                // resulting in us thinking there is no possible path, even if other paths exist.
                let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
                let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let config = UserConfig::default();
@@ -4982,10 +5011,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(ln_test_utils::TestLogger::new());
-               let network_graph = NetworkGraph::new(genesis_hash, Arc::clone(&logger));
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let network_graph = NetworkGraph::new(Network::Testnet, Arc::clone(&logger));
+               let scorer = ln_test_utils::TestScorer::new();
                let config = UserConfig::default();
                let payment_params = PaymentParameters::from_node_id(nodes[0], 42).with_features(channelmanager::provided_invoice_features(&config));
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
@@ -5056,7 +5084,7 @@ mod tests {
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes));
 
                // Without penalizing each hop 100 msats, a longer path with lower fees is chosen.
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let route = get_route(
@@ -5071,7 +5099,7 @@ mod tests {
 
                // Applying a 100 msat penalty to each hop results in taking channels 7 and 10 to nodes[6]
                // from nodes[2] rather than channel 6, 11, and 8, even though the longer path is cheaper.
-               let scorer = ln_test_utils::TestScorer::with_penalty(100);
+               let scorer = FixedPenaltyScorer::with_penalty(100);
                let route = get_route(
                        &our_id, &payment_params, &network_graph.read_only(), None, 100, 42,
                        Arc::clone(&logger), &scorer, &random_seed_bytes
@@ -5130,7 +5158,7 @@ mod tests {
                let network_graph = network.read_only();
 
                // A path to nodes[6] exists when no penalties are applied to any channel.
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
                let route = get_route(
@@ -5245,7 +5273,7 @@ mod tests {
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let network_graph = network.read_only();
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
 
                // Make sure that generally there is at least one route available
                let feasible_max_total_cltv_delta = 1008;
@@ -5278,7 +5306,7 @@ mod tests {
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let network_graph = network.read_only();
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let mut payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes))
                        .with_max_path_count(1);
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
@@ -5305,7 +5333,7 @@ mod tests {
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
                let network_graph = network.read_only();
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
 
@@ -5333,7 +5361,7 @@ mod tests {
                let (secp_ctx, network_graph, _, _, logger) = build_graph();
                let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
 
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
 
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes));
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
@@ -5367,7 +5395,7 @@ mod tests {
                let network_graph = network.read_only();
                let network_nodes = network_graph.nodes();
                let network_channels = network_graph.channels();
-               let scorer = ln_test_utils::TestScorer::with_penalty(0);
+               let scorer = ln_test_utils::TestScorer::new();
                let payment_params = PaymentParameters::from_node_id(nodes[3], 0);
                let keys_manager = ln_test_utils::TestKeysInterface::new(&[4u8; 32], Network::Testnet);
                let random_seed_bytes = keys_manager.get_secure_random_bytes();
@@ -5710,6 +5738,7 @@ mod benches {
                        inbound_htlc_minimum_msat: None,
                        inbound_htlc_maximum_msat: None,
                        config: None,
+                       feerate_sat_per_1000_weight: None,
                }
        }