Skip to content

Commit c8a3cf7

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 f7a080d commit c8a3cf7

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

lightning/src/routing/scoring.rs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,19 @@ 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 liquidity available on a channel.
398+
///
399+
/// Note that in this case the liquidity penalties are still included to ensure such channels
400+
/// which may have enough liquidity are scored worse than channels which we do not believe have
401+
/// enough.
402+
///
403+
/// Note if you wish to avoid creating paths with such channels entirely, a penalty of
404+
/// `u64::max_value()` will guarantee that.
405+
///
406+
/// Default value: `u64::max_value()`
407+
pub considered_impossible_penalty_msat: u64,
395408
}
396409

397410
/// Accounting for channel liquidity balance uncertainty.
@@ -510,6 +523,7 @@ impl ProbabilisticScoringParameters {
510523
amount_penalty_multiplier_msat: 0,
511524
banned_nodes: HashSet::new(),
512525
anti_probing_penalty_msat: 0,
526+
considered_impossible_penalty_msat: 0,
513527
}
514528
}
515529

@@ -531,6 +545,7 @@ impl Default for ProbabilisticScoringParameters {
531545
amount_penalty_multiplier_msat: 256,
532546
banned_nodes: HashSet::new(),
533547
anti_probing_penalty_msat: 250,
548+
considered_impossible_penalty_msat: u64::max_value(),
534549
}
535550
}
536551
}
@@ -608,17 +623,12 @@ impl<L: Deref<Target = u64>, T: Time, U: Deref<Target = T>> DirectedChannelLiqui
608623
if amount_msat <= min_liquidity_msat {
609624
0
610625
} 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-
}
626+
// Equivalent to hitting the else clause below with the amount equal to the effective
627+
// capacity and without any certainty on the liquidity upper bound, plus the
628+
// impossibility penalty.
629+
let negative_log10_times_2048 = NEGATIVE_LOG10_UPPER_BOUND * 2048;
630+
self.combined_penalty_msat(amount_msat, negative_log10_times_2048, params)
631+
.saturating_add(params.considered_impossible_penalty_msat)
622632
} else {
623633
let numerator = (max_liquidity_msat - amount_msat).saturating_add(1);
624634
let denominator = (max_liquidity_msat - min_liquidity_msat).saturating_add(1);
@@ -1600,7 +1610,7 @@ mod tests {
16001610
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
16011611
let usage = ChannelUsage { amount_msat: 102_400, ..usage };
16021612
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 47);
1603-
let usage = ChannelUsage { amount_msat: 1_024_000, ..usage };
1613+
let usage = ChannelUsage { amount_msat: 1_023_999, ..usage };
16041614
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
16051615

16061616
let usage = ChannelUsage {
@@ -1630,6 +1640,7 @@ mod tests {
16301640
let network_graph = network_graph(&logger);
16311641
let params = ProbabilisticScoringParameters {
16321642
liquidity_penalty_multiplier_msat: 1_000,
1643+
considered_impossible_penalty_msat: u64::max_value(),
16331644
..ProbabilisticScoringParameters::zero_penalty()
16341645
};
16351646
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger)
@@ -1721,6 +1732,7 @@ mod tests {
17211732
let network_graph = network_graph(&logger);
17221733
let params = ProbabilisticScoringParameters {
17231734
liquidity_penalty_multiplier_msat: 1_000,
1735+
considered_impossible_penalty_msat: u64::max_value(),
17241736
..ProbabilisticScoringParameters::zero_penalty()
17251737
};
17261738
let mut scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
@@ -1787,6 +1799,7 @@ mod tests {
17871799
let params = ProbabilisticScoringParameters {
17881800
liquidity_penalty_multiplier_msat: 1_000,
17891801
liquidity_offset_half_life: Duration::from_secs(10),
1802+
considered_impossible_penalty_msat: u64::max_value(),
17901803
..ProbabilisticScoringParameters::zero_penalty()
17911804
};
17921805
let mut scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
@@ -1796,10 +1809,10 @@ mod tests {
17961809
let usage = ChannelUsage {
17971810
amount_msat: 0,
17981811
inflight_htlc_msat: 0,
1799-
effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: Some(1_000) },
1812+
effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: Some(1_024) },
18001813
};
18011814
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
1802-
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1815+
let usage = ChannelUsage { amount_msat: 1_023, ..usage };
18031816
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
18041817

18051818
scorer.payment_path_failed(&payment_path_for_amount(768).iter().collect::<Vec<_>>(), 42);
@@ -1843,20 +1856,20 @@ mod tests {
18431856
let usage = ChannelUsage { amount_msat: 1_023, ..usage };
18441857
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
18451858
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1846-
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
1859+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), u64::max_value());
18471860

18481861
// Fully decay liquidity upper bound.
18491862
SinceEpoch::advance(Duration::from_secs(10));
18501863
let usage = ChannelUsage { amount_msat: 0, ..usage };
18511864
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
18521865
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1853-
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 2_000);
1866+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), u64::max_value());
18541867

18551868
SinceEpoch::advance(Duration::from_secs(10));
18561869
let usage = ChannelUsage { amount_msat: 0, ..usage };
18571870
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 0);
18581871
let usage = ChannelUsage { amount_msat: 1_024, ..usage };
1859-
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());
18601873
}
18611874

18621875
#[test]
@@ -1941,6 +1954,7 @@ mod tests {
19411954
let params = ProbabilisticScoringParameters {
19421955
liquidity_penalty_multiplier_msat: 1_000,
19431956
liquidity_offset_half_life: Duration::from_secs(10),
1957+
considered_impossible_penalty_msat: u64::max_value(),
19441958
..ProbabilisticScoringParameters::zero_penalty()
19451959
};
19461960
let mut scorer = ProbabilisticScorer::new(params.clone(), &network_graph, &logger);
@@ -1977,6 +1991,7 @@ mod tests {
19771991
let params = ProbabilisticScoringParameters {
19781992
liquidity_penalty_multiplier_msat: 1_000,
19791993
liquidity_offset_half_life: Duration::from_secs(10),
1994+
considered_impossible_penalty_msat: u64::max_value(),
19801995
..ProbabilisticScoringParameters::zero_penalty()
19811996
};
19821997
let mut scorer = ProbabilisticScorer::new(params.clone(), &network_graph, &logger);
@@ -2136,11 +2151,11 @@ mod tests {
21362151
};
21372152

21382153
let params = ProbabilisticScoringParameters {
2139-
liquidity_penalty_multiplier_msat: 40_000,
2154+
considered_impossible_penalty_msat: 42_420,
21402155
..ProbabilisticScoringParameters::zero_penalty()
21412156
};
21422157
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
2143-
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 80_000);
2158+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage), 42_420);
21442159
}
21452160

21462161
#[test]

0 commit comments

Comments
 (0)