@@ -1151,10 +1151,25 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
11511151 }
11521152
11531153 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+ }
11581173 }
11591174}
11601175
@@ -2405,6 +2420,7 @@ mod tests {
24052420 scorer. payment_path_failed ( & payment_path_for_amount ( 768 ) , 42 ) ;
24062421 scorer. payment_path_failed ( & payment_path_for_amount ( 128 ) , 43 ) ;
24072422
2423+ // Initial penalties
24082424 let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
24092425 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
24102426 let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2414,7 +2430,8 @@ mod tests {
24142430 let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
24152431 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
24162432
2417- SinceEpoch :: advance ( Duration :: from_secs ( 9 ) ) ;
2433+ // No decay
2434+ SinceEpoch :: advance ( Duration :: from_secs ( 4 ) ) ;
24182435 let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
24192436 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
24202437 let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2424,7 +2441,19 @@ mod tests {
24242441 let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
24252442 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
24262443
2444+ // Half decay (i.e., three-quarter life)
24272445 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 ) ) ;
24282457 let usage = ChannelUsage { amount_msat : 64 , ..usage } ;
24292458 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
24302459 let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
0 commit comments