From: Jeffrey Czyz Date: Thu, 24 Mar 2022 23:21:29 +0000 (-0500) Subject: Fix overflow in ProbabilisticScorer X-Git-Tag: v0.0.106~6^2~2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=4ea18e323292ddee00c84cad8bfdb3bb2bc64306;p=rust-lightning Fix overflow in ProbabilisticScorer When a routing hint is given in an invoice, the effective capacity of the channel is assumed to be infinite (i.e., u64::max_value) if the hop is private. Adding 1 to this in the success probability calculation will cause an overflow and ultimately an `index out of bounds panic` in log10_times_1024. This was not an issue with using log10 because the use of f64 would give infinite which casts to 0 for u64. --- diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index 22d7012c..d9d0bee3 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -673,8 +673,8 @@ impl, T: Time, U: Deref> DirectedChannelLiqui } else if amount_msat <= min_liquidity_msat { 0 } else { - let numerator = max_liquidity_msat + 1 - amount_msat; - let denominator = max_liquidity_msat + 1 - min_liquidity_msat; + let numerator = (max_liquidity_msat - amount_msat).saturating_add(1); + let denominator = (max_liquidity_msat - min_liquidity_msat).saturating_add(1); approx::negative_log10_times_1024(numerator, denominator) .saturating_mul(liquidity_penalty_multiplier_msat) / 1024 } @@ -2061,4 +2061,20 @@ mod tests { let scorer = ProbabilisticScorer::new(params, &network_graph); assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 1085); } + + #[test] + fn calculates_log10_without_overflowing_u64_max_value() { + let network_graph = network_graph(); + let source = source_node_id(); + let target = target_node_id(); + + let params = ProbabilisticScoringParameters { + base_penalty_msat: 0, ..Default::default() + }; + let scorer = ProbabilisticScorer::new(params, &network_graph); + assert_eq!( + scorer.channel_penalty_msat(42, u64::max_value(), u64::max_value(), &source, &target), + 20_000, + ); + } }