mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 02:01:02 +00:00
CountedNMap implementation (#10621)
* add initial CountedDoubleMap implementation * extend CountedDoubleMap functionality * add some traits implementation for CountedStorageDoubleMap * add basic tests for CountedStorageDoubleMap * add mutate functions implementation * add additional tests * add test_option_query test * add try_append_decode_len_works, append_decode_len_works tests * add migrate_keys_works, translate_values tests * add test_iter_drain_translate test * add test_metadata test * add remove_prefix implementation, add test_iter_drain_prefix test * update * refactor PrefixIterator usage * Fix CI build * fix storage_ensure_span_are_ok_wrong_gen.rs storage_ensure_span_are_ok_wrong_gen_unnamed.rs * add counted_nmap implementation * add tests, fixes * remove counted double map impl * fix metadata checks * update clear func * fix clear, clear with prefix * fix set function * update * final fix * Update frame/support/src/storage/types/counted_nmap.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * Update frame/support/src/storage/types/counted_nmap.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * Update frame/support/src/storage/types/counted_nmap.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * fix comments * fix suggestion * cargo update * Relocate impl of Sealed for Ref to module root * fix StorageEntryMetadata type * Update frame/support/src/storage/types/nmap.rs Co-authored-by: Guillaume Yu Thiolliere <gui.thiolliere@gmail.com> * removed StorageNMap and StoragePrefixedMap traits impl * fix tests * Update frame/support/src/storage/types/counted_nmap.rs Co-authored-by: Guillaume Yu Thiolliere <gui.thiolliere@gmail.com> * extend pallet::storage macro with CountedStorageNMap usage * fix * add tests * fix * fix * Add counter_storage_final_key(), map_storage_final_prefix() functions * update tests * fix * fix * fix * update tests * fix fmt * fix fmt --------- Co-authored-by: Anton <anton.kalyaev@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Guillaume Yu Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: parity-processbot <>
This commit is contained in:
@@ -194,18 +194,7 @@ pub fn process_generics(def: &mut Def) -> syn::Result<Vec<ResultOnEmptyStructMet
|
|||||||
let on_empty = on_empty.unwrap_or_else(|| default_on_empty(value));
|
let on_empty = on_empty.unwrap_or_else(|| default_on_empty(value));
|
||||||
args.args.push(syn::GenericArgument::Type(on_empty));
|
args.args.push(syn::GenericArgument::Type(on_empty));
|
||||||
},
|
},
|
||||||
StorageGenerics::Map { hasher, key, value, query_kind, on_empty, max_values } => {
|
StorageGenerics::Map { hasher, key, value, query_kind, on_empty, max_values } |
|
||||||
args.args.push(syn::GenericArgument::Type(hasher));
|
|
||||||
args.args.push(syn::GenericArgument::Type(key));
|
|
||||||
args.args.push(syn::GenericArgument::Type(value.clone()));
|
|
||||||
let mut query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
|
|
||||||
set_result_query_type_parameter(&mut query_kind)?;
|
|
||||||
args.args.push(syn::GenericArgument::Type(query_kind));
|
|
||||||
let on_empty = on_empty.unwrap_or_else(|| default_on_empty(value));
|
|
||||||
args.args.push(syn::GenericArgument::Type(on_empty));
|
|
||||||
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
|
|
||||||
args.args.push(syn::GenericArgument::Type(max_values));
|
|
||||||
},
|
|
||||||
StorageGenerics::CountedMap {
|
StorageGenerics::CountedMap {
|
||||||
hasher,
|
hasher,
|
||||||
key,
|
key,
|
||||||
@@ -248,7 +237,14 @@ pub fn process_generics(def: &mut Def) -> syn::Result<Vec<ResultOnEmptyStructMet
|
|||||||
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
|
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
|
||||||
args.args.push(syn::GenericArgument::Type(max_values));
|
args.args.push(syn::GenericArgument::Type(max_values));
|
||||||
},
|
},
|
||||||
StorageGenerics::NMap { keygen, value, query_kind, on_empty, max_values } => {
|
StorageGenerics::NMap { keygen, value, query_kind, on_empty, max_values } |
|
||||||
|
StorageGenerics::CountedNMap {
|
||||||
|
keygen,
|
||||||
|
value,
|
||||||
|
query_kind,
|
||||||
|
on_empty,
|
||||||
|
max_values,
|
||||||
|
} => {
|
||||||
args.args.push(syn::GenericArgument::Type(keygen));
|
args.args.push(syn::GenericArgument::Type(keygen));
|
||||||
args.args.push(syn::GenericArgument::Type(value.clone()));
|
args.args.push(syn::GenericArgument::Type(value.clone()));
|
||||||
let mut query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
|
let mut query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
|
||||||
@@ -265,7 +261,7 @@ pub fn process_generics(def: &mut Def) -> syn::Result<Vec<ResultOnEmptyStructMet
|
|||||||
|
|
||||||
let (value_idx, query_idx, on_empty_idx) = match storage_def.metadata {
|
let (value_idx, query_idx, on_empty_idx) = match storage_def.metadata {
|
||||||
Metadata::Value { .. } => (1, 2, 3),
|
Metadata::Value { .. } => (1, 2, 3),
|
||||||
Metadata::NMap { .. } => (2, 3, 4),
|
Metadata::NMap { .. } | Metadata::CountedNMap { .. } => (2, 3, 4),
|
||||||
Metadata::Map { .. } | Metadata::CountedMap { .. } => (3, 4, 5),
|
Metadata::Map { .. } | Metadata::CountedMap { .. } => (3, 4, 5),
|
||||||
Metadata::DoubleMap { .. } => (5, 6, 7),
|
Metadata::DoubleMap { .. } => (5, 6, 7),
|
||||||
};
|
};
|
||||||
@@ -359,6 +355,17 @@ fn augment_final_docs(def: &mut Def) {
|
|||||||
);
|
);
|
||||||
push_string_literal(&doc_line, storage);
|
push_string_literal(&doc_line, storage);
|
||||||
},
|
},
|
||||||
|
Metadata::CountedNMap { keys, value, .. } => {
|
||||||
|
let doc_line = format!(
|
||||||
|
"Storage type is [`CountedStorageNMap`] with keys type ({}) and value type {}.",
|
||||||
|
keys.iter()
|
||||||
|
.map(|k| k.to_token_stream().to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", "),
|
||||||
|
value.to_token_stream()
|
||||||
|
);
|
||||||
|
push_string_literal(&doc_line, storage);
|
||||||
|
},
|
||||||
Metadata::CountedMap { key, value } => {
|
Metadata::CountedMap { key, value } => {
|
||||||
let doc_line = format!(
|
let doc_line = format!(
|
||||||
"Storage type is [`CountedStorageMap`] with key type {} and value type {}.",
|
"Storage type is [`CountedStorageMap`] with key type {} and value type {}.",
|
||||||
@@ -579,6 +586,36 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
Metadata::CountedNMap { keygen, value, .. } => {
|
||||||
|
let query = match storage.query_kind.as_ref().expect("Checked by def") {
|
||||||
|
QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
|
||||||
|
Option<#value>
|
||||||
|
),
|
||||||
|
QueryKind::ResultQuery(error_path, _) => {
|
||||||
|
quote::quote_spanned!(storage.attr_span =>
|
||||||
|
Result<#value, #error_path>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
QueryKind::ValueQuery => quote::quote!(#value),
|
||||||
|
};
|
||||||
|
quote::quote_spanned!(storage.attr_span =>
|
||||||
|
#(#cfg_attrs)*
|
||||||
|
impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause {
|
||||||
|
#[doc = #getter_doc_line]
|
||||||
|
pub fn #getter<KArg>(key: KArg) -> #query
|
||||||
|
where
|
||||||
|
KArg: #frame_support::storage::types::EncodeLikeTuple<
|
||||||
|
<#keygen as #frame_support::storage::types::KeyGenerator>::KArg
|
||||||
|
>
|
||||||
|
+ #frame_support::storage::types::TupleToEncodedIter,
|
||||||
|
{
|
||||||
|
// NOTE: we can't use any trait here because CountedStorageNMap
|
||||||
|
// doesn't implement any.
|
||||||
|
<#full_ident>::get(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
@@ -595,40 +632,72 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
|||||||
|
|
||||||
let cfg_attrs = &storage_def.cfg_attrs;
|
let cfg_attrs = &storage_def.cfg_attrs;
|
||||||
|
|
||||||
let maybe_counter = if let Metadata::CountedMap { .. } = storage_def.metadata {
|
let maybe_counter = match storage_def.metadata {
|
||||||
let counter_prefix_struct_ident = counter_prefix_ident(&storage_def.ident);
|
Metadata::CountedMap { .. } => {
|
||||||
let counter_prefix_struct_const = counter_prefix(&prefix_struct_const);
|
let counter_prefix_struct_ident = counter_prefix_ident(&storage_def.ident);
|
||||||
|
let counter_prefix_struct_const = counter_prefix(&prefix_struct_const);
|
||||||
quote::quote_spanned!(storage_def.attr_span =>
|
quote::quote_spanned!(storage_def.attr_span =>
|
||||||
#(#cfg_attrs)*
|
#(#cfg_attrs)*
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#prefix_struct_vis struct #counter_prefix_struct_ident<#type_use_gen>(
|
#prefix_struct_vis struct #counter_prefix_struct_ident<#type_use_gen>(
|
||||||
core::marker::PhantomData<(#type_use_gen,)>
|
core::marker::PhantomData<(#type_use_gen,)>
|
||||||
);
|
);
|
||||||
#(#cfg_attrs)*
|
#(#cfg_attrs)*
|
||||||
impl<#type_impl_gen> #frame_support::traits::StorageInstance
|
impl<#type_impl_gen> #frame_support::traits::StorageInstance
|
||||||
for #counter_prefix_struct_ident<#type_use_gen>
|
for #counter_prefix_struct_ident<#type_use_gen>
|
||||||
#config_where_clause
|
#config_where_clause
|
||||||
{
|
{
|
||||||
fn pallet_prefix() -> &'static str {
|
fn pallet_prefix() -> &'static str {
|
||||||
<
|
<
|
||||||
<T as #frame_system::Config>::PalletInfo
|
<T as #frame_system::Config>::PalletInfo
|
||||||
as #frame_support::traits::PalletInfo
|
as #frame_support::traits::PalletInfo
|
||||||
>::name::<Pallet<#type_use_gen>>()
|
>::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!`.")
|
.expect("No name 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;
|
||||||
}
|
}
|
||||||
const STORAGE_PREFIX: &'static str = #counter_prefix_struct_const;
|
#(#cfg_attrs)*
|
||||||
}
|
impl<#type_impl_gen> #frame_support::storage::types::CountedStorageMapInstance
|
||||||
#(#cfg_attrs)*
|
for #prefix_struct_ident<#type_use_gen>
|
||||||
impl<#type_impl_gen> #frame_support::storage::types::CountedStorageMapInstance
|
#config_where_clause
|
||||||
for #prefix_struct_ident<#type_use_gen>
|
{
|
||||||
#config_where_clause
|
type CounterPrefix = #counter_prefix_struct_ident<#type_use_gen>;
|
||||||
{
|
}
|
||||||
type CounterPrefix = #counter_prefix_struct_ident<#type_use_gen>;
|
)
|
||||||
}
|
},
|
||||||
)
|
Metadata::CountedNMap { .. } => {
|
||||||
} else {
|
let counter_prefix_struct_ident = counter_prefix_ident(&storage_def.ident);
|
||||||
proc_macro2::TokenStream::default()
|
let counter_prefix_struct_const = counter_prefix(&prefix_struct_const);
|
||||||
|
quote::quote_spanned!(storage_def.attr_span =>
|
||||||
|
#(#cfg_attrs)*
|
||||||
|
#[doc(hidden)]
|
||||||
|
#prefix_struct_vis struct #counter_prefix_struct_ident<#type_use_gen>(
|
||||||
|
core::marker::PhantomData<(#type_use_gen,)>
|
||||||
|
);
|
||||||
|
#(#cfg_attrs)*
|
||||||
|
impl<#type_impl_gen> #frame_support::traits::StorageInstance
|
||||||
|
for #counter_prefix_struct_ident<#type_use_gen>
|
||||||
|
#config_where_clause
|
||||||
|
{
|
||||||
|
fn pallet_prefix() -> &'static str {
|
||||||
|
<
|
||||||
|
<T as #frame_system::Config>::PalletInfo
|
||||||
|
as #frame_support::traits::PalletInfo
|
||||||
|
>::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!`.")
|
||||||
|
}
|
||||||
|
const STORAGE_PREFIX: &'static str = #counter_prefix_struct_const;
|
||||||
|
}
|
||||||
|
#(#cfg_attrs)*
|
||||||
|
impl<#type_impl_gen> #frame_support::storage::types::CountedStorageNMapInstance
|
||||||
|
for #prefix_struct_ident<#type_use_gen>
|
||||||
|
#config_where_clause
|
||||||
|
{
|
||||||
|
type CounterPrefix = #counter_prefix_struct_ident<#type_use_gen>;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_ => proc_macro2::TokenStream::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
quote::quote_spanned!(storage_def.attr_span =>
|
quote::quote_spanned!(storage_def.attr_span =>
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ pub enum Metadata {
|
|||||||
CountedMap { value: syn::Type, key: syn::Type },
|
CountedMap { value: syn::Type, key: syn::Type },
|
||||||
DoubleMap { value: syn::Type, key1: syn::Type, key2: syn::Type },
|
DoubleMap { value: syn::Type, key1: syn::Type, key2: syn::Type },
|
||||||
NMap { keys: Vec<syn::Type>, keygen: syn::Type, value: syn::Type },
|
NMap { keys: Vec<syn::Type>, keygen: syn::Type, value: syn::Type },
|
||||||
|
CountedNMap { keys: Vec<syn::Type>, keygen: syn::Type, value: syn::Type },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum QueryKind {
|
pub enum QueryKind {
|
||||||
@@ -230,6 +231,13 @@ pub enum StorageGenerics {
|
|||||||
on_empty: Option<syn::Type>,
|
on_empty: Option<syn::Type>,
|
||||||
max_values: Option<syn::Type>,
|
max_values: Option<syn::Type>,
|
||||||
},
|
},
|
||||||
|
CountedNMap {
|
||||||
|
keygen: syn::Type,
|
||||||
|
value: syn::Type,
|
||||||
|
query_kind: Option<syn::Type>,
|
||||||
|
on_empty: Option<syn::Type>,
|
||||||
|
max_values: Option<syn::Type>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StorageGenerics {
|
impl StorageGenerics {
|
||||||
@@ -242,6 +250,8 @@ impl StorageGenerics {
|
|||||||
Self::Value { value, .. } => Metadata::Value { value },
|
Self::Value { value, .. } => Metadata::Value { value },
|
||||||
Self::NMap { keygen, value, .. } =>
|
Self::NMap { keygen, value, .. } =>
|
||||||
Metadata::NMap { keys: collect_keys(&keygen)?, keygen, value },
|
Metadata::NMap { keys: collect_keys(&keygen)?, keygen, value },
|
||||||
|
Self::CountedNMap { keygen, value, .. } =>
|
||||||
|
Metadata::CountedNMap { keys: collect_keys(&keygen)?, keygen, value },
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
@@ -254,7 +264,8 @@ impl StorageGenerics {
|
|||||||
Self::Map { query_kind, .. } |
|
Self::Map { query_kind, .. } |
|
||||||
Self::CountedMap { query_kind, .. } |
|
Self::CountedMap { query_kind, .. } |
|
||||||
Self::Value { query_kind, .. } |
|
Self::Value { query_kind, .. } |
|
||||||
Self::NMap { query_kind, .. } => query_kind.clone(),
|
Self::NMap { query_kind, .. } |
|
||||||
|
Self::CountedNMap { query_kind, .. } => query_kind.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,6 +276,7 @@ enum StorageKind {
|
|||||||
CountedMap,
|
CountedMap,
|
||||||
DoubleMap,
|
DoubleMap,
|
||||||
NMap,
|
NMap,
|
||||||
|
CountedNMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check the generics in the `map` contains the generics in `gen` may contains generics in
|
/// Check the generics in the `map` contains the generics in `gen` may contains generics in
|
||||||
@@ -493,6 +505,29 @@ fn process_named_generics(
|
|||||||
max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
|
max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
StorageKind::CountedNMap => {
|
||||||
|
check_generics(
|
||||||
|
&parsed,
|
||||||
|
&["Key", "Value"],
|
||||||
|
&["QueryKind", "OnEmpty", "MaxValues"],
|
||||||
|
"CountedStorageNMap",
|
||||||
|
args_span,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
StorageGenerics::CountedNMap {
|
||||||
|
keygen: parsed
|
||||||
|
.remove("Key")
|
||||||
|
.map(|binding| binding.ty)
|
||||||
|
.expect("checked above as mandatory generic"),
|
||||||
|
value: parsed
|
||||||
|
.remove("Value")
|
||||||
|
.map(|binding| binding.ty)
|
||||||
|
.expect("checked above as mandatory generic"),
|
||||||
|
query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
|
||||||
|
on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
|
||||||
|
max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let metadata = generics.metadata()?;
|
let metadata = generics.metadata()?;
|
||||||
@@ -578,6 +613,16 @@ fn process_unnamed_generics(
|
|||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
StorageKind::CountedNMap => {
|
||||||
|
let keygen = retrieve_arg(1)?;
|
||||||
|
let keys = collect_keys(&keygen)?;
|
||||||
|
(
|
||||||
|
None,
|
||||||
|
Metadata::CountedNMap { keys, keygen, value: retrieve_arg(2)? },
|
||||||
|
retrieve_arg(3).ok(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
@@ -594,10 +639,11 @@ fn process_generics(
|
|||||||
"CountedStorageMap" => StorageKind::CountedMap,
|
"CountedStorageMap" => StorageKind::CountedMap,
|
||||||
"StorageDoubleMap" => StorageKind::DoubleMap,
|
"StorageDoubleMap" => StorageKind::DoubleMap,
|
||||||
"StorageNMap" => StorageKind::NMap,
|
"StorageNMap" => StorageKind::NMap,
|
||||||
|
"CountedStorageNMap" => StorageKind::CountedNMap,
|
||||||
found => {
|
found => {
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"Invalid pallet::storage, expected ident: `StorageValue` or \
|
"Invalid pallet::storage, expected ident: `StorageValue` or \
|
||||||
`StorageMap` or `CountedStorageMap` or `StorageDoubleMap` or `StorageNMap` \
|
`StorageMap` or `CountedStorageMap` or `StorageDoubleMap` or `StorageNMap` or `CountedStorageNMap` \
|
||||||
in order to expand metadata, found `{}`.",
|
in order to expand metadata, found `{}`.",
|
||||||
found,
|
found,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1545,8 +1545,8 @@ pub mod pallet_prelude {
|
|||||||
storage::{
|
storage::{
|
||||||
bounded_vec::BoundedVec,
|
bounded_vec::BoundedVec,
|
||||||
types::{
|
types::{
|
||||||
CountedStorageMap, Key as NMapKey, OptionQuery, ResultQuery, StorageDoubleMap,
|
CountedStorageMap, CountedStorageNMap, Key as NMapKey, OptionQuery, ResultQuery,
|
||||||
StorageMap, StorageNMap, StorageValue, ValueQuery,
|
StorageDoubleMap, StorageMap, StorageNMap, StorageValue, ValueQuery,
|
||||||
},
|
},
|
||||||
StorageList,
|
StorageList,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1428,6 +1428,7 @@ mod private {
|
|||||||
impl<K, V, S> Sealed for bounded_btree_map::BoundedBTreeMap<K, V, S> {}
|
impl<K, V, S> Sealed for bounded_btree_map::BoundedBTreeMap<K, V, S> {}
|
||||||
impl<T, S> Sealed for bounded_btree_set::BoundedBTreeSet<T, S> {}
|
impl<T, S> Sealed for bounded_btree_set::BoundedBTreeSet<T, S> {}
|
||||||
impl<T: Encode> Sealed for BTreeSet<T> {}
|
impl<T: Encode> Sealed for BTreeSet<T> {}
|
||||||
|
impl<'a, T: EncodeLike<U>, U: Encode> Sealed for codec::Ref<'a, T, U> {}
|
||||||
|
|
||||||
macro_rules! impl_sealed_for_tuple {
|
macro_rules! impl_sealed_for_tuple {
|
||||||
($($elem:ident),+) => {
|
($($elem:ident),+) => {
|
||||||
|
|||||||
@@ -612,8 +612,9 @@ mod test {
|
|||||||
assert_eq!(A::count(), 2);
|
assert_eq!(A::count(), 2);
|
||||||
|
|
||||||
// Insert an existing key, shouldn't increment counted values.
|
// Insert an existing key, shouldn't increment counted values.
|
||||||
A::insert(3, 11);
|
A::insert(3, 12);
|
||||||
|
|
||||||
|
assert_eq!(A::try_get(3), Ok(12));
|
||||||
assert_eq!(A::count(), 2);
|
assert_eq!(A::count(), 2);
|
||||||
|
|
||||||
// Remove non-existing.
|
// Remove non-existing.
|
||||||
@@ -706,17 +707,17 @@ mod test {
|
|||||||
// Try succeed mutate existing to existing.
|
// Try succeed mutate existing to existing.
|
||||||
A::try_mutate_exists(1, |query| {
|
A::try_mutate_exists(1, |query| {
|
||||||
assert_eq!(*query, Some(43));
|
assert_eq!(*query, Some(43));
|
||||||
*query = Some(43);
|
*query = Some(45);
|
||||||
Result::<(), ()>::Ok(())
|
Result::<(), ()>::Ok(())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(A::try_get(1), Ok(43));
|
assert_eq!(A::try_get(1), Ok(45));
|
||||||
assert_eq!(A::count(), 4);
|
assert_eq!(A::count(), 4);
|
||||||
|
|
||||||
// Try succeed mutate existing to non-existing.
|
// Try succeed mutate existing to non-existing.
|
||||||
A::try_mutate_exists(1, |query| {
|
A::try_mutate_exists(1, |query| {
|
||||||
assert_eq!(*query, Some(43));
|
assert_eq!(*query, Some(45));
|
||||||
*query = None;
|
*query = None;
|
||||||
Result::<(), ()>::Ok(())
|
Result::<(), ()>::Ok(())
|
||||||
})
|
})
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@ pub struct Key<Hasher, KeyType>(core::marker::PhantomData<(Hasher, KeyType)>);
|
|||||||
/// A trait that contains the current key as an associated type.
|
/// A trait that contains the current key as an associated type.
|
||||||
pub trait KeyGenerator {
|
pub trait KeyGenerator {
|
||||||
type Key: EncodeLike<Self::Key> + StaticTypeInfo;
|
type Key: EncodeLike<Self::Key> + StaticTypeInfo;
|
||||||
type KArg: Encode;
|
type KArg: Encode + EncodeLike<Self::KArg>;
|
||||||
type HashFn: FnOnce(&[u8]) -> Vec<u8>;
|
type HashFn: FnOnce(&[u8]) -> Vec<u8>;
|
||||||
type HArg;
|
type HArg;
|
||||||
|
|
||||||
@@ -196,6 +196,11 @@ impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P);
|
|||||||
impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q);
|
impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q);
|
||||||
impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q, R);
|
impl_encode_like_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q, R);
|
||||||
|
|
||||||
|
impl<'a, T: EncodeLike<U> + EncodeLikeTuple<U>, U: Encode> EncodeLikeTuple<U>
|
||||||
|
for codec::Ref<'a, T, U>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Trait to indicate that a tuple can be converted into an iterator of a vector of encoded bytes.
|
/// Trait to indicate that a tuple can be converted into an iterator of a vector of encoded bytes.
|
||||||
pub trait TupleToEncodedIter {
|
pub trait TupleToEncodedIter {
|
||||||
fn to_encoded_iter(&self) -> sp_std::vec::IntoIter<Vec<u8>>;
|
fn to_encoded_iter(&self) -> sp_std::vec::IntoIter<Vec<u8>>;
|
||||||
@@ -215,6 +220,15 @@ impl<T: TupleToEncodedIter> TupleToEncodedIter for &T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: EncodeLike<U> + TupleToEncodedIter, U: Encode> TupleToEncodedIter
|
||||||
|
for codec::Ref<'a, T, U>
|
||||||
|
{
|
||||||
|
fn to_encoded_iter(&self) -> sp_std::vec::IntoIter<Vec<u8>> {
|
||||||
|
use core::ops::Deref as _;
|
||||||
|
self.deref().to_encoded_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A trait that indicates the hashers for the keys generated are all reversible.
|
/// A trait that indicates the hashers for the keys generated are all reversible.
|
||||||
pub trait ReversibleKeyGenerator: KeyGenerator {
|
pub trait ReversibleKeyGenerator: KeyGenerator {
|
||||||
type ReversibleHasher;
|
type ReversibleHasher;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ use codec::FullCodec;
|
|||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
mod counted_map;
|
mod counted_map;
|
||||||
|
mod counted_nmap;
|
||||||
mod double_map;
|
mod double_map;
|
||||||
mod key;
|
mod key;
|
||||||
mod map;
|
mod map;
|
||||||
@@ -30,6 +31,7 @@ mod nmap;
|
|||||||
mod value;
|
mod value;
|
||||||
|
|
||||||
pub use counted_map::{CountedStorageMap, CountedStorageMapInstance};
|
pub use counted_map::{CountedStorageMap, CountedStorageMapInstance};
|
||||||
|
pub use counted_nmap::{CountedStorageNMap, CountedStorageNMapInstance};
|
||||||
pub use double_map::StorageDoubleMap;
|
pub use double_map::StorageDoubleMap;
|
||||||
pub use key::{
|
pub use key::{
|
||||||
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, Key, KeyGenerator,
|
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, Key, KeyGenerator,
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//! Storage map type. Implements StorageDoubleMap, StorageIterableDoubleMap,
|
//! Storage n-map type. Particularly implements `StorageNMap` and `StoragePrefixedMap`
|
||||||
//! StoragePrefixedDoubleMap traits and their methods directly.
|
//! traits and their methods directly.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR},
|
metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR},
|
||||||
|
|||||||
@@ -368,6 +368,27 @@ pub mod pallet {
|
|||||||
ResultQuery<Error<T>::NonExistentStorageValue>,
|
ResultQuery<Error<T>::NonExistentStorageValue>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
#[pallet::storage]
|
||||||
|
#[pallet::getter(fn counted_nmap)]
|
||||||
|
pub type CountedNMap<T> = CountedStorageNMap<_, storage::Key<Blake2_128Concat, u8>, u32>;
|
||||||
|
|
||||||
|
#[pallet::storage]
|
||||||
|
#[pallet::getter(fn counted_nmap2)]
|
||||||
|
pub type CountedNMap2<T> = CountedStorageNMap<
|
||||||
|
Key = (NMapKey<Twox64Concat, u16>, NMapKey<Blake2_128Concat, u32>),
|
||||||
|
Value = u64,
|
||||||
|
MaxValues = ConstU32<11>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
#[pallet::storage]
|
||||||
|
#[pallet::getter(fn counted_nmap3)]
|
||||||
|
pub type CountedNMap3<T> = CountedStorageNMap<
|
||||||
|
_,
|
||||||
|
(NMapKey<Blake2_128Concat, u8>, NMapKey<Twox64Concat, u16>),
|
||||||
|
u128,
|
||||||
|
ResultQuery<Error<T>::NonExistentStorageValue>,
|
||||||
|
>;
|
||||||
|
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
#[pallet::getter(fn conditional_value)]
|
#[pallet::getter(fn conditional_value)]
|
||||||
#[cfg(feature = "frame-feature-testing")]
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
@@ -391,6 +412,15 @@ pub mod pallet {
|
|||||||
pub type ConditionalNMap<T> =
|
pub type ConditionalNMap<T> =
|
||||||
StorageNMap<_, (storage::Key<Blake2_128Concat, u8>, storage::Key<Twox64Concat, u16>), u32>;
|
StorageNMap<_, (storage::Key<Blake2_128Concat, u8>, storage::Key<Twox64Concat, u16>), u32>;
|
||||||
|
|
||||||
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
|
#[pallet::storage]
|
||||||
|
#[pallet::getter(fn conditional_counted_nmap)]
|
||||||
|
pub type ConditionalCountedNMap<T> = CountedStorageNMap<
|
||||||
|
_,
|
||||||
|
(storage::Key<Blake2_128Concat, u8>, storage::Key<Twox64Concat, u16>),
|
||||||
|
u32,
|
||||||
|
>;
|
||||||
|
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
#[pallet::storage_prefix = "RenamedCountedMap"]
|
#[pallet::storage_prefix = "RenamedCountedMap"]
|
||||||
#[pallet::getter(fn counted_storage_map)]
|
#[pallet::getter(fn counted_storage_map)]
|
||||||
@@ -1125,6 +1155,7 @@ fn storage_expand() {
|
|||||||
k.extend(2u32.using_encoded(blake2_128_concat));
|
k.extend(2u32.using_encoded(blake2_128_concat));
|
||||||
assert_eq!(unhashed::get::<u64>(&k), Some(3u64));
|
assert_eq!(unhashed::get::<u64>(&k), Some(3u64));
|
||||||
assert_eq!(&k[..32], &<pallet::NMap2<Runtime>>::final_prefix());
|
assert_eq!(&k[..32], &<pallet::NMap2<Runtime>>::final_prefix());
|
||||||
|
assert_eq!(pallet::Pallet::<Runtime>::nmap2((1, 2)), Some(3u64));
|
||||||
|
|
||||||
pallet::NMap3::<Runtime>::insert((&1, &2), &3);
|
pallet::NMap3::<Runtime>::insert((&1, &2), &3);
|
||||||
let mut k = [twox_128(b"Example"), twox_128(b"NMap3")].concat();
|
let mut k = [twox_128(b"Example"), twox_128(b"NMap3")].concat();
|
||||||
@@ -1132,11 +1163,56 @@ fn storage_expand() {
|
|||||||
k.extend(2u16.using_encoded(twox_64_concat));
|
k.extend(2u16.using_encoded(twox_64_concat));
|
||||||
assert_eq!(unhashed::get::<u128>(&k), Some(3u128));
|
assert_eq!(unhashed::get::<u128>(&k), Some(3u128));
|
||||||
assert_eq!(&k[..32], &<pallet::NMap3<Runtime>>::final_prefix());
|
assert_eq!(&k[..32], &<pallet::NMap3<Runtime>>::final_prefix());
|
||||||
|
assert_eq!(pallet::Pallet::<Runtime>::nmap3((1, 2)), Ok(3u128));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pallet::NMap3::<Runtime>::get((2, 3)),
|
pallet::NMap3::<Runtime>::get((2, 3)),
|
||||||
Err(pallet::Error::<Runtime>::NonExistentStorageValue),
|
Err(pallet::Error::<Runtime>::NonExistentStorageValue),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pallet::CountedNMap::<Runtime>::insert((&1,), &3);
|
||||||
|
let mut k = [twox_128(b"Example"), twox_128(b"CountedNMap")].concat();
|
||||||
|
k.extend(1u8.using_encoded(blake2_128_concat));
|
||||||
|
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
|
||||||
|
assert_eq!(pallet::CountedNMap::<Runtime>::count(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
unhashed::get::<u32>(
|
||||||
|
&[twox_128(b"Example"), twox_128(b"CounterForCountedNMap")].concat()
|
||||||
|
),
|
||||||
|
Some(1u32)
|
||||||
|
);
|
||||||
|
|
||||||
|
pallet::CountedNMap2::<Runtime>::insert((&1, &2), &3);
|
||||||
|
let mut k = [twox_128(b"Example"), twox_128(b"CountedNMap2")].concat();
|
||||||
|
k.extend(1u16.using_encoded(twox_64_concat));
|
||||||
|
k.extend(2u32.using_encoded(blake2_128_concat));
|
||||||
|
assert_eq!(unhashed::get::<u64>(&k), Some(3u64));
|
||||||
|
assert_eq!(pallet::CountedNMap2::<Runtime>::count(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
unhashed::get::<u32>(
|
||||||
|
&[twox_128(b"Example"), twox_128(b"CounterForCountedNMap2")].concat()
|
||||||
|
),
|
||||||
|
Some(1u32)
|
||||||
|
);
|
||||||
|
assert_eq!(pallet::Pallet::<Runtime>::counted_nmap2((1, 2)), Some(3u64));
|
||||||
|
|
||||||
|
pallet::CountedNMap3::<Runtime>::insert((&1, &2), &3);
|
||||||
|
let mut k = [twox_128(b"Example"), twox_128(b"CountedNMap3")].concat();
|
||||||
|
k.extend(1u8.using_encoded(blake2_128_concat));
|
||||||
|
k.extend(2u16.using_encoded(twox_64_concat));
|
||||||
|
assert_eq!(pallet::CountedNMap3::<Runtime>::count(), 1);
|
||||||
|
assert_eq!(unhashed::get::<u128>(&k), Some(3u128));
|
||||||
|
assert_eq!(pallet::Pallet::<Runtime>::counted_nmap3((1, 2)), Ok(3u128));
|
||||||
|
assert_eq!(
|
||||||
|
pallet::CountedNMap3::<Runtime>::get((2, 3)),
|
||||||
|
Err(pallet::Error::<Runtime>::NonExistentStorageValue),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unhashed::get::<u32>(
|
||||||
|
&[twox_128(b"Example"), twox_128(b"CounterForCountedNMap3")].concat()
|
||||||
|
),
|
||||||
|
Some(1u32)
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "frame-feature-testing")]
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
{
|
{
|
||||||
pallet::ConditionalValue::<Runtime>::put(1);
|
pallet::ConditionalValue::<Runtime>::put(1);
|
||||||
@@ -1457,6 +1533,66 @@ fn metadata() {
|
|||||||
default: vec![1, 1],
|
default: vec![1, 1],
|
||||||
docs: vec![],
|
docs: vec![],
|
||||||
},
|
},
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "CountedNMap",
|
||||||
|
modifier: StorageEntryModifier::Optional,
|
||||||
|
ty: StorageEntryType::Map {
|
||||||
|
key: meta_type::<u8>(),
|
||||||
|
hashers: vec![StorageHasher::Blake2_128Concat],
|
||||||
|
value: meta_type::<u32>(),
|
||||||
|
},
|
||||||
|
default: vec![0],
|
||||||
|
docs: vec![],
|
||||||
|
},
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "CounterForCountedNMap",
|
||||||
|
modifier: StorageEntryModifier::Default,
|
||||||
|
ty: StorageEntryType::Plain(meta_type::<u32>()),
|
||||||
|
default: vec![0, 0, 0, 0],
|
||||||
|
docs: maybe_docs(vec!["Counter for the related counted storage map"]),
|
||||||
|
},
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "CountedNMap2",
|
||||||
|
modifier: StorageEntryModifier::Optional,
|
||||||
|
ty: StorageEntryType::Map {
|
||||||
|
key: meta_type::<(u16, u32)>(),
|
||||||
|
hashers: vec![
|
||||||
|
StorageHasher::Twox64Concat,
|
||||||
|
StorageHasher::Blake2_128Concat,
|
||||||
|
],
|
||||||
|
value: meta_type::<u64>(),
|
||||||
|
},
|
||||||
|
default: vec![0],
|
||||||
|
docs: vec![],
|
||||||
|
},
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "CounterForCountedNMap2",
|
||||||
|
modifier: StorageEntryModifier::Default,
|
||||||
|
ty: StorageEntryType::Plain(meta_type::<u32>()),
|
||||||
|
default: vec![0, 0, 0, 0],
|
||||||
|
docs: maybe_docs(vec!["Counter for the related counted storage map"]),
|
||||||
|
},
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "CountedNMap3",
|
||||||
|
modifier: StorageEntryModifier::Optional,
|
||||||
|
ty: StorageEntryType::Map {
|
||||||
|
key: meta_type::<(u8, u16)>(),
|
||||||
|
hashers: vec![
|
||||||
|
StorageHasher::Blake2_128Concat,
|
||||||
|
StorageHasher::Twox64Concat,
|
||||||
|
],
|
||||||
|
value: meta_type::<u128>(),
|
||||||
|
},
|
||||||
|
default: vec![1, 1],
|
||||||
|
docs: vec![],
|
||||||
|
},
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "CounterForCountedNMap3",
|
||||||
|
modifier: StorageEntryModifier::Default,
|
||||||
|
ty: StorageEntryType::Plain(meta_type::<u32>()),
|
||||||
|
default: vec![0, 0, 0, 0],
|
||||||
|
docs: maybe_docs(vec!["Counter for the related counted storage map"]),
|
||||||
|
},
|
||||||
#[cfg(feature = "frame-feature-testing")]
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
StorageEntryMetadata {
|
StorageEntryMetadata {
|
||||||
name: "ConditionalValue",
|
name: "ConditionalValue",
|
||||||
@@ -1507,6 +1643,29 @@ fn metadata() {
|
|||||||
default: vec![0],
|
default: vec![0],
|
||||||
docs: vec![],
|
docs: vec![],
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "ConditionalCountedNMap",
|
||||||
|
modifier: StorageEntryModifier::Optional,
|
||||||
|
ty: StorageEntryType::Map {
|
||||||
|
key: meta_type::<(u8, u16)>(),
|
||||||
|
hashers: vec![
|
||||||
|
StorageHasher::Blake2_128Concat,
|
||||||
|
StorageHasher::Twox64Concat,
|
||||||
|
],
|
||||||
|
value: meta_type::<u32>(),
|
||||||
|
},
|
||||||
|
default: vec![0],
|
||||||
|
docs: vec![],
|
||||||
|
},
|
||||||
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
|
StorageEntryMetadata {
|
||||||
|
name: "CounterForConditionalCountedNMap",
|
||||||
|
modifier: StorageEntryModifier::Default,
|
||||||
|
ty: StorageEntryType::Plain(meta_type::<u32>()),
|
||||||
|
default: vec![0, 0, 0, 0],
|
||||||
|
docs: maybe_docs(vec!["Counter for the related counted storage map"]),
|
||||||
|
},
|
||||||
StorageEntryMetadata {
|
StorageEntryMetadata {
|
||||||
name: "RenamedCountedMap",
|
name: "RenamedCountedMap",
|
||||||
modifier: StorageEntryModifier::Optional,
|
modifier: StorageEntryModifier::Optional,
|
||||||
@@ -1873,6 +2032,48 @@ fn test_storage_info() {
|
|||||||
max_values: None,
|
max_values: None,
|
||||||
max_size: Some(16 + 1 + 8 + 2 + 16),
|
max_size: Some(16 + 1 + 8 + 2 + 16),
|
||||||
},
|
},
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"CountedNMap".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"CountedNMap").to_vec(),
|
||||||
|
max_values: None,
|
||||||
|
max_size: Some(16 + 1 + 4),
|
||||||
|
},
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"CounterForCountedNMap".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"CounterForCountedNMap").to_vec(),
|
||||||
|
max_values: Some(1),
|
||||||
|
max_size: Some(4),
|
||||||
|
},
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"CountedNMap2".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"CountedNMap2").to_vec(),
|
||||||
|
max_values: Some(11),
|
||||||
|
max_size: Some(8 + 2 + 16 + 4 + 8),
|
||||||
|
},
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"CounterForCountedNMap2".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"CounterForCountedNMap2").to_vec(),
|
||||||
|
max_values: Some(1),
|
||||||
|
max_size: Some(4),
|
||||||
|
},
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"CountedNMap3".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"CountedNMap3").to_vec(),
|
||||||
|
max_values: None,
|
||||||
|
max_size: Some(16 + 1 + 8 + 2 + 16),
|
||||||
|
},
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"CounterForCountedNMap3".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"CounterForCountedNMap3").to_vec(),
|
||||||
|
max_values: Some(1),
|
||||||
|
max_size: Some(4),
|
||||||
|
},
|
||||||
#[cfg(feature = "frame-feature-testing")]
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
{
|
{
|
||||||
StorageInfo {
|
StorageInfo {
|
||||||
@@ -1913,6 +2114,26 @@ fn test_storage_info() {
|
|||||||
max_size: Some(16 + 1 + 8 + 2 + 4),
|
max_size: Some(16 + 1 + 8 + 2 + 4),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
|
{
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"ConditionalCountedNMap".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"ConditionalCountedNMap").to_vec(),
|
||||||
|
max_values: None,
|
||||||
|
max_size: Some(16 + 1 + 8 + 2 + 4),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#[cfg(feature = "frame-feature-testing")]
|
||||||
|
{
|
||||||
|
StorageInfo {
|
||||||
|
pallet_name: b"Example".to_vec(),
|
||||||
|
storage_name: b"CounterForConditionalCountedNMap".to_vec(),
|
||||||
|
prefix: prefix(b"Example", b"CounterForConditionalCountedNMap").to_vec(),
|
||||||
|
max_values: Some(1),
|
||||||
|
max_size: Some(4),
|
||||||
|
}
|
||||||
|
},
|
||||||
StorageInfo {
|
StorageInfo {
|
||||||
pallet_name: b"Example".to_vec(),
|
pallet_name: b"Example".to_vec(),
|
||||||
storage_name: b"RenamedCountedMap".to_vec(),
|
storage_name: b"RenamedCountedMap".to_vec(),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
error: Invalid pallet::storage, expected ident: `StorageValue` or `StorageMap` or `CountedStorageMap` or `StorageDoubleMap` or `StorageNMap` in order to expand metadata, found `u8`.
|
error: Invalid pallet::storage, expected ident: `StorageValue` or `StorageMap` or `CountedStorageMap` or `StorageDoubleMap` or `StorageNMap` or `CountedStorageNMap` in order to expand metadata, found `u8`.
|
||||||
--> $DIR/storage_not_storage_type.rs:19:16
|
--> $DIR/storage_not_storage_type.rs:19:16
|
||||||
|
|
|
|
||||||
19 | type Foo<T> = u8;
|
19 | type Foo<T> = u8;
|
||||||
|
|||||||
Reference in New Issue
Block a user