X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Frouter.rs;h=0910985418ed8b23a958efa5f9056bef8414c3e7;hb=b5827f77ad539ce047e513401f6cabb08576e204;hp=1e2ca10c0bf4a0795bc4089d0145b69ad8914de5;hpb=801d297f53150ed1ee5073da0c2d6cbc2fb47706;p=rust-lightning diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 1e2ca10c..09109854 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -7,22 +7,21 @@ // You may not use this file except in accordance with one or both of these // licenses. -//! The top-level routing/network map tracking logic lives here. -//! -//! You probably want to create a P2PGossipSync and use that as your RoutingMessageHandler and then -//! interrogate it to get routes for your own payments. +//! The router finds paths within a [`NetworkGraph`] for a payment. use bitcoin::secp256k1::PublicKey; use bitcoin::hashes::Hash; use bitcoin::hashes::sha256::Hash as Sha256; +use crate::blinded_path::BlindedPath; use crate::ln::PaymentHash; use crate::ln::channelmanager::{ChannelDetails, PaymentId}; use crate::ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures}; use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT}; +use crate::offers::invoice::BlindedPayInfo; 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; @@ -75,22 +74,6 @@ impl>, 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. @@ -109,14 +92,6 @@ pub trait Router { ) -> Result { 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. @@ -237,7 +212,8 @@ impl Readable for InFlightHtlcs { } } -/// A hop in a route +/// A hop in a route, and additional metadata about it. "Hop" is defined as a node and the channel +/// that leads to it. #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct RouteHop { /// The node_id of the node at this hop. @@ -251,11 +227,10 @@ pub struct RouteHop { /// to reach this node. pub channel_features: ChannelFeatures, /// The fee taken on this hop (for paying for the use of the *next* channel in the path). - /// For the last hop, this should be the full value of the payment (might be more than - /// requested if we had to match htlc_minimum_msat). + /// For the last hop, this should be the full value of this path's part of the payment. pub fee_msat: u64, - /// The CLTV delta added for this hop. For the last hop, this should be the full CLTV value - /// expected at the destination, in excess of the current block height. + /// The CLTV delta added for this hop. For the last hop, this is the CLTV delta expected at the + /// destination. pub cltv_expiry_delta: u32, } @@ -272,17 +247,17 @@ impl_writeable_tlv_based!(RouteHop, { /// it can take multiple paths. Each path is composed of one or more hops through the network. #[derive(Clone, Hash, PartialEq, Eq)] pub struct Route { - /// The list of routes taken for a single (potentially-)multi-part payment. The pubkey of the - /// last RouteHop in each path must be the same. Each entry represents a list of hops, NOT - /// INCLUDING our own, where the last hop is the destination. Thus, this must always be at - /// least length one. While the maximum length of any given path is variable, keeping the length - /// of any path less or equal to 19 should currently ensure it is viable. + /// The list of paths taken for a single (potentially-)multi-part payment. The pubkey of the + /// last [`RouteHop`] in each path must be the same. Each entry represents a list of hops, where + /// the last hop is the destination. Thus, this must always be at least length one. While the + /// maximum length of any given path is variable, keeping the length of any path less or equal to + /// 19 should currently ensure it is viable. pub paths: Vec>, /// The `payment_params` parameter passed to [`find_route`]. /// This is used by `ChannelManager` to track information which may be required for retries, /// provided back to you via [`Event::PaymentPathFailed`]. /// - /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed + /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed pub payment_params: Option, } @@ -308,7 +283,8 @@ impl Route { self.paths.iter().map(|path| path.get_path_fees()).sum() } - /// Returns the total amount paid on this [`Route`], excluding the fees. + /// Returns the total amount paid on this [`Route`], excluding the fees. Might be more than + /// requested if we had to reach htlc_minimum_msat. pub fn get_total_amount(&self) -> u64 { return self.paths.iter() .map(|path| path.split_last().map(|(hop, _)| hop.fee_msat).unwrap_or(0)) @@ -340,18 +316,23 @@ impl Readable for Route { fn read(reader: &mut R) -> Result { 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 = 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 }) } @@ -360,9 +341,9 @@ 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 +/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed #[derive(Clone, Debug, PartialEq, Eq)] pub struct RouteParameters { /// The parameters of the failed payment path. @@ -370,16 +351,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. - pub final_cltv_expiry_delta: u32, +impl Writeable for RouteParameters { + fn write(&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(reader: &mut R) -> Result { + _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; @@ -420,7 +423,7 @@ pub struct PaymentParameters { pub features: Option, /// Hints for routing to the payee, containing channels connecting the payee to public nodes. - pub route_hints: Vec, + pub route_hints: Hints, /// Expiration of a payment to the payee, in seconds relative to the UNIX epoch. pub expiry_time: Option, @@ -452,82 +455,152 @@ pub struct PaymentParameters { /// payment to fail. Future attempts for the same payment shouldn't be relayed through any of /// these SCIDs. pub previously_failed_channels: Vec, + + /// 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(&self, writer: &mut W) -> Result<(), io::Error> { + let mut clear_hints = &vec![]; + let mut blinded_hints = &vec![]; + match &self.route_hints { + Hints::Clear(hints) => clear_hints = hints, + Hints::Blinded(hints) => blinded_hints = hints, + } + 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, *clear_hints, vec_type), + (5, self.max_channel_saturation_power_of_half, required), + (6, self.expiry_time, option), + (7, self.previously_failed_channels, vec_type), + (8, *blinded_hints, optional_vec), + (9, self.final_cltv_expiry_delta, required), + }); + Ok(()) + } +} + +impl ReadableArgs for PaymentParameters { + fn read(reader: &mut R, default_final_cltv_expiry_delta: u32) -> Result { + _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), + (8, blinded_route_hints, optional_vec), + (9, final_cltv_expiry_delta, (default_value, default_final_cltv_expiry_delta)), + }); + let clear_route_hints = route_hints.unwrap_or(vec![]); + let blinded_route_hints = blinded_route_hints.unwrap_or(vec![]); + let route_hints = if blinded_route_hints.len() != 0 { + if clear_route_hints.len() != 0 { return Err(DecodeError::InvalidValue) } + Hints::Blinded(blinded_route_hints) + } else { + Hints::Clear(clear_route_hints) + }; + 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, + 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), -}); impl PaymentParameters { /// Creates a payee with the node id of the given `pubkey`. - pub fn from_node_id(payee_pubkey: PublicKey) -> Self { + /// + /// The `final_cltv_expiry_delta` should match the expected final CLTV delta the recipient has + /// provided. + pub fn from_node_id(payee_pubkey: PublicKey, final_cltv_expiry_delta: u32) -> Self { Self { payee_pubkey, features: None, - route_hints: vec![], + route_hints: Hints::Clear(vec![]), expiry_time: None, max_total_cltv_expiry_delta: DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, max_path_count: DEFAULT_MAX_PATH_COUNT, max_channel_saturation_power_of_half: 2, previously_failed_channels: Vec::new(), + final_cltv_expiry_delta, } } /// Creates a payee with the node id of the given `pubkey` to use for keysend payments. - pub fn for_keysend(payee_pubkey: PublicKey) -> Self { - Self::from_node_id(payee_pubkey).with_features(InvoiceFeatures::for_keysend()) + /// + /// The `final_cltv_expiry_delta` should match the expected final CLTV delta the recipient has + /// provided. + pub fn for_keysend(payee_pubkey: PublicKey, final_cltv_expiry_delta: u32) -> Self { + Self::from_node_id(payee_pubkey, final_cltv_expiry_delta).with_features(InvoiceFeatures::for_keysend()) } /// Includes the payee's features. /// - /// (C-not exported) since bindings don't support move semantics + /// This is not exported to bindings users since bindings don't support move semantics pub fn with_features(self, features: InvoiceFeatures) -> Self { Self { features: Some(features), ..self } } /// Includes hints for routing to the payee. /// - /// (C-not exported) since bindings don't support move semantics + /// This is not exported to bindings users since bindings don't support move semantics pub fn with_route_hints(self, route_hints: Vec) -> Self { - Self { route_hints, ..self } + Self { route_hints: Hints::Clear(route_hints), ..self } } /// Includes a payment expiration in seconds relative to the UNIX epoch. /// - /// (C-not exported) since bindings don't support move semantics + /// This is not exported to bindings users since bindings don't support move semantics pub fn with_expiry_time(self, expiry_time: u64) -> Self { Self { expiry_time: Some(expiry_time), ..self } } /// Includes a limit for the total CLTV expiry delta which is considered during routing /// - /// (C-not exported) since bindings don't support move semantics + /// This is not exported to bindings users since bindings don't support move semantics pub fn with_max_total_cltv_expiry_delta(self, max_total_cltv_expiry_delta: u32) -> Self { Self { max_total_cltv_expiry_delta, ..self } } /// Includes a limit for the maximum number of payment paths that may be used. /// - /// (C-not exported) since bindings don't support move semantics + /// This is not exported to bindings users since bindings don't support move semantics pub fn with_max_path_count(self, max_path_count: u8) -> Self { Self { max_path_count, ..self } } /// Includes a limit for the maximum number of payment paths that may be used. /// - /// (C-not exported) since bindings don't support move semantics + /// This is not exported to bindings users since bindings don't support move semantics pub fn with_max_channel_saturation_power_of_half(self, max_channel_saturation_power_of_half: u8) -> Self { Self { max_channel_saturation_power_of_half, ..self } } } +/// Routing hints for the tail of the route. +#[derive(Clone, Debug, Hash, PartialEq, Eq)] +pub enum Hints { + /// The recipient provided blinded paths and payinfo to reach them. The blinded paths themselves + /// will be included in the final [`Route`]. + Blinded(Vec<(BlindedPayInfo, BlindedPath)>), + /// The recipient included these route hints in their BOLT11 invoice. + Clear(Vec), +} + /// A list of hops along a payment path terminating with a channel to the recipient. #[derive(Clone, Debug, Hash, Eq, PartialEq)] pub struct RouteHint(pub Vec); @@ -939,7 +1012,7 @@ fn default_node_features() -> NodeFeatures { /// [`ChannelManager::list_usable_channels`] will never include such channels. /// /// [`ChannelManager::list_usable_channels`]: crate::ln::channelmanager::ChannelManager::list_usable_channels -/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed +/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph pub fn find_route( our_node_pubkey: &PublicKey, route_params: &RouteParameters, @@ -948,8 +1021,9 @@ pub fn find_route( ) -> Result where L::Target: Logger, GL::Target: Logger { let graph_lock = network_graph.read_only(); + 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, route_params.final_cltv_expiry_delta, logger, scorer, + route_params.final_value_msat, final_cltv_expiry_delta, logger, scorer, random_seed_bytes)?; add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes); Ok(route) @@ -976,17 +1050,26 @@ where L::Target: Logger { return Err(LightningError{err: "Cannot send a payment of 0 msat".to_owned(), action: ErrorAction::IgnoreError}); } - for route in payment_params.route_hints.iter() { - for hop in &route.0 { - if hop.src_node_id == payment_params.payee_pubkey { - return Err(LightningError{err: "Route hint cannot have the payee as the source.".to_owned(), action: ErrorAction::IgnoreError}); + match &payment_params.route_hints { + Hints::Clear(hints) => { + for route in hints.iter() { + for hop in &route.0 { + if hop.src_node_id == payment_params.payee_pubkey { + return Err(LightningError{err: "Route hint cannot have the payee as the source.".to_owned(), action: ErrorAction::IgnoreError}); + } + } } - } + }, + _ => return Err(LightningError{err: "Routing to blinded paths isn't supported yet".to_owned(), action: ErrorAction::IgnoreError}), + } 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}); } + // 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. // 2. Attempt to construct a path from payer to payee for transferring @@ -1503,7 +1586,11 @@ where L::Target: Logger { // If a caller provided us with last hops, add them to routing targets. Since this happens // earlier than general path finding, they will be somewhat prioritized, although currently // it matters only if the fees are exactly the same. - for route in payment_params.route_hints.iter().filter(|route| !route.0.is_empty()) { + let route_hints = match &payment_params.route_hints { + Hints::Clear(hints) => hints, + _ => return Err(LightningError{err: "Routing to blinded paths isn't supported yet".to_owned(), action: ErrorAction::IgnoreError}), + }; + for route in route_hints.iter().filter(|route| !route.0.is_empty()) { let first_hop_in_route = &(route.0)[0]; let have_hop_src_in_graph = // Only add the hops in this route to our candidate set if either @@ -2024,7 +2111,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) } @@ -2093,10 +2181,11 @@ fn build_route_from_hops_internal( #[cfg(test)] mod tests { use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, EffectiveCapacity}; + use crate::routing::utxo::UtxoResult; 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; @@ -2158,6 +2247,7 @@ mod tests { inbound_htlc_minimum_msat: None, inbound_htlc_maximum_msat: None, config: None, + feerate_sat_per_1000_weight: None } } @@ -2165,8 +2255,8 @@ mod tests { fn simple_route_test() { 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]); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); + 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(); @@ -2198,8 +2288,8 @@ mod tests { fn invalid_first_hop_test() { 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]); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); + 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(); @@ -2220,8 +2310,8 @@ mod tests { fn htlc_minimum_test() { 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]); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); + 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(); @@ -2348,8 +2438,8 @@ mod tests { let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph(); let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx); let config = UserConfig::default(); - let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features(&config)); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config)); + 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(); @@ -2486,8 +2576,8 @@ mod tests { fn disable_channels_test() { 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]); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); + 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(); @@ -2546,8 +2636,8 @@ mod tests { fn disable_node_test() { 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]); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); + 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(); @@ -2591,12 +2681,12 @@ 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(); // Route to 1 via 2 and 3 because our channel to 1 is disabled - let payment_params = PaymentParameters::from_node_id(nodes[0]); + let payment_params = PaymentParameters::from_node_id(nodes[0], 42); let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].len(), 3); @@ -2622,7 +2712,7 @@ mod tests { assert_eq!(route.paths[0][2].channel_features.le_flags(), &id_to_feature_flags(3)); // If we specify a channel to node7, that overrides our local channel view and that gets used - let payment_params = PaymentParameters::from_node_id(nodes[2]); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].len(), 2); @@ -2722,7 +2812,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(); @@ -2746,13 +2836,13 @@ mod tests { let mut invalid_last_hops = last_hops_multi_private_channels(&nodes); invalid_last_hops.push(invalid_last_hop); { - let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(invalid_last_hops); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(invalid_last_hops); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes) { assert_eq!(err, "Route hint cannot have the payee as the source."); } else { panic!(); } } - let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops_multi_private_channels(&nodes)); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_multi_private_channels(&nodes)); let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].len(), 5); @@ -2822,8 +2912,8 @@ mod tests { fn ignores_empty_last_hops_test() { 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]).with_route_hints(empty_last_hop(&nodes)); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(empty_last_hop(&nodes)); + 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(); @@ -2902,8 +2992,8 @@ mod tests { let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph(); 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]).with_route_hints(last_hops.clone()); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()); + 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. @@ -2976,8 +3066,8 @@ mod tests { let non_announced_pubkey = PublicKey::from_secret_key(&secp_ctx, &non_announced_privkey); let last_hops = multi_hop_last_hops_hint([nodes[2], non_announced_pubkey]); - let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops.clone()); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()); + let scorer = ln_test_utils::TestScorer::new(); // Test through channels 2, 3, 0xff00, 0xff01. // Test shows that multiple hop hints are considered. @@ -3082,8 +3172,8 @@ mod tests { fn last_hops_with_public_channel_test() { 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]).with_route_hints(last_hops_with_public_channel(&nodes)); - let scorer = ln_test_utils::TestScorer::with_penalty(0); + 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::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 @@ -3134,14 +3224,14 @@ 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(); // Simple test with outbound channel to 4 to test that last_hops and first_hops connect let our_chans = vec![get_channel_details(Some(42), nodes[3].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; let mut last_hops = last_hops(&nodes); - let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops.clone()); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()); let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].len(), 2); @@ -3162,7 +3252,7 @@ mod tests { last_hops[0].0[0].fees.base_msat = 1000; // Revert to via 6 as the fee on 8 goes up - let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops); let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].len(), 4); @@ -3255,14 +3345,13 @@ mod tests { htlc_minimum_msat: None, htlc_maximum_msat: last_hop_htlc_max, }]); - let payment_params = PaymentParameters::from_node_id(target_node_id).with_route_hints(vec![last_hops]); + 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::>()), route_val, 42, &logger, &scorer, &random_seed_bytes); route @@ -3318,11 +3407,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config)); // We will use a simple single-path route from // our node to node2 via node0: channels {1, 3}. @@ -3507,8 +3596,9 @@ mod tests { .push_opcode(opcodes::all::OP_PUSHNUM_2) .push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script().to_v0_p2wsh(); - *chain_monitor.utxo_ret.lock().unwrap() = Ok(TxOut { value: 15, script_pubkey: good_script.clone() }); - gossip_sync.add_chain_access(Some(chain_monitor)); + *chain_monitor.utxo_ret.lock().unwrap() = + UtxoResult::Sync(Ok(TxOut { value: 15, script_pubkey: good_script.clone() })); + gossip_sync.add_utxo_lookup(Some(chain_monitor)); add_channel(&gossip_sync, &secp_ctx, &privkeys[0], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 333); update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate { @@ -3593,11 +3683,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config)); // Path via {node7, node2, node4} is channels {12, 13, 6, 11}. // {12, 13, 11} have the capacities of 100, {6} has a capacity of 50. @@ -3719,10 +3809,10 @@ 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]); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); // Path via node0 is channels {1, 3}. Limit them to 100 and 50 sats (total limit 50). update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate { @@ -3767,11 +3857,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[2]) + let payment_params = PaymentParameters::from_node_id(nodes[2], 42) .with_features(channelmanager::provided_invoice_features(&config)); // We need a route consisting of 3 paths: @@ -3927,11 +4017,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config)); // We need a route consisting of 3 paths: // From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}. @@ -4092,11 +4182,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config)); // This test checks that if we have two cheaper paths and one more expensive path, // so that liquidity-wise any 2 of 3 combination is sufficient, @@ -4262,11 +4352,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[3]).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_features(channelmanager::provided_invoice_features(&config)); // We need a route consisting of 2 paths: // From our node to node3 via {node0, node2} and {node7, node2, node4}. @@ -4444,11 +4534,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(PublicKey::from_slice(&[02; 33]).unwrap()).with_features(channelmanager::provided_invoice_features(&config)) + let payment_params = PaymentParameters::from_node_id(PublicKey::from_slice(&[02; 33]).unwrap(), 42).with_features(channelmanager::provided_invoice_features(&config)) .with_route_hints(vec![RouteHint(vec![RouteHintHop { src_node_id: nodes[2], short_channel_id: 42, @@ -4536,11 +4626,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features(&config)) + let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config)) .with_max_channel_saturation_power_of_half(0); // We need a route consisting of 3 paths: @@ -4693,15 +4783,14 @@ 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]); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42); add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6); update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate { @@ -4829,10 +4918,10 @@ 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]); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42); // We modify the graph to set the htlc_maximum of channel 2 to below the value we wish to // send. @@ -4893,11 +4982,11 @@ 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(); - let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config)); // We modify the graph to set the htlc_minimum of channel 2 and 4 as needed - channel 2 // gets an htlc_maximum_msat of 80_000 and channel 4 an htlc_minimum_msat of 90_000. We @@ -4961,12 +5050,11 @@ 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]).with_features(channelmanager::provided_invoice_features(&config)); + 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); let random_seed_bytes = keys_manager.get_secure_random_bytes(); @@ -5032,10 +5120,10 @@ mod tests { fn prefers_shorter_route_with_higher_fees() { 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]).with_route_hints(last_hops(&nodes)); + 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( @@ -5050,7 +5138,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 @@ -5105,11 +5193,11 @@ mod tests { fn avoids_routing_through_bad_channels_and_nodes() { let (secp_ctx, network, _, _, logger) = build_graph(); let (_, our_id, _, nodes) = get_nodes(&secp_ctx); - let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes)); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes)); 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( @@ -5224,11 +5312,11 @@ 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; - let feasible_payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes)) + let feasible_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)) .with_max_total_cltv_expiry_delta(feasible_max_total_cltv_delta); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); @@ -5238,7 +5326,7 @@ mod tests { // But not if we exclude all paths on the basis of their accumulated CLTV delta let fail_max_total_cltv_delta = 23; - let fail_payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes)) + let fail_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)) .with_max_total_cltv_expiry_delta(fail_max_total_cltv_delta); match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, 0, Arc::clone(&logger), &scorer, &random_seed_bytes) { @@ -5257,8 +5345,8 @@ 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 mut payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes)) + 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); let random_seed_bytes = keys_manager.get_secure_random_bytes(); @@ -5284,19 +5372,19 @@ 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(); // First check we can actually create a long route on this graph. - let feasible_payment_params = PaymentParameters::from_node_id(nodes[18]); + let feasible_payment_params = PaymentParameters::from_node_id(nodes[18], 0); let route = get_route(&our_id, &feasible_payment_params, &network_graph, None, 100, 0, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap(); let path = route.paths[0].iter().map(|hop| hop.short_channel_id).collect::>(); assert!(path.len() == MAX_PATH_LENGTH_ESTIMATE.into()); // But we can't create a path surpassing the MAX_PATH_LENGTH_ESTIMATE limit. - let fail_payment_params = PaymentParameters::from_node_id(nodes[19]); + let fail_payment_params = PaymentParameters::from_node_id(nodes[19], 0); match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, 0, Arc::clone(&logger), &scorer, &random_seed_bytes) { @@ -5312,9 +5400,9 @@ 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]).with_route_hints(last_hops(&nodes)); + 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); let random_seed_bytes = keys_manager.get_secure_random_bytes(); let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap(); @@ -5346,8 +5434,8 @@ 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 payment_params = PaymentParameters::from_node_id(nodes[3]); + 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(); @@ -5414,7 +5502,7 @@ mod tests { 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[3]); + let payment_params = PaymentParameters::from_node_id(nodes[3], 0); let hops = [nodes[1], nodes[2], nodes[4], nodes[3]]; let route = build_route_from_hops_internal(&our_id, &hops, &payment_params, &network_graph, 100, 0, Arc::clone(&logger), &random_seed_bytes).unwrap(); @@ -5460,7 +5548,7 @@ mod tests { }); let config = UserConfig::default(); - let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_features(channelmanager::provided_invoice_features(&config)); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); // 100,000 sats is less than the available liquidity on each channel, set above. @@ -5507,7 +5595,7 @@ mod tests { let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap(); seed = seed.overflowing_mul(0xdeadbeef).0; let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap(); - let payment_params = PaymentParameters::from_node_id(dst); + let payment_params = PaymentParameters::from_node_id(dst, 42); let amt = seed as u64 % 200_000_000; let params = ProbabilisticScoringParameters::default(); let scorer = ProbabilisticScorer::new(params, &graph, &logger); @@ -5545,7 +5633,7 @@ mod tests { let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap(); seed = seed.overflowing_mul(0xdeadbeef).0; let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap(); - let payment_params = PaymentParameters::from_node_id(dst).with_features(channelmanager::provided_invoice_features(&config)); + let payment_params = PaymentParameters::from_node_id(dst, 42).with_features(channelmanager::provided_invoice_features(&config)); let amt = seed as u64 % 200_000_000; let params = ProbabilisticScoringParameters::default(); let scorer = ProbabilisticScorer::new(params, &graph, &logger); @@ -5578,7 +5666,7 @@ mod tests { assert_eq!(scorer.channel_penalty_msat(42, &NodeId::from_pubkey(&nodes[3]), &NodeId::from_pubkey(&nodes[4]), usage), 456); // Then check we can get a normal route - let payment_params = PaymentParameters::from_node_id(nodes[10]); + let payment_params = PaymentParameters::from_node_id(nodes[10], 42); let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes); assert!(route.is_ok()); @@ -5689,6 +5777,7 @@ mod benches { inbound_htlc_minimum_msat: None, inbound_htlc_maximum_msat: None, config: None, + feerate_sat_per_1000_weight: None, } } @@ -5745,7 +5834,7 @@ mod benches { let src = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap(); seed *= 0xdeadbeef; let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap(); - let params = PaymentParameters::from_node_id(dst).with_features(features.clone()); + let params = PaymentParameters::from_node_id(dst, 42).with_features(features.clone()); let first_hop = first_hop(src); let amt = seed as u64 % 1_000_000; if let Ok(route) = get_route(&payer, ¶ms, &graph.read_only(), Some(&[&first_hop]), amt, 42, &DummyLogger{}, &scorer, &random_seed_bytes) {