@@ -331,6 +331,17 @@ pub struct ProbabilisticScoringParameters {
331
331
/// Default value: 500 msat
332
332
pub base_penalty_msat : u64 ,
333
333
334
+ /// A fixed penalty in msats to apply to each channel, multiplied by the payment amount.
335
+ ///
336
+ /// The purpose of the amount penalty is to avoid having fees dominate the channel cost (i.e.,
337
+ /// fees plus penalty) for large payments. The penalty is computed as the product of this
338
+ /// multiplier and `2^30`ths of the payment amount.
339
+ ///
340
+ /// ie `amount_penalty_multiplier_msat * amount_msat / 2^30`
341
+ ///
342
+ /// Default value: 8,192 msat
343
+ pub base_penalty_amount_multiplier_msat : u64 ,
344
+
334
345
/// A multiplier used in conjunction with the negative `log10` of the channel's success
335
346
/// probability for a payment to determine the liquidity penalty.
336
347
///
@@ -536,6 +547,7 @@ impl ProbabilisticScoringParameters {
536
547
fn zero_penalty ( ) -> Self {
537
548
Self {
538
549
base_penalty_msat : 0 ,
550
+ base_penalty_amount_multiplier_msat : 0 ,
539
551
liquidity_penalty_multiplier_msat : 0 ,
540
552
liquidity_offset_half_life : Duration :: from_secs ( 3600 ) ,
541
553
amount_penalty_multiplier_msat : 0 ,
@@ -558,6 +570,7 @@ impl Default for ProbabilisticScoringParameters {
558
570
fn default ( ) -> Self {
559
571
Self {
560
572
base_penalty_msat : 500 ,
573
+ base_penalty_amount_multiplier_msat : 8192 ,
561
574
liquidity_penalty_multiplier_msat : 40_000 ,
562
575
liquidity_offset_half_life : Duration :: from_secs ( 3600 ) ,
563
576
amount_penalty_multiplier_msat : 256 ,
@@ -631,10 +644,11 @@ const PRECISION_LOWER_BOUND_DENOMINATOR: u64 = approx::LOWER_BITS_BOUND;
631
644
632
645
/// The divisor used when computing the amount penalty.
633
646
const AMOUNT_PENALTY_DIVISOR : u64 = 1 << 20 ;
647
+ const BASE_AMOUNT_PENALTY_DIVISOR : u64 = 1 << 30 ;
634
648
635
649
impl < L : Deref < Target = u64 > , T : Time , U : Deref < Target = T > > DirectedChannelLiquidity < L , T , U > {
636
- /// Returns a penalty for routing the given HTLC `amount_msat` through the channel in this
637
- /// direction.
650
+ /// Returns a liquidity penalty for routing the given HTLC `amount_msat` through the channel in
651
+ /// this direction.
638
652
fn penalty_msat ( & self , amount_msat : u64 , params : & ProbabilisticScoringParameters ) -> u64 {
639
653
let max_liquidity_msat = self . max_liquidity_msat ( ) ;
640
654
let min_liquidity_msat = core:: cmp:: min ( self . min_liquidity_msat ( ) , max_liquidity_msat) ;
@@ -653,8 +667,8 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
653
667
if amount_msat - min_liquidity_msat < denominator / PRECISION_LOWER_BOUND_DENOMINATOR {
654
668
// If the failure probability is < 1.5625% (as 1 - numerator/denominator < 1/64),
655
669
// don't bother trying to use the log approximation as it gets too noisy to be
656
- // particularly helpful, instead just round down to 0 and return the base penalty .
657
- params . base_penalty_msat
670
+ // particularly helpful, instead just round down to 0.
671
+ 0
658
672
} else {
659
673
let negative_log10_times_2048 =
660
674
approx:: negative_log10_times_2048 ( numerator, denominator) ;
@@ -679,9 +693,7 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
679
693
. saturating_mul ( params. amount_penalty_multiplier_msat )
680
694
. saturating_mul ( amount_msat) / 2048 / AMOUNT_PENALTY_DIVISOR ;
681
695
682
- params. base_penalty_msat
683
- . saturating_add ( liquidity_penalty_msat)
684
- . saturating_add ( amount_penalty_msat)
696
+ liquidity_penalty_msat. saturating_add ( amount_penalty_msat)
685
697
}
686
698
687
699
/// Returns the lower bound of the channel liquidity balance in this direction.
@@ -763,13 +775,17 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
763
775
return * penalty;
764
776
}
765
777
778
+ let base_penalty_msat = self . params . base_penalty_msat . saturating_add (
779
+ self . params . base_penalty_amount_multiplier_msat
780
+ . saturating_mul ( usage. amount_msat ) / BASE_AMOUNT_PENALTY_DIVISOR ) ;
781
+
766
782
let mut anti_probing_penalty_msat = 0 ;
767
783
match usage. effective_capacity {
768
784
EffectiveCapacity :: ExactLiquidity { liquidity_msat } => {
769
785
if usage. amount_msat > liquidity_msat {
770
786
return u64:: max_value ( ) ;
771
787
} else {
772
- return self . params . base_penalty_msat ;
788
+ return base_penalty_msat;
773
789
}
774
790
} ,
775
791
EffectiveCapacity :: Total { capacity_msat, htlc_maximum_msat : Some ( htlc_maximum_msat) } => {
@@ -790,6 +806,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
790
806
. as_directed ( source, target, capacity_msat, liquidity_offset_half_life)
791
807
. penalty_msat ( amount_msat, & self . params )
792
808
. saturating_add ( anti_probing_penalty_msat)
809
+ . saturating_add ( base_penalty_msat)
793
810
}
794
811
795
812
fn payment_path_failed ( & mut self , path : & [ & RouteHop ] , short_channel_id : u64 ) {
@@ -2069,47 +2086,47 @@ mod tests {
2069
2086
inflight_htlc_msat : 0 ,
2070
2087
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } ,
2071
2088
} ;
2072
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 3613 ) ;
2089
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 4375 ) ;
2073
2090
let usage = ChannelUsage {
2074
2091
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2075
2092
} ;
2076
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1977 ) ;
2093
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2739 ) ;
2077
2094
let usage = ChannelUsage {
2078
2095
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 2_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2079
2096
} ;
2080
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1474 ) ;
2097
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2236 ) ;
2081
2098
let usage = ChannelUsage {
2082
2099
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 3_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2083
2100
} ;
2084
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1223 ) ;
2101
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1985 ) ;
2085
2102
let usage = ChannelUsage {
2086
2103
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 4_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2087
2104
} ;
2088
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 877 ) ;
2105
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1639 ) ;
2089
2106
let usage = ChannelUsage {
2090
2107
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 5_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2091
2108
} ;
2092
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 845 ) ;
2109
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1607 ) ;
2093
2110
let usage = ChannelUsage {
2094
2111
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 6_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2095
2112
} ;
2096
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2113
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2097
2114
let usage = ChannelUsage {
2098
2115
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 7_450_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2099
2116
} ;
2100
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2117
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2101
2118
let usage = ChannelUsage {
2102
2119
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 7_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2103
2120
} ;
2104
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2121
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2105
2122
let usage = ChannelUsage {
2106
2123
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 8_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2107
2124
} ;
2108
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2125
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2109
2126
let usage = ChannelUsage {
2110
2127
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 9_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2111
2128
} ;
2112
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2129
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2113
2130
}
2114
2131
2115
2132
#[ test]
@@ -2137,6 +2154,15 @@ mod tests {
2137
2154
} ;
2138
2155
let scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
2139
2156
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 558 ) ;
2157
+
2158
+ let params = ProbabilisticScoringParameters {
2159
+ base_penalty_msat : 500 , liquidity_penalty_multiplier_msat : 1_000 ,
2160
+ base_penalty_amount_multiplier_msat : ( 1 <<30 ) ,
2161
+ anti_probing_penalty_msat : 0 , ..Default :: default ( )
2162
+ } ;
2163
+
2164
+ let scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
2165
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 558 + 128 ) ;
2140
2166
}
2141
2167
2142
2168
#[ test]
0 commit comments