mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 09:21:05 +00:00
Forward port blake2 storage support (#2360)
* move storage maps to blake2_128 (#2268) * remove default hash, introduce twox_128 and blake2 * use blake2_128 & create ext_blake2_128 * refactor code * add benchmark * factorize generator * fix * parameterizable hasher * some fix * fix * fix * fix * metadata * fix * remove debug print * map -> blake2_256 * fix test * fix test * Apply suggestions from code review Co-Authored-By: thiolliere <gui.thiolliere@gmail.com> * impl twox 128 concat (#2353) * impl twox_128_concat * comment addressed * fix * impl twox_128->64_concat * fix test * Fix compilation and cleanup some docs * Apply suggestions from code review Co-Authored-By: bkchr <bkchr@users.noreply.github.com>
This commit is contained in:
committed by
Gavin Wood
parent
21d1ee4e99
commit
f0862606b7
@@ -67,13 +67,13 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
|
||||
let mutate_impl = if !is_option {
|
||||
quote!{
|
||||
<Self as #scrate::storage::generator::StorageValue<#typ>>::put(&val, storage)
|
||||
<Self as #scrate::storage::hashed::generator::StorageValue<#typ>>::put(&val, storage)
|
||||
}
|
||||
} else {
|
||||
quote!{
|
||||
match val {
|
||||
Some(ref val) => <Self as #scrate::storage::generator::StorageValue<#typ>>::put(&val, storage),
|
||||
None => <Self as #scrate::storage::generator::StorageValue<#typ>>::kill(storage),
|
||||
Some(ref val) => <Self as #scrate::storage::hashed::generator::StorageValue<#typ>>::put(&val, storage),
|
||||
None => <Self as #scrate::storage::hashed::generator::StorageValue<#typ>>::kill(storage),
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -96,9 +96,12 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
// generator for value
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>);
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>
|
||||
(#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>);
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::StorageValue<#typ> for #name<#traitinstance, #instance> {
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::StorageValue<#typ> for #name<#traitinstance, #instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
/// Get the storage key.
|
||||
@@ -107,20 +110,20 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
|
||||
/// Load the value from the provided storage instance.
|
||||
fn get<S: #scrate::GenericStorage>(storage: &S) -> Self::Query {
|
||||
storage.get(<Self as #scrate::storage::generator::StorageValue<#typ>>::key())
|
||||
fn get<S: #scrate::HashedStorage<#scrate::Twox128>>(storage: &S) -> Self::Query {
|
||||
storage.get(<Self as #scrate::storage::hashed::generator::StorageValue<#typ>>::key())
|
||||
.#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Take a value from storage, removing it afterwards.
|
||||
fn take<S: #scrate::GenericStorage>(storage: &S) -> Self::Query {
|
||||
storage.take(<Self as #scrate::storage::generator::StorageValue<#typ>>::key())
|
||||
fn take<S: #scrate::HashedStorage<#scrate::Twox128>>(storage: &S) -> Self::Query {
|
||||
storage.take(<Self as #scrate::storage::hashed::generator::StorageValue<#typ>>::key())
|
||||
.#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Mutate the value under a key.
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::GenericStorage>(f: F, storage: &S) -> R {
|
||||
let mut val = <Self as #scrate::storage::generator::StorageValue<#typ>>::get(storage);
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::HashedStorage<#scrate::Twox128>>(f: F, storage: &S) -> R {
|
||||
let mut val = <Self as #scrate::storage::hashed::generator::StorageValue<#typ>>::get(storage);
|
||||
|
||||
let ret = f(&mut val);
|
||||
#mutate_impl ;
|
||||
@@ -130,7 +133,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map(self, kty: &syn::Type) -> TokenStream2 {
|
||||
pub fn map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 {
|
||||
let Self {
|
||||
scrate,
|
||||
visibility,
|
||||
@@ -147,15 +150,17 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos;
|
||||
let option_simple_1 = option_unwrap(is_option);
|
||||
|
||||
let as_map = quote!{ <Self as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>> };
|
||||
|
||||
let mutate_impl = if !is_option {
|
||||
quote!{
|
||||
<Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::insert(key, &val, storage)
|
||||
#as_map::insert(key, &val, storage)
|
||||
}
|
||||
} else {
|
||||
quote!{
|
||||
match val {
|
||||
Some(ref val) => <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::insert(key, &val, storage),
|
||||
None => <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::remove(key, storage),
|
||||
Some(ref val) => #as_map::insert(key, &val, storage),
|
||||
None => #as_map::remove(key, storage),
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -178,11 +183,16 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
// generator for map
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>);
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>
|
||||
(#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>);
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> {
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
type Hasher = #scrate::#hasher;
|
||||
|
||||
/// Get the prefix key in storage.
|
||||
fn prefix() -> &'static [u8] {
|
||||
#final_prefix
|
||||
@@ -190,26 +200,26 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
|
||||
/// Get the storage key used to fetch a value corresponding to a specific key.
|
||||
fn key_for(x: &#kty) -> #scrate::rstd::vec::Vec<u8> {
|
||||
let mut key = <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::prefix().to_vec();
|
||||
let mut key = #as_map::prefix().to_vec();
|
||||
#scrate::codec::Encode::encode_to(x, &mut key);
|
||||
key
|
||||
}
|
||||
|
||||
/// Load the value associated with the given key from the map.
|
||||
fn get<S: #scrate::GenericStorage>(key: &#kty, storage: &S) -> Self::Query {
|
||||
let key = <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(key);
|
||||
fn get<S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, storage: &S) -> Self::Query {
|
||||
let key = #as_map::key_for(key);
|
||||
storage.get(&key[..]).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Take the value, reading and removing it.
|
||||
fn take<S: #scrate::GenericStorage>(key: &#kty, storage: &S) -> Self::Query {
|
||||
let key = <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(key);
|
||||
fn take<S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, storage: &S) -> Self::Query {
|
||||
let key = #as_map::key_for(key);
|
||||
storage.take(&key[..]).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Mutate the value under a key
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::GenericStorage>(key: &#kty, f: F, storage: &S) -> R {
|
||||
let mut val = <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::get(key, storage);
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, f: F, storage: &S) -> R {
|
||||
let mut val = #as_map::get(key, storage);
|
||||
|
||||
let ret = f(&mut val);
|
||||
#mutate_impl ;
|
||||
@@ -220,7 +230,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn linked_map(self, kty: &syn::Type) -> TokenStream2 {
|
||||
pub fn linked_map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 {
|
||||
let Self {
|
||||
scrate,
|
||||
visibility,
|
||||
@@ -264,8 +274,8 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
let name_lowercase = name.to_string().to_lowercase();
|
||||
let inner_module = syn::Ident::new(&format!("__linked_map_details_for_{}_do_not_use", name_lowercase), name.span());
|
||||
let linkage = syn::Ident::new(&format!("__LinkageFor{}DoNotUse", name), name.span());
|
||||
let phantom_data = quote! { #scrate::storage::generator::PhantomData };
|
||||
let as_map = quote!{ <Self as #scrate::storage::generator::StorageMap<#kty, #typ>> };
|
||||
let phantom_data = quote! { #scrate::rstd::marker::PhantomData };
|
||||
let as_map = quote!{ <Self as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>> };
|
||||
let put_or_insert = quote! {
|
||||
match linkage {
|
||||
Some(linkage) => storage.put(key_for, &(val, linkage)),
|
||||
@@ -316,14 +326,17 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
pub _data: #phantom_data<V>,
|
||||
}
|
||||
|
||||
impl<'a, S: #scrate::GenericStorage, #traitinstance: #traittype, #instance #bound_instantiable> Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)>
|
||||
impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #traitinstance: #traittype, #instance #bound_instantiable>
|
||||
Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)>
|
||||
where #traitinstance: 'a
|
||||
{
|
||||
type Item = (#kty, #typ);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let next = self.next.take()?;
|
||||
let key_for = <super::#name<#traitinstance, #instance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(&next);
|
||||
let key_for = <super::#name<#traitinstance, #instance>
|
||||
as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>>::key_for(&next);
|
||||
|
||||
let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for)
|
||||
.expect("previous/next only contain existing entires; we enumerate using next; entry exists; qed");
|
||||
self.next = linkage.next;
|
||||
@@ -336,26 +349,26 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
///
|
||||
/// Takes care of updating previous and next elements points
|
||||
/// as well as updates head if the element is first or last.
|
||||
fn remove_linkage<S: #scrate::GenericStorage>(linkage: Linkage<#kty>, storage: &S);
|
||||
fn remove_linkage<S: #scrate::HashedStorage<#scrate::#hasher>>(linkage: Linkage<#kty>, storage: &S);
|
||||
|
||||
/// Read the contained data and it's linkage.
|
||||
fn read_with_linkage<S: #scrate::GenericStorage>(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>;
|
||||
fn read_with_linkage<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>;
|
||||
|
||||
/// Generate linkage for newly inserted element.
|
||||
///
|
||||
/// Takes care of updating head and previous head's pointer.
|
||||
fn new_head_linkage<S: #scrate::GenericStorage>(
|
||||
fn new_head_linkage<S: #scrate::HashedStorage<#scrate::#hasher>>(
|
||||
storage: &S,
|
||||
key: &#kty,
|
||||
) -> Linkage<#kty>;
|
||||
|
||||
/// Read current head pointer.
|
||||
fn read_head<S: #scrate::GenericStorage>(storage: &S) -> Option<#kty>;
|
||||
fn read_head<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S) -> Option<#kty>;
|
||||
|
||||
/// Overwrite current head pointer.
|
||||
///
|
||||
/// If `None` is given head is removed from storage.
|
||||
fn write_head<S: #scrate::GenericStorage>(storage: &S, head: Option<&#kty>);
|
||||
fn write_head<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S, head: Option<&#kty>);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -365,7 +378,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#phantom_data<(#traitinstance #comma_instance)>);
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> self::#inner_module::Utils<#traitinstance, #instance> for #name<#traitinstance, #instance> {
|
||||
fn remove_linkage<S: #scrate::GenericStorage>(
|
||||
fn remove_linkage<S: #scrate::HashedStorage<#scrate::#hasher>>(
|
||||
linkage: self::#inner_module::Linkage<#kty>,
|
||||
storage: &S,
|
||||
) {
|
||||
@@ -394,14 +407,14 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_with_linkage<S: #scrate::GenericStorage>(
|
||||
fn read_with_linkage<S: #scrate::HashedStorage<#scrate::#hasher>>(
|
||||
storage: &S,
|
||||
key: &[u8],
|
||||
) -> Option<(#value_type, self::#inner_module::Linkage<#kty>)> {
|
||||
storage.get(key)
|
||||
}
|
||||
|
||||
fn new_head_linkage<S: #scrate::GenericStorage>(
|
||||
fn new_head_linkage<S: #scrate::HashedStorage<#scrate::#hasher>>(
|
||||
storage: &S,
|
||||
key: &#kty,
|
||||
) -> self::#inner_module::Linkage<#kty> {
|
||||
@@ -433,11 +446,11 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_head<S: #scrate::GenericStorage>(storage: &S) -> Option<#kty> {
|
||||
fn read_head<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S) -> Option<#kty> {
|
||||
storage.get(#final_head_key)
|
||||
}
|
||||
|
||||
fn write_head<S: #scrate::GenericStorage>(storage: &S, head: Option<&#kty>) {
|
||||
fn write_head<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S, head: Option<&#kty>) {
|
||||
match head {
|
||||
Some(head) => storage.put(#final_head_key, head),
|
||||
None => storage.kill(#final_head_key),
|
||||
@@ -451,9 +464,13 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
|
||||
#structure
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> {
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
type Hasher = #scrate::#hasher;
|
||||
|
||||
/// Get the prefix key in storage.
|
||||
fn prefix() -> &'static [u8] {
|
||||
#final_prefix
|
||||
@@ -467,12 +484,12 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
|
||||
/// Load the value associated with the given key from the map.
|
||||
fn get<S: #scrate::GenericStorage>(key: &#kty, storage: &S) -> Self::Query {
|
||||
fn get<S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, storage: &S) -> Self::Query {
|
||||
storage.get(&*#as_map::key_for(key)).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Take the value, reading and removing it.
|
||||
fn take<S: #scrate::GenericStorage>(key: &#kty, storage: &S) -> Self::Query {
|
||||
fn take<S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, storage: &S) -> Self::Query {
|
||||
use self::#inner_module::Utils;
|
||||
|
||||
let res: Option<(#value_type, self::#inner_module::Linkage<#kty>)> = storage.take(&*#as_map::key_for(key));
|
||||
@@ -486,12 +503,12 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
|
||||
/// Remove the value under a key.
|
||||
fn remove<S: #scrate::GenericStorage>(key: &#kty, storage: &S) {
|
||||
fn remove<S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, storage: &S) {
|
||||
#as_map::take(key, storage);
|
||||
}
|
||||
|
||||
/// Store a value to be associated with the given key from the map.
|
||||
fn insert<S: #scrate::GenericStorage>(key: &#kty, val: &#typ, storage: &S) {
|
||||
fn insert<S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, val: &#typ, storage: &S) {
|
||||
use self::#inner_module::Utils;
|
||||
|
||||
let key_for = &*#as_map::key_for(key);
|
||||
@@ -505,7 +522,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
|
||||
/// Mutate the value under a key
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::GenericStorage>(key: &#kty, f: F, storage: &S) -> R {
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, f: F, storage: &S) -> R {
|
||||
use self::#inner_module::Utils;
|
||||
|
||||
let key_for = &*#as_map::key_for(key);
|
||||
@@ -519,20 +536,22 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> #scrate::storage::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> {
|
||||
fn head<S: #scrate::GenericStorage>(storage: &S) -> Option<#kty> {
|
||||
impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance>
|
||||
{
|
||||
fn head<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S) -> Option<#kty> {
|
||||
use self::#inner_module::Utils;
|
||||
|
||||
Self::read_head(storage)
|
||||
}
|
||||
|
||||
fn enumerate<'a, S: #scrate::GenericStorage>(storage: &'a S) -> #scrate::storage::generator::Box<dyn Iterator<Item = (#kty, #typ)> + 'a> where
|
||||
fn enumerate<'a, S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &'a S) -> #scrate::rstd::boxed::Box<dyn Iterator<Item = (#kty, #typ)> + 'a> where
|
||||
#kty: 'a,
|
||||
#typ: 'a,
|
||||
{
|
||||
use self::#inner_module::{Utils, Enumerator};
|
||||
|
||||
#scrate::storage::generator::Box::new(Enumerator {
|
||||
#scrate::rstd::boxed::Box::new(Enumerator {
|
||||
next: Self::read_head(storage),
|
||||
storage,
|
||||
_data: #phantom_data::<(#typ, #traitinstance, #instance)>::default(),
|
||||
@@ -542,7 +561,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn double_map(self, k1ty: &syn::Type, k2ty: &syn::Type, k2_hasher: TokenStream2) -> TokenStream2 {
|
||||
pub fn double_map(self, hasher: TokenStream2, k1ty: &syn::Type, k2ty: &syn::Type, k2_hasher: TokenStream2) -> TokenStream2 {
|
||||
let Self {
|
||||
scrate,
|
||||
visibility,
|
||||
@@ -593,11 +612,20 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
// generator for double map
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>);
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>
|
||||
(#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>);
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#traitinstance, #instance> {
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#traitinstance, #instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
fn prefix_for(k1: &#k1ty) -> Vec<u8> {
|
||||
let mut key = #as_double_map::prefix().to_vec();
|
||||
#scrate::codec::Encode::encode_to(k1, &mut key);
|
||||
#scrate::Hashable::#hasher(&key).to_vec()
|
||||
}
|
||||
|
||||
fn prefix() -> &'static [u8] {
|
||||
#final_prefix
|
||||
}
|
||||
@@ -608,17 +636,17 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
key
|
||||
}
|
||||
|
||||
fn get<S: #scrate::GenericUnhashedStorage>(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query {
|
||||
fn get<S: #scrate::UnhashedStorage>(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query {
|
||||
let key = #as_double_map::key_for(key1, key2);
|
||||
storage.get(&key).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
fn take<S: #scrate::GenericUnhashedStorage>(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query {
|
||||
fn take<S: #scrate::UnhashedStorage>(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query {
|
||||
let key = #as_double_map::key_for(key1, key2);
|
||||
storage.take(&key).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::GenericUnhashedStorage>(key1: &#k1ty, key2: &#k2ty, f: F, storage: &S) -> R {
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::UnhashedStorage>(key1: &#k1ty, key2: &#k2ty, f: F, storage: &S) -> R {
|
||||
let mut val = #as_double_map::get(key1, key2, storage);
|
||||
|
||||
let ret = f(&mut val);
|
||||
|
||||
@@ -23,6 +23,8 @@ use srml_support_procedural_tools::{ToTokens, Parse, custom_keyword, custom_keyw
|
||||
|
||||
use syn::{Ident, Token};
|
||||
use syn::token::CustomKeyword;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
|
||||
mod impls;
|
||||
|
||||
@@ -138,6 +140,7 @@ enum DeclStorageType {
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
struct DeclStorageMap {
|
||||
pub map_keyword: ext::CustomToken<MapKeyword>,
|
||||
pub hasher: Option<SetHasher>,
|
||||
pub key: syn::Type,
|
||||
pub ass_keyword: Token![=>],
|
||||
pub value: syn::Type,
|
||||
@@ -146,6 +149,7 @@ struct DeclStorageMap {
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
struct DeclStorageLinkedMap {
|
||||
pub map_keyword: ext::CustomToken<LinkedMapKeyword>,
|
||||
pub hasher: Option<SetHasher>,
|
||||
pub key: syn::Type,
|
||||
pub ass_keyword: Token![=>],
|
||||
pub value: syn::Type,
|
||||
@@ -154,19 +158,22 @@ struct DeclStorageLinkedMap {
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
struct DeclStorageDoubleMap {
|
||||
pub map_keyword: ext::CustomToken<DoubleMapKeyword>,
|
||||
pub hasher: Option<SetHasher>,
|
||||
pub key1: syn::Type,
|
||||
pub comma_keyword: Token![,],
|
||||
pub key2_hasher: DeclStorageDoubleMapHasher,
|
||||
pub key2_hasher: Hasher,
|
||||
pub key2: ext::Parens<syn::Type>,
|
||||
pub ass_keyword: Token![=>],
|
||||
pub value: syn::Type,
|
||||
}
|
||||
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
enum DeclStorageDoubleMapHasher {
|
||||
enum Hasher {
|
||||
Blake2_256(ext::CustomToken<Blake2_256Keyword>),
|
||||
Blake2_128(ext::CustomToken<Blake2_128Keyword>),
|
||||
Twox256(ext::CustomToken<Twox256Keyword>),
|
||||
Twox128(ext::CustomToken<Twox128Keyword>),
|
||||
Twox64Concat(ext::CustomToken<Twox64ConcatKeyword>),
|
||||
}
|
||||
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
@@ -175,6 +182,64 @@ struct DeclStorageDefault {
|
||||
pub expr: syn::Expr,
|
||||
}
|
||||
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
struct SetHasher {
|
||||
pub hasher_keyword: ext::CustomToken<SetHasher>,
|
||||
pub inner: ext::Parens<Hasher>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum HasherKind {
|
||||
Blake2_256,
|
||||
Blake2_128,
|
||||
Twox256,
|
||||
Twox128,
|
||||
Twox64Concat,
|
||||
}
|
||||
|
||||
impl From<&SetHasher> for HasherKind {
|
||||
fn from(set_hasher: &SetHasher) -> Self {
|
||||
match set_hasher.inner.content {
|
||||
Hasher::Blake2_256(_) => HasherKind::Blake2_256,
|
||||
Hasher::Blake2_128(_) => HasherKind::Blake2_128,
|
||||
Hasher::Twox256(_) => HasherKind::Twox256,
|
||||
Hasher::Twox128(_) => HasherKind::Twox128,
|
||||
Hasher::Twox64Concat(_) => HasherKind::Twox64Concat,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl HasherKind {
|
||||
fn into_storage_hasher_struct(&self) -> TokenStream2 {
|
||||
match self {
|
||||
HasherKind::Blake2_256 => quote!( Blake2_256 ),
|
||||
HasherKind::Blake2_128 => quote!( Blake2_128 ),
|
||||
HasherKind::Twox256 => quote!( Twox256 ),
|
||||
HasherKind::Twox128 => quote!( Twox128 ),
|
||||
HasherKind::Twox64Concat => quote!( Twox64Concat ),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_hashable_fn(&self) -> TokenStream2 {
|
||||
match self {
|
||||
HasherKind::Blake2_256 => quote!( blake2_256 ),
|
||||
HasherKind::Blake2_128 => quote!( blake2_128 ),
|
||||
HasherKind::Twox256 => quote!( twox_256 ),
|
||||
HasherKind::Twox128 => quote!( twox_128 ),
|
||||
HasherKind::Twox64Concat => quote!( twox_64_concat),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_metadata(&self) -> TokenStream2 {
|
||||
match self {
|
||||
HasherKind::Blake2_256 => quote!( StorageHasher::Blake2_256 ),
|
||||
HasherKind::Blake2_128 => quote!( StorageHasher::Blake2_128 ),
|
||||
HasherKind::Twox256 => quote!( StorageHasher::Twox256 ),
|
||||
HasherKind::Twox128 => quote!( StorageHasher::Twox128 ),
|
||||
HasherKind::Twox64Concat => quote!( StorageHasher::Twox64Concat ),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
custom_keyword_impl!(SpecificHiddenCrate, "hiddencrate", "hiddencrate as keyword");
|
||||
custom_keyword_impl!(DeclStorageConfig, "config", "build as keyword");
|
||||
custom_keyword!(ConfigKeyword, "config", "config as keyword");
|
||||
@@ -186,6 +251,9 @@ custom_keyword!(MapKeyword, "map", "map as keyword");
|
||||
custom_keyword!(LinkedMapKeyword, "linked_map", "linked_map as keyword");
|
||||
custom_keyword!(DoubleMapKeyword, "double_map", "double_map as keyword");
|
||||
custom_keyword!(Blake2_256Keyword, "blake2_256", "Blake2_256 as keyword");
|
||||
custom_keyword!(Twox256Keyword, "twox_256", "Twox_256 as keyword");
|
||||
custom_keyword!(Twox128Keyword, "twox_128", "Twox_128 as keyword");
|
||||
custom_keyword!(Blake2_128Keyword, "blake2_128", "Blake2_128 as keyword");
|
||||
custom_keyword!(Twox256Keyword, "twox_256", "Twox256 as keyword");
|
||||
custom_keyword!(Twox128Keyword, "twox_128", "Twox128 as keyword");
|
||||
custom_keyword!(Twox64ConcatKeyword, "twox_64_concat", "Twox64Concat as keyword");
|
||||
custom_keyword_impl!(ExtraGenesisSkipPhantomDataField, "extra_genesis_skip_phantom_data_field", "extra_genesis_skip_phantom_data_field as keyword");
|
||||
custom_keyword_impl!(SetHasher, "hasher", "storage hasher");
|
||||
|
||||
@@ -156,13 +156,13 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream {
|
||||
impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> #module_ident<#traitinstance, #instance> {
|
||||
#impl_store_fns
|
||||
#[doc(hidden)]
|
||||
pub fn store_metadata() -> #scrate::storage::generator::StorageMetadata {
|
||||
#scrate::storage::generator::StorageMetadata {
|
||||
functions: #scrate::storage::generator::DecodeDifferent::Encode(#store_functions_to_metadata) ,
|
||||
pub fn store_metadata() -> #scrate::metadata::StorageMetadata {
|
||||
#scrate::metadata::StorageMetadata {
|
||||
functions: #scrate::metadata::DecodeDifferent::Encode(#store_functions_to_metadata) ,
|
||||
}
|
||||
}
|
||||
#[doc(hidden)]
|
||||
pub fn store_metadata_functions() -> &'static [#scrate::storage::generator::StorageFunctionMetadata] {
|
||||
pub fn store_metadata_functions() -> &'static [#scrate::metadata::StorageFunctionMetadata] {
|
||||
#store_functions_to_metadata
|
||||
}
|
||||
#[doc(hidden)]
|
||||
@@ -284,7 +284,7 @@ fn decl_store_extra_genesis(
|
||||
use #scrate::codec::{Encode, Decode};
|
||||
|
||||
let v = (#builder)(&self);
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::generator::StorageValue<#typ>>::put(&v, &storage);
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageValue<#typ>>::put(&v, &storage);
|
||||
}}
|
||||
},
|
||||
DeclStorageTypeInfosKind::Map { key_type, .. } => {
|
||||
@@ -294,7 +294,7 @@ fn decl_store_extra_genesis(
|
||||
|
||||
let data = (#builder)(&self);
|
||||
for (k, v) in data.into_iter() {
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage);
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage);
|
||||
}
|
||||
}}
|
||||
},
|
||||
@@ -402,7 +402,7 @@ fn decl_store_extra_genesis(
|
||||
|
||||
quote!{
|
||||
#[serde(skip)]
|
||||
pub _genesis_phantom_data: #scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>,
|
||||
pub _genesis_phantom_data: #scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>,
|
||||
},
|
||||
quote!{
|
||||
_genesis_phantom_data: Default::default(),
|
||||
@@ -440,12 +440,12 @@ fn decl_store_extra_genesis(
|
||||
#[cfg(feature = "std")]
|
||||
impl#fparam_impl #scrate::runtime_primitives::BuildStorage for GenesisConfig#sparam {
|
||||
fn assimilate_storage(self, r: &mut #scrate::runtime_primitives::StorageOverlay, c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay) -> ::std::result::Result<(), String> {
|
||||
use #scrate::rstd::{cell::RefCell, marker::PhantomData};
|
||||
let storage = (RefCell::new(r), PhantomData::<Self>::default());
|
||||
use #scrate::rstd::cell::RefCell;
|
||||
let storage = RefCell::new(r);
|
||||
|
||||
#builders
|
||||
|
||||
let r = storage.0.into_inner();
|
||||
let r = storage.into_inner();
|
||||
|
||||
#scall(r, c, &self);
|
||||
|
||||
@@ -589,14 +589,14 @@ fn decl_storage_items(
|
||||
DeclStorageTypeInfosKind::Simple => {
|
||||
i.simple_value()
|
||||
},
|
||||
DeclStorageTypeInfosKind::Map { key_type, is_linked: false } => {
|
||||
i.map(key_type)
|
||||
DeclStorageTypeInfosKind::Map { key_type, is_linked: false, hasher } => {
|
||||
i.map(hasher.into_storage_hasher_struct(), key_type)
|
||||
},
|
||||
DeclStorageTypeInfosKind::Map { key_type, is_linked: true } => {
|
||||
i.linked_map(key_type)
|
||||
DeclStorageTypeInfosKind::Map { key_type, is_linked: true, hasher } => {
|
||||
i.linked_map(hasher.into_storage_hasher_struct(), key_type)
|
||||
},
|
||||
DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher } => {
|
||||
i.double_map(key1_type, key2_type, key2_hasher)
|
||||
DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => {
|
||||
i.double_map(hasher.into_hashable_fn(), key1_type, key2_type, key2_hasher)
|
||||
},
|
||||
};
|
||||
impls.extend(implementation)
|
||||
@@ -662,15 +662,15 @@ fn impl_store_fns(
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
pub fn #get_fn() -> #value_type {
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage)
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage)
|
||||
}
|
||||
}
|
||||
},
|
||||
DeclStorageTypeInfosKind::Map { key_type, .. } => {
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
pub fn #get_fn<K: #scrate::storage::generator::Borrow<#key_type>>(key: K) -> #value_type {
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage)
|
||||
pub fn #get_fn<K: #scrate::rstd::borrow::Borrow<#key_type>>(key: K) -> #value_type {
|
||||
<#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -678,8 +678,8 @@ fn impl_store_fns(
|
||||
quote!{
|
||||
pub fn #get_fn<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> #value_type
|
||||
where
|
||||
KArg1: #scrate::storage::generator::Borrow<#key1_type>,
|
||||
KArg2: #scrate::storage::generator::Borrow<#key2_type>,
|
||||
KArg1: #scrate::rstd::borrow::Borrow<#key1_type>,
|
||||
KArg2: #scrate::rstd::borrow::Borrow<#key2_type>,
|
||||
{
|
||||
<#name<#traitinstance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>> :: get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage)
|
||||
}
|
||||
@@ -727,42 +727,46 @@ fn store_functions_to_metadata (
|
||||
let stype = match type_infos.kind {
|
||||
DeclStorageTypeInfosKind::Simple => {
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionType::Plain(
|
||||
#scrate::storage::generator::DecodeDifferent::Encode(#styp),
|
||||
#scrate::metadata::StorageFunctionType::Plain(
|
||||
#scrate::metadata::DecodeDifferent::Encode(#styp),
|
||||
)
|
||||
}
|
||||
},
|
||||
DeclStorageTypeInfosKind::Map { key_type, is_linked } => {
|
||||
DeclStorageTypeInfosKind::Map { key_type, is_linked, hasher } => {
|
||||
let hasher = hasher.into_metadata();
|
||||
let kty = clean_type_string("e!(#key_type).to_string());
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionType::Map {
|
||||
key: #scrate::storage::generator::DecodeDifferent::Encode(#kty),
|
||||
value: #scrate::storage::generator::DecodeDifferent::Encode(#styp),
|
||||
#scrate::metadata::StorageFunctionType::Map {
|
||||
hasher: #scrate::metadata::#hasher,
|
||||
key: #scrate::metadata::DecodeDifferent::Encode(#kty),
|
||||
value: #scrate::metadata::DecodeDifferent::Encode(#styp),
|
||||
is_linked: #is_linked,
|
||||
}
|
||||
}
|
||||
},
|
||||
DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher } => {
|
||||
DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => {
|
||||
let hasher = hasher.into_metadata();
|
||||
let k1ty = clean_type_string("e!(#key1_type).to_string());
|
||||
let k2ty = clean_type_string("e!(#key2_type).to_string());
|
||||
let k2_hasher = clean_type_string(&key2_hasher.to_string());
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionType::DoubleMap {
|
||||
key1: #scrate::storage::generator::DecodeDifferent::Encode(#k1ty),
|
||||
key2: #scrate::storage::generator::DecodeDifferent::Encode(#k2ty),
|
||||
value: #scrate::storage::generator::DecodeDifferent::Encode(#styp),
|
||||
key2_hasher: #scrate::storage::generator::DecodeDifferent::Encode(#k2_hasher),
|
||||
#scrate::metadata::StorageFunctionType::DoubleMap {
|
||||
hasher: #scrate::metadata::#hasher,
|
||||
key1: #scrate::metadata::DecodeDifferent::Encode(#k1ty),
|
||||
key2: #scrate::metadata::DecodeDifferent::Encode(#k2ty),
|
||||
value: #scrate::metadata::DecodeDifferent::Encode(#styp),
|
||||
key2_hasher: #scrate::metadata::DecodeDifferent::Encode(#k2_hasher),
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
let modifier = if type_infos.is_option {
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionModifier::Optional
|
||||
#scrate::metadata::StorageFunctionModifier::Optional
|
||||
}
|
||||
} else {
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionModifier::Default
|
||||
#scrate::metadata::StorageFunctionModifier::Default
|
||||
}
|
||||
};
|
||||
let default = default_value.inner.as_ref().map(|d| &d.expr)
|
||||
@@ -786,16 +790,16 @@ fn store_functions_to_metadata (
|
||||
let struct_name = proc_macro2::Ident::new(&("__GetByteStruct".to_string() + &str_name), name.span());
|
||||
let cache_name = proc_macro2::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), name.span());
|
||||
let item = quote! {
|
||||
#scrate::storage::generator::StorageFunctionMetadata {
|
||||
name: #scrate::storage::generator::DecodeDifferent::Encode(#str_name),
|
||||
#scrate::metadata::StorageFunctionMetadata {
|
||||
name: #scrate::metadata::DecodeDifferent::Encode(#str_name),
|
||||
modifier: #modifier,
|
||||
ty: #stype,
|
||||
default: #scrate::storage::generator::DecodeDifferent::Encode(
|
||||
#scrate::storage::generator::DefaultByteGetter(
|
||||
default: #scrate::metadata::DecodeDifferent::Encode(
|
||||
#scrate::metadata::DefaultByteGetter(
|
||||
&#struct_name::<#traitinstance, #instance>(#scrate::rstd::marker::PhantomData)
|
||||
)
|
||||
),
|
||||
documentation: #scrate::storage::generator::DecodeDifferent::Encode(&[ #docs ]),
|
||||
documentation: #scrate::metadata::DecodeDifferent::Encode(&[ #docs ]),
|
||||
},
|
||||
};
|
||||
items.extend(item);
|
||||
@@ -806,7 +810,7 @@ fn store_functions_to_metadata (
|
||||
#[allow(non_upper_case_globals)]
|
||||
static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec<u8>> = #scrate::once_cell::sync::OnceCell::INIT;
|
||||
#[cfg(feature = "std")]
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance, #instance> {
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte for #struct_name<#traitinstance, #instance> {
|
||||
fn default_byte(&self) -> #scrate::rstd::vec::Vec<u8> {
|
||||
use #scrate::codec::Encode;
|
||||
#cache_name.get_or_init(|| {
|
||||
@@ -816,7 +820,7 @@ fn store_functions_to_metadata (
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance, #instance> {
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte for #struct_name<#traitinstance, #instance> {
|
||||
fn default_byte(&self) -> #scrate::rstd::vec::Vec<u8> {
|
||||
use #scrate::codec::Encode;
|
||||
let def_val: #value_type = #default;
|
||||
@@ -848,10 +852,12 @@ pub(crate) struct DeclStorageTypeInfos<'a> {
|
||||
enum DeclStorageTypeInfosKind<'a> {
|
||||
Simple,
|
||||
Map {
|
||||
hasher: HasherKind,
|
||||
key_type: &'a syn::Type,
|
||||
is_linked: bool,
|
||||
},
|
||||
DoubleMap {
|
||||
hasher: HasherKind,
|
||||
key1_type: &'a syn::Type,
|
||||
key2_type: &'a syn::Type,
|
||||
key2_hasher: TokenStream2,
|
||||
@@ -871,14 +877,17 @@ fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos {
|
||||
let (value_type, kind) = match storage_type {
|
||||
DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple),
|
||||
DeclStorageType::Map(ref map) => (&map.value, DeclStorageTypeInfosKind::Map {
|
||||
hasher: map.hasher.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256),
|
||||
key_type: &map.key,
|
||||
is_linked: false,
|
||||
}),
|
||||
DeclStorageType::LinkedMap(ref map) => (&map.value, DeclStorageTypeInfosKind::Map {
|
||||
hasher: map.hasher.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256),
|
||||
key_type: &map.key,
|
||||
is_linked: true,
|
||||
}),
|
||||
DeclStorageType::DoubleMap(ref map) => (&map.value, DeclStorageTypeInfosKind::DoubleMap {
|
||||
hasher: map.hasher.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256),
|
||||
key1_type: &map.key1,
|
||||
key2_type: &map.key2.content,
|
||||
key2_hasher: { let h = &map.key2_hasher; quote! { #h } },
|
||||
|
||||
Reference in New Issue
Block a user