diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 0f5b8e0123ab6..3672056534b75 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -881,31 +881,6 @@ impl Default for Forcing { } } -// A value placed in storage that represents the current version of the Staking storage. This value -// is used by the `on_runtime_upgrade` logic to determine whether we run storage migration logic. -// This should match directly with the semantic versions of the Rust crate. -#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -enum Releases { - V1_0_0Ancient, - V2_0_0, - V3_0_0, - V4_0_0, - V5_0_0, // blockable validators. - V6_0_0, // removal of all storage associated with offchain phragmen. - V7_0_0, // keep track of number of nominators / validators in map - V8_0_0, // populate `VoterList`. - V9_0_0, // inject validators into `VoterList` as well. - V10_0_0, // remove `EarliestUnappliedSlash`. - V11_0_0, // Move pallet storage prefix, e.g. BagsList -> VoterBagsList - V12_0_0, // remove `HistoryDepth`. -} - -impl Default for Releases { - fn default() -> Self { - Releases::V11_0_0 - } -} - /// A `Convert` implementation that finds the stash of the given controller account, /// if any. pub struct StashOf(sp_std::marker::PhantomData); diff --git a/frame/staking/src/migrations.rs b/frame/staking/src/migrations.rs index f2ccb4f8b096f..6253c3feed17d 100644 --- a/frame/staking/src/migrations.rs +++ b/frame/staking/src/migrations.rs @@ -18,7 +18,87 @@ use super::*; use frame_election_provider_support::SortedListProvider; -use frame_support::traits::OnRuntimeUpgrade; +use frame_support::{ + dispatch::GetStorageVersion, pallet_prelude::ValueQuery, storage_alias, + traits::OnRuntimeUpgrade, +}; + +/// Used for release versioning upto v12. +/// +/// Obsolete from v13. Keeping around to make encoding/decoding of old migration code easier. +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +enum ObsoleteReleases { + V1_0_0Ancient, + V2_0_0, + V3_0_0, + V4_0_0, + V5_0_0, // blockable validators. + V6_0_0, // removal of all storage associated with offchain phragmen. + V7_0_0, // keep track of number of nominators / validators in map + V8_0_0, // populate `VoterList`. + V9_0_0, // inject validators into `VoterList` as well. + V10_0_0, // remove `EarliestUnappliedSlash`. + V11_0_0, // Move pallet storage prefix, e.g. BagsList -> VoterBagsList + V12_0_0, // remove `HistoryDepth`. +} + +impl Default for ObsoleteReleases { + fn default() -> Self { + ObsoleteReleases::V12_0_0 + } +} + +/// Alias to the old storage item used for release versioning. Obsolete since v13. +#[storage_alias] +type StorageVersion = StorageValue, ObsoleteReleases, ValueQuery>; + +pub mod v13 { + use super::*; + + pub struct MigrateToV13(sp_std::marker::PhantomData); + impl OnRuntimeUpgrade for MigrateToV13 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + frame_support::ensure!( + StorageVersion::::get() == ObsoleteReleases::V12_0_0, + "Required v12 before upgrading to v13" + ); + + Ok(Default::default()) + } + + fn on_runtime_upgrade() -> Weight { + let current = Pallet::::current_storage_version(); + let onchain = StorageVersion::::get(); + + if current == 13 && onchain == ObsoleteReleases::V12_0_0 { + StorageVersion::::kill(); + current.put::>(); + + log!(info, "v13 applied successfully"); + T::DbWeight::get().reads_writes(1, 2) + } else { + log!(warn, "Skipping v13, should be removed"); + T::DbWeight::get().reads(1) + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), &'static str> { + frame_support::ensure!( + Pallet::::on_chain_storage_version() == 13, + "v13 not applied" + ); + + frame_support::ensure!( + !StorageVersion::::exists(), + "Storage version not migrated correctly" + ); + + Ok(()) + } + } +} pub mod v12 { use super::*; @@ -36,7 +116,7 @@ pub mod v12 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, &'static str> { frame_support::ensure!( - StorageVersion::::get() == Releases::V11_0_0, + StorageVersion::::get() == ObsoleteReleases::V11_0_0, "Expected v11 before upgrading to v12" ); @@ -53,9 +133,9 @@ pub mod v12 { } fn on_runtime_upgrade() -> frame_support::weights::Weight { - if StorageVersion::::get() == Releases::V11_0_0 { + if StorageVersion::::get() == ObsoleteReleases::V11_0_0 { HistoryDepth::::kill(); - StorageVersion::::put(Releases::V12_0_0); + StorageVersion::::put(ObsoleteReleases::V12_0_0); log!(info, "v12 applied successfully"); T::DbWeight::get().reads_writes(1, 2) @@ -68,7 +148,7 @@ pub mod v12 { #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), &'static str> { frame_support::ensure!( - StorageVersion::::get() == crate::Releases::V12_0_0, + StorageVersion::::get() == ObsoleteReleases::V12_0_0, "v12 not applied" ); Ok(()) @@ -92,7 +172,7 @@ pub mod v11 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, &'static str> { frame_support::ensure!( - StorageVersion::::get() == crate::Releases::V10_0_0, + StorageVersion::::get() == ObsoleteReleases::V10_0_0, "must upgrade linearly" ); let old_pallet_prefix = twox_128(N::get().as_bytes()); @@ -117,9 +197,9 @@ pub mod v11 { let old_pallet_name = N::get(); let new_pallet_name =

::name(); - if StorageVersion::::get() == Releases::V10_0_0 { + if StorageVersion::::get() == ObsoleteReleases::V10_0_0 { // bump version anyway, even if we don't need to move the prefix - StorageVersion::::put(Releases::V11_0_0); + StorageVersion::::put(ObsoleteReleases::V11_0_0); if new_pallet_name == old_pallet_name { log!( warn, @@ -139,7 +219,7 @@ pub mod v11 { #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), &'static str> { frame_support::ensure!( - StorageVersion::::get() == crate::Releases::V11_0_0, + StorageVersion::::get() == ObsoleteReleases::V11_0_0, "wrong version after the upgrade" ); @@ -184,7 +264,7 @@ pub mod v10 { pub struct MigrateToV10(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV10 { fn on_runtime_upgrade() -> frame_support::weights::Weight { - if StorageVersion::::get() == Releases::V9_0_0 { + if StorageVersion::::get() == ObsoleteReleases::V9_0_0 { let pending_slashes = as Store>::UnappliedSlashes::iter().take(512); for (era, slashes) in pending_slashes { for slash in slashes { @@ -196,7 +276,7 @@ pub mod v10 { } EarliestUnappliedSlash::::kill(); - StorageVersion::::put(Releases::V10_0_0); + StorageVersion::::put(ObsoleteReleases::V10_0_0); log!(info, "MigrateToV10 executed successfully"); T::DbWeight::get().reads_writes(1, 1) @@ -221,7 +301,7 @@ pub mod v9 { pub struct InjectValidatorsIntoVoterList(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for InjectValidatorsIntoVoterList { fn on_runtime_upgrade() -> Weight { - if StorageVersion::::get() == Releases::V8_0_0 { + if StorageVersion::::get() == ObsoleteReleases::V8_0_0 { let prev_count = T::VoterList::count(); let weight_of_cached = Pallet::::weight_of_fn(); for (v, _) in Validators::::iter() { @@ -239,13 +319,13 @@ pub mod v9 { T::VoterList::count(), ); - StorageVersion::::put(crate::Releases::V9_0_0); + StorageVersion::::put(ObsoleteReleases::V9_0_0); T::BlockWeights::get().max_block } else { log!( warn, "InjectValidatorsIntoVoterList being executed on the wrong storage \ - version, expected Releases::V8_0_0" + version, expected ObsoleteReleases::V8_0_0" ); T::DbWeight::get().reads(1) } @@ -254,7 +334,7 @@ pub mod v9 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, &'static str> { frame_support::ensure!( - StorageVersion::::get() == crate::Releases::V8_0_0, + StorageVersion::::get() == ObsoleteReleases::V8_0_0, "must upgrade linearly" ); @@ -272,7 +352,7 @@ pub mod v9 { assert!(post_count == prev_count + validators); frame_support::ensure!( - StorageVersion::::get() == crate::Releases::V9_0_0, + StorageVersion::::get() == ObsoleteReleases::V9_0_0, "must upgrade " ); Ok(()) @@ -281,14 +361,15 @@ pub mod v9 { } pub mod v8 { - use crate::{Config, Nominators, Pallet, StorageVersion, Weight}; + use super::*; + use crate::{Config, Nominators, Pallet, Weight}; use frame_election_provider_support::SortedListProvider; use frame_support::traits::Get; #[cfg(feature = "try-runtime")] pub fn pre_migrate() -> Result<(), &'static str> { frame_support::ensure!( - StorageVersion::::get() == crate::Releases::V7_0_0, + StorageVersion::::get() == ObsoleteReleases::V7_0_0, "must upgrade linearly" ); @@ -298,8 +379,8 @@ pub mod v8 { /// Migration to sorted `VoterList`. pub fn migrate() -> Weight { - if StorageVersion::::get() == crate::Releases::V7_0_0 { - crate::log!(info, "migrating staking to Releases::V8_0_0"); + if StorageVersion::::get() == ObsoleteReleases::V7_0_0 { + crate::log!(info, "migrating staking to ObsoleteReleases::V8_0_0"); let migrated = T::VoterList::unsafe_regenerate( Nominators::::iter().map(|(id, _)| id), @@ -307,10 +388,10 @@ pub mod v8 { ); debug_assert_eq!(T::VoterList::try_state(), Ok(())); - StorageVersion::::put(crate::Releases::V8_0_0); + StorageVersion::::put(ObsoleteReleases::V8_0_0); crate::log!( info, - "👜 completed staking migration to Releases::V8_0_0 with {} voters migrated", + "👜 completed staking migration to ObsoleteReleases::V8_0_0 with {} voters migrated", migrated, ); @@ -348,20 +429,20 @@ pub mod v7 { ); assert!(Validators::::count().is_zero(), "Validators already set."); assert!(Nominators::::count().is_zero(), "Nominators already set."); - assert!(StorageVersion::::get() == Releases::V6_0_0); + assert!(StorageVersion::::get() == ObsoleteReleases::V6_0_0); Ok(()) } pub fn migrate() -> Weight { - log!(info, "Migrating staking to Releases::V7_0_0"); + log!(info, "Migrating staking to ObsoleteReleases::V7_0_0"); let validator_count = Validators::::iter().count() as u32; let nominator_count = Nominators::::iter().count() as u32; CounterForValidators::::put(validator_count); CounterForNominators::::put(nominator_count); - StorageVersion::::put(Releases::V7_0_0); - log!(info, "Completed staking migration to Releases::V7_0_0"); + StorageVersion::::put(ObsoleteReleases::V7_0_0); + log!(info, "Completed staking migration to ObsoleteReleases::V7_0_0"); T::DbWeight::get().reads_writes(validator_count.saturating_add(nominator_count).into(), 2) } @@ -403,7 +484,7 @@ pub mod v6 { /// Migrate storage to v6. pub fn migrate() -> Weight { - log!(info, "Migrating staking to Releases::V6_0_0"); + log!(info, "Migrating staking to ObsoleteReleases::V6_0_0"); SnapshotValidators::::kill(); SnapshotNominators::::kill(); @@ -412,7 +493,8 @@ pub mod v6 { EraElectionStatus::::kill(); IsCurrentSessionFinal::::kill(); - StorageVersion::::put(Releases::V6_0_0); + StorageVersion::::put(ObsoleteReleases::V6_0_0); + log!(info, "Done."); T::DbWeight::get().writes(6 + 1) } diff --git a/frame/staking/src/pallet/mod.rs b/frame/staking/src/pallet/mod.rs index 8e8a8d9c7f600..92502949ef1a0 100644 --- a/frame/staking/src/pallet/mod.rs +++ b/frame/staking/src/pallet/mod.rs @@ -46,7 +46,7 @@ pub use impls::*; use crate::{ slashing, weights::WeightInfo, AccountIdLookupOf, ActiveEraInfo, BalanceOf, EraPayout, EraRewardPoints, Exposure, Forcing, NegativeImbalanceOf, Nominations, PositiveImbalanceOf, - Releases, RewardDestination, SessionInterface, StakingLedger, UnappliedSlash, UnlockChunk, + RewardDestination, SessionInterface, StakingLedger, UnappliedSlash, UnlockChunk, ValidatorPrefs, }; @@ -64,8 +64,12 @@ pub mod pallet { use super::*; + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(13); + #[pallet::pallet] #[pallet::generate_store(pub(crate) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] pub struct Pallet(_); /// Possible operations on the configuration values of this pallet. @@ -561,13 +565,6 @@ pub mod pallet { #[pallet::getter(fn offending_validators)] pub type OffendingValidators = StorageValue<_, Vec<(u32, bool)>, ValueQuery>; - /// True if network has been upgraded to this version. - /// Storage version of the pallet. - /// - /// This is set to v7.0.0 for new networks. - #[pallet::storage] - pub(crate) type StorageVersion = StorageValue<_, Releases, ValueQuery>; - /// The threshold for when users can start calling `chill_other` for other validators / /// nominators. The threshold is compared to the actual number of validators / nominators /// (`CountFor*`) in the system compared to the configured max (`Max*Count`). @@ -618,7 +615,6 @@ pub mod pallet { ForceEra::::put(self.force_era); CanceledSlashPayout::::put(self.canceled_payout); SlashRewardFraction::::put(self.slash_reward_fraction); - StorageVersion::::put(Releases::V7_0_0); MinNominatorBond::::put(self.min_nominator_bond); MinValidatorBond::::put(self.min_validator_bond); if let Some(x) = self.max_validator_count {