48
48
49
49
use routing;
50
50
51
+ use ln:: msgs:: DecodeError ;
51
52
use routing:: network_graph:: NodeId ;
52
53
use routing:: router:: RouteHop ;
54
+ use util:: ser:: { Readable , Writeable , Writer } ;
53
55
54
56
use prelude:: * ;
57
+ use core:: ops:: Sub ;
55
58
use core:: time:: Duration ;
59
+ use io:: { self , Read } ;
56
60
57
61
/// [`routing::Score`] implementation that provides reasonable default behavior.
58
62
///
@@ -75,7 +79,7 @@ pub type DefaultTime = Eternity;
75
79
/// [`routing::Score`] implementation parameterized by [`Time`].
76
80
///
77
81
/// See [`Scorer`] for details.
78
- pub struct ScorerUsingTime < T : Time > {
82
+ pub struct ScorerUsingTime < T : Time + Sub < Duration , Output = T > > {
79
83
params : ScoringParameters ,
80
84
// TODO: Remove entries of closed channels.
81
85
channel_failures : HashMap < u64 , ChannelFailure < T > > ,
@@ -103,10 +107,16 @@ pub struct ScoringParameters {
103
107
pub failure_penalty_half_life : Duration ,
104
108
}
105
109
110
+ impl_writeable_tlv_based ! ( ScoringParameters , {
111
+ ( 0 , base_penalty_msat, required) ,
112
+ ( 2 , failure_penalty_msat, required) ,
113
+ ( 4 , failure_penalty_half_life, required) ,
114
+ } ) ;
115
+
106
116
/// Accounting for penalties from channel failures.
107
117
///
108
118
/// Penalties decay over time, though accumulate as more failures occur.
109
- struct ChannelFailure < T : Time > {
119
+ struct ChannelFailure < T : Time + Sub < Duration , Output = T > > {
110
120
/// Accumulated penalty in msats for the channel as of `last_failed`.
111
121
undecayed_penalty_msat : u64 ,
112
122
@@ -123,7 +133,7 @@ pub trait Time {
123
133
fn elapsed ( & self ) -> Duration ;
124
134
}
125
135
126
- impl < T : Time > ScorerUsingTime < T > {
136
+ impl < T : Time + Sub < Duration , Output = T > > ScorerUsingTime < T > {
127
137
/// Creates a new scorer using the given scoring parameters.
128
138
pub fn new ( params : ScoringParameters ) -> Self {
129
139
Self {
@@ -143,7 +153,7 @@ impl<T: Time> ScorerUsingTime<T> {
143
153
}
144
154
}
145
155
146
- impl < T : Time > ChannelFailure < T > {
156
+ impl < T : Time + Sub < Duration , Output = T > > ChannelFailure < T > {
147
157
fn new ( failure_penalty_msat : u64 ) -> Self {
148
158
Self {
149
159
undecayed_penalty_msat : failure_penalty_msat,
@@ -165,7 +175,7 @@ impl<T: Time> ChannelFailure<T> {
165
175
}
166
176
}
167
177
168
- impl < T : Time > Default for ScorerUsingTime < T > {
178
+ impl < T : Time + Sub < Duration , Output = T > > Default for ScorerUsingTime < T > {
169
179
fn default ( ) -> Self {
170
180
Self :: new ( ScoringParameters :: default ( ) )
171
181
}
@@ -181,7 +191,7 @@ impl Default for ScoringParameters {
181
191
}
182
192
}
183
193
184
- impl < T : Time > routing:: Score for ScorerUsingTime < T > {
194
+ impl < T : Time + Sub < Duration , Output = T > > routing:: Score for ScorerUsingTime < T > {
185
195
fn channel_penalty_msat (
186
196
& self , short_channel_id : u64 , _source : & NodeId , _target : & NodeId
187
197
) -> u64 {
@@ -225,3 +235,57 @@ impl Time for Eternity {
225
235
Duration :: from_secs ( 0 )
226
236
}
227
237
}
238
+
239
+ impl Sub < Duration > for Eternity {
240
+ type Output = Self ;
241
+
242
+ fn sub ( self , _other : Duration ) -> Self {
243
+ self
244
+ }
245
+ }
246
+
247
+ impl < T : Time + Sub < Duration , Output = T > > Writeable for ScorerUsingTime < T > {
248
+ #[ inline]
249
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
250
+ self . params . write ( w) ?;
251
+ self . channel_failures . write ( w)
252
+ }
253
+ }
254
+
255
+ impl < T : Time + Sub < Duration , Output = T > > Readable for ScorerUsingTime < T > {
256
+ #[ inline]
257
+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
258
+ Ok ( Self {
259
+ params : Readable :: read ( r) ?,
260
+ channel_failures : Readable :: read ( r) ?,
261
+ } )
262
+ }
263
+ }
264
+
265
+ impl < T : Time + Sub < Duration , Output = T > > Writeable for ChannelFailure < T > {
266
+ #[ inline]
267
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
268
+ self . undecayed_penalty_msat . write ( w) ?;
269
+ ( duration_since_epoch ( ) - self . last_failed . elapsed ( ) ) . write ( w)
270
+ }
271
+ }
272
+
273
+ impl < T : Time + Sub < Duration , Output = T > > Readable for ChannelFailure < T > {
274
+ #[ inline]
275
+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
276
+ Ok ( Self {
277
+ undecayed_penalty_msat : Readable :: read ( r) ?,
278
+ last_failed : T :: now ( ) - ( duration_since_epoch ( ) - Readable :: read ( r) ?) ,
279
+ } )
280
+ }
281
+ }
282
+
283
+ fn duration_since_epoch ( ) -> Duration {
284
+ #[ cfg( not( feature = "no-std" ) ) ]
285
+ {
286
+ use std:: time:: SystemTime ;
287
+ SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH ) . unwrap ( )
288
+ }
289
+ #[ cfg( feature = "no-std" ) ]
290
+ return Duration :: from_secs ( 0 ) ;
291
+ }
0 commit comments