@@ -1758,7 +1758,32 @@ mod bucketed_history {
1758
1758
}
1759
1759
1760
1760
let mut cumulative_success_prob_times_billion = 0 ;
1761
- for ( min_idx, min_bucket) in self . min_liquidity_offset_history . buckets . iter ( ) . enumerate ( ) {
1761
+ // Special-case the 0th min bucket - it generally means we failed a payment, so only
1762
+ // consider the highest (i.e. largest-offset-from-max-capacity) max bucket for all
1763
+ // points against the 0th min bucket!
1764
+ if self . min_liquidity_offset_history . buckets [ 0 ] != 0 {
1765
+ let mut highest_max_bucket_with_points = 0 ;
1766
+ let mut total_max_points = 0 ;
1767
+ for ( max_idx, max_bucket) in self . max_liquidity_offset_history . buckets . iter ( ) . enumerate ( ) {
1768
+ if * max_bucket >= 32 {
1769
+ highest_max_bucket_with_points = cmp:: max ( highest_max_bucket_with_points, max_idx) ;
1770
+ }
1771
+ total_max_points += * max_bucket as u64 ;
1772
+ }
1773
+ let max_bucket_end_pos = BUCKET_START_POS [ 32 - highest_max_bucket_with_points] - 1 ;
1774
+ if payment_pos < max_bucket_end_pos {
1775
+ let bucket_prob_times_billion =
1776
+ ( self . min_liquidity_offset_history . buckets [ 0 ] as u64 ) * total_max_points
1777
+ * 1024 * 1024 * 1024 / total_valid_points_tracked;
1778
+ cumulative_success_prob_times_billion += bucket_prob_times_billion *
1779
+ ( ( max_bucket_end_pos - payment_pos) as u64 ) /
1780
+ // Add an additional one in the divisor as the payment bucket has been
1781
+ // rounded down.
1782
+ ( max_bucket_end_pos + 1 ) as u64 ;
1783
+ }
1784
+ }
1785
+
1786
+ for ( min_idx, min_bucket) in self . min_liquidity_offset_history . buckets . iter ( ) . enumerate ( ) . skip ( 1 ) {
1762
1787
let min_bucket_start_pos = BUCKET_START_POS [ min_idx] ;
1763
1788
for ( max_idx, max_bucket) in self . max_liquidity_offset_history . buckets . iter ( ) . enumerate ( ) . take ( 32 - min_idx) {
1764
1789
let max_bucket_end_pos = BUCKET_START_POS [ 32 - max_idx] - 1 ;
@@ -2987,7 +3012,7 @@ mod tests {
2987
3012
// Even after we tell the scorer we definitely have enough available liquidity, it will
2988
3013
// still remember that there was some failure in the past, and assign a non-0 penalty.
2989
3014
scorer. payment_path_failed ( & payment_path_for_amount ( 1000 ) . iter ( ) . collect :: < Vec < _ > > ( ) , 43 ) ;
2990
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 198 ) ;
3015
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 32 ) ;
2991
3016
// The first points should be decayed just slightly and the last bucket has a new point.
2992
3017
assert_eq ! ( scorer. historical_estimated_channel_liquidity_probabilities( 42 , & target) ,
2993
3018
Some ( ( [ 31 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 32 , 0 , 0 , 0 , 0 , 0 ] ,
@@ -2997,8 +3022,8 @@ mod tests {
2997
3022
// simply check bounds here.
2998
3023
let five_hundred_prob =
2999
3024
scorer. historical_estimated_payment_success_probability ( 42 , & target, 500 ) . unwrap ( ) ;
3000
- assert ! ( five_hundred_prob > 512 * 1024 * 1024 ) ; // 0.5
3001
- assert ! ( five_hundred_prob < 532 * 1024 * 1024 ) ; // ~ 0.52
3025
+ assert ! ( five_hundred_prob > 680 * 1024 * 1024 ) ; // ~0.66
3026
+ assert ! ( five_hundred_prob < 690 * 1024 * 1024 ) ; // ~0.67
3002
3027
let one_prob =
3003
3028
scorer. historical_estimated_payment_success_probability ( 42 , & target, 1 ) . unwrap ( ) ;
3004
3029
assert ! ( one_prob < 1024 * 1024 * 1024 ) ;
@@ -3147,16 +3172,14 @@ mod tests {
3147
3172
assert_eq ! ( scorer. historical_estimated_payment_success_probability( 42 , & target, amount_msat) ,
3148
3173
Some ( 512 * 1024 * 1024 ) ) ;
3149
3174
3150
- // ...but once we see a failure, we consider the payment to be substantially less likely,
3151
- // even though not a probability of zero as we still look at the second max bucket which
3152
- // now shows 31 .
3175
+ // Once we see a second failure for the lower amount, we'll again consider the success
3176
+ // probability zero, as we only look at the lowest-value maximum bucket when all previous
3177
+ // attempts at using a channel have failed .
3153
3178
scorer. payment_path_failed ( & payment_path_for_amount ( amount_msat) . iter ( ) . collect :: < Vec < _ > > ( ) , 42 ) ;
3154
3179
assert_eq ! ( scorer. historical_estimated_channel_liquidity_probabilities( 42 , & target) ,
3155
3180
Some ( ( [ 63 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ,
3156
3181
[ 32 , 31 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ) ) ;
3157
- assert ! ( scorer. historical_estimated_payment_success_probability( 42 , & target, amount_msat)
3158
- . unwrap( ) > 251 * 1024 * 1024 ) ;
3159
- assert ! ( scorer. historical_estimated_payment_success_probability( 42 , & target, amount_msat)
3160
- . unwrap( ) < 256 * 1024 * 1024 ) ;
3182
+ assert_eq ! ( scorer. historical_estimated_payment_success_probability( 42 , & target, amount_msat) ,
3183
+ Some ( 0 ) ) ;
3161
3184
}
3162
3185
}
0 commit comments