diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs index d04ffab205283..f6c2c270ffe74 100644 --- a/frame/atomic-swap/src/tests.rs +++ b/frame/atomic-swap/src/tests.rs @@ -52,6 +52,7 @@ impl frame_system::Trait for Test { type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; + type MigrateAccount = (); type OnNewAccount = (); type OnKilledAccount = (); } diff --git a/frame/balances/src/migration.rs b/frame/balances/src/migration.rs index 05f84a45e325e..ace17f63fd386 100644 --- a/frame/balances/src/migration.rs +++ b/frame/balances/src/migration.rs @@ -33,7 +33,7 @@ pub fn on_runtime_upgrade, I: Instance>() -> Weight { // Upgrade from the pre-#4649 balances/vesting into the new balances. fn upgrade_v1_to_v2, I: Instance>() -> Weight { - sp_runtime::print("Upgrading Account Balances..."); + sp_runtime::print("🕊️ Migrating Account Balances..."); // First, migrate from old FreeBalance to new Account. // We also move all locks across since only accounts with FreeBalance values have locks. // FreeBalance: map T::AccountId => T::Balance @@ -139,7 +139,7 @@ fn upgrade_v1_to_v2, I: Instance>() -> Weight { StorageVersion::::put(Releases::V2_0_0); - sp_runtime::print("Done Account Balances."); - // TODO determine actual weight + sp_runtime::print("🕊️ Done Account Balances."); + // TODO determine actual weight? T::MaximumBlockWeight::get() } diff --git a/frame/contracts/src/migration.rs b/frame/contracts/src/migration.rs index 089187afce152..39f6657dc0634 100644 --- a/frame/contracts/src/migration.rs +++ b/frame/contracts/src/migration.rs @@ -33,7 +33,7 @@ pub fn on_runtime_upgrade() -> Weight { // upgraded, nothing here will happen anyway. fn change_name_contract_to_contracts() -> Weight { - sp_runtime::print("Migrating Contracts."); + sp_runtime::print("🕊️ Migrating Contracts."); let mut weight = 0; let db = T::DbWeight::get(); @@ -76,6 +76,6 @@ fn change_name_contract_to_contracts() -> Weight { } weight += db.reads(1); - sp_runtime::print("Done Contracts."); + sp_runtime::print("🕊️ Done Contracts."); weight } diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index d56af9c6ef069..d6d8d190e8120 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -630,7 +630,7 @@ impl MigrateAccount for Module { mod migration { use super::*; - pub fn migrate() { + pub fn migrate() -> Weight { mod deprecated { use super::*; @@ -660,6 +660,9 @@ mod migration { DepositOf::::migrate_key_from_blake(p); Preimages::::migrate_key_from_blake(h); } + + // TODO: figure out actual weight + 0 } } @@ -697,6 +700,10 @@ decl_module! { fn deposit_event() = default; + fn on_runtime_upgrade() -> Weight { + migration::migrate::() + } + /// Propose a sensitive action to be taken. /// /// The dispatch origin of this call must be _Signed_ and the sender must diff --git a/frame/finality-tracker/src/migration.rs b/frame/finality-tracker/src/migration.rs index 0ec33d3fd32e0..26a4a1cbd89fa 100644 --- a/frame/finality-tracker/src/migration.rs +++ b/frame/finality-tracker/src/migration.rs @@ -31,7 +31,7 @@ pub fn on_runtime_upgrade() -> Weight { // upgraded, nothing here will happen anyway. fn change_name_timestamp_to_finality_tracker() -> Weight { - sp_runtime::print("Migrating Finality Tracker."); + sp_runtime::print("🕊️ Migrating Finality Tracker."); let mut reads = 0; let mut writes = 0; @@ -65,6 +65,6 @@ fn change_name_timestamp_to_finality_tracker() -> Weight { } reads += 1; - sp_runtime::print("Done Finality Tracker."); + sp_runtime::print("🕊️ Done Finality Tracker."); T::DbWeight::get().reads_writes(reads, writes) } diff --git a/frame/identity/src/migration.rs b/frame/identity/src/migration.rs index 7f69f4ad7ff9c..3eafc3c6b6ed0 100644 --- a/frame/identity/src/migration.rs +++ b/frame/identity/src/migration.rs @@ -31,7 +31,7 @@ pub fn on_runtime_upgrade() -> Weight { // upgraded, nothing here will happen anyway. fn change_name_sudo_to_identity() -> Weight { - sp_runtime::print("Migrating Identity."); + sp_runtime::print("🕊️ Migrating Identity."); let mut weight = 0; let db = T::DbWeight::get(); @@ -56,6 +56,6 @@ fn change_name_sudo_to_identity() -> Weight { } weight += db.reads(1); - sp_runtime::print("Done Identity."); + sp_runtime::print("🕊️ Done Identity."); weight } diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 759e3b99dfa80..ea8e9977c9f5d 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -280,6 +280,8 @@ pub mod slashing; pub mod offchain_election; pub mod inflation; +pub mod migration; + use sp_std::{ result, prelude::*, @@ -1380,7 +1382,7 @@ decl_module! { } fn on_runtime_upgrade() -> Weight { - migrate::(); + migrate_hasher::(); // TODO: determine actual weight 0 } @@ -2228,7 +2230,7 @@ impl MigrateAccount for Module { } } -fn migrate() { +fn migrate_hasher() { if let Some(current_era) = CurrentEra::get() { let history_depth = HistoryDepth::get(); for era in current_era.saturating_sub(history_depth)..=current_era { @@ -2240,27 +2242,6 @@ fn migrate() { } } -fn remove_migrate_era() -> Weight { - #[allow(dead_code)] - mod inner { - pub struct Module(sp_std::marker::PhantomData); - frame_support::decl_storage! { - trait Store for Module as Staking { - pub MigrateEra: Option; - } - } - } - - if let Releases::V3_0_0 = StorageVersion::get() { - StorageVersion::put(Releases::V4_0_0); - inner::MigrateEra::kill(); - - T::DbWeight::get().reads_writes(1, 1) - } else { - T::DbWeight::get().reads(1) - } -} - impl Module { /// The total balance that can be slashed from a stash account as of right now. pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { diff --git a/frame/staking/src/migration.rs b/frame/staking/src/migration.rs new file mode 100644 index 0000000000000..4735c77bbe6a6 --- /dev/null +++ b/frame/staking/src/migration.rs @@ -0,0 +1,151 @@ +use super::*; + +use frame_support::weights::Weight; + +/// Deprecated storages used for migration only. +mod deprecated { + use crate::{Trait, BalanceOf, SessionIndex, Exposure}; + use codec::{Encode, Decode}; + use frame_support::{decl_module, decl_storage}; + use sp_std::prelude::*; + + // edgeware uses `u64` for `Moment` + type Moment = u64; + + /// Reward points of an era. Used to split era total payout between validators. + #[derive(Encode, Decode, Default)] + pub struct EraPoints { + /// Total number of points. Equals the sum of reward points for each validator. + pub total: u32, + /// The reward points earned by a given validator. The index of this vec corresponds to the + /// index into the current validator set. + pub individual: Vec, + } + + decl_module! { + pub struct Module for enum Call where origin: T::Origin { } + } + + decl_storage! { + pub trait Store for Module as Staking { + pub SlotStake: BalanceOf; + + /// The currently elected validator set keyed by stash account ID. + pub CurrentElected: Vec; + + /// The start of the current era. + pub CurrentEraStart: Moment; + + /// The session index at which the current era started. + pub CurrentEraStartSessionIndex: SessionIndex; + + /// Rewards for the current era. Using indices of current elected set. + pub CurrentEraPointsEarned: EraPoints; + + /// Nominators for a particular account that is in action right now. You can't iterate + /// through validators here, but you can find them in the Session module. + /// + /// This is keyed by the stash account. + pub Stakers: map hasher(opaque_blake2_256) T::AccountId => Exposure>; + } + } +} + +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +struct OldStakingLedger { + pub stash: AccountId, + #[codec(compact)] + pub total: Balance, + #[codec(compact)] + pub active: Balance, + pub unlocking: Vec>, +} + +/// Update storages to current version +/// +/// In old version the staking module has several issue about handling session delay, the +/// current era was always considered the active one. +/// +/// After the migration the current era will still be considered the active one for the era of +/// the upgrade. And the delay issue will be fixed when planning the next era. +// * create: +// * ActiveEraStart +// * ErasRewardPoints +// * ActiveEra +// * ErasStakers +// * ErasStakersClipped +// * ErasValidatorPrefs +// * ErasTotalStake +// * ErasStartSessionIndex +// * translate StakingLedger +// * removal of: +// * Stakers +// * SlotStake +// * CurrentElected +// * CurrentEraStart +// * CurrentEraStartSessionIndex +// * CurrentEraPointsEarned +pub fn migrate_to_simple_payouts() -> Weight { + sp_runtime::print("🕊️ Migrating Staking..."); + let current_era_start_index = deprecated::CurrentEraStartSessionIndex::get(); + let current_era = as Store>::CurrentEra::get().unwrap_or(0); + let current_era_start = deprecated::CurrentEraStart::get(); + as Store>::ErasStartSessionIndex::insert(current_era, current_era_start_index); + as Store>::ActiveEra::put(ActiveEraInfo { + index: current_era, + start: Some(current_era_start), + }); + + let current_elected = deprecated::CurrentElected::::get(); + let mut current_total_stake = >::zero(); + for validator in ¤t_elected { + let exposure = deprecated::Stakers::::get(validator); + current_total_stake += exposure.total; + as Store>::ErasStakers::insert(current_era, validator, &exposure); + + let mut exposure_clipped = exposure; + let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize; + if exposure_clipped.others.len() > clipped_max_len { + exposure_clipped.others.sort_unstable_by(|a, b| a.value.cmp(&b.value).reverse()); + exposure_clipped.others.truncate(clipped_max_len); + } + as Store>::ErasStakersClipped::insert(current_era, validator, exposure_clipped); + + let pref = as Store>::Validators::get(validator); + as Store>::ErasValidatorPrefs::insert(current_era, validator, pref); + } + as Store>::ErasTotalStake::insert(current_era, current_total_stake); + + let points = deprecated::CurrentEraPointsEarned::get(); + as Store>::ErasRewardPoints::insert(current_era, EraRewardPoints { + total: points.total, + individual: current_elected.iter().cloned().zip(points.individual.iter().cloned()).collect(), + }); + + let res = as Store>::Ledger::translate_values( + |old: OldStakingLedger>| StakingLedger { + stash: old.stash, + total: old.total, + active: old.active, + unlocking: old.unlocking, + claimed_rewards: vec![], + } + ); + if let Err(e) = res { + frame_support::print("Encountered error in migration of Staking::Ledger map."); + frame_support::print("The number of removed key/value is:"); + frame_support::print(e); + } + + // Kill old storages + deprecated::Stakers::::remove_all(); + deprecated::SlotStake::::kill(); + deprecated::CurrentElected::::kill(); + deprecated::CurrentEraStart::kill(); + deprecated::CurrentEraStartSessionIndex::kill(); + deprecated::CurrentEraPointsEarned::kill(); + + sp_runtime::print("🕊️ Done Staking."); + // TODO: determine actual weight? + T::MaximumBlockWeight::get() +} \ No newline at end of file diff --git a/frame/system/src/migration.rs b/frame/system/src/migration.rs index 19db37f875039..092a6f4bbe5f6 100644 --- a/frame/system/src/migration.rs +++ b/frame/system/src/migration.rs @@ -14,7 +14,7 @@ pub fn migrate_block_hash() -> Weight { let db = T::DbWeight::get(); let block_num = Number::::get(); if block_num > One::one() { - sp_runtime::print("Migrating BlockHashes..."); + sp_runtime::print("🕊️ Migrating BlockHashes..."); BlockHash::::migrate_key_from_blake(T::BlockNumber::zero()); let mut n = block_num - One::one() - One::one(); let mut migrations = 1; @@ -26,7 +26,7 @@ pub fn migrate_block_hash() -> Weight { } n -= One::one(); } - sp_runtime::print("Done BlockHashes"); + sp_runtime::print("🕊️ Done BlockHashes"); db.reads_writes(migrations + 1, migrations) } else { sp_runtime::print("No BlockHashes to migrate..."); @@ -35,7 +35,7 @@ pub fn migrate_block_hash() -> Weight { } pub fn migrate_accounts() -> Weight { - sp_runtime::print("Migrating Accounts..."); + sp_runtime::print("🕊️ Migrating Accounts..."); let mut count = 0u32; if let Ok(accounts) = Vec::::decode(&mut &include_bytes!("accounts.scale")[..]) { for a in &accounts { @@ -50,6 +50,6 @@ pub fn migrate_accounts() -> Weight { } } sp_runtime::print(count); - sp_runtime::print("Done Accounts."); + sp_runtime::print("🕊️ Done Accounts."); T::MaximumBlockWeight::get() } \ No newline at end of file diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index d36417c372799..a6fc4276a028d 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -232,6 +232,10 @@ decl_module! { ).unwrap(), ); } + + fn on_runtime_upgrade() -> Weight { + migration::on_runtime_upgrade::() + } } } diff --git a/frame/transaction-payment/src/migration.rs b/frame/transaction-payment/src/migration.rs index 82592078cced3..3c4f597398f77 100644 --- a/frame/transaction-payment/src/migration.rs +++ b/frame/transaction-payment/src/migration.rs @@ -34,7 +34,7 @@ pub fn on_runtime_upgrade() -> Weight { // upgraded, nothing here will happen anyway. fn rename_and_convert() -> Weight { - sp_runtime::print("Migrating Transaction Payment."); + sp_runtime::print("🕊️ Migrating Transaction Payment."); let mut reads = 0; let mut writes = 0; @@ -49,6 +49,6 @@ fn rename_and_convert() -> Weight { } reads += 1; - sp_runtime::print("Done Transaction Payment."); + sp_runtime::print("🕊️ Done Transaction Payment."); T::DbWeight::get().reads_writes(reads, writes) }