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.
@@ -103,6 +117,12 @@ pub struct ScoringParameters {
103117 pub failure_penalty_half_life : Duration ,
104118}
105119
120+ impl_writeable_tlv_based ! ( ScoringParameters , {
121+ ( 0 , base_penalty_msat, required) ,
122+ ( 2 , failure_penalty_msat, required) ,
123+ ( 4 , failure_penalty_half_life, required) ,
124+ } ) ;
125+
106126/// Accounting for penalties from channel failures.
107127///
108128/// Penalties decay over time, though accumulate as more failures occur.
@@ -115,12 +135,17 @@ struct ChannelFailure<T: Time> {
115135}
116136
117137/// A measurement of time.
118- pub trait Time {
138+ pub trait Time : Sub < Duration , Output = Self > where Self : Sized {
119139 /// Returns an instance corresponding to the current moment.
120140 fn now ( ) -> Self ;
121141
122142 /// Returns the amount of time elapsed since created.
123143 fn elapsed ( & self ) -> Duration ;
144+
145+ /// Returns the amount of time passed since the beginning of [`Time`].
146+ ///
147+ /// Used during (de-)serialization.
148+ fn duration_since_epoch ( ) -> Duration ;
124149}
125150
126151impl < T : Time > ScorerUsingTime < T > {
@@ -208,6 +233,11 @@ impl Time for std::time::Instant {
208233 std:: time:: Instant :: now ( )
209234 }
210235
236+ fn duration_since_epoch ( ) -> Duration {
237+ use std:: time:: SystemTime ;
238+ SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH ) . unwrap ( )
239+ }
240+
211241 fn elapsed ( & self ) -> Duration {
212242 std:: time:: Instant :: elapsed ( self )
213243 }
@@ -221,7 +251,55 @@ impl Time for Eternity {
221251 Self
222252 }
223253
254+ fn duration_since_epoch ( ) -> Duration {
255+ Duration :: from_secs ( 0 )
256+ }
257+
224258 fn elapsed ( & self ) -> Duration {
225259 Duration :: from_secs ( 0 )
226260 }
227261}
262+
263+ impl Sub < Duration > for Eternity {
264+ type Output = Self ;
265+
266+ fn sub ( self , _other : Duration ) -> Self {
267+ self
268+ }
269+ }
270+
271+ impl < T : Time > Writeable for ScorerUsingTime < T > {
272+ #[ inline]
273+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
274+ self . params . write ( w) ?;
275+ self . channel_failures . write ( w)
276+ }
277+ }
278+
279+ impl < T : Time > Readable for ScorerUsingTime < T > {
280+ #[ inline]
281+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
282+ Ok ( Self {
283+ params : Readable :: read ( r) ?,
284+ channel_failures : Readable :: read ( r) ?,
285+ } )
286+ }
287+ }
288+
289+ impl < T : Time > Writeable for ChannelFailure < T > {
290+ #[ inline]
291+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
292+ self . undecayed_penalty_msat . write ( w) ?;
293+ ( T :: duration_since_epoch ( ) - self . last_failed . elapsed ( ) ) . write ( w)
294+ }
295+ }
296+
297+ impl < T : Time > Readable for ChannelFailure < T > {
298+ #[ inline]
299+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
300+ Ok ( Self {
301+ undecayed_penalty_msat : Readable :: read ( r) ?,
302+ last_failed : T :: now ( ) - ( T :: duration_since_epoch ( ) - Readable :: read ( r) ?) ,
303+ } )
304+ }
305+ }
0 commit comments