//!
//! # Note
//!
-//! If persisting [`Scorer`], it must be restored using the same [`Time`] parameterization. Using a
-//! different type results in undefined behavior. Specifically, persisting when built with feature
-//! `no-std` and restoring without it, or vice versa, uses different types and thus is undefined.
+//! Persisting when built with feature `no-std` and restoring without it, or vice versa, uses
+//! different types and thus is undefined.
//!
//! [`find_route`]: crate::routing::router::find_route
use prelude::*;
use core::cell::{RefCell, RefMut};
-use core::ops::{DerefMut, Sub};
+use core::ops::DerefMut;
use core::time::Duration;
-use io::{self, Read}; use sync::{Mutex, MutexGuard};
+use io::{self, Read};
+use sync::{Mutex, MutexGuard};
/// We define Score ever-so-slightly differently based on whether we are being built for C bindings
/// or not. For users, `LockableScore` must somehow be writeable to disk. For Rust users, this is
/// See [module-level documentation] for usage.
///
/// [module-level documentation]: crate::routing::scoring
-pub type Scorer = ScorerUsingTime::<DefaultTime>;
-
-/// Time used by [`Scorer`].
#[cfg(not(feature = "no-std"))]
-pub type DefaultTime = std::time::Instant;
-
-/// Time used by [`Scorer`].
+pub type Scorer = ScorerUsingTime::<std::time::Instant>;
+/// [`Score`] implementation that provides reasonable default behavior.
+///
+/// Used to apply a fixed penalty to each channel, thus avoiding long paths when shorter paths with
+/// slightly higher fees are available. Will further penalize channels that fail to relay payments.
+///
+/// See [module-level documentation] for usage.
+///
+/// [module-level documentation]: crate::routing::scoring
#[cfg(feature = "no-std")]
-pub type DefaultTime = Eternity;
+pub type Scorer = ScorerUsingTime::<time::Eternity>;
+
+// Note that ideally we'd hide ScorerUsingTime from public view by sealing it as well, but rustdoc
+// doesn't handle this well - instead exposing a `Scorer` which has no trait implementation(s) or
+// methods at all.
-/// [`Score`] implementation parameterized by [`Time`].
+/// [`Score`] implementation.
///
/// See [`Scorer`] for details.
///
/// # Note
///
-/// Mixing [`Time`] types between serialization and deserialization results in undefined behavior.
+/// Mixing the `no-std` feature between serialization and deserialization results in undefined
+/// behavior.
+///
+/// (C-not exported) generally all users should use the [`Scorer`] type alias.
pub struct ScorerUsingTime<T: Time> {
params: ScoringParameters,
// TODO: Remove entries of closed channels.
///
/// # Note
///
- /// When time is an [`Eternity`], as is default when enabling feature `no-std`, it will never
- /// elapse. Therefore, this penalty will never decay.
+ /// When built with the `no-std` feature, time will never elapse. Therefore, this penalty will
+ /// never decay.
///
/// [`failure_penalty_msat`]: Self::failure_penalty_msat
pub failure_penalty_half_life: Duration,
last_failed: T,
}
-/// A measurement of time.
-pub trait Time: Sub<Duration, Output = Self> where Self: Sized {
- /// Returns an instance corresponding to the current moment.
- fn now() -> Self;
-
- /// Returns the amount of time elapsed since `self` was created.
- fn elapsed(&self) -> Duration;
-
- /// Returns the amount of time passed since the beginning of [`Time`].
- ///
- /// Used during (de-)serialization.
- fn duration_since_epoch() -> Duration;
-}
-
impl<T: Time> ScorerUsingTime<T> {
/// Creates a new scorer using the given scoring parameters.
pub fn new(params: ScoringParameters) -> Self {
}
}
-#[cfg(not(feature = "no-std"))]
-impl Time for std::time::Instant {
- fn now() -> Self {
- std::time::Instant::now()
- }
-
- fn duration_since_epoch() -> Duration {
- use std::time::SystemTime;
- SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()
- }
-
- fn elapsed(&self) -> Duration {
- std::time::Instant::elapsed(self)
- }
-}
-
-/// A state in which time has no meaning.
-#[derive(Debug, PartialEq, Eq)]
-pub struct Eternity;
-
-impl Time for Eternity {
- fn now() -> Self {
- Self
- }
-
- fn duration_since_epoch() -> Duration {
- Duration::from_secs(0)
- }
-
- fn elapsed(&self) -> Duration {
- Duration::from_secs(0)
- }
-}
-
-impl Sub<Duration> for Eternity {
- type Output = Self;
-
- fn sub(self, _other: Duration) -> Self {
- self
- }
-}
-
impl<T: Time> Writeable for ScorerUsingTime<T> {
#[inline]
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
}
}
+pub(crate) mod time {
+ use core::ops::Sub;
+ use core::time::Duration;
+ /// A measurement of time.
+ pub trait Time: Sub<Duration, Output = Self> where Self: Sized {
+ /// Returns an instance corresponding to the current moment.
+ fn now() -> Self;
+
+ /// Returns the amount of time elapsed since `self` was created.
+ fn elapsed(&self) -> Duration;
+
+ /// Returns the amount of time passed since the beginning of [`Time`].
+ ///
+ /// Used during (de-)serialization.
+ fn duration_since_epoch() -> Duration;
+ }
+
+ /// A state in which time has no meaning.
+ #[derive(Debug, PartialEq, Eq)]
+ pub struct Eternity;
+
+ #[cfg(not(feature = "no-std"))]
+ impl Time for std::time::Instant {
+ fn now() -> Self {
+ std::time::Instant::now()
+ }
+
+ fn duration_since_epoch() -> Duration {
+ use std::time::SystemTime;
+ SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()
+ }
+
+ fn elapsed(&self) -> Duration {
+ std::time::Instant::elapsed(self)
+ }
+ }
+
+ impl Time for Eternity {
+ fn now() -> Self {
+ Self
+ }
+
+ fn duration_since_epoch() -> Duration {
+ Duration::from_secs(0)
+ }
+
+ fn elapsed(&self) -> Duration {
+ Duration::from_secs(0)
+ }
+ }
+
+ impl Sub<Duration> for Eternity {
+ type Output = Self;
+
+ fn sub(self, _other: Duration) -> Self {
+ self
+ }
+ }
+}
+
+pub(crate) use self::time::Time;
+
#[cfg(test)]
mod tests {
- use super::{Eternity, ScoringParameters, ScorerUsingTime, Time};
+ use super::{ScoringParameters, ScorerUsingTime, Time};
+ use super::time::Eternity;
use routing::scoring::Score;
use routing::network_graph::NodeId;