Skip to content

Commit

Permalink
chore(runtime): Adjust target inflation value (#3176)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekovalev authored and shamilsan committed Sep 11, 2023
1 parent 114bb46 commit fc2b754
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 85 deletions.
126 changes: 63 additions & 63 deletions pallets/staking-rewards/src/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ mod test {
}

static TTS: u128 = 10_000_000_000;
static STAKEABLE: u128 = 4_250_000_000; // 42.5% of TTS
static STAKEABLE: u128 = 4_849_000_000; // 48.49% of TTS
static IDEAL_STAKE: Perquintill = Perquintill::from_percent(85);
static MIN_INFLATION: Perquintill = Perquintill::from_percent(1);
static MAX_INFLATION: Perquintill = Perquintill::from_parts(57_800_000_000_000_000_u64); // 5.78%
static MAX_INFLATION: Perquintill = Perquintill::from_parts(60_000_000_000_000_000_u64); // 6.00%
static FALLOFF: Perquintill = Perquintill::from_percent(2);
static MAX_ROI: Perquintill = Perquintill::from_percent(30);
static MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
Expand All @@ -136,26 +136,26 @@ mod test {

let expected_payouts = vec![
(0, 100_000_000),
(63_750_000, 64_367_647),
(127_500_000, 28_735_294),
(184_352_941, 0),
(212_470_588, 0),
(240_588_235, 0),
(268_705_882, 0),
(296_823_529, 0),
(324_941_176, 0),
(353_058_824, 0),
(381_176_471, 0),
(409_294_118, 0),
(437_411_765, 0),
(465_529_412, 0),
(493_647_059, 0),
(521_764_706, 0),
(549_882_353, 0),
(578_000_000, 0),
(184_499_260, 0),
(114_937_500, 0),
(102_640_602, 0),
(72_735_000, 56_676_765),
(145_470_000, 13_353_529),
(188_235_294, 0),
(217_647_059, 0),
(247_058_824, 0),
(276_470_588, 0),
(305_882_353, 0),
(335_294_118, 0),
(364_705_882, 0),
(394_117_647, 0),
(423_529_412, 0),
(452_941_176, 0),
(482_352_941, 0),
(511_764_706, 0),
(541_176_471, 0),
(570_588_235, 0),
(600_000_000, 0),
(188_388_348, 0),
(115_625_000, 0),
(102_762_136, 0),
];
assert_eq!(staked.len(), expected_payouts.len());

Expand Down Expand Up @@ -188,26 +188,26 @@ mod test {

let expected_payouts = vec![
(0, 273_785),
(174_538, 176_229),
(349_076, 78_673),
(504_731, 0),
(581_713, 0),
(658_695, 0),
(735_677, 0),
(812_659, 0),
(889_640, 0),
(966_622, 0),
(1_043_604, 0),
(1_120_586, 0),
(1_197_568, 0),
(1_274_550, 0),
(1_351_532, 0),
(1_428_514, 0),
(1_505_496, 0),
(1_582_478, 0),
(505_131, 0),
(314_682, 0),
(281_015, 0),
(199_138, 155_172),
(398_275, 36_560),
(515_360, 0),
(595_885, 0),
(676_410, 0),
(756_935, 0),
(837_460, 0),
(917_985, 0),
(998_510, 0),
(1_079_035, 0),
(1_159_560, 0),
(1_240_085, 0),
(1_320_610, 0),
(1_401_135, 0),
(1_481_660, 0),
(1_562_185, 0),
(1_642_710, 0),
(515_779, 0),
(316_564, 0),
(281_347, 0),
];
assert_eq!(staked.len(), expected_payouts.len());

Expand Down Expand Up @@ -239,27 +239,27 @@ mod test {
.collect::<Vec<_>>();

let expected_payouts = vec![
(0, 45_631),
(29_090, 29_372),
(58_179, 13_112),
(84_122, 0),
(96_952, 0),
(109_782, 0),
(122_613, 0),
(135_443, 0),
(148_273, 0),
(161_104, 0),
(173_934, 0),
(186_764, 0),
(199_595, 0),
(212_425, 0),
(225_255, 0),
(238_086, 0),
(250_916, 0),
(263_746, 0),
(84_189, 0),
(52_447, 0),
(46_836, 0),
(0, 45_630),
(33_189, 25_862),
(66_379, 6_093),
(85_893, 0),
(99_314, 0),
(112_735, 0),
(126_155, 0),
(139_576, 0),
(152_997, 0),
(166_418, 0),
(179_839, 0),
(193_260, 0),
(206_680, 0),
(220_101, 0),
(233_522, 0),
(246_943, 0),
(260_364, 0),
(273_785, 0),
(85_963, 0),
(52_760, 0),
(46_891, 0),
];
assert_eq!(staked.len(), expected_payouts.len());

Expand Down
23 changes: 13 additions & 10 deletions pallets/staking-rewards/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub mod pallet {
use frame_system::pallet_prelude::*;

/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
Expand Down Expand Up @@ -367,19 +367,22 @@ impl<T: Config> OnUnbalanced<PositiveImbalanceOf<T>> for Pallet<T> {
fn on_nonzero_unbalanced(minted: PositiveImbalanceOf<T>) {
let amount = minted.peek();

let burned = T::Currency::withdraw(
if let Ok(burned) = T::Currency::withdraw(
&Self::account_id(),
amount,
WithdrawReasons::TRANSFER,
ExistenceRequirement::KeepAlive,
)
.unwrap_or_else(|_| NegativeImbalanceOf::<T>::zero());

// Offsetting rewards against rewards pool until the latter is not depleted.
// After that the positive imbalance is dropped adding up to the total supply.
let _ = minted.offset(burned);

Self::deposit_event(Event::Burned { amount });
) {
// Offsetting rewards against rewards pool until the latter is not depleted.
// After that the positive imbalance is dropped adding up to the total supply.
let _ = minted.offset(burned);

Self::deposit_event(Event::Burned { amount });
} else {
log::warn!(
"Staking rewards pool has insufficient balance to burn minted rewards. The currency total supply may grow."
);
};
}
}

Expand Down
94 changes: 87 additions & 7 deletions pallets/staking-rewards/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,94 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::{Config, Pallet, Weight};
use crate::{pallet, Config, Pallet, Weight};
use frame_support::traits::{Get, GetStorageVersion, OnRuntimeUpgrade};
use sp_runtime::Perquintill;
use sp_std::marker::PhantomData;
#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;

/// Wrapper for all migrations of this pallet, based on `StorageVersion`.
pub fn migrate<T: Config>() -> Weight {
use frame_support::traits::GetStorageVersion;
pub struct MigrateToV2<T: Config>(PhantomData<T>);

let _onchain = Pallet::<T>::on_chain_storage_version();
let weight: Weight = Weight::zero();
impl<T: Config> OnRuntimeUpgrade for MigrateToV2<T> {
fn on_runtime_upgrade() -> Weight {
let current = Pallet::<T>::current_storage_version();
let onchain = Pallet::<T>::on_chain_storage_version();

weight
log::info!(
"🚚 Running migration with current storage version {:?} / onchain {:?}",
current,
onchain
);

let mut weight = T::DbWeight::get().reads(1); // 1 read for on chain storage version.

if current == 2 && onchain == 1 {
// Adjusted target inflation parameter: 6.00%
let adjusted_inflation: Perquintill = Perquintill::from_percent(6);
pallet::TargetInflation::<T>::put(adjusted_inflation);

current.put::<Pallet<T>>();

log::info!("Successfully migrated storage from v1 to v2");

// 1 write for `TargetInflation` + 1 write for `StorageVersion`
weight += T::DbWeight::get().writes(2)
} else {
log::info!("❌ Migration did not execute. This probably should be removed");
}

weight
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
use parity_scale_codec::Encode;

let inflation = pallet::TargetInflation::<T>::get();
assert_eq!(inflation, Perquintill::from_rational(578_u64, 10_000_u64));
Ok(inflation.encode())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(state: Vec<u8>) -> Result<(), &'static str> {
use parity_scale_codec::Decode;

let old_inflation: Perquintill = Decode::decode(&mut &state[..]).unwrap();
let new_inflation = pallet::TargetInflation::<T>::get();
assert_ne!(old_inflation, new_inflation);
assert_eq!(new_inflation, Perquintill::from_percent(6));
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::mock::*;
use frame_support::traits::StorageVersion;

#[test]
fn migrate_to_v2() {
ExtBuilder::default()
.initial_authorities(vec![(VAL_1_STASH, VAL_1_CONTROLLER, VAL_1_AUTH_ID)])
.stash(VALIDATOR_STAKE)
.endowment(ENDOWMENT)
.target_inflation(Perquintill::from_rational(578_u64, 10_000_u64))
.build()
.execute_with(|| {
StorageVersion::new(1).put::<Pallet<Test>>();

let weight = MigrateToV2::<Test>::on_runtime_upgrade();
assert_eq!(
weight,
<Test as frame_system::Config>::DbWeight::get().reads_writes(1, 2)
);

assert_eq!(
pallet::TargetInflation::<Test>::get(),
Perquintill::from_percent(6),
);
})
}
}
5 changes: 0 additions & 5 deletions pallets/staking-rewards/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,20 +612,15 @@ pub(crate) fn run_for_n_blocks(n: u64) {

// Run on_initialize hooks in order as they appear in AllPalletsWithSystem.
pub(crate) fn on_initialize(new_block_number: BlockNumberFor<Test>) {
System::on_initialize(new_block_number);
Timestamp::set_timestamp(new_block_number.saturating_mul(MILLISECS_PER_BLOCK));
Balances::on_initialize(new_block_number);
Authorship::on_initialize(new_block_number);
Session::on_initialize(new_block_number);
Staking::on_initialize(new_block_number);
}

// Run on_finalize hooks (in pallets reverse order, as they appear in AllPalletsWithSystem)
pub(crate) fn on_finalize(current_blk: BlockNumberFor<Test>) {
Staking::on_finalize(current_blk);
Authorship::on_finalize(current_blk);
Balances::on_finalize(current_blk);
System::on_finalize(current_blk);
}

pub fn default_test_ext() -> sp_io::TestExternalities {
Expand Down
51 changes: 51 additions & 0 deletions pallets/staking-rewards/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,57 @@ fn unclaimed_rewards_burn() {
});
}

#[test]
fn empty_rewards_pool_causes_inflation() {
let (target_inflation, ideal_stake, _, non_stakeable) = sensible_defaults();
let pool_balance = 0; // empty rewards pool
let mut ext = with_parameters(target_inflation, ideal_stake, pool_balance, non_stakeable);
ext.execute_with(|| {
// Getting up-to-date data on era duration (they may differ from runtime constants)
let sessions_per_era = <Test as pallet_staking::Config>::SessionsPerEra::get() as u64;
let epoch_duration = SESSION_DURATION;
let era_duration = sessions_per_era * epoch_duration;

let (initial_total_issuance, _, _, initial_rewards_pool_balance) = chain_state();
assert_eq!(initial_rewards_pool_balance, 0); // ED is auto-deducted by the getter function

// Running chain until era rollover
run_to_block(era_duration + 1);

// No payout is expected for era #0 anyway because the "official" staked amount is 0
assert_eq!(
Staking::eras_validator_reward(0)
.expect("ErasValidatorReward storage must exist after era end; qed"),
0
);

// Running chain until the next era rollover
run_to_block(2 * era_duration + 1);

// Claim rewards to trigger rewards minting
for era in 0_u32..2 {
pallet_staking::Validators::<Test>::iter().for_each(|(stash_id, _)| {
assert_ok!(Staking::payout_stakers(
RuntimeOrigin::signed(SIGNER),
stash_id,
era
));
});
}

// Take up-to-date measurements of the chain stats
let (total_issuance, _, _, rewards_pool_balance) = chain_state();

// The rewards pool balance is still 0: we should have failed to offset any rewards
assert_eq!(initial_rewards_pool_balance, rewards_pool_balance);
// Staker rewards for eras 0 and 1
let actual_rewards = Staking::eras_validator_reward(1)
.expect("ErasValidatorReward storage must exist after era end; qed");
// Total issuance grew accordingly have changed
assert_eq!(total_issuance, initial_total_issuance + actual_rewards);
});
}

fn sensible_defaults() -> (Perquintill, Perquintill, u128, Perquintill) {
(
Perquintill::from_rational(578_u64, 10_000_u64),
Expand Down
1 change: 1 addition & 0 deletions runtime/vara/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ pub type Migrations = (
pallet_gear_scheduler::migration::MigrateToV2<Runtime>,
pallet_gear_gas::migrations::v2::MigrateToV2<Runtime>,
pallet_gear_messenger::migrations::MigrateToV2<Runtime>,
pallet_gear_staking_rewards::migration::MigrateToV2<Runtime>,
);

0 comments on commit fc2b754

Please sign in to comment.