@@ -580,6 +580,28 @@ pub struct ProbabilisticScoringFeeParameters {
580580/// [`base_penalty_msat`]: Self::base_penalty_msat 
581581/// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat 
582582pub  considered_impossible_penalty_msat :  u64 , 
583+ 
584+ 	/// In order to calculate most of the scores above, we must first convert a lower and upper 
585+ /// bound on the available liquidity in a channel into the probability that we think a payment 
586+ /// will succeed. That probability is derived from a Probability Density Function for where we 
587+ /// think the liquidity in a channel likely lies, given such bounds. 
588+ /// 
589+ /// If this flag is set, that PDF is simply a constant - we assume that the actual available 
590+ /// liquidity in a channel is just as likely to be at any point between our lower and upper 
591+ /// bounds. 
592+ /// 
593+ /// If this flag is *not* set, that PDF is `(x - 0.5*capacity) ^ 2`. That is, we use an 
594+ /// exponential curve which expects the liquidity of a channel to lie "at the edges". This 
595+ /// matches experimental results - most routing nodes do not aggressively rebalance their 
596+ /// channels and flows in the network are often unbalanced, leaving liquidity usually 
597+ /// unavailable. 
598+ /// 
599+ /// Thus, for the "best" routes, leave this flag `false`. However, the flag does imply a number 
600+ /// of floating-point multiplications in the hottest routing code, which may lead to routing 
601+ /// performance degradation on some machines. 
602+ /// 
603+ /// Default value: false 
604+ pub  linear_success_probability :  bool , 
583605} 
584606
585607impl  Default  for  ProbabilisticScoringFeeParameters  { 
@@ -594,6 +616,7 @@ impl Default for ProbabilisticScoringFeeParameters {
594616			considered_impossible_penalty_msat :  1_0000_0000_000 , 
595617			historical_liquidity_penalty_multiplier_msat :  10_000 , 
596618			historical_liquidity_penalty_amount_multiplier_msat :  64 , 
619+ 			linear_success_probability :  false , 
597620		} 
598621	} 
599622} 
@@ -647,6 +670,7 @@ impl ProbabilisticScoringFeeParameters {
647670			manual_node_penalties :  HashMap :: new ( ) , 
648671			anti_probing_penalty_msat :  0 , 
649672			considered_impossible_penalty_msat :  0 , 
673+ 			linear_success_probability :  true , 
650674		} 
651675	} 
652676} 
@@ -999,6 +1023,12 @@ const PRECISION_LOWER_BOUND_DENOMINATOR: u64 = approx::LOWER_BITS_BOUND;
9991023const  AMOUNT_PENALTY_DIVISOR :  u64  = 1  << 20 ; 
10001024const  BASE_AMOUNT_PENALTY_DIVISOR :  u64  = 1  << 30 ; 
10011025
1026+ /// Raises three `f64`s to the 3rd power, without `powi` because it requires `std` (dunno why). 
1027+ #[ inline( always) ]  
1028+ fn  three_f64_pow_3 ( a :  f64 ,  b :  f64 ,  c :  f64 )  -> ( f64 ,  f64 ,  f64 )  { 
1029+ 	( a *  a *  a,  b *  b *  b,  c *  c *  c) 
1030+ } 
1031+ 
10021032/// Given liquidity bounds, calculates the success probability (in the form of a numerator and 
10031033/// denominator) of an HTLC. This is a key assumption in our scoring models. 
10041034/// 
@@ -1009,14 +1039,46 @@ const BASE_AMOUNT_PENALTY_DIVISOR: u64 = 1 << 30;
10091039#[ inline( always) ]  
10101040fn  success_probability ( 
10111041	amount_msat :  u64 ,  min_liquidity_msat :  u64 ,  max_liquidity_msat :  u64 ,  capacity_msat :  u64 , 
1012- 	_params :  & ProbabilisticScoringFeeParameters ,  min_zero_implies_no_successes :  bool , 
1042+ 	params :  & ProbabilisticScoringFeeParameters ,  min_zero_implies_no_successes :  bool , 
10131043)  -> ( u64 ,  u64 )  { 
10141044	debug_assert ! ( min_liquidity_msat <= amount_msat) ; 
10151045	debug_assert ! ( amount_msat < max_liquidity_msat) ; 
10161046	debug_assert ! ( max_liquidity_msat <= capacity_msat) ; 
10171047
1018- 	let  numerator = max_liquidity_msat - amount_msat; 
1019- 	let  mut  denominator = ( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ; 
1048+ 	let  ( numerator,  mut  denominator)  =
1049+ 		if  params. linear_success_probability  { 
1050+ 			( max_liquidity_msat - amount_msat, 
1051+ 				( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ) 
1052+ 		}  else  { 
1053+ 			let  capacity = capacity_msat as  f64 ; 
1054+ 			let  min = ( min_liquidity_msat as  f64 )  / capacity; 
1055+ 			let  max = ( max_liquidity_msat as  f64 )  / capacity; 
1056+ 			let  amount = ( amount_msat as  f64 )  / capacity; 
1057+ 
1058+ 			// Assume the channel has a probability density function of (x - 0.5)^2 for values from 
1059+ 			// 0 to 1 (where 1 is the channel's full capacity). The success probability given some 
1060+ 			// liquidity bounds is thus the integral under the curve from the amount to maximum 
1061+ 			// estimated liquidity, divided by the same integral from the minimum to the maximum 
1062+ 			// estimated liquidity bounds. 
1063+ 			// 
1064+ 			// Because the integral from x to y is simply (y - 0.5)^3 - (x - 0.5)^3, we can 
1065+ 			// calculate the cumulative density function between the min/max bounds trivially. Note 
1066+ 			// that we don't bother to normalize the CDF to total to 1, as it will come out in the 
1067+ 			// division of num / den. 
1068+ 			let  ( max_pow,  amt_pow,  min_pow)  = three_f64_pow_3 ( max - 0.5 ,  amount - 0.5 ,  min - 0.5 ) ; 
1069+ 			let  num = max_pow - amt_pow; 
1070+ 			let  den = max_pow - min_pow; 
1071+ 
1072+ 			// Because our numerator and denominator max out at 0.5^3 we need to multiply them by 
1073+ 			// quite a large factor to get something useful (ideally in the 2^30 range). 
1074+ 			const  BILLIONISH :  f64  = 1024.0  *  1024.0  *  1024.0 ; 
1075+ 			let  numerator = ( num *  BILLIONISH )  as  u64  + 1 ; 
1076+ 			let  denominator = ( den *  BILLIONISH )  as  u64  + 1 ; 
1077+ 			debug_assert ! ( numerator <= 1  << 30 ,  "Got large numerator ({}) from float {}." ,  numerator,  num) ; 
1078+ 			debug_assert ! ( denominator <= 1  << 30 ,  "Got large denominator ({}) from float {}." ,  denominator,  den) ; 
1079+ 			( numerator,  denominator) 
1080+ 		} ; 
1081+ 
10201082	if  min_zero_implies_no_successes && min_liquidity_msat == 0  &&
10211083		denominator < u64:: max_value ( )  / 21 
10221084	{ 
@@ -2964,47 +3026,47 @@ mod tests {
29643026			inflight_htlc_msat :  0 , 
29653027			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  950_000_000 ,  htlc_maximum_msat :  1_000  } , 
29663028		} ; 
2967- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  6262 ) ; 
3029+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  11497 ) ; 
29683030		let  usage = ChannelUsage  { 
29693031			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  1_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29703032		} ; 
2971- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4634 ) ; 
3033+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  7408 ) ; 
29723034		let  usage = ChannelUsage  { 
29733035			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  2_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29743036		} ; 
2975- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4186 ) ; 
3037+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  6151 ) ; 
29763038		let  usage = ChannelUsage  { 
29773039			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  3_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29783040		} ; 
2979- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3909 ) ; 
3041+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  5427 ) ; 
29803042		let  usage = ChannelUsage  { 
29813043			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  4_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29823044		} ; 
2983- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3556 ) ; 
3045+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4955 ) ; 
29843046		let  usage = ChannelUsage  { 
29853047			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  5_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29863048		} ; 
2987- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3533 ) ; 
3049+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4736 ) ; 
29883050		let  usage = ChannelUsage  { 
29893051			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  6_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29903052		} ; 
2991- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3172 ) ; 
3053+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4484 ) ; 
29923054		let  usage = ChannelUsage  { 
29933055			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  7_450_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29943056		} ; 
2995- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3211 ) ; 
3057+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4484 ) ; 
29963058		let  usage = ChannelUsage  { 
29973059			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  7_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29983060		} ; 
2999- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3243 ) ; 
3061+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4263 ) ; 
30003062		let  usage = ChannelUsage  { 
30013063			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  8_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30023064		} ; 
3003- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3297 ) ; 
3065+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4263 ) ; 
30043066		let  usage = ChannelUsage  { 
30053067			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  9_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30063068		} ; 
3007- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3250 ) ; 
3069+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4044 ) ; 
30083070	} 
30093071
30103072	#[ test]  
0 commit comments