@@ -576,6 +576,28 @@ pub struct ProbabilisticScoringFeeParameters {
576576/// [`base_penalty_msat`]: Self::base_penalty_msat 
577577/// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat 
578578pub  considered_impossible_penalty_msat :  u64 , 
579+ 
580+ 	/// In order to calculate most of the scores above, we must first convert a lower and upper 
581+ /// bound on the available liquidity in a channel into the probability that we think a payment 
582+ /// will succeed. That probability is derived from a Probability Density Function for where we 
583+ /// think the liquidity in a channel likely lies, given such bounds. 
584+ /// 
585+ /// If this flag is set, that PDF is simply a constant - we assume that the actual available 
586+ /// liquidity in a channel is just as likely to be at any point between our lower and upper 
587+ /// bounds. 
588+ /// 
589+ /// If this flag is *not* set, that PDF is `(x - 0.5*capacity) ^ 6`. That is, we use an 
590+ /// exponential curve which expects the liquidity of a channel to lie "at the edges". This 
591+ /// matches experimental results - most routing nodes do not aggressively rebalance their 
592+ /// channels and flows in the network are often unbalanced, leaving liquidity usually 
593+ /// unavailable. 
594+ /// 
595+ /// Thus, for the "best" routes, leave this flag `false`. However, the flag does imply a number 
596+ /// of floating-point multiplications in the hottest routing code, which may lead to routing 
597+ /// performance degradation on some machines. 
598+ /// 
599+ /// Default value: false 
600+ pub  linear_success_probability :  bool , 
579601} 
580602
581603impl  Default  for  ProbabilisticScoringFeeParameters  { 
@@ -590,6 +612,7 @@ impl Default for ProbabilisticScoringFeeParameters {
590612			considered_impossible_penalty_msat :  1_0000_0000_000 , 
591613			historical_liquidity_penalty_multiplier_msat :  10_000 , 
592614			historical_liquidity_penalty_amount_multiplier_msat :  64 , 
615+ 			linear_success_probability :  false , 
593616		} 
594617	} 
595618} 
@@ -643,6 +666,7 @@ impl ProbabilisticScoringFeeParameters {
643666			manual_node_penalties :  HashMap :: new ( ) , 
644667			anti_probing_penalty_msat :  0 , 
645668			considered_impossible_penalty_msat :  0 , 
669+ 			linear_success_probability :  true , 
646670		} 
647671	} 
648672} 
@@ -1008,14 +1032,42 @@ const BASE_AMOUNT_PENALTY_DIVISOR: u64 = 1 << 30;
10081032/// seen an HTLC successfully complete over this channel. 
10091033fn  success_probability ( 
10101034	min_liquidity_msat :  u64 ,  amount_msat :  u64 ,  max_liquidity_msat :  u64 ,  capacity_msat :  u64 , 
1011- 	_params :  & ProbabilisticScoringFeeParameters ,  min_zero_implies_no_successes :  bool , 
1035+ 	params :  & ProbabilisticScoringFeeParameters ,  min_zero_implies_no_successes :  bool , 
10121036)  -> ( u64 ,  u64 )  { 
10131037	debug_assert ! ( min_liquidity_msat <= amount_msat) ; 
10141038	debug_assert ! ( amount_msat < max_liquidity_msat) ; 
10151039	debug_assert ! ( max_liquidity_msat <= capacity_msat) ; 
10161040
1017- 	let  numerator = max_liquidity_msat - amount_msat; 
1018- 	let  mut  denominator = ( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ; 
1041+ 	let  ( numerator,  mut  denominator)  =
1042+ 		if  params. linear_success_probability  { 
1043+ 			( max_liquidity_msat - amount_msat, 
1044+ 				( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ) 
1045+ 		}  else  { 
1046+ 			let  capacity = capacity_msat as  f64 ; 
1047+ 			let  min = ( min_liquidity_msat as  f64 )  / capacity; 
1048+ 			let  max = ( max_liquidity_msat as  f64 )  / capacity; 
1049+ 			let  amount = ( amount_msat as  f64 )  / capacity; 
1050+ 
1051+ 			// Assume the channel has a probability density function of (x - 0.5)^6 for values from 0 to 1 
1052+ 			// (where 1 is the channel's full capacity). The success probability given some liquidity 
1053+ 			// bounds is thus the integral under the curve from the minimum liquidity to the amount, 
1054+ 			// divided by the same integral from the minimum to the maximum liquidity bounds. 
1055+ 			// 
1056+ 			// For (x - 0.5)^7, this means simply subtracting the two bounds mius 0.5 to the 7th power. 
1057+ 			let  max_pow = ( max - 0.5 ) . powi ( 7 ) ; 
1058+ 			let  num = max_pow - ( amount - 0.5 ) . powi ( 7 ) ; 
1059+ 			let  den = max_pow - ( min - 0.5 ) . powi ( 7 ) ; 
1060+ 
1061+ 			// Because our numerator and denominator max out at 2^-6 we need to multiply them by 
1062+ 			// quite a large factor to get something useful (ideally in the 2^30 range). 
1063+ 			const  ALMOST_TRILLION :  f64  = 1024.0  *  1024.0  *  1024.0  *  32.0 ; 
1064+ 			let  numerator = ( num *  ALMOST_TRILLION )  as  u64  + 1 ; 
1065+ 			let  denominator = ( den *  ALMOST_TRILLION )  as  u64  + 1 ; 
1066+ 			debug_assert ! ( numerator <= 1  << 30 ,  "Got large numerator ({}) from float {}." ,  numerator,  num) ; 
1067+ 			debug_assert ! ( denominator <= 1  << 30 ,  "Got large denominator ({}) from float {}." ,  denominator,  den) ; 
1068+ 			( numerator,  denominator) 
1069+ 		} ; 
1070+ 
10191071	if  min_zero_implies_no_successes && min_liquidity_msat == 0  &&
10201072		denominator < u64:: max_value ( )  / 21 
10211073	{ 
@@ -2970,47 +3022,47 @@ mod tests {
29703022			inflight_htlc_msat :  0 , 
29713023			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  950_000_000 ,  htlc_maximum_msat :  1_000  } , 
29723024		} ; 
2973- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  6262 ) ; 
3025+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  17757 ) ; 
29743026		let  usage = ChannelUsage  { 
29753027			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  1_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29763028		} ; 
2977- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4634 ) ; 
3029+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  11812 ) ; 
29783030		let  usage = ChannelUsage  { 
29793031			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  2_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29803032		} ; 
2981- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4186 ) ; 
3033+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  9264 ) ; 
29823034		let  usage = ChannelUsage  { 
29833035			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  3_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29843036		} ; 
2985- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3909 ) ; 
3037+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  7912 ) ; 
29863038		let  usage = ChannelUsage  { 
29873039			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  4_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29883040		} ; 
2989- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3556 ) ; 
3041+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  7157 ) ; 
29903042		let  usage = ChannelUsage  { 
29913043			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  5_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29923044		} ; 
2993- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3533 ) ; 
3045+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  6402 ) ; 
29943046		let  usage = ChannelUsage  { 
29953047			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  6_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29963048		} ; 
2997- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3172 ) ; 
3049+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  5931 ) ; 
29983050		let  usage = ChannelUsage  { 
29993051			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  7_450_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30003052		} ; 
3001- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3211 ) ; 
3053+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  5931 ) ; 
30023054		let  usage = ChannelUsage  { 
30033055			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  7_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30043056		} ; 
3005- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3243 ) ; 
3057+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  5679 ) ; 
30063058		let  usage = ChannelUsage  { 
30073059			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  8_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30083060		} ; 
3009- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3297 ) ; 
3061+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  5459 ) ; 
30103062		let  usage = ChannelUsage  { 
30113063			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  9_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30123064		} ; 
3013- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3250 ) ; 
3065+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  5208 ) ; 
30143066	} 
30153067
30163068	#[ test]  
0 commit comments