@@ -725,7 +725,7 @@ impl HistoricalMinMaxBuckets<'_> {
725725
726726 #[ inline]
727727 fn calculate_success_probability_times_billion < T : Time > (
728- & self , now : T , last_updated : T , half_life : Duration , payment_amt_64th_bucket : u8 )
728+ & self , now : T , last_updated : T , half_life : Duration , amount_msat : u64 , capacity_msat : u64 )
729729 -> Option < u64 > {
730730 // If historical penalties are enabled, calculate the penalty by walking the set of
731731 // historical liquidity bucket (min, max) combinations (where min_idx < max_idx) and, for
@@ -748,6 +748,20 @@ impl HistoricalMinMaxBuckets<'_> {
748748 // less than 1/16th of a channel's capacity, or 1/8th if we used the top of the bucket.
749749 let mut total_valid_points_tracked = 0 ;
750750
751+ let payment_amt_64th_bucket: u8 = if amount_msat < u64:: max_value ( ) / 64 {
752+ ( amount_msat * 64 / capacity_msat. saturating_add ( 1 ) )
753+ . try_into ( ) . unwrap_or ( 65 )
754+ } else {
755+ // Only use 128-bit arithmetic when multiplication will overflow to avoid 128-bit
756+ // division. This branch should only be hit in fuzz testing since the amount would
757+ // need to be over 2.88 million BTC in practice.
758+ ( ( amount_msat as u128 ) * 64 / ( capacity_msat as u128 ) . saturating_add ( 1 ) )
759+ . try_into ( ) . unwrap_or ( 65 )
760+ } ;
761+ #[ cfg( not( fuzzing) ) ]
762+ debug_assert ! ( payment_amt_64th_bucket <= 64 ) ;
763+ if payment_amt_64th_bucket >= 64 { return None ; }
764+
751765 // Check if all our buckets are zero, once decayed and treat it as if we had no data. We
752766 // don't actually use the decayed buckets, though, as that would lose precision.
753767 let ( decayed_min_buckets, decayed_max_buckets, required_decays) =
@@ -1079,26 +1093,13 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
10791093
10801094 if score_params. historical_liquidity_penalty_multiplier_msat != 0 ||
10811095 score_params. historical_liquidity_penalty_amount_multiplier_msat != 0 {
1082- let payment_amt_64th_bucket = if amount_msat < u64:: max_value ( ) / 64 {
1083- amount_msat * 64 / self . capacity_msat . saturating_add ( 1 )
1084- } else {
1085- // Only use 128-bit arithmetic when multiplication will overflow to avoid 128-bit
1086- // division. This branch should only be hit in fuzz testing since the amount would
1087- // need to be over 2.88 million BTC in practice.
1088- ( ( amount_msat as u128 ) * 64 / ( self . capacity_msat as u128 ) . saturating_add ( 1 ) )
1089- . try_into ( ) . unwrap_or ( 65 )
1090- } ;
1091- #[ cfg( not( fuzzing) ) ]
1092- debug_assert ! ( payment_amt_64th_bucket <= 64 ) ;
1093- if payment_amt_64th_bucket > 64 { return res; }
1094-
10951096 let buckets = HistoricalMinMaxBuckets {
10961097 min_liquidity_offset_history : & self . min_liquidity_offset_history ,
10971098 max_liquidity_offset_history : & self . max_liquidity_offset_history ,
10981099 } ;
10991100 if let Some ( cumulative_success_prob_times_billion) = buckets
11001101 . calculate_success_probability_times_billion ( self . now , * self . last_updated ,
1101- self . decay_params . historical_no_updates_half_life , payment_amt_64th_bucket as u8 )
1102+ self . decay_params . historical_no_updates_half_life , amount_msat , self . capacity_msat )
11021103 {
11031104 let historical_negative_log10_times_2048 = approx:: negative_log10_times_2048 ( cumulative_success_prob_times_billion + 1 , 1024 * 1024 * 1024 ) ;
11041105 res = res. saturating_add ( Self :: combined_penalty_msat ( amount_msat,
0 commit comments