mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 18:11:10 +00:00
feat: compute pallet/storage prefix hash at compile time (#1539)
Since the hash rules of this part of the `pallet_prefix/storage_prefix` are always fixed, we can put the runtime calculation into compile time. --- polkadot address: 15ouFh2SHpGbHtDPsJ6cXQfes9Cx1gEFnJJsJVqPGzBSTudr --------- Co-authored-by: Juan <juangirini@gmail.com> Co-authored-by: command-bot <> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Generated
+1
@@ -5289,6 +5289,7 @@ dependencies = [
|
||||
"proc-macro-warning",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sp-core-hashing",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ pub struct ProposerFactory<A, B, C, PR> {
|
||||
/// The soft deadline indicates where we should stop attempting to add transactions
|
||||
/// to the block, which exhaust resources. After soft deadline is reached,
|
||||
/// we switch to a fixed-amount mode, in which after we see `MAX_SKIPPED_TRANSACTIONS`
|
||||
/// transactions which exhaust resrouces, we will conclude that the block is full.
|
||||
/// transactions which exhaust resources, we will conclude that the block is full.
|
||||
soft_deadline_percent: Percent,
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
/// When estimating the block size, should the proof be included?
|
||||
|
||||
@@ -42,8 +42,8 @@ where
|
||||
.to_string()],
|
||||
at: None,
|
||||
hashed_prefixes: vec![
|
||||
<pallet_staking::Bonded<Runtime>>::prefix_hash(),
|
||||
<pallet_staking::Ledger<Runtime>>::prefix_hash(),
|
||||
<pallet_staking::Bonded<Runtime>>::prefix_hash().to_vec(),
|
||||
<pallet_staking::Ledger<Runtime>>::prefix_hash().to_vec(),
|
||||
<pallet_staking::Validators<Runtime>>::map_storage_final_prefix(),
|
||||
<pallet_staking::Nominators<Runtime>>::map_storage_final_prefix(),
|
||||
],
|
||||
|
||||
@@ -39,8 +39,8 @@ pub async fn execute<Runtime, Block>(
|
||||
pallets: vec![pallet_bags_list::Pallet::<Runtime, pallet_bags_list::Instance1>::name()
|
||||
.to_string()],
|
||||
hashed_prefixes: vec![
|
||||
<pallet_staking::Bonded<Runtime>>::prefix_hash(),
|
||||
<pallet_staking::Ledger<Runtime>>::prefix_hash(),
|
||||
<pallet_staking::Bonded<Runtime>>::prefix_hash().to_vec(),
|
||||
<pallet_staking::Ledger<Runtime>>::prefix_hash().to_vec(),
|
||||
],
|
||||
..Default::default()
|
||||
}))
|
||||
|
||||
@@ -53,7 +53,7 @@ pub type ValueIndex = u32;
|
||||
/// [`Page`]s.
|
||||
///
|
||||
/// Each [`Page`] holds at most `ValuesPerNewPage` values in its `values` vector. The last page is
|
||||
/// the only one that could have less than `ValuesPerNewPage` values.
|
||||
/// the only one that could have less than `ValuesPerNewPage` values.
|
||||
/// **Iteration** happens by starting
|
||||
/// at [`first_page`][StoragePagedListMeta::first_page]/
|
||||
/// [`first_value_offset`][StoragePagedListMeta::first_value_offset] and incrementing these indices
|
||||
@@ -373,11 +373,11 @@ where
|
||||
/// that are completely useless for prefix calculation.
|
||||
struct StoragePagedListPrefix<Prefix>(PhantomData<Prefix>);
|
||||
|
||||
impl<Prefix> frame_support::storage::StoragePrefixedContainer for StoragePagedListPrefix<Prefix>
|
||||
impl<Prefix> StoragePrefixedContainer for StoragePagedListPrefix<Prefix>
|
||||
where
|
||||
Prefix: StorageInstance,
|
||||
{
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
Prefix::pallet_prefix().as_bytes()
|
||||
}
|
||||
|
||||
@@ -386,15 +386,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Prefix, Value, ValuesPerNewPage> frame_support::storage::StoragePrefixedContainer
|
||||
impl<Prefix, Value, ValuesPerNewPage> StoragePrefixedContainer
|
||||
for StoragePagedList<Prefix, Value, ValuesPerNewPage>
|
||||
where
|
||||
Prefix: StorageInstance,
|
||||
Value: FullCodec,
|
||||
ValuesPerNewPage: Get<u32>,
|
||||
{
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
StoragePagedListPrefix::<Prefix>::module_prefix()
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
StoragePagedListPrefix::<Prefix>::pallet_prefix()
|
||||
}
|
||||
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
|
||||
@@ -26,6 +26,7 @@ frame-support-procedural-tools = { path = "tools" }
|
||||
proc-macro-warning = { version = "0.4.2", default-features = false }
|
||||
macro_magic = { version = "0.4.2", features = ["proc_support"] }
|
||||
expander = "2.0.0"
|
||||
sp-core-hashing = { path = "../../../primitives/core/hashing" }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
|
||||
@@ -211,6 +211,7 @@
|
||||
mod expand;
|
||||
mod parse;
|
||||
|
||||
use crate::pallet::parse::helper::two128_str;
|
||||
use cfg_expr::Predicate;
|
||||
use frame_support_procedural_tools::{
|
||||
generate_crate_access, generate_crate_access_2018, generate_hidden_includes,
|
||||
@@ -403,17 +404,19 @@ fn construct_runtime_final_expansion(
|
||||
let integrity_test = decl_integrity_test(&scrate);
|
||||
let static_assertions = decl_static_assertions(&name, &pallets, &scrate);
|
||||
|
||||
let warning =
|
||||
where_section.map_or(None, |where_section| {
|
||||
Some(proc_macro_warning::Warning::new_deprecated("WhereSection")
|
||||
.old("use a `where` clause in `construct_runtime`")
|
||||
.new("use `frame_system::Config` to set the `Block` type and delete this clause.
|
||||
It is planned to be removed in December 2023")
|
||||
.help_links(&["https://github.com/paritytech/substrate/pull/14437"])
|
||||
.span(where_section.span)
|
||||
.build(),
|
||||
let warning = where_section.map_or(None, |where_section| {
|
||||
Some(
|
||||
proc_macro_warning::Warning::new_deprecated("WhereSection")
|
||||
.old("use a `where` clause in `construct_runtime`")
|
||||
.new(
|
||||
"use `frame_system::Config` to set the `Block` type and delete this clause.
|
||||
It is planned to be removed in December 2023",
|
||||
)
|
||||
.help_links(&["https://github.com/paritytech/substrate/pull/14437"])
|
||||
.span(where_section.span)
|
||||
.build(),
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
let res = quote!(
|
||||
#warning
|
||||
@@ -659,7 +662,6 @@ fn decl_all_pallets<'a>(
|
||||
#( #all_pallets_reversed_with_system_first )*
|
||||
)
|
||||
}
|
||||
|
||||
fn decl_pallet_runtime_setup(
|
||||
runtime: &Ident,
|
||||
pallet_declarations: &[Pallet],
|
||||
@@ -667,6 +669,7 @@ fn decl_pallet_runtime_setup(
|
||||
) -> TokenStream2 {
|
||||
let names = pallet_declarations.iter().map(|d| &d.name).collect::<Vec<_>>();
|
||||
let name_strings = pallet_declarations.iter().map(|d| d.name.to_string());
|
||||
let name_hashes = pallet_declarations.iter().map(|d| two128_str(&d.name.to_string()));
|
||||
let module_names = pallet_declarations.iter().map(|d| d.path.module_name());
|
||||
let indices = pallet_declarations.iter().map(|pallet| pallet.index as usize);
|
||||
let pallet_structs = pallet_declarations
|
||||
@@ -699,6 +702,7 @@ fn decl_pallet_runtime_setup(
|
||||
pub struct PalletInfo;
|
||||
|
||||
impl #scrate::traits::PalletInfo for PalletInfo {
|
||||
|
||||
fn index<P: 'static>() -> Option<usize> {
|
||||
let type_id = #scrate::__private::sp_std::any::TypeId::of::<P>();
|
||||
#(
|
||||
@@ -723,6 +727,18 @@ fn decl_pallet_runtime_setup(
|
||||
None
|
||||
}
|
||||
|
||||
fn name_hash<P: 'static>() -> Option<[u8; 16]> {
|
||||
let type_id = #scrate::__private::sp_std::any::TypeId::of::<P>();
|
||||
#(
|
||||
#pallet_attrs
|
||||
if type_id == #scrate::__private::sp_std::any::TypeId::of::<#names>() {
|
||||
return Some(#name_hashes)
|
||||
}
|
||||
)*
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn module_name<P: 'static>() -> Option<&'static str> {
|
||||
let type_id = #scrate::__private::sp_std::any::TypeId::of::<P>();
|
||||
#(
|
||||
|
||||
@@ -246,6 +246,14 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
implemented by the runtime")
|
||||
}
|
||||
|
||||
fn name_hash() -> [u8; 16] {
|
||||
<
|
||||
<T as #frame_system::Config>::PalletInfo as #frame_support::traits::PalletInfo
|
||||
>::name_hash::<Self>()
|
||||
.expect("Pallet is part of the runtime because pallet `Config` trait is \
|
||||
implemented by the runtime")
|
||||
}
|
||||
|
||||
fn module_name() -> &'static str {
|
||||
<
|
||||
<T as #frame_system::Config>::PalletInfo as #frame_support::traits::PalletInfo
|
||||
|
||||
@@ -18,7 +18,10 @@
|
||||
use crate::{
|
||||
counter_prefix,
|
||||
pallet::{
|
||||
parse::storage::{Metadata, QueryKind, StorageDef, StorageGenerics},
|
||||
parse::{
|
||||
helper::two128_str,
|
||||
storage::{Metadata, QueryKind, StorageDef, StorageGenerics},
|
||||
},
|
||||
Def,
|
||||
},
|
||||
};
|
||||
@@ -638,6 +641,7 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
Metadata::CountedMap { .. } => {
|
||||
let counter_prefix_struct_ident = counter_prefix_ident(&storage_def.ident);
|
||||
let counter_prefix_struct_const = counter_prefix(&prefix_struct_const);
|
||||
let storage_prefix_hash = two128_str(&counter_prefix_struct_const);
|
||||
quote::quote_spanned!(storage_def.attr_span =>
|
||||
#(#cfg_attrs)*
|
||||
#[doc(hidden)]
|
||||
@@ -656,7 +660,19 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
>::name::<Pallet<#type_use_gen>>()
|
||||
.expect("No name found for the pallet in the runtime! This usually means that the pallet wasn't added to `construct_runtime!`.")
|
||||
}
|
||||
|
||||
fn pallet_prefix_hash() -> [u8; 16] {
|
||||
<
|
||||
<T as #frame_system::Config>::PalletInfo
|
||||
as #frame_support::traits::PalletInfo
|
||||
>::name_hash::<Pallet<#type_use_gen>>()
|
||||
.expect("No name_hash found for the pallet in the runtime! This usually means that the pallet wasn't added to `construct_runtime!`.")
|
||||
}
|
||||
|
||||
const STORAGE_PREFIX: &'static str = #counter_prefix_struct_const;
|
||||
fn storage_prefix_hash() -> [u8; 16] {
|
||||
#storage_prefix_hash
|
||||
}
|
||||
}
|
||||
#(#cfg_attrs)*
|
||||
impl<#type_impl_gen> #frame_support::storage::types::CountedStorageMapInstance
|
||||
@@ -670,6 +686,7 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
Metadata::CountedNMap { .. } => {
|
||||
let counter_prefix_struct_ident = counter_prefix_ident(&storage_def.ident);
|
||||
let counter_prefix_struct_const = counter_prefix(&prefix_struct_const);
|
||||
let storage_prefix_hash = two128_str(&counter_prefix_struct_const);
|
||||
quote::quote_spanned!(storage_def.attr_span =>
|
||||
#(#cfg_attrs)*
|
||||
#[doc(hidden)]
|
||||
@@ -688,7 +705,17 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
>::name::<Pallet<#type_use_gen>>()
|
||||
.expect("No name found for the pallet in the runtime! This usually means that the pallet wasn't added to `construct_runtime!`.")
|
||||
}
|
||||
fn pallet_prefix_hash() -> [u8; 16] {
|
||||
<
|
||||
<T as #frame_system::Config>::PalletInfo
|
||||
as #frame_support::traits::PalletInfo
|
||||
>::name_hash::<Pallet<#type_use_gen>>()
|
||||
.expect("No name_hash found for the pallet in the runtime! This usually means that the pallet wasn't added to `construct_runtime!`.")
|
||||
}
|
||||
const STORAGE_PREFIX: &'static str = #counter_prefix_struct_const;
|
||||
fn storage_prefix_hash() -> [u8; 16] {
|
||||
#storage_prefix_hash
|
||||
}
|
||||
}
|
||||
#(#cfg_attrs)*
|
||||
impl<#type_impl_gen> #frame_support::storage::types::CountedStorageNMapInstance
|
||||
@@ -702,6 +729,7 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
_ => proc_macro2::TokenStream::default(),
|
||||
};
|
||||
|
||||
let storage_prefix_hash = two128_str(&prefix_struct_const);
|
||||
quote::quote_spanned!(storage_def.attr_span =>
|
||||
#maybe_counter
|
||||
|
||||
@@ -722,7 +750,19 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
>::name::<Pallet<#type_use_gen>>()
|
||||
.expect("No name found for the pallet in the runtime! This usually means that the pallet wasn't added to `construct_runtime!`.")
|
||||
}
|
||||
|
||||
fn pallet_prefix_hash() -> [u8; 16] {
|
||||
<
|
||||
<T as #frame_system::Config>::PalletInfo
|
||||
as #frame_support::traits::PalletInfo
|
||||
>::name_hash::<Pallet<#type_use_gen>>()
|
||||
.expect("No name_hash found for the pallet in the runtime! This usually means that the pallet wasn't added to `construct_runtime!`.")
|
||||
}
|
||||
|
||||
const STORAGE_PREFIX: &'static str = #prefix_struct_const;
|
||||
fn storage_prefix_hash() -> [u8; 16] {
|
||||
#storage_prefix_hash
|
||||
}
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
//! to user defined types. And also crate new types and implement block.
|
||||
|
||||
mod expand;
|
||||
mod parse;
|
||||
pub(crate) mod parse;
|
||||
|
||||
pub use parse::{composite::keyword::CompositeKeyword, Def};
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use quote::ToTokens;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
/// List of additional token to be used for parsing.
|
||||
@@ -610,3 +611,16 @@ pub fn check_pallet_call_return_type(type_: &syn::Type) -> syn::Result<()> {
|
||||
|
||||
syn::parse2::<Checker>(type_.to_token_stream()).map(|_| ())
|
||||
}
|
||||
|
||||
pub(crate) fn two128_str(s: &str) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::twox_128(s.as_bytes()).into_iter())
|
||||
}
|
||||
|
||||
pub(crate) fn bytes_to_array(bytes: impl IntoIterator<Item = u8>) -> TokenStream {
|
||||
let bytes = bytes.into_iter();
|
||||
|
||||
quote!(
|
||||
[ #( #bytes ),* ]
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
//! Implementation of the `storage_alias` attribute macro.
|
||||
|
||||
use crate::counter_prefix;
|
||||
use crate::{counter_prefix, pallet::parse::helper};
|
||||
use frame_support_procedural_tools::generate_crate_access_2018;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
@@ -619,6 +619,7 @@ fn generate_storage_instance(
|
||||
let counter_code = is_counted_map.then(|| {
|
||||
let counter_name = Ident::new(&counter_prefix(&name_str), Span::call_site());
|
||||
let counter_storage_name_str = counter_prefix(&storage_name_str);
|
||||
let storage_prefix_hash = helper::two128_str(&counter_storage_name_str);
|
||||
|
||||
quote! {
|
||||
#visibility struct #counter_name< #impl_generics >(
|
||||
@@ -633,6 +634,9 @@ fn generate_storage_instance(
|
||||
}
|
||||
|
||||
const STORAGE_PREFIX: &'static str = #counter_storage_name_str;
|
||||
fn storage_prefix_hash() -> [u8; 16] {
|
||||
#storage_prefix_hash
|
||||
}
|
||||
}
|
||||
|
||||
impl<#impl_generics> #crate_::storage::types::CountedStorageMapInstance
|
||||
@@ -643,6 +647,8 @@ fn generate_storage_instance(
|
||||
}
|
||||
});
|
||||
|
||||
let storage_prefix_hash = helper::two128_str(&storage_name_str);
|
||||
|
||||
// Implement `StorageInstance` trait.
|
||||
let code = quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
@@ -658,6 +664,9 @@ fn generate_storage_instance(
|
||||
}
|
||||
|
||||
const STORAGE_PREFIX: &'static str = #storage_name_str;
|
||||
fn storage_prefix_hash() -> [u8; 16] {
|
||||
#storage_prefix_hash
|
||||
}
|
||||
}
|
||||
|
||||
#counter_code
|
||||
|
||||
@@ -33,7 +33,7 @@ use sp_std::prelude::*;
|
||||
///
|
||||
/// Thus value for (key1, key2) is stored at:
|
||||
/// ```nocompile
|
||||
/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2))
|
||||
/// Twox128(pallet_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2))
|
||||
/// ```
|
||||
///
|
||||
/// # Warning
|
||||
@@ -53,18 +53,15 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
|
||||
/// Hasher for the second key.
|
||||
type Hasher2: StorageHasher;
|
||||
|
||||
/// Module prefix. Used for generating final key.
|
||||
fn module_prefix() -> &'static [u8];
|
||||
/// Pallet prefix. Used for generating final key.
|
||||
fn pallet_prefix() -> &'static [u8];
|
||||
|
||||
/// Storage prefix. Used for generating final key.
|
||||
fn storage_prefix() -> &'static [u8];
|
||||
|
||||
/// The full prefix; just the hash of `module_prefix` concatenated to the hash of
|
||||
/// The full prefix; just the hash of `pallet_prefix` concatenated to the hash of
|
||||
/// `storage_prefix`.
|
||||
fn prefix_hash() -> Vec<u8> {
|
||||
let result = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
result.to_vec()
|
||||
}
|
||||
fn prefix_hash() -> [u8; 32];
|
||||
|
||||
/// Convert an optional value retrieved from storage to the type queried.
|
||||
fn from_optional_value_to_query(v: Option<V>) -> Self::Query;
|
||||
@@ -77,7 +74,7 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
|
||||
where
|
||||
KArg1: EncodeLike<K1>,
|
||||
{
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
let key_hashed = k1.using_encoded(Self::Hasher1::hash);
|
||||
|
||||
let mut final_key = Vec::with_capacity(storage_prefix.len() + key_hashed.as_ref().len());
|
||||
@@ -94,7 +91,7 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
{
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
let key1_hashed = k1.using_encoded(Self::Hasher1::hash);
|
||||
let key2_hashed = k2.using_encoded(Self::Hasher2::hash);
|
||||
|
||||
@@ -334,7 +331,7 @@ where
|
||||
key2: KeyArg2,
|
||||
) -> Option<V> {
|
||||
let old_key = {
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
|
||||
let key1_hashed = key1.using_encoded(OldHasher1::hash);
|
||||
let key2_hashed = key2.using_encoded(OldHasher2::hash);
|
||||
@@ -419,7 +416,7 @@ where
|
||||
}
|
||||
|
||||
fn iter() -> Self::Iterator {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
Self::Iterator {
|
||||
prefix: prefix.clone(),
|
||||
previous_key: prefix,
|
||||
@@ -442,7 +439,7 @@ where
|
||||
}
|
||||
|
||||
fn iter_keys() -> Self::FullKeyIterator {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
Self::FullKeyIterator {
|
||||
prefix: prefix.clone(),
|
||||
previous_key: prefix,
|
||||
@@ -470,7 +467,7 @@ where
|
||||
}
|
||||
|
||||
fn translate<O: Decode, F: FnMut(K1, K2, O) -> Option<V>>(mut f: F) {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
let mut previous_key = prefix.clone();
|
||||
while let Some(next) =
|
||||
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
|
||||
@@ -561,7 +558,7 @@ mod test_iterators {
|
||||
type DoubleMap = self::frame_system::DoubleMap<Runtime>;
|
||||
|
||||
// All map iterator
|
||||
let prefix = DoubleMap::prefix_hash();
|
||||
let prefix = DoubleMap::prefix_hash().to_vec();
|
||||
|
||||
unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
|
||||
unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
|
||||
@@ -621,7 +618,7 @@ mod test_iterators {
|
||||
assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64));
|
||||
|
||||
// Translate
|
||||
let prefix = DoubleMap::prefix_hash();
|
||||
let prefix = DoubleMap::prefix_hash().to_vec();
|
||||
|
||||
unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
|
||||
unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
|
||||
|
||||
@@ -28,7 +28,7 @@ use sp_std::prelude::*;
|
||||
///
|
||||
/// By default each key value is stored at:
|
||||
/// ```nocompile
|
||||
/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key))
|
||||
/// Twox128(pallet_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key))
|
||||
/// ```
|
||||
///
|
||||
/// # Warning
|
||||
@@ -42,18 +42,15 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
|
||||
/// Hasher. Used for generating final key.
|
||||
type Hasher: StorageHasher;
|
||||
|
||||
/// Module prefix. Used for generating final key.
|
||||
fn module_prefix() -> &'static [u8];
|
||||
/// Pallet prefix. Used for generating final key.
|
||||
fn pallet_prefix() -> &'static [u8];
|
||||
|
||||
/// Storage prefix. Used for generating final key.
|
||||
fn storage_prefix() -> &'static [u8];
|
||||
|
||||
/// The full prefix; just the hash of `module_prefix` concatenated to the hash of
|
||||
/// The full prefix; just the hash of `pallet_prefix` concatenated to the hash of
|
||||
/// `storage_prefix`.
|
||||
fn prefix_hash() -> Vec<u8> {
|
||||
let result = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
result.to_vec()
|
||||
}
|
||||
fn prefix_hash() -> [u8; 32];
|
||||
|
||||
/// Convert an optional value retrieved from storage to the type queried.
|
||||
fn from_optional_value_to_query(v: Option<V>) -> Self::Query;
|
||||
@@ -66,7 +63,7 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
|
||||
where
|
||||
KeyArg: EncodeLike<K>,
|
||||
{
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
let key_hashed = key.using_encoded(Self::Hasher::hash);
|
||||
|
||||
let mut final_key = Vec::with_capacity(storage_prefix.len() + key_hashed.as_ref().len());
|
||||
@@ -128,7 +125,7 @@ where
|
||||
|
||||
/// Enumerate all elements in the map.
|
||||
fn iter() -> Self::Iterator {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
PrefixIterator {
|
||||
prefix: prefix.clone(),
|
||||
previous_key: prefix,
|
||||
@@ -150,7 +147,7 @@ where
|
||||
|
||||
/// Enumerate all keys in the map.
|
||||
fn iter_keys() -> Self::KeyIterator {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
KeyPrefixIterator {
|
||||
prefix: prefix.clone(),
|
||||
previous_key: prefix,
|
||||
@@ -190,7 +187,7 @@ where
|
||||
previous_key: Option<Vec<u8>>,
|
||||
mut f: F,
|
||||
) -> Option<Vec<u8>> {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
let previous_key = previous_key.unwrap_or_else(|| prefix.clone());
|
||||
|
||||
let current_key =
|
||||
@@ -339,7 +336,7 @@ impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V>
|
||||
|
||||
fn migrate_key<OldHasher: StorageHasher, KeyArg: EncodeLike<K>>(key: KeyArg) -> Option<V> {
|
||||
let old_key = {
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
let key_hashed = key.using_encoded(OldHasher::hash);
|
||||
|
||||
let mut final_key =
|
||||
@@ -398,7 +395,7 @@ mod test_iterators {
|
||||
type Map = self::frame_system::Map<Runtime>;
|
||||
|
||||
// All map iterator
|
||||
let prefix = Map::prefix_hash();
|
||||
let prefix = Map::prefix_hash().to_vec();
|
||||
|
||||
unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
|
||||
unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
|
||||
@@ -420,7 +417,7 @@ mod test_iterators {
|
||||
assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64));
|
||||
|
||||
// Translate
|
||||
let prefix = Map::prefix_hash();
|
||||
let prefix = Map::prefix_hash().to_vec();
|
||||
|
||||
unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
|
||||
unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
|
||||
|
||||
@@ -61,18 +61,15 @@ pub trait StorageNMap<K: KeyGenerator, V: FullCodec> {
|
||||
/// The type that get/take returns.
|
||||
type Query;
|
||||
|
||||
/// Module prefix. Used for generating final key.
|
||||
fn module_prefix() -> &'static [u8];
|
||||
/// Pallet prefix. Used for generating final key.
|
||||
fn pallet_prefix() -> &'static [u8];
|
||||
|
||||
/// Storage prefix. Used for generating final key.
|
||||
fn storage_prefix() -> &'static [u8];
|
||||
|
||||
/// The full prefix; just the hash of `module_prefix` concatenated to the hash of
|
||||
/// The full prefix; just the hash of `pallet_prefix` concatenated to the hash of
|
||||
/// `storage_prefix`.
|
||||
fn prefix_hash() -> Vec<u8> {
|
||||
let result = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
result.to_vec()
|
||||
}
|
||||
fn prefix_hash() -> [u8; 32];
|
||||
|
||||
/// Convert an optional value retrieved from storage to the type queried.
|
||||
fn from_optional_value_to_query(v: Option<V>) -> Self::Query;
|
||||
@@ -85,7 +82,7 @@ pub trait StorageNMap<K: KeyGenerator, V: FullCodec> {
|
||||
where
|
||||
K: HasKeyPrefix<KP>,
|
||||
{
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
let key_hashed = <K as HasKeyPrefix<KP>>::partial_key(key);
|
||||
|
||||
let mut final_key = Vec::with_capacity(storage_prefix.len() + key_hashed.len());
|
||||
@@ -102,7 +99,7 @@ pub trait StorageNMap<K: KeyGenerator, V: FullCodec> {
|
||||
KG: KeyGenerator,
|
||||
KArg: EncodeLikeTuple<KG::KArg> + TupleToEncodedIter,
|
||||
{
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
let key_hashed = KG::final_key(key);
|
||||
|
||||
let mut final_key = Vec::with_capacity(storage_prefix.len() + key_hashed.len());
|
||||
@@ -299,7 +296,7 @@ where
|
||||
KArg: EncodeLikeTuple<K::KArg> + TupleToEncodedIter,
|
||||
{
|
||||
let old_key = {
|
||||
let storage_prefix = storage_prefix(Self::module_prefix(), Self::storage_prefix());
|
||||
let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
|
||||
let key_hashed = K::migrate_key(&key, hash_fns);
|
||||
|
||||
let mut final_key = Vec::with_capacity(storage_prefix.len() + key_hashed.len());
|
||||
@@ -386,11 +383,11 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
|
||||
}
|
||||
|
||||
fn iter() -> Self::Iterator {
|
||||
Self::iter_from(G::prefix_hash())
|
||||
Self::iter_from(G::prefix_hash().to_vec())
|
||||
}
|
||||
|
||||
fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
Self::Iterator {
|
||||
prefix,
|
||||
previous_key: starting_raw_key,
|
||||
@@ -404,11 +401,11 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
|
||||
}
|
||||
|
||||
fn iter_keys() -> Self::KeyIterator {
|
||||
Self::iter_keys_from(G::prefix_hash())
|
||||
Self::iter_keys_from(G::prefix_hash().to_vec())
|
||||
}
|
||||
|
||||
fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::KeyIterator {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
Self::KeyIterator {
|
||||
prefix,
|
||||
previous_key: starting_raw_key,
|
||||
@@ -427,7 +424,7 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
|
||||
}
|
||||
|
||||
fn translate<O: Decode, F: FnMut(K::Key, O) -> Option<V>>(mut f: F) {
|
||||
let prefix = G::prefix_hash();
|
||||
let prefix = G::prefix_hash().to_vec();
|
||||
let mut previous_key = prefix.clone();
|
||||
while let Some(next) =
|
||||
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
|
||||
@@ -537,7 +534,7 @@ mod test_iterators {
|
||||
type NMap = self::frame_system::NMap<Runtime>;
|
||||
|
||||
// All map iterator
|
||||
let prefix = NMap::prefix_hash();
|
||||
let prefix = NMap::prefix_hash().to_vec();
|
||||
|
||||
unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
|
||||
unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
|
||||
@@ -594,7 +591,7 @@ mod test_iterators {
|
||||
assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64));
|
||||
|
||||
// Translate
|
||||
let prefix = NMap::prefix_hash();
|
||||
let prefix = NMap::prefix_hash().to_vec();
|
||||
|
||||
unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
|
||||
unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
|
||||
|
||||
@@ -25,14 +25,14 @@ use codec::{Decode, Encode, EncodeLike, FullCodec};
|
||||
///
|
||||
/// By default value is stored at:
|
||||
/// ```nocompile
|
||||
/// Twox128(module_prefix) ++ Twox128(storage_prefix)
|
||||
/// Twox128(pallet_prefix) ++ Twox128(storage_prefix)
|
||||
/// ```
|
||||
pub trait StorageValue<T: FullCodec> {
|
||||
/// The type that get/take returns.
|
||||
type Query;
|
||||
|
||||
/// Module prefix. Used for generating final key.
|
||||
fn module_prefix() -> &'static [u8];
|
||||
/// Pallet prefix. Used for generating final key.
|
||||
fn pallet_prefix() -> &'static [u8];
|
||||
|
||||
/// Storage prefix. Used for generating final key.
|
||||
fn storage_prefix() -> &'static [u8];
|
||||
@@ -44,9 +44,7 @@ pub trait StorageValue<T: FullCodec> {
|
||||
fn from_query_to_optional_value(v: Self::Query) -> Option<T>;
|
||||
|
||||
/// Generate the full key used in top storage.
|
||||
fn storage_value_final_key() -> [u8; 32] {
|
||||
crate::storage::storage_prefix(Self::module_prefix(), Self::storage_prefix())
|
||||
}
|
||||
fn storage_value_final_key() -> [u8; 32];
|
||||
}
|
||||
|
||||
impl<T: FullCodec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
@@ -97,10 +95,6 @@ impl<T: FullCodec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
}
|
||||
}
|
||||
|
||||
fn kill() {
|
||||
unhashed::kill(&Self::storage_value_final_key())
|
||||
}
|
||||
|
||||
fn mutate<R, F: FnOnce(&mut G::Query) -> R>(f: F) -> R {
|
||||
Self::try_mutate(|v| Ok::<R, Never>(f(v))).expect("`Never` can not be constructed; qed")
|
||||
}
|
||||
@@ -142,6 +136,10 @@ impl<T: FullCodec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
ret
|
||||
}
|
||||
|
||||
fn kill() {
|
||||
unhashed::kill(&Self::storage_value_final_key())
|
||||
}
|
||||
|
||||
fn take() -> G::Query {
|
||||
let key = Self::storage_value_final_key();
|
||||
let value = unhashed::get(&key);
|
||||
|
||||
@@ -191,7 +191,7 @@ pub trait StorageList<V: FullCodec> {
|
||||
|
||||
/// Append a single element.
|
||||
///
|
||||
/// Should not be called repeatedly; use `append_many` instead.
|
||||
/// Should not be called repeatedly; use `append_many` instead.
|
||||
/// Worst case linear `O(len)` with `len` being the number if elements in the list.
|
||||
fn append_one<EncodeLikeValue>(item: EncodeLikeValue)
|
||||
where
|
||||
@@ -202,7 +202,7 @@ pub trait StorageList<V: FullCodec> {
|
||||
|
||||
/// Append many elements.
|
||||
///
|
||||
/// Should not be called repeatedly; use `appender` instead.
|
||||
/// Should not be called repeatedly; use `appender` instead.
|
||||
/// Worst case linear `O(len + items.count())` with `len` beings the number if elements in the
|
||||
/// list.
|
||||
fn append_many<EncodeLikeValue, I>(items: I)
|
||||
@@ -1273,15 +1273,15 @@ impl<T> Iterator for ChildTriePrefixIterator<T> {
|
||||
|
||||
/// Trait for storage types that store all its value after a unique prefix.
|
||||
pub trait StoragePrefixedContainer {
|
||||
/// Module prefix. Used for generating final key.
|
||||
fn module_prefix() -> &'static [u8];
|
||||
/// Pallet prefix. Used for generating final key.
|
||||
fn pallet_prefix() -> &'static [u8];
|
||||
|
||||
/// Storage prefix. Used for generating final key.
|
||||
fn storage_prefix() -> &'static [u8];
|
||||
|
||||
/// Final full prefix that prefixes all keys.
|
||||
fn final_prefix() -> [u8; 32] {
|
||||
crate::storage::storage_prefix(Self::module_prefix(), Self::storage_prefix())
|
||||
crate::storage::storage_prefix(Self::pallet_prefix(), Self::storage_prefix())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1289,18 +1289,18 @@ pub trait StoragePrefixedContainer {
|
||||
///
|
||||
/// By default the final prefix is:
|
||||
/// ```nocompile
|
||||
/// Twox128(module_prefix) ++ Twox128(storage_prefix)
|
||||
/// Twox128(pallet_prefix) ++ Twox128(storage_prefix)
|
||||
/// ```
|
||||
pub trait StoragePrefixedMap<Value: FullCodec> {
|
||||
/// Module prefix. Used for generating final key.
|
||||
fn module_prefix() -> &'static [u8]; // TODO move to StoragePrefixedContainer
|
||||
/// Pallet prefix. Used for generating final key.
|
||||
fn pallet_prefix() -> &'static [u8]; // TODO move to StoragePrefixedContainer
|
||||
|
||||
/// Storage prefix. Used for generating final key.
|
||||
fn storage_prefix() -> &'static [u8];
|
||||
|
||||
/// Final full prefix that prefixes all keys.
|
||||
fn final_prefix() -> [u8; 32] {
|
||||
crate::storage::storage_prefix(Self::module_prefix(), Self::storage_prefix())
|
||||
crate::storage::storage_prefix(Self::pallet_prefix(), Self::storage_prefix())
|
||||
}
|
||||
|
||||
/// Remove all values in the overlay and up to `limit` in the backend.
|
||||
@@ -1624,7 +1624,7 @@ mod test {
|
||||
TestExternalities::default().execute_with(|| {
|
||||
struct MyStorage;
|
||||
impl StoragePrefixedMap<u64> for MyStorage {
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
b"MyModule"
|
||||
}
|
||||
|
||||
@@ -1701,7 +1701,7 @@ mod test {
|
||||
impl generator::StorageValue<Digest> for Storage {
|
||||
type Query = Digest;
|
||||
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
b"MyModule"
|
||||
}
|
||||
|
||||
@@ -1716,6 +1716,10 @@ mod test {
|
||||
fn from_query_to_optional_value(v: Self::Query) -> Option<Digest> {
|
||||
Some(v)
|
||||
}
|
||||
|
||||
fn storage_value_final_key() -> [u8; 32] {
|
||||
storage_prefix(Self::pallet_prefix(), Self::storage_prefix())
|
||||
}
|
||||
}
|
||||
|
||||
Storage::append(DigestItem::Other(Vec::new()));
|
||||
@@ -1736,7 +1740,7 @@ mod test {
|
||||
type Query = u64;
|
||||
type Hasher = Twox64Concat;
|
||||
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
b"MyModule"
|
||||
}
|
||||
|
||||
@@ -1744,6 +1748,10 @@ mod test {
|
||||
b"MyStorageMap"
|
||||
}
|
||||
|
||||
fn prefix_hash() -> [u8; 32] {
|
||||
storage_prefix(Self::pallet_prefix(), Self::storage_prefix())
|
||||
}
|
||||
|
||||
fn from_optional_value_to_query(v: Option<u64>) -> Self::Query {
|
||||
v.unwrap_or_default()
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ where
|
||||
/// The prefix used to generate the key of the map.
|
||||
pub fn map_storage_final_prefix() -> Vec<u8> {
|
||||
use crate::storage::generator::StorageMap;
|
||||
<Self as MapWrapper>::Map::prefix_hash()
|
||||
<Self as MapWrapper>::Map::prefix_hash().to_vec()
|
||||
}
|
||||
|
||||
/// Get the storage key used to fetch a value corresponding to a specific key.
|
||||
|
||||
@@ -104,7 +104,7 @@ where
|
||||
/// The prefix used to generate the key of the map.
|
||||
pub fn map_storage_final_prefix() -> Vec<u8> {
|
||||
use crate::storage::generator::StorageNMap;
|
||||
<Self as MapWrapper>::Map::prefix_hash()
|
||||
<Self as MapWrapper>::Map::prefix_hash().to_vec()
|
||||
}
|
||||
|
||||
/// Get the storage key used to fetch a value corresponding to a specific key.
|
||||
|
||||
@@ -117,12 +117,17 @@ where
|
||||
type Query = QueryKind::Query;
|
||||
type Hasher1 = Hasher1;
|
||||
type Hasher2 = Hasher2;
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
Prefix::pallet_prefix().as_bytes()
|
||||
}
|
||||
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
Prefix::STORAGE_PREFIX.as_bytes()
|
||||
}
|
||||
fn prefix_hash() -> [u8; 32] {
|
||||
Prefix::prefix_hash()
|
||||
}
|
||||
|
||||
fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
|
||||
QueryKind::from_optional_value_to_query(v)
|
||||
}
|
||||
@@ -145,8 +150,8 @@ where
|
||||
OnEmpty: Get<QueryKind::Query> + 'static,
|
||||
MaxValues: Get<Option<u32>>,
|
||||
{
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageDoubleMap<Key1, Key2, Value>>::module_prefix()
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageDoubleMap<Key1, Key2, Value>>::pallet_prefix()
|
||||
}
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageDoubleMap<Key1, Key2, Value>>::storage_prefix()
|
||||
@@ -691,7 +696,7 @@ where
|
||||
{
|
||||
fn storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::final_prefix().to_vec(),
|
||||
max_values: MaxValues::get(),
|
||||
@@ -722,7 +727,7 @@ where
|
||||
{
|
||||
fn partial_storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::final_prefix().to_vec(),
|
||||
max_values: MaxValues::get(),
|
||||
|
||||
@@ -83,12 +83,15 @@ where
|
||||
{
|
||||
type Query = QueryKind::Query;
|
||||
type Hasher = Hasher;
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
Prefix::pallet_prefix().as_bytes()
|
||||
}
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
Prefix::STORAGE_PREFIX.as_bytes()
|
||||
}
|
||||
fn prefix_hash() -> [u8; 32] {
|
||||
Prefix::prefix_hash()
|
||||
}
|
||||
fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
|
||||
QueryKind::from_optional_value_to_query(v)
|
||||
}
|
||||
@@ -108,8 +111,8 @@ where
|
||||
OnEmpty: Get<QueryKind::Query> + 'static,
|
||||
MaxValues: Get<Option<u32>>,
|
||||
{
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageMap<Key, Value>>::module_prefix()
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageMap<Key, Value>>::pallet_prefix()
|
||||
}
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageMap<Key, Value>>::storage_prefix()
|
||||
@@ -469,7 +472,7 @@ where
|
||||
{
|
||||
fn storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::final_prefix().to_vec(),
|
||||
max_values: MaxValues::get(),
|
||||
@@ -497,7 +500,7 @@ where
|
||||
{
|
||||
fn partial_storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::final_prefix().to_vec(),
|
||||
max_values: MaxValues::get(),
|
||||
|
||||
@@ -72,12 +72,15 @@ where
|
||||
MaxValues: Get<Option<u32>>,
|
||||
{
|
||||
type Query = QueryKind::Query;
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
Prefix::pallet_prefix().as_bytes()
|
||||
}
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
Prefix::STORAGE_PREFIX.as_bytes()
|
||||
}
|
||||
fn prefix_hash() -> [u8; 32] {
|
||||
Prefix::prefix_hash()
|
||||
}
|
||||
fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
|
||||
QueryKind::from_optional_value_to_query(v)
|
||||
}
|
||||
@@ -96,8 +99,8 @@ where
|
||||
OnEmpty: Get<QueryKind::Query> + 'static,
|
||||
MaxValues: Get<Option<u32>>,
|
||||
{
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageNMap<Key, Value>>::module_prefix()
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageNMap<Key, Value>>::pallet_prefix()
|
||||
}
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
<Self as crate::storage::generator::StorageNMap<Key, Value>>::storage_prefix()
|
||||
@@ -581,7 +584,7 @@ where
|
||||
{
|
||||
fn storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::final_prefix().to_vec(),
|
||||
max_values: MaxValues::get(),
|
||||
@@ -607,7 +610,7 @@ where
|
||||
{
|
||||
fn partial_storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::final_prefix().to_vec(),
|
||||
max_values: MaxValues::get(),
|
||||
|
||||
@@ -49,7 +49,7 @@ where
|
||||
OnEmpty: crate::traits::Get<QueryKind::Query> + 'static,
|
||||
{
|
||||
type Query = QueryKind::Query;
|
||||
fn module_prefix() -> &'static [u8] {
|
||||
fn pallet_prefix() -> &'static [u8] {
|
||||
Prefix::pallet_prefix().as_bytes()
|
||||
}
|
||||
fn storage_prefix() -> &'static [u8] {
|
||||
@@ -61,6 +61,9 @@ where
|
||||
fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
|
||||
QueryKind::from_query_to_optional_value(v)
|
||||
}
|
||||
fn storage_value_final_key() -> [u8; 32] {
|
||||
Prefix::prefix_hash()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Prefix, Value, QueryKind, OnEmpty> StorageValue<Prefix, Value, QueryKind, OnEmpty>
|
||||
@@ -251,7 +254,7 @@ where
|
||||
{
|
||||
fn storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::hashed_key().to_vec(),
|
||||
max_values: Some(1),
|
||||
@@ -271,7 +274,7 @@ where
|
||||
{
|
||||
fn partial_storage_info() -> Vec<StorageInfo> {
|
||||
vec![StorageInfo {
|
||||
pallet_name: Self::module_prefix().to_vec(),
|
||||
pallet_name: Self::pallet_prefix().to_vec(),
|
||||
storage_name: Self::storage_prefix().to_vec(),
|
||||
prefix: Self::hashed_key().to_vec(),
|
||||
max_values: Some(1),
|
||||
|
||||
@@ -112,7 +112,7 @@ fn verbatim_attribute() {
|
||||
assert_eq!(1, Value::get().unwrap());
|
||||
|
||||
// The prefix is the one we declared above.
|
||||
assert_eq!(&b"Test"[..], Value::module_prefix());
|
||||
assert_eq!(&b"Test"[..], Value::pallet_prefix());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ fn pallet_name_attribute() {
|
||||
|
||||
// The prefix is the pallet name. In this case the pallet name is `System` as declared in
|
||||
// `construct_runtime!`.
|
||||
assert_eq!(&b"System"[..], Value::<Runtime>::module_prefix());
|
||||
assert_eq!(&b"System"[..], Value::<Runtime>::pallet_prefix());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ fn dynamic_attribute() {
|
||||
assert_eq!(1, Value::<Prefix>::get().unwrap());
|
||||
|
||||
// The prefix is the one we declared above.
|
||||
assert_eq!(&b"Hello"[..], Value::<Prefix>::module_prefix());
|
||||
assert_eq!(&b"Hello"[..], Value::<Prefix>::pallet_prefix());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -166,13 +166,13 @@ fn storage_alias_guess() {
|
||||
#[crate::storage_alias]
|
||||
pub type Value = StorageValue<Test, u32>;
|
||||
|
||||
assert_eq!(&b"Test"[..], Value::module_prefix());
|
||||
assert_eq!(&b"Test"[..], Value::pallet_prefix());
|
||||
|
||||
// The macro will use the pallet name as prefix.
|
||||
#[crate::storage_alias]
|
||||
pub type PalletValue<T: Config> = StorageValue<Pallet<T>, u32>;
|
||||
|
||||
assert_eq!(&b"System"[..], PalletValue::<Runtime>::module_prefix());
|
||||
assert_eq!(&b"System"[..], PalletValue::<Runtime>::pallet_prefix());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ pub trait PalletInfo {
|
||||
fn index<P: 'static>() -> Option<usize>;
|
||||
/// Convert the given pallet `P` into its name as configured in the runtime.
|
||||
fn name<P: 'static>() -> Option<&'static str>;
|
||||
/// The two128 hash of name.
|
||||
fn name_hash<P: 'static>() -> Option<[u8; 16]>;
|
||||
/// Convert the given pallet `P` into its Rust module name as used in `construct_runtime!`.
|
||||
fn module_name<P: 'static>() -> Option<&'static str>;
|
||||
/// Convert the given pallet `P` into its containing crate version.
|
||||
@@ -59,6 +61,8 @@ pub trait PalletInfoAccess {
|
||||
fn index() -> usize;
|
||||
/// Name of the pallet as configured in the runtime.
|
||||
fn name() -> &'static str;
|
||||
/// Two128 hash of name.
|
||||
fn name_hash() -> [u8; 16];
|
||||
/// Name of the Rust module containing the pallet.
|
||||
fn module_name() -> &'static str;
|
||||
/// Version of the crate containing the pallet.
|
||||
@@ -281,6 +285,7 @@ pub trait GetStorageVersion {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sp_core::twox_128;
|
||||
|
||||
struct Pallet1;
|
||||
impl PalletInfoAccess for Pallet1 {
|
||||
@@ -290,6 +295,9 @@ mod tests {
|
||||
fn name() -> &'static str {
|
||||
"Pallet1"
|
||||
}
|
||||
fn name_hash() -> [u8; 16] {
|
||||
twox_128(Self::name().as_bytes())
|
||||
}
|
||||
fn module_name() -> &'static str {
|
||||
"pallet1"
|
||||
}
|
||||
@@ -305,6 +313,11 @@ mod tests {
|
||||
fn name() -> &'static str {
|
||||
"Pallet2"
|
||||
}
|
||||
|
||||
fn name_hash() -> [u8; 16] {
|
||||
twox_128(Self::name().as_bytes())
|
||||
}
|
||||
|
||||
fn module_name() -> &'static str {
|
||||
"pallet2"
|
||||
}
|
||||
|
||||
@@ -61,8 +61,35 @@ pub trait StorageInstance {
|
||||
/// Prefix of a pallet to isolate it from other pallets.
|
||||
fn pallet_prefix() -> &'static str;
|
||||
|
||||
/// Return the prefix hash of pallet instance.
|
||||
///
|
||||
/// NOTE: This hash must be `twox_128(pallet_prefix())`.
|
||||
/// Should not impl this function by hand. Only use the default or macro generated impls.
|
||||
fn pallet_prefix_hash() -> [u8; 16] {
|
||||
sp_io::hashing::twox_128(Self::pallet_prefix().as_bytes())
|
||||
}
|
||||
|
||||
/// Prefix given to a storage to isolate from other storages in the pallet.
|
||||
const STORAGE_PREFIX: &'static str;
|
||||
|
||||
/// Return the prefix hash of storage instance.
|
||||
///
|
||||
/// NOTE: This hash must be `twox_128(STORAGE_PREFIX)`.
|
||||
fn storage_prefix_hash() -> [u8; 16] {
|
||||
sp_io::hashing::twox_128(Self::STORAGE_PREFIX.as_bytes())
|
||||
}
|
||||
|
||||
/// Return the prefix hash of instance.
|
||||
///
|
||||
/// NOTE: This hash must be `twox_128(pallet_prefix())++twox_128(STORAGE_PREFIX)`.
|
||||
/// Should not impl this function by hand. Only use the default or macro generated impls.
|
||||
fn prefix_hash() -> [u8; 32] {
|
||||
let mut final_key = [0u8; 32];
|
||||
final_key[..16].copy_from_slice(&Self::pallet_prefix_hash());
|
||||
final_key[16..].copy_from_slice(&Self::storage_prefix_hash());
|
||||
|
||||
final_key
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata about storage from the runtime.
|
||||
|
||||
@@ -489,7 +489,7 @@ fn test_last_reward_migration() {
|
||||
s.top = data.into_iter().collect();
|
||||
|
||||
sp_io::TestExternalities::new(s).execute_with(|| {
|
||||
let module = pallet_tips::Tips::<Test>::module_prefix();
|
||||
let module = pallet_tips::Tips::<Test>::pallet_prefix();
|
||||
let item = pallet_tips::Tips::<Test>::storage_prefix();
|
||||
Tips::migrate_retract_tip_for_tip_new(module, item);
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ impl<T: Config> Pallet<T> {
|
||||
/// Ensure that this call can be paused.
|
||||
pub fn ensure_can_pause(full_name: &RuntimeCallNameOf<T>) -> Result<(), Error<T>> {
|
||||
// SAFETY: The `TxPause` pallet can never pause itself.
|
||||
if full_name.0.as_ref() == <Self as PalletInfoAccess>::name().as_bytes().to_vec() {
|
||||
if full_name.0.as_slice() == <Self as PalletInfoAccess>::name().as_bytes() {
|
||||
return Err(Error::<T>::Unpausable)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user