@@ -1138,10 +1138,25 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
11381138 }
11391139
11401140 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+ }
11451160 }
11461161}
11471162
@@ -2392,6 +2407,7 @@ mod tests {
23922407 scorer. payment_path_failed ( & payment_path_for_amount ( 768 ) , 42 ) ;
23932408 scorer. payment_path_failed ( & payment_path_for_amount ( 128 ) , 43 ) ;
23942409
2410+ // Initial penalties
23952411 let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
23962412 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
23972413 let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2401,7 +2417,8 @@ mod tests {
24012417 let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
24022418 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
24032419
2404- SinceEpoch :: advance ( Duration :: from_secs ( 9 ) ) ;
2420+ // No decay
2421+ SinceEpoch :: advance ( Duration :: from_secs ( 4 ) ) ;
24052422 let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
24062423 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
24072424 let usage = ChannelUsage { amount_msat : 256 , ..usage } ;
@@ -2411,7 +2428,19 @@ mod tests {
24112428 let usage = ChannelUsage { amount_msat : 896 , ..usage } ;
24122429 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , u64 :: max_value( ) ) ;
24132430
2431+ // Half decay (i.e., three-quarter life)
24142432 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 ) ) ;
24152444 let usage = ChannelUsage { amount_msat : 64 , ..usage } ;
24162445 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage, & params) , 0 ) ;
24172446 let usage = ChannelUsage { amount_msat : 128 , ..usage } ;
0 commit comments