X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Frouter.rs;h=710101299c038e08ed7407b145d99d7f865e557e;hb=f2b2920b135887eb30e2230e4a11833edc43e04c;hp=799b6407981341b0bc4fbfae0f387bdbe23186ad;hpb=266a3aa9152e9d50570ae41b3be1548a715d0754;p=rust-lightning diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 799b6407..71010129 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -337,23 +337,34 @@ pub struct Route { /// [`BlindedTail`]s are present, then the pubkey of the last [`RouteHop`] in each path must be /// the same. pub paths: Vec, - /// The `payment_params` parameter passed via [`RouteParameters`] to [`find_route`]. + /// The `route_params` parameter passed to [`find_route`]. /// /// This is used by `ChannelManager` to track information which may be required for retries. - pub payment_params: Option, + /// + /// Will be `None` for objects serialized with LDK versions prior to 0.0.117. + pub route_params: Option, } impl Route { /// Returns the total amount of fees paid on this [`Route`]. /// - /// This doesn't include any extra payment made to the recipient, which can happen in excess of - /// the amount passed to [`find_route`]'s `route_params.final_value_msat`. + /// For objects serialized with LDK 0.0.117 and after, this includes any extra payment made to + /// the recipient, which can happen in excess of the amount passed to [`find_route`] via + /// [`RouteParameters::final_value_msat`], if we had to reach the [`htlc_minimum_msat`] limits. + /// + /// [`htlc_minimum_msat`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_update-message pub fn get_total_fees(&self) -> u64 { - self.paths.iter().map(|path| path.fee_msat()).sum() + let overpaid_value_msat = self.route_params.as_ref() + .map_or(0, |p| self.get_total_amount().saturating_sub(p.final_value_msat)); + overpaid_value_msat + self.paths.iter().map(|path| path.fee_msat()).sum::() } - /// Returns the total amount paid on this [`Route`], excluding the fees. Might be more than - /// requested if we had to reach htlc_minimum_msat. + /// Returns the total amount paid on this [`Route`], excluding the fees. + /// + /// Might be more than requested as part of the given [`RouteParameters::final_value_msat`] if + /// we had to reach the [`htlc_minimum_msat`] limits. + /// + /// [`htlc_minimum_msat`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_update-message pub fn get_total_amount(&self) -> u64 { self.paths.iter().map(|path| path.final_value_msat()).sum() } @@ -383,8 +394,11 @@ impl Writeable for Route { } } write_tlv_fields!(writer, { - (1, self.payment_params, option), + // For compatibility with LDK versions prior to 0.0.117, we take the individual + // RouteParameters' fields and reconstruct them on read. + (1, self.route_params.as_ref().map(|p| &p.payment_params), option), (2, blinded_tails, optional_vec), + (3, self.route_params.as_ref().map(|p| p.final_value_msat), option), }); Ok(()) } @@ -411,6 +425,7 @@ impl Readable for Route { _init_and_read_len_prefixed_tlv_fields!(reader, { (1, payment_params, (option: ReadableArgs, min_final_cltv_expiry_delta)), (2, blinded_tails, optional_vec), + (3, final_value_msat, option), }); let blinded_tails = blinded_tails.unwrap_or(Vec::new()); if blinded_tails.len() != 0 { @@ -419,14 +434,23 @@ impl Readable for Route { path.blinded_tail = blinded_tail_opt; } } - Ok(Route { paths, payment_params }) + + // If we previously wrote the corresponding fields, reconstruct RouteParameters. + let route_params = match (payment_params, final_value_msat) { + (Some(payment_params), Some(final_value_msat)) => { + Some(RouteParameters { payment_params, final_value_msat }) + } + _ => None, + }; + + Ok(Route { paths, route_params }) } } /// Parameters needed to find a [`Route`]. /// /// Passed to [`find_route`] and [`build_route_from_hops`]. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct RouteParameters { /// The parameters of the failed payment path. pub payment_params: PaymentParameters, @@ -2291,8 +2315,9 @@ where L::Target: Logger { // Decrease the available liquidity of a hop in the middle of the path. let victim_candidate = &payment_path.hops[(payment_path.hops.len()) / 2].0.candidate; let exhausted = u64::max_value(); - log_trace!(logger, "Disabling route candidate {} for future path building iterations to - avoid duplicates.", LoggedCandidateHop(victim_candidate)); + log_trace!(logger, + "Disabling route candidate {} for future path building iterations to avoid duplicates.", + LoggedCandidateHop(victim_candidate)); *used_liquidities.entry(victim_candidate.id(false)).or_default() = exhausted; *used_liquidities.entry(victim_candidate.id(true)).or_default() = exhausted; } @@ -2489,7 +2514,7 @@ where L::Target: Logger { } } - let route = Route { paths, payment_params: Some(payment_params.clone()) }; + let route = Route { paths, route_params: Some(route_params.clone()) }; log_info!(logger, "Got route: {}", log_route!(route)); Ok(route) } @@ -5953,7 +5978,7 @@ mod tests { short_channel_id: 0, fee_msat: 225, cltv_expiry_delta: 0 }, ], blinded_tail: None }], - payment_params: None, + route_params: None, }; assert_eq!(route.get_total_fees(), 250); @@ -5986,7 +6011,7 @@ mod tests { short_channel_id: 0, fee_msat: 150, cltv_expiry_delta: 0 }, ], blinded_tail: None }], - payment_params: None, + route_params: None, }; assert_eq!(route.get_total_fees(), 200); @@ -5998,7 +6023,7 @@ mod tests { // In an earlier version of `Route::get_total_fees` and `Route::get_total_amount`, they // would both panic if the route was completely empty. We test to ensure they return 0 // here, even though its somewhat nonsensical as a route. - let route = Route { paths: Vec::new(), payment_params: None }; + let route = Route { paths: Vec::new(), route_params: None }; assert_eq!(route.get_total_fees(), 0); assert_eq!(route.get_total_amount(), 0); @@ -6597,7 +6622,7 @@ mod tests { fee_msat: 100, cltv_expiry_delta: 0, }], blinded_tail: None }], - payment_params: None, + route_params: None, }; let encoded_route = route.encode(); let decoded_route: Route = Readable::read(&mut Cursor::new(&encoded_route[..])).unwrap(); @@ -6691,7 +6716,7 @@ mod tests { excess_final_cltv_expiry_delta: 0, final_value_msat: 200, }), - }], payment_params: None}; + }], route_params: None}; let payment_params = PaymentParameters::from_node_id(ln_test_utils::pubkey(47), 18); let (_, network_graph, _, _, _) = build_line_graph(); @@ -7300,6 +7325,42 @@ pub mod benches { "generate_large_mpp_routes_with_probabilistic_scorer"); } + pub fn generate_routes_with_nonlinear_probabilistic_scorer(bench: &mut Criterion) { + let logger = TestLogger::new(); + let network_graph = bench_utils::read_network_graph(&logger).unwrap(); + let mut params = ProbabilisticScoringFeeParameters::default(); + params.linear_success_probability = false; + let scorer = ProbabilisticScorer::new( + ProbabilisticScoringDecayParameters::default(), &network_graph, &logger); + generate_routes(bench, &network_graph, scorer, ¶ms, + channelmanager::provided_invoice_features(&UserConfig::default()), 0, + "generate_routes_with_nonlinear_probabilistic_scorer"); + } + + pub fn generate_mpp_routes_with_nonlinear_probabilistic_scorer(bench: &mut Criterion) { + let logger = TestLogger::new(); + let network_graph = bench_utils::read_network_graph(&logger).unwrap(); + let mut params = ProbabilisticScoringFeeParameters::default(); + params.linear_success_probability = false; + let scorer = ProbabilisticScorer::new( + ProbabilisticScoringDecayParameters::default(), &network_graph, &logger); + generate_routes(bench, &network_graph, scorer, ¶ms, + channelmanager::provided_invoice_features(&UserConfig::default()), 0, + "generate_mpp_routes_with_nonlinear_probabilistic_scorer"); + } + + pub fn generate_large_mpp_routes_with_nonlinear_probabilistic_scorer(bench: &mut Criterion) { + let logger = TestLogger::new(); + let network_graph = bench_utils::read_network_graph(&logger).unwrap(); + let mut params = ProbabilisticScoringFeeParameters::default(); + params.linear_success_probability = false; + let scorer = ProbabilisticScorer::new( + ProbabilisticScoringDecayParameters::default(), &network_graph, &logger); + generate_routes(bench, &network_graph, scorer, ¶ms, + channelmanager::provided_invoice_features(&UserConfig::default()), 100_000_000, + "generate_large_mpp_routes_with_nonlinear_probabilistic_scorer"); + } + fn generate_routes( bench: &mut Criterion, graph: &NetworkGraph<&TestLogger>, mut scorer: S, score_params: &S::ScoreParams, features: Bolt11InvoiceFeatures, starting_amount: u64,