@@ -1151,10 +1151,25 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
1151
1151
}
1152
1152
1153
1153
fn decayed_offset_msat ( & self , offset_msat : u64 ) -> u64 {
1154
- self . now . duration_since ( * self . last_updated ) . as_secs ( )
1155
- . checked_div ( self . decay_params . liquidity_offset_half_life . as_secs ( ) )
1156
- . and_then ( |decays| offset_msat. checked_shr ( decays as u32 ) )
1157
- . unwrap_or ( 0 )
1154
+ let half_life = self . decay_params . liquidity_offset_half_life . as_secs ( ) ;
1155
+ if half_life != 0 {
1156
+ // Decay the offset by the appropriate number of half lives. If half of the next half
1157
+ // life has passed, approximate an additional three-quarter life to help smooth out the
1158
+ // decay.
1159
+ let elapsed_time = self . now . duration_since ( * self . last_updated ) . as_secs ( ) ;
1160
+ let half_decays = elapsed_time / ( half_life / 2 ) ;
1161
+ let decays = half_decays / 2 ;
1162
+ let decayed_offset_msat = offset_msat. checked_shr ( decays as u32 ) . unwrap_or ( 0 ) ;
1163
+ if half_decays % 2 == 0 {
1164
+ decayed_offset_msat
1165
+ } else {
1166
+ // 11_585 / 16_384 ~= core::f64::consts::FRAC_1_SQRT_2
1167
+ // 16_384 == 2^14
1168
+ ( decayed_offset_msat as u128 * 11_585 / 16_384 ) as u64
1169
+ }
1170
+ } else {
1171
+ 0
1172
+ }
1158
1173
}
1159
1174
}
1160
1175
@@ -2405,6 +2420,7 @@ mod tests {
2405
2420
scorer. payment_path_failed ( & payment_path_for_amount ( 768 ) , 42 ) ;
2406
2421
scorer. payment_path_failed ( & payment_path_for_amount ( 128 ) , 43 ) ;
2407
2422
2423
+ // Initial penalties
2408
2424
let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
2409
2425
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
2410
2426
let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2414,7 +2430,8 @@ mod tests {
2414
2430
let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
2415
2431
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
2416
2432
2417
- SinceEpoch :: advance ( Duration :: from_secs ( 9 ) ) ;
2433
+ // No decay
2434
+ SinceEpoch :: advance ( Duration :: from_secs ( 4 ) ) ;
2418
2435
let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
2419
2436
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
2420
2437
let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2424,7 +2441,19 @@ mod tests {
2424
2441
let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
2425
2442
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
2426
2443
2444
+ // Half decay (i.e., three-quarter life)
2427
2445
SinceEpoch :: advance ( Duration :: from_secs ( 1 ) ) ;
2446
+ let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
2447
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 22 ) ;
2448
+ let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
2449
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 106 ) ;
2450
+ let usage = ChannelUsage { amount_msat : 768 , ..usage } ;
2451
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 916 ) ;
2452
+ let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
2453
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
2454
+
2455
+ // One decay (i.e., half life)
2456
+ SinceEpoch :: advance ( Duration :: from_secs ( 5 ) ) ;
2428
2457
let usage = ChannelUsage { amount_msat : 64 , ..usage } ;
2429
2458
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
2430
2459
let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
0 commit comments