@@ -616,7 +616,7 @@ impl HistoricalMinMaxBuckets<'_> {
616616
617617 #[ inline]
618618 fn calculate_success_probability_times_billion < T : Time > (
619- & self , now : T , last_updated : T , half_life : Duration , payment_amt_64th_bucket : u8 )
619+ & self , now : T , last_updated : T , half_life : Duration , amount_msat : u64 , capacity_msat : u64 )
620620 -> Option < u64 > {
621621 // If historical penalties are enabled, calculate the penalty by walking the set of
622622 // historical liquidity bucket (min, max) combinations (where min_idx < max_idx) and, for
@@ -639,6 +639,20 @@ impl HistoricalMinMaxBuckets<'_> {
639639 // less than 1/16th of a channel's capacity, or 1/8th if we used the top of the bucket.
640640 let mut total_valid_points_tracked = 0 ;
641641
642+ let payment_amt_64th_bucket: u8 = if amount_msat < u64:: max_value ( ) / 64 {
643+ ( amount_msat * 64 / capacity_msat. saturating_add ( 1 ) )
644+ . try_into ( ) . unwrap_or ( 65 )
645+ } else {
646+ // Only use 128-bit arithmetic when multiplication will overflow to avoid 128-bit
647+ // division. This branch should only be hit in fuzz testing since the amount would
648+ // need to be over 2.88 million BTC in practice.
649+ ( ( amount_msat as u128 ) * 64 / ( capacity_msat as u128 ) . saturating_add ( 1 ) )
650+ . try_into ( ) . unwrap_or ( 65 )
651+ } ;
652+ #[ cfg( not( fuzzing) ) ]
653+ debug_assert ! ( payment_amt_64th_bucket <= 64 ) ;
654+ if payment_amt_64th_bucket >= 64 { return None ; }
655+
642656 // Check if all our buckets are zero, once decayed and treat it as if we had no data. We
643657 // don't actually use the decayed buckets, though, as that would lose precision.
644658 let ( decayed_min_buckets, decayed_max_buckets, required_decays) =
@@ -1043,26 +1057,13 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
10431057
10441058 if params. historical_liquidity_penalty_multiplier_msat != 0 ||
10451059 params. historical_liquidity_penalty_amount_multiplier_msat != 0 {
1046- let payment_amt_64th_bucket = if amount_msat < u64:: max_value ( ) / 64 {
1047- amount_msat * 64 / self . capacity_msat . saturating_add ( 1 )
1048- } else {
1049- // Only use 128-bit arithmetic when multiplication will overflow to avoid 128-bit
1050- // division. This branch should only be hit in fuzz testing since the amount would
1051- // need to be over 2.88 million BTC in practice.
1052- ( ( amount_msat as u128 ) * 64 / ( self . capacity_msat as u128 ) . saturating_add ( 1 ) )
1053- . try_into ( ) . unwrap_or ( 65 )
1054- } ;
1055- #[ cfg( not( fuzzing) ) ]
1056- debug_assert ! ( payment_amt_64th_bucket <= 64 ) ;
1057- if payment_amt_64th_bucket > 64 { return res; }
1058-
10591060 let buckets = HistoricalMinMaxBuckets {
10601061 min_liquidity_offset_history : & self . min_liquidity_offset_history ,
10611062 max_liquidity_offset_history : & self . max_liquidity_offset_history ,
10621063 } ;
10631064 if let Some ( cumulative_success_prob_times_billion) = buckets
10641065 . calculate_success_probability_times_billion ( self . now , * self . last_updated ,
1065- params. historical_no_updates_half_life , payment_amt_64th_bucket as u8 )
1066+ params. historical_no_updates_half_life , amount_msat , self . capacity_msat )
10661067 {
10671068 let historical_negative_log10_times_2048 = approx:: negative_log10_times_2048 ( cumulative_success_prob_times_billion + 1 , 1024 * 1024 * 1024 ) ;
10681069 res = res. saturating_add ( Self :: combined_penalty_msat ( amount_msat,
0 commit comments