@@ -315,26 +315,40 @@ type ConfiguredTime = Eternity;
315315
316316/// [`Score`] implementation using channel success probability distributions.
317317///
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.
323322///
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)`) .
327326///
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 combined with the [`liquidity_penalty_multiplier_msat`] and
328+ /// [`liquidity_penalty_amount_multiplier_msat`] parameters to calculate a concrete penalty in
329+ /// milli-satoshis. The penalties, when added across all hops, have the property of being linear in
330+ /// terms of the entire path's success probability. This allows the router to directly compare
331+ /// penalties for different paths. See the documentation of those parameters for the exact formulas.
332+ ///
333+ /// The liquidity bounds are decayed by halving them every [`liquidity_offset_half_life`].
334+ ///
335+ /// Further, we track the history of our upper and lower liquidity bounds for each channel,
336+ /// allowing us to assign a second penalty (using [`historical_liquidity_penalty_multiplier_msat`]
337+ /// and [`historical_liquidity_penalty_amount_multiplier_msat`]) based on the same probability
338+ /// formula, but using the history of a channel rather than our latest estimates for the liquidity
339+ /// bounds.
331340///
332341/// # Note
333342///
334343/// Mixing the `no-std` feature between serialization and deserialization results in undefined
335344/// behavior.
336345///
337346/// [1]: https://arxiv.org/abs/2107.05322
347+ /// [`liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_multiplier_msat
348+ /// [`liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_amount_multiplier_msat
349+ /// [`liquidity_offset_half_life`]: ProbabilisticScoringParameters::liquidity_offset_half_life
350+ /// [`historical_liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_multiplier_msat
351+ /// [`historical_liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_amount_multiplier_msat
338352pub type ProbabilisticScorer < G , L > = ProbabilisticScorerUsingTime :: < G , L , ConfiguredTime > ;
339353
340354/// Probabilistic [`Score`] implementation.
@@ -388,19 +402,27 @@ pub struct ProbabilisticScoringParameters {
388402 /// uncertainty bounds of the channel liquidity balance. Amounts above the upper bound will
389403 /// result in a `u64::max_value` penalty, however.
390404 ///
405+ /// `-log10(success_probability) * liquidity_penalty_multiplier_msat`
406+ ///
391407 /// Default value: 30,000 msat
392408 ///
393409 /// [`liquidity_offset_half_life`]: Self::liquidity_offset_half_life
394410 pub liquidity_penalty_multiplier_msat : u64 ,
395411
396- /// The time required to elapse before any knowledge learned about channel liquidity balances is
397- /// cut in half.
412+ /// Whenever this amount of time elapses since the last update to a channel's liquidity bounds,
413+ /// the distance from the bounds to "zero" is cut in half. In other words, the lower-bound on
414+ /// the available liquidity is halved and the upper-bound moves half-way to the channel's total
415+ /// capacity.
416+ ///
417+ /// Because halving the liquidity bounds grows the uncertainty on the channel's liquidity,
418+ /// the penalty for an amount within the new bounds may change. See the [`ProbabilisticScorer`]
419+ /// struct documentation for more info on the way the liquidity bounds are used.
398420 ///
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 .
402424 ///
403- /// Default value: 1 hour
425+ /// Default value: 6 hours
404426 ///
405427 /// # Note
406428 ///
@@ -758,7 +780,7 @@ impl ProbabilisticScoringParameters {
758780 base_penalty_msat : 0 ,
759781 base_penalty_amount_multiplier_msat : 0 ,
760782 liquidity_penalty_multiplier_msat : 0 ,
761- liquidity_offset_half_life : Duration :: from_secs ( 3600 ) ,
783+ liquidity_offset_half_life : Duration :: from_secs ( 6 * 60 * 60 ) ,
762784 liquidity_penalty_amount_multiplier_msat : 0 ,
763785 historical_liquidity_penalty_multiplier_msat : 0 ,
764786 historical_liquidity_penalty_amount_multiplier_msat : 0 ,
@@ -784,7 +806,7 @@ impl Default for ProbabilisticScoringParameters {
784806 base_penalty_msat : 500 ,
785807 base_penalty_amount_multiplier_msat : 8192 ,
786808 liquidity_penalty_multiplier_msat : 30_000 ,
787- liquidity_offset_half_life : Duration :: from_secs ( 3600 ) ,
809+ liquidity_offset_half_life : Duration :: from_secs ( 6 * 60 * 60 ) ,
788810 liquidity_penalty_amount_multiplier_msat : 192 ,
789811 historical_liquidity_penalty_multiplier_msat : 10_000 ,
790812 historical_liquidity_penalty_amount_multiplier_msat : 64 ,
0 commit comments