4444//! # }
4545//! ```
4646//!
47+ //! # Note
48+ //!
49+ //! If persisting [`Scorer`], it must be restored using the same [`Time`] parameterization. Using a
50+ //! different type results in undefined behavior. Specifically, persisting when built with feature
51+ //! `no-std` and restoring without it, or vice versa, uses different types and thus is undefined.
52+ //!
4753//! [`find_route`]: crate::routing::router::find_route
4854
4955use routing;
5056
57+ use ln:: msgs:: DecodeError ;
5158use routing:: network_graph:: NodeId ;
5259use routing:: router:: RouteHop ;
60+ use util:: ser:: { Readable , Writeable , Writer } ;
5361
5462use prelude:: * ;
63+ use core:: ops:: Sub ;
5564use core:: time:: Duration ;
65+ use io:: { self , Read } ;
5666
5767/// [`routing::Score`] implementation that provides reasonable default behavior.
5868///
@@ -75,6 +85,10 @@ pub type DefaultTime = Eternity;
7585/// [`routing::Score`] implementation parameterized by [`Time`].
7686///
7787/// See [`Scorer`] for details.
88+ ///
89+ /// # Note
90+ ///
91+ /// Mixing [`Time`] types between serialization and deserialization results in undefined behavior.
7892pub struct ScorerUsingTime < T : Time > {
7993 params : ScoringParameters ,
8094 // TODO: Remove entries of closed channels.
@@ -106,6 +120,12 @@ pub struct ScoringParameters {
106120 pub failure_penalty_half_life : Duration ,
107121}
108122
123+ impl_writeable_tlv_based ! ( ScoringParameters , {
124+ ( 0 , base_penalty_msat, required) ,
125+ ( 2 , failure_penalty_msat, required) ,
126+ ( 4 , failure_penalty_half_life, required) ,
127+ } ) ;
128+
109129/// Accounting for penalties against a channel for failing to relay any payments.
110130///
111131/// Penalties decay over time, though accumulate as more failures occur.
@@ -118,12 +138,17 @@ struct ChannelFailure<T: Time> {
118138}
119139
120140/// A measurement of time.
121- pub trait Time {
141+ pub trait Time : Sub < Duration , Output = Self > where Self : Sized {
122142 /// Returns an instance corresponding to the current moment.
123143 fn now ( ) -> Self ;
124144
125145 /// Returns the amount of time elapsed since `self` was created.
126146 fn elapsed ( & self ) -> Duration ;
147+
148+ /// Returns the amount of time passed since the beginning of [`Time`].
149+ ///
150+ /// Used during (de-)serialization.
151+ fn duration_since_epoch ( ) -> Duration ;
127152}
128153
129154impl < T : Time > ScorerUsingTime < T > {
@@ -211,6 +236,11 @@ impl Time for std::time::Instant {
211236 std:: time:: Instant :: now ( )
212237 }
213238
239+ fn duration_since_epoch ( ) -> Duration {
240+ use std:: time:: SystemTime ;
241+ SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH ) . unwrap ( )
242+ }
243+
214244 fn elapsed ( & self ) -> Duration {
215245 std:: time:: Instant :: elapsed ( self )
216246 }
@@ -224,7 +254,55 @@ impl Time for Eternity {
224254 Self
225255 }
226256
257+ fn duration_since_epoch ( ) -> Duration {
258+ Duration :: from_secs ( 0 )
259+ }
260+
227261 fn elapsed ( & self ) -> Duration {
228262 Duration :: from_secs ( 0 )
229263 }
230264}
265+
266+ impl Sub < Duration > for Eternity {
267+ type Output = Self ;
268+
269+ fn sub ( self , _other : Duration ) -> Self {
270+ self
271+ }
272+ }
273+
274+ impl < T : Time > Writeable for ScorerUsingTime < T > {
275+ #[ inline]
276+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
277+ self . params . write ( w) ?;
278+ self . channel_failures . write ( w)
279+ }
280+ }
281+
282+ impl < T : Time > Readable for ScorerUsingTime < T > {
283+ #[ inline]
284+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
285+ Ok ( Self {
286+ params : Readable :: read ( r) ?,
287+ channel_failures : Readable :: read ( r) ?,
288+ } )
289+ }
290+ }
291+
292+ impl < T : Time > Writeable for ChannelFailure < T > {
293+ #[ inline]
294+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
295+ self . undecayed_penalty_msat . write ( w) ?;
296+ ( T :: duration_since_epoch ( ) - self . last_failed . elapsed ( ) ) . write ( w)
297+ }
298+ }
299+
300+ impl < T : Time > Readable for ChannelFailure < T > {
301+ #[ inline]
302+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
303+ Ok ( Self {
304+ undecayed_penalty_msat : Readable :: read ( r) ?,
305+ last_failed : T :: now ( ) - ( T :: duration_since_epoch ( ) - Readable :: read ( r) ?) ,
306+ } )
307+ }
308+ }
0 commit comments