diff --git a/substrate/frame/elections-phragmen/src/migrations_3_0_0.rs b/substrate/frame/elections-phragmen/src/migrations_3_0_0.rs index 8adc4c1a69f7c41cef7303e04065253c5f69d5ab..8afc9ed66920b352bf8dbd99c686f3d6a45f0ffb 100644 --- a/substrate/frame/elections-phragmen/src/migrations_3_0_0.rs +++ b/substrate/frame/elections-phragmen/src/migrations_3_0_0.rs @@ -21,7 +21,6 @@ use codec::{Encode, Decode, FullCodec}; use sp_std::prelude::*; use frame_support::{ RuntimeDebug, weights::Weight, Twox64Concat, - storage::types::{StorageMap, StorageValue}, traits::{GetPalletVersion, PalletVersion}, }; @@ -51,38 +50,21 @@ pub trait V2ToV3 { type Balance: 'static + FullCodec + Copy; } -struct __Candidates; -impl frame_support::traits::StorageInstance for __Candidates { - fn pallet_prefix() -> &'static str { "PhragmenElection" } - const STORAGE_PREFIX: &'static str = "Candidates"; -} - -#[allow(type_alias_bounds)] -type Candidates<T: V2ToV3> = StorageValue<__Candidates, Vec<(T::AccountId, T::Balance)>>; - -struct __Members; -impl frame_support::traits::StorageInstance for __Members { - fn pallet_prefix() -> &'static str { "PhragmenElection" } - const STORAGE_PREFIX: &'static str = "Members"; -} -#[allow(type_alias_bounds)] -type Members<T: V2ToV3> = StorageValue<__Members, Vec<SeatHolder<T::AccountId, T::Balance>>>; - -struct __RunnersUp; -impl frame_support::traits::StorageInstance for __RunnersUp { - fn pallet_prefix() -> &'static str { "PhragmenElection" } - const STORAGE_PREFIX: &'static str = "RunnersUp"; -} -#[allow(type_alias_bounds)] -type RunnersUp<T: V2ToV3> = StorageValue<__RunnersUp, Vec<SeatHolder<T::AccountId, T::Balance>>>; - -struct __Voting; -impl frame_support::traits::StorageInstance for __Voting { - fn pallet_prefix() -> &'static str { "PhragmenElection" } - const STORAGE_PREFIX: &'static str = "Voting"; -} -#[allow(type_alias_bounds)] -type Voting<T: V2ToV3> = StorageMap<__Voting, Twox64Concat, T::AccountId, Voter<T::AccountId, T::Balance>>; +frame_support::generate_storage_alias!( + PhragmenElection, Candidates<T: V2ToV3> => Value<Vec<(T::AccountId, T::Balance)>> +); +frame_support::generate_storage_alias!( + PhragmenElection, Members<T: V2ToV3> => Value<Vec<SeatHolder<T::AccountId, T::Balance>>> +); +frame_support::generate_storage_alias!( + PhragmenElection, RunnersUp<T: V2ToV3> => Value<Vec<SeatHolder<T::AccountId, T::Balance>>> +); +frame_support::generate_storage_alias!( + PhragmenElection, Voting<T: V2ToV3> => Map< + (Twox64Concat, T::AccountId), + Voter<T::AccountId, T::Balance> + > +); /// Apply all of the migrations from 2_0_0 to 3_0_0. /// diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 0ec976e37712319563b808fe7fcaaf9555ccabf0..c28dbc87bccddd0597327e8e90c9c3e048f5f174 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -1036,30 +1036,15 @@ pub mod migrations { pub mod v6 { use super::*; - use frame_support::{traits::Get, weights::Weight, pallet_prelude::*}; - - macro_rules! generate_storage_types { - ($name:ident => Value<$value:ty>) => { - paste::paste! { - struct [<$name Instance>]; - impl frame_support::traits::StorageInstance for [<$name Instance>] { - fn pallet_prefix() -> &'static str { - "Staking" - } - const STORAGE_PREFIX: &'static str = stringify!($name); - } - type $name = StorageValue<[<$name Instance>], $value, ValueQuery>; - } - } - } + use frame_support::{traits::Get, weights::Weight, generate_storage_alias}; // NOTE: value type doesn't matter, we just set it to () here. - generate_storage_types!(SnapshotValidators => Value<()>); - generate_storage_types!(SnapshotNominators => Value<()>); - generate_storage_types!(QueuedElected => Value<()>); - generate_storage_types!(QueuedScore => Value<()>); - generate_storage_types!(EraElectionStatus => Value<()>); - generate_storage_types!(IsCurrentSessionFinal => Value<()>); + generate_storage_alias!(Staking, SnapshotValidators => Value<()>); + generate_storage_alias!(Staking, SnapshotNominators => Value<()>); + generate_storage_alias!(Staking, QueuedElected => Value<()>); + generate_storage_alias!(Staking, QueuedScore => Value<()>); + generate_storage_alias!(Staking, EraElectionStatus => Value<()>); + generate_storage_alias!(Staking, IsCurrentSessionFinal => Value<()>); /// check to execute prior to migration. pub fn pre_migrate<T: Config>() -> Result<(), &'static str> { diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 220e7a06bdf3146cd1c4eb24b1889c9c8966c310..362c4c5a0a73bd267a856af0ac93f92caeeef008 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -87,6 +87,124 @@ pub const LOG_TARGET: &'static str = "runtime::frame-support"; #[derive(Debug, PartialEq, Eq, Clone)] pub enum Never {} +/// Generate a new type alias for [`storage::types::value::StorageValue`], +/// [`storage::types::value::StorageMap`] and [`storage::types::value::StorageDoubleMap`]. +/// +/// Useful for creating a *storage-like* struct for test and migrations. +/// +///``` +/// # use frame_support::generate_storage_alias; +/// use frame_support::codec; +/// use frame_support::Twox64Concat; +/// // generate a storage value with type u32. +/// generate_storage_alias!(Prefix, StorageName => Value<u32>); +/// +/// // generate a double map from `(u32, u32)` (with hasher `Twox64Concat`) to `Vec<u8>` +/// generate_storage_alias!( +/// OtherPrefix, OtherStorageName => DoubleMap< +/// (u32, u32), +/// (u32, u32), +/// Vec<u8> +/// > +/// ); +/// +/// // generate a map from `Config::AccountId` (with hasher `Twox64Concat`) to `Vec<u8>` +/// trait Config { type AccountId: codec::FullCodec; } +/// generate_storage_alias!( +/// Prefix, GenericStorage<T: Config> => Map<(Twox64Concat, T::AccountId), Vec<u8>> +/// ); +/// # fn main() {} +///``` +#[macro_export] +macro_rules! generate_storage_alias { + // without generic for $name. + ($pallet:ident, $name:ident => Map<($key:ty, $hasher:ty), $value:ty>) => { + $crate::paste::paste! { + $crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name); + type $name = $crate::storage::types::StorageMap< + [<$name Instance>], + $hasher, + $key, + $value, + >; + } + }; + ($pallet:ident, $name:ident => DoubleMap<($key1:ty, $hasher1:ty), ($key2:ty, $hasher2:ty), $value:ty>) => { + $crate::paste::paste! { + $crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name); + type $name = $crate::storage::types::StorageMap< + [<$name Instance>], + $hasher1, + $key1, + $hasher2, + $key2, + $value, + >; + } + }; + ($pallet:ident, $name:ident => Value<$value:ty>) => { + $crate::paste::paste! { + $crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name); + type $name = $crate::storage::types::StorageValue< + [<$name Instance>], + $value, + >; + } + }; + // with generic for $name. + ($pallet:ident, $name:ident<$t:ident : $bounds:tt> => Map<($key:ty, $hasher:ty), $value:ty>) => { + $crate::paste::paste! { + $crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name); + #[allow(type_alias_bounds)] + type $name<$t : $bounds> = $crate::storage::types::StorageMap< + [<$name Instance>], + $key, + $hasher, + $value, + >; + } + }; + ( + $pallet:ident, + $name:ident<$t:ident : $bounds:tt> + => DoubleMap<($key1:ty, $hasher1:ty), ($key2:ty, $hasher2:ty), $value:ty>) + => { + $crate::paste::paste! { + $crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name); + #[allow(type_alias_bounds)] + type $name<$t : $bounds> = $crate::storage::types::StorageMap< + [<$name Instance>], + $key1, + $hasher1, + $key2, + $hasher2, + $value, + >; + } + }; + ($pallet:ident, $name:ident<$t:ident : $bounds:tt> => Value<$value:ty>) => { + $crate::paste::paste! { + $crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name); + #[allow(type_alias_bounds)] + type $name<$t : $bounds> = $crate::storage::types::StorageValue< + [<$name Instance>], + $value, + $crate::storage::types::ValueQuery, + >; + } + }; + // helper used in all arms. + (@GENERATE_INSTANCE_STRUCT $pallet:ident, $name:ident) => { + $crate::paste::paste! { + struct [<$name Instance>]; + impl $crate::traits::StorageInstance for [<$name Instance>] { + fn pallet_prefix() -> &'static str { stringify!($pallet) } + const STORAGE_PREFIX: &'static str = stringify!($name); + } + } + } +} + /// Create new implementations of the [`Get`](crate::traits::Get) trait. /// /// The so-called parameter type can be created in four different ways: