@@ -1138,10 +1138,25 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
1138
1138
}
1139
1139
1140
1140
fn decayed_offset_msat ( & self , offset_msat : u64 ) -> u64 {
1141
- self . now . duration_since ( * self . last_updated ) . as_secs ( )
1142
- . checked_div ( self . decay_params . liquidity_offset_half_life . as_secs ( ) )
1143
- . and_then ( |decays| offset_msat. checked_shr ( decays as u32 ) )
1144
- . unwrap_or ( 0 )
1141
+ let half_life = self . decay_params . liquidity_offset_half_life . as_secs ( ) ;
1142
+ if half_life != 0 {
1143
+ // Decay the offset by the appropriate number of half lives. If half of the next half
1144
+ // life has passed, approximate an additional three-quarter life to help smooth out the
1145
+ // decay.
1146
+ let elapsed_time = self . now . duration_since ( * self . last_updated ) . as_secs ( ) ;
1147
+ let half_decays = elapsed_time / ( half_life / 2 ) ;
1148
+ let decays = half_decays / 2 ;
1149
+ let decayed_offset_msat = offset_msat. checked_shr ( decays as u32 ) . unwrap_or ( 0 ) ;
1150
+ if half_decays % 2 == 0 {
1151
+ decayed_offset_msat
1152
+ } else {
1153
+ // 11_585 / 16_384 ~= core::f64::consts::FRAC_1_SQRT_2
1154
+ // 16_384 == 2^14
1155
+ ( decayed_offset_msat as u128 * 11_585 / 16_384 ) as u64
1156
+ }
1157
+ } else {
1158
+ 0
1159
+ }
1145
1160
}
1146
1161
}
1147
1162
@@ -2392,6 +2407,7 @@ mod tests {
2392
2407
scorer. payment_path_failed ( & payment_path_for_amount ( 768 ) , 42 ) ;
2393
2408
scorer. payment_path_failed ( & payment_path_for_amount ( 128 ) , 43 ) ;
2394
2409
2410
+ // Initial penalties
2395
2411
let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
2396
2412
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
2397
2413
let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2401,7 +2417,8 @@ mod tests {
2401
2417
let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
2402
2418
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
2403
2419
2404
- SinceEpoch :: advance ( Duration :: from_secs ( 9 ) ) ;
2420
+ // No decay
2421
+ SinceEpoch :: advance ( Duration :: from_secs ( 4 ) ) ;
2405
2422
let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
2406
2423
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
2407
2424
let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2411,7 +2428,19 @@ mod tests {
2411
2428
let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
2412
2429
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
2413
2430
2431
+ // Half decay (i.e., three-quarter life)
2414
2432
SinceEpoch :: advance ( Duration :: from_secs ( 1 ) ) ;
2433
+ let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
2434
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 22 ) ;
2435
+ let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
2436
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 106 ) ;
2437
+ let usage = ChannelUsage { amount_msat : 768 , ..usage } ;
2438
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 916 ) ;
2439
+ let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
2440
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
2441
+
2442
+ // One decay (i.e., half life)
2443
+ SinceEpoch :: advance ( Duration :: from_secs ( 5 ) ) ;
2415
2444
let usage = ChannelUsage { amount_msat : 64 , ..usage } ;
2416
2445
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
2417
2446
let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
0 commit comments