Skip to content

Commit 58e13b8

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 66ca68a commit 58e13b8

File tree

1 file changed

+35
-17
lines changed

1 file changed

+35
-17
lines changed

lightning/src/routing/scoring.rs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)