mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 11:38:01 +00:00
Introduce storage attr macro #[disable_try_decode_storage] and set it on System::Events and ParachainSystem::HostConfiguration (#3454)
Closes https://github.com/paritytech/polkadot-sdk/issues/2560 Allows marking storage items with `#[disable_try_decode_storage]`, and uses it with `System::Events`. Question: what's the recommended way to write a test for this? I couldn't find a test for similar existing macro `#[whitelist_storage]`.
This commit is contained in:
@@ -1371,6 +1371,25 @@ pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream {
|
||||
pallet_macro_stub()
|
||||
}
|
||||
|
||||
/// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the
|
||||
/// storage as whitelisted from decoding during try-runtime checks. This should only be
|
||||
/// attached to transient storage which cannot be migrated during runtime upgrades.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// #[pallet::storage]
|
||||
/// #[pallet::disable_try_decode_storage]
|
||||
/// pub(super) type Events<T: Config> = StorageValue<_, Vec<Box<EventRecord<T::RuntimeEvent, T::Hash>>>, ValueQuery>;
|
||||
/// ```
|
||||
///
|
||||
/// NOTE: As with all `pallet::*` attributes, this one _must_ be written as
|
||||
/// `#[pallet::disable_try_decode_storage]` and can only be placed inside a `pallet` module in order
|
||||
/// for it to work properly.
|
||||
#[proc_macro_attribute]
|
||||
pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream {
|
||||
pallet_macro_stub()
|
||||
}
|
||||
|
||||
/// The `#[pallet::type_value]` attribute lets you define a struct implementing the `Get` trait
|
||||
/// to ease the use of storage types. This attribute is meant to be used alongside
|
||||
/// [`#[pallet::storage]`](`macro@storage`) to define a storage's default value. This attribute
|
||||
|
||||
@@ -834,7 +834,10 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
.storages
|
||||
.iter()
|
||||
.filter_map(|storage| {
|
||||
if storage.cfg_attrs.is_empty() {
|
||||
// A little hacky; don't generate for cfg gated storages to not get compile errors
|
||||
// when building "frame-feature-testing" gated storages in the "frame-support-test"
|
||||
// crate.
|
||||
if storage.try_decode && storage.cfg_attrs.is_empty() {
|
||||
let ident = &storage.ident;
|
||||
let gen = &def.type_use_generics(storage.attr_span);
|
||||
Some(quote::quote_spanned!(storage.attr_span => #ident<#gen> ))
|
||||
|
||||
@@ -29,6 +29,7 @@ mod keyword {
|
||||
syn::custom_keyword!(storage_prefix);
|
||||
syn::custom_keyword!(unbounded);
|
||||
syn::custom_keyword!(whitelist_storage);
|
||||
syn::custom_keyword!(disable_try_decode_storage);
|
||||
syn::custom_keyword!(OptionQuery);
|
||||
syn::custom_keyword!(ResultQuery);
|
||||
syn::custom_keyword!(ValueQuery);
|
||||
@@ -39,11 +40,13 @@ mod keyword {
|
||||
/// * `#[pallet::storage_prefix = "CustomName"]`
|
||||
/// * `#[pallet::unbounded]`
|
||||
/// * `#[pallet::whitelist_storage]
|
||||
/// * `#[pallet::disable_try_decode_storage]`
|
||||
pub enum PalletStorageAttr {
|
||||
Getter(syn::Ident, proc_macro2::Span),
|
||||
StorageName(syn::LitStr, proc_macro2::Span),
|
||||
Unbounded(proc_macro2::Span),
|
||||
WhitelistStorage(proc_macro2::Span),
|
||||
DisableTryDecodeStorage(proc_macro2::Span),
|
||||
}
|
||||
|
||||
impl PalletStorageAttr {
|
||||
@@ -53,6 +56,7 @@ impl PalletStorageAttr {
|
||||
Self::StorageName(_, span) |
|
||||
Self::Unbounded(span) |
|
||||
Self::WhitelistStorage(span) => *span,
|
||||
Self::DisableTryDecodeStorage(span) => *span,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,6 +97,9 @@ impl syn::parse::Parse for PalletStorageAttr {
|
||||
} else if lookahead.peek(keyword::whitelist_storage) {
|
||||
content.parse::<keyword::whitelist_storage>()?;
|
||||
Ok(Self::WhitelistStorage(attr_span))
|
||||
} else if lookahead.peek(keyword::disable_try_decode_storage) {
|
||||
content.parse::<keyword::disable_try_decode_storage>()?;
|
||||
Ok(Self::DisableTryDecodeStorage(attr_span))
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
@@ -104,6 +111,7 @@ struct PalletStorageAttrInfo {
|
||||
rename_as: Option<syn::LitStr>,
|
||||
unbounded: bool,
|
||||
whitelisted: bool,
|
||||
try_decode: bool,
|
||||
}
|
||||
|
||||
impl PalletStorageAttrInfo {
|
||||
@@ -112,6 +120,7 @@ impl PalletStorageAttrInfo {
|
||||
let mut rename_as = None;
|
||||
let mut unbounded = false;
|
||||
let mut whitelisted = false;
|
||||
let mut disable_try_decode_storage = false;
|
||||
for attr in attrs {
|
||||
match attr {
|
||||
PalletStorageAttr::Getter(ident, ..) if getter.is_none() => getter = Some(ident),
|
||||
@@ -119,6 +128,8 @@ impl PalletStorageAttrInfo {
|
||||
rename_as = Some(name),
|
||||
PalletStorageAttr::Unbounded(..) if !unbounded => unbounded = true,
|
||||
PalletStorageAttr::WhitelistStorage(..) if !whitelisted => whitelisted = true,
|
||||
PalletStorageAttr::DisableTryDecodeStorage(..) if !disable_try_decode_storage =>
|
||||
disable_try_decode_storage = true,
|
||||
attr =>
|
||||
return Err(syn::Error::new(
|
||||
attr.attr_span(),
|
||||
@@ -127,7 +138,13 @@ impl PalletStorageAttrInfo {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(PalletStorageAttrInfo { getter, rename_as, unbounded, whitelisted })
|
||||
Ok(PalletStorageAttrInfo {
|
||||
getter,
|
||||
rename_as,
|
||||
unbounded,
|
||||
whitelisted,
|
||||
try_decode: !disable_try_decode_storage,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +203,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 to try to decode the storage key when running try-runtime checks.
|
||||
pub try_decode: bool,
|
||||
/// Whether or not a default hasher is allowed to replace `_`
|
||||
pub use_default_hasher: bool,
|
||||
}
|
||||
@@ -775,7 +794,7 @@ impl StorageDef {
|
||||
};
|
||||
|
||||
let attrs: Vec<PalletStorageAttr> = helper::take_item_pallet_attrs(&mut item.attrs)?;
|
||||
let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted } =
|
||||
let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted, try_decode } =
|
||||
PalletStorageAttrInfo::from_attrs(attrs)?;
|
||||
|
||||
// set all storages to be unbounded if dev_mode is enabled
|
||||
@@ -921,6 +940,7 @@ impl StorageDef {
|
||||
named_generics,
|
||||
unbounded,
|
||||
whitelisted,
|
||||
try_decode,
|
||||
use_default_hasher,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user