mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 19:17:58 +00:00
Adds support for storage parameter types (#6296)
* Adds support for storage parameter types This pr adds a new parameter types type, the storage parameter types. This parameter type supports loading the value from the storage or returning the given default value. * Use twox_128 * Update docs * Update frame/support/src/lib.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
This commit is contained in:
@@ -44,7 +44,7 @@ pub use paste;
|
||||
#[doc(hidden)]
|
||||
pub use sp_state_machine::BasicExternalities;
|
||||
#[doc(hidden)]
|
||||
pub use sp_io::storage::root as storage_root;
|
||||
pub use sp_io::{storage::root as storage_root, self};
|
||||
#[doc(hidden)]
|
||||
pub use sp_runtime::RuntimeDebug;
|
||||
|
||||
@@ -84,8 +84,24 @@ pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable};
|
||||
#[derive(Debug)]
|
||||
pub enum Never {}
|
||||
|
||||
/// Macro for easily creating a new implementation of the `Get` trait. If `const` token is used, the
|
||||
/// rhs of the expression must be `const`-only, and get is implemented as `const`:
|
||||
/// Create new implementations of the [`Get`](crate::traits::Get) trait.
|
||||
///
|
||||
/// The so-called parameter type can be created in three different ways:
|
||||
///
|
||||
/// - Using `const` to create a parameter type that provides a `const` getter.
|
||||
/// It is required that the `value` is const.
|
||||
///
|
||||
/// - Declare the parameter type without `const` to have more freedom when creating the value.
|
||||
///
|
||||
/// - Using `storage` to create a storage parameter type. This type is special as it tries to
|
||||
/// load the value from the storage under a fixed key. If the value could not be found in the
|
||||
/// storage, the given default value will be returned. It is required that the value implements
|
||||
/// [`Encode`](codec::Encode) and [`Decode`](codec::Decode). The key for looking up the value
|
||||
/// in the storage is built using the following formular:
|
||||
///
|
||||
/// `twox_128(":" ++ NAME ++ ":")` where `NAME` is the name that is passed as type name.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use frame_support::traits::Get;
|
||||
@@ -95,23 +111,27 @@ pub enum Never {}
|
||||
///
|
||||
/// const FIXED_VALUE: u64 = 10;
|
||||
/// parameter_types! {
|
||||
/// pub const Argument: u64 = 42 + FIXED_VALUE;
|
||||
/// pub OtherArgument: u64 = non_const_expression();
|
||||
/// pub const Argument: u64 = 42 + FIXED_VALUE;
|
||||
/// /// Visibility of the type is optional
|
||||
/// OtherArgument: u64 = non_const_expression();
|
||||
/// pub storage StorageArgument: u64 = 5;
|
||||
/// }
|
||||
///
|
||||
/// trait Config {
|
||||
/// type Parameter: Get<u64>;
|
||||
/// type OtherParameter: Get<u64>;
|
||||
/// type Parameter: Get<u64>;
|
||||
/// type OtherParameter: Get<u64>;
|
||||
/// type StorageParameter: Get<u64>;
|
||||
/// }
|
||||
///
|
||||
/// struct Runtime;
|
||||
/// impl Config for Runtime {
|
||||
/// type Parameter = Argument;
|
||||
/// type OtherParameter = OtherArgument;
|
||||
/// type Parameter = Argument;
|
||||
/// type OtherParameter = OtherArgument;
|
||||
/// type StorageParameter = StorageArgument;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Invalid example:
|
||||
/// # Invalid example:
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// # use frame_support::traits::Get;
|
||||
@@ -120,7 +140,7 @@ pub enum Never {}
|
||||
/// fn non_const_expression() -> u64 { 99 }
|
||||
///
|
||||
/// parameter_types! {
|
||||
/// pub const Argument: u64 = non_const_expression();
|
||||
/// pub const Argument: u64 = non_const_expression();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@@ -133,8 +153,8 @@ macro_rules! parameter_types {
|
||||
) => (
|
||||
$( #[ $attr ] )*
|
||||
$vis struct $name;
|
||||
$crate::parameter_types!{IMPL_CONST $name , $type , $value}
|
||||
$crate::parameter_types!{ $( $rest )* }
|
||||
$crate::parameter_types!(IMPL_CONST $name , $type , $value);
|
||||
$crate::parameter_types!( $( $rest )* );
|
||||
);
|
||||
(
|
||||
$( #[ $attr:meta ] )*
|
||||
@@ -143,33 +163,79 @@ macro_rules! parameter_types {
|
||||
) => (
|
||||
$( #[ $attr ] )*
|
||||
$vis struct $name;
|
||||
$crate::parameter_types!{IMPL $name , $type , $value}
|
||||
$crate::parameter_types!{ $( $rest )* }
|
||||
$crate::parameter_types!(IMPL $name, $type, $value);
|
||||
$crate::parameter_types!( $( $rest )* );
|
||||
);
|
||||
(
|
||||
$( #[ $attr:meta ] )*
|
||||
$vis:vis storage $name:ident: $type:ty = $value:expr;
|
||||
$( $rest:tt )*
|
||||
) => (
|
||||
$( #[ $attr ] )*
|
||||
$vis struct $name;
|
||||
$crate::parameter_types!(IMPL_STORAGE $name, $type, $value);
|
||||
$crate::parameter_types!( $( $rest )* );
|
||||
);
|
||||
() => ();
|
||||
(IMPL_CONST $name:ident , $type:ty , $value:expr) => {
|
||||
(IMPL_CONST $name:ident, $type:ty, $value:expr) => {
|
||||
impl $name {
|
||||
/// Returns the value of this parameter type.
|
||||
pub const fn get() -> $type {
|
||||
$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: From<$type>> $crate::traits::Get<I> for $name {
|
||||
fn get() -> I {
|
||||
I::from($value)
|
||||
}
|
||||
}
|
||||
};
|
||||
(IMPL $name:ident , $type:ty , $value:expr) => {
|
||||
(IMPL $name:ident, $type:ty, $value:expr) => {
|
||||
impl $name {
|
||||
/// Returns the value of this parameter type.
|
||||
pub fn get() -> $type {
|
||||
$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: From<$type>> $crate::traits::Get<I> for $name {
|
||||
fn get() -> I {
|
||||
I::from($value)
|
||||
}
|
||||
}
|
||||
};
|
||||
(IMPL_STORAGE $name:ident, $type:ty, $value:expr) => {
|
||||
impl $name {
|
||||
/// Returns the key for this parameter type.
|
||||
pub fn key() -> [u8; 16] {
|
||||
$crate::sp_io::hashing::twox_128(
|
||||
concat!(":", stringify!($name), ":").as_bytes()
|
||||
)
|
||||
}
|
||||
|
||||
/// Set the value of this parameter type in the storage.
|
||||
///
|
||||
/// This needs to be executed in an externalities provided
|
||||
/// environment.
|
||||
pub fn set(value: &$type) {
|
||||
$crate::storage::unhashed::put(&Self::key(), value);
|
||||
}
|
||||
|
||||
/// Returns the value of this parameter type.
|
||||
///
|
||||
/// This needs to be executed in an externalities provided
|
||||
/// environment.
|
||||
pub fn get() -> $type {
|
||||
$crate::storage::unhashed::get(&Self::key()).unwrap_or_else(|| $value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: From<$type>> $crate::traits::Get<I> for $name {
|
||||
fn get() -> I {
|
||||
I::from(Self::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,6 +382,7 @@ mod tests {
|
||||
StorageEntryModifier, DefaultByteGetter, StorageHasher,
|
||||
};
|
||||
use sp_std::marker::PhantomData;
|
||||
use sp_io::TestExternalities;
|
||||
|
||||
pub trait Trait {
|
||||
type BlockNumber: Codec + EncodeLike + Default;
|
||||
@@ -361,7 +428,7 @@ mod tests {
|
||||
type Origin = u32;
|
||||
}
|
||||
|
||||
fn new_test_ext() -> sp_io::TestExternalities {
|
||||
fn new_test_ext() -> TestExternalities {
|
||||
GenesisConfig::default().build_storage().unwrap().into()
|
||||
}
|
||||
|
||||
@@ -696,4 +763,20 @@ mod tests {
|
||||
let metadata = Module::<Test>::storage_metadata();
|
||||
pretty_assertions::assert_eq!(EXPECTED_METADATA, metadata);
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
storage StorageParameter: u64 = 10;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_storage_parameter_type_works() {
|
||||
TestExternalities::default().execute_with(|| {
|
||||
assert_eq!(sp_io::hashing::twox_128(b":StorageParameter:"), StorageParameter::key());
|
||||
|
||||
assert_eq!(10, StorageParameter::get());
|
||||
|
||||
StorageParameter::set(&300);
|
||||
assert_eq!(300, StorageParameter::get());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,9 +450,11 @@ impl<T: IntoIterator + Clone,> Len for T where <T as IntoIterator>::IntoIter: Ex
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for querying a single fixed value from a type.
|
||||
/// A trait for querying a single value from a type.
|
||||
///
|
||||
/// It is not required that the value is constant.
|
||||
pub trait Get<T> {
|
||||
/// Return a constant value.
|
||||
/// Return the current value.
|
||||
fn get() -> T;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user