diff --git a/Cargo.lock b/Cargo.lock index 20ba70484b..ffef3cb09f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5798,6 +5798,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "log", "orml-utilities", "parity-scale-codec", "scale-info", diff --git a/pallets/msa/Cargo.toml b/pallets/msa/Cargo.toml index c2ec8fffd0..0d5f247d65 100644 --- a/pallets/msa/Cargo.toml +++ b/pallets/msa/Cargo.toml @@ -19,6 +19,7 @@ codec = {package = "parity-scale-codec", version = "3.1.5", default-features = f frame-benchmarking = {default-features = false, git = "https://github.com/paritytech/substrate.git", optional = true, branch = "polkadot-v0.9.27" } frame-support = {default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } frame-system = {default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +log = { version = "0.4.17", default-features = false } scale-info = {version = "2.1.2", default-features = false, features = ["derive"]} sp-core = {default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } sp-runtime = {default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } diff --git a/pallets/msa/src/lib.rs b/pallets/msa/src/lib.rs index c4c28f7447..b573b29f15 100644 --- a/pallets/msa/src/lib.rs +++ b/pallets/msa/src/lib.rs @@ -84,6 +84,9 @@ mod mock; #[cfg(test)] mod tests; +/// Import migrations module which executes migrations when the runtime is upgraded. +pub mod migrations; + pub mod weights; pub use weights::*; @@ -97,6 +100,10 @@ use sp_std::prelude::*; #[frame_support::pallet] pub mod pallet { use super::*; + use frame_support::traits::StorageVersion; + + // Upgrade storage version from 0 to 1 + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::config] pub trait Config: frame_system::Config { @@ -123,6 +130,7 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] pub struct Pallet(_); /// Storage type for MSA identifier @@ -163,10 +171,17 @@ pub mod pallet { /// - Key: AccountId /// - Value: [`MessageSourceId`] #[pallet::storage] - #[pallet::getter(fn get_msa_by_account_id)] pub type MessageSourceIdOf = StorageMap<_, Twox64Concat, T::AccountId, MessageSourceId, OptionQuery>; + /// Migrated Storage type for key to MSA information + /// - Key: AccountId + /// - Value: [`MessageSourceId`] + #[pallet::storage] + #[pallet::getter(fn get_msa_by_account_id)] + pub type MessageSourceMigratedIdOf = + StorageMap<_, Twox64Concat, T::AccountId, MessageSourceId, OptionQuery>; + /// Storage for MSA keys /// - Key: MSA Id /// - Value: List of Keys diff --git a/pallets/msa/src/migrations/mod.rs b/pallets/msa/src/migrations/mod.rs new file mode 100644 index 0000000000..c3b6446630 --- /dev/null +++ b/pallets/msa/src/migrations/mod.rs @@ -0,0 +1,2 @@ +/// Version 1. +pub mod v1; diff --git a/pallets/msa/src/migrations/v1.rs b/pallets/msa/src/migrations/v1.rs new file mode 100644 index 0000000000..a5c33c9112 --- /dev/null +++ b/pallets/msa/src/migrations/v1.rs @@ -0,0 +1,69 @@ +/// Trivial migration which moves MessageSourceIdOf -> MessageSourceMigratedIdOf +/// +/// Note: The depositor is not optional since he can never change. +use crate::*; + +use frame_support::{traits::OnRuntimeUpgrade, weights::Weight}; +use log; +/// Struct on which to implement OnRuntimeUpgrade trait +pub struct MigrateToV1(sp_std::marker::PhantomData); +impl OnRuntimeUpgrade for MigrateToV1 { + /// Perform a module upgrade. + /// + /// # Warning + /// + /// This function will be called before we initialized any runtime state, aka `on_initialize` + /// wasn't called yet. So, information like the block number and any other + /// block local data are not accessible. + /// + /// Return the non-negotiable weight consumed for runtime upgrade. + fn on_runtime_upgrade() -> Weight { + let current = Pallet::::current_storage_version(); + let onchain = Pallet::::on_chain_storage_version(); + log::info!( + "Running MSA migration with current storage version {:?} / onchain {:?}", + current, + onchain + ); + + // Execute the migration when upgrading MSA storage version from version 0 to version 1 + if current == 1 && onchain == 0 { + // Iterate through AccountId in MessageSourceIdOf and + // copy the key/value pair to MessageSourceMigratedIdOf + let mut count = 0; + for (account_id, msa_id) in MessageSourceIdOf::::iter() { + MessageSourceMigratedIdOf::::insert(account_id, msa_id); + count += 1; + } + + // put the current storage version into storage + current.put::>(); + log::info!("Migrated MessageSourceIdOf storage to MessageSourceMigratedIdOf"); + + // Return the weight to reflect the cost of iterating through MessageSourceIdOf + // writing to MessageSourceMigratedIdOf, read the on chain storage version, and update the on chain storage version + T::DbWeight::get().reads_writes(count + 1, count + 1) + } else { + log::info!("MigrateToV1 has already been completed and can be removed."); + + // The weight cost to read the on chain storage version + T::DbWeight::get().reads(1) + } + } + + /// Execute some pre-checks prior to a runtime upgrade. + /// + /// This hook is never meant to be executed on-chain but is meant to be used by testing tools. + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + Ok(()) + } + + /// Execute some post-checks after a runtime upgrade. + /// + /// This hook is never meant to be executed on-chain but is meant to be used by testing tools. + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + Ok(()) + } +} diff --git a/runtime/frequency-rococo/src/lib.rs b/runtime/frequency-rococo/src/lib.rs index 8b0d419361..ea8f12155a 100644 --- a/runtime/frequency-rococo/src/lib.rs +++ b/runtime/frequency-rococo/src/lib.rs @@ -133,8 +133,13 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, + Migrations, >; +// All migrations executed on runtime upgrade as a nested tuple of types implementing +// `OnRuntimeUpgrade`. +type Migrations = (pallet_msa::migrations::v1::MigrateToV1,); + /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the /// node's balance type. /// @@ -190,7 +195,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frequency-rococo"), impl_name: create_runtime_str!("frequency-rococo"), authoring_version: 1, - spec_version: 1, + spec_version: 2, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/frequency/src/lib.rs b/runtime/frequency/src/lib.rs index 0245bf67cc..9e74da915d 100644 --- a/runtime/frequency/src/lib.rs +++ b/runtime/frequency/src/lib.rs @@ -208,7 +208,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frequency"), impl_name: create_runtime_str!("frequency"), authoring_version: 1, - spec_version: 1, + spec_version: 2, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1,