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.
@@ -103,6 +117,12 @@ pub struct ScoringParameters {
103
117
pub failure_penalty_half_life : Duration ,
104
118
}
105
119
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
+
106
126
/// Accounting for penalties from channel failures.
107
127
///
108
128
/// Penalties decay over time, though accumulate as more failures occur.
@@ -115,12 +135,17 @@ struct ChannelFailure<T: Time> {
115
135
}
116
136
117
137
/// A measurement of time.
118
- pub trait Time {
138
+ pub trait Time : Sub < Duration , Output = Self > where Self : Sized {
119
139
/// Returns an instance corresponding to the current moment.
120
140
fn now ( ) -> Self ;
121
141
122
142
/// Returns the amount of time elapsed since created.
123
143
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 ;
124
149
}
125
150
126
151
impl < T : Time > ScorerUsingTime < T > {
@@ -208,6 +233,11 @@ impl Time for std::time::Instant {
208
233
std:: time:: Instant :: now ( )
209
234
}
210
235
236
+ fn duration_since_epoch ( ) -> Duration {
237
+ use std:: time:: SystemTime ;
238
+ SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH ) . unwrap ( )
239
+ }
240
+
211
241
fn elapsed ( & self ) -> Duration {
212
242
std:: time:: Instant :: elapsed ( self )
213
243
}
@@ -221,7 +251,55 @@ impl Time for Eternity {
221
251
Self
222
252
}
223
253
254
+ fn duration_since_epoch ( ) -> Duration {
255
+ Duration :: from_secs ( 0 )
256
+ }
257
+
224
258
fn elapsed ( & self ) -> Duration {
225
259
Duration :: from_secs ( 0 )
226
260
}
227
261
}
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