This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Adds support for storage parameter types #6296
Merged
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
c73b28f
Adds support for storage parameter types
bkchr 701bd88
Use twox_128
bkchr 37c26c8
Update docs
bkchr 5685925
Merge remote-tracking branch 'origin/master' into bkchr-storage-param…
bkchr c4c6c8d
Update frame/support/src/lib.rs
bkchr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 build using the following formular: | ||
| /// | ||
| /// `twox_128(":" ++ NAME ++ ":")` where `NAME` is the name that is passed as type name. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have each module at |
||
| /// | ||
| /// # 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()); | ||
| }) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.