@@ -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
///
@@ -517,6 +528,7 @@ impl ProbabilisticScoringParameters {
517
528
fn zero_penalty ( ) -> Self {
518
529
Self {
519
530
base_penalty_msat : 0 ,
531
+ base_penalty_amount_multiplier_msat : 0 ,
520
532
liquidity_penalty_multiplier_msat : 0 ,
521
533
liquidity_offset_half_life : Duration :: from_secs ( 3600 ) ,
522
534
amount_penalty_multiplier_msat : 0 ,
@@ -538,6 +550,7 @@ impl Default for ProbabilisticScoringParameters {
538
550
fn default ( ) -> Self {
539
551
Self {
540
552
base_penalty_msat : 500 ,
553
+ base_penalty_amount_multiplier_msat : 8192 ,
541
554
liquidity_penalty_multiplier_msat : 40_000 ,
542
555
liquidity_offset_half_life : Duration :: from_secs ( 3600 ) ,
543
556
amount_penalty_multiplier_msat : 256 ,
@@ -610,10 +623,11 @@ const PRECISION_LOWER_BOUND_DENOMINATOR: u64 = approx::LOWER_BITS_BOUND;
610
623
611
624
/// The divisor used when computing the amount penalty.
612
625
const AMOUNT_PENALTY_DIVISOR : u64 = 1 << 20 ;
626
+ const BASE_AMOUNT_PENALTY_DIVISOR : u64 = 1 << 30 ;
613
627
614
628
impl < L : Deref < Target = u64 > , T : Time , U : Deref < Target = T > > DirectedChannelLiquidity < L , T , U > {
615
- /// Returns a penalty for routing the given HTLC `amount_msat` through the channel in this
616
- /// direction.
629
+ /// Returns a liquidity penalty for routing the given HTLC `amount_msat` through the channel in
630
+ /// this direction.
617
631
fn penalty_msat ( & self , amount_msat : u64 , params : & ProbabilisticScoringParameters ) -> u64 {
618
632
let max_liquidity_msat = self . max_liquidity_msat ( ) ;
619
633
let min_liquidity_msat = core:: cmp:: min ( self . min_liquidity_msat ( ) , max_liquidity_msat) ;
@@ -637,8 +651,8 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
637
651
if amount_msat - min_liquidity_msat < denominator / PRECISION_LOWER_BOUND_DENOMINATOR {
638
652
// If the failure probability is < 1.5625% (as 1 - numerator/denominator < 1/64),
639
653
// don't bother trying to use the log approximation as it gets too noisy to be
640
- // particularly helpful, instead just round down to 0 and return the base penalty .
641
- params . base_penalty_msat
654
+ // particularly helpful, instead just round down to 0.
655
+ 0
642
656
} else {
643
657
let negative_log10_times_2048 =
644
658
approx:: negative_log10_times_2048 ( numerator, denominator) ;
@@ -663,9 +677,7 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
663
677
. saturating_mul ( params. amount_penalty_multiplier_msat )
664
678
. saturating_mul ( amount_msat) / 2048 / AMOUNT_PENALTY_DIVISOR ;
665
679
666
- params. base_penalty_msat
667
- . saturating_add ( liquidity_penalty_msat)
668
- . saturating_add ( amount_penalty_msat)
680
+ liquidity_penalty_msat. saturating_add ( amount_penalty_msat)
669
681
}
670
682
671
683
/// Returns the lower bound of the channel liquidity balance in this direction.
@@ -747,13 +759,17 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
747
759
return * penalty;
748
760
}
749
761
762
+ let base_penalty_msat = self . params . base_penalty_msat . saturating_add (
763
+ self . params . base_penalty_amount_multiplier_msat
764
+ . saturating_mul ( usage. amount_msat ) / BASE_AMOUNT_PENALTY_DIVISOR ) ;
765
+
750
766
let mut anti_probing_penalty_msat = 0 ;
751
767
match usage. effective_capacity {
752
768
EffectiveCapacity :: ExactLiquidity { liquidity_msat } => {
753
769
if usage. amount_msat > liquidity_msat {
754
770
return u64:: max_value ( ) ;
755
771
} else {
756
- return self . params . base_penalty_msat ;
772
+ return base_penalty_msat;
757
773
}
758
774
} ,
759
775
EffectiveCapacity :: Total { capacity_msat, htlc_maximum_msat : Some ( htlc_maximum_msat) } => {
@@ -774,6 +790,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
774
790
. as_directed ( source, target, capacity_msat, liquidity_offset_half_life)
775
791
. penalty_msat ( amount_msat, & self . params )
776
792
. saturating_add ( anti_probing_penalty_msat)
793
+ . saturating_add ( base_penalty_msat)
777
794
}
778
795
779
796
fn payment_path_failed ( & mut self , path : & [ & RouteHop ] , short_channel_id : u64 ) {
@@ -2048,47 +2065,47 @@ mod tests {
2048
2065
inflight_htlc_msat : 0 ,
2049
2066
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } ,
2050
2067
} ;
2051
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 3613 ) ;
2068
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 4375 ) ;
2052
2069
let usage = ChannelUsage {
2053
2070
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2054
2071
} ;
2055
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1977 ) ;
2072
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2739 ) ;
2056
2073
let usage = ChannelUsage {
2057
2074
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 2_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2058
2075
} ;
2059
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1474 ) ;
2076
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2236 ) ;
2060
2077
let usage = ChannelUsage {
2061
2078
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 3_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2062
2079
} ;
2063
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1223 ) ;
2080
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1985 ) ;
2064
2081
let usage = ChannelUsage {
2065
2082
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 4_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2066
2083
} ;
2067
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 877 ) ;
2084
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1639 ) ;
2068
2085
let usage = ChannelUsage {
2069
2086
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 5_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2070
2087
} ;
2071
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 845 ) ;
2088
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1607 ) ;
2072
2089
let usage = ChannelUsage {
2073
2090
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 6_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2074
2091
} ;
2075
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2092
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2076
2093
let usage = ChannelUsage {
2077
2094
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 7_450_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2078
2095
} ;
2079
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2096
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2080
2097
let usage = ChannelUsage {
2081
2098
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 7_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2082
2099
} ;
2083
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2100
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2084
2101
let usage = ChannelUsage {
2085
2102
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 8_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2086
2103
} ;
2087
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2104
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2088
2105
let usage = ChannelUsage {
2089
2106
effective_capacity : EffectiveCapacity :: Total { capacity_msat : 9_950_000_000 , htlc_maximum_msat : Some ( 1_000 ) } , ..usage
2090
2107
} ;
2091
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 500 ) ;
2108
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 1262 ) ;
2092
2109
}
2093
2110
2094
2111
#[ test]
@@ -2116,6 +2133,15 @@ mod tests {
2116
2133
} ;
2117
2134
let scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
2118
2135
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 558 ) ;
2136
+
2137
+ let params = ProbabilisticScoringParameters {
2138
+ base_penalty_msat : 500 , liquidity_penalty_multiplier_msat : 1_000 ,
2139
+ base_penalty_amount_multiplier_msat : ( 1 <<30 ) ,
2140
+ anti_probing_penalty_msat : 0 , ..Default :: default ( )
2141
+ } ;
2142
+
2143
+ let scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
2144
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 558 + 128 ) ;
2119
2145
}
2120
2146
2121
2147
#[ test]
0 commit comments