@@ -1758,7 +1758,32 @@ mod bucketed_history {
17581758			} 
17591759
17601760			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 )  { 
17621787				let  min_bucket_start_pos = BUCKET_START_POS [ min_idx] ; 
17631788				for  ( max_idx,  max_bucket)  in  self . max_liquidity_offset_history . buckets . iter ( ) . enumerate ( ) . take ( 32  - min_idx)  { 
17641789					let  max_bucket_end_pos = BUCKET_START_POS [ 32  - max_idx]  - 1 ; 
@@ -2989,7 +3014,7 @@ mod tests {
29893014		// Even after we tell the scorer we definitely have enough available liquidity, it will 
29903015		// still remember that there was some failure in the past, and assign a non-0 penalty. 
29913016		scorer. payment_path_failed ( & payment_path_for_amount ( 1000 ) ,  43 ) ; 
2992- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage) ,  198 ) ; 
3017+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage) ,  32 ) ; 
29933018		// The first points should be decayed just slightly and the last bucket has a new point. 
29943019		assert_eq ! ( scorer. historical_estimated_channel_liquidity_probabilities( 42 ,  & target) , 
29953020			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 ] , 
@@ -2999,8 +3024,8 @@ mod tests {
29993024		// simply check bounds here. 
30003025		let  five_hundred_prob =
30013026			scorer. historical_estimated_payment_success_probability ( 42 ,  & target,  500 ) . unwrap ( ) ; 
3002- 		assert ! ( five_hundred_prob > 512  *  1024  *  1024 ) ;  // 0.5  
3003- 		assert ! ( five_hundred_prob < 532  *  1024  *  1024 ) ;  // ~ 0.52  
3027+ 		assert ! ( five_hundred_prob > 680  *  1024  *  1024 ) ;  // ~0.66  
3028+ 		assert ! ( five_hundred_prob < 690  *  1024  *  1024 ) ;  // ~0.67  
30043029		let  one_prob =
30053030			scorer. historical_estimated_payment_success_probability ( 42 ,  & target,  1 ) . unwrap ( ) ; 
30063031		assert ! ( one_prob < 1024  *  1024  *  1024 ) ; 
@@ -3199,16 +3224,14 @@ mod tests {
31993224		assert_eq ! ( scorer. historical_estimated_payment_success_probability( 42 ,  & target,  amount_msat) , 
32003225			Some ( 512  *  1024  *  1024 ) ) ; 
32013226
3202- 		// ...but once  we see a failure, we consider  the payment to be substantially less likely,  
3203- 		// even though not a  probability of  zero as we still  look at the second max  bucket which  
3204- 		// now shows 31 . 
3227+ 		// Once  we see a second  failure for  the lower amount, we'll again consider the success  
3228+ 		// probability zero,  as we only  look at the lowest-value maximum  bucket when all previous  
3229+ 		// attempts at using a channel have failed . 
32053230		scorer. payment_path_failed ( & payment_path_for_amount ( amount_msat) . iter ( ) . collect :: < Vec < _ > > ( ) ,  42 ) ; 
32063231		assert_eq ! ( scorer. historical_estimated_channel_liquidity_probabilities( 42 ,  & target) , 
32073232			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 ] , 
32083233				[ 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 ] ) ) ) ; 
3209- 		assert ! ( scorer. historical_estimated_payment_success_probability( 42 ,  & target,  amount_msat) 
3210- 			. unwrap( )  > 251  *  1024  *  1024 ) ; 
3211- 		assert ! ( scorer. historical_estimated_payment_success_probability( 42 ,  & target,  amount_msat) 
3212- 			. unwrap( )  < 256  *  1024  *  1024 ) ; 
3234+ 		assert_eq ! ( scorer. historical_estimated_payment_success_probability( 42 ,  & target,  amount_msat) , 
3235+ 			Some ( 0 ) ) ; 
32133236	} 
32143237} 
0 commit comments