@@ -137,7 +137,7 @@ pub mod pallet {
137137 use super :: * ;
138138
139139 /// The current storage version.
140- pub const STORAGE_VERSION : StorageVersion = StorageVersion :: new ( 1 ) ;
140+ pub const STORAGE_VERSION : StorageVersion = StorageVersion :: new ( 2 ) ;
141141
142142 #[ pallet:: pallet]
143143 #[ pallet:: storage_version( STORAGE_VERSION ) ]
@@ -211,7 +211,8 @@ pub mod pallet {
211211 assert ! ( self . params. is_valid( ) ) ;
212212
213213 let starting_era = 1 ;
214- let config = Pallet :: < T > :: recalculate_inflation ( starting_era) ;
214+ let starting_decay_factor = Perquintill :: one ( ) ;
215+ let config = Pallet :: < T > :: recalculate_inflation ( starting_era, starting_decay_factor) ;
215216
216217 ActiveInflationConfig :: < T > :: put ( config) ;
217218 InflationParams :: < T > :: put ( self . params ) ;
@@ -221,13 +222,22 @@ pub mod pallet {
221222 #[ pallet:: hooks]
222223 impl < T : Config > Hooks < BlockNumberFor < T > > for Pallet < T > {
223224 fn on_initialize ( _now : BlockNumberFor < T > ) -> Weight {
224- Self :: payout_block_rewards ( ) ;
225+ let mut weight = T :: DbWeight :: get ( ) . reads ( 1 ) ;
226+ let mut config = ActiveInflationConfig :: < T > :: get ( ) ;
227+
228+ if config. decay_rate != Perquintill :: one ( ) {
229+ config. decay_factor = config. decay_factor * config. decay_rate ;
230+ ActiveInflationConfig :: < T > :: put ( config) ;
231+ weight = weight. saturating_add ( T :: DbWeight :: get ( ) . writes ( 1 ) ) ;
232+ }
233+
234+ Self :: payout_block_rewards ( & config) ;
225235
226236 // Benchmarks won't account for the whitelisted storage access so this needs to be added manually.
227- //
228- // ActiveInflationConfig - 1 DB read
229237 // DoRecalculation - 1 DB read
230- <T as frame_system:: Config >:: DbWeight :: get ( ) . reads ( 2 )
238+ weight = weight. saturating_add ( <T as frame_system:: Config >:: DbWeight :: get ( ) . reads ( 1 ) ) ;
239+
240+ weight
231241 }
232242
233243 fn on_finalize ( _now : BlockNumberFor < T > ) {
@@ -238,7 +248,8 @@ pub mod pallet {
238248 //
239249 // This should be done as late as possible, to ensure all operations that modify issuance are done.
240250 if let Some ( next_era) = DoRecalculation :: < T > :: get ( ) {
241- let config = Self :: recalculate_inflation ( next_era) ;
251+ let decay_factor = ActiveInflationConfig :: < T > :: get ( ) . decay_factor ;
252+ let config = Self :: recalculate_inflation ( next_era, decay_factor) ;
242253 ActiveInflationConfig :: < T > :: put ( config. clone ( ) ) ;
243254 DoRecalculation :: < T > :: kill ( ) ;
244255
@@ -294,8 +305,8 @@ pub mod pallet {
294305 ) -> DispatchResult {
295306 ensure_root ( origin) ?;
296307
297- let config = Self :: recalculate_inflation ( next_era ) ;
298-
308+ let decay_factor = ActiveInflationConfig :: < T > :: get ( ) . decay_factor ;
309+ let config = Self :: recalculate_inflation ( next_era , decay_factor ) ;
299310 ActiveInflationConfig :: < T > :: put ( config. clone ( ) ) ;
300311
301312 Self :: deposit_event ( Event :: < T > :: ForcedInflationRecalculation { config } ) ;
@@ -331,25 +342,25 @@ pub mod pallet {
331342 }
332343
333344 impl < T : Config > Pallet < T > {
334- /// Payout block rewards to the beneficiaries.
335- ///
336- /// Return the total amount issued.
337- fn payout_block_rewards ( ) -> Balance {
338- let config = ActiveInflationConfig :: < T > :: get ( ) ;
345+ /// Payout block rewards to the beneficiaries applying the decay factor.
346+ fn payout_block_rewards ( config : & InflationConfiguration ) {
347+ let collator_rewards = config. decay_factor * config. collator_reward_per_block ;
348+ let treasury_rewards = config. decay_factor * config. treasury_reward_per_block ;
339349
340- let collator_amount = T :: Currency :: issue ( config . collator_reward_per_block ) ;
341- let treasury_amount = T :: Currency :: issue ( config . treasury_reward_per_block ) ;
350+ let collator_amount = T :: Currency :: issue ( collator_rewards ) ;
351+ let treasury_amount = T :: Currency :: issue ( treasury_rewards ) ;
342352
343353 T :: PayoutPerBlock :: collators ( collator_amount) ;
344354 T :: PayoutPerBlock :: treasury ( treasury_amount) ;
345-
346- config. collator_reward_per_block + config. treasury_reward_per_block
347355 }
348356
349357 /// Recalculates the inflation based on the current total issuance & inflation parameters.
350358 ///
351359 /// Returns the new inflation configuration.
352- pub ( crate ) fn recalculate_inflation ( next_era : EraNumber ) -> InflationConfiguration {
360+ pub ( crate ) fn recalculate_inflation (
361+ next_era : EraNumber ,
362+ decay_factor : Perquintill ,
363+ ) -> InflationConfiguration {
353364 // Calculate max emission based on the current total issuance.
354365 let params = InflationParams :: < T > :: get ( ) ;
355366 let total_issuance = T :: Currency :: total_issuance ( ) ;
@@ -358,7 +369,7 @@ pub mod pallet {
358369 let recalculation_era =
359370 next_era. saturating_add ( T :: CycleConfiguration :: eras_per_cycle ( ) ) ;
360371
361- Self :: new_config ( recalculation_era, max_emission)
372+ Self :: new_config ( recalculation_era, max_emission, decay_factor )
362373 }
363374
364375 /// Re-adjust the existing inflation configuration using the current inflation parameters.
@@ -411,13 +422,14 @@ pub mod pallet {
411422 . saturating_add ( bonus_reward_pool) ;
412423
413424 // 4. Calculate new inflation configuration
414- Self :: new_config ( config. recalculation_era , max_emission)
425+ Self :: new_config ( config. recalculation_era , max_emission, config . decay_factor )
415426 }
416427
417428 // Calculate new inflation configuration, based on the provided `max_emission`.
418429 fn new_config (
419430 recalculation_era : EraNumber ,
420431 max_emission : Balance ,
432+ decay_factor : Perquintill ,
421433 ) -> InflationConfiguration {
422434 let params = InflationParams :: < T > :: get ( ) ;
423435
@@ -478,6 +490,8 @@ pub mod pallet {
478490 adjustable_staker_reward_pool_per_era,
479491 bonus_reward_pool_per_period,
480492 ideal_staking_rate : params. ideal_staking_rate ,
493+ decay_rate : params. decay_rate ,
494+ decay_factor,
481495 } ;
482496 new_inflation_config. sanity_check ( ) ;
483497
@@ -512,15 +526,18 @@ pub mod pallet {
512526 let adjustment_factor = staked_ratio / config. ideal_staking_rate ;
513527
514528 let adjustable_part = adjustment_factor * config. adjustable_staker_reward_pool_per_era ;
515- let staker_reward_pool = config
516- . base_staker_reward_pool_per_era
517- . saturating_add ( adjustable_part) ;
529+ let staker_reward_pool = config. decay_factor
530+ * config
531+ . base_staker_reward_pool_per_era
532+ . saturating_add ( adjustable_part) ;
533+ let dapp_reward_pool = config. decay_factor * config. dapp_reward_pool_per_era ;
518534
519- ( staker_reward_pool, config . dapp_reward_pool_per_era )
535+ ( staker_reward_pool, dapp_reward_pool )
520536 }
521537
522538 fn bonus_reward_pool ( ) -> Balance {
523- ActiveInflationConfig :: < T > :: get ( ) . bonus_reward_pool_per_period
539+ let config = ActiveInflationConfig :: < T > :: get ( ) ;
540+ config. decay_factor * config. bonus_reward_pool_per_period
524541 }
525542
526543 fn payout_reward ( account : & T :: AccountId , reward : Balance ) -> Result < ( ) , ( ) > {
@@ -571,6 +588,14 @@ pub struct InflationConfiguration {
571588 /// Used to derive exact amount of adjustable staker rewards.
572589 #[ codec( compact) ]
573590 pub ideal_staking_rate : Perquintill ,
591+ /// Per-block decay rate applied to the decay factor.
592+ /// A value of `Perquintill::one()` means no decay.
593+ #[ codec( compact) ]
594+ pub decay_rate : Perquintill ,
595+ /// Compounded decay multiplied into rewards when they are actually paid.
596+ /// A value of `Perquintill::one()` means no decay.
597+ #[ codec( compact) ]
598+ pub decay_factor : Perquintill ,
574599}
575600
576601impl InflationConfiguration {
@@ -643,6 +668,10 @@ pub struct InflationParameters {
643668 /// Used to derive exact amount of adjustable staker rewards.
644669 #[ codec( compact) ]
645670 pub ideal_staking_rate : Perquintill ,
671+ /// Per-block decay rate applied to all reward pools and per-block rewards.
672+ /// A value of `Perquintill::one()` means no decay.
673+ #[ codec( compact) ]
674+ pub decay_rate : Perquintill ,
646675}
647676
648677impl InflationParameters {
@@ -682,6 +711,13 @@ impl Default for InflationParameters {
682711 adjustable_stakers_part : Perquintill :: from_percent ( 35 ) ,
683712 bonus_part : Perquintill :: from_percent ( 12 ) ,
684713 ideal_staking_rate : Perquintill :: from_percent ( 50 ) ,
714+
715+ // Use non-default decay rate when benchmarking to measure decay calculation
716+ #[ cfg( feature = "runtime-benchmarks" ) ]
717+ decay_rate : Perquintill :: from_percent ( 99 ) ,
718+
719+ #[ cfg( not( feature = "runtime-benchmarks" ) ) ]
720+ decay_rate : Perquintill :: one ( ) ,
685721 }
686722 }
687723}
0 commit comments