Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Next Next commit
Initial changes
  • Loading branch information
codekitz committed Apr 4, 2023
commit c7d0b9a471a96483c24cdf4afa92bd3c19eb25de
13 changes: 12 additions & 1 deletion frame/support/procedural/src/pallet/expand/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
},
};
use quote::ToTokens;
use std::{collections::HashMap, ops::IndexMut};
use std::{collections::HashMap, ops::{IndexMut, Index}};
use syn::spanned::Spanned;

/// Generate the prefix_ident related to the storage.
Expand Down Expand Up @@ -269,6 +269,17 @@ pub fn process_generics(def: &mut Def) -> syn::Result<Vec<ResultOnEmptyStructMet
Metadata::DoubleMap { .. } => (5, 6, 7),
};

if storage_def.use_default_hasher {
let hasher_indices: Vec<usize> = match storage_def.metadata {
Metadata::Map { .. } | Metadata::CountedMap { .. } => vec![1],
Metadata::DoubleMap { .. } => vec![1, 3],
_ => vec![]
};
for hasher_idx in hasher_indices {
args.args[hasher_idx] = syn::GenericArgument::Type(syn::parse_quote!(#frame_support::Blake2_128Concat));
}
}

if query_idx < args.args.len() {
if let syn::GenericArgument::Type(query_kind) = args.args.index_mut(query_idx) {
set_result_query_type_parameter(query_kind)?;
Expand Down
38 changes: 27 additions & 11 deletions frame/support/procedural/src/pallet/parse/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ pub struct StorageDef {
pub unbounded: bool,
/// Whether or not reads to this storage key will be ignored by benchmarking
pub whitelisted: bool,
/// Whether or not a default hasher is allowed to replace `_`
pub use_default_hasher: bool,
}

/// The parsed generic from the
Expand Down Expand Up @@ -325,12 +327,12 @@ fn check_generics(
}
}

/// Returns `(named generics, metadata, query kind)`
/// Returns `(named generics, metadata, query kind, use_default_hasher)`
fn process_named_generics(
storage: &StorageKind,
args_span: proc_macro2::Span,
args: &[syn::Binding],
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>)> {
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>, bool)> {
let mut parsed = HashMap::<String, syn::Binding>::new();

// Ensure no duplicate.
Expand Down Expand Up @@ -480,15 +482,16 @@ fn process_named_generics(
let metadata = generics.metadata()?;
let query_kind = generics.query_kind();

Ok((Some(generics), metadata, query_kind))
Ok((Some(generics), metadata, query_kind, false))
}

/// Returns `(named generics, metadata, query kind)`
/// Returns `(named generics, metadata, query kind, use_default_hasher)`
fn process_unnamed_generics(
storage: &StorageKind,
args_span: proc_macro2::Span,
args: &[syn::Type],
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>)> {
dev_mode: bool
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>, bool)> {
let retrieve_arg = |arg_pos| {
args.get(arg_pos).cloned().ok_or_else(|| {
let msg = format!(
Expand All @@ -510,18 +513,28 @@ fn process_unnamed_generics(
err
})?;

let use_default_hasher = |arg_pos| {
if let Some(arg) = retrieve_arg(arg_pos).ok() {
dev_mode && syn::parse2::<syn::Token![_]>(arg.to_token_stream()).is_ok()
} else {
false
}
};

let res = match storage {
StorageKind::Value =>
(None, Metadata::Value { value: retrieve_arg(1)? }, retrieve_arg(2).ok()),
(None, Metadata::Value { value: retrieve_arg(1)? }, retrieve_arg(2).ok(), false),
StorageKind::Map => (
None,
Metadata::Map { key: retrieve_arg(2)?, value: retrieve_arg(3)? },
retrieve_arg(4).ok(),
use_default_hasher(1),
),
StorageKind::CountedMap => (
None,
Metadata::CountedMap { key: retrieve_arg(2)?, value: retrieve_arg(3)? },
retrieve_arg(4).ok(),
use_default_hasher(1),
),
StorageKind::DoubleMap => (
None,
Expand All @@ -531,21 +544,23 @@ fn process_unnamed_generics(
value: retrieve_arg(5)?,
},
retrieve_arg(6).ok(),
use_default_hasher(1) && use_default_hasher(3),
),
StorageKind::NMap => {
let keygen = retrieve_arg(1)?;
let keys = collect_keys(&keygen)?;
(None, Metadata::NMap { keys, keygen, value: retrieve_arg(2)? }, retrieve_arg(3).ok())
(None, Metadata::NMap { keys, keygen, value: retrieve_arg(2)? }, retrieve_arg(3).ok(), false)
},
};

Ok(res)
}

/// Returns `(named generics, metadata, query kind)`
/// Returns `(named generics, metadata, query kind, use_default_hasher)`
fn process_generics(
segment: &syn::PathSegment,
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>)> {
dev_mode: bool
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>, bool)> {
let storage_kind = match &*segment.ident.to_string() {
"StorageValue" => StorageKind::Value,
"StorageMap" => StorageKind::Map,
Expand Down Expand Up @@ -583,7 +598,7 @@ fn process_generics(
_ => unreachable!("It is asserted above that all generics are types"),
})
.collect::<Vec<_>>();
process_unnamed_generics(&storage_kind, args_span, &args)
process_unnamed_generics(&storage_kind, args_span, &args, dev_mode)
} else if args.args.iter().all(|gen| matches!(gen, syn::GenericArgument::Binding(_))) {
let args = args
.args
Expand Down Expand Up @@ -711,7 +726,7 @@ impl StorageDef {
return Err(syn::Error::new(item.ty.span(), msg))
}

let (named_generics, metadata, query_kind) = process_generics(&typ.path.segments[0])?;
let (named_generics, metadata, query_kind, use_default_hasher) = process_generics(&typ.path.segments[0], dev_mode)?;

let query_kind = query_kind
.map(|query_kind| {
Expand Down Expand Up @@ -832,6 +847,7 @@ impl StorageDef {
named_generics,
unbounded,
whitelisted,
use_default_hasher
})
}
}
10 changes: 10 additions & 0 deletions frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ pub mod pallet {
#[pallet::storage]
type MyStorage<T: Config> = StorageValue<_, Vec<u8>>;

// The Hasher requirement skipped by `dev_mode`.
#[pallet::storage]
type MyStorageMap<T: Config> = StorageMap<_, _, u32, u64>;

#[pallet::storage]
type MyStorageDoubleMap<T: Config> = StorageDoubleMap<_, _, u32, _, u64>;

#[pallet::storage]
type MyCountedStorageMap<T: Config> = CountedStorageMap<_, _, u32, _, u64>;

// Your Pallet's callable functions.
#[pallet::call]
impl<T: Config> Pallet<T> {
Expand Down