Skip to content

Commit ed6034f

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 33eaf98 commit ed6034f

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
@@ -392,6 +392,25 @@ 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 all other penalties, including the
400+
/// [`liquidity_penalty_multiplier_msat`] and [`amount_penalty_multiplier_msat`]-based
401+
/// penalties, as well as the [`base_penalty_msat`] and the [`anti_probing_penalty_msat`], if
402+
/// applicable, are still included in the overall penalty.
403+
///
404+
/// If you wish to avoid creating paths with such channels entirely, setting this to a value of
405+
/// `u64::max_value()` will guarantee that.
406+
///
407+
/// Default value: `u64::max_value()`
408+
///
409+
/// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat
410+
/// [`amount_penalty_multiplier_msat`]: Self::amount_penalty_multiplier_msat
411+
/// [`base_penalty_msat`]: Self::base_penalty_msat
412+
/// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat
413+
pub considered_impossible_penalty_msat: u64,
395414
}
396415

397416
/// Accounting for channel liquidity balance uncertainty.
@@ -510,6 +529,7 @@ impl ProbabilisticScoringParameters {
510529
amount_penalty_multiplier_msat: 0,
511530
banned_nodes: HashSet::new(),
512531
anti_probing_penalty_msat: 0,
532+
considered_impossible_penalty_msat: 0,
513533
}
514534
}
515535

@@ -531,6 +551,7 @@ impl Default for ProbabilisticScoringParameters {
531551
amount_penalty_multiplier_msat: 256,
532552
banned_nodes: HashSet::new(),
533553
anti_probing_penalty_msat: 250,
554+
considered_impossible_penalty_msat: u64::max_value(),
534555
}
535556
}
536557
}
@@ -608,17 +629,12 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
608629
if amount_msat <= min_liquidity_msat {
609630
0
610631
} 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-
}
632+
// Equivalent to hitting the else clause below with the amount equal to the effective
633+
// capacity and without any certainty on the liquidity upper bound, plus the
634+
// impossibility penalty.
635+
let negative_log10_times_2048 = NEGATIVE_LOG10_UPPER_BOUND * 2048;
636+
self.combined_penalty_msat(amount_msat, negative_log10_times_2048, params)
637+
.saturating_add(params.considered_impossible_penalty_msat)
622638
} else {
623639
let numerator = (max_liquidity_msat - amount_msat).saturating_add(1);
624640
let denominator = (max_liquidity_msat - min_liquidity_msat).saturating_add(1);
@@ -1600,7 +1616,7 @@ mod tests {
16001616
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
16011617
let usage = ChannelUsage { amount_msat: 102_400, ..usage };
16021618
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 47);
1603-
let usage = ChannelUsage { amount_msat: 1_024_000, ..usage };
1619+
let usage = ChannelUsage { amount_msat: 1_023_999, ..usage };
16041620
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
16051621

16061622
let usage = ChannelUsage {
@@ -1630,6 +1646,7 @@ mod tests {
16301646
let network_graph = network_graph(&logger);
16311647
let params = ProbabilisticScoringParameters {
16321648
liquidity_penalty_multiplier_msat: 1_000,
1649+
considered_impossible_penalty_msat: u64::max_value(),
16331650
..ProbabilisticScoringParameters::zero_penalty()
16341651
};
16351652
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger)
@@ -1721,6 +1738,7 @@ mod tests {
17211738
let network_graph = network_graph(&logger);
17221739
let params = ProbabilisticScoringParameters {
17231740
liquidity_penalty_multiplier_msat: 1_000,
1741+
considered_impossible_penalty_msat: u64::max_value(),
17241742
..ProbabilisticScoringParameters::zero_penalty()
17251743
};
17261744
let mut scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
@@ -1787,6 +1805,7 @@ mod tests {
17871805
let params = ProbabilisticScoringParameters {
17881806
liquidity_penalty_multiplier_msat: 1_000,
17891807
liquidity_offset_half_life: Duration::from_secs(10),
1808+
considered_impossible_penalty_msat: u64::max_value(),
17901809
..ProbabilisticScoringParameters::zero_penalty()
17911810
};
17921811
let mut scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
@@ -1796,10 +1815,10 @@ mod tests {
17961815
let usage = ChannelUsage {
17971816
amount_msat: 0,
17981817
inflight_htlc_msat: 0,
1799-
effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: Some(1_000) },
1818+
effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: Some(1_024) },
18001819
};
18011820
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
1802-
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1821+
let usage = ChannelUsage { amount_msat: 1_023, ..usage };
18031822
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
18041823

18051824
scorer.payment_path_failed(&payment_path_for_amount(768).iter().collect::<Vec<_>>(), 42);
@@ -1843,20 +1862,20 @@ mod tests {
18431862
let usage = ChannelUsage { amount_msat: 1_023, ..usage };
18441863
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
18451864
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1846-
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
1865+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), u64::max_value());
18471866

18481867
// Fully decay liquidity upper bound.
18491868
SinceEpoch::advance(Duration::from_secs(10));
18501869
let usage = ChannelUsage { amount_msat: 0, ..usage };
18511870
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
18521871
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1853-
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
1872+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), u64::max_value());
18541873

18551874
SinceEpoch::advance(Duration::from_secs(10));
18561875
let usage = ChannelUsage { amount_msat: 0, ..usage };
18571876
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
18581877
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1859-
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
1878+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), u64::max_value());
18601879
}
18611880

18621881
#[test]
@@ -1941,6 +1960,7 @@ mod tests {
19411960
let params = ProbabilisticScoringParameters {
19421961
liquidity_penalty_multiplier_msat: 1_000,
19431962
liquidity_offset_half_life: Duration::from_secs(10),
1963+
considered_impossible_penalty_msat: u64::max_value(),
19441964
..ProbabilisticScoringParameters::zero_penalty()
19451965
};
19461966
let mut scorer = ProbabilisticScorer::new(params.clone(), &network_graph, &logger);
@@ -1977,6 +1997,7 @@ mod tests {
19771997
let params = ProbabilisticScoringParameters {
19781998
liquidity_penalty_multiplier_msat: 1_000,
19791999
liquidity_offset_half_life: Duration::from_secs(10),
2000+
considered_impossible_penalty_msat: u64::max_value(),
19802001
..ProbabilisticScoringParameters::zero_penalty()
19812002
};
19822003
let mut scorer = ProbabilisticScorer::new(params.clone(), &network_graph, &logger);

0 commit comments

Comments
 (0)