16c7249f33998b1462ea7cf30895b5f5658cac40
[rust-lightning] / lightning / src / routing / scoring.rs
1 // This file is Copyright its original authors, visible in version control
2 // history.
3 //
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
8 // licenses.
9
10 //! Utilities for scoring payment channels.
11 //!
12 //! [`ProbabilisticScorer`] may be given to [`find_route`] to score payment channels during path
13 //! finding when a custom [`ScoreLookUp`] implementation is not needed.
14 //!
15 //! # Example
16 //!
17 //! ```
18 //! # extern crate bitcoin;
19 //! #
20 //! # use lightning::routing::gossip::NetworkGraph;
21 //! # use lightning::routing::router::{RouteParameters, find_route};
22 //! # use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters, ProbabilisticScoringDecayParameters};
23 //! # use lightning::sign::KeysManager;
24 //! # use lightning::util::logger::{Logger, Record};
25 //! # use bitcoin::secp256k1::PublicKey;
26 //! #
27 //! # struct FakeLogger {};
28 //! # impl Logger for FakeLogger {
29 //! #     fn log(&self, record: Record) { unimplemented!() }
30 //! # }
31 //! # fn find_scored_route(payer: PublicKey, route_params: RouteParameters, network_graph: NetworkGraph<&FakeLogger>) {
32 //! # let logger = FakeLogger {};
33 //! #
34 //! // Use the default channel penalties.
35 //! let params = ProbabilisticScoringFeeParameters::default();
36 //! let decay_params = ProbabilisticScoringDecayParameters::default();
37 //! let scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
38 //!
39 //! // Or use custom channel penalties.
40 //! let params = ProbabilisticScoringFeeParameters {
41 //!     liquidity_penalty_multiplier_msat: 2 * 1000,
42 //!     ..ProbabilisticScoringFeeParameters::default()
43 //! };
44 //! let decay_params = ProbabilisticScoringDecayParameters::default();
45 //! let scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
46 //! # let random_seed_bytes = [42u8; 32];
47 //!
48 //! let route = find_route(&payer, &route_params, &network_graph, None, &logger, &scorer, &params, &random_seed_bytes);
49 //! # }
50 //! ```
51 //!
52 //! # Note
53 //!
54 //! Persisting when built with feature `no-std` and restoring without it, or vice versa, uses
55 //! different types and thus is undefined.
56 //!
57 //! [`find_route`]: crate::routing::router::find_route
58
59 use crate::ln::msgs::DecodeError;
60 use crate::routing::gossip::{EffectiveCapacity, NetworkGraph, NodeId};
61 use crate::routing::router::{Path, CandidateRouteHop};
62 use crate::routing::log_approx;
63 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
64 use crate::util::logger::Logger;
65
66 use crate::prelude::*;
67 use core::{cmp, fmt};
68 use core::cell::{RefCell, RefMut, Ref};
69 use core::convert::TryInto;
70 use core::ops::{Deref, DerefMut};
71 use core::time::Duration;
72 use crate::io::{self, Read};
73 use crate::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
74
75 /// We define Score ever-so-slightly differently based on whether we are being built for C bindings
76 /// or not. For users, `LockableScore` must somehow be writeable to disk. For Rust users, this is
77 /// no problem - you move a `Score` that implements `Writeable` into a `Mutex`, lock it, and now
78 /// you have the original, concrete, `Score` type, which presumably implements `Writeable`.
79 ///
80 /// For C users, once you've moved the `Score` into a `LockableScore` all you have after locking it
81 /// is an opaque trait object with an opaque pointer with no type info. Users could take the unsafe
82 /// approach of blindly casting that opaque pointer to a concrete type and calling `Writeable` from
83 /// there, but other languages downstream of the C bindings (e.g. Java) can't even do that.
84 /// Instead, we really want `Score` and `LockableScore` to implement `Writeable` directly, which we
85 /// do here by defining `Score` differently for `cfg(c_bindings)`.
86 macro_rules! define_score { ($($supertrait: path)*) => {
87 /// An interface used to score payment channels for path finding.
88 ///
89 /// `ScoreLookUp` is used to determine the penalty for a given channel.
90 ///
91 /// Scoring is in terms of fees willing to be paid in order to avoid routing through a channel.
92 pub trait ScoreLookUp {
93         /// A configurable type which should contain various passed-in parameters for configuring the scorer,
94         /// on a per-routefinding-call basis through to the scorer methods,
95         /// which are used to determine the parameters for the suitability of channels for use.
96         type ScoreParams;
97         /// Returns the fee in msats willing to be paid to avoid routing `send_amt_msat` through the
98         /// given channel in the direction from `source` to `target`.
99         ///
100         /// The channel's capacity (less any other MPP parts that are also being considered for use in
101         /// the same payment) is given by `capacity_msat`. It may be determined from various sources
102         /// such as a chain data, network gossip, or invoice hints. For invoice hints, a capacity near
103         /// [`u64::max_value`] is given to indicate sufficient capacity for the invoice's full amount.
104         /// Thus, implementations should be overflow-safe.
105         fn channel_penalty_msat(
106                 &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams
107         ) -> u64;
108 }
109
110 /// `ScoreUpdate` is used to update the scorer's internal state after a payment attempt.
111 pub trait ScoreUpdate {
112         /// Handles updating channel penalties after failing to route through a channel.
113         fn payment_path_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration);
114
115         /// Handles updating channel penalties after successfully routing along a path.
116         fn payment_path_successful(&mut self, path: &Path, duration_since_epoch: Duration);
117
118         /// Handles updating channel penalties after a probe over the given path failed.
119         fn probe_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration);
120
121         /// Handles updating channel penalties after a probe over the given path succeeded.
122         fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration);
123
124         /// Scorers may wish to reduce their certainty of channel liquidity information over time.
125         /// Thus, this method is provided to allow scorers to observe the passage of time - the holder
126         /// of this object should call this method regularly (generally via the
127         /// `lightning-background-processor` crate).
128         fn decay_liquidity_certainty(&mut self, duration_since_epoch: Duration);
129 }
130
131 /// A trait which can both lookup and update routing channel penalty scores.
132 ///
133 /// This is used in places where both bounds are required and implemented for all types which
134 /// implement [`ScoreLookUp`] and [`ScoreUpdate`].
135 ///
136 /// Bindings users may need to manually implement this for their custom scoring implementations.
137 pub trait Score : ScoreLookUp + ScoreUpdate $(+ $supertrait)* {}
138
139 #[cfg(not(c_bindings))]
140 impl<T: ScoreLookUp + ScoreUpdate $(+ $supertrait)*> Score for T {}
141
142 #[cfg(not(c_bindings))]
143 impl<S: ScoreLookUp, T: Deref<Target=S>> ScoreLookUp for T {
144         type ScoreParams = S::ScoreParams;
145         fn channel_penalty_msat(
146                 &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams
147         ) -> u64 {
148                 self.deref().channel_penalty_msat(candidate, usage, score_params)
149         }
150 }
151
152 #[cfg(not(c_bindings))]
153 impl<S: ScoreUpdate, T: DerefMut<Target=S>> ScoreUpdate for T {
154         fn payment_path_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration) {
155                 self.deref_mut().payment_path_failed(path, short_channel_id, duration_since_epoch)
156         }
157
158         fn payment_path_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
159                 self.deref_mut().payment_path_successful(path, duration_since_epoch)
160         }
161
162         fn probe_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration) {
163                 self.deref_mut().probe_failed(path, short_channel_id, duration_since_epoch)
164         }
165
166         fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
167                 self.deref_mut().probe_successful(path, duration_since_epoch)
168         }
169
170         fn decay_liquidity_certainty(&mut self, duration_since_epoch: Duration) {
171                 self.deref_mut().decay_liquidity_certainty(duration_since_epoch)
172         }
173 }
174 } }
175
176 #[cfg(c_bindings)]
177 define_score!(Writeable);
178
179 #[cfg(not(c_bindings))]
180 define_score!();
181
182 /// A scorer that is accessed under a lock.
183 ///
184 /// Needed so that calls to [`ScoreLookUp::channel_penalty_msat`] in [`find_route`] can be made while
185 /// having shared ownership of a scorer but without requiring internal locking in [`ScoreUpdate`]
186 /// implementations. Internal locking would be detrimental to route finding performance and could
187 /// result in [`ScoreLookUp::channel_penalty_msat`] returning a different value for the same channel.
188 ///
189 /// [`find_route`]: crate::routing::router::find_route
190 pub trait LockableScore<'a> {
191         /// The [`ScoreUpdate`] type.
192         type ScoreUpdate: 'a + ScoreUpdate;
193         /// The [`ScoreLookUp`] type.
194         type ScoreLookUp: 'a + ScoreLookUp;
195
196         /// The write locked [`ScoreUpdate`] type.
197         type WriteLocked: DerefMut<Target = Self::ScoreUpdate> + Sized;
198
199         /// The read locked [`ScoreLookUp`] type.
200         type ReadLocked: Deref<Target = Self::ScoreLookUp> + Sized;
201
202         /// Returns read locked scorer.
203         fn read_lock(&'a self) -> Self::ReadLocked;
204
205         /// Returns write locked scorer.
206         fn write_lock(&'a self) -> Self::WriteLocked;
207 }
208
209 /// Refers to a scorer that is accessible under lock and also writeable to disk
210 ///
211 /// We need this trait to be able to pass in a scorer to `lightning-background-processor` that will enable us to
212 /// use the Persister to persist it.
213 pub trait WriteableScore<'a>: LockableScore<'a> + Writeable {}
214
215 #[cfg(not(c_bindings))]
216 impl<'a, T> WriteableScore<'a> for T where T: LockableScore<'a> + Writeable {}
217 #[cfg(not(c_bindings))]
218 impl<'a, T: Score + 'a> LockableScore<'a> for Mutex<T> {
219         type ScoreUpdate = T;
220         type ScoreLookUp = T;
221
222         type WriteLocked = MutexGuard<'a, Self::ScoreUpdate>;
223         type ReadLocked = MutexGuard<'a, Self::ScoreLookUp>;
224
225         fn read_lock(&'a self) -> Self::ReadLocked {
226                 Mutex::lock(self).unwrap()
227         }
228
229         fn write_lock(&'a self) -> Self::WriteLocked {
230                 Mutex::lock(self).unwrap()
231         }
232 }
233
234 #[cfg(not(c_bindings))]
235 impl<'a, T: Score + 'a> LockableScore<'a> for RefCell<T> {
236         type ScoreUpdate = T;
237         type ScoreLookUp = T;
238
239         type WriteLocked = RefMut<'a, Self::ScoreUpdate>;
240         type ReadLocked = Ref<'a, Self::ScoreLookUp>;
241
242         fn write_lock(&'a self) -> Self::WriteLocked {
243                 self.borrow_mut()
244         }
245
246         fn read_lock(&'a self) -> Self::ReadLocked {
247                 self.borrow()
248         }
249 }
250
251 #[cfg(not(c_bindings))]
252 impl<'a, T: Score + 'a> LockableScore<'a> for RwLock<T> {
253         type ScoreUpdate = T;
254         type ScoreLookUp = T;
255
256         type WriteLocked = RwLockWriteGuard<'a, Self::ScoreLookUp>;
257         type ReadLocked = RwLockReadGuard<'a, Self::ScoreUpdate>;
258
259         fn read_lock(&'a self) -> Self::ReadLocked {
260                 RwLock::read(self).unwrap()
261         }
262
263         fn write_lock(&'a self) -> Self::WriteLocked {
264                 RwLock::write(self).unwrap()
265         }
266 }
267
268 #[cfg(c_bindings)]
269 /// A concrete implementation of [`LockableScore`] which supports multi-threading.
270 pub struct MultiThreadedLockableScore<T: Score> {
271         score: RwLock<T>,
272 }
273
274 #[cfg(c_bindings)]
275 impl<'a, T: Score + 'a> LockableScore<'a> for MultiThreadedLockableScore<T> {
276         type ScoreUpdate = T;
277         type ScoreLookUp = T;
278         type WriteLocked = MultiThreadedScoreLockWrite<'a, Self::ScoreUpdate>;
279         type ReadLocked = MultiThreadedScoreLockRead<'a, Self::ScoreLookUp>;
280
281         fn read_lock(&'a self) -> Self::ReadLocked {
282                 MultiThreadedScoreLockRead(self.score.read().unwrap())
283         }
284
285         fn write_lock(&'a self) -> Self::WriteLocked {
286                 MultiThreadedScoreLockWrite(self.score.write().unwrap())
287         }
288 }
289
290 #[cfg(c_bindings)]
291 impl<T: Score> Writeable for MultiThreadedLockableScore<T> {
292         fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
293                 self.score.read().unwrap().write(writer)
294         }
295 }
296
297 #[cfg(c_bindings)]
298 impl<'a, T: Score + 'a> WriteableScore<'a> for MultiThreadedLockableScore<T> {}
299
300 #[cfg(c_bindings)]
301 impl<T: Score> MultiThreadedLockableScore<T> {
302         /// Creates a new [`MultiThreadedLockableScore`] given an underlying [`Score`].
303         pub fn new(score: T) -> Self {
304                 MultiThreadedLockableScore { score: RwLock::new(score) }
305         }
306 }
307
308 #[cfg(c_bindings)]
309 /// A locked `MultiThreadedLockableScore`.
310 pub struct MultiThreadedScoreLockRead<'a, T: Score>(RwLockReadGuard<'a, T>);
311
312 #[cfg(c_bindings)]
313 /// A locked `MultiThreadedLockableScore`.
314 pub struct MultiThreadedScoreLockWrite<'a, T: Score>(RwLockWriteGuard<'a, T>);
315
316 #[cfg(c_bindings)]
317 impl<'a, T: 'a + Score> Deref for MultiThreadedScoreLockRead<'a, T> {
318         type Target = T;
319
320         fn deref(&self) -> &Self::Target {
321                 self.0.deref()
322         }
323 }
324
325 #[cfg(c_bindings)]
326 impl<'a, T: Score> ScoreLookUp for MultiThreadedScoreLockRead<'a, T> {
327         type ScoreParams = T::ScoreParams;
328         fn channel_penalty_msat(&self, candidate:&CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams
329         ) -> u64 {
330                 self.0.channel_penalty_msat(candidate, usage, score_params)
331         }
332 }
333
334 #[cfg(c_bindings)]
335 impl<'a, T: Score> Writeable for MultiThreadedScoreLockWrite<'a, T> {
336         fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
337                 self.0.write(writer)
338         }
339 }
340
341 #[cfg(c_bindings)]
342 impl<'a, T: 'a + Score> Deref for MultiThreadedScoreLockWrite<'a, T> {
343         type Target = T;
344
345         fn deref(&self) -> &Self::Target {
346                 self.0.deref()
347         }
348 }
349
350 #[cfg(c_bindings)]
351 impl<'a, T: 'a + Score> DerefMut for MultiThreadedScoreLockWrite<'a, T> {
352         fn deref_mut(&mut self) -> &mut Self::Target {
353                 self.0.deref_mut()
354         }
355 }
356
357 #[cfg(c_bindings)]
358 impl<'a, T: Score> ScoreUpdate for MultiThreadedScoreLockWrite<'a, T> {
359         fn payment_path_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration) {
360                 self.0.payment_path_failed(path, short_channel_id, duration_since_epoch)
361         }
362
363         fn payment_path_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
364                 self.0.payment_path_successful(path, duration_since_epoch)
365         }
366
367         fn probe_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration) {
368                 self.0.probe_failed(path, short_channel_id, duration_since_epoch)
369         }
370
371         fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
372                 self.0.probe_successful(path, duration_since_epoch)
373         }
374
375         fn decay_liquidity_certainty(&mut self, duration_since_epoch: Duration) {
376                 self.0.decay_liquidity_certainty(duration_since_epoch)
377         }
378 }
379
380
381 /// Proposed use of a channel passed as a parameter to [`ScoreLookUp::channel_penalty_msat`].
382 #[derive(Clone, Copy, Debug, PartialEq)]
383 pub struct ChannelUsage {
384         /// The amount to send through the channel, denominated in millisatoshis.
385         pub amount_msat: u64,
386
387         /// Total amount, denominated in millisatoshis, already allocated to send through the channel
388         /// as part of a multi-path payment.
389         pub inflight_htlc_msat: u64,
390
391         /// The effective capacity of the channel.
392         pub effective_capacity: EffectiveCapacity,
393 }
394
395 #[derive(Clone)]
396 /// [`ScoreLookUp`] implementation that uses a fixed penalty.
397 pub struct FixedPenaltyScorer {
398         penalty_msat: u64,
399 }
400
401 impl FixedPenaltyScorer {
402         /// Creates a new scorer using `penalty_msat`.
403         pub fn with_penalty(penalty_msat: u64) -> Self {
404                 Self { penalty_msat }
405         }
406 }
407
408 impl ScoreLookUp for FixedPenaltyScorer {
409         type ScoreParams = ();
410         fn channel_penalty_msat(&self, _: &CandidateRouteHop, _: ChannelUsage, _score_params: &Self::ScoreParams) -> u64 {
411                 self.penalty_msat
412         }
413 }
414
415 impl ScoreUpdate for FixedPenaltyScorer {
416         fn payment_path_failed(&mut self, _path: &Path, _short_channel_id: u64, _duration_since_epoch: Duration) {}
417
418         fn payment_path_successful(&mut self, _path: &Path, _duration_since_epoch: Duration) {}
419
420         fn probe_failed(&mut self, _path: &Path, _short_channel_id: u64, _duration_since_epoch: Duration) {}
421
422         fn probe_successful(&mut self, _path: &Path, _duration_since_epoch: Duration) {}
423
424         fn decay_liquidity_certainty(&mut self, _duration_since_epoch: Duration) {}
425 }
426
427 impl Writeable for FixedPenaltyScorer {
428         #[inline]
429         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
430                 write_tlv_fields!(w, {});
431                 Ok(())
432         }
433 }
434
435 impl ReadableArgs<u64> for FixedPenaltyScorer {
436         #[inline]
437         fn read<R: Read>(r: &mut R, penalty_msat: u64) -> Result<Self, DecodeError> {
438                 read_tlv_fields!(r, {});
439                 Ok(Self { penalty_msat })
440         }
441 }
442
443 /// [`ScoreLookUp`] implementation using channel success probability distributions.
444 ///
445 /// Channels are tracked with upper and lower liquidity bounds - when an HTLC fails at a channel,
446 /// we learn that the upper-bound on the available liquidity is lower than the amount of the HTLC.
447 /// When a payment is forwarded through a channel (but fails later in the route), we learn the
448 /// lower-bound on the channel's available liquidity must be at least the value of the HTLC.
449 ///
450 /// These bounds are then used to determine a success probability using the formula from
451 /// *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt
452 /// and Stefan Richter [[1]] (i.e. `(upper_bound - payment_amount) / (upper_bound - lower_bound)`).
453 ///
454 /// This probability is combined with the [`liquidity_penalty_multiplier_msat`] and
455 /// [`liquidity_penalty_amount_multiplier_msat`] parameters to calculate a concrete penalty in
456 /// milli-satoshis. The penalties, when added across all hops, have the property of being linear in
457 /// terms of the entire path's success probability. This allows the router to directly compare
458 /// penalties for different paths. See the documentation of those parameters for the exact formulas.
459 ///
460 /// The liquidity bounds are decayed by halving them every [`liquidity_offset_half_life`].
461 ///
462 /// Further, we track the history of our upper and lower liquidity bounds for each channel,
463 /// allowing us to assign a second penalty (using [`historical_liquidity_penalty_multiplier_msat`]
464 /// and [`historical_liquidity_penalty_amount_multiplier_msat`]) based on the same probability
465 /// formula, but using the history of a channel rather than our latest estimates for the liquidity
466 /// bounds.
467 ///
468 /// [1]: https://arxiv.org/abs/2107.05322
469 /// [`liquidity_penalty_multiplier_msat`]: ProbabilisticScoringFeeParameters::liquidity_penalty_multiplier_msat
470 /// [`liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringFeeParameters::liquidity_penalty_amount_multiplier_msat
471 /// [`liquidity_offset_half_life`]: ProbabilisticScoringDecayParameters::liquidity_offset_half_life
472 /// [`historical_liquidity_penalty_multiplier_msat`]: ProbabilisticScoringFeeParameters::historical_liquidity_penalty_multiplier_msat
473 /// [`historical_liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringFeeParameters::historical_liquidity_penalty_amount_multiplier_msat
474 pub struct ProbabilisticScorer<G: Deref<Target = NetworkGraph<L>>, L: Deref>
475 where L::Target: Logger {
476         decay_params: ProbabilisticScoringDecayParameters,
477         network_graph: G,
478         logger: L,
479         channel_liquidities: HashMap<u64, ChannelLiquidity>,
480 }
481
482 /// Parameters for configuring [`ProbabilisticScorer`].
483 ///
484 /// Used to configure base, liquidity, and amount penalties, the sum of which comprises the channel
485 /// penalty (i.e., the amount in msats willing to be paid to avoid routing through the channel).
486 ///
487 /// The penalty applied to any channel by the [`ProbabilisticScorer`] is the sum of each of the
488 /// parameters here.
489 #[derive(Clone)]
490 pub struct ProbabilisticScoringFeeParameters {
491         /// A fixed penalty in msats to apply to each channel.
492         ///
493         /// Default value: 500 msat
494         pub base_penalty_msat: u64,
495
496         /// A multiplier used with the total amount flowing over a channel to calculate a fixed penalty
497         /// applied to each channel, in excess of the [`base_penalty_msat`].
498         ///
499         /// The purpose of the amount penalty is to avoid having fees dominate the channel cost (i.e.,
500         /// fees plus penalty) for large payments. The penalty is computed as the product of this
501         /// multiplier and `2^30`ths of the total amount flowing over a channel (i.e. the payment
502         /// amount plus the amount of any other HTLCs flowing we sent over the same channel).
503         ///
504         /// ie `base_penalty_amount_multiplier_msat * amount_msat / 2^30`
505         ///
506         /// Default value: 8,192 msat
507         ///
508         /// [`base_penalty_msat`]: Self::base_penalty_msat
509         pub base_penalty_amount_multiplier_msat: u64,
510
511         /// A multiplier used in conjunction with the negative `log10` of the channel's success
512         /// probability for a payment, as determined by our latest estimates of the channel's
513         /// liquidity, to determine the liquidity penalty.
514         ///
515         /// The penalty is based in part on the knowledge learned from prior successful and unsuccessful
516         /// payments. This knowledge is decayed over time based on [`liquidity_offset_half_life`]. The
517         /// penalty is effectively limited to `2 * liquidity_penalty_multiplier_msat` (corresponding to
518         /// lower bounding the success probability to `0.01`) when the amount falls within the
519         /// uncertainty bounds of the channel liquidity balance. Amounts above the upper bound will
520         /// result in a `u64::max_value` penalty, however.
521         ///
522         /// `-log10(success_probability) * liquidity_penalty_multiplier_msat`
523         ///
524         /// Default value: 30,000 msat
525         ///
526         /// [`liquidity_offset_half_life`]: ProbabilisticScoringDecayParameters::liquidity_offset_half_life
527         pub liquidity_penalty_multiplier_msat: u64,
528
529         /// A multiplier used in conjunction with the total amount flowing over a channel and the
530         /// negative `log10` of the channel's success probability for the payment, as determined by our
531         /// latest estimates of the channel's liquidity, to determine the amount penalty.
532         ///
533         /// The purpose of the amount penalty is to avoid having fees dominate the channel cost (i.e.,
534         /// fees plus penalty) for large payments. The penalty is computed as the product of this
535         /// multiplier and `2^20`ths of the amount flowing over this channel, weighted by the negative
536         /// `log10` of the success probability.
537         ///
538         /// `-log10(success_probability) * liquidity_penalty_amount_multiplier_msat * amount_msat / 2^20`
539         ///
540         /// In practice, this means for 0.1 success probability (`-log10(0.1) == 1`) each `2^20`th of
541         /// the amount will result in a penalty of the multiplier. And, as the success probability
542         /// decreases, the negative `log10` weighting will increase dramatically. For higher success
543         /// probabilities, the multiplier will have a decreasing effect as the negative `log10` will
544         /// fall below `1`.
545         ///
546         /// Default value: 192 msat
547         pub liquidity_penalty_amount_multiplier_msat: u64,
548
549         /// A multiplier used in conjunction with the negative `log10` of the channel's success
550         /// probability for the payment, as determined based on the history of our estimates of the
551         /// channel's available liquidity, to determine a penalty.
552         ///
553         /// This penalty is similar to [`liquidity_penalty_multiplier_msat`], however, instead of using
554         /// only our latest estimate for the current liquidity available in the channel, it estimates
555         /// success probability based on the estimated liquidity available in the channel through
556         /// history. Specifically, every time we update our liquidity bounds on a given channel, we
557         /// track which of several buckets those bounds fall into, exponentially decaying the
558         /// probability of each bucket as new samples are added.
559         ///
560         /// Default value: 10,000 msat
561         ///
562         /// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat
563         pub historical_liquidity_penalty_multiplier_msat: u64,
564
565         /// A multiplier used in conjunction with the total amount flowing over a channel and the
566         /// negative `log10` of the channel's success probability for the payment, as determined based
567         /// on the history of our estimates of the channel's available liquidity, to determine a
568         /// penalty.
569         ///
570         /// The purpose of the amount penalty is to avoid having fees dominate the channel cost for
571         /// large payments. The penalty is computed as the product of this multiplier and `2^20`ths
572         /// of the amount flowing over this channel, weighted by the negative `log10` of the success
573         /// probability.
574         ///
575         /// This penalty is similar to [`liquidity_penalty_amount_multiplier_msat`], however, instead
576         /// of using only our latest estimate for the current liquidity available in the channel, it
577         /// estimates success probability based on the estimated liquidity available in the channel
578         /// through history. Specifically, every time we update our liquidity bounds on a given
579         /// channel, we track which of several buckets those bounds fall into, exponentially decaying
580         /// the probability of each bucket as new samples are added.
581         ///
582         /// Default value: 64 msat
583         ///
584         /// [`liquidity_penalty_amount_multiplier_msat`]: Self::liquidity_penalty_amount_multiplier_msat
585         pub historical_liquidity_penalty_amount_multiplier_msat: u64,
586
587         /// Manual penalties used for the given nodes. Allows to set a particular penalty for a given
588         /// node. Note that a manual penalty of `u64::max_value()` means the node would not ever be
589         /// considered during path finding.
590         ///
591         /// This is not exported to bindings users
592         pub manual_node_penalties: HashMap<NodeId, u64>,
593
594         /// This penalty is applied when `htlc_maximum_msat` is equal to or larger than half of the
595         /// channel's capacity, (ie. htlc_maximum_msat >= 0.5 * channel_capacity) which makes us
596         /// prefer nodes with a smaller `htlc_maximum_msat`. We treat such nodes preferentially
597         /// as this makes balance discovery attacks harder to execute, thereby creating an incentive
598         /// to restrict `htlc_maximum_msat` and improve privacy.
599         ///
600         /// Default value: 250 msat
601         pub anti_probing_penalty_msat: u64,
602
603         /// This penalty is applied when the total amount flowing over a channel exceeds our current
604         /// estimate of the channel's available liquidity. The total amount is the amount of the
605         /// current HTLC plus any HTLCs which we've sent over the same channel.
606         ///
607         /// Note that in this case all other penalties, including the
608         /// [`liquidity_penalty_multiplier_msat`] and [`liquidity_penalty_amount_multiplier_msat`]-based
609         /// penalties, as well as the [`base_penalty_msat`] and the [`anti_probing_penalty_msat`], if
610         /// applicable, are still included in the overall penalty.
611         ///
612         /// If you wish to avoid creating paths with such channels entirely, setting this to a value of
613         /// `u64::max_value()` will guarantee that.
614         ///
615         /// Default value: 1_0000_0000_000 msat (1 Bitcoin)
616         ///
617         /// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat
618         /// [`liquidity_penalty_amount_multiplier_msat`]: Self::liquidity_penalty_amount_multiplier_msat
619         /// [`base_penalty_msat`]: Self::base_penalty_msat
620         /// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat
621         pub considered_impossible_penalty_msat: u64,
622
623         /// In order to calculate most of the scores above, we must first convert a lower and upper
624         /// bound on the available liquidity in a channel into the probability that we think a payment
625         /// will succeed. That probability is derived from a Probability Density Function for where we
626         /// think the liquidity in a channel likely lies, given such bounds.
627         ///
628         /// If this flag is set, that PDF is simply a constant - we assume that the actual available
629         /// liquidity in a channel is just as likely to be at any point between our lower and upper
630         /// bounds.
631         ///
632         /// If this flag is *not* set, that PDF is `(x - 0.5*capacity) ^ 2`. That is, we use an
633         /// exponential curve which expects the liquidity of a channel to lie "at the edges". This
634         /// matches experimental results - most routing nodes do not aggressively rebalance their
635         /// channels and flows in the network are often unbalanced, leaving liquidity usually
636         /// unavailable.
637         ///
638         /// Thus, for the "best" routes, leave this flag `false`. However, the flag does imply a number
639         /// of floating-point multiplications in the hottest routing code, which may lead to routing
640         /// performance degradation on some machines.
641         ///
642         /// Default value: false
643         pub linear_success_probability: bool,
644 }
645
646 impl Default for ProbabilisticScoringFeeParameters {
647         fn default() -> Self {
648                 Self {
649                         base_penalty_msat: 500,
650                         base_penalty_amount_multiplier_msat: 8192,
651                         liquidity_penalty_multiplier_msat: 30_000,
652                         liquidity_penalty_amount_multiplier_msat: 192,
653                         manual_node_penalties: HashMap::new(),
654                         anti_probing_penalty_msat: 250,
655                         considered_impossible_penalty_msat: 1_0000_0000_000,
656                         historical_liquidity_penalty_multiplier_msat: 10_000,
657                         historical_liquidity_penalty_amount_multiplier_msat: 64,
658                         linear_success_probability: false,
659                 }
660         }
661 }
662
663 impl ProbabilisticScoringFeeParameters {
664         /// Marks the node with the given `node_id` as banned,
665         /// i.e it will be avoided during path finding.
666         pub fn add_banned(&mut self, node_id: &NodeId) {
667                 self.manual_node_penalties.insert(*node_id, u64::max_value());
668         }
669
670         /// Marks all nodes in the given list as banned, i.e.,
671         /// they will be avoided during path finding.
672         pub fn add_banned_from_list(&mut self, node_ids: Vec<NodeId>) {
673                 for id in node_ids {
674                         self.manual_node_penalties.insert(id, u64::max_value());
675                 }
676         }
677
678         /// Removes the node with the given `node_id` from the list of nodes to avoid.
679         pub fn remove_banned(&mut self, node_id: &NodeId) {
680                 self.manual_node_penalties.remove(node_id);
681         }
682
683         /// Sets a manual penalty for the given node.
684         pub fn set_manual_penalty(&mut self, node_id: &NodeId, penalty: u64) {
685                 self.manual_node_penalties.insert(*node_id, penalty);
686         }
687
688         /// Removes the node with the given `node_id` from the list of manual penalties.
689         pub fn remove_manual_penalty(&mut self, node_id: &NodeId) {
690                 self.manual_node_penalties.remove(node_id);
691         }
692
693         /// Clears the list of manual penalties that are applied during path finding.
694         pub fn clear_manual_penalties(&mut self) {
695                 self.manual_node_penalties = HashMap::new();
696         }
697 }
698
699 #[cfg(test)]
700 impl ProbabilisticScoringFeeParameters {
701         fn zero_penalty() -> Self {
702                 Self {
703                         base_penalty_msat: 0,
704                         base_penalty_amount_multiplier_msat: 0,
705                         liquidity_penalty_multiplier_msat: 0,
706                         liquidity_penalty_amount_multiplier_msat: 0,
707                         historical_liquidity_penalty_multiplier_msat: 0,
708                         historical_liquidity_penalty_amount_multiplier_msat: 0,
709                         manual_node_penalties: HashMap::new(),
710                         anti_probing_penalty_msat: 0,
711                         considered_impossible_penalty_msat: 0,
712                         linear_success_probability: true,
713                 }
714         }
715 }
716
717 /// Parameters for configuring [`ProbabilisticScorer`].
718 ///
719 /// Used to configure decay parameters that are static throughout the lifetime of the scorer.
720 /// these decay parameters affect the score of the channel penalty and are not changed on a
721 /// per-route penalty cost call.
722 #[derive(Copy, Clone)]
723 pub struct ProbabilisticScoringDecayParameters {
724         /// If we aren't learning any new datapoints for a channel, the historical liquidity bounds
725         /// tracking can simply live on with increasingly stale data. Instead, when a channel has not
726         /// seen a liquidity estimate update for this amount of time, the historical datapoints are
727         /// decayed by half.
728         /// For an example of historical_no_updates_half_life being used see [`historical_estimated_channel_liquidity_probabilities`]
729         ///
730         /// Note that after 16 or more half lives all historical data will be completely gone.
731         ///
732         /// Default value: 14 days
733         ///
734         /// [`historical_estimated_channel_liquidity_probabilities`]: ProbabilisticScorer::historical_estimated_channel_liquidity_probabilities
735         pub historical_no_updates_half_life: Duration,
736
737         /// Whenever this amount of time elapses since the last update to a channel's liquidity bounds,
738         /// the distance from the bounds to "zero" is cut in half. In other words, the lower-bound on
739         /// the available liquidity is halved and the upper-bound moves half-way to the channel's total
740         /// capacity.
741         ///
742         /// Because halving the liquidity bounds grows the uncertainty on the channel's liquidity,
743         /// the penalty for an amount within the new bounds may change. See the [`ProbabilisticScorer`]
744         /// struct documentation for more info on the way the liquidity bounds are used.
745         ///
746         /// For example, if the channel's capacity is 1 million sats, and the current upper and lower
747         /// liquidity bounds are 200,000 sats and 600,000 sats, after this amount of time the upper
748         /// and lower liquidity bounds will be decayed to 100,000 and 800,000 sats.
749         ///
750         /// Default value: 6 hours
751         ///
752         /// # Note
753         ///
754         /// When built with the `no-std` feature, time will never elapse. Therefore, the channel
755         /// liquidity knowledge will never decay except when the bounds cross.
756         pub liquidity_offset_half_life: Duration,
757 }
758
759 impl Default for ProbabilisticScoringDecayParameters {
760         fn default() -> Self {
761                 Self {
762                         liquidity_offset_half_life: Duration::from_secs(6 * 60 * 60),
763                         historical_no_updates_half_life: Duration::from_secs(60 * 60 * 24 * 14),
764                 }
765         }
766 }
767
768 #[cfg(test)]
769 impl ProbabilisticScoringDecayParameters {
770         fn zero_penalty() -> Self {
771                 Self {
772                         liquidity_offset_half_life: Duration::from_secs(6 * 60 * 60),
773                         historical_no_updates_half_life: Duration::from_secs(60 * 60 * 24 * 14),
774                 }
775         }
776 }
777
778 /// Accounting for channel liquidity balance uncertainty.
779 ///
780 /// Direction is defined in terms of [`NodeId`] partial ordering, where the source node is the
781 /// first node in the ordering of the channel's counterparties. Thus, swapping the two liquidity
782 /// offset fields gives the opposite direction.
783 struct ChannelLiquidity {
784         /// Lower channel liquidity bound in terms of an offset from zero.
785         min_liquidity_offset_msat: u64,
786
787         /// Upper channel liquidity bound in terms of an offset from the effective capacity.
788         max_liquidity_offset_msat: u64,
789
790         liquidity_history: HistoricalLiquidityTracker,
791
792         /// Time when the liquidity bounds were last modified as an offset since the unix epoch.
793         last_updated: Duration,
794
795         /// Time when the historical liquidity bounds were last modified as an offset against the unix
796         /// epoch.
797         offset_history_last_updated: Duration,
798 }
799
800 /// A snapshot of [`ChannelLiquidity`] in one direction assuming a certain channel capacity and
801 /// decayed with a given half life.
802 struct DirectedChannelLiquidity<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>, T: Deref<Target = Duration>> {
803         min_liquidity_offset_msat: L,
804         max_liquidity_offset_msat: L,
805         liquidity_history: HistoricalMinMaxBuckets<BRT>,
806         capacity_msat: u64,
807         last_updated: T,
808         offset_history_last_updated: T,
809 }
810
811 impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ProbabilisticScorer<G, L> where L::Target: Logger {
812         /// Creates a new scorer using the given scoring parameters for sending payments from a node
813         /// through a network graph.
814         pub fn new(decay_params: ProbabilisticScoringDecayParameters, network_graph: G, logger: L) -> Self {
815                 Self {
816                         decay_params,
817                         network_graph,
818                         logger,
819                         channel_liquidities: HashMap::new(),
820                 }
821         }
822
823         #[cfg(test)]
824         fn with_channel(mut self, short_channel_id: u64, liquidity: ChannelLiquidity) -> Self {
825                 assert!(self.channel_liquidities.insert(short_channel_id, liquidity).is_none());
826                 self
827         }
828
829         /// Dump the contents of this scorer into the configured logger.
830         ///
831         /// Note that this writes roughly one line per channel for which we have a liquidity estimate,
832         /// which may be a substantial amount of log output.
833         pub fn debug_log_liquidity_stats(&self) {
834                 let graph = self.network_graph.read_only();
835                 for (scid, liq) in self.channel_liquidities.iter() {
836                         if let Some(chan_debug) = graph.channels().get(scid) {
837                                 let log_direction = |source, target| {
838                                         if let Some((directed_info, _)) = chan_debug.as_directed_to(target) {
839                                                 let amt = directed_info.effective_capacity().as_msat();
840                                                 let dir_liq = liq.as_directed(source, target, amt);
841
842                                                 let min_buckets = &dir_liq.liquidity_history.min_liquidity_offset_history_buckets();
843                                                 let max_buckets = &dir_liq.liquidity_history.max_liquidity_offset_history_buckets();
844
845                                                 log_debug!(self.logger, core::concat!(
846                                                         "Liquidity from {} to {} via {} is in the range ({}, {}).\n",
847                                                         "\tHistorical min liquidity bucket relative probabilities:\n",
848                                                         "\t\t{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}\n",
849                                                         "\tHistorical max liquidity bucket relative probabilities:\n",
850                                                         "\t\t{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}"),
851                                                         source, target, scid, dir_liq.min_liquidity_msat(), dir_liq.max_liquidity_msat(),
852                                                         min_buckets[ 0], min_buckets[ 1], min_buckets[ 2], min_buckets[ 3],
853                                                         min_buckets[ 4], min_buckets[ 5], min_buckets[ 6], min_buckets[ 7],
854                                                         min_buckets[ 8], min_buckets[ 9], min_buckets[10], min_buckets[11],
855                                                         min_buckets[12], min_buckets[13], min_buckets[14], min_buckets[15],
856                                                         min_buckets[16], min_buckets[17], min_buckets[18], min_buckets[19],
857                                                         min_buckets[20], min_buckets[21], min_buckets[22], min_buckets[23],
858                                                         min_buckets[24], min_buckets[25], min_buckets[26], min_buckets[27],
859                                                         min_buckets[28], min_buckets[29], min_buckets[30], min_buckets[31],
860                                                         // Note that the liquidity buckets are an offset from the edge, so we
861                                                         // inverse the max order to get the probabilities from zero.
862                                                         max_buckets[31], max_buckets[30], max_buckets[29], max_buckets[28],
863                                                         max_buckets[27], max_buckets[26], max_buckets[25], max_buckets[24],
864                                                         max_buckets[23], max_buckets[22], max_buckets[21], max_buckets[20],
865                                                         max_buckets[19], max_buckets[18], max_buckets[17], max_buckets[16],
866                                                         max_buckets[15], max_buckets[14], max_buckets[13], max_buckets[12],
867                                                         max_buckets[11], max_buckets[10], max_buckets[ 9], max_buckets[ 8],
868                                                         max_buckets[ 7], max_buckets[ 6], max_buckets[ 5], max_buckets[ 4],
869                                                         max_buckets[ 3], max_buckets[ 2], max_buckets[ 1], max_buckets[ 0]);
870                                         } else {
871                                                 log_debug!(self.logger, "No amount known for SCID {} from {:?} to {:?}", scid, source, target);
872                                         }
873                                 };
874
875                                 log_direction(&chan_debug.node_one, &chan_debug.node_two);
876                                 log_direction(&chan_debug.node_two, &chan_debug.node_one);
877                         } else {
878                                 log_debug!(self.logger, "No network graph entry for SCID {}", scid);
879                         }
880                 }
881         }
882
883         /// Query the estimated minimum and maximum liquidity available for sending a payment over the
884         /// channel with `scid` towards the given `target` node.
885         pub fn estimated_channel_liquidity_range(&self, scid: u64, target: &NodeId) -> Option<(u64, u64)> {
886                 let graph = self.network_graph.read_only();
887
888                 if let Some(chan) = graph.channels().get(&scid) {
889                         if let Some(liq) = self.channel_liquidities.get(&scid) {
890                                 if let Some((directed_info, source)) = chan.as_directed_to(target) {
891                                         let amt = directed_info.effective_capacity().as_msat();
892                                         let dir_liq = liq.as_directed(source, target, amt);
893                                         return Some((dir_liq.min_liquidity_msat(), dir_liq.max_liquidity_msat()));
894                                 }
895                         }
896                 }
897                 None
898         }
899
900         /// Query the historical estimated minimum and maximum liquidity available for sending a
901         /// payment over the channel with `scid` towards the given `target` node.
902         ///
903         /// Returns two sets of 32 buckets. The first set describes the lower-bound liquidity history,
904         /// the second set describes the upper-bound liquidity history. Each bucket describes the
905         /// relative frequency at which we've seen a liquidity bound in the bucket's range relative to
906         /// the channel's total capacity, on an arbitrary scale. Because the values are slowly decayed,
907         /// more recent data points are weighted more heavily than older datapoints.
908         ///
909         /// Note that the range of each bucket varies by its location to provide more granular results
910         /// at the edges of a channel's capacity, where it is more likely to sit.
911         ///
912         /// When scoring, the estimated probability that an upper-/lower-bound lies in a given bucket
913         /// is calculated by dividing that bucket's value with the total value of all buckets.
914         ///
915         /// For example, using a lower bucket count for illustrative purposes, a value of
916         /// `[0, 0, 0, ..., 0, 32]` indicates that we believe the probability of a bound being very
917         /// close to the channel's capacity to be 100%, and have never (recently) seen it in any other
918         /// bucket. A value of `[31, 0, 0, ..., 0, 0, 32]` indicates we've seen the bound being both
919         /// in the top and bottom bucket, and roughly with similar (recent) frequency.
920         ///
921         /// Because the datapoints are decayed slowly over time, values will eventually return to
922         /// `Some(([0; 32], [0; 32]))` or `None` if no data remains for a channel.
923         ///
924         /// In order to fetch a single success probability from the buckets provided here, as used in
925         /// the scoring model, see [`Self::historical_estimated_payment_success_probability`].
926         pub fn historical_estimated_channel_liquidity_probabilities(&self, scid: u64, target: &NodeId)
927         -> Option<([u16; 32], [u16; 32])> {
928                 let graph = self.network_graph.read_only();
929
930                 if let Some(chan) = graph.channels().get(&scid) {
931                         if let Some(liq) = self.channel_liquidities.get(&scid) {
932                                 if let Some((directed_info, source)) = chan.as_directed_to(target) {
933                                         let amt = directed_info.effective_capacity().as_msat();
934                                         let dir_liq = liq.as_directed(source, target, amt);
935
936                                         let min_buckets = *dir_liq.liquidity_history.min_liquidity_offset_history_buckets();
937                                         let mut max_buckets = *dir_liq.liquidity_history.max_liquidity_offset_history_buckets();
938
939                                         // Note that the liquidity buckets are an offset from the edge, so we inverse
940                                         // the max order to get the probabilities from zero.
941                                         max_buckets.reverse();
942                                         return Some((min_buckets, max_buckets));
943                                 }
944                         }
945                 }
946                 None
947         }
948
949         /// Query the probability of payment success sending the given `amount_msat` over the channel
950         /// with `scid` towards the given `target` node, based on the historical estimated liquidity
951         /// bounds.
952         ///
953         /// These are the same bounds as returned by
954         /// [`Self::historical_estimated_channel_liquidity_probabilities`] (but not those returned by
955         /// [`Self::estimated_channel_liquidity_range`]).
956         pub fn historical_estimated_payment_success_probability(
957                 &self, scid: u64, target: &NodeId, amount_msat: u64, params: &ProbabilisticScoringFeeParameters)
958         -> Option<f64> {
959                 let graph = self.network_graph.read_only();
960
961                 if let Some(chan) = graph.channels().get(&scid) {
962                         if let Some(liq) = self.channel_liquidities.get(&scid) {
963                                 if let Some((directed_info, source)) = chan.as_directed_to(target) {
964                                         let capacity_msat = directed_info.effective_capacity().as_msat();
965                                         let dir_liq = liq.as_directed(source, target, capacity_msat);
966
967                                         return dir_liq.liquidity_history.calculate_success_probability_times_billion(
968                                                 &params, amount_msat, capacity_msat
969                                         ).map(|p| p as f64 / (1024 * 1024 * 1024) as f64);
970                                 }
971                         }
972                 }
973                 None
974         }
975 }
976
977 impl ChannelLiquidity {
978         fn new(last_updated: Duration) -> Self {
979                 Self {
980                         min_liquidity_offset_msat: 0,
981                         max_liquidity_offset_msat: 0,
982                         liquidity_history: HistoricalLiquidityTracker::new(),
983                         last_updated,
984                         offset_history_last_updated: last_updated,
985                 }
986         }
987
988         /// Returns a view of the channel liquidity directed from `source` to `target` assuming
989         /// `capacity_msat`.
990         fn as_directed(
991                 &self, source: &NodeId, target: &NodeId, capacity_msat: u64,
992         ) -> DirectedChannelLiquidity<&u64, &HistoricalBucketRangeTracker, &Duration> {
993                 let source_less_than_target = source < target;
994                 let (min_liquidity_offset_msat, max_liquidity_offset_msat) =
995                         if source_less_than_target {
996                                 (&self.min_liquidity_offset_msat, &self.max_liquidity_offset_msat)
997                         } else {
998                                 (&self.max_liquidity_offset_msat, &self.min_liquidity_offset_msat)
999                         };
1000
1001                 DirectedChannelLiquidity {
1002                         min_liquidity_offset_msat,
1003                         max_liquidity_offset_msat,
1004                         liquidity_history: self.liquidity_history.as_directed(source_less_than_target),
1005                         capacity_msat,
1006                         last_updated: &self.last_updated,
1007                         offset_history_last_updated: &self.offset_history_last_updated,
1008                 }
1009         }
1010
1011         /// Returns a mutable view of the channel liquidity directed from `source` to `target` assuming
1012         /// `capacity_msat`.
1013         fn as_directed_mut(
1014                 &mut self, source: &NodeId, target: &NodeId, capacity_msat: u64,
1015         ) -> DirectedChannelLiquidity<&mut u64, &mut HistoricalBucketRangeTracker, &mut Duration> {
1016                 let source_less_than_target = source < target;
1017                 let (min_liquidity_offset_msat, max_liquidity_offset_msat) =
1018                         if source_less_than_target {
1019                                 (&mut self.min_liquidity_offset_msat, &mut self.max_liquidity_offset_msat)
1020                         } else {
1021                                 (&mut self.max_liquidity_offset_msat, &mut self.min_liquidity_offset_msat)
1022                         };
1023
1024                 DirectedChannelLiquidity {
1025                         min_liquidity_offset_msat,
1026                         max_liquidity_offset_msat,
1027                         liquidity_history: self.liquidity_history.as_directed_mut(source_less_than_target),
1028                         capacity_msat,
1029                         last_updated: &mut self.last_updated,
1030                         offset_history_last_updated: &mut self.offset_history_last_updated,
1031                 }
1032         }
1033
1034         fn decayed_offset(&self, offset: u64, duration_since_epoch: Duration,
1035                 decay_params: ProbabilisticScoringDecayParameters
1036         ) -> u64 {
1037                 let half_life = decay_params.liquidity_offset_half_life.as_secs_f64();
1038                 if half_life != 0.0 {
1039                         let elapsed_time = duration_since_epoch.saturating_sub(self.last_updated).as_secs_f64();
1040                         ((offset as f64) * powf64(0.5, elapsed_time / half_life)) as u64
1041                 } else {
1042                         0
1043                 }
1044         }
1045 }
1046
1047 /// Bounds `-log10` to avoid excessive liquidity penalties for payments with low success
1048 /// probabilities.
1049 const NEGATIVE_LOG10_UPPER_BOUND: u64 = 2;
1050
1051 /// The rough cutoff at which our precision falls off and we should stop bothering to try to log a
1052 /// ratio, as X in 1/X.
1053 const PRECISION_LOWER_BOUND_DENOMINATOR: u64 = log_approx::LOWER_BITS_BOUND;
1054
1055 /// The divisor used when computing the amount penalty.
1056 const AMOUNT_PENALTY_DIVISOR: u64 = 1 << 20;
1057 const BASE_AMOUNT_PENALTY_DIVISOR: u64 = 1 << 30;
1058
1059 /// Raises three `f64`s to the 3rd power, without `powi` because it requires `std` (dunno why).
1060 #[inline(always)]
1061 fn three_f64_pow_3(a: f64, b: f64, c: f64) -> (f64, f64, f64) {
1062         (a * a * a, b * b * b, c * c * c)
1063 }
1064
1065 /// Given liquidity bounds, calculates the success probability (in the form of a numerator and
1066 /// denominator) of an HTLC. This is a key assumption in our scoring models.
1067 ///
1068 /// Must not return a numerator or denominator greater than 2^31 for arguments less than 2^31.
1069 ///
1070 /// min_zero_implies_no_successes signals that a `min_liquidity_msat` of 0 means we've not
1071 /// (recently) seen an HTLC successfully complete over this channel.
1072 #[inline(always)]
1073 fn success_probability(
1074         amount_msat: u64, min_liquidity_msat: u64, max_liquidity_msat: u64, capacity_msat: u64,
1075         params: &ProbabilisticScoringFeeParameters, min_zero_implies_no_successes: bool,
1076 ) -> (u64, u64) {
1077         debug_assert!(min_liquidity_msat <= amount_msat);
1078         debug_assert!(amount_msat < max_liquidity_msat);
1079         debug_assert!(max_liquidity_msat <= capacity_msat);
1080
1081         let (numerator, mut denominator) =
1082                 if params.linear_success_probability {
1083                         (max_liquidity_msat - amount_msat,
1084                                 (max_liquidity_msat - min_liquidity_msat).saturating_add(1))
1085                 } else {
1086                         let capacity = capacity_msat as f64;
1087                         let min = (min_liquidity_msat as f64) / capacity;
1088                         let max = (max_liquidity_msat as f64) / capacity;
1089                         let amount = (amount_msat as f64) / capacity;
1090
1091                         // Assume the channel has a probability density function of (x - 0.5)^2 for values from
1092                         // 0 to 1 (where 1 is the channel's full capacity). The success probability given some
1093                         // liquidity bounds is thus the integral under the curve from the amount to maximum
1094                         // estimated liquidity, divided by the same integral from the minimum to the maximum
1095                         // estimated liquidity bounds.
1096                         //
1097                         // Because the integral from x to y is simply (y - 0.5)^3 - (x - 0.5)^3, we can
1098                         // calculate the cumulative density function between the min/max bounds trivially. Note
1099                         // that we don't bother to normalize the CDF to total to 1, as it will come out in the
1100                         // division of num / den.
1101                         let (max_pow, amt_pow, min_pow) = three_f64_pow_3(max - 0.5, amount - 0.5, min - 0.5);
1102                         let num = max_pow - amt_pow;
1103                         let den = max_pow - min_pow;
1104
1105                         // Because our numerator and denominator max out at 0.5^3 we need to multiply them by
1106                         // quite a large factor to get something useful (ideally in the 2^30 range).
1107                         const BILLIONISH: f64 = 1024.0 * 1024.0 * 1024.0;
1108                         let numerator = (num * BILLIONISH) as u64 + 1;
1109                         let denominator = (den * BILLIONISH) as u64 + 1;
1110                         debug_assert!(numerator <= 1 << 30, "Got large numerator ({}) from float {}.", numerator, num);
1111                         debug_assert!(denominator <= 1 << 30, "Got large denominator ({}) from float {}.", denominator, den);
1112                         (numerator, denominator)
1113                 };
1114
1115         if min_zero_implies_no_successes && min_liquidity_msat == 0 &&
1116                 denominator < u64::max_value() / 21
1117         {
1118                 // If we have no knowledge of the channel, scale probability down by ~75%
1119                 // Note that we prefer to increase the denominator rather than decrease the numerator as
1120                 // the denominator is more likely to be larger and thus provide greater precision. This is
1121                 // mostly an overoptimization but makes a large difference in tests.
1122                 denominator = denominator * 21 / 16
1123         }
1124
1125         (numerator, denominator)
1126 }
1127
1128 impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>, T: Deref<Target = Duration>>
1129 DirectedChannelLiquidity< L, BRT, T> {
1130         /// Returns a liquidity penalty for routing the given HTLC `amount_msat` through the channel in
1131         /// this direction.
1132         fn penalty_msat(&self, amount_msat: u64, score_params: &ProbabilisticScoringFeeParameters) -> u64 {
1133                 let available_capacity = self.capacity_msat;
1134                 let max_liquidity_msat = self.max_liquidity_msat();
1135                 let min_liquidity_msat = core::cmp::min(self.min_liquidity_msat(), max_liquidity_msat);
1136
1137                 let mut res = if amount_msat <= min_liquidity_msat {
1138                         0
1139                 } else if amount_msat >= max_liquidity_msat {
1140                         // Equivalent to hitting the else clause below with the amount equal to the effective
1141                         // capacity and without any certainty on the liquidity upper bound, plus the
1142                         // impossibility penalty.
1143                         let negative_log10_times_2048 = NEGATIVE_LOG10_UPPER_BOUND * 2048;
1144                         Self::combined_penalty_msat(amount_msat, negative_log10_times_2048,
1145                                         score_params.liquidity_penalty_multiplier_msat,
1146                                         score_params.liquidity_penalty_amount_multiplier_msat)
1147                                 .saturating_add(score_params.considered_impossible_penalty_msat)
1148                 } else {
1149                         let (numerator, denominator) = success_probability(amount_msat,
1150                                 min_liquidity_msat, max_liquidity_msat, available_capacity, score_params, false);
1151                         if denominator - numerator < denominator / PRECISION_LOWER_BOUND_DENOMINATOR {
1152                                 // If the failure probability is < 1.5625% (as 1 - numerator/denominator < 1/64),
1153                                 // don't bother trying to use the log approximation as it gets too noisy to be
1154                                 // particularly helpful, instead just round down to 0.
1155                                 0
1156                         } else {
1157                                 let negative_log10_times_2048 =
1158                                         log_approx::negative_log10_times_2048(numerator, denominator);
1159                                 Self::combined_penalty_msat(amount_msat, negative_log10_times_2048,
1160                                         score_params.liquidity_penalty_multiplier_msat,
1161                                         score_params.liquidity_penalty_amount_multiplier_msat)
1162                         }
1163                 };
1164
1165                 if amount_msat >= available_capacity {
1166                         // We're trying to send more than the capacity, use a max penalty.
1167                         res = res.saturating_add(Self::combined_penalty_msat(amount_msat,
1168                                 NEGATIVE_LOG10_UPPER_BOUND * 2048,
1169                                 score_params.historical_liquidity_penalty_multiplier_msat,
1170                                 score_params.historical_liquidity_penalty_amount_multiplier_msat));
1171                         return res;
1172                 }
1173
1174                 if score_params.historical_liquidity_penalty_multiplier_msat != 0 ||
1175                    score_params.historical_liquidity_penalty_amount_multiplier_msat != 0 {
1176                         if let Some(cumulative_success_prob_times_billion) = self.liquidity_history
1177                                 .calculate_success_probability_times_billion(
1178                                         score_params, amount_msat, self.capacity_msat)
1179                         {
1180                                 let historical_negative_log10_times_2048 =
1181                                         log_approx::negative_log10_times_2048(cumulative_success_prob_times_billion + 1, 1024 * 1024 * 1024);
1182                                 res = res.saturating_add(Self::combined_penalty_msat(amount_msat,
1183                                         historical_negative_log10_times_2048, score_params.historical_liquidity_penalty_multiplier_msat,
1184                                         score_params.historical_liquidity_penalty_amount_multiplier_msat));
1185                         } else {
1186                                 // If we don't have any valid points (or, once decayed, we have less than a full
1187                                 // point), redo the non-historical calculation with no liquidity bounds tracked and
1188                                 // the historical penalty multipliers.
1189                                 let (numerator, denominator) = success_probability(amount_msat, 0,
1190                                         available_capacity, available_capacity, score_params, true);
1191                                 let negative_log10_times_2048 =
1192                                         log_approx::negative_log10_times_2048(numerator, denominator);
1193                                 res = res.saturating_add(Self::combined_penalty_msat(amount_msat, negative_log10_times_2048,
1194                                         score_params.historical_liquidity_penalty_multiplier_msat,
1195                                         score_params.historical_liquidity_penalty_amount_multiplier_msat));
1196                         }
1197                 }
1198
1199                 res
1200         }
1201
1202         /// Computes the liquidity penalty from the penalty multipliers.
1203         #[inline(always)]
1204         fn combined_penalty_msat(amount_msat: u64, mut negative_log10_times_2048: u64,
1205                 liquidity_penalty_multiplier_msat: u64, liquidity_penalty_amount_multiplier_msat: u64,
1206         ) -> u64 {
1207                 negative_log10_times_2048 =
1208                         negative_log10_times_2048.min(NEGATIVE_LOG10_UPPER_BOUND * 2048);
1209
1210                 // Upper bound the liquidity penalty to ensure some channel is selected.
1211                 let liquidity_penalty_msat = negative_log10_times_2048
1212                         .saturating_mul(liquidity_penalty_multiplier_msat) / 2048;
1213                 let amount_penalty_msat = negative_log10_times_2048
1214                         .saturating_mul(liquidity_penalty_amount_multiplier_msat)
1215                         .saturating_mul(amount_msat) / 2048 / AMOUNT_PENALTY_DIVISOR;
1216
1217                 liquidity_penalty_msat.saturating_add(amount_penalty_msat)
1218         }
1219
1220         /// Returns the lower bound of the channel liquidity balance in this direction.
1221         #[inline(always)]
1222         fn min_liquidity_msat(&self) -> u64 {
1223                 *self.min_liquidity_offset_msat
1224         }
1225
1226         /// Returns the upper bound of the channel liquidity balance in this direction.
1227         #[inline(always)]
1228         fn max_liquidity_msat(&self) -> u64 {
1229                 self.capacity_msat
1230                         .saturating_sub(*self.max_liquidity_offset_msat)
1231         }
1232 }
1233
1234 impl<L: DerefMut<Target = u64>, BRT: DerefMut<Target = HistoricalBucketRangeTracker>, T: DerefMut<Target = Duration>>
1235 DirectedChannelLiquidity<L, BRT, T> {
1236         /// Adjusts the channel liquidity balance bounds when failing to route `amount_msat`.
1237         fn failed_at_channel<Log: Deref>(
1238                 &mut self, amount_msat: u64, duration_since_epoch: Duration, chan_descr: fmt::Arguments, logger: &Log
1239         ) where Log::Target: Logger {
1240                 let existing_max_msat = self.max_liquidity_msat();
1241                 if amount_msat < existing_max_msat {
1242                         log_debug!(logger, "Setting max liquidity of {} from {} to {}", chan_descr, existing_max_msat, amount_msat);
1243                         self.set_max_liquidity_msat(amount_msat, duration_since_epoch);
1244                 } else {
1245                         log_trace!(logger, "Max liquidity of {} is {} (already less than or equal to {})",
1246                                 chan_descr, existing_max_msat, amount_msat);
1247                 }
1248                 self.update_history_buckets(0, duration_since_epoch);
1249         }
1250
1251         /// Adjusts the channel liquidity balance bounds when failing to route `amount_msat` downstream.
1252         fn failed_downstream<Log: Deref>(
1253                 &mut self, amount_msat: u64, duration_since_epoch: Duration, chan_descr: fmt::Arguments, logger: &Log
1254         ) where Log::Target: Logger {
1255                 let existing_min_msat = self.min_liquidity_msat();
1256                 if amount_msat > existing_min_msat {
1257                         log_debug!(logger, "Setting min liquidity of {} from {} to {}", existing_min_msat, chan_descr, amount_msat);
1258                         self.set_min_liquidity_msat(amount_msat, duration_since_epoch);
1259                 } else {
1260                         log_trace!(logger, "Min liquidity of {} is {} (already greater than or equal to {})",
1261                                 chan_descr, existing_min_msat, amount_msat);
1262                 }
1263                 self.update_history_buckets(0, duration_since_epoch);
1264         }
1265
1266         /// Adjusts the channel liquidity balance bounds when successfully routing `amount_msat`.
1267         fn successful<Log: Deref>(&mut self,
1268                 amount_msat: u64, duration_since_epoch: Duration, chan_descr: fmt::Arguments, logger: &Log
1269         ) where Log::Target: Logger {
1270                 let max_liquidity_msat = self.max_liquidity_msat().checked_sub(amount_msat).unwrap_or(0);
1271                 log_debug!(logger, "Subtracting {} from max liquidity of {} (setting it to {})", amount_msat, chan_descr, max_liquidity_msat);
1272                 self.set_max_liquidity_msat(max_liquidity_msat, duration_since_epoch);
1273                 self.update_history_buckets(amount_msat, duration_since_epoch);
1274         }
1275
1276         /// Updates the history buckets for this channel. Because the history buckets track what we now
1277         /// know about the channel's state *prior to our payment* (i.e. what we assume is "steady
1278         /// state"), we allow the caller to set an offset applied to our liquidity bounds which
1279         /// represents the amount of the successful payment we just made.
1280         fn update_history_buckets(&mut self, bucket_offset_msat: u64, duration_since_epoch: Duration) {
1281                 self.liquidity_history.track_datapoint(
1282                         *self.min_liquidity_offset_msat + bucket_offset_msat,
1283                         self.max_liquidity_offset_msat.saturating_sub(bucket_offset_msat),
1284                         self.capacity_msat,
1285                 );
1286                 *self.offset_history_last_updated = duration_since_epoch;
1287         }
1288
1289         /// Adjusts the lower bound of the channel liquidity balance in this direction.
1290         fn set_min_liquidity_msat(&mut self, amount_msat: u64, duration_since_epoch: Duration) {
1291                 *self.min_liquidity_offset_msat = amount_msat;
1292                 if amount_msat > self.max_liquidity_msat() {
1293                         *self.max_liquidity_offset_msat = 0;
1294                 }
1295                 *self.last_updated = duration_since_epoch;
1296         }
1297
1298         /// Adjusts the upper bound of the channel liquidity balance in this direction.
1299         fn set_max_liquidity_msat(&mut self, amount_msat: u64, duration_since_epoch: Duration) {
1300                 *self.max_liquidity_offset_msat = self.capacity_msat.checked_sub(amount_msat).unwrap_or(0);
1301                 if amount_msat < *self.min_liquidity_offset_msat {
1302                         *self.min_liquidity_offset_msat = 0;
1303                 }
1304                 *self.last_updated = duration_since_epoch;
1305         }
1306 }
1307
1308 impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreLookUp for ProbabilisticScorer<G, L> where L::Target: Logger {
1309         type ScoreParams = ProbabilisticScoringFeeParameters;
1310         fn channel_penalty_msat(
1311                 &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &ProbabilisticScoringFeeParameters
1312         ) -> u64 {
1313                 let (scid, target) = match candidate {
1314                         CandidateRouteHop::PublicHop { info, short_channel_id } => {
1315                                 (short_channel_id, info.target())
1316                         },
1317                         _ => return 0,
1318                 };
1319                 let source = candidate.source();
1320                 if let Some(penalty) = score_params.manual_node_penalties.get(&target) {
1321                         return *penalty;
1322                 }
1323
1324                 let base_penalty_msat = score_params.base_penalty_msat.saturating_add(
1325                         score_params.base_penalty_amount_multiplier_msat
1326                                 .saturating_mul(usage.amount_msat) / BASE_AMOUNT_PENALTY_DIVISOR);
1327
1328                 let mut anti_probing_penalty_msat = 0;
1329                 match usage.effective_capacity {
1330                         EffectiveCapacity::ExactLiquidity { liquidity_msat: amount_msat } |
1331                                 EffectiveCapacity::HintMaxHTLC { amount_msat } =>
1332                         {
1333                                 if usage.amount_msat > amount_msat {
1334                                         return u64::max_value();
1335                                 } else {
1336                                         return base_penalty_msat;
1337                                 }
1338                         },
1339                         EffectiveCapacity::Total { capacity_msat, htlc_maximum_msat } => {
1340                                 if htlc_maximum_msat >= capacity_msat/2 {
1341                                         anti_probing_penalty_msat = score_params.anti_probing_penalty_msat;
1342                                 }
1343                         },
1344                         _ => {},
1345                 }
1346
1347                 let amount_msat = usage.amount_msat.saturating_add(usage.inflight_htlc_msat);
1348                 let capacity_msat = usage.effective_capacity.as_msat();
1349                 self.channel_liquidities
1350                         .get(&scid)
1351                         .unwrap_or(&ChannelLiquidity::new(Duration::ZERO))
1352                         .as_directed(&source, &target, capacity_msat)
1353                         .penalty_msat(amount_msat, score_params)
1354                         .saturating_add(anti_probing_penalty_msat)
1355                         .saturating_add(base_penalty_msat)
1356         }
1357 }
1358
1359 impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreUpdate for ProbabilisticScorer<G, L> where L::Target: Logger {
1360         fn payment_path_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration) {
1361                 let amount_msat = path.final_value_msat();
1362                 log_trace!(self.logger, "Scoring path through to SCID {} as having failed at {} msat", short_channel_id, amount_msat);
1363                 let network_graph = self.network_graph.read_only();
1364                 for (hop_idx, hop) in path.hops.iter().enumerate() {
1365                         let target = NodeId::from_pubkey(&hop.pubkey);
1366                         let channel_directed_from_source = network_graph.channels()
1367                                 .get(&hop.short_channel_id)
1368                                 .and_then(|channel| channel.as_directed_to(&target));
1369
1370                         let at_failed_channel = hop.short_channel_id == short_channel_id;
1371                         if at_failed_channel && hop_idx == 0 {
1372                                 log_warn!(self.logger, "Payment failed at the first hop - we do not attempt to learn channel info in such cases as we can directly observe local state.\n\tBecause we know the local state, we should generally not see failures here - this may be an indication that your channel peer on channel {} is broken and you may wish to close the channel.", hop.short_channel_id);
1373                         }
1374
1375                         // Only score announced channels.
1376                         if let Some((channel, source)) = channel_directed_from_source {
1377                                 let capacity_msat = channel.effective_capacity().as_msat();
1378                                 if at_failed_channel {
1379                                         self.channel_liquidities
1380                                                 .entry(hop.short_channel_id)
1381                                                 .or_insert_with(|| ChannelLiquidity::new(duration_since_epoch))
1382                                                 .as_directed_mut(source, &target, capacity_msat)
1383                                                 .failed_at_channel(amount_msat, duration_since_epoch,
1384                                                         format_args!("SCID {}, towards {:?}", hop.short_channel_id, target), &self.logger);
1385                                 } else {
1386                                         self.channel_liquidities
1387                                                 .entry(hop.short_channel_id)
1388                                                 .or_insert_with(|| ChannelLiquidity::new(duration_since_epoch))
1389                                                 .as_directed_mut(source, &target, capacity_msat)
1390                                                 .failed_downstream(amount_msat, duration_since_epoch,
1391                                                         format_args!("SCID {}, towards {:?}", hop.short_channel_id, target), &self.logger);
1392                                 }
1393                         } else {
1394                                 log_debug!(self.logger, "Not able to penalize channel with SCID {} as we do not have graph info for it (likely a route-hint last-hop).",
1395                                         hop.short_channel_id);
1396                         }
1397                         if at_failed_channel { break; }
1398                 }
1399         }
1400
1401         fn payment_path_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
1402                 let amount_msat = path.final_value_msat();
1403                 log_trace!(self.logger, "Scoring path through SCID {} as having succeeded at {} msat.",
1404                         path.hops.split_last().map(|(hop, _)| hop.short_channel_id).unwrap_or(0), amount_msat);
1405                 let network_graph = self.network_graph.read_only();
1406                 for hop in &path.hops {
1407                         let target = NodeId::from_pubkey(&hop.pubkey);
1408                         let channel_directed_from_source = network_graph.channels()
1409                                 .get(&hop.short_channel_id)
1410                                 .and_then(|channel| channel.as_directed_to(&target));
1411
1412                         // Only score announced channels.
1413                         if let Some((channel, source)) = channel_directed_from_source {
1414                                 let capacity_msat = channel.effective_capacity().as_msat();
1415                                 self.channel_liquidities
1416                                         .entry(hop.short_channel_id)
1417                                         .or_insert_with(|| ChannelLiquidity::new(duration_since_epoch))
1418                                         .as_directed_mut(source, &target, capacity_msat)
1419                                         .successful(amount_msat, duration_since_epoch,
1420                                                 format_args!("SCID {}, towards {:?}", hop.short_channel_id, target), &self.logger);
1421                         } else {
1422                                 log_debug!(self.logger, "Not able to learn for channel with SCID {} as we do not have graph info for it (likely a route-hint last-hop).",
1423                                         hop.short_channel_id);
1424                         }
1425                 }
1426         }
1427
1428         fn probe_failed(&mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration) {
1429                 self.payment_path_failed(path, short_channel_id, duration_since_epoch)
1430         }
1431
1432         fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
1433                 self.payment_path_failed(path, u64::max_value(), duration_since_epoch)
1434         }
1435
1436         fn decay_liquidity_certainty(&mut self, duration_since_epoch: Duration) {
1437                 let decay_params = self.decay_params;
1438                 self.channel_liquidities.retain(|_scid, liquidity| {
1439                         liquidity.min_liquidity_offset_msat =
1440                                 liquidity.decayed_offset(liquidity.min_liquidity_offset_msat, duration_since_epoch, decay_params);
1441                         liquidity.max_liquidity_offset_msat =
1442                                 liquidity.decayed_offset(liquidity.max_liquidity_offset_msat, duration_since_epoch, decay_params);
1443                         liquidity.last_updated = duration_since_epoch;
1444
1445                         let elapsed_time =
1446                                 duration_since_epoch.saturating_sub(liquidity.offset_history_last_updated);
1447                         if elapsed_time > decay_params.historical_no_updates_half_life {
1448                                 let half_life = decay_params.historical_no_updates_half_life.as_secs_f64();
1449                                 if half_life != 0.0 {
1450                                         liquidity.liquidity_history.decay_buckets(elapsed_time.as_secs_f64() / half_life);
1451                                         liquidity.offset_history_last_updated = duration_since_epoch;
1452                                 }
1453                         }
1454                         liquidity.min_liquidity_offset_msat != 0 || liquidity.max_liquidity_offset_msat != 0 ||
1455                                 liquidity.liquidity_history.has_datapoints()
1456                 });
1457         }
1458 }
1459
1460 #[cfg(c_bindings)]
1461 impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> Score for ProbabilisticScorer<G, L>
1462 where L::Target: Logger {}
1463
1464 #[cfg(feature = "std")]
1465 #[inline]
1466 fn powf64(n: f64, exp: f64) -> f64 {
1467         n.powf(exp)
1468 }
1469 #[cfg(not(feature = "std"))]
1470 fn powf64(n: f64, exp: f64) -> f64 {
1471         libm::powf(n as f32, exp as f32) as f64
1472 }
1473
1474 mod bucketed_history {
1475         use super::*;
1476
1477         // Because liquidity is often skewed heavily in one direction, we store historical state
1478         // distribution in buckets of different size. For backwards compatibility, buckets of size 1/8th
1479         // must fit evenly into the buckets here.
1480         //
1481         // The smallest bucket is 2^-14th of the channel, for each of our 32 buckets here we define the
1482         // width of the bucket in 2^14'ths of the channel. This increases exponentially until we reach
1483         // a full 16th of the channel's capacity, which is reapeated a few times for backwards
1484         // compatibility. The four middle buckets represent full octiles of the channel's capacity.
1485         //
1486         // For a 1 BTC channel, this let's us differentiate between failures in the bottom 6k sats, or
1487         // between the 12,000th sat and 24,000th sat, while only needing to store and operate on 32
1488         // buckets in total.
1489
1490         const BUCKET_START_POS: [u16; 33] = [
1491                 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 3072, 4096, 6144, 8192, 10240, 12288,
1492                 13312, 14336, 15360, 15872, 16128, 16256, 16320, 16352, 16368, 16376, 16380, 16382, 16383, 16384,
1493         ];
1494
1495         const LEGACY_TO_BUCKET_RANGE: [(u8, u8); 8] = [
1496                 (0, 12), (12, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 20), (20, 32)
1497         ];
1498
1499         const POSITION_TICKS: u16 = 1 << 14;
1500
1501         fn pos_to_bucket(pos: u16) -> usize {
1502                 for bucket in 0..32 {
1503                         if pos < BUCKET_START_POS[bucket + 1] {
1504                                 return bucket;
1505                         }
1506                 }
1507                 debug_assert!(false);
1508                 return 32;
1509         }
1510
1511         #[cfg(test)]
1512         #[test]
1513         fn check_bucket_maps() {
1514                 const BUCKET_WIDTH_IN_16384S: [u16; 32] = [
1515                         1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024, 1024, 2048, 2048,
1516                         2048, 2048, 1024, 1024, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 1];
1517
1518                 let mut min_size_iter = 0;
1519                 let mut legacy_bucket_iter = 0;
1520                 for (bucket, width) in BUCKET_WIDTH_IN_16384S.iter().enumerate() {
1521                         assert_eq!(BUCKET_START_POS[bucket], min_size_iter);
1522                         for i in 0..*width {
1523                                 assert_eq!(pos_to_bucket(min_size_iter + i) as usize, bucket);
1524                         }
1525                         min_size_iter += *width;
1526                         if min_size_iter % (POSITION_TICKS / 8) == 0 {
1527                                 assert_eq!(LEGACY_TO_BUCKET_RANGE[legacy_bucket_iter].1 as usize, bucket + 1);
1528                                 if legacy_bucket_iter + 1 < 8 {
1529                                         assert_eq!(LEGACY_TO_BUCKET_RANGE[legacy_bucket_iter + 1].0 as usize, bucket + 1);
1530                                 }
1531                                 legacy_bucket_iter += 1;
1532                         }
1533                 }
1534                 assert_eq!(BUCKET_START_POS[32], POSITION_TICKS);
1535                 assert_eq!(min_size_iter, POSITION_TICKS);
1536         }
1537
1538         #[inline]
1539         fn amount_to_pos(amount_msat: u64, capacity_msat: u64) -> u16 {
1540                 let pos = if amount_msat < u64::max_value() / (POSITION_TICKS as u64) {
1541                         (amount_msat * (POSITION_TICKS as u64) / capacity_msat.saturating_add(1))
1542                                 .try_into().unwrap_or(POSITION_TICKS)
1543                 } else {
1544                         // Only use 128-bit arithmetic when multiplication will overflow to avoid 128-bit
1545                         // division. This branch should only be hit in fuzz testing since the amount would
1546                         // need to be over 2.88 million BTC in practice.
1547                         ((amount_msat as u128) * (POSITION_TICKS as u128)
1548                                         / (capacity_msat as u128).saturating_add(1))
1549                                 .try_into().unwrap_or(POSITION_TICKS)
1550                 };
1551                 // If we are running in a client that doesn't validate gossip, its possible for a channel's
1552                 // capacity to change due to a `channel_update` message which, if received while a payment
1553                 // is in-flight, could cause this to fail. Thus, we only assert in test.
1554                 #[cfg(test)]
1555                 debug_assert!(pos < POSITION_TICKS);
1556                 pos
1557         }
1558
1559         /// Prior to LDK 0.0.117 we used eight buckets which were split evenly across the either
1560         /// octiles. This was changed to use 32 buckets for accuracy reasons in 0.0.117, however we
1561         /// support reading the legacy values here for backwards compatibility.
1562         pub(super) struct LegacyHistoricalBucketRangeTracker {
1563                 buckets: [u16; 8],
1564         }
1565
1566         impl LegacyHistoricalBucketRangeTracker {
1567                 pub(crate) fn into_current(&self) -> HistoricalBucketRangeTracker {
1568                         let mut buckets = [0; 32];
1569                         for (idx, legacy_bucket) in self.buckets.iter().enumerate() {
1570                                 let mut new_val = *legacy_bucket;
1571                                 let (start, end) = LEGACY_TO_BUCKET_RANGE[idx];
1572                                 new_val /= (end - start) as u16;
1573                                 for i in start..end {
1574                                         buckets[i as usize] = new_val;
1575                                 }
1576                         }
1577                         HistoricalBucketRangeTracker { buckets }
1578                 }
1579         }
1580
1581         /// Tracks the historical state of a distribution as a weighted average of how much time was spent
1582         /// in each of 32 buckets.
1583         #[derive(Clone, Copy)]
1584         pub(super) struct HistoricalBucketRangeTracker {
1585                 buckets: [u16; 32],
1586         }
1587
1588         /// Buckets are stored in fixed point numbers with a 5 bit fractional part. Thus, the value
1589         /// "one" is 32, or this constant.
1590         pub const BUCKET_FIXED_POINT_ONE: u16 = 32;
1591
1592         impl HistoricalBucketRangeTracker {
1593                 pub(super) fn new() -> Self { Self { buckets: [0; 32] } }
1594                 fn track_datapoint(&mut self, liquidity_offset_msat: u64, capacity_msat: u64) {
1595                         // We have 32 leaky buckets for min and max liquidity. Each bucket tracks the amount of time
1596                         // we spend in each bucket as a 16-bit fixed-point number with a 5 bit fractional part.
1597                         //
1598                         // Each time we update our liquidity estimate, we add 32 (1.0 in our fixed-point system) to
1599                         // the buckets for the current min and max liquidity offset positions.
1600                         //
1601                         // We then decay each bucket by multiplying by 2047/2048 (avoiding dividing by a
1602                         // non-power-of-two). This ensures we can't actually overflow the u16 - when we get to
1603                         // 63,457 adding 32 and decaying by 2047/2048 leaves us back at 63,457.
1604                         //
1605                         // In total, this allows us to track data for the last 8,000 or so payments across a given
1606                         // channel.
1607                         //
1608                         // These constants are a balance - we try to fit in 2 bytes per bucket to reduce overhead,
1609                         // and need to balance having more bits in the decimal part (to ensure decay isn't too
1610                         // non-linear) with having too few bits in the mantissa, causing us to not store very many
1611                         // datapoints.
1612                         //
1613                         // The constants were picked experimentally, selecting a decay amount that restricts us
1614                         // from overflowing buckets without having to cap them manually.
1615
1616                         let pos: u16 = amount_to_pos(liquidity_offset_msat, capacity_msat);
1617                         if pos < POSITION_TICKS {
1618                                 for e in self.buckets.iter_mut() {
1619                                         *e = ((*e as u32) * 2047 / 2048) as u16;
1620                                 }
1621                                 let bucket = pos_to_bucket(pos);
1622                                 self.buckets[bucket] = self.buckets[bucket].saturating_add(BUCKET_FIXED_POINT_ONE);
1623                         }
1624                 }
1625         }
1626
1627         impl_writeable_tlv_based!(HistoricalBucketRangeTracker, { (0, buckets, required) });
1628         impl_writeable_tlv_based!(LegacyHistoricalBucketRangeTracker, { (0, buckets, required) });
1629
1630         #[derive(Clone, Copy)]
1631         pub(super) struct HistoricalLiquidityTracker {
1632                 min_liquidity_offset_history: HistoricalBucketRangeTracker,
1633                 max_liquidity_offset_history: HistoricalBucketRangeTracker,
1634         }
1635
1636         impl HistoricalLiquidityTracker {
1637                 pub(super) fn new() -> HistoricalLiquidityTracker {
1638                         HistoricalLiquidityTracker {
1639                                 min_liquidity_offset_history: HistoricalBucketRangeTracker::new(),
1640                                 max_liquidity_offset_history: HistoricalBucketRangeTracker::new(),
1641                         }
1642                 }
1643
1644                 pub(super) fn from_min_max(
1645                         min_liquidity_offset_history: HistoricalBucketRangeTracker,
1646                         max_liquidity_offset_history: HistoricalBucketRangeTracker,
1647                 ) -> HistoricalLiquidityTracker {
1648                         HistoricalLiquidityTracker {
1649                                 min_liquidity_offset_history,
1650                                 max_liquidity_offset_history,
1651                         }
1652                 }
1653
1654                 pub(super) fn has_datapoints(&self) -> bool {
1655                         self.min_liquidity_offset_history.buckets != [0; 32] ||
1656                                 self.max_liquidity_offset_history.buckets != [0; 32]
1657                 }
1658
1659                 pub(super) fn decay_buckets(&mut self, half_lives: f64) {
1660                         let divisor = powf64(2048.0, half_lives) as u64;
1661                         for bucket in self.min_liquidity_offset_history.buckets.iter_mut() {
1662                                 *bucket = ((*bucket as u64) * 1024 / divisor) as u16;
1663                         }
1664                         for bucket in self.max_liquidity_offset_history.buckets.iter_mut() {
1665                                 *bucket = ((*bucket as u64) * 1024 / divisor) as u16;
1666                         }
1667                 }
1668
1669                 pub(super) fn writeable_min_offset_history(&self) -> &HistoricalBucketRangeTracker {
1670                         &self.min_liquidity_offset_history
1671                 }
1672
1673                 pub(super) fn writeable_max_offset_history(&self) -> &HistoricalBucketRangeTracker {
1674                         &self.max_liquidity_offset_history
1675                 }
1676
1677                 pub(super) fn as_directed<'a>(&'a self, source_less_than_target: bool)
1678                 -> HistoricalMinMaxBuckets<&'a HistoricalBucketRangeTracker> {
1679                         let (min_liquidity_offset_history, max_liquidity_offset_history) =
1680                                 if source_less_than_target {
1681                                         (&self.min_liquidity_offset_history, &self.max_liquidity_offset_history)
1682                                 } else {
1683                                         (&self.max_liquidity_offset_history, &self.min_liquidity_offset_history)
1684                                 };
1685                         HistoricalMinMaxBuckets { min_liquidity_offset_history, max_liquidity_offset_history }
1686                 }
1687
1688                 pub(super) fn as_directed_mut<'a>(&'a mut self, source_less_than_target: bool)
1689                 -> HistoricalMinMaxBuckets<&'a mut HistoricalBucketRangeTracker> {
1690                         let (min_liquidity_offset_history, max_liquidity_offset_history) =
1691                                 if source_less_than_target {
1692                                         (&mut self.min_liquidity_offset_history, &mut self.max_liquidity_offset_history)
1693                                 } else {
1694                                         (&mut self.max_liquidity_offset_history, &mut self.min_liquidity_offset_history)
1695                                 };
1696                         HistoricalMinMaxBuckets { min_liquidity_offset_history, max_liquidity_offset_history }
1697                 }
1698         }
1699
1700         /// A set of buckets representing the history of where we've seen the minimum- and maximum-
1701         /// liquidity bounds for a given channel.
1702         pub(super) struct HistoricalMinMaxBuckets<D: Deref<Target = HistoricalBucketRangeTracker>> {
1703                 /// Buckets tracking where and how often we've seen the minimum liquidity bound for a
1704                 /// channel.
1705                 min_liquidity_offset_history: D,
1706                 /// Buckets tracking where and how often we've seen the maximum liquidity bound for a
1707                 /// channel.
1708                 max_liquidity_offset_history: D,
1709         }
1710
1711         impl<D: DerefMut<Target = HistoricalBucketRangeTracker>> HistoricalMinMaxBuckets<D> {
1712                 pub(super) fn track_datapoint(
1713                         &mut self, min_offset_msat: u64, max_offset_msat: u64, capacity_msat: u64,
1714                 ) {
1715                         self.min_liquidity_offset_history.track_datapoint(min_offset_msat, capacity_msat);
1716                         self.max_liquidity_offset_history.track_datapoint(max_offset_msat, capacity_msat);
1717                 }
1718         }
1719
1720         impl<D: Deref<Target = HistoricalBucketRangeTracker>> HistoricalMinMaxBuckets<D> {
1721                 pub(super) fn min_liquidity_offset_history_buckets(&self) -> &[u16; 32] {
1722                         &self.min_liquidity_offset_history.buckets
1723                 }
1724
1725                 pub(super) fn max_liquidity_offset_history_buckets(&self) -> &[u16; 32] {
1726                         &self.max_liquidity_offset_history.buckets
1727                 }
1728
1729                 #[inline]
1730                 pub(super) fn calculate_success_probability_times_billion(
1731                         &self, params: &ProbabilisticScoringFeeParameters, amount_msat: u64,
1732                         capacity_msat: u64
1733                 ) -> Option<u64> {
1734                         // If historical penalties are enabled, we try to calculate a probability of success
1735                         // given our historical distribution of min- and max-liquidity bounds in a channel.
1736                         // To do so, we walk the set of historical liquidity bucket (min, max) combinations
1737                         // (where min_idx < max_idx, as having a minimum above our maximum is an invalid
1738                         // state). For each pair, we calculate the probability as if the bucket's corresponding
1739                         // min- and max- liquidity bounds were our current liquidity bounds and then multiply
1740                         // that probability by the weight of the selected buckets.
1741                         let payment_pos = amount_to_pos(amount_msat, capacity_msat);
1742                         if payment_pos >= POSITION_TICKS { return None; }
1743
1744                         let mut total_valid_points_tracked = 0;
1745                         for (min_idx, min_bucket) in self.min_liquidity_offset_history.buckets.iter().enumerate() {
1746                                 for max_bucket in self.max_liquidity_offset_history.buckets.iter().take(32 - min_idx) {
1747                                         total_valid_points_tracked += (*min_bucket as u64) * (*max_bucket as u64);
1748                                 }
1749                         }
1750
1751                         // If the total valid points is smaller than 1.0 (i.e. 32 in our fixed-point scheme),
1752                         // treat it as if we were fully decayed.
1753                         const FULLY_DECAYED: u16 = BUCKET_FIXED_POINT_ONE * BUCKET_FIXED_POINT_ONE;
1754                         if total_valid_points_tracked < FULLY_DECAYED.into() {
1755                                 return None;
1756                         }
1757
1758                         let mut cumulative_success_prob_times_billion = 0;
1759                         // Special-case the 0th min bucket - it generally means we failed a payment, so only
1760                         // consider the highest (i.e. largest-offset-from-max-capacity) max bucket for all
1761                         // points against the 0th min bucket. This avoids the case where we fail to route
1762                         // increasingly lower values over a channel, but treat each failure as a separate
1763                         // datapoint, many of which may have relatively high maximum-available-liquidity
1764                         // values, which will result in us thinking we have some nontrivial probability of
1765                         // routing up to that amount.
1766                         if self.min_liquidity_offset_history.buckets[0] != 0 {
1767                                 let mut highest_max_bucket_with_points = 0; // The highest max-bucket with any data
1768                                 let mut total_max_points = 0; // Total points in max-buckets to consider
1769                                 for (max_idx, max_bucket) in self.max_liquidity_offset_history.buckets.iter().enumerate() {
1770                                         if *max_bucket >= BUCKET_FIXED_POINT_ONE {
1771                                                 highest_max_bucket_with_points = cmp::max(highest_max_bucket_with_points, max_idx);
1772                                         }
1773                                         total_max_points += *max_bucket as u64;
1774                                 }
1775                                 let max_bucket_end_pos = BUCKET_START_POS[32 - highest_max_bucket_with_points] - 1;
1776                                 if payment_pos < max_bucket_end_pos {
1777                                         let (numerator, denominator) = success_probability(payment_pos as u64, 0,
1778                                                 max_bucket_end_pos as u64, POSITION_TICKS as u64 - 1, params, true);
1779                                         let bucket_prob_times_billion =
1780                                                 (self.min_liquidity_offset_history.buckets[0] as u64) * total_max_points
1781                                                         * 1024 * 1024 * 1024 / total_valid_points_tracked;
1782                                         cumulative_success_prob_times_billion += bucket_prob_times_billion *
1783                                                 numerator / denominator;
1784                                 }
1785                         }
1786
1787                         for (min_idx, min_bucket) in self.min_liquidity_offset_history.buckets.iter().enumerate().skip(1) {
1788                                 let min_bucket_start_pos = BUCKET_START_POS[min_idx];
1789                                 for (max_idx, max_bucket) in self.max_liquidity_offset_history.buckets.iter().enumerate().take(32 - min_idx) {
1790                                         let max_bucket_end_pos = BUCKET_START_POS[32 - max_idx] - 1;
1791                                         // Note that this multiply can only barely not overflow - two 16 bit ints plus
1792                                         // 30 bits is 62 bits.
1793                                         let bucket_prob_times_billion = (*min_bucket as u64) * (*max_bucket as u64)
1794                                                 * 1024 * 1024 * 1024 / total_valid_points_tracked;
1795                                         if payment_pos >= max_bucket_end_pos {
1796                                                 // Success probability 0, the payment amount may be above the max liquidity
1797                                                 break;
1798                                         } else if payment_pos < min_bucket_start_pos {
1799                                                 cumulative_success_prob_times_billion += bucket_prob_times_billion;
1800                                         } else {
1801                                                 let (numerator, denominator) = success_probability(payment_pos as u64,
1802                                                         min_bucket_start_pos as u64, max_bucket_end_pos as u64,
1803                                                         POSITION_TICKS as u64 - 1, params, true);
1804                                                 cumulative_success_prob_times_billion += bucket_prob_times_billion *
1805                                                         numerator / denominator;
1806                                         }
1807                                 }
1808                         }
1809
1810                         Some(cumulative_success_prob_times_billion)
1811                 }
1812         }
1813 }
1814 use bucketed_history::{LegacyHistoricalBucketRangeTracker, HistoricalBucketRangeTracker, HistoricalMinMaxBuckets, HistoricalLiquidityTracker};
1815
1816 impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> Writeable for ProbabilisticScorer<G, L> where L::Target: Logger {
1817         #[inline]
1818         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
1819                 write_tlv_fields!(w, {
1820                         (0, self.channel_liquidities, required),
1821                 });
1822                 Ok(())
1823         }
1824 }
1825
1826 impl<G: Deref<Target = NetworkGraph<L>>, L: Deref>
1827 ReadableArgs<(ProbabilisticScoringDecayParameters, G, L)> for ProbabilisticScorer<G, L> where L::Target: Logger {
1828         #[inline]
1829         fn read<R: Read>(
1830                 r: &mut R, args: (ProbabilisticScoringDecayParameters, G, L)
1831         ) -> Result<Self, DecodeError> {
1832                 let (decay_params, network_graph, logger) = args;
1833                 let mut channel_liquidities = HashMap::new();
1834                 read_tlv_fields!(r, {
1835                         (0, channel_liquidities, required),
1836                 });
1837                 Ok(Self {
1838                         decay_params,
1839                         network_graph,
1840                         logger,
1841                         channel_liquidities,
1842                 })
1843         }
1844 }
1845
1846 impl Writeable for ChannelLiquidity {
1847         #[inline]
1848         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
1849                 write_tlv_fields!(w, {
1850                         (0, self.min_liquidity_offset_msat, required),
1851                         // 1 was the min_liquidity_offset_history in octile form
1852                         (2, self.max_liquidity_offset_msat, required),
1853                         // 3 was the max_liquidity_offset_history in octile form
1854                         (4, self.last_updated, required),
1855                         (5, self.liquidity_history.writeable_min_offset_history(), required),
1856                         (7, self.liquidity_history.writeable_max_offset_history(), required),
1857                         (9, self.offset_history_last_updated, required),
1858                 });
1859                 Ok(())
1860         }
1861 }
1862
1863 impl Readable for ChannelLiquidity {
1864         #[inline]
1865         fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
1866                 let mut min_liquidity_offset_msat = 0;
1867                 let mut max_liquidity_offset_msat = 0;
1868                 let mut legacy_min_liq_offset_history: Option<LegacyHistoricalBucketRangeTracker> = None;
1869                 let mut legacy_max_liq_offset_history: Option<LegacyHistoricalBucketRangeTracker> = None;
1870                 let mut min_liquidity_offset_history: Option<HistoricalBucketRangeTracker> = None;
1871                 let mut max_liquidity_offset_history: Option<HistoricalBucketRangeTracker> = None;
1872                 let mut last_updated = Duration::from_secs(0);
1873                 let mut offset_history_last_updated = None;
1874                 read_tlv_fields!(r, {
1875                         (0, min_liquidity_offset_msat, required),
1876                         (1, legacy_min_liq_offset_history, option),
1877                         (2, max_liquidity_offset_msat, required),
1878                         (3, legacy_max_liq_offset_history, option),
1879                         (4, last_updated, required),
1880                         (5, min_liquidity_offset_history, option),
1881                         (7, max_liquidity_offset_history, option),
1882                         (9, offset_history_last_updated, option),
1883                 });
1884
1885                 if min_liquidity_offset_history.is_none() {
1886                         if let Some(legacy_buckets) = legacy_min_liq_offset_history {
1887                                 min_liquidity_offset_history = Some(legacy_buckets.into_current());
1888                         } else {
1889                                 min_liquidity_offset_history = Some(HistoricalBucketRangeTracker::new());
1890                         }
1891                 }
1892                 if max_liquidity_offset_history.is_none() {
1893                         if let Some(legacy_buckets) = legacy_max_liq_offset_history {
1894                                 max_liquidity_offset_history = Some(legacy_buckets.into_current());
1895                         } else {
1896                                 max_liquidity_offset_history = Some(HistoricalBucketRangeTracker::new());
1897                         }
1898                 }
1899                 Ok(Self {
1900                         min_liquidity_offset_msat,
1901                         max_liquidity_offset_msat,
1902                         liquidity_history: HistoricalLiquidityTracker::from_min_max(
1903                                 min_liquidity_offset_history.unwrap(), max_liquidity_offset_history.unwrap()
1904                         ),
1905                         last_updated,
1906                         offset_history_last_updated: offset_history_last_updated.unwrap_or(last_updated),
1907                 })
1908         }
1909 }
1910
1911 #[cfg(test)]
1912 mod tests {
1913         use super::{ChannelLiquidity, HistoricalLiquidityTracker, ProbabilisticScoringFeeParameters, ProbabilisticScoringDecayParameters, ProbabilisticScorer};
1914         use crate::blinded_path::{BlindedHop, BlindedPath};
1915         use crate::util::config::UserConfig;
1916
1917         use crate::ln::channelmanager;
1918         use crate::ln::msgs::{ChannelAnnouncement, ChannelUpdate, UnsignedChannelAnnouncement, UnsignedChannelUpdate};
1919         use crate::routing::gossip::{EffectiveCapacity, NetworkGraph, NodeId};
1920         use crate::routing::router::{BlindedTail, Path, RouteHop, CandidateRouteHop};
1921         use crate::routing::scoring::{ChannelUsage, ScoreLookUp, ScoreUpdate};
1922         use crate::util::ser::{ReadableArgs, Writeable};
1923         use crate::util::test_utils::{self, TestLogger};
1924
1925         use bitcoin::blockdata::constants::ChainHash;
1926         use bitcoin::hashes::Hash;
1927         use bitcoin::hashes::sha256d::Hash as Sha256dHash;
1928         use bitcoin::network::constants::Network;
1929         use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
1930         use core::time::Duration;
1931         use crate::io;
1932
1933         fn source_privkey() -> SecretKey {
1934                 SecretKey::from_slice(&[42; 32]).unwrap()
1935         }
1936
1937         fn target_privkey() -> SecretKey {
1938                 SecretKey::from_slice(&[43; 32]).unwrap()
1939         }
1940
1941         fn source_pubkey() -> PublicKey {
1942                 let secp_ctx = Secp256k1::new();
1943                 PublicKey::from_secret_key(&secp_ctx, &source_privkey())
1944         }
1945
1946         fn target_pubkey() -> PublicKey {
1947                 let secp_ctx = Secp256k1::new();
1948                 PublicKey::from_secret_key(&secp_ctx, &target_privkey())
1949         }
1950
1951         fn source_node_id() -> NodeId {
1952                 NodeId::from_pubkey(&source_pubkey())
1953         }
1954
1955         fn target_node_id() -> NodeId {
1956                 NodeId::from_pubkey(&target_pubkey())
1957         }
1958
1959         // `ProbabilisticScorer` tests
1960
1961         fn sender_privkey() -> SecretKey {
1962                 SecretKey::from_slice(&[41; 32]).unwrap()
1963         }
1964
1965         fn recipient_privkey() -> SecretKey {
1966                 SecretKey::from_slice(&[45; 32]).unwrap()
1967         }
1968
1969         fn sender_pubkey() -> PublicKey {
1970                 let secp_ctx = Secp256k1::new();
1971                 PublicKey::from_secret_key(&secp_ctx, &sender_privkey())
1972         }
1973
1974         fn recipient_pubkey() -> PublicKey {
1975                 let secp_ctx = Secp256k1::new();
1976                 PublicKey::from_secret_key(&secp_ctx, &recipient_privkey())
1977         }
1978
1979         fn recipient_node_id() -> NodeId {
1980                 NodeId::from_pubkey(&recipient_pubkey())
1981         }
1982
1983         fn network_graph(logger: &TestLogger) -> NetworkGraph<&TestLogger> {
1984                 let mut network_graph = NetworkGraph::new(Network::Testnet, logger);
1985                 add_channel(&mut network_graph, 42, source_privkey(), target_privkey());
1986                 add_channel(&mut network_graph, 43, target_privkey(), recipient_privkey());
1987
1988                 network_graph
1989         }
1990
1991         fn add_channel(
1992                 network_graph: &mut NetworkGraph<&TestLogger>, short_channel_id: u64, node_1_key: SecretKey,
1993                 node_2_key: SecretKey
1994         ) {
1995                 let genesis_hash = ChainHash::using_genesis_block(Network::Testnet);
1996                 let node_1_secret = &SecretKey::from_slice(&[39; 32]).unwrap();
1997                 let node_2_secret = &SecretKey::from_slice(&[40; 32]).unwrap();
1998                 let secp_ctx = Secp256k1::new();
1999                 let unsigned_announcement = UnsignedChannelAnnouncement {
2000                         features: channelmanager::provided_channel_features(&UserConfig::default()),
2001                         chain_hash: genesis_hash,
2002                         short_channel_id,
2003                         node_id_1: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_1_key)),
2004                         node_id_2: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_2_key)),
2005                         bitcoin_key_1: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_1_secret)),
2006                         bitcoin_key_2: NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, &node_2_secret)),
2007                         excess_data: Vec::new(),
2008                 };
2009                 let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
2010                 let signed_announcement = ChannelAnnouncement {
2011                         node_signature_1: secp_ctx.sign_ecdsa(&msghash, &node_1_key),
2012                         node_signature_2: secp_ctx.sign_ecdsa(&msghash, &node_2_key),
2013                         bitcoin_signature_1: secp_ctx.sign_ecdsa(&msghash, &node_1_secret),
2014                         bitcoin_signature_2: secp_ctx.sign_ecdsa(&msghash, &node_2_secret),
2015                         contents: unsigned_announcement,
2016                 };
2017                 let chain_source: Option<&crate::util::test_utils::TestChainSource> = None;
2018                 network_graph.update_channel_from_announcement(
2019                         &signed_announcement, &chain_source).unwrap();
2020                 update_channel(network_graph, short_channel_id, node_1_key, 0, 1_000, 100);
2021                 update_channel(network_graph, short_channel_id, node_2_key, 1, 0, 100);
2022         }
2023
2024         fn update_channel(
2025                 network_graph: &mut NetworkGraph<&TestLogger>, short_channel_id: u64, node_key: SecretKey,
2026                 flags: u8, htlc_maximum_msat: u64, timestamp: u32,
2027         ) {
2028                 let genesis_hash = ChainHash::using_genesis_block(Network::Testnet);
2029                 let secp_ctx = Secp256k1::new();
2030                 let unsigned_update = UnsignedChannelUpdate {
2031                         chain_hash: genesis_hash,
2032                         short_channel_id,
2033                         timestamp,
2034                         flags,
2035                         cltv_expiry_delta: 18,
2036                         htlc_minimum_msat: 0,
2037                         htlc_maximum_msat,
2038                         fee_base_msat: 1,
2039                         fee_proportional_millionths: 0,
2040                         excess_data: Vec::new(),
2041                 };
2042                 let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_update.encode()[..])[..]);
2043                 let signed_update = ChannelUpdate {
2044                         signature: secp_ctx.sign_ecdsa(&msghash, &node_key),
2045                         contents: unsigned_update,
2046                 };
2047                 network_graph.update_channel(&signed_update).unwrap();
2048         }
2049
2050         fn path_hop(pubkey: PublicKey, short_channel_id: u64, fee_msat: u64) -> RouteHop {
2051                 let config = UserConfig::default();
2052                 RouteHop {
2053                         pubkey,
2054                         node_features: channelmanager::provided_node_features(&config),
2055                         short_channel_id,
2056                         channel_features: channelmanager::provided_channel_features(&config),
2057                         fee_msat,
2058                         cltv_expiry_delta: 18,
2059                         maybe_announced_channel: true,
2060                 }
2061         }
2062
2063         fn payment_path_for_amount(amount_msat: u64) -> Path {
2064                 Path {
2065                         hops: vec![
2066                                 path_hop(source_pubkey(), 41, 1),
2067                                 path_hop(target_pubkey(), 42, 2),
2068                                 path_hop(recipient_pubkey(), 43, amount_msat),
2069                         ], blinded_tail: None,
2070                 }
2071         }
2072
2073         #[test]
2074         fn liquidity_bounds_directed_from_lowest_node_id() {
2075                 let logger = TestLogger::new();
2076                 let last_updated = Duration::ZERO;
2077                 let offset_history_last_updated = Duration::ZERO;
2078                 let network_graph = network_graph(&logger);
2079                 let decay_params = ProbabilisticScoringDecayParameters::default();
2080                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger)
2081                         .with_channel(42,
2082                                 ChannelLiquidity {
2083                                         min_liquidity_offset_msat: 700, max_liquidity_offset_msat: 100,
2084                                         last_updated, offset_history_last_updated,
2085                                         liquidity_history: HistoricalLiquidityTracker::new(),
2086                                 })
2087                         .with_channel(43,
2088                                 ChannelLiquidity {
2089                                         min_liquidity_offset_msat: 700, max_liquidity_offset_msat: 100,
2090                                         last_updated, offset_history_last_updated,
2091                                         liquidity_history: HistoricalLiquidityTracker::new(),
2092                                 });
2093                 let source = source_node_id();
2094                 let target = target_node_id();
2095                 let recipient = recipient_node_id();
2096                 assert!(source > target);
2097                 assert!(target < recipient);
2098
2099                 // Update minimum liquidity.
2100
2101                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2102                         .as_directed(&source, &target, 1_000);
2103                 assert_eq!(liquidity.min_liquidity_msat(), 100);
2104                 assert_eq!(liquidity.max_liquidity_msat(), 300);
2105
2106                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2107                         .as_directed(&target, &source, 1_000);
2108                 assert_eq!(liquidity.min_liquidity_msat(), 700);
2109                 assert_eq!(liquidity.max_liquidity_msat(), 900);
2110
2111                 scorer.channel_liquidities.get_mut(&42).unwrap()
2112                         .as_directed_mut(&source, &target, 1_000)
2113                         .set_min_liquidity_msat(200, Duration::ZERO);
2114
2115                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2116                         .as_directed(&source, &target, 1_000);
2117                 assert_eq!(liquidity.min_liquidity_msat(), 200);
2118                 assert_eq!(liquidity.max_liquidity_msat(), 300);
2119
2120                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2121                         .as_directed(&target, &source, 1_000);
2122                 assert_eq!(liquidity.min_liquidity_msat(), 700);
2123                 assert_eq!(liquidity.max_liquidity_msat(), 800);
2124
2125                 // Update maximum liquidity.
2126
2127                 let liquidity = scorer.channel_liquidities.get(&43).unwrap()
2128                         .as_directed(&target, &recipient, 1_000);
2129                 assert_eq!(liquidity.min_liquidity_msat(), 700);
2130                 assert_eq!(liquidity.max_liquidity_msat(), 900);
2131
2132                 let liquidity = scorer.channel_liquidities.get(&43).unwrap()
2133                         .as_directed(&recipient, &target, 1_000);
2134                 assert_eq!(liquidity.min_liquidity_msat(), 100);
2135                 assert_eq!(liquidity.max_liquidity_msat(), 300);
2136
2137                 scorer.channel_liquidities.get_mut(&43).unwrap()
2138                         .as_directed_mut(&target, &recipient, 1_000)
2139                         .set_max_liquidity_msat(200, Duration::ZERO);
2140
2141                 let liquidity = scorer.channel_liquidities.get(&43).unwrap()
2142                         .as_directed(&target, &recipient, 1_000);
2143                 assert_eq!(liquidity.min_liquidity_msat(), 0);
2144                 assert_eq!(liquidity.max_liquidity_msat(), 200);
2145
2146                 let liquidity = scorer.channel_liquidities.get(&43).unwrap()
2147                         .as_directed(&recipient, &target, 1_000);
2148                 assert_eq!(liquidity.min_liquidity_msat(), 800);
2149                 assert_eq!(liquidity.max_liquidity_msat(), 1000);
2150         }
2151
2152         #[test]
2153         fn resets_liquidity_upper_bound_when_crossed_by_lower_bound() {
2154                 let logger = TestLogger::new();
2155                 let last_updated = Duration::ZERO;
2156                 let offset_history_last_updated = Duration::ZERO;
2157                 let network_graph = network_graph(&logger);
2158                 let decay_params = ProbabilisticScoringDecayParameters::default();
2159                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger)
2160                         .with_channel(42,
2161                                 ChannelLiquidity {
2162                                         min_liquidity_offset_msat: 200, max_liquidity_offset_msat: 400,
2163                                         last_updated, offset_history_last_updated,
2164                                         liquidity_history: HistoricalLiquidityTracker::new(),
2165                                 });
2166                 let source = source_node_id();
2167                 let target = target_node_id();
2168                 assert!(source > target);
2169
2170                 // Check initial bounds.
2171                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2172                         .as_directed(&source, &target, 1_000);
2173                 assert_eq!(liquidity.min_liquidity_msat(), 400);
2174                 assert_eq!(liquidity.max_liquidity_msat(), 800);
2175
2176                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2177                         .as_directed(&target, &source, 1_000);
2178                 assert_eq!(liquidity.min_liquidity_msat(), 200);
2179                 assert_eq!(liquidity.max_liquidity_msat(), 600);
2180
2181                 // Reset from source to target.
2182                 scorer.channel_liquidities.get_mut(&42).unwrap()
2183                         .as_directed_mut(&source, &target, 1_000)
2184                         .set_min_liquidity_msat(900, Duration::ZERO);
2185
2186                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2187                         .as_directed(&source, &target, 1_000);
2188                 assert_eq!(liquidity.min_liquidity_msat(), 900);
2189                 assert_eq!(liquidity.max_liquidity_msat(), 1_000);
2190
2191                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2192                         .as_directed(&target, &source, 1_000);
2193                 assert_eq!(liquidity.min_liquidity_msat(), 0);
2194                 assert_eq!(liquidity.max_liquidity_msat(), 100);
2195
2196                 // Reset from target to source.
2197                 scorer.channel_liquidities.get_mut(&42).unwrap()
2198                         .as_directed_mut(&target, &source, 1_000)
2199                         .set_min_liquidity_msat(400, Duration::ZERO);
2200
2201                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2202                         .as_directed(&source, &target, 1_000);
2203                 assert_eq!(liquidity.min_liquidity_msat(), 0);
2204                 assert_eq!(liquidity.max_liquidity_msat(), 600);
2205
2206                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2207                         .as_directed(&target, &source, 1_000);
2208                 assert_eq!(liquidity.min_liquidity_msat(), 400);
2209                 assert_eq!(liquidity.max_liquidity_msat(), 1_000);
2210         }
2211
2212         #[test]
2213         fn resets_liquidity_lower_bound_when_crossed_by_upper_bound() {
2214                 let logger = TestLogger::new();
2215                 let last_updated = Duration::ZERO;
2216                 let offset_history_last_updated = Duration::ZERO;
2217                 let network_graph = network_graph(&logger);
2218                 let decay_params = ProbabilisticScoringDecayParameters::default();
2219                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger)
2220                         .with_channel(42,
2221                                 ChannelLiquidity {
2222                                         min_liquidity_offset_msat: 200, max_liquidity_offset_msat: 400,
2223                                         last_updated, offset_history_last_updated,
2224                                         liquidity_history: HistoricalLiquidityTracker::new(),
2225                                 });
2226                 let source = source_node_id();
2227                 let target = target_node_id();
2228                 assert!(source > target);
2229
2230                 // Check initial bounds.
2231                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2232                         .as_directed(&source, &target, 1_000);
2233                 assert_eq!(liquidity.min_liquidity_msat(), 400);
2234                 assert_eq!(liquidity.max_liquidity_msat(), 800);
2235
2236                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2237                         .as_directed(&target, &source, 1_000);
2238                 assert_eq!(liquidity.min_liquidity_msat(), 200);
2239                 assert_eq!(liquidity.max_liquidity_msat(), 600);
2240
2241                 // Reset from source to target.
2242                 scorer.channel_liquidities.get_mut(&42).unwrap()
2243                         .as_directed_mut(&source, &target, 1_000)
2244                         .set_max_liquidity_msat(300, Duration::ZERO);
2245
2246                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2247                         .as_directed(&source, &target, 1_000);
2248                 assert_eq!(liquidity.min_liquidity_msat(), 0);
2249                 assert_eq!(liquidity.max_liquidity_msat(), 300);
2250
2251                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2252                         .as_directed(&target, &source, 1_000);
2253                 assert_eq!(liquidity.min_liquidity_msat(), 700);
2254                 assert_eq!(liquidity.max_liquidity_msat(), 1_000);
2255
2256                 // Reset from target to source.
2257                 scorer.channel_liquidities.get_mut(&42).unwrap()
2258                         .as_directed_mut(&target, &source, 1_000)
2259                         .set_max_liquidity_msat(600, Duration::ZERO);
2260
2261                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2262                         .as_directed(&source, &target, 1_000);
2263                 assert_eq!(liquidity.min_liquidity_msat(), 400);
2264                 assert_eq!(liquidity.max_liquidity_msat(), 1_000);
2265
2266                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
2267                         .as_directed(&target, &source, 1_000);
2268                 assert_eq!(liquidity.min_liquidity_msat(), 0);
2269                 assert_eq!(liquidity.max_liquidity_msat(), 600);
2270         }
2271
2272         #[test]
2273         fn increased_penalty_nearing_liquidity_upper_bound() {
2274                 let logger = TestLogger::new();
2275                 let network_graph = network_graph(&logger);
2276                 let params = ProbabilisticScoringFeeParameters {
2277                         liquidity_penalty_multiplier_msat: 1_000,
2278                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2279                 };
2280                 let decay_params = ProbabilisticScoringDecayParameters::default();
2281                 let scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
2282                 let source = source_node_id();
2283
2284                 let usage = ChannelUsage {
2285                         amount_msat: 1_024,
2286                         inflight_htlc_msat: 0,
2287                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024_000, htlc_maximum_msat: 1_000 },
2288                 };
2289                 let network_graph = network_graph.read_only();
2290                 let channel = network_graph.channel(42).unwrap();
2291                 let (info, _) = channel.as_directed_from(&source).unwrap();
2292                 let candidate = CandidateRouteHop::PublicHop {
2293                         info,
2294                         short_channel_id: 42,
2295                 };
2296                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2297                 let usage = ChannelUsage { amount_msat: 10_240, ..usage };
2298                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2299                 let usage = ChannelUsage { amount_msat: 102_400, ..usage };
2300                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 47);
2301                 let usage = ChannelUsage { amount_msat: 1_023_999, ..usage };
2302                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 2_000);
2303
2304                 let usage = ChannelUsage {
2305                         amount_msat: 128,
2306                         inflight_htlc_msat: 0,
2307                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_000 },
2308                 };
2309                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 58);
2310                 let usage = ChannelUsage { amount_msat: 256, ..usage };
2311                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 125);
2312                 let usage = ChannelUsage { amount_msat: 374, ..usage };
2313                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 198);
2314                 let usage = ChannelUsage { amount_msat: 512, ..usage };
2315                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2316                 let usage = ChannelUsage { amount_msat: 640, ..usage };
2317                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 425);
2318                 let usage = ChannelUsage { amount_msat: 768, ..usage };
2319                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 602);
2320                 let usage = ChannelUsage { amount_msat: 896, ..usage };
2321                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 902);
2322         }
2323
2324         #[test]
2325         fn constant_penalty_outside_liquidity_bounds() {
2326                 let logger = TestLogger::new();
2327                 let last_updated = Duration::ZERO;
2328                 let offset_history_last_updated = Duration::ZERO;
2329                 let network_graph = network_graph(&logger);
2330                 let params = ProbabilisticScoringFeeParameters {
2331                         liquidity_penalty_multiplier_msat: 1_000,
2332                         considered_impossible_penalty_msat: u64::max_value(),
2333                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2334                 };
2335                 let decay_params = ProbabilisticScoringDecayParameters {
2336                         ..ProbabilisticScoringDecayParameters::zero_penalty()
2337                 };
2338                 let scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger)
2339                         .with_channel(42,
2340                                 ChannelLiquidity {
2341                                         min_liquidity_offset_msat: 40, max_liquidity_offset_msat: 40,
2342                                         last_updated, offset_history_last_updated,
2343                                         liquidity_history: HistoricalLiquidityTracker::new(),
2344                                 });
2345                 let source = source_node_id();
2346
2347                 let usage = ChannelUsage {
2348                         amount_msat: 39,
2349                         inflight_htlc_msat: 0,
2350                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 100, htlc_maximum_msat: 1_000 },
2351                 };
2352                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2353                 let (info, _) = channel.as_directed_from(&source).unwrap();
2354                 let candidate = CandidateRouteHop::PublicHop {
2355                         info,
2356                         short_channel_id: 42,
2357                 };
2358                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2359                 let usage = ChannelUsage { amount_msat: 50, ..usage };
2360                 assert_ne!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2361                 assert_ne!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2362                 let usage = ChannelUsage { amount_msat: 61, ..usage };
2363                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2364         }
2365
2366         #[test]
2367         fn does_not_further_penalize_own_channel() {
2368                 let logger = TestLogger::new();
2369                 let network_graph = network_graph(&logger);
2370                 let params = ProbabilisticScoringFeeParameters {
2371                         liquidity_penalty_multiplier_msat: 1_000,
2372                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2373                 };
2374                 let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2375                 let source = source_node_id();
2376                 let usage = ChannelUsage {
2377                         amount_msat: 500,
2378                         inflight_htlc_msat: 0,
2379                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
2380                 };
2381                 let failed_path = payment_path_for_amount(500);
2382                 let successful_path = payment_path_for_amount(200);
2383                 let channel = &network_graph.read_only().channel(42).unwrap().to_owned();
2384                 let (info, _) = channel.as_directed_from(&source).unwrap();
2385                 let candidate = CandidateRouteHop::PublicHop {
2386                         info,
2387                         short_channel_id: 41,
2388                 };
2389
2390                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 301);
2391
2392                 scorer.payment_path_failed(&failed_path, 41, Duration::ZERO);
2393                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 301);
2394
2395                 scorer.payment_path_successful(&successful_path, Duration::ZERO);
2396                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 301);
2397         }
2398
2399         #[test]
2400         fn sets_liquidity_lower_bound_on_downstream_failure() {
2401                 let logger = TestLogger::new();
2402                 let network_graph = network_graph(&logger);
2403                 let params = ProbabilisticScoringFeeParameters {
2404                         liquidity_penalty_multiplier_msat: 1_000,
2405                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2406                 };
2407                 let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2408                 let source = source_node_id();
2409                 let path = payment_path_for_amount(500);
2410
2411                 let usage = ChannelUsage {
2412                         amount_msat: 250,
2413                         inflight_htlc_msat: 0,
2414                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
2415                 };
2416                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2417                 let (info, _) = channel.as_directed_from(&source).unwrap();
2418                 let candidate = CandidateRouteHop::PublicHop {
2419                         info,
2420                         short_channel_id: 42,
2421                 };
2422                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 128);
2423                 let usage = ChannelUsage { amount_msat: 500, ..usage };
2424                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 301);
2425                 let usage = ChannelUsage { amount_msat: 750, ..usage };
2426                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 602);
2427
2428                 scorer.payment_path_failed(&path, 43, Duration::ZERO);
2429
2430                 let usage = ChannelUsage { amount_msat: 250, ..usage };
2431                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2432                 let usage = ChannelUsage { amount_msat: 500, ..usage };
2433                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2434                 let usage = ChannelUsage { amount_msat: 750, ..usage };
2435                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2436         }
2437
2438         #[test]
2439         fn sets_liquidity_upper_bound_on_failure() {
2440                 let logger = TestLogger::new();
2441                 let network_graph = network_graph(&logger);
2442                 let params = ProbabilisticScoringFeeParameters {
2443                         liquidity_penalty_multiplier_msat: 1_000,
2444                         considered_impossible_penalty_msat: u64::max_value(),
2445                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2446                 };
2447                 let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2448                 let source = source_node_id();
2449                 let path = payment_path_for_amount(500);
2450
2451                 let usage = ChannelUsage {
2452                         amount_msat: 250,
2453                         inflight_htlc_msat: 0,
2454                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
2455                 };
2456                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2457                 let (info, _) = channel.as_directed_from(&source).unwrap();
2458                 let candidate = CandidateRouteHop::PublicHop {
2459                         info,
2460                         short_channel_id: 42,
2461                 };
2462                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 128);
2463                 let usage = ChannelUsage { amount_msat: 500, ..usage };
2464                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 301);
2465                 let usage = ChannelUsage { amount_msat: 750, ..usage };
2466                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 602);
2467
2468                 scorer.payment_path_failed(&path, 42, Duration::ZERO);
2469
2470                 let usage = ChannelUsage { amount_msat: 250, ..usage };
2471                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2472                 let usage = ChannelUsage { amount_msat: 500, ..usage };
2473                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2474                 let usage = ChannelUsage { amount_msat: 750, ..usage };
2475                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2476         }
2477
2478         #[test]
2479         fn ignores_channels_after_removed_failed_channel() {
2480                 // Previously, if we'd tried to send over a channel which was removed from the network
2481                 // graph before we call `payment_path_failed` (which is the default if the we get a "no
2482                 // such channel" error in the `InvoicePayer`), we would call `failed_downstream` on all
2483                 // channels in the route, even ones which they payment never reached. This tests to ensure
2484                 // we do not score such channels.
2485                 let secp_ctx = Secp256k1::new();
2486                 let logger = TestLogger::new();
2487                 let mut network_graph = NetworkGraph::new(Network::Testnet, &logger);
2488                 let secret_a = SecretKey::from_slice(&[42; 32]).unwrap();
2489                 let secret_b = SecretKey::from_slice(&[43; 32]).unwrap();
2490                 let secret_c = SecretKey::from_slice(&[44; 32]).unwrap();
2491                 let secret_d = SecretKey::from_slice(&[45; 32]).unwrap();
2492                 add_channel(&mut network_graph, 42, secret_a, secret_b);
2493                 // Don't add the channel from B -> C.
2494                 add_channel(&mut network_graph, 44, secret_c, secret_d);
2495
2496                 let pub_a = PublicKey::from_secret_key(&secp_ctx, &secret_a);
2497                 let pub_b = PublicKey::from_secret_key(&secp_ctx, &secret_b);
2498                 let pub_c = PublicKey::from_secret_key(&secp_ctx, &secret_c);
2499                 let pub_d = PublicKey::from_secret_key(&secp_ctx, &secret_d);
2500
2501                 let path = vec![
2502                         path_hop(pub_b, 42, 1),
2503                         path_hop(pub_c, 43, 2),
2504                         path_hop(pub_d, 44, 100),
2505                 ];
2506
2507                 let node_a = NodeId::from_pubkey(&pub_a);
2508                 let node_b = NodeId::from_pubkey(&pub_b);
2509                 let node_c = NodeId::from_pubkey(&pub_c);
2510
2511                 let params = ProbabilisticScoringFeeParameters {
2512                         liquidity_penalty_multiplier_msat: 1_000,
2513                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2514                 };
2515                 let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2516
2517                 let usage = ChannelUsage {
2518                         amount_msat: 250,
2519                         inflight_htlc_msat: 0,
2520                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
2521                 };
2522                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2523                 let (info, _) = channel.as_directed_from(&node_a).unwrap();
2524                 let candidate = CandidateRouteHop::PublicHop {
2525                         info,
2526                         short_channel_id: 42,
2527                 };
2528                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 128);
2529                 // Note that a default liquidity bound is used for B -> C as no channel exists
2530                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2531                 let (info, _) = channel.as_directed_from(&node_b).unwrap();
2532                 let candidate = CandidateRouteHop::PublicHop {
2533                         info,
2534                         short_channel_id: 43,
2535                 };
2536                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 128);
2537                 let channel = network_graph.read_only().channel(44).unwrap().to_owned();
2538                 let (info, _) = channel.as_directed_from(&node_c).unwrap();
2539                 let candidate = CandidateRouteHop::PublicHop {
2540                         info,
2541                         short_channel_id: 44,
2542                 };
2543                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 128);
2544
2545                 scorer.payment_path_failed(&Path { hops: path, blinded_tail: None }, 43, Duration::ZERO);
2546
2547                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2548                 let (info, _) = channel.as_directed_from(&node_a).unwrap();
2549                 let candidate = CandidateRouteHop::PublicHop {
2550                         info,
2551                         short_channel_id: 42,
2552                 };
2553                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 80);
2554                 // Note that a default liquidity bound is used for B -> C as no channel exists
2555                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2556                 let (info, _) = channel.as_directed_from(&node_b).unwrap();
2557                 let candidate = CandidateRouteHop::PublicHop {
2558                         info,
2559                         short_channel_id: 43,
2560                 };
2561                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 128);
2562                 let channel = network_graph.read_only().channel(44).unwrap().to_owned();
2563                 let (info, _) = channel.as_directed_from(&node_c).unwrap();
2564                 let candidate = CandidateRouteHop::PublicHop {
2565                         info,
2566                         short_channel_id: 44,
2567                 };
2568                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 128);
2569         }
2570
2571         #[test]
2572         fn reduces_liquidity_upper_bound_along_path_on_success() {
2573                 let logger = TestLogger::new();
2574                 let network_graph = network_graph(&logger);
2575                 let params = ProbabilisticScoringFeeParameters {
2576                         liquidity_penalty_multiplier_msat: 1_000,
2577                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2578                 };
2579                 let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2580                 let source = source_node_id();
2581                 let usage = ChannelUsage {
2582                         amount_msat: 250,
2583                         inflight_htlc_msat: 0,
2584                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
2585                 };
2586                 let network_graph = network_graph.read_only().channels().clone();
2587                 let channel_42 = network_graph.get(&42).unwrap();
2588                 let channel_43 = network_graph.get(&43).unwrap();
2589                 let (info, _) = channel_42.as_directed_from(&source).unwrap();
2590                 let candidate_41 = CandidateRouteHop::PublicHop {
2591                         info,
2592                         short_channel_id: 41,
2593                 };
2594                 let (info, target) = channel_42.as_directed_from(&source).unwrap();
2595                 let candidate_42 = CandidateRouteHop::PublicHop {
2596                         info,
2597                         short_channel_id: 42,
2598                 };
2599                 let (info, _) = channel_43.as_directed_from(&target).unwrap();
2600                 let candidate_43 = CandidateRouteHop::PublicHop {
2601                         info,
2602                         short_channel_id: 43,
2603                 };
2604                 assert_eq!(scorer.channel_penalty_msat(&candidate_41, usage, &params), 128);
2605                 assert_eq!(scorer.channel_penalty_msat(&candidate_42, usage, &params), 128);
2606                 assert_eq!(scorer.channel_penalty_msat(&candidate_43, usage, &params), 128);
2607
2608                 scorer.payment_path_successful(&payment_path_for_amount(500), Duration::ZERO);
2609
2610                 assert_eq!(scorer.channel_penalty_msat(&candidate_41, usage, &params), 128);
2611                 assert_eq!(scorer.channel_penalty_msat(&candidate_42, usage, &params), 300);
2612                 assert_eq!(scorer.channel_penalty_msat(&candidate_43, usage, &params), 300);
2613         }
2614
2615         #[test]
2616         fn decays_liquidity_bounds_over_time() {
2617                 let logger = TestLogger::new();
2618                 let network_graph = network_graph(&logger);
2619                 let params = ProbabilisticScoringFeeParameters {
2620                         liquidity_penalty_multiplier_msat: 1_000,
2621                         considered_impossible_penalty_msat: u64::max_value(),
2622                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2623                 };
2624                 let decay_params = ProbabilisticScoringDecayParameters {
2625                         liquidity_offset_half_life: Duration::from_secs(10),
2626                         ..ProbabilisticScoringDecayParameters::zero_penalty()
2627                 };
2628                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
2629                 let source = source_node_id();
2630
2631                 let usage = ChannelUsage {
2632                         amount_msat: 0,
2633                         inflight_htlc_msat: 0,
2634                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_024 },
2635                 };
2636                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2637                 let (info, _) = channel.as_directed_from(&source).unwrap();
2638                 let candidate = CandidateRouteHop::PublicHop {
2639                         info,
2640                         short_channel_id: 42,
2641                 };
2642                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2643                 let usage = ChannelUsage { amount_msat: 1_023, ..usage };
2644                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 2_000);
2645
2646                 scorer.payment_path_failed(&payment_path_for_amount(768), 42, Duration::ZERO);
2647                 scorer.payment_path_failed(&payment_path_for_amount(128), 43, Duration::ZERO);
2648
2649                 // Initial penalties
2650                 let usage = ChannelUsage { amount_msat: 128, ..usage };
2651                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2652                 let usage = ChannelUsage { amount_msat: 256, ..usage };
2653                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 93);
2654                 let usage = ChannelUsage { amount_msat: 768, ..usage };
2655                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 1_479);
2656                 let usage = ChannelUsage { amount_msat: 896, ..usage };
2657                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2658
2659                 // Half decay (i.e., three-quarter life)
2660                 scorer.decay_liquidity_certainty(Duration::from_secs(5));
2661                 let usage = ChannelUsage { amount_msat: 128, ..usage };
2662                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 22);
2663                 let usage = ChannelUsage { amount_msat: 256, ..usage };
2664                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 106);
2665                 let usage = ChannelUsage { amount_msat: 768, ..usage };
2666                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 921);
2667                 let usage = ChannelUsage { amount_msat: 896, ..usage };
2668                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2669
2670                 // One decay (i.e., half life)
2671                 scorer.decay_liquidity_certainty(Duration::from_secs(10));
2672                 let usage = ChannelUsage { amount_msat: 64, ..usage };
2673                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2674                 let usage = ChannelUsage { amount_msat: 128, ..usage };
2675                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 34);
2676                 let usage = ChannelUsage { amount_msat: 896, ..usage };
2677                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 1_970);
2678                 let usage = ChannelUsage { amount_msat: 960, ..usage };
2679                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2680
2681                 // Fully decay liquidity lower bound.
2682                 scorer.decay_liquidity_certainty(Duration::from_secs(10 * 8));
2683                 let usage = ChannelUsage { amount_msat: 0, ..usage };
2684                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2685                 let usage = ChannelUsage { amount_msat: 1, ..usage };
2686                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2687                 let usage = ChannelUsage { amount_msat: 1_023, ..usage };
2688                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 2_000);
2689                 let usage = ChannelUsage { amount_msat: 1_024, ..usage };
2690                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2691
2692                 // Fully decay liquidity upper bound.
2693                 scorer.decay_liquidity_certainty(Duration::from_secs(10 * 9));
2694                 let usage = ChannelUsage { amount_msat: 0, ..usage };
2695                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2696                 let usage = ChannelUsage { amount_msat: 1_024, ..usage };
2697                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2698
2699                 scorer.decay_liquidity_certainty(Duration::from_secs(10 * 10));
2700                 let usage = ChannelUsage { amount_msat: 0, ..usage };
2701                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
2702                 let usage = ChannelUsage { amount_msat: 1_024, ..usage };
2703                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2704         }
2705
2706         #[test]
2707         fn restricts_liquidity_bounds_after_decay() {
2708                 let logger = TestLogger::new();
2709                 let network_graph = network_graph(&logger);
2710                 let params = ProbabilisticScoringFeeParameters {
2711                         liquidity_penalty_multiplier_msat: 1_000,
2712                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2713                 };
2714                 let decay_params = ProbabilisticScoringDecayParameters {
2715                         liquidity_offset_half_life: Duration::from_secs(10),
2716                         ..ProbabilisticScoringDecayParameters::default()
2717                 };
2718                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
2719                 let source = source_node_id();
2720                 let usage = ChannelUsage {
2721                         amount_msat: 512,
2722                         inflight_htlc_msat: 0,
2723                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_000 },
2724                 };
2725                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2726                 let (info, _) = channel.as_directed_from(&source).unwrap();
2727                 let candidate = CandidateRouteHop::PublicHop {
2728                         info,
2729                         short_channel_id: 42,
2730                 };
2731
2732                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2733
2734                 // More knowledge gives higher confidence (256, 768), meaning a lower penalty.
2735                 scorer.payment_path_failed(&payment_path_for_amount(768), 42, Duration::ZERO);
2736                 scorer.payment_path_failed(&payment_path_for_amount(256), 43, Duration::ZERO);
2737                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 281);
2738
2739                 // Decaying knowledge gives less confidence (128, 896), meaning a higher penalty.
2740                 scorer.decay_liquidity_certainty(Duration::from_secs(10));
2741                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 291);
2742
2743                 // Reducing the upper bound gives more confidence (128, 832) that the payment amount (512)
2744                 // is closer to the upper bound, meaning a higher penalty.
2745                 scorer.payment_path_successful(&payment_path_for_amount(64), Duration::from_secs(10));
2746                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 331);
2747
2748                 // Increasing the lower bound gives more confidence (256, 832) that the payment amount (512)
2749                 // is closer to the lower bound, meaning a lower penalty.
2750                 scorer.payment_path_failed(&payment_path_for_amount(256), 43, Duration::from_secs(10));
2751                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 245);
2752
2753                 // Further decaying affects the lower bound more than the upper bound (128, 928).
2754                 scorer.decay_liquidity_certainty(Duration::from_secs(20));
2755                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 280);
2756         }
2757
2758         #[test]
2759         fn restores_persisted_liquidity_bounds() {
2760                 let logger = TestLogger::new();
2761                 let network_graph = network_graph(&logger);
2762                 let params = ProbabilisticScoringFeeParameters {
2763                         liquidity_penalty_multiplier_msat: 1_000,
2764                         considered_impossible_penalty_msat: u64::max_value(),
2765                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2766                 };
2767                 let decay_params = ProbabilisticScoringDecayParameters {
2768                         liquidity_offset_half_life: Duration::from_secs(10),
2769                         ..ProbabilisticScoringDecayParameters::default()
2770                 };
2771                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
2772                 let source = source_node_id();
2773                 let usage = ChannelUsage {
2774                         amount_msat: 500,
2775                         inflight_htlc_msat: 0,
2776                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
2777                 };
2778
2779                 scorer.payment_path_failed(&payment_path_for_amount(500), 42, Duration::ZERO);
2780                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2781                 let (info, _) = channel.as_directed_from(&source).unwrap();
2782                 let candidate = CandidateRouteHop::PublicHop {
2783                         info,
2784                         short_channel_id: 42,
2785                 };
2786                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2787
2788                 scorer.decay_liquidity_certainty(Duration::from_secs(10));
2789                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 473);
2790
2791                 scorer.payment_path_failed(&payment_path_for_amount(250), 43, Duration::from_secs(10));
2792                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2793
2794                 let mut serialized_scorer = Vec::new();
2795                 scorer.write(&mut serialized_scorer).unwrap();
2796
2797                 let mut serialized_scorer = io::Cursor::new(&serialized_scorer);
2798                 let deserialized_scorer =
2799                         <ProbabilisticScorer<_, _>>::read(&mut serialized_scorer, (decay_params, &network_graph, &logger)).unwrap();
2800                 assert_eq!(deserialized_scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2801         }
2802
2803         fn do_decays_persisted_liquidity_bounds(decay_before_reload: bool) {
2804                 let logger = TestLogger::new();
2805                 let network_graph = network_graph(&logger);
2806                 let params = ProbabilisticScoringFeeParameters {
2807                         liquidity_penalty_multiplier_msat: 1_000,
2808                         considered_impossible_penalty_msat: u64::max_value(),
2809                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2810                 };
2811                 let decay_params = ProbabilisticScoringDecayParameters {
2812                         liquidity_offset_half_life: Duration::from_secs(10),
2813                         ..ProbabilisticScoringDecayParameters::zero_penalty()
2814                 };
2815                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
2816                 let source = source_node_id();
2817                 let usage = ChannelUsage {
2818                         amount_msat: 500,
2819                         inflight_htlc_msat: 0,
2820                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
2821                 };
2822
2823                 scorer.payment_path_failed(&payment_path_for_amount(500), 42, Duration::ZERO);
2824                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2825                 let (info, _) = channel.as_directed_from(&source).unwrap();
2826                 let candidate = CandidateRouteHop::PublicHop {
2827                         info,
2828                         short_channel_id: 42,
2829                 };
2830                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
2831
2832                 if decay_before_reload {
2833                         scorer.decay_liquidity_certainty(Duration::from_secs(10));
2834                 }
2835
2836                 let mut serialized_scorer = Vec::new();
2837                 scorer.write(&mut serialized_scorer).unwrap();
2838
2839                 let mut serialized_scorer = io::Cursor::new(&serialized_scorer);
2840                 let mut deserialized_scorer =
2841                         <ProbabilisticScorer<_, _>>::read(&mut serialized_scorer, (decay_params, &network_graph, &logger)).unwrap();
2842                 if !decay_before_reload {
2843                         scorer.decay_liquidity_certainty(Duration::from_secs(10));
2844                         deserialized_scorer.decay_liquidity_certainty(Duration::from_secs(10));
2845                 }
2846                 assert_eq!(deserialized_scorer.channel_penalty_msat(&candidate, usage, &params), 473);
2847
2848                 scorer.payment_path_failed(&payment_path_for_amount(250), 43, Duration::from_secs(10));
2849                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2850
2851                 deserialized_scorer.decay_liquidity_certainty(Duration::from_secs(20));
2852                 assert_eq!(deserialized_scorer.channel_penalty_msat(&candidate, usage, &params), 370);
2853         }
2854
2855         #[test]
2856         fn decays_persisted_liquidity_bounds() {
2857                 do_decays_persisted_liquidity_bounds(false);
2858                 do_decays_persisted_liquidity_bounds(true);
2859         }
2860
2861         #[test]
2862         fn scores_realistic_payments() {
2863                 // Shows the scores of "realistic" sends of 100k sats over channels of 1-10m sats (with a
2864                 // 50k sat reserve).
2865                 let logger = TestLogger::new();
2866                 let network_graph = network_graph(&logger);
2867                 let params = ProbabilisticScoringFeeParameters::default();
2868                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2869                 let source = source_node_id();
2870
2871                 let usage = ChannelUsage {
2872                         amount_msat: 100_000_000,
2873                         inflight_htlc_msat: 0,
2874                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 950_000_000, htlc_maximum_msat: 1_000 },
2875                 };
2876                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2877                 let (info, _) = channel.as_directed_from(&source).unwrap();
2878                 let candidate = CandidateRouteHop::PublicHop {
2879                         info,
2880                         short_channel_id: 42,
2881                 };
2882                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 11497);
2883                 let usage = ChannelUsage {
2884                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2885                 };
2886                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 7408);
2887                 let usage = ChannelUsage {
2888                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 2_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2889                 };
2890                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 6151);
2891                 let usage = ChannelUsage {
2892                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 3_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2893                 };
2894                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 5427);
2895                 let usage = ChannelUsage {
2896                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 4_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2897                 };
2898                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 4955);
2899                 let usage = ChannelUsage {
2900                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 5_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2901                 };
2902                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 4736);
2903                 let usage = ChannelUsage {
2904                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 6_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2905                 };
2906                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 4484);
2907                 let usage = ChannelUsage {
2908                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 7_450_000_000, htlc_maximum_msat: 1_000 }, ..usage
2909                 };
2910                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 4484);
2911                 let usage = ChannelUsage {
2912                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 7_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2913                 };
2914                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 4263);
2915                 let usage = ChannelUsage {
2916                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 8_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2917                 };
2918                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 4263);
2919                 let usage = ChannelUsage {
2920                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 9_950_000_000, htlc_maximum_msat: 1_000 }, ..usage
2921                 };
2922                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 4044);
2923         }
2924
2925         #[test]
2926         fn adds_base_penalty_to_liquidity_penalty() {
2927                 let logger = TestLogger::new();
2928                 let network_graph = network_graph(&logger);
2929                 let source = source_node_id();
2930                 let usage = ChannelUsage {
2931                         amount_msat: 128,
2932                         inflight_htlc_msat: 0,
2933                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_000 },
2934                 };
2935
2936                 let params = ProbabilisticScoringFeeParameters {
2937                         liquidity_penalty_multiplier_msat: 1_000,
2938                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2939                 };
2940                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2941                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2942                 let (info, _) = channel.as_directed_from(&source).unwrap();
2943                 let candidate = CandidateRouteHop::PublicHop {
2944                         info,
2945                         short_channel_id: 42,
2946                 };
2947                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 58);
2948
2949                 let params = ProbabilisticScoringFeeParameters {
2950                         base_penalty_msat: 500, liquidity_penalty_multiplier_msat: 1_000,
2951                         anti_probing_penalty_msat: 0, ..ProbabilisticScoringFeeParameters::zero_penalty()
2952                 };
2953                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2954                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 558);
2955
2956                 let params = ProbabilisticScoringFeeParameters {
2957                         base_penalty_msat: 500, liquidity_penalty_multiplier_msat: 1_000,
2958                         base_penalty_amount_multiplier_msat: (1 << 30),
2959                         anti_probing_penalty_msat: 0, ..ProbabilisticScoringFeeParameters::zero_penalty()
2960                 };
2961
2962                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2963                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 558 + 128);
2964         }
2965
2966         #[test]
2967         fn adds_amount_penalty_to_liquidity_penalty() {
2968                 let logger = TestLogger::new();
2969                 let network_graph = network_graph(&logger);
2970                 let source = source_node_id();
2971                 let usage = ChannelUsage {
2972                         amount_msat: 512_000,
2973                         inflight_htlc_msat: 0,
2974                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024_000, htlc_maximum_msat: 1_000 },
2975                 };
2976
2977                 let params = ProbabilisticScoringFeeParameters {
2978                         liquidity_penalty_multiplier_msat: 1_000,
2979                         liquidity_penalty_amount_multiplier_msat: 0,
2980                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2981                 };
2982                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2983                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
2984                 let (info, _) = channel.as_directed_from(&source).unwrap();
2985                 let candidate = CandidateRouteHop::PublicHop {
2986                         info,
2987                         short_channel_id: 42,
2988                 };
2989                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
2990
2991                 let params = ProbabilisticScoringFeeParameters {
2992                         liquidity_penalty_multiplier_msat: 1_000,
2993                         liquidity_penalty_amount_multiplier_msat: 256,
2994                         ..ProbabilisticScoringFeeParameters::zero_penalty()
2995                 };
2996                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
2997                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 337);
2998         }
2999
3000         #[test]
3001         fn calculates_log10_without_overflowing_u64_max_value() {
3002                 let logger = TestLogger::new();
3003                 let network_graph = network_graph(&logger);
3004                 let source = source_node_id();
3005                 let usage = ChannelUsage {
3006                         amount_msat: u64::max_value(),
3007                         inflight_htlc_msat: 0,
3008                         effective_capacity: EffectiveCapacity::Infinite,
3009                 };
3010                 let params = ProbabilisticScoringFeeParameters {
3011                         liquidity_penalty_multiplier_msat: 40_000,
3012                         ..ProbabilisticScoringFeeParameters::zero_penalty()
3013                 };
3014                 let decay_params = ProbabilisticScoringDecayParameters::zero_penalty();
3015                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
3016                 let (info, _) = channel.as_directed_from(&source).unwrap();
3017                 let candidate = CandidateRouteHop::PublicHop {
3018                         info,
3019                         short_channel_id: 42,
3020                 };
3021                 let scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
3022                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 80_000);
3023         }
3024
3025         #[test]
3026         fn accounts_for_inflight_htlc_usage() {
3027                 let logger = TestLogger::new();
3028                 let network_graph = network_graph(&logger);
3029                 let params = ProbabilisticScoringFeeParameters {
3030                         considered_impossible_penalty_msat: u64::max_value(),
3031                         ..ProbabilisticScoringFeeParameters::zero_penalty()
3032                 };
3033                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
3034                 let source = source_node_id();
3035
3036                 let usage = ChannelUsage {
3037                         amount_msat: 750,
3038                         inflight_htlc_msat: 0,
3039                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_000, htlc_maximum_msat: 1_000 },
3040                 };
3041                 let network_graph = network_graph.read_only();
3042                 let channel = network_graph.channel(42).unwrap();
3043                 let (info, _) = channel.as_directed_from(&source).unwrap();
3044                 let candidate = CandidateRouteHop::PublicHop {
3045                         info,
3046                         short_channel_id: 42,
3047                 };
3048                 assert_ne!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
3049
3050                 let usage = ChannelUsage { inflight_htlc_msat: 251, ..usage };
3051                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
3052         }
3053
3054         #[test]
3055         fn removes_uncertainity_when_exact_liquidity_known() {
3056                 let logger = TestLogger::new();
3057                 let network_graph = network_graph(&logger);
3058                 let params = ProbabilisticScoringFeeParameters::default();
3059                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
3060                 let source = source_node_id();
3061
3062                 let base_penalty_msat = params.base_penalty_msat;
3063                 let usage = ChannelUsage {
3064                         amount_msat: 750,
3065                         inflight_htlc_msat: 0,
3066                         effective_capacity: EffectiveCapacity::ExactLiquidity { liquidity_msat: 1_000 },
3067                 };
3068                 let network_graph = network_graph.read_only();
3069                 let channel = network_graph.channel(42).unwrap();
3070                 let (info, _) = channel.as_directed_from(&source).unwrap();
3071                 let candidate = CandidateRouteHop::PublicHop {
3072                         info,
3073                         short_channel_id: 42,
3074                 };
3075                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), base_penalty_msat);
3076
3077                 let usage = ChannelUsage { amount_msat: 1_000, ..usage };
3078                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), base_penalty_msat);
3079
3080                 let usage = ChannelUsage { amount_msat: 1_001, ..usage };
3081                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), u64::max_value());
3082         }
3083
3084         #[test]
3085         fn remembers_historical_failures() {
3086                 let logger = TestLogger::new();
3087                 let network_graph = network_graph(&logger);
3088                 let params = ProbabilisticScoringFeeParameters {
3089                         historical_liquidity_penalty_multiplier_msat: 1024,
3090                         historical_liquidity_penalty_amount_multiplier_msat: 1024,
3091                         ..ProbabilisticScoringFeeParameters::zero_penalty()
3092                 };
3093                 let decay_params = ProbabilisticScoringDecayParameters {
3094                         liquidity_offset_half_life: Duration::from_secs(60 * 60),
3095                         historical_no_updates_half_life: Duration::from_secs(10),
3096                 };
3097                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
3098                 let source = source_node_id();
3099                 let target = target_node_id();
3100
3101                 let usage = ChannelUsage {
3102                         amount_msat: 100,
3103                         inflight_htlc_msat: 0,
3104                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_024 },
3105                 };
3106                 let usage_1 = ChannelUsage {
3107                         amount_msat: 1,
3108                         inflight_htlc_msat: 0,
3109                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_024 },
3110                 };
3111
3112                 {
3113                         let network_graph = network_graph.read_only();
3114                         let channel = network_graph.channel(42).unwrap();
3115                         let (info, _) = channel.as_directed_from(&source).unwrap();
3116                         let candidate = CandidateRouteHop::PublicHop {
3117                                 info,
3118                                 short_channel_id: 42,
3119                         };
3120
3121                         // With no historical data the normal liquidity penalty calculation is used.
3122                         assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 168);
3123                 }
3124                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3125                 None);
3126                 assert_eq!(scorer.historical_estimated_payment_success_probability(42, &target, 42, &params),
3127                 None);
3128
3129                 scorer.payment_path_failed(&payment_path_for_amount(1), 42, Duration::ZERO);
3130                 {
3131                         let network_graph = network_graph.read_only();
3132                         let channel = network_graph.channel(42).unwrap();
3133                         let (info, _) = channel.as_directed_from(&source).unwrap();
3134                         let candidate = CandidateRouteHop::PublicHop {
3135                                 info,
3136                                 short_channel_id: 42,
3137                         };
3138
3139                         assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 2048);
3140                         assert_eq!(scorer.channel_penalty_msat(&candidate, usage_1, &params), 249);
3141                 }
3142                 // The "it failed" increment is 32, where the probability should lie several buckets into
3143                 // the first octile.
3144                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3145                         Some(([32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
3146                                 [0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])));
3147                 assert!(scorer.historical_estimated_payment_success_probability(42, &target, 1, &params)
3148                         .unwrap() > 0.35);
3149                 assert_eq!(scorer.historical_estimated_payment_success_probability(42, &target, 500, &params),
3150                         Some(0.0));
3151
3152                 // Even after we tell the scorer we definitely have enough available liquidity, it will
3153                 // still remember that there was some failure in the past, and assign a non-0 penalty.
3154                 scorer.payment_path_failed(&payment_path_for_amount(1000), 43, Duration::ZERO);
3155                 {
3156                         let network_graph = network_graph.read_only();
3157                         let channel = network_graph.channel(42).unwrap();
3158                         let (info, _) = channel.as_directed_from(&source).unwrap();
3159                         let candidate = CandidateRouteHop::PublicHop {
3160                                 info,
3161                                 short_channel_id: 42,
3162                         };
3163
3164                         assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 105);
3165                 }
3166                 // The first points should be decayed just slightly and the last bucket has a new point.
3167                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3168                         Some(([31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0],
3169                                 [0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32])));
3170
3171                 // The exact success probability is a bit complicated and involves integer rounding, so we
3172                 // simply check bounds here.
3173                 let five_hundred_prob =
3174                         scorer.historical_estimated_payment_success_probability(42, &target, 500, &params).unwrap();
3175                 assert!(five_hundred_prob > 0.59);
3176                 assert!(five_hundred_prob < 0.60);
3177                 let one_prob =
3178                         scorer.historical_estimated_payment_success_probability(42, &target, 1, &params).unwrap();
3179                 assert!(one_prob < 0.85);
3180                 assert!(one_prob > 0.84);
3181
3182                 // Advance the time forward 16 half-lives (which the docs claim will ensure all data is
3183                 // gone), and check that we're back to where we started.
3184                 scorer.decay_liquidity_certainty(Duration::from_secs(10 * 16));
3185                 {
3186                         let network_graph = network_graph.read_only();
3187                         let channel = network_graph.channel(42).unwrap();
3188                         let (info, _) = channel.as_directed_from(&source).unwrap();
3189                         let candidate = CandidateRouteHop::PublicHop {
3190                                 info,
3191                                 short_channel_id: 42,
3192                         };
3193
3194                         assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 168);
3195                 }
3196                 // Once fully decayed we still have data, but its all-0s. In the future we may remove the
3197                 // data entirely instead.
3198                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3199                         Some(([0; 32], [0; 32])));
3200                 assert_eq!(scorer.historical_estimated_payment_success_probability(42, &target, 1, &params), None);
3201
3202                 let mut usage = ChannelUsage {
3203                         amount_msat: 100,
3204                         inflight_htlc_msat: 1024,
3205                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_024 },
3206                 };
3207                 scorer.payment_path_failed(&payment_path_for_amount(1), 42, Duration::from_secs(10 * 16));
3208                 {
3209                         let network_graph = network_graph.read_only();
3210                         let channel = network_graph.channel(42).unwrap();
3211                         let (info, _) = channel.as_directed_from(&source).unwrap();
3212                         let candidate = CandidateRouteHop::PublicHop {
3213                                 info,
3214                                 short_channel_id: 42,
3215                         };
3216
3217                         assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 2050);
3218
3219                         let usage = ChannelUsage {
3220                                 amount_msat: 1,
3221                                 inflight_htlc_msat: 0,
3222                                 effective_capacity: EffectiveCapacity::AdvertisedMaxHTLC { amount_msat: 0 },
3223                         };
3224                         assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 2048);
3225                 }
3226
3227                 // Advance to decay all liquidity offsets to zero.
3228                 scorer.decay_liquidity_certainty(Duration::from_secs(10 * (16 + 60 * 60)));
3229
3230                 // Once even the bounds have decayed information about the channel should be removed
3231                 // entirely.
3232                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3233                         None);
3234
3235                 // Use a path in the opposite direction, which have zero for htlc_maximum_msat. This will
3236                 // ensure that the effective capacity is zero to test division-by-zero edge cases.
3237                 let path = vec![
3238                         path_hop(target_pubkey(), 43, 2),
3239                         path_hop(source_pubkey(), 42, 1),
3240                         path_hop(sender_pubkey(), 41, 0),
3241                 ];
3242                 scorer.payment_path_failed(&Path { hops: path, blinded_tail: None }, 42, Duration::from_secs(10 * (16 + 60 * 60)));
3243         }
3244
3245         #[test]
3246         fn adds_anti_probing_penalty() {
3247                 let logger = TestLogger::new();
3248                 let network_graph = network_graph(&logger);
3249                 let source = source_node_id();
3250                 let params = ProbabilisticScoringFeeParameters {
3251                         anti_probing_penalty_msat: 500,
3252                         ..ProbabilisticScoringFeeParameters::zero_penalty()
3253                 };
3254                 let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
3255
3256                 // Check we receive no penalty for a low htlc_maximum_msat.
3257                 let usage = ChannelUsage {
3258                         amount_msat: 512_000,
3259                         inflight_htlc_msat: 0,
3260                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024_000, htlc_maximum_msat: 1_000 },
3261                 };
3262                 let network_graph = network_graph.read_only();
3263                 let channel = network_graph.channel(42).unwrap();
3264                 let (info, _) = channel.as_directed_from(&source).unwrap();
3265                 let candidate = CandidateRouteHop::PublicHop {
3266                         info,
3267                         short_channel_id: 42,
3268                 };
3269                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
3270
3271                 // Check we receive anti-probing penalty for htlc_maximum_msat == channel_capacity.
3272                 let usage = ChannelUsage {
3273                         amount_msat: 512_000,
3274                         inflight_htlc_msat: 0,
3275                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024_000, htlc_maximum_msat: 1_024_000 },
3276                 };
3277                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 500);
3278
3279                 // Check we receive anti-probing penalty for htlc_maximum_msat == channel_capacity/2.
3280                 let usage = ChannelUsage {
3281                         amount_msat: 512_000,
3282                         inflight_htlc_msat: 0,
3283                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024_000, htlc_maximum_msat: 512_000 },
3284                 };
3285                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 500);
3286
3287                 // Check we receive no anti-probing penalty for htlc_maximum_msat == channel_capacity/2 - 1.
3288                 let usage = ChannelUsage {
3289                         amount_msat: 512_000,
3290                         inflight_htlc_msat: 0,
3291                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024_000, htlc_maximum_msat: 511_999 },
3292                 };
3293                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 0);
3294         }
3295
3296         #[test]
3297         fn scores_with_blinded_path() {
3298                 // Make sure we'll account for a blinded path's final_value_msat in scoring
3299                 let logger = TestLogger::new();
3300                 let network_graph = network_graph(&logger);
3301                 let params = ProbabilisticScoringFeeParameters {
3302                         liquidity_penalty_multiplier_msat: 1_000,
3303                         ..ProbabilisticScoringFeeParameters::zero_penalty()
3304                 };
3305                 let decay_params = ProbabilisticScoringDecayParameters::default();
3306                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
3307                 let source = source_node_id();
3308                 let usage = ChannelUsage {
3309                         amount_msat: 512,
3310                         inflight_htlc_msat: 0,
3311                         effective_capacity: EffectiveCapacity::Total { capacity_msat: 1_024, htlc_maximum_msat: 1_000 },
3312                 };
3313                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
3314                 let (info, target) = channel.as_directed_from(&source).unwrap();
3315                 let candidate = CandidateRouteHop::PublicHop {
3316                         info,
3317                         short_channel_id: 42,
3318                 };
3319                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 300);
3320
3321                 let mut path = payment_path_for_amount(768);
3322                 let recipient_hop = path.hops.pop().unwrap();
3323                 let blinded_path = BlindedPath {
3324                         introduction_node_id: path.hops.last().as_ref().unwrap().pubkey,
3325                         blinding_point: test_utils::pubkey(42),
3326                         blinded_hops: vec![
3327                                 BlindedHop { blinded_node_id: test_utils::pubkey(44), encrypted_payload: Vec::new() }
3328                         ],
3329                 };
3330                 path.blinded_tail = Some(BlindedTail {
3331                         hops: blinded_path.blinded_hops,
3332                         blinding_point: blinded_path.blinding_point,
3333                         excess_final_cltv_expiry_delta: recipient_hop.cltv_expiry_delta,
3334                         final_value_msat: recipient_hop.fee_msat,
3335                 });
3336
3337                 // Check the liquidity before and after scoring payment failures to ensure the blinded path's
3338                 // final value is taken into account.
3339                 assert!(scorer.channel_liquidities.get(&42).is_none());
3340
3341                 scorer.payment_path_failed(&path, 42, Duration::ZERO);
3342                 path.blinded_tail.as_mut().unwrap().final_value_msat = 256;
3343                 scorer.payment_path_failed(&path, 43, Duration::ZERO);
3344
3345                 let liquidity = scorer.channel_liquidities.get(&42).unwrap()
3346                         .as_directed(&source, &target, 1_000);
3347                 assert_eq!(liquidity.min_liquidity_msat(), 256);
3348                 assert_eq!(liquidity.max_liquidity_msat(), 768);
3349         }
3350
3351         #[test]
3352         fn realistic_historical_failures() {
3353                 // The motivation for the unequal sized buckets came largely from attempting to pay 10k
3354                 // sats over a one bitcoin channel. This tests that case explicitly, ensuring that we score
3355                 // properly.
3356                 let logger = TestLogger::new();
3357                 let mut network_graph = network_graph(&logger);
3358                 let params = ProbabilisticScoringFeeParameters {
3359                         historical_liquidity_penalty_multiplier_msat: 1024,
3360                         historical_liquidity_penalty_amount_multiplier_msat: 1024,
3361                         ..ProbabilisticScoringFeeParameters::zero_penalty()
3362                 };
3363                 let decay_params = ProbabilisticScoringDecayParameters {
3364                         liquidity_offset_half_life: Duration::from_secs(60 * 60),
3365                         historical_no_updates_half_life: Duration::from_secs(10),
3366                         ..ProbabilisticScoringDecayParameters::default()
3367                 };
3368
3369                 let capacity_msat = 100_000_000_000;
3370                 update_channel(&mut network_graph, 42, source_privkey(), 0, capacity_msat, 200);
3371                 update_channel(&mut network_graph, 42, target_privkey(), 1, capacity_msat, 200);
3372
3373                 let mut scorer = ProbabilisticScorer::new(decay_params, &network_graph, &logger);
3374                 let source = source_node_id();
3375
3376                 let mut amount_msat = 10_000_000;
3377                 let usage = ChannelUsage {
3378                         amount_msat,
3379                         inflight_htlc_msat: 0,
3380                         effective_capacity: EffectiveCapacity::Total { capacity_msat, htlc_maximum_msat: capacity_msat },
3381                 };
3382                 let channel = network_graph.read_only().channel(42).unwrap().to_owned();
3383                 let (info, target) = channel.as_directed_from(&source).unwrap();
3384                 let candidate = CandidateRouteHop::PublicHop {
3385                         info,
3386                         short_channel_id: 42,
3387                 };
3388                 // With no historical data the normal liquidity penalty calculation is used, which results
3389                 // in a success probability of ~75%.
3390                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params), 1269);
3391                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3392                         None);
3393                 assert_eq!(scorer.historical_estimated_payment_success_probability(42, &target, 42, &params),
3394                         None);
3395
3396                 // Fail to pay once, and then check the buckets and penalty.
3397                 scorer.payment_path_failed(&payment_path_for_amount(amount_msat), 42, Duration::ZERO);
3398                 // The penalty should be the maximum penalty, as the payment we're scoring is now in the
3399                 // same bucket which is the only maximum datapoint.
3400                 assert_eq!(scorer.channel_penalty_msat(&candidate, usage, &params),
3401                         2048 + 2048 * amount_msat / super::AMOUNT_PENALTY_DIVISOR);
3402                 // The "it failed" increment is 32, which we should apply to the first upper-bound (between
3403                 // 6k sats and 12k sats).
3404                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3405                         Some(([32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
3406                                 [0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])));
3407                 // The success probability estimate itself should be zero.
3408                 assert_eq!(scorer.historical_estimated_payment_success_probability(42, &target, amount_msat, &params),
3409                         Some(0.0));
3410
3411                 // Now test again with the amount in the bottom bucket.
3412                 amount_msat /= 2;
3413                 // The new amount is entirely within the only minimum bucket with score, so the probability
3414                 // we assign is 1/2.
3415                 assert_eq!(scorer.historical_estimated_payment_success_probability(42, &target, amount_msat, &params),
3416                         Some(0.5));
3417
3418                 // ...but once we see a failure, we consider the payment to be substantially less likely,
3419                 // even though not a probability of zero as we still look at the second max bucket which
3420                 // now shows 31.
3421                 scorer.payment_path_failed(&payment_path_for_amount(amount_msat), 42, Duration::ZERO);
3422                 assert_eq!(scorer.historical_estimated_channel_liquidity_probabilities(42, &target),
3423                         Some(([63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
3424                                 [32, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])));
3425                 assert_eq!(scorer.historical_estimated_payment_success_probability(42, &target, amount_msat, &params),
3426                         Some(0.0));
3427         }
3428 }
3429
3430 #[cfg(ldk_bench)]
3431 pub mod benches {
3432         use super::*;
3433         use criterion::Criterion;
3434         use crate::routing::router::{bench_utils, RouteHop};
3435         use crate::util::test_utils::TestLogger;
3436         use crate::ln::features::{ChannelFeatures, NodeFeatures};
3437
3438         pub fn decay_100k_channel_bounds(bench: &mut Criterion) {
3439                 let logger = TestLogger::new();
3440                 let network_graph = bench_utils::read_network_graph(&logger).unwrap();
3441                 let mut scorer = ProbabilisticScorer::new(Default::default(), &network_graph, &logger);
3442                 // Score a number of random channels
3443                 let mut seed: u64 = 0xdeadbeef;
3444                 for _ in 0..100_000 {
3445                         seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
3446                         let (victim, victim_dst, amt) = {
3447                                 let rong = network_graph.read_only();
3448                                 let channels = rong.channels();
3449                                 let chan = channels.unordered_iter()
3450                                         .skip((seed as usize) % channels.len())
3451                                         .next().unwrap();
3452                                 seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
3453                                 let amt = seed % chan.1.capacity_sats.map(|c| c * 1000)
3454                                         .or(chan.1.one_to_two.as_ref().map(|info| info.htlc_maximum_msat))
3455                                         .or(chan.1.two_to_one.as_ref().map(|info| info.htlc_maximum_msat))
3456                                         .unwrap_or(1_000_000_000).saturating_add(1);
3457                                 (*chan.0, chan.1.node_two, amt)
3458                         };
3459                         let path = Path {
3460                                 hops: vec![RouteHop {
3461                                         pubkey: victim_dst.as_pubkey().unwrap(),
3462                                         node_features: NodeFeatures::empty(),
3463                                         short_channel_id: victim,
3464                                         channel_features: ChannelFeatures::empty(),
3465                                         fee_msat: amt,
3466                                         cltv_expiry_delta: 42,
3467                                         maybe_announced_channel: true,
3468                                 }],
3469                                 blinded_tail: None
3470                         };
3471                         seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
3472                         if seed % 1 == 0 {
3473                                 scorer.probe_failed(&path, victim, Duration::ZERO);
3474                         } else {
3475                                 scorer.probe_successful(&path, Duration::ZERO);
3476                         }
3477                 }
3478                 let mut cur_time = Duration::ZERO;
3479                         cur_time += Duration::from_millis(1);
3480                         scorer.decay_liquidity_certainty(cur_time);
3481                 bench.bench_function("decay_100k_channel_bounds", |b| b.iter(|| {
3482                         cur_time += Duration::from_millis(1);
3483                         scorer.decay_liquidity_certainty(cur_time);
3484                 }));
3485         }
3486 }