@@ -392,6 +392,22 @@ pub struct ProbabilisticScoringParameters {
392392 ///
393393 /// Default value: 250 msat
394394 pub anti_probing_penalty_msat : u64 ,
395+
396+ /// This penalty is applied when the amount we're attempting to send over a channel exceeds our
397+ /// current estimate of the channel's available liquidity.
398+ ///
399+ /// Note that in this case the [`liquidity_penalty_multiplier_msat`] and
400+ /// [`amount_penalty_multiplier_msat`]-based penalties are still included in the overall
401+ /// penalty.
402+ ///
403+ /// If you wish to avoid creating paths with such channels entirely, setting this to a value of
404+ /// `u64::max_value()` will guarantee that.
405+ ///
406+ /// Default value: `u64::max_value()`
407+ ///
408+ /// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat
409+ /// [`amount_penalty_multiplier_msat`]: Self::amount_penalty_multiplier_msat
410+ pub considered_impossible_penalty_msat : u64 ,
395411}
396412
397413/// Accounting for channel liquidity balance uncertainty.
@@ -510,6 +526,7 @@ impl ProbabilisticScoringParameters {
510526 amount_penalty_multiplier_msat : 0 ,
511527 banned_nodes : HashSet :: new ( ) ,
512528 anti_probing_penalty_msat : 0 ,
529+ considered_impossible_penalty_msat : 0 ,
513530 }
514531 }
515532
@@ -531,6 +548,7 @@ impl Default for ProbabilisticScoringParameters {
531548 amount_penalty_multiplier_msat : 256 ,
532549 banned_nodes : HashSet :: new ( ) ,
533550 anti_probing_penalty_msat : 250 ,
551+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
534552 }
535553 }
536554}
@@ -608,17 +626,12 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
608626 if amount_msat <= min_liquidity_msat {
609627 0
610628 } else if amount_msat >= max_liquidity_msat {
611- if amount_msat > max_liquidity_msat {
612- u64:: max_value ( )
613- } else if max_liquidity_msat != self . capacity_msat {
614- // Avoid using the failed channel on retry.
615- u64:: max_value ( )
616- } else {
617- // Equivalent to hitting the else clause below with the amount equal to the
618- // effective capacity and without any certainty on the liquidity upper bound.
619- let negative_log10_times_2048 = NEGATIVE_LOG10_UPPER_BOUND * 2048 ;
620- self . combined_penalty_msat ( amount_msat, negative_log10_times_2048, params)
621- }
629+ // Equivalent to hitting the else clause below with the amount equal to the effective
630+ // capacity and without any certainty on the liquidity upper bound, plus the
631+ // impossibility penalty.
632+ let negative_log10_times_2048 = NEGATIVE_LOG10_UPPER_BOUND * 2048 ;
633+ self . combined_penalty_msat ( amount_msat, negative_log10_times_2048, params)
634+ . saturating_add ( params. considered_impossible_penalty_msat )
622635 } else {
623636 let numerator = ( max_liquidity_msat - amount_msat) . saturating_add ( 1 ) ;
624637 let denominator = ( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ;
@@ -1600,7 +1613,7 @@ mod tests {
16001613 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
16011614 let usage = ChannelUsage { amount_msat : 102_400 , ..usage } ;
16021615 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 47 ) ;
1603- let usage = ChannelUsage { amount_msat : 1_024_000 , ..usage } ;
1616+ let usage = ChannelUsage { amount_msat : 1_023_999 , ..usage } ;
16041617 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
16051618
16061619 let usage = ChannelUsage {
@@ -1630,6 +1643,7 @@ mod tests {
16301643 let network_graph = network_graph ( & logger) ;
16311644 let params = ProbabilisticScoringParameters {
16321645 liquidity_penalty_multiplier_msat : 1_000 ,
1646+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
16331647 ..ProbabilisticScoringParameters :: zero_penalty ( )
16341648 } ;
16351649 let scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger)
@@ -1721,6 +1735,7 @@ mod tests {
17211735 let network_graph = network_graph ( & logger) ;
17221736 let params = ProbabilisticScoringParameters {
17231737 liquidity_penalty_multiplier_msat : 1_000 ,
1738+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
17241739 ..ProbabilisticScoringParameters :: zero_penalty ( )
17251740 } ;
17261741 let mut scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
@@ -1787,6 +1802,7 @@ mod tests {
17871802 let params = ProbabilisticScoringParameters {
17881803 liquidity_penalty_multiplier_msat : 1_000 ,
17891804 liquidity_offset_half_life : Duration :: from_secs ( 10 ) ,
1805+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
17901806 ..ProbabilisticScoringParameters :: zero_penalty ( )
17911807 } ;
17921808 let mut scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
@@ -1796,10 +1812,10 @@ mod tests {
17961812 let usage = ChannelUsage {
17971813 amount_msat : 0 ,
17981814 inflight_htlc_msat : 0 ,
1799- effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_024 , htlc_maximum_msat : Some ( 1_000 ) } ,
1815+ effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_024 , htlc_maximum_msat : Some ( 1_024 ) } ,
18001816 } ;
18011817 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
1802- let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1818+ let usage = ChannelUsage { amount_msat : 1_023 , ..usage } ;
18031819 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
18041820
18051821 scorer. payment_path_failed ( & payment_path_for_amount ( 768 ) . iter ( ) . collect :: < Vec < _ > > ( ) , 42 ) ;
@@ -1843,20 +1859,20 @@ mod tests {
18431859 let usage = ChannelUsage { amount_msat : 1_023 , ..usage } ;
18441860 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
18451861 let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1846- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
1862+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value ( ) ) ;
18471863
18481864 // Fully decay liquidity upper bound.
18491865 SinceEpoch :: advance ( Duration :: from_secs ( 10 ) ) ;
18501866 let usage = ChannelUsage { amount_msat : 0 , ..usage } ;
18511867 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
18521868 let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1853- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
1869+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value ( ) ) ;
18541870
18551871 SinceEpoch :: advance ( Duration :: from_secs ( 10 ) ) ;
18561872 let usage = ChannelUsage { amount_msat : 0 , ..usage } ;
18571873 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
18581874 let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1859- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
1875+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value ( ) ) ;
18601876 }
18611877
18621878 #[ test]
@@ -1941,6 +1957,7 @@ mod tests {
19411957 let params = ProbabilisticScoringParameters {
19421958 liquidity_penalty_multiplier_msat : 1_000 ,
19431959 liquidity_offset_half_life : Duration :: from_secs ( 10 ) ,
1960+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
19441961 ..ProbabilisticScoringParameters :: zero_penalty ( )
19451962 } ;
19461963 let mut scorer = ProbabilisticScorer :: new ( params. clone ( ) , & network_graph, & logger) ;
@@ -1977,6 +1994,7 @@ mod tests {
19771994 let params = ProbabilisticScoringParameters {
19781995 liquidity_penalty_multiplier_msat : 1_000 ,
19791996 liquidity_offset_half_life : Duration :: from_secs ( 10 ) ,
1997+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
19801998 ..ProbabilisticScoringParameters :: zero_penalty ( )
19811999 } ;
19822000 let mut scorer = ProbabilisticScorer :: new ( params. clone ( ) , & network_graph, & logger) ;
0 commit comments