@@ -394,6 +394,25 @@ pub struct ProbabilisticScoringParameters {
394394 ///
395395 /// Default value: 250 msat
396396 pub anti_probing_penalty_msat : u64 ,
397+
398+ /// This penalty is applied when the amount we're attempting to send over a channel exceeds our
399+ /// current estimate of the channel's available liquidity.
400+ ///
401+ /// Note that in this case all other penalties, including the
402+ /// [`liquidity_penalty_multiplier_msat`] and [`amount_penalty_multiplier_msat`]-based
403+ /// penalties, as well as the [`base_penalty_msat`] and the [`anti_probing_penalty_msat`], if
404+ /// applicable, are still included in the overall penalty.
405+ ///
406+ /// If you wish to avoid creating paths with such channels entirely, setting this to a value of
407+ /// `u64::max_value()` will guarantee that.
408+ ///
409+ /// Default value: 1_0000_0000_000 msat (1 Bitcoin)
410+ ///
411+ /// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat
412+ /// [`amount_penalty_multiplier_msat`]: Self::amount_penalty_multiplier_msat
413+ /// [`base_penalty_msat`]: Self::base_penalty_msat
414+ /// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat
415+ pub considered_impossible_penalty_msat : u64 ,
397416}
398417
399418/// Accounting for channel liquidity balance uncertainty.
@@ -522,6 +541,7 @@ impl ProbabilisticScoringParameters {
522541 amount_penalty_multiplier_msat : 0 ,
523542 manual_node_penalties : HashMap :: new ( ) ,
524543 anti_probing_penalty_msat : 0 ,
544+ considered_impossible_penalty_msat : 0 ,
525545 }
526546 }
527547
@@ -543,6 +563,7 @@ impl Default for ProbabilisticScoringParameters {
543563 amount_penalty_multiplier_msat : 256 ,
544564 manual_node_penalties : HashMap :: new ( ) ,
545565 anti_probing_penalty_msat : 250 ,
566+ considered_impossible_penalty_msat : 1_0000_0000_000 ,
546567 }
547568 }
548569}
@@ -620,17 +641,12 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
620641 if amount_msat <= min_liquidity_msat {
621642 0
622643 } else if amount_msat >= max_liquidity_msat {
623- if amount_msat > max_liquidity_msat {
624- u64:: max_value ( )
625- } else if max_liquidity_msat != self . capacity_msat {
626- // Avoid using the failed channel on retry.
627- u64:: max_value ( )
628- } else {
629- // Equivalent to hitting the else clause below with the amount equal to the
630- // effective capacity and without any certainty on the liquidity upper bound.
631- let negative_log10_times_2048 = NEGATIVE_LOG10_UPPER_BOUND * 2048 ;
632- self . combined_penalty_msat ( amount_msat, negative_log10_times_2048, params)
633- }
644+ // Equivalent to hitting the else clause below with the amount equal to the effective
645+ // capacity and without any certainty on the liquidity upper bound, plus the
646+ // impossibility penalty.
647+ let negative_log10_times_2048 = NEGATIVE_LOG10_UPPER_BOUND * 2048 ;
648+ self . combined_penalty_msat ( amount_msat, negative_log10_times_2048, params)
649+ . saturating_add ( params. considered_impossible_penalty_msat )
634650 } else {
635651 let numerator = ( max_liquidity_msat - amount_msat) . saturating_add ( 1 ) ;
636652 let denominator = ( max_liquidity_msat - min_liquidity_msat) . saturating_add ( 1 ) ;
@@ -1624,7 +1640,7 @@ mod tests {
16241640 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
16251641 let usage = ChannelUsage { amount_msat : 102_400 , ..usage } ;
16261642 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 47 ) ;
1627- let usage = ChannelUsage { amount_msat : 1_024_000 , ..usage } ;
1643+ let usage = ChannelUsage { amount_msat : 1_023_999 , ..usage } ;
16281644 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
16291645
16301646 let usage = ChannelUsage {
@@ -1654,6 +1670,7 @@ mod tests {
16541670 let network_graph = network_graph ( & logger) ;
16551671 let params = ProbabilisticScoringParameters {
16561672 liquidity_penalty_multiplier_msat : 1_000 ,
1673+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
16571674 ..ProbabilisticScoringParameters :: zero_penalty ( )
16581675 } ;
16591676 let scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger)
@@ -1745,6 +1762,7 @@ mod tests {
17451762 let network_graph = network_graph ( & logger) ;
17461763 let params = ProbabilisticScoringParameters {
17471764 liquidity_penalty_multiplier_msat : 1_000 ,
1765+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
17481766 ..ProbabilisticScoringParameters :: zero_penalty ( )
17491767 } ;
17501768 let mut scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
@@ -1811,6 +1829,7 @@ mod tests {
18111829 let params = ProbabilisticScoringParameters {
18121830 liquidity_penalty_multiplier_msat : 1_000 ,
18131831 liquidity_offset_half_life : Duration :: from_secs ( 10 ) ,
1832+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
18141833 ..ProbabilisticScoringParameters :: zero_penalty ( )
18151834 } ;
18161835 let mut scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
@@ -1820,10 +1839,10 @@ mod tests {
18201839 let usage = ChannelUsage {
18211840 amount_msat : 0 ,
18221841 inflight_htlc_msat : 0 ,
1823- effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_024 , htlc_maximum_msat : Some ( 1_000 ) } ,
1842+ effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_024 , htlc_maximum_msat : Some ( 1_024 ) } ,
18241843 } ;
18251844 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
1826- let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1845+ let usage = ChannelUsage { amount_msat : 1_023 , ..usage } ;
18271846 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
18281847
18291848 scorer. payment_path_failed ( & payment_path_for_amount ( 768 ) . iter ( ) . collect :: < Vec < _ > > ( ) , 42 ) ;
@@ -1867,20 +1886,20 @@ mod tests {
18671886 let usage = ChannelUsage { amount_msat : 1_023 , ..usage } ;
18681887 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
18691888 let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1870- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
1889+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value ( ) ) ;
18711890
18721891 // Fully decay liquidity upper bound.
18731892 SinceEpoch :: advance ( Duration :: from_secs ( 10 ) ) ;
18741893 let usage = ChannelUsage { amount_msat : 0 , ..usage } ;
18751894 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
18761895 let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1877- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
1896+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value ( ) ) ;
18781897
18791898 SinceEpoch :: advance ( Duration :: from_secs ( 10 ) ) ;
18801899 let usage = ChannelUsage { amount_msat : 0 , ..usage } ;
18811900 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
18821901 let usage = ChannelUsage { amount_msat : 1_024 , ..usage } ;
1883- assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 2_000 ) ;
1902+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value ( ) ) ;
18841903 }
18851904
18861905 #[ test]
@@ -1965,6 +1984,7 @@ mod tests {
19651984 let params = ProbabilisticScoringParameters {
19661985 liquidity_penalty_multiplier_msat : 1_000 ,
19671986 liquidity_offset_half_life : Duration :: from_secs ( 10 ) ,
1987+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
19681988 ..ProbabilisticScoringParameters :: zero_penalty ( )
19691989 } ;
19701990 let mut scorer = ProbabilisticScorer :: new ( params. clone ( ) , & network_graph, & logger) ;
@@ -2001,6 +2021,7 @@ mod tests {
20012021 let params = ProbabilisticScoringParameters {
20022022 liquidity_penalty_multiplier_msat : 1_000 ,
20032023 liquidity_offset_half_life : Duration :: from_secs ( 10 ) ,
2024+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
20042025 ..ProbabilisticScoringParameters :: zero_penalty ( )
20052026 } ;
20062027 let mut scorer = ProbabilisticScorer :: new ( params. clone ( ) , & network_graph, & logger) ;
@@ -2171,7 +2192,10 @@ mod tests {
21712192 fn accounts_for_inflight_htlc_usage ( ) {
21722193 let logger = TestLogger :: new ( ) ;
21732194 let network_graph = network_graph ( & logger) ;
2174- let params = ProbabilisticScoringParameters :: default ( ) ;
2195+ let params = ProbabilisticScoringParameters {
2196+ considered_impossible_penalty_msat : u64:: max_value ( ) ,
2197+ ..ProbabilisticScoringParameters :: zero_penalty ( )
2198+ } ;
21752199 let scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
21762200 let source = source_node_id ( ) ;
21772201 let target = target_node_id ( ) ;
0 commit comments