@@ -579,6 +579,28 @@ pub struct ProbabilisticScoringFeeParameters {
579579/// [`base_penalty_msat`]: Self::base_penalty_msat 
580580/// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat 
581581pub  considered_impossible_penalty_msat :  u64 , 
582+ 
583+ 	/// In order to calculate most of the scores above, we must first convert a lower and upper 
584+ /// bound on the available liquidity in a channel into the probability that we think a payment 
585+ /// will succeed. That probability is derived from a Probability Density Function for where we 
586+ /// think the liquidity in a channel likely lies, given such bounds. 
587+ /// 
588+ /// If this flag is set, that PDF is simply a constant - we assume that the actual available 
589+ /// liquidity in a channel is just as likely to be at any point between our lower and upper 
590+ /// bounds. 
591+ /// 
592+ /// If this flag is *not* set, that PDF is `(x - 0.5*capacity) ^ 2`. That is, we use an 
593+ /// exponential curve which expects the liquidity of a channel to lie "at the edges". This 
594+ /// matches experimental results - most routing nodes do not aggressively rebalance their 
595+ /// channels and flows in the network are often unbalanced, leaving liquidity usually 
596+ /// unavailable. 
597+ /// 
598+ /// Thus, for the "best" routes, leave this flag `false`. However, the flag does imply a number 
599+ /// of floating-point multiplications in the hottest routing code, which may lead to routing 
600+ /// performance degradation on some machines. 
601+ /// 
602+ /// Default value: false 
603+ pub  linear_success_probability :  bool , 
582604} 
583605
584606impl  Default  for  ProbabilisticScoringFeeParameters  { 
@@ -593,6 +615,7 @@ impl Default for ProbabilisticScoringFeeParameters {
593615			considered_impossible_penalty_msat :  1_0000_0000_000 , 
594616			historical_liquidity_penalty_multiplier_msat :  10_000 , 
595617			historical_liquidity_penalty_amount_multiplier_msat :  64 , 
618+ 			linear_success_probability :  false , 
596619		} 
597620	} 
598621} 
@@ -646,6 +669,7 @@ impl ProbabilisticScoringFeeParameters {
646669			manual_node_penalties :  HashMap :: new ( ) , 
647670			anti_probing_penalty_msat :  0 , 
648671			considered_impossible_penalty_msat :  0 , 
672+ 			linear_success_probability :  true , 
649673		} 
650674	} 
651675} 
@@ -998,6 +1022,12 @@ const PRECISION_LOWER_BOUND_DENOMINATOR: u64 = approx::LOWER_BITS_BOUND;
9981022const  AMOUNT_PENALTY_DIVISOR :  u64  = 1  << 20 ; 
9991023const  BASE_AMOUNT_PENALTY_DIVISOR :  u64  = 1  << 30 ; 
10001024
1025+ /// Raises three `f64`s to the 3rd power, without `powi` because it requires `std` (dunno why). 
1026+ #[ inline( always) ]  
1027+ fn  three_f64_pow_3 ( a :  f64 ,  b :  f64 ,  c :  f64 )  -> ( f64 ,  f64 ,  f64 )  { 
1028+ 	( a *  a *  a,  b *  b *  b,  c *  c *  c) 
1029+ } 
1030+ 
10011031/// Given liquidity bounds, calculates the success probability (in the form of a numerator and 
10021032/// denominator) of an HTLC. This is a key assumption in our scoring models. 
10031033/// 
@@ -1008,14 +1038,46 @@ const BASE_AMOUNT_PENALTY_DIVISOR: u64 = 1 << 30;
10081038#[ inline( always) ]  
10091039fn  success_probability ( 
10101040	amount_msat :  u64 ,  min_liquidity_msat :  u64 ,  max_liquidity_msat :  u64 ,  capacity_msat :  u64 , 
1011- 	_params :  & ProbabilisticScoringFeeParameters ,  min_zero_implies_no_successes :  bool , 
1041+ 	params :  & ProbabilisticScoringFeeParameters ,  min_zero_implies_no_successes :  bool , 
10121042)  -> ( u64 ,  u64 )  { 
10131043	debug_assert ! ( min_liquidity_msat <= amount_msat) ; 
10141044	debug_assert ! ( amount_msat < max_liquidity_msat) ; 
10151045	debug_assert ! ( max_liquidity_msat <= capacity_msat) ; 
10161046
1017- 	let  numerator = max_liquidity_msat - amount_msat; 
1018- 	let  mut  denominator = ( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ; 
1047+ 	let  ( numerator,  mut  denominator)  =
1048+ 		if  params. linear_success_probability  { 
1049+ 			( max_liquidity_msat - amount_msat, 
1050+ 				( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ) 
1051+ 		}  else  { 
1052+ 			let  capacity = capacity_msat as  f64 ; 
1053+ 			let  min = ( min_liquidity_msat as  f64 )  / capacity; 
1054+ 			let  max = ( max_liquidity_msat as  f64 )  / capacity; 
1055+ 			let  amount = ( amount_msat as  f64 )  / capacity; 
1056+ 
1057+ 			// Assume the channel has a probability density function of (x - 0.5)^2 for values from 
1058+ 			// 0 to 1 (where 1 is the channel's full capacity). The success probability given some 
1059+ 			// liquidity bounds is thus the integral under the curve from the amount to maximum 
1060+ 			// estimated liquidity, divided by the same integral from the minimum to the maximum 
1061+ 			// estimated liquidity bounds. 
1062+ 			// 
1063+ 			// Because the integral from x to y is simply (y - 0.5)^3 - (x - 0.5)^3, we can 
1064+ 			// calculate the cumulative density function between the min/max bounds trivially. Note 
1065+ 			// that we don't bother to normalize the CDF to total to 1, as it will come out in the 
1066+ 			// division of num / den. 
1067+ 			let  ( max_pow,  amt_pow,  min_pow)  = three_f64_pow_3 ( max - 0.5 ,  amount - 0.5 ,  min - 0.5 ) ; 
1068+ 			let  num = max_pow - amt_pow; 
1069+ 			let  den = max_pow - min_pow; 
1070+ 
1071+ 			// Because our numerator and denominator max out at 0.5^3 we need to multiply them by 
1072+ 			// quite a large factor to get something useful (ideally in the 2^30 range). 
1073+ 			const  BILLIONISH :  f64  = 1024.0  *  1024.0  *  1024.0 ; 
1074+ 			let  numerator = ( num *  BILLIONISH )  as  u64  + 1 ; 
1075+ 			let  denominator = ( den *  BILLIONISH )  as  u64  + 1 ; 
1076+ 			debug_assert ! ( numerator <= 1  << 30 ,  "Got large numerator ({}) from float {}." ,  numerator,  num) ; 
1077+ 			debug_assert ! ( denominator <= 1  << 30 ,  "Got large denominator ({}) from float {}." ,  denominator,  den) ; 
1078+ 			( numerator,  denominator) 
1079+ 		} ; 
1080+ 
10191081	if  min_zero_implies_no_successes && min_liquidity_msat == 0  &&
10201082		denominator < u64:: max_value ( )  / 21 
10211083	{ 
@@ -2963,47 +3025,47 @@ mod tests {
29633025			inflight_htlc_msat :  0 , 
29643026			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  950_000_000 ,  htlc_maximum_msat :  1_000  } , 
29653027		} ; 
2966- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  6262 ) ; 
3028+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  11497 ) ; 
29673029		let  usage = ChannelUsage  { 
29683030			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  1_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29693031		} ; 
2970- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4634 ) ; 
3032+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  7408 ) ; 
29713033		let  usage = ChannelUsage  { 
29723034			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  2_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29733035		} ; 
2974- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4186 ) ; 
3036+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  6151 ) ; 
29753037		let  usage = ChannelUsage  { 
29763038			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  3_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29773039		} ; 
2978- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3909 ) ; 
3040+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  5427 ) ; 
29793041		let  usage = ChannelUsage  { 
29803042			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  4_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29813043		} ; 
2982- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3556 ) ; 
3044+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4955 ) ; 
29833045		let  usage = ChannelUsage  { 
29843046			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  5_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29853047		} ; 
2986- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3533 ) ; 
3048+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4736 ) ; 
29873049		let  usage = ChannelUsage  { 
29883050			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  6_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29893051		} ; 
2990- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3172 ) ; 
3052+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4484 ) ; 
29913053		let  usage = ChannelUsage  { 
29923054			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  7_450_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29933055		} ; 
2994- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3211 ) ; 
3056+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4484 ) ; 
29953057		let  usage = ChannelUsage  { 
29963058			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  7_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
29973059		} ; 
2998- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3243 ) ; 
3060+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4263 ) ; 
29993061		let  usage = ChannelUsage  { 
30003062			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  8_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30013063		} ; 
3002- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3297 ) ; 
3064+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4263 ) ; 
30033065		let  usage = ChannelUsage  { 
30043066			effective_capacity :  EffectiveCapacity :: Total  {  capacity_msat :  9_950_000_000 ,  htlc_maximum_msat :  1_000  } ,  ..usage
30053067		} ; 
3006- 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  3250 ) ; 
3068+ 		assert_eq ! ( scorer. channel_penalty_msat( 42 ,  & source,  & target,  usage,  & params) ,  4044 ) ; 
30073069	} 
30083070
30093071	#[ test]  
0 commit comments