Skip to content

Commit ec2b1ce

Browse files
committed
Make the ProbabilisticScorer impossibility penalty configurable
When we consider sending an HTLC over a given channel impossible due to our current knowledge of the channel's liquidity, we currently always assign a penalty of `u64::max_value()`. However, because we now refuse to retry a payment along the same path in the router itself, we can now make this value configurable. This allows users to have a relatively high knowledge decay interval without the side-effect of refusing to try the only available path in cases where a channel is intermittently available.
1 parent 93e645d commit ec2b1ce

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed

lightning/src/routing/scoring.rs

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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: `u64::max_value()`
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: u64::max_value(),
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);

0 commit comments

Comments
 (0)