44
44
//! # }
45
45
//! ```
46
46
//!
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
+ //!
47
53
//! [`find_route`]: crate::routing::router::find_route
48
54
49
55
use routing;
50
56
57
+ use ln:: msgs:: DecodeError ;
51
58
use routing:: network_graph:: NodeId ;
52
59
use routing:: router:: RouteHop ;
60
+ use util:: ser:: { Readable , Writeable , Writer } ;
53
61
54
62
use prelude:: * ;
63
+ use core:: ops:: Sub ;
55
64
use core:: time:: Duration ;
65
+ use io:: { self , Read } ;
56
66
57
67
/// [`routing::Score`] implementation that provides reasonable default behavior.
58
68
///
@@ -75,6 +85,10 @@ pub type DefaultTime = Eternity;
75
85
/// [`routing::Score`] implementation parameterized by [`Time`].
76
86
///
77
87
/// See [`Scorer`] for details.
88
+ ///
89
+ /// # Note
90
+ ///
91
+ /// Mixing [`Time`] types between serialization and deserialization results in undefined behavior.
78
92
pub struct ScorerUsingTime < T : Time > {
79
93
params : ScoringParameters ,
80
94
// TODO: Remove entries of closed channels.
@@ -106,6 +120,12 @@ pub struct ScoringParameters {
106
120
pub failure_penalty_half_life : Duration ,
107
121
}
108
122
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
+
109
129
/// Accounting for penalties against a channel for failing to relay any payments.
110
130
///
111
131
/// Penalties decay over time, though accumulate as more failures occur.
@@ -118,12 +138,17 @@ struct ChannelFailure<T: Time> {
118
138
}
119
139
120
140
/// A measurement of time.
121
- pub trait Time {
141
+ pub trait Time : Sub < Duration , Output = Self > where Self : Sized {
122
142
/// Returns an instance corresponding to the current moment.
123
143
fn now ( ) -> Self ;
124
144
125
145
/// Returns the amount of time elapsed since `self` was created.
126
146
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 ;
127
152
}
128
153
129
154
impl < T : Time > ScorerUsingTime < T > {
@@ -211,6 +236,11 @@ impl Time for std::time::Instant {
211
236
std:: time:: Instant :: now ( )
212
237
}
213
238
239
+ fn duration_since_epoch ( ) -> Duration {
240
+ use std:: time:: SystemTime ;
241
+ SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH ) . unwrap ( )
242
+ }
243
+
214
244
fn elapsed ( & self ) -> Duration {
215
245
std:: time:: Instant :: elapsed ( self )
216
246
}
@@ -224,7 +254,55 @@ impl Time for Eternity {
224
254
Self
225
255
}
226
256
257
+ fn duration_since_epoch ( ) -> Duration {
258
+ Duration :: from_secs ( 0 )
259
+ }
260
+
227
261
fn elapsed ( & self ) -> Duration {
228
262
Duration :: from_secs ( 0 )
229
263
}
230
264
}
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