Skip to content

Commit 9d8ba85

Browse files
committed
Add a base penalty to ProbabilisticScorer
ProbabilisticScorer tends to prefer longer routes to shorter ones. Make the default scoring behavior include a customizable base penalty to avoid longer routes.
1 parent 9402554 commit 9d8ba85

File tree

1 file changed

+47
-15
lines changed

1 file changed

+47
-15
lines changed

lightning/src/routing/scoring.rs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -516,27 +516,32 @@ pub struct ProbabilisticScorerUsingTime<G: Deref<Target = NetworkGraph>, T: Time
516516
}
517517

518518
/// Parameters for configuring [`ProbabilisticScorer`].
519+
///
520+
/// Used to configure a base penalty and a liquidity penalty, the sum of which is the channel
521+
/// penalty (i.e., the amount in msats willing to be paid to avoid routing through the channel).
519522
#[derive(Clone, Copy)]
520523
pub struct ProbabilisticScoringParameters {
521-
/// The function calculating the cost of routing an amount through a channel.
524+
/// A fixed penalty in msats to apply to each channel.
522525
///
523-
/// The cost is multiplied by [`liquidity_penalty_multiplier_msat`] to determine the channel
524-
/// penalty (i.e., the amount msats willing to be paid to avoid routing through the channel).
525-
/// Penalties are limited to `2 * liquidity_penalty_multiplier_msat`.
526+
/// Default value: 500 msat
527+
pub base_penalty_msat: u64,
528+
529+
/// The function calculating the cost of routing an amount through a channel.
526530
///
527-
/// The cost is based in part by the knowledge learned from prior successful and unsuccessful
528-
/// payments. This knowledge is decayed over time based on [`liquidity_offset_half_life`].
531+
/// The cost is multiplied by [`liquidity_penalty_multiplier_msat`] to determine the liquidity
532+
/// penalty, which is limited to `2 * liquidity_penalty_multiplier_msat`. The cost is based in
533+
/// part by the knowledge learned from prior successful and unsuccessful payments. This
534+
/// knowledge is decayed over time based on [`liquidity_offset_half_life`].
529535
///
530536
/// Default value: [`ProbabilisticScoringCostFunction::NegativeLogSuccessProbability`]
531537
///
532538
/// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat
533539
/// [`liquidity_offset_half_life`]: Self::liquidity_offset_half_life
534540
pub cost_function: ProbabilisticScoringCostFunction,
535541

536-
/// A multiplier used in conjunction with [`cost_function`] to determine the channel penalty.
542+
/// A multiplier used in conjunction with [`cost_function`] to determine the liquidity penalty.
537543
///
538-
/// The channel penalty is the amount in msats willing to be paid to avoid routing through a
539-
/// channel. It is effectively limited to `2 * liquidity_penalty_multiplier_msat`.
544+
/// The liquidity penalty is effectively limited to `2 * liquidity_penalty_multiplier_msat`.
540545
///
541546
/// Default value: 10,000 msat
542547
///
@@ -630,6 +635,7 @@ impl<G: Deref<Target = NetworkGraph>, T: Time> ProbabilisticScorerUsingTime<G, T
630635
impl Default for ProbabilisticScoringParameters {
631636
fn default() -> Self {
632637
Self {
638+
base_penalty_msat: 500,
633639
cost_function: ProbabilisticScoringCostFunction::NegativeLogSuccessProbability,
634640
liquidity_penalty_multiplier_msat: 10_000,
635641
liquidity_offset_half_life: Duration::from_secs(3600),
@@ -795,6 +801,7 @@ impl<G: Deref<Target = NetworkGraph>, T: Time> Score for ProbabilisticScorerUsin
795801
.unwrap_or(&ChannelLiquidity::new())
796802
.as_directed(source, target, capacity_msat, self.params.liquidity_offset_half_life)
797803
.penalty_msat(amount_msat, &self.params)
804+
.saturating_add(self.params.base_penalty_msat)
798805
}
799806

800807
fn payment_path_failed(&mut self, path: &[&RouteHop], short_channel_id: u64) {
@@ -1772,7 +1779,7 @@ mod tests {
17721779
fn increased_penalty_nearing_liquidity_upper_bound() {
17731780
let network_graph = network_graph();
17741781
let params = ProbabilisticScoringParameters {
1775-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1782+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
17761783
};
17771784
let scorer = ProbabilisticScorer::new(params, &network_graph);
17781785
let source = source_node_id();
@@ -1796,6 +1803,7 @@ mod tests {
17961803
fn increased_penalty_linearly_nearing_liquidity_upper_bound() {
17971804
let network_graph = network_graph();
17981805
let params = ProbabilisticScoringParameters {
1806+
base_penalty_msat: 0,
17991807
cost_function: ProbabilisticScoringCostFunction::TwiceFailureProbability,
18001808
liquidity_penalty_multiplier_msat: 1_000,
18011809
..Default::default()
@@ -1823,7 +1831,7 @@ mod tests {
18231831
let last_updated = SinceEpoch::now();
18241832
let network_graph = network_graph();
18251833
let params = ProbabilisticScoringParameters {
1826-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1834+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
18271835
};
18281836
let scorer = ProbabilisticScorer::new(params, &network_graph)
18291837
.with_channel(42,
@@ -1843,7 +1851,7 @@ mod tests {
18431851
fn does_not_further_penalize_own_channel() {
18441852
let network_graph = network_graph();
18451853
let params = ProbabilisticScoringParameters {
1846-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1854+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
18471855
};
18481856
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
18491857
let sender = sender_node_id();
@@ -1864,7 +1872,7 @@ mod tests {
18641872
fn sets_liquidity_lower_bound_on_downstream_failure() {
18651873
let network_graph = network_graph();
18661874
let params = ProbabilisticScoringParameters {
1867-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1875+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
18681876
};
18691877
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
18701878
let source = source_node_id();
@@ -1886,7 +1894,7 @@ mod tests {
18861894
fn sets_liquidity_upper_bound_on_failure() {
18871895
let network_graph = network_graph();
18881896
let params = ProbabilisticScoringParameters {
1889-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1897+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
18901898
};
18911899
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
18921900
let source = source_node_id();
@@ -1908,7 +1916,7 @@ mod tests {
19081916
fn reduces_liquidity_upper_bound_along_path_on_success() {
19091917
let network_graph = network_graph();
19101918
let params = ProbabilisticScoringParameters {
1911-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1919+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
19121920
};
19131921
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
19141922
let sender = sender_node_id();
@@ -1932,6 +1940,7 @@ mod tests {
19321940
fn decays_liquidity_bounds_over_time() {
19331941
let network_graph = network_graph();
19341942
let params = ProbabilisticScoringParameters {
1943+
base_penalty_msat: 0,
19351944
liquidity_penalty_multiplier_msat: 1_000,
19361945
liquidity_offset_half_life: Duration::from_secs(10),
19371946
..Default::default()
@@ -1984,6 +1993,7 @@ mod tests {
19841993
fn decays_liquidity_bounds_without_shift_overflow() {
19851994
let network_graph = network_graph();
19861995
let params = ProbabilisticScoringParameters {
1996+
base_penalty_msat: 0,
19871997
liquidity_penalty_multiplier_msat: 1_000,
19881998
liquidity_offset_half_life: Duration::from_secs(10),
19891999
..Default::default()
@@ -2009,6 +2019,7 @@ mod tests {
20092019
fn restricts_liquidity_bounds_after_decay() {
20102020
let network_graph = network_graph();
20112021
let params = ProbabilisticScoringParameters {
2022+
base_penalty_msat: 0,
20122023
liquidity_penalty_multiplier_msat: 1_000,
20132024
liquidity_offset_half_life: Duration::from_secs(10),
20142025
..Default::default()
@@ -2047,6 +2058,7 @@ mod tests {
20472058
fn restores_persisted_liquidity_bounds() {
20482059
let network_graph = network_graph();
20492060
let params = ProbabilisticScoringParameters {
2061+
base_penalty_msat: 0,
20502062
liquidity_penalty_multiplier_msat: 1_000,
20512063
liquidity_offset_half_life: Duration::from_secs(10),
20522064
..Default::default()
@@ -2077,6 +2089,7 @@ mod tests {
20772089
fn decays_persisted_liquidity_bounds() {
20782090
let network_graph = network_graph();
20792091
let params = ProbabilisticScoringParameters {
2092+
base_penalty_msat: 0,
20802093
liquidity_penalty_multiplier_msat: 1_000,
20812094
liquidity_offset_half_life: Duration::from_secs(10),
20822095
..Default::default()
@@ -2104,4 +2117,23 @@ mod tests {
21042117
SinceEpoch::advance(Duration::from_secs(10));
21052118
assert_eq!(deserialized_scorer.channel_penalty_msat(42, 500, 1_000, &source, &target), 371);
21062119
}
2120+
2121+
#[test]
2122+
fn adds_base_penalty_to_liquidity_penalty() {
2123+
let network_graph = network_graph();
2124+
let source = source_node_id();
2125+
let target = target_node_id();
2126+
2127+
let params = ProbabilisticScoringParameters {
2128+
base_penalty_msat: 0, ..Default::default()
2129+
};
2130+
let scorer = ProbabilisticScorer::new(params, &network_graph);
2131+
assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 585);
2132+
2133+
let params = ProbabilisticScoringParameters {
2134+
base_penalty_msat: 500, ..Default::default()
2135+
};
2136+
let scorer = ProbabilisticScorer::new(params, &network_graph);
2137+
assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 1085);
2138+
}
21072139
}

0 commit comments

Comments
 (0)