Skip to content

Commit 56d91c2

Browse files
committed
Rewrite documentation some on ProbabilisticScorer
We had some user confusion on how the probabilistic scorer works, especially in reference to the half-life parameter. This attempts to clarify how the bounds work, and how they are decayed.
1 parent 7544030 commit 56d91c2

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

lightning/src/routing/scoring.rs

+29-16
Original file line numberDiff line numberDiff line change
@@ -314,26 +314,37 @@ type ConfiguredTime = Eternity;
314314

315315
/// [`Score`] implementation using channel success probability distributions.
316316
///
317-
/// Based on *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt
318-
/// and Stefan Richter [[1]]. Given the uncertainty of channel liquidity balances, probability
319-
/// distributions are defined based on knowledge learned from successful and unsuccessful attempts.
320-
/// Then the negative `log10` of the success probability is used to determine the cost of routing a
321-
/// specific HTLC amount through a channel.
317+
/// Channels are tracked with upper- and lower- liquidity bounds - when an HTLC fails at a channel,
318+
/// we learn that the upper-bound on the available liquidity is lower than the amount of the HTLC.
319+
/// When a payment is forwarded through a channel (but fails later in the route), we learn the
320+
/// lower-bound on the channel's available liquidity must be at least the value of the HTLC.
322321
///
323-
/// Knowledge about channel liquidity balances takes the form of upper and lower bounds on the
324-
/// possible liquidity. Certainty of the bounds is decreased over time using a decay function. See
325-
/// [`ProbabilisticScoringParameters`] for details.
322+
/// These bounds are then used to determine a success probability using the formula from
323+
/// *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt
324+
/// and Stefan Richter [[1]] (i.e. `(payment amount + lower-bound) / (upper-bound - lower-bound)`).
326325
///
327-
/// Since the scorer aims to learn the current channel liquidity balances, it works best for nodes
328-
/// with high payment volume or that actively probe the [`NetworkGraph`]. Nodes with low payment
329-
/// volume are more likely to experience failed payment paths, which would need to be retried.
326+
/// This probability is converted into a linear score by `log10`'ing it and multiplying it with the
327+
/// [`liquidity_penalty_multiplier_msat`] and [`liquidity_penalty_amount_multiplier_msat`]
328+
/// parameters to get a concrete msat value.
329+
///
330+
/// The liquidity bounds are then decayed by halving them every [`liquidity_offset_half_life`].
331+
///
332+
/// Further, we track the history of our upper- and lower- liquidity bounds for each channel,
333+
/// allowing us to assign a second penalty (using [`historical_liquidity_penalty_multiplier_msat`]
334+
/// and [`historical_liquidity_penalty_amount_multiplier_msat`]) based on the same probability
335+
/// formula, but using the history of a channel rather than our latest estimates for the liquidity
336+
/// bounds.
330337
///
331338
/// # Note
332339
///
333340
/// Mixing the `no-std` feature between serialization and deserialization results in undefined
334341
/// behavior.
335342
///
336343
/// [1]: https://arxiv.org/abs/2107.05322
344+
/// [`liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_multiplier_msat
345+
/// [`liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_amount_multiplier_msat
346+
/// [`liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_multiplier_msat
347+
/// [`liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_amount_multiplier_msat
337348
pub type ProbabilisticScorer<G, L> = ProbabilisticScorerUsingTime::<G, L, ConfiguredTime>;
338349

339350
/// Probabilistic [`Score`] implementation.
@@ -391,12 +402,14 @@ pub struct ProbabilisticScoringParameters {
391402
/// [`liquidity_offset_half_life`]: Self::liquidity_offset_half_life
392403
pub liquidity_penalty_multiplier_msat: u64,
393404

394-
/// The time required to elapse before any knowledge learned about channel liquidity balances is
395-
/// cut in half.
405+
/// We track upper and lower bounds on the available liquidity in a channel in order to
406+
/// calculate success probability given recent successes and failures. In order to ensure we do
407+
/// not get stuck avoiding channels which only failed once, we decay these bounds over time.
396408
///
397-
/// The bounds are defined in terms of offsets and are initially zero. Increasing the offsets
398-
/// gives tighter bounds on the channel liquidity balance. Thus, halving the offsets decreases
399-
/// the certainty of the channel liquidity balance.
409+
/// Whenever this amount of time elapses since the last update to a channel's liquidity bounds,
410+
/// the distance from the bounds to "zero" is cut in half. In other words, the lower-bound on
411+
/// the available liquidity is halved and the upper-bound moves half-way to the channel's total
412+
/// capacity.
400413
///
401414
/// Default value: 1 hour
402415
///

0 commit comments

Comments
 (0)