diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index 76f67ea11b1..0f25f108c0c 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -1771,7 +1771,7 @@ mod bucketed_history { // Because the first thing we do is check if `total_valid_points` is sufficient to consider // the data here at all, and can return early if it is not, we want this to go first to // avoid hitting a second cache line load entirely in that case. - total_valid_points_tracked: f64, + total_valid_points_tracked: u64, min_liquidity_offset_history: HistoricalBucketRangeTracker, max_liquidity_offset_history: HistoricalBucketRangeTracker, } @@ -1781,7 +1781,7 @@ mod bucketed_history { HistoricalLiquidityTracker { min_liquidity_offset_history: HistoricalBucketRangeTracker::new(), max_liquidity_offset_history: HistoricalBucketRangeTracker::new(), - total_valid_points_tracked: 0.0, + total_valid_points_tracked: 0, } } @@ -1792,7 +1792,7 @@ mod bucketed_history { let mut res = HistoricalLiquidityTracker { min_liquidity_offset_history, max_liquidity_offset_history, - total_valid_points_tracked: 0.0, + total_valid_points_tracked: 0, }; res.recalculate_valid_point_count(); res @@ -1823,7 +1823,7 @@ mod bucketed_history { total_valid_points_tracked += bucket_weight; } } - self.total_valid_points_tracked = total_valid_points_tracked as f64; + self.total_valid_points_tracked = total_valid_points_tracked; } pub(super) fn writeable_min_offset_history(&self) -> &HistoricalBucketRangeTracker { @@ -1914,18 +1914,18 @@ mod bucketed_history { actual_valid_points_tracked += bucket_weight; } } - assert_eq!(total_valid_points_tracked, actual_valid_points_tracked as f64); + assert_eq!(total_valid_points_tracked, actual_valid_points_tracked); } // If the total valid points is smaller than 1.0 (i.e. 16 in our fixed-point scheme), // treat it as if we were fully decayed. - const FULLY_DECAYED: f64 = BUCKET_FIXED_POINT_ONE as f64 * BUCKET_FIXED_POINT_ONE as f64 * - BUCKET_FIXED_POINT_ONE as f64 * BUCKET_FIXED_POINT_ONE as f64; - if total_valid_points_tracked < FULLY_DECAYED.into() { + const FULLY_DECAYED: u64 = BUCKET_FIXED_POINT_ONE as u64 * BUCKET_FIXED_POINT_ONE as u64 * + BUCKET_FIXED_POINT_ONE as u64 * BUCKET_FIXED_POINT_ONE as u64; + if total_valid_points_tracked < FULLY_DECAYED { return None; } - let mut cumulative_success_prob = 0.0f64; + let mut cumulative_success_prob_times_billion = 0; // Special-case the 0th min bucket - it generally means we failed a payment, so only // consider the highest (i.e. largest-offset-from-max-capacity) max bucket for all // points against the 0th min bucket. This avoids the case where we fail to route @@ -1949,7 +1949,7 @@ mod bucketed_history { total_weight += (*max_bucket as u64) * (*max_bucket as u64) * (min_liquidity_offset_history_buckets[0] as u64) * (min_liquidity_offset_history_buckets[0] as u64); } - debug_assert!(total_weight as f64 <= total_valid_points_tracked); + debug_assert!(total_weight <= total_valid_points_tracked); // Use the highest max-bucket with at least BUCKET_FIXED_POINT_ONE, but if none is // available use the highest max-bucket with any non-zero value. This ensures that // if we have substantially decayed data we don't end up thinking the highest @@ -1958,10 +1958,10 @@ mod bucketed_history { let selected_max = highest_max_bucket_with_full_points.unwrap_or(highest_max_bucket_with_points); let max_bucket_end_pos = BUCKET_START_POS[32 - selected_max] - 1; if payment_pos < max_bucket_end_pos { - let (numerator, denominator) = success_probability_float(payment_pos as u64, 0, + let (numerator, denominator) = success_probability(payment_pos as u64, 0, max_bucket_end_pos as u64, POSITION_TICKS as u64 - 1, params, true); - let bucket_prob = total_weight as f64 / total_valid_points_tracked; - cumulative_success_prob += bucket_prob * numerator / denominator; + let bucket_prob = (total_weight as u128) * 1024 * 1024 * 1024 / total_valid_points_tracked as u128; + cumulative_success_prob_times_billion += bucket_prob as u64 * numerator / denominator; } } @@ -1971,24 +1971,25 @@ mod bucketed_history { let max_bucket_end_pos = BUCKET_START_POS[32 - max_idx] - 1; let mut bucket_weight = (*min_bucket as u64) * (*max_bucket as u64); bucket_weight *= bucket_weight; - debug_assert!(bucket_weight as f64 <= total_valid_points_tracked); + debug_assert!(bucket_weight <= total_valid_points_tracked); + + let bucket_prob = (bucket_weight as u128) * 1024 * 1024 * 1024 / total_valid_points_tracked as u128; - let bucket_prob = bucket_weight as f64 / total_valid_points_tracked; if payment_pos >= max_bucket_end_pos { // Success probability 0, the payment amount may be above the max liquidity break; } else if payment_pos < min_bucket_start_pos { - cumulative_success_prob += bucket_prob; + cumulative_success_prob_times_billion += bucket_prob as u64; } else { - let (numerator, denominator) = success_probability_float(payment_pos as u64, + let (numerator, denominator) = success_probability(payment_pos as u64, min_bucket_start_pos as u64, max_bucket_end_pos as u64, POSITION_TICKS as u64 - 1, params, true); - cumulative_success_prob += bucket_prob * numerator / denominator; + cumulative_success_prob_times_billion += bucket_prob as u64 * numerator / denominator; } } } - Some((cumulative_success_prob * (1024.0 * 1024.0 * 1024.0)) as u64) + Some(cumulative_success_prob_times_billion) } } }