46
46
47
47
use routing;
48
48
49
+ use ln:: msgs:: DecodeError ;
49
50
use routing:: network_graph:: NodeId ;
50
51
use routing:: router:: RouteHop ;
52
+ use util:: ser:: { Readable , Writeable , Writer } ;
51
53
52
54
use prelude:: * ;
55
+ use core:: ops:: Sub ;
53
56
use core:: time:: Duration ;
57
+ use io:: { self , Read } ;
54
58
55
59
/// [`routing::Score`] implementation that provides reasonable default behavior.
56
60
///
@@ -60,7 +64,7 @@ use core::time::Duration;
60
64
/// See [module-level documentation] for usage.
61
65
///
62
66
/// [module-level documentation]: crate::routing::scorer
63
- pub struct Scorer < C : Clock > {
67
+ pub struct Scorer < C : Clock + Sub < Duration , Output = C > > {
64
68
params : ScoringParameters ,
65
69
channel_failures : HashMap < u64 , ChannelFailure < C > > ,
66
70
}
@@ -81,10 +85,16 @@ pub struct ScoringParameters {
81
85
pub failure_penalty_half_life : Duration ,
82
86
}
83
87
88
+ impl_writeable_tlv_based ! ( ScoringParameters , {
89
+ ( 0 , base_penalty_msat, required) ,
90
+ ( 2 , failure_penalty_msat, required) ,
91
+ ( 4 , failure_penalty_half_life, required) ,
92
+ } ) ;
93
+
84
94
/// Accounting for penalties from channel failures.
85
95
///
86
96
/// Penalties decay over time, though accumulated as more failures occur.
87
- struct ChannelFailure < C : Clock > {
97
+ struct ChannelFailure < C : Clock + Sub < Duration , Output = C > > {
88
98
/// Accumulated penalty in msats for the channel as of `last_failed`.
89
99
undecayed_penalty_msat : u64 ,
90
100
@@ -101,7 +111,7 @@ pub trait Clock {
101
111
fn elapsed ( & self ) -> Duration ;
102
112
}
103
113
104
- impl < C : Clock > Scorer < C > {
114
+ impl < C : Clock + Sub < Duration , Output = C > > Scorer < C > {
105
115
/// Creates a new scorer using the given scoring parameters.
106
116
pub fn new ( params : ScoringParameters ) -> Self {
107
117
Self {
@@ -121,7 +131,7 @@ impl<C: Clock> Scorer<C> {
121
131
}
122
132
}
123
133
124
- impl < C : Clock > ChannelFailure < C > {
134
+ impl < C : Clock + Sub < Duration , Output = C > > ChannelFailure < C > {
125
135
fn new ( failure_penalty_msat : u64 ) -> Self {
126
136
Self {
127
137
undecayed_penalty_msat : failure_penalty_msat,
@@ -143,7 +153,7 @@ impl<C: Clock> ChannelFailure<C> {
143
153
}
144
154
}
145
155
146
- impl < C : Clock > Default for Scorer < C > {
156
+ impl < C : Clock + Sub < Duration , Output = C > > Default for Scorer < C > {
147
157
fn default ( ) -> Self {
148
158
Scorer :: new ( ScoringParameters :: default ( ) )
149
159
}
@@ -159,7 +169,7 @@ impl Default for ScoringParameters {
159
169
}
160
170
}
161
171
162
- impl < C : Clock > routing:: Score for Scorer < C > {
172
+ impl < C : Clock + Sub < Duration , Output = C > > routing:: Score for Scorer < C > {
163
173
fn channel_penalty_msat (
164
174
& self , short_channel_id : u64 , _source : & NodeId , _target : & NodeId
165
175
) -> u64 {
@@ -203,3 +213,57 @@ impl Clock for AlwaysPresent {
203
213
Duration :: from_secs ( 0 )
204
214
}
205
215
}
216
+
217
+ impl Sub < Duration > for AlwaysPresent {
218
+ type Output = Self ;
219
+
220
+ fn sub ( self , _other : Duration ) -> Self {
221
+ self
222
+ }
223
+ }
224
+
225
+ impl < C : Clock + Sub < Duration , Output = C > > Writeable for Scorer < C > {
226
+ #[ inline]
227
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
228
+ self . params . write ( w) ?;
229
+ self . channel_failures . write ( w)
230
+ }
231
+ }
232
+
233
+ impl < C : Clock + Sub < Duration , Output = C > > Readable for Scorer < C > {
234
+ #[ inline]
235
+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
236
+ Ok ( Scorer {
237
+ params : Readable :: read ( r) ?,
238
+ channel_failures : Readable :: read ( r) ?,
239
+ } )
240
+ }
241
+ }
242
+
243
+ impl < C : Clock + Sub < Duration , Output = C > > Writeable for ChannelFailure < C > {
244
+ #[ inline]
245
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
246
+ self . undecayed_penalty_msat . write ( w) ?;
247
+ ( duration_since_epoch ( ) - self . last_failed . elapsed ( ) ) . write ( w)
248
+ }
249
+ }
250
+
251
+ impl < C : Clock + Sub < Duration , Output = C > > Readable for ChannelFailure < C > {
252
+ #[ inline]
253
+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
254
+ Ok ( ChannelFailure {
255
+ undecayed_penalty_msat : Readable :: read ( r) ?,
256
+ last_failed : C :: now ( ) - ( duration_since_epoch ( ) - Readable :: read ( r) ?) ,
257
+ } )
258
+ }
259
+ }
260
+
261
+ fn duration_since_epoch ( ) -> Duration {
262
+ #[ cfg( not( feature = "no-std" ) ) ]
263
+ {
264
+ use std:: time:: SystemTime ;
265
+ SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH ) . unwrap ( )
266
+ }
267
+ #[ cfg( feature = "no-std" ) ]
268
+ return Duration :: from_secs ( 0 ) ;
269
+ }
0 commit comments