@@ -98,16 +98,37 @@ pub struct ScorerUsingTime<T: Time> {
98
98
/// Parameters for configuring [`Scorer`].
99
99
pub struct ScoringParameters {
100
100
/// A fixed penalty in msats to apply to each channel.
101
+ ///
102
+ /// Default value: 500 msat
101
103
pub base_penalty_msat : u64 ,
102
104
103
105
/// A penalty in msats to apply to a channel upon failing to relay a payment.
104
106
///
105
107
/// This accumulates for each failure but may be reduced over time based on
106
108
/// [`failure_penalty_half_life`].
107
109
///
110
+ /// Default value: 1,024,000 msat
111
+ ///
108
112
/// [`failure_penalty_half_life`]: Self::failure_penalty_half_life
109
113
pub failure_penalty_msat : u64 ,
110
114
115
+ /// When the amount being sent over a channel is this many 1024ths of the total channel
116
+ /// capacity, we begin applying [`overuse_penalty_msat_per_1024th`].
117
+ ///
118
+ /// Default value: 128 1024ths (i.e. begin penalizing when an HTLC uses 1/8th of a channel)
119
+ ///
120
+ /// [`overuse_penalty_msat_per_1024th`]: Self::overuse_penalty_msat_per_1024th
121
+ pub overuse_penalty_start_1024th : u16 ,
122
+
123
+ /// A penalty applied, per whole 1024ths of the channel capacity which the amount being sent
124
+ /// over the channel exceeds [`overuse_penalty_start_1024th`] by.
125
+ ///
126
+ /// Default value: 20 msat (i.e. 2560 msat penalty to use 1/4th of a channel, 7680 msat penalty
127
+ /// to use half a channel, and 12,560 msat penalty to use 3/4ths of a channel)
128
+ ///
129
+ /// [`overuse_penalty_start_1024th`]: Self::overuse_penalty_start_1024th
130
+ pub overuse_penalty_msat_per_1024th : u64 ,
131
+
111
132
/// The time required to elapse before any accumulated [`failure_penalty_msat`] penalties are
112
133
/// cut in half.
113
134
///
@@ -122,7 +143,9 @@ pub struct ScoringParameters {
122
143
123
144
impl_writeable_tlv_based ! ( ScoringParameters , {
124
145
( 0 , base_penalty_msat, required) ,
146
+ ( 1 , overuse_penalty_start_1024th, ( default_value, 128 ) ) ,
125
147
( 2 , failure_penalty_msat, required) ,
148
+ ( 3 , overuse_penalty_msat_per_1024th, ( default_value, 20 ) ) ,
126
149
( 4 , failure_penalty_half_life, required) ,
127
150
} ) ;
128
151
@@ -167,6 +190,8 @@ impl<T: Time> ScorerUsingTime<T> {
167
190
base_penalty_msat : penalty_msat,
168
191
failure_penalty_msat : 0 ,
169
192
failure_penalty_half_life : Duration :: from_secs ( 0 ) ,
193
+ overuse_penalty_start_1024th : 1024 ,
194
+ overuse_penalty_msat_per_1024th : 0 ,
170
195
} )
171
196
}
172
197
}
@@ -205,19 +230,34 @@ impl Default for ScoringParameters {
205
230
base_penalty_msat : 500 ,
206
231
failure_penalty_msat : 1024 * 1000 ,
207
232
failure_penalty_half_life : Duration :: from_secs ( 3600 ) ,
233
+ overuse_penalty_start_1024th : 1024 / 8 ,
234
+ overuse_penalty_msat_per_1024th : 20 ,
208
235
}
209
236
}
210
237
}
211
238
212
239
impl < T : Time > routing:: Score for ScorerUsingTime < T > {
213
240
fn channel_penalty_msat (
214
- & self , short_channel_id : u64 , _send_amt_msat : u64 , _chan_capacity_msat : Option < u64 > , _source : & NodeId , _target : & NodeId
241
+ & self , short_channel_id : u64 , send_amt_msat : u64 , chan_capacity_opt : Option < u64 > , _source : & NodeId , _target : & NodeId
215
242
) -> u64 {
216
243
let failure_penalty_msat = self . channel_failures
217
244
. get ( & short_channel_id)
218
245
. map_or ( 0 , |value| value. decayed_penalty_msat ( self . params . failure_penalty_half_life ) ) ;
219
246
220
- self . params . base_penalty_msat + failure_penalty_msat
247
+ let mut penalty_msat = self . params . base_penalty_msat + failure_penalty_msat;
248
+
249
+ if let Some ( chan_capacity_msat) = chan_capacity_opt {
250
+ let send_1024ths = send_amt_msat. checked_mul ( 1024 ) . unwrap_or ( u64:: max_value ( ) ) / chan_capacity_msat;
251
+
252
+ if send_1024ths > self . params . overuse_penalty_start_1024th as u64 {
253
+ penalty_msat = penalty_msat. checked_add (
254
+ ( send_1024ths - self . params . overuse_penalty_start_1024th as u64 )
255
+ . checked_mul ( self . params . overuse_penalty_msat_per_1024th ) . unwrap_or ( u64:: max_value ( ) ) )
256
+ . unwrap_or ( u64:: max_value ( ) ) ;
257
+ }
258
+ }
259
+
260
+ penalty_msat
221
261
}
222
262
223
263
fn payment_path_failed ( & mut self , _path : & [ & RouteHop ] , short_channel_id : u64 ) {
@@ -414,6 +454,8 @@ mod tests {
414
454
base_penalty_msat : 1_000 ,
415
455
failure_penalty_msat : 512 ,
416
456
failure_penalty_half_life : Duration :: from_secs ( 1 ) ,
457
+ overuse_penalty_start_1024th : 1024 ,
458
+ overuse_penalty_msat_per_1024th : 0 ,
417
459
} ) ;
418
460
let source = source_node_id ( ) ;
419
461
let target = target_node_id ( ) ;
@@ -429,6 +471,8 @@ mod tests {
429
471
base_penalty_msat : 1_000 ,
430
472
failure_penalty_msat : 64 ,
431
473
failure_penalty_half_life : Duration :: from_secs ( 10 ) ,
474
+ overuse_penalty_start_1024th : 1024 ,
475
+ overuse_penalty_msat_per_1024th : 0 ,
432
476
} ) ;
433
477
let source = source_node_id ( ) ;
434
478
let target = target_node_id ( ) ;
@@ -450,6 +494,8 @@ mod tests {
450
494
base_penalty_msat : 1_000 ,
451
495
failure_penalty_msat : 512 ,
452
496
failure_penalty_half_life : Duration :: from_secs ( 10 ) ,
497
+ overuse_penalty_start_1024th : 1024 ,
498
+ overuse_penalty_msat_per_1024th : 0 ,
453
499
} ) ;
454
500
let source = source_node_id ( ) ;
455
501
let target = target_node_id ( ) ;
@@ -480,6 +526,8 @@ mod tests {
480
526
base_penalty_msat : 1_000 ,
481
527
failure_penalty_msat : 512 ,
482
528
failure_penalty_half_life : Duration :: from_secs ( 10 ) ,
529
+ overuse_penalty_start_1024th : 1024 ,
530
+ overuse_penalty_msat_per_1024th : 0 ,
483
531
} ) ;
484
532
let source = source_node_id ( ) ;
485
533
let target = target_node_id ( ) ;
@@ -504,6 +552,8 @@ mod tests {
504
552
base_penalty_msat : 1_000 ,
505
553
failure_penalty_msat : 512 ,
506
554
failure_penalty_half_life : Duration :: from_secs ( 10 ) ,
555
+ overuse_penalty_start_1024th : 1024 ,
556
+ overuse_penalty_msat_per_1024th : 0 ,
507
557
} ) ;
508
558
let source = source_node_id ( ) ;
509
559
let target = target_node_id ( ) ;
@@ -531,6 +581,8 @@ mod tests {
531
581
base_penalty_msat : 1_000 ,
532
582
failure_penalty_msat : 512 ,
533
583
failure_penalty_half_life : Duration :: from_secs ( 10 ) ,
584
+ overuse_penalty_start_1024th : 1024 ,
585
+ overuse_penalty_msat_per_1024th : 0 ,
534
586
} ) ;
535
587
let source = source_node_id ( ) ;
536
588
let target = target_node_id ( ) ;
@@ -549,4 +601,24 @@ mod tests {
549
601
SinceEpoch :: advance ( Duration :: from_secs ( 10 ) ) ;
550
602
assert_eq ! ( deserialized_scorer. channel_penalty_msat( 42 , 1 , Some ( 1 ) , & source, & target) , 1_128 ) ;
551
603
}
604
+
605
+ #[ test]
606
+ fn charges_per_1024th_penalty ( ) {
607
+ let scorer = Scorer :: new ( ScoringParameters {
608
+ base_penalty_msat : 0 ,
609
+ failure_penalty_msat : 0 ,
610
+ failure_penalty_half_life : Duration :: from_secs ( 0 ) ,
611
+ overuse_penalty_start_1024th : 256 ,
612
+ overuse_penalty_msat_per_1024th : 100 ,
613
+ } ) ;
614
+ let source = source_node_id ( ) ;
615
+ let target = target_node_id ( ) ;
616
+
617
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , 1_000 , None , & source, & target) , 0 ) ;
618
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , 1_000 , Some ( 1_024_000 ) , & source, & target) , 0 ) ;
619
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , 256_999 , Some ( 1_024_000 ) , & source, & target) , 0 ) ;
620
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , 257_000 , Some ( 1_024_000 ) , & source, & target) , 100 ) ;
621
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , 258_000 , Some ( 1_024_000 ) , & source, & target) , 200 ) ;
622
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , 512_000 , Some ( 1_024_000 ) , & source, & target) , 256 * 100 ) ;
623
+ }
552
624
}
0 commit comments