Skip to content

Commit 5b36449

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 188f919 commit 5b36449

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

lightning/src/routing/scoring.rs

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -516,17 +516,22 @@ 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-
/// A multiplier used to determine the amount in msats willing to be paid to avoid routing
522-
/// through a channel, as per multiplying by the negative `log10` of the channel's success
523-
/// probability for a payment.
524+
/// A fixed penalty in msats to apply to each channel.
524525
///
525-
/// The success probability is determined by the effective channel capacity, the payment amount,
526-
/// and knowledge learned from prior successful and unsuccessful payments. The lower bound of
527-
/// the success probability is 0.01, effectively limiting the penalty to the range
528-
/// `0..=2*liquidity_penalty_multiplier_msat`. The knowledge learned is decayed over time based
529-
/// on [`liquidity_offset_half_life`].
526+
/// Default value: 500 msat
527+
pub base_penalty_msat: u64,
528+
529+
/// A multiplier used in conjunction with the negative `log10` of the channel's success
530+
/// probability for a payment to determine the liquidity penalty.
531+
///
532+
/// The penalty is based in part by the knowledge learned from prior successful and unsuccessful
533+
/// payments. This knowledge is decayed over time based on [`liquidity_offset_half_life`]. The
534+
/// penalty is effectively limited to `2 * liquidity_penalty_multiplier_msat`.
530535
///
531536
/// Default value: 10,000 msat
532537
///
@@ -549,11 +554,6 @@ pub struct ProbabilisticScoringParameters {
549554
pub liquidity_offset_half_life: Duration,
550555
}
551556

552-
impl_writeable_tlv_based!(ProbabilisticScoringParameters, {
553-
(0, liquidity_penalty_multiplier_msat, required),
554-
(2, liquidity_offset_half_life, required),
555-
});
556-
557557
/// Accounting for channel liquidity balance uncertainty.
558558
///
559559
/// Direction is defined in terms of [`NodeId`] partial ordering, where the source node is the
@@ -602,6 +602,7 @@ impl<G: Deref<Target = NetworkGraph>, T: Time> ProbabilisticScorerUsingTime<G, T
602602
impl Default for ProbabilisticScoringParameters {
603603
fn default() -> Self {
604604
Self {
605+
base_penalty_msat: 500,
605606
liquidity_penalty_multiplier_msat: 10_000,
606607
liquidity_offset_half_life: Duration::from_secs(3600),
607608
}
@@ -757,6 +758,7 @@ impl<G: Deref<Target = NetworkGraph>, T: Time> Score for ProbabilisticScorerUsin
757758
.unwrap_or(&ChannelLiquidity::new())
758759
.as_directed(source, target, capacity_msat, liquidity_offset_half_life)
759760
.penalty_msat(amount_msat, liquidity_penalty_multiplier_msat)
761+
.saturating_add(self.params.base_penalty_msat)
760762
}
761763

762764
fn payment_path_failed(&mut self, path: &[&RouteHop], short_channel_id: u64) {
@@ -1734,7 +1736,7 @@ mod tests {
17341736
fn increased_penalty_nearing_liquidity_upper_bound() {
17351737
let network_graph = network_graph();
17361738
let params = ProbabilisticScoringParameters {
1737-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1739+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
17381740
};
17391741
let scorer = ProbabilisticScorer::new(params, &network_graph);
17401742
let source = source_node_id();
@@ -1759,7 +1761,7 @@ mod tests {
17591761
let last_updated = SinceEpoch::now();
17601762
let network_graph = network_graph();
17611763
let params = ProbabilisticScoringParameters {
1762-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1764+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
17631765
};
17641766
let scorer = ProbabilisticScorer::new(params, &network_graph)
17651767
.with_channel(42,
@@ -1779,7 +1781,7 @@ mod tests {
17791781
fn does_not_further_penalize_own_channel() {
17801782
let network_graph = network_graph();
17811783
let params = ProbabilisticScoringParameters {
1782-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1784+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
17831785
};
17841786
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
17851787
let sender = sender_node_id();
@@ -1800,7 +1802,7 @@ mod tests {
18001802
fn sets_liquidity_lower_bound_on_downstream_failure() {
18011803
let network_graph = network_graph();
18021804
let params = ProbabilisticScoringParameters {
1803-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1805+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
18041806
};
18051807
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
18061808
let source = source_node_id();
@@ -1822,7 +1824,7 @@ mod tests {
18221824
fn sets_liquidity_upper_bound_on_failure() {
18231825
let network_graph = network_graph();
18241826
let params = ProbabilisticScoringParameters {
1825-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1827+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
18261828
};
18271829
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
18281830
let source = source_node_id();
@@ -1844,7 +1846,7 @@ mod tests {
18441846
fn reduces_liquidity_upper_bound_along_path_on_success() {
18451847
let network_graph = network_graph();
18461848
let params = ProbabilisticScoringParameters {
1847-
liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
1849+
base_penalty_msat: 0, liquidity_penalty_multiplier_msat: 1_000, ..Default::default()
18481850
};
18491851
let mut scorer = ProbabilisticScorer::new(params, &network_graph);
18501852
let sender = sender_node_id();
@@ -1868,6 +1870,7 @@ mod tests {
18681870
fn decays_liquidity_bounds_over_time() {
18691871
let network_graph = network_graph();
18701872
let params = ProbabilisticScoringParameters {
1873+
base_penalty_msat: 0,
18711874
liquidity_penalty_multiplier_msat: 1_000,
18721875
liquidity_offset_half_life: Duration::from_secs(10),
18731876
};
@@ -1919,6 +1922,7 @@ mod tests {
19191922
fn decays_liquidity_bounds_without_shift_overflow() {
19201923
let network_graph = network_graph();
19211924
let params = ProbabilisticScoringParameters {
1925+
base_penalty_msat: 0,
19221926
liquidity_penalty_multiplier_msat: 1_000,
19231927
liquidity_offset_half_life: Duration::from_secs(10),
19241928
};
@@ -1943,6 +1947,7 @@ mod tests {
19431947
fn restricts_liquidity_bounds_after_decay() {
19441948
let network_graph = network_graph();
19451949
let params = ProbabilisticScoringParameters {
1950+
base_penalty_msat: 0,
19461951
liquidity_penalty_multiplier_msat: 1_000,
19471952
liquidity_offset_half_life: Duration::from_secs(10),
19481953
};
@@ -1980,6 +1985,7 @@ mod tests {
19801985
fn restores_persisted_liquidity_bounds() {
19811986
let network_graph = network_graph();
19821987
let params = ProbabilisticScoringParameters {
1988+
base_penalty_msat: 0,
19831989
liquidity_penalty_multiplier_msat: 1_000,
19841990
liquidity_offset_half_life: Duration::from_secs(10),
19851991
};
@@ -2009,6 +2015,7 @@ mod tests {
20092015
fn decays_persisted_liquidity_bounds() {
20102016
let network_graph = network_graph();
20112017
let params = ProbabilisticScoringParameters {
2018+
base_penalty_msat: 0,
20122019
liquidity_penalty_multiplier_msat: 1_000,
20132020
liquidity_offset_half_life: Duration::from_secs(10),
20142021
};
@@ -2035,4 +2042,23 @@ mod tests {
20352042
SinceEpoch::advance(Duration::from_secs(10));
20362043
assert_eq!(deserialized_scorer.channel_penalty_msat(42, 500, 1_000, &source, &target), 371);
20372044
}
2045+
2046+
#[test]
2047+
fn adds_base_penalty_to_liquidity_penalty() {
2048+
let network_graph = network_graph();
2049+
let source = source_node_id();
2050+
let target = target_node_id();
2051+
2052+
let params = ProbabilisticScoringParameters {
2053+
base_penalty_msat: 0, ..Default::default()
2054+
};
2055+
let scorer = ProbabilisticScorer::new(params, &network_graph);
2056+
assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 585);
2057+
2058+
let params = ProbabilisticScoringParameters {
2059+
base_penalty_msat: 500, ..Default::default()
2060+
};
2061+
let scorer = ProbabilisticScorer::new(params, &network_graph);
2062+
assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 1085);
2063+
}
20382064
}

0 commit comments

Comments
 (0)