Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
48 changes: 15 additions & 33 deletions frame/elections-phragmen/src/migrations_3_0_0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};

Expand Down Expand Up @@ -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.
///
Expand Down
29 changes: 7 additions & 22 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()>);
Comment on lines +1042 to +1047
Copy link
Contributor

@Lohann Lohann Mar 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[optional suggestion]

Once the pallet:ident is shared across many storages, what do you think about creating a pattern like this:

generate_storage_alias!(
    Staking,
    SnapshotValidators => Value<()>,
    SnapshotNominators => Value<()>,
    QueuedElected => Value<()>,
    QueuedScore => Value<()>,
    EraElectionStatus => Value<()>,
    IsCurrentSessionFinal => Value<()>,
);


/// check to execute prior to migration.
pub fn pre_migrate<T: Config>() -> Result<(), &'static str> {
Expand Down
118 changes: 118 additions & 0 deletions frame/support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down