mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 21:21:11 +00:00
helper macro to create storage types on the fly (#8456)
* helper macro to create storage types on the fly * Update frame/support/src/lib.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * update lock * fix test; * Fix line width Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
This commit is contained in:
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user