@@ -315,26 +315,39 @@ type ConfiguredTime = Eternity;
315
315
316
316
/// [`Score`] implementation using channel success probability distributions.
317
317
///
318
- /// Based on *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt
319
- /// and Stefan Richter [[1]]. Given the uncertainty of channel liquidity balances, probability
320
- /// distributions are defined based on knowledge learned from successful and unsuccessful attempts.
321
- /// Then the negative `log10` of the success probability is used to determine the cost of routing a
322
- /// specific HTLC amount through a channel.
318
+ /// Channels are tracked with upper and lower liquidity bounds - when an HTLC fails at a channel,
319
+ /// we learn that the upper-bound on the available liquidity is lower than the amount of the HTLC.
320
+ /// When a payment is forwarded through a channel (but fails later in the route), we learn the
321
+ /// lower-bound on the channel's available liquidity must be at least the value of the HTLC.
323
322
///
324
- /// Knowledge about channel liquidity balances takes the form of upper and lower bounds on the
325
- /// possible liquidity. Certainty of the bounds is decreased over time using a decay function. See
326
- /// [`ProbabilisticScoringParameters`] for details .
323
+ /// These bounds are then used to determine a success probability using the formula from
324
+ /// *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt
325
+ /// and Stefan Richter [[1]] (i.e. `(upper_bound - payment_amount) / (upper_bound - lower_bound)`) .
327
326
///
328
- /// Since the scorer aims to learn the current channel liquidity balances, it works best for nodes
329
- /// with high payment volume or that actively probe the [`NetworkGraph`]. Nodes with low payment
330
- /// volume are more likely to experience failed payment paths, which would need to be retried.
327
+ /// This probability is converted into a linear score and multiplied with the
328
+ /// [`liquidity_penalty_multiplier_msat`] and [`liquidity_penalty_amount_multiplier_msat`]
329
+ /// parameters to calculate a concrete penalty in milli-satoshis. See the documentation of those
330
+ /// parameters for the exact formulas.
331
+ ///
332
+ /// The liquidity bounds are decayed by halving them every [`liquidity_offset_half_life`].
333
+ ///
334
+ /// Further, we track the history of our upper and lower liquidity bounds for each channel,
335
+ /// allowing us to assign a second penalty (using [`historical_liquidity_penalty_multiplier_msat`]
336
+ /// and [`historical_liquidity_penalty_amount_multiplier_msat`]) based on the same probability
337
+ /// formula, but using the history of a channel rather than our latest estimates for the liquidity
338
+ /// bounds.
331
339
///
332
340
/// # Note
333
341
///
334
342
/// Mixing the `no-std` feature between serialization and deserialization results in undefined
335
343
/// behavior.
336
344
///
337
345
/// [1]: https://arxiv.org/abs/2107.05322
346
+ /// [`liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_multiplier_msat
347
+ /// [`liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_amount_multiplier_msat
348
+ /// [`liquidity_offset_half_life`]: ProbabilisticScoringParameters::liquidity_offset_half_life
349
+ /// [`historical_liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_multiplier_msat
350
+ /// [`historical_liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_amount_multiplier_msat
338
351
pub type ProbabilisticScorer < G , L > = ProbabilisticScorerUsingTime :: < G , L , ConfiguredTime > ;
339
352
340
353
/// Probabilistic [`Score`] implementation.
@@ -388,19 +401,28 @@ pub struct ProbabilisticScoringParameters {
388
401
/// uncertainty bounds of the channel liquidity balance. Amounts above the upper bound will
389
402
/// result in a `u64::max_value` penalty, however.
390
403
///
404
+ /// `-log10(success_probability) * liquidity_penalty_multiplier_msat`
405
+ ///
391
406
/// Default value: 30,000 msat
392
407
///
393
408
/// [`liquidity_offset_half_life`]: Self::liquidity_offset_half_life
394
409
pub liquidity_penalty_multiplier_msat : u64 ,
395
410
396
- /// The time required to elapse before any knowledge learned about channel liquidity balances is
397
- /// cut in half.
411
+ /// Whenever this amount of time elapses since the last update to a channel's liquidity bounds,
412
+ /// the distance from the bounds to "zero" is cut in half. In other words, the lower-bound on
413
+ /// the available liquidity is halved and the upper-bound moves half-way to the channel's total
414
+ /// capacity.
415
+ ///
416
+ /// Because halving the liquidity bounds grows the uncertainty on the channel's liquidity,
417
+ /// penalties for payments that are within the liquidity bounds will be decreased. See the
418
+ /// [`ProbabilisticScorer`] struct documentation for more info on the way the liquidity bounds
419
+ /// are used.
398
420
///
399
- /// The bounds are defined in terms of offsets and are initially zero. Increasing the offsets
400
- /// gives tighter bounds on the channel liquidity balance. Thus, halving the offsets decreases
401
- /// the certainty of the channel liquidity balance .
421
+ /// For example, if the channel's capacity is 1 million sats, and the current upper- and lower-
422
+ /// liquidity bounds are 200,000 sats and 600,000 sats, after this amount of time the upper-
423
+ /// and lower- liquidity bounds will be decayed to 100,000 and 800,000 sats .
402
424
///
403
- /// Default value: 1 hour
425
+ /// Default value: hour
404
426
///
405
427
/// # Note
406
428
///
0 commit comments