From 8e171a115aa370c5f563114bcbfc36a9ba322df7 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Mon, 17 Oct 2022 04:38:14 +0000 Subject: [PATCH 01/33] stub for construct_dev_runtime! --- frame/support/procedural/src/construct_runtime/mod.rs | 2 +- frame/support/procedural/src/lib.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 73d0d54343eb9..2ecb1e5fbdd8a 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -164,7 +164,7 @@ const SYSTEM_PALLET_NAME: &str = "System"; /// Implementation of `construct_runtime` macro. Either expand to some code which will call /// `construct_runtime` again, or expand to the final runtime definition. -pub fn construct_runtime(input: TokenStream) -> TokenStream { +pub fn construct_runtime(input: TokenStream, _dev_mode: bool) -> TokenStream { let input_copy = input.clone(); let definition = syn::parse_macro_input!(input as RuntimeDeclaration); diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index ccff5488c93be..60b53adb56ef0 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -400,7 +400,15 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// frame_system::Pallet` #[proc_macro] pub fn construct_runtime(input: TokenStream) -> TokenStream { - construct_runtime::construct_runtime(input) + construct_runtime::construct_runtime(input, false) +} + +/// A develop-mode alternative to [`construct_runtime!`] with less stringent requirements +/// allowing for easier development-mode construction of a runtime. This **should not** be used +/// with a production runtime. +#[proc_macro] +pub fn construct_dev_runtime(input: TokenStream) -> TokenStream { + construct_runtime::construct_runtime(input, true) } /// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to specify From ba45d0b9640651cf8309c6629407ec65b8271364 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 18 Oct 2022 20:19:52 +0000 Subject: [PATCH 02/33] revert --- frame/support/procedural/src/construct_runtime/mod.rs | 2 +- frame/support/procedural/src/lib.rs | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 2ecb1e5fbdd8a..73d0d54343eb9 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -164,7 +164,7 @@ const SYSTEM_PALLET_NAME: &str = "System"; /// Implementation of `construct_runtime` macro. Either expand to some code which will call /// `construct_runtime` again, or expand to the final runtime definition. -pub fn construct_runtime(input: TokenStream, _dev_mode: bool) -> TokenStream { +pub fn construct_runtime(input: TokenStream) -> TokenStream { let input_copy = input.clone(); let definition = syn::parse_macro_input!(input as RuntimeDeclaration); diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 60b53adb56ef0..ccff5488c93be 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -400,15 +400,7 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// frame_system::Pallet` #[proc_macro] pub fn construct_runtime(input: TokenStream) -> TokenStream { - construct_runtime::construct_runtime(input, false) -} - -/// A develop-mode alternative to [`construct_runtime!`] with less stringent requirements -/// allowing for easier development-mode construction of a runtime. This **should not** be used -/// with a production runtime. -#[proc_macro] -pub fn construct_dev_runtime(input: TokenStream) -> TokenStream { - construct_runtime::construct_runtime(input, true) + construct_runtime::construct_runtime(input) } /// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to specify From e1883c9938fc07c331ee5a066ff4a74c366b5437 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 19 Oct 2022 05:55:48 +0000 Subject: [PATCH 03/33] stub for dev_mode proc macro --- frame/support/procedural/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index ccff5488c93be..e828081151f6f 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -1261,3 +1261,8 @@ pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } + +#[proc_macro_attribute] +pub fn dev_mode(_: TokenStream, _: TokenStream) -> TokenStream { + pallet_macro_stub() +} From 1f3eb5acc09677cc896a5f051d6c899431076b3a Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 19 Oct 2022 05:56:07 +0000 Subject: [PATCH 04/33] preliminary docs for pallet::dev_mode (attribute) proc macro --- frame/support/procedural/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index e828081151f6f..4a2f4f4ab7728 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -1262,6 +1262,13 @@ pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } +/// The `#[pallet::dev_mode]` attribute can be applied to a pallet to indicate that you are +/// tinkering with the pallet and don't intend to use it in its current form in production. +/// +/// Doing so has a few implications: +/// * The [`macro@weight`] for the pallet will be set to 0 +/// * `MaxEncodedLen` will be set automatically (expand on this) +/// * A number of dev-mode-only traits will be available for your pallet to use (expand on this) #[proc_macro_attribute] pub fn dev_mode(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() From ef886e28680f9c918909ebe3e45c170bf833938e Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 19 Oct 2022 05:58:37 +0000 Subject: [PATCH 05/33] add dev_mode to pallet_macros module --- frame/support/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 9b0ee84c34d8a..cd3e8efe27461 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -2699,9 +2699,9 @@ pub use frame_support_procedural::pallet; /// Contains macro stubs for all of the pallet:: macros pub mod pallet_macros { pub use frame_support_procedural::{ - call_index, compact, config, constant, disable_frame_system_supertrait_check, error, event, - extra_constants, generate_deposit, generate_storage_info, generate_store, genesis_build, - genesis_config, getter, hooks, inherent, origin, storage, storage_prefix, storage_version, - type_value, unbounded, validate_unsigned, weight, whitelist_storage, + call_index, compact, config, constant, dev_mode, disable_frame_system_supertrait_check, + error, event, extra_constants, generate_deposit, generate_storage_info, generate_store, + genesis_build, genesis_config, getter, hooks, inherent, origin, storage, storage_prefix, + storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, }; } From a62437a581ba30119f05f1cc36e41f66c1a76edf Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 19 Oct 2022 06:47:32 +0000 Subject: [PATCH 06/33] add docs item for dev_mode to frame_support --- frame/support/src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index cd3e8efe27461..135b448c61f69 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1473,6 +1473,7 @@ pub mod pallet_prelude { /// * [`pallet::inherent`](#inherent-palletinherent-optional) /// * [`pallet::validate_unsigned`](#validate-unsigned-palletvalidate_unsigned-optional) /// * [`pallet::origin`](#origin-palletorigin-optional) +/// * [`pallet::dev_mode`](#palletdev_mode-optional) /// /// Note that at compile-time, the `#[pallet]` macro will analyze and expand all of these /// attributes, ultimately removing their AST nodes before they can be parsed as real @@ -2168,6 +2169,19 @@ pub mod pallet_prelude { /// /// Also see [`pallet::origin`](`frame_support::pallet_macros::origin`) /// +/// # `#[pallet::dev_mode]` (optional) +/// +/// The `#[pallet::dev_mode]` attribute can be applied to a pallet to indicate that you are +/// tinkering with the pallet and don't intend to use it in its current form in production. +/// +/// Doing so has a few implications: +/// * The [`weight`](`frame_support::pallet_macros::weight`) for the pallet will be set to 0 +/// * `MaxEncodedLen` will be set automatically (expand on this) +/// * A number of dev-mode-only traits will be available for your pallet to use (expand on +/// this) +/// +/// Also see [`pallet::dev_mode`](`frame_support::pallet_macros::dev_mode`) +/// /// # General notes on instantiable pallets /// /// An instantiable pallet is one where Config is generic, i.e. `Config`. This allows From 89337a64e3142dcb3016793554fb514e51c19dca Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 20 Oct 2022 08:17:05 +0000 Subject: [PATCH 07/33] parsing of #[pallet(dev_mode)] --- frame/support/procedural/src/pallet/mod.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index ff9f122867746..cf3f0f94202ba 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -31,16 +31,25 @@ mod parse; pub use parse::Def; use syn::spanned::Spanned; +mod keyword { + syn::custom_keyword!(dev_mode); +} + pub fn pallet( attr: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { if !attr.is_empty() { - let msg = - "Invalid pallet macro call: expected no attributes, e.g. macro call must be just \ - `#[frame_support::pallet]` or `#[pallet]`"; - let span = proc_macro2::TokenStream::from(attr).span(); - return syn::Error::new(span, msg).to_compile_error().into() + if let Ok(_) = syn::parse::(attr.clone()) { + println!("dev mode detected!"); + } else { + let msg = "Invalid pallet macro call: unexpected attribute. Macro call must be \ + bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the \ + `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or \ + #[pallet(dev_mode)]. No other attributes are supported at this time."; + let span = proc_macro2::TokenStream::from(attr).span(); + return syn::Error::new(span, msg).to_compile_error().into() + } } let item = syn::parse_macro_input!(item as syn::ItemMod); From 4d4f23572ece56a8fa1359ee8b9b218f1cda0266 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 20 Oct 2022 08:24:32 +0000 Subject: [PATCH 08/33] strip out dev_mode stub since it will be an arg for pallet instead --- frame/support/procedural/src/lib.rs | 12 ------------ frame/support/src/lib.rs | 22 ++++------------------ 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 4a2f4f4ab7728..ccff5488c93be 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -1261,15 +1261,3 @@ pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } - -/// The `#[pallet::dev_mode]` attribute can be applied to a pallet to indicate that you are -/// tinkering with the pallet and don't intend to use it in its current form in production. -/// -/// Doing so has a few implications: -/// * The [`macro@weight`] for the pallet will be set to 0 -/// * `MaxEncodedLen` will be set automatically (expand on this) -/// * A number of dev-mode-only traits will be available for your pallet to use (expand on this) -#[proc_macro_attribute] -pub fn dev_mode(_: TokenStream, _: TokenStream) -> TokenStream { - pallet_macro_stub() -} diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 135b448c61f69..9b0ee84c34d8a 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1473,7 +1473,6 @@ pub mod pallet_prelude { /// * [`pallet::inherent`](#inherent-palletinherent-optional) /// * [`pallet::validate_unsigned`](#validate-unsigned-palletvalidate_unsigned-optional) /// * [`pallet::origin`](#origin-palletorigin-optional) -/// * [`pallet::dev_mode`](#palletdev_mode-optional) /// /// Note that at compile-time, the `#[pallet]` macro will analyze and expand all of these /// attributes, ultimately removing their AST nodes before they can be parsed as real @@ -2169,19 +2168,6 @@ pub mod pallet_prelude { /// /// Also see [`pallet::origin`](`frame_support::pallet_macros::origin`) /// -/// # `#[pallet::dev_mode]` (optional) -/// -/// The `#[pallet::dev_mode]` attribute can be applied to a pallet to indicate that you are -/// tinkering with the pallet and don't intend to use it in its current form in production. -/// -/// Doing so has a few implications: -/// * The [`weight`](`frame_support::pallet_macros::weight`) for the pallet will be set to 0 -/// * `MaxEncodedLen` will be set automatically (expand on this) -/// * A number of dev-mode-only traits will be available for your pallet to use (expand on -/// this) -/// -/// Also see [`pallet::dev_mode`](`frame_support::pallet_macros::dev_mode`) -/// /// # General notes on instantiable pallets /// /// An instantiable pallet is one where Config is generic, i.e. `Config`. This allows @@ -2713,9 +2699,9 @@ pub use frame_support_procedural::pallet; /// Contains macro stubs for all of the pallet:: macros pub mod pallet_macros { pub use frame_support_procedural::{ - call_index, compact, config, constant, dev_mode, disable_frame_system_supertrait_check, - error, event, extra_constants, generate_deposit, generate_storage_info, generate_store, - genesis_build, genesis_config, getter, hooks, inherent, origin, storage, storage_prefix, - storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, + call_index, compact, config, constant, disable_frame_system_supertrait_check, error, event, + extra_constants, generate_deposit, generate_storage_info, generate_store, genesis_build, + genesis_config, getter, hooks, inherent, origin, storage, storage_prefix, storage_version, + type_value, unbounded, validate_unsigned, weight, whitelist_storage, }; } From 76eb78bf7852bb63d5c24caaeb5261d75af96457 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 20 Oct 2022 08:49:28 +0000 Subject: [PATCH 09/33] make pallet Def struct aware of dev mode --- frame/support/procedural/src/pallet/mod.rs | 7 ++++++- frame/support/procedural/src/pallet/parse/mod.rs | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index cf3f0f94202ba..5911f704aa2ae 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -39,9 +39,11 @@ pub fn pallet( attr: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { + let mut dev_mode = false; if !attr.is_empty() { if let Ok(_) = syn::parse::(attr.clone()) { println!("dev mode detected!"); + dev_mode = true; } else { let msg = "Invalid pallet macro call: unexpected attribute. Macro call must be \ bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the \ @@ -54,7 +56,10 @@ pub fn pallet( let item = syn::parse_macro_input!(item as syn::ItemMod); match parse::Def::try_from(item) { - Ok(def) => expand::expand(def).into(), + Ok(mut def) => { + def.dev_mode = dev_mode; + expand::expand(def).into() + }, Err(e) => e.to_compile_error().into(), } } diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index 8b4ab154b306a..4fcc771bcafa9 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -59,6 +59,7 @@ pub struct Def { pub type_values: Vec, pub frame_system: syn::Ident, pub frame_support: syn::Ident, + pub dev_mode: bool, } impl Def { @@ -173,6 +174,7 @@ impl Def { type_values, frame_system, frame_support, + dev_mode: false, }; def.check_instance_usage()?; From 7ac54dec63c10310beef68035d09cd805935244e Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Sat, 22 Oct 2022 12:22:06 +0000 Subject: [PATCH 10/33] WIP --- .../procedural/src/pallet/expand/call.rs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/frame/support/procedural/src/pallet/expand/call.rs b/frame/support/procedural/src/pallet/expand/call.rs index 6b166e6726d38..85aeded9bfaa3 100644 --- a/frame/support/procedural/src/pallet/expand/call.rs +++ b/frame/support/procedural/src/pallet/expand/call.rs @@ -16,6 +16,7 @@ // limitations under the License. use crate::{pallet::Def, COUNTER}; +use proc_macro2::TokenStream; use quote::ToTokens; use syn::spanned::Spanned; @@ -23,7 +24,7 @@ use syn::spanned::Spanned; /// * Generate enum call and implement various trait on it. /// * Implement Callable and call_function on `Pallet` pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { - let (span, where_clause, methods, docs) = match def.call.as_ref() { + let (span, where_clause, mut methods, docs) = match def.call.as_ref() { Some(call) => { let span = call.attr_span; let where_clause = call.where_clause.clone(); @@ -42,6 +43,24 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { let call_ident = syn::Ident::new("Call", span); let pallet_ident = &def.pallet_struct.pallet; + if def.dev_mode || true { + let empty_weight: TokenStream = quote::quote!(#[pallet::weight(T::WeightInfo::create())]); + methods = methods.into_iter().map(|method| { + if method.attrs.iter().filter(|attr| { + println!("{}", attr.path.to_token_stream().to_string()); + if let Some(seg) = attr.path.segments.last() { + if seg.ident.to_string() != "doc" { + println!("|{}|", seg.ident.to_string()); + } + } + false + }).count() == 0 { + + } + method + }).collect(); + } + let fn_name = methods.iter().map(|method| &method.name).collect::>(); let call_index = methods.iter().map(|method| method.call_index).collect::>(); let new_call_variant_fn_name = fn_name From 2a5857e96d72d11b155374af5a97c17ce8701133 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 25 Oct 2022 00:40:32 +0000 Subject: [PATCH 11/33] revert changes to call.rs --- .../procedural/src/pallet/expand/call.rs | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/frame/support/procedural/src/pallet/expand/call.rs b/frame/support/procedural/src/pallet/expand/call.rs index 85aeded9bfaa3..6b166e6726d38 100644 --- a/frame/support/procedural/src/pallet/expand/call.rs +++ b/frame/support/procedural/src/pallet/expand/call.rs @@ -16,7 +16,6 @@ // limitations under the License. use crate::{pallet::Def, COUNTER}; -use proc_macro2::TokenStream; use quote::ToTokens; use syn::spanned::Spanned; @@ -24,7 +23,7 @@ use syn::spanned::Spanned; /// * Generate enum call and implement various trait on it. /// * Implement Callable and call_function on `Pallet` pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { - let (span, where_clause, mut methods, docs) = match def.call.as_ref() { + let (span, where_clause, methods, docs) = match def.call.as_ref() { Some(call) => { let span = call.attr_span; let where_clause = call.where_clause.clone(); @@ -43,24 +42,6 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { let call_ident = syn::Ident::new("Call", span); let pallet_ident = &def.pallet_struct.pallet; - if def.dev_mode || true { - let empty_weight: TokenStream = quote::quote!(#[pallet::weight(T::WeightInfo::create())]); - methods = methods.into_iter().map(|method| { - if method.attrs.iter().filter(|attr| { - println!("{}", attr.path.to_token_stream().to_string()); - if let Some(seg) = attr.path.segments.last() { - if seg.ident.to_string() != "doc" { - println!("|{}|", seg.ident.to_string()); - } - } - false - }).count() == 0 { - - } - method - }).collect(); - } - let fn_name = methods.iter().map(|method| &method.name).collect::>(); let call_index = methods.iter().map(|method| method.call_index).collect::>(); let new_call_variant_fn_name = fn_name From fce8e414334202b2e0e203038b16c2a0836e1586 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 25 Oct 2022 03:18:44 +0000 Subject: [PATCH 12/33] pass dev_mode to pallet parsing code --- frame/support/procedural/src/pallet/mod.rs | 2 +- frame/support/procedural/src/pallet/parse/mod.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index 5911f704aa2ae..efd50d3cf972e 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -55,7 +55,7 @@ pub fn pallet( } let item = syn::parse_macro_input!(item as syn::ItemMod); - match parse::Def::try_from(item) { + match parse::Def::try_from(item, dev_mode) { Ok(mut def) => { def.dev_mode = dev_mode; expand::expand(def).into() diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index 4fcc771bcafa9..6dd561859b062 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -63,7 +63,7 @@ pub struct Def { } impl Def { - pub fn try_from(mut item: syn::ItemMod) -> syn::Result { + pub fn try_from(mut item: syn::ItemMod, dev_mode: bool) -> syn::Result { let frame_system = generate_crate_access_2018("frame-system")?; let frame_support = generate_crate_access_2018("frame-support")?; @@ -107,7 +107,7 @@ impl Def { hooks = Some(m); }, Some(PalletAttr::RuntimeCall(span)) if call.is_none() => - call = Some(call::CallDef::try_from(span, index, item)?), + call = Some(call::CallDef::try_from(span, index, item, dev_mode)?), Some(PalletAttr::Error(span)) if error.is_none() => error = Some(error::ErrorDef::try_from(span, index, item)?), Some(PalletAttr::RuntimeEvent(span)) if event.is_none() => @@ -174,7 +174,7 @@ impl Def { type_values, frame_system, frame_support, - dev_mode: false, + dev_mode, }; def.check_instance_usage()?; From 011f1e07cf75945a5efeb6d314b762972e1cca03 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 25 Oct 2022 03:29:10 +0000 Subject: [PATCH 13/33] auto-specify default weights when in dev mode if not specified --- frame/support/procedural/src/pallet/parse/call.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index f7b2c9544d831..a6c118d0fb29f 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -144,6 +144,7 @@ impl CallDef { attr_span: proc_macro2::Span, index: usize, item: &mut syn::Item, + dev_mode: bool, ) -> syn::Result { let item_impl = if let syn::Item::Impl(item) = item { item @@ -213,6 +214,14 @@ impl CallDef { }, ); + if weight_attrs.is_empty() && dev_mode { + // inject a default O(1) weight when dev mode is enabled and no weight has + // been specified on the call + let empty_weight: syn::Expr = + syn::parse(quote::quote!(T::WeightInfo::create()).into()).unwrap(); + weight_attrs.push(FunctionAttr::Weight(empty_weight)); + } + if weight_attrs.len() != 1 { let msg = if weight_attrs.is_empty() { "Invalid pallet::call, requires weight attribute i.e. `#[pallet::weight($expr)]`" From 41f159c997f610f044e4bb484b24faae03482f9b Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 25 Oct 2022 05:18:45 +0000 Subject: [PATCH 14/33] add proof / expect for syn::parse in dev mode weight processing --- frame/support/procedural/src/pallet/parse/call.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index a6c118d0fb29f..dc7cdbd387411 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -218,7 +218,8 @@ impl CallDef { // inject a default O(1) weight when dev mode is enabled and no weight has // been specified on the call let empty_weight: syn::Expr = - syn::parse(quote::quote!(T::WeightInfo::create()).into()).unwrap(); + syn::parse(quote::quote!(T::WeightInfo::create()).into()) + .expect("we are parsing a quoted string; qed"); weight_attrs.push(FunctionAttr::Weight(empty_weight)); } From a7c85b3227d43e608512eaf7d4fd49a171a1f314 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 25 Oct 2022 15:26:39 +0000 Subject: [PATCH 15/33] set all storages to unbounded when in dev mode --- frame/support/procedural/src/pallet/parse/mod.rs | 2 +- frame/support/procedural/src/pallet/parse/storage.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index 6dd561859b062..f91159248281c 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -125,7 +125,7 @@ impl Def { Some(PalletAttr::Inherent(_)) if inherent.is_none() => inherent = Some(inherent::InherentDef::try_from(index, item)?), Some(PalletAttr::Storage(span)) => - storages.push(storage::StorageDef::try_from(span, index, item)?), + storages.push(storage::StorageDef::try_from(span, index, item, dev_mode)?), Some(PalletAttr::ValidateUnsigned(_)) if validate_unsigned.is_none() => { let v = validate_unsigned::ValidateUnsignedDef::try_from(index, item)?; validate_unsigned = Some(v); diff --git a/frame/support/procedural/src/pallet/parse/storage.rs b/frame/support/procedural/src/pallet/parse/storage.rs index b16ff05803d98..15741f758ef41 100644 --- a/frame/support/procedural/src/pallet/parse/storage.rs +++ b/frame/support/procedural/src/pallet/parse/storage.rs @@ -678,6 +678,7 @@ impl StorageDef { attr_span: proc_macro2::Span, index: usize, item: &mut syn::Item, + dev_mode: bool, ) -> syn::Result { let item = if let syn::Item::Type(item) = item { item @@ -686,9 +687,14 @@ impl StorageDef { }; let attrs: Vec = helper::take_item_pallet_attrs(&mut item.attrs)?; - let PalletStorageAttrInfo { getter, rename_as, unbounded, whitelisted } = + let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted } = PalletStorageAttrInfo::from_attrs(attrs)?; + if dev_mode { + // set all storages to be unbounded if dev_mode is enabled + unbounded = true; + } + let cfg_attrs = helper::get_item_cfg_attrs(&item.attrs); let instances = vec![helper::check_type_def_gen(&item.generics, item.ident.span())?]; From bb71c7fbd8b16555557bd850169a7dd00dea610d Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 25 Oct 2022 13:31:40 -0400 Subject: [PATCH 16/33] just use 0 Co-authored-by: Shawn Tabrizi --- frame/support/procedural/src/pallet/parse/call.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index dc7cdbd387411..d0ca3fd45666b 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -218,7 +218,7 @@ impl CallDef { // inject a default O(1) weight when dev mode is enabled and no weight has // been specified on the call let empty_weight: syn::Expr = - syn::parse(quote::quote!(T::WeightInfo::create()).into()) + syn::parse(quote::quote!(0).into()) .expect("we are parsing a quoted string; qed"); weight_attrs.push(FunctionAttr::Weight(empty_weight)); } From 45f993251989afc6066f2ecdaf96a3bf5a729c0a Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 27 Oct 2022 04:30:56 +0000 Subject: [PATCH 17/33] add invalid pallet arg test --- frame/support/test/tests/pallet_ui/pallet_invalid_arg.rs | 4 ++++ frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr | 5 +++++ 2 files changed, 9 insertions(+) create mode 100644 frame/support/test/tests/pallet_ui/pallet_invalid_arg.rs create mode 100644 frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr diff --git a/frame/support/test/tests/pallet_ui/pallet_invalid_arg.rs b/frame/support/test/tests/pallet_ui/pallet_invalid_arg.rs new file mode 100644 index 0000000000000..1fc42f6511cfa --- /dev/null +++ b/frame/support/test/tests/pallet_ui/pallet_invalid_arg.rs @@ -0,0 +1,4 @@ +#[frame_support::pallet(foo)] +pub mod pallet {} + +fn main() {} diff --git a/frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr b/frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr new file mode 100644 index 0000000000000..bb184d0ddec4b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet macro call: unexpected attribute. Macro call must be bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or #[pallet(dev_mode)]. No other attributes are supported at this time. + --> tests/pallet_ui/pallet_invalid_arg.rs:1:25 + | +1 | #[frame_support::pallet(foo)] + | ^^^ From 04708085a9b77108e23de8cf52d4438b2be312ce Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 27 Oct 2022 04:59:58 +0000 Subject: [PATCH 18/33] add passing dev mode pallet test --- .../tests/pallet_ui/pass/dev_mode_valid.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs diff --git a/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs new file mode 100644 index 0000000000000..8d6dad32657e8 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs @@ -0,0 +1,33 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[frame_support::pallet(dev_mode)] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + // The struct on which we build all of our Pallet logic. + #[pallet::pallet] + pub struct Pallet(_); + + // Your Pallet's configuration trait, representing custom external types and interfaces. + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::storage] + type MyStorage = StorageValue<_, Vec>; + + // Your Pallet's callable functions. + #[pallet::call] + impl Pallet { + pub fn my_call(_origin: OriginFor) -> DispatchResult { + Ok(()) + } + } + + // Your Pallet's internal functions. + impl Pallet {} +} + +fn main() {} From b0cfc6aa22b22960d5fa98cd7ba0357f03bf06ca Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 27 Oct 2022 14:44:37 +0000 Subject: [PATCH 19/33] add test confirming that dev mode features only work in dev mode --- .../tests/pallet_ui/dev_mode_without_arg.rs | 33 ++++++++++++++++++ .../pallet_ui/dev_mode_without_arg.stderr | 11 ++++++ .../dev_mode_without_arg_max_encoded_len.rs | 34 +++++++++++++++++++ ...ev_mode_without_arg_max_encoded_len.stderr | 17 ++++++++++ 4 files changed, 95 insertions(+) create mode 100644 frame/support/test/tests/pallet_ui/dev_mode_without_arg.rs create mode 100644 frame/support/test/tests/pallet_ui/dev_mode_without_arg.stderr create mode 100644 frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.rs create mode 100644 frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.stderr diff --git a/frame/support/test/tests/pallet_ui/dev_mode_without_arg.rs b/frame/support/test/tests/pallet_ui/dev_mode_without_arg.rs new file mode 100644 index 0000000000000..f044ae6d7878f --- /dev/null +++ b/frame/support/test/tests/pallet_ui/dev_mode_without_arg.rs @@ -0,0 +1,33 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + // The struct on which we build all of our Pallet logic. + #[pallet::pallet] + pub struct Pallet(_); + + // Your Pallet's configuration trait, representing custom external types and interfaces. + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::storage] + type MyStorage = StorageValue<_, Vec>; + + // Your Pallet's callable functions. + #[pallet::call] + impl Pallet { + pub fn my_call(_origin: OriginFor) -> DispatchResult { + Ok(()) + } + } + + // Your Pallet's internal functions. + impl Pallet {} +} + +fn main() {} diff --git a/frame/support/test/tests/pallet_ui/dev_mode_without_arg.stderr b/frame/support/test/tests/pallet_ui/dev_mode_without_arg.stderr new file mode 100644 index 0000000000000..fac7fd77df9ae --- /dev/null +++ b/frame/support/test/tests/pallet_ui/dev_mode_without_arg.stderr @@ -0,0 +1,11 @@ +error: Invalid pallet::call, requires weight attribute i.e. `#[pallet::weight($expr)]` + --> tests/pallet_ui/dev_mode_without_arg.rs:24:7 + | +24 | pub fn my_call(_origin: OriginFor) -> DispatchResult { + | ^^ + +error[E0432]: unresolved import `pallet` + --> tests/pallet_ui/dev_mode_without_arg.rs:3:9 + | +3 | pub use pallet::*; + | ^^^^^^ help: a similar path exists: `test_pallet::pallet` diff --git a/frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.rs b/frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.rs new file mode 100644 index 0000000000000..f6efcc3fc3d72 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.rs @@ -0,0 +1,34 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + // The struct on which we build all of our Pallet logic. + #[pallet::pallet] + pub struct Pallet(_); + + // Your Pallet's configuration trait, representing custom external types and interfaces. + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::storage] + type MyStorage = StorageValue<_, Vec>; + + // Your Pallet's callable functions. + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + pub fn my_call(_origin: OriginFor) -> DispatchResult { + Ok(()) + } + } + + // Your Pallet's internal functions. + impl Pallet {} +} + +fn main() {} diff --git a/frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.stderr b/frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.stderr new file mode 100644 index 0000000000000..2f8d0cc761ab2 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/dev_mode_without_arg_max_encoded_len.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `Vec: MaxEncodedLen` is not satisfied + --> tests/pallet_ui/dev_mode_without_arg_max_encoded_len.rs:11:12 + | +11 | #[pallet::pallet] + | ^^^^^^ the trait `MaxEncodedLen` is not implemented for `Vec` + | + = help: the following other types implement trait `MaxEncodedLen`: + () + (TupleElement0, TupleElement1) + (TupleElement0, TupleElement1, TupleElement2) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) + and 78 others + = note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageMyStorage, Vec>` From b5a82cb9d6b57f9a18ebb1b5eab6a7199f9236ef Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 27 Oct 2022 15:18:13 +0000 Subject: [PATCH 20/33] cargo fmt + clean up --- frame/support/procedural/src/pallet/mod.rs | 1 - frame/support/procedural/src/pallet/parse/call.rs | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index efd50d3cf972e..707a9b7c9280b 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -42,7 +42,6 @@ pub fn pallet( let mut dev_mode = false; if !attr.is_empty() { if let Ok(_) = syn::parse::(attr.clone()) { - println!("dev mode detected!"); dev_mode = true; } else { let msg = "Invalid pallet macro call: unexpected attribute. Macro call must be \ diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index d0ca3fd45666b..fbca9a52c767c 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -217,9 +217,8 @@ impl CallDef { if weight_attrs.is_empty() && dev_mode { // inject a default O(1) weight when dev mode is enabled and no weight has // been specified on the call - let empty_weight: syn::Expr = - syn::parse(quote::quote!(0).into()) - .expect("we are parsing a quoted string; qed"); + let empty_weight: syn::Expr = syn::parse(quote::quote!(0).into()) + .expect("we are parsing a quoted string; qed"); weight_attrs.push(FunctionAttr::Weight(empty_weight)); } From 450f09dc09d864fec1931aeeaa56ec381518d713 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 27 Oct 2022 16:18:56 +0000 Subject: [PATCH 21/33] bump CI From e765c4267b5af931e71fb213b4abaf1a8635aec7 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 28 Oct 2022 03:52:48 -0400 Subject: [PATCH 22/33] fix pallet ui test --- frame/support/test/tests/pallet_ui/attr_non_empty.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/support/test/tests/pallet_ui/attr_non_empty.stderr b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr index 144af5a17ea5c..9a2242b52c194 100644 --- a/frame/support/test/tests/pallet_ui/attr_non_empty.stderr +++ b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr @@ -1,5 +1,5 @@ -error: Invalid pallet macro call: expected no attributes, e.g. macro call must be just `#[frame_support::pallet]` or `#[pallet]` - --> $DIR/attr_non_empty.rs:1:26 +error: Invalid pallet macro call: unexpected attribute. Macro call must be bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or #[pallet(dev_mode)]. No other attributes are supported at this time. + --> tests/pallet_ui/attr_non_empty.rs:1:26 | 1 | #[frame_support::pallet [foo]] | ^^^ From 755a62c299c39c9710fb90b9671c556758a1744b Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 28 Oct 2022 08:56:05 +0000 Subject: [PATCH 23/33] add docs for dev mode --- frame/support/procedural/src/lib.rs | 14 ++++++++++++++ frame/support/src/lib.rs | 15 +++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index ccff5488c93be..67d0103a6a8d4 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -445,6 +445,20 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// pallet. Otherwise it implements `StorageInfoTrait` for the pallet using the /// `PartialStorageInfoTrait` implementation of storages. /// +/// ## Dev Mode (`#[pallet::pallet(dev_mode)]`) +/// +/// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The aim +/// of dev mode is to loosen some of the restrictions and requirements placed on production +/// pallets for easy tinkering and development. Dev mode pallets should not be used in +/// production. Enabling dev mode has the following effects: +/// +/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By default, dev +/// mode pallets will assume a weight of zero (`0`) if a weight is not specified. This is +/// equivalent to specifying `#[weight(0)]` on all calls that do not specify a weight. +/// * All storages are marked as unbounded, meaning you do not need to implement `MaxEncodedLen` on +/// storage types. This is equivalent to specifying `#[pallet::unbounded]` on all storage type +/// definitions. +/// /// See `frame_support::pallet` docs for more info. #[proc_macro_attribute] pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream { diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 9b0ee84c34d8a..1e1a41710d01a 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1487,6 +1487,21 @@ pub mod pallet_prelude { /// non-instantiable pallets. For an example of an instantiable pallet, see [this /// example](#example-of-an-instantiable-pallet). /// +/// # Dev Mode (`#[pallet::pallet(dev_mode)]`) +/// +/// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The aim +/// of dev mode is to loosen some of the restrictions and requirements placed on production +/// pallets for easy tinkering and development. Dev mode pallets should not be used in +/// production. Enabling dev mode has the following effects: +/// +/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By +/// default, dev mode pallets will assume a weight of zero (`0`) if a weight is not +/// specified. This is equivalent to specifying `#[weight(0)]` on all calls that do not +/// specify a weight. +/// * All storages are marked as unbounded, meaning you do not need to implement +/// `MaxEncodedLen` on storage types. This is equivalent to specifying `#[pallet::unbounded]` +/// on all storage type definitions. +/// /// # Pallet struct placeholder: `#[pallet::pallet]` (mandatory) /// /// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to specify From 69411ab3962b6e91a0f3c237a3e456ae1b3fc8a8 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 1 Nov 2022 15:33:52 +0000 Subject: [PATCH 24/33] add warning about using dev mode in production circumstances --- frame/support/procedural/src/lib.rs | 10 +++++++++- frame/support/src/lib.rs | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 67d0103a6a8d4..d400ae9be0f3c 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -445,7 +445,7 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// pallet. Otherwise it implements `StorageInfoTrait` for the pallet using the /// `PartialStorageInfoTrait` implementation of storages. /// -/// ## Dev Mode (`#[pallet::pallet(dev_mode)]`) +/// ## Dev Mode (`#[pallet(dev_mode)]`) /// /// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The aim /// of dev mode is to loosen some of the restrictions and requirements placed on production @@ -459,6 +459,14 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// storage types. This is equivalent to specifying `#[pallet::unbounded]` on all storage type /// definitions. /// +///
+/// WARNING:
+/// You should not deploy or use dev mode pallets in production. Once you are done
+/// tinkering, you should remove the 'dev_mode' argument from your #[pallet] declaration and
+/// fix any compile errors before attempting to use your pallet in a production scenario.
+/// 
+/// /// See `frame_support::pallet` docs for more info. #[proc_macro_attribute] pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream { diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 1e1a41710d01a..cc24bf068bbd0 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1487,7 +1487,7 @@ pub mod pallet_prelude { /// non-instantiable pallets. For an example of an instantiable pallet, see [this /// example](#example-of-an-instantiable-pallet). /// -/// # Dev Mode (`#[pallet::pallet(dev_mode)]`) +/// # Dev Mode (`#[pallet(dev_mode)]`) /// /// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The aim /// of dev mode is to loosen some of the restrictions and requirements placed on production @@ -1502,6 +1502,14 @@ pub mod pallet_prelude { /// `MaxEncodedLen` on storage types. This is equivalent to specifying `#[pallet::unbounded]` /// on all storage type definitions. /// +///
+/// WARNING:
+/// You should not deploy or use dev mode pallets in production. Once you are done
+/// tinkering, you should remove the 'dev_mode' argument from your #[pallet] declaration and
+/// fix any compile errors before attempting to use your pallet in a production scenario.
+/// 
+/// /// # Pallet struct placeholder: `#[pallet::pallet]` (mandatory) /// /// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to specify From 4f8b58fa09d3b6cb76023fdca9da2168373ca5d4 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 1 Nov 2022 15:42:49 +0000 Subject: [PATCH 25/33] remove comment about no other attributes being supported --- frame/support/procedural/src/pallet/mod.rs | 2 +- frame/support/test/tests/pallet_ui/attr_non_empty.stderr | 2 +- frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index 707a9b7c9280b..8578ff5b08943 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -47,7 +47,7 @@ pub fn pallet( let msg = "Invalid pallet macro call: unexpected attribute. Macro call must be \ bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the \ `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or \ - #[pallet(dev_mode)]. No other attributes are supported at this time."; + #[pallet(dev_mode)]."; let span = proc_macro2::TokenStream::from(attr).span(); return syn::Error::new(span, msg).to_compile_error().into() } diff --git a/frame/support/test/tests/pallet_ui/attr_non_empty.stderr b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr index 9a2242b52c194..9eac5de35db80 100644 --- a/frame/support/test/tests/pallet_ui/attr_non_empty.stderr +++ b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet macro call: unexpected attribute. Macro call must be bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or #[pallet(dev_mode)]. No other attributes are supported at this time. +error: Invalid pallet macro call: unexpected attribute. Macro call must be bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or #[pallet(dev_mode)]. --> tests/pallet_ui/attr_non_empty.rs:1:26 | 1 | #[frame_support::pallet [foo]] diff --git a/frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr b/frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr index bb184d0ddec4b..234dc07f2ece3 100644 --- a/frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr +++ b/frame/support/test/tests/pallet_ui/pallet_invalid_arg.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet macro call: unexpected attribute. Macro call must be bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or #[pallet(dev_mode)]. No other attributes are supported at this time. +error: Invalid pallet macro call: unexpected attribute. Macro call must be bare, such as `#[frame_support::pallet]` or `#[pallet]`, or must specify the `dev_mode` attribute, such as `#[frame_support::pallet(dev_mode)]` or #[pallet(dev_mode)]. --> tests/pallet_ui/pallet_invalid_arg.rs:1:25 | 1 | #[frame_support::pallet(foo)] From da619d7205275606897928aa84ef4849d8692fba Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 1 Nov 2022 15:44:46 +0000 Subject: [PATCH 26/33] fix unneeded assignment --- frame/support/procedural/src/pallet/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index 8578ff5b08943..3f85be81c1f7d 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -55,10 +55,7 @@ pub fn pallet( let item = syn::parse_macro_input!(item as syn::ItemMod); match parse::Def::try_from(item, dev_mode) { - Ok(mut def) => { - def.dev_mode = dev_mode; - expand::expand(def).into() - }, + Ok(def) => expand::expand(def).into(), Err(e) => e.to_compile_error().into(), } } From d350781f67dbd4c3b5b8948ee10a4c075608a5b0 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Mon, 7 Nov 2022 07:18:05 +0000 Subject: [PATCH 27/33] make warning more explicit --- frame/support/procedural/src/lib.rs | 7 ++++--- frame/support/src/lib.rs | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index d400ae9be0f3c..9b244ed417356 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -462,9 +462,10 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { ///
 /// WARNING:
-/// You should not deploy or use dev mode pallets in production. Once you are done
-/// tinkering, you should remove the 'dev_mode' argument from your #[pallet] declaration and
-/// fix any compile errors before attempting to use your pallet in a production scenario.
+/// You should not deploy or use dev mode pallets in production. Doing so can break your chain
+/// and therefore should never be done. Once you are done tinkering, you should remove the
+/// 'dev_mode' argument from your #[pallet] declaration and fix any compile errors before
+/// attempting to use your pallet in a production scenario.
 /// 
/// /// See `frame_support::pallet` docs for more info. diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index cc24bf068bbd0..358937851fc7d 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1505,9 +1505,10 @@ pub mod pallet_prelude { ///
 /// WARNING:
-/// You should not deploy or use dev mode pallets in production. Once you are done
-/// tinkering, you should remove the 'dev_mode' argument from your #[pallet] declaration and
-/// fix any compile errors before attempting to use your pallet in a production scenario.
+/// You should not deploy or use dev mode pallets in production. Doing so can break your chain
+/// and therefore should never be done. Once you are done tinkering, you should remove the
+/// 'dev_mode' argument from your #[pallet] declaration and fix any compile errors before
+/// attempting to use your pallet in a production scenario.
 /// 
/// /// # Pallet struct placeholder: `#[pallet::pallet]` (mandatory) From 6ac7643482e3eb8670306de8b369b4ddfd3651a1 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Mon, 7 Nov 2022 07:37:50 +0000 Subject: [PATCH 28/33] more explicit warning about using dev mode in production --- frame/support/procedural/src/lib.rs | 5 +++++ frame/support/src/lib.rs | 14 ++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 9b244ed417356..cd30946ae7855 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -459,6 +459,11 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// storage types. This is equivalent to specifying `#[pallet::unbounded]` on all storage type /// definitions. /// +/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or +/// `#[frame_support::pallet]` attribute macro that encloses your pallet module. This argument +/// cannot be specified anywhere else, including but not limited to the `#[pallet::pallet]` +/// attribute macro. +/// ///
 /// WARNING:
diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs
index 358937851fc7d..84e416e50544d 100644
--- a/frame/support/src/lib.rs
+++ b/frame/support/src/lib.rs
@@ -1489,10 +1489,11 @@ pub mod pallet_prelude {
 ///
 /// # Dev Mode (`#[pallet(dev_mode)]`)
 ///
-/// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The aim
-/// of dev mode is to loosen some of the restrictions and requirements placed on production
-/// pallets for easy tinkering and development. Dev mode pallets should not be used in
-/// production. Enabling dev mode has the following effects:
+/// Specifying the argument `dev_mode` on the `#[pallet]` or `#[frame_support::pallet]`
+/// attribute attached to your pallet module will allow you to enable dev mode for a pallet.
+/// The aim of dev mode is to loosen some of the restrictions and requirements placed on
+/// production pallets for easy tinkering and development. Dev mode pallets should not be used
+/// in production. Enabling dev mode has the following effects:
 ///
 /// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By
 ///   default, dev mode pallets will assume a weight of zero (`0`) if a weight is not
@@ -1502,6 +1503,11 @@ pub mod pallet_prelude {
 ///   `MaxEncodedLen` on storage types. This is equivalent to specifying `#[pallet::unbounded]`
 ///   on all storage type definitions.
 ///
+/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or
+/// `#[frame_support::pallet]` attribute macro that encloses your pallet module. This argument
+/// cannot be specified anywhere else, including but not limited to the `#[pallet::pallet]`
+/// attribute macro.
+///
 /// 
 /// WARNING:

From dc038d42b81e37356ef24eecd4862cd5c65a22f7 Mon Sep 17 00:00:00 2001
From: Sam Johnson 
Date: Mon, 7 Nov 2022 02:39:30 -0500
Subject: [PATCH 29/33] simpler assignment for dev_mode boolean

Co-authored-by: Oliver Tale-Yazdi 
---
 frame/support/procedural/src/pallet/parse/storage.rs | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/frame/support/procedural/src/pallet/parse/storage.rs b/frame/support/procedural/src/pallet/parse/storage.rs
index 15741f758ef41..8b551ab31d6c3 100644
--- a/frame/support/procedural/src/pallet/parse/storage.rs
+++ b/frame/support/procedural/src/pallet/parse/storage.rs
@@ -690,11 +690,8 @@ impl StorageDef {
 		let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted } =
 			PalletStorageAttrInfo::from_attrs(attrs)?;
 
-		if dev_mode {
-			// set all storages to be unbounded if dev_mode is enabled
-			unbounded = true;
-		}
-
+		// set all storages to be unbounded if dev_mode is enabled
+		unbounded |= dev_mode;
 		let cfg_attrs = helper::get_item_cfg_attrs(&item.attrs);
 
 		let instances = vec![helper::check_type_def_gen(&item.generics, item.ident.span())?];

From 555516d28d9623d1f42a5e7d1db4297ec5465074 Mon Sep 17 00:00:00 2001
From: Sam Johnson 
Date: Mon, 7 Nov 2022 02:40:47 -0500
Subject: [PATCH 30/33] add note about MEL requirement

Co-authored-by: Oliver Tale-Yazdi 
---
 frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
index 8d6dad32657e8..1456fad041ff9 100644
--- a/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
+++ b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
@@ -15,6 +15,7 @@ pub mod pallet {
 	#[pallet::config]
 	pub trait Config: frame_system::Config {}
 
+	// The MEL requirement for bounded pallets is skipped by the `dev_mode`.
 	#[pallet::storage]
 	type MyStorage = StorageValue<_, Vec>;
 

From 386a8c11a77e29e444984bbda2e4158a8d6b785c Mon Sep 17 00:00:00 2001
From: Sam Johnson 
Date: Mon, 7 Nov 2022 02:41:24 -0500
Subject: [PATCH 31/33] add comment specifying why weights can be omitted in
 example

Co-authored-by: Oliver Tale-Yazdi 
---
 frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
index 1456fad041ff9..4e0c0a8f615e0 100644
--- a/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
+++ b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
@@ -22,6 +22,7 @@ pub mod pallet {
 	// Your Pallet's callable functions.
 	#[pallet::call]
 	impl Pallet {
+		// No need to define a `weight` attribute here because of the `dev_mode`.
 		pub fn my_call(_origin: OriginFor) -> DispatchResult {
 			Ok(())
 		}

From b2d988a678d38474ca9985fbb38158b5ac69ce1b Mon Sep 17 00:00:00 2001
From: Sam Johnson 
Date: Mon, 7 Nov 2022 07:42:45 +0000
Subject: [PATCH 32/33] tweak wording of comments

---
 frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
index 4e0c0a8f615e0..97e0d585d0ce9 100644
--- a/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
+++ b/frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
@@ -15,14 +15,14 @@ pub mod pallet {
 	#[pallet::config]
 	pub trait Config: frame_system::Config {}
 
-	// The MEL requirement for bounded pallets is skipped by the `dev_mode`.
+	// The MEL requirement for bounded pallets is skipped by `dev_mode`.
 	#[pallet::storage]
 	type MyStorage = StorageValue<_, Vec>;
 
 	// Your Pallet's callable functions.
 	#[pallet::call]
 	impl Pallet {
-		// No need to define a `weight` attribute here because of the `dev_mode`.
+		// No need to define a `weight` attribute here because of `dev_mode`.
 		pub fn my_call(_origin: OriginFor) -> DispatchResult {
 			Ok(())
 		}

From 0aea2c8e9fd260c99667ac2b3471f17deb473892 Mon Sep 17 00:00:00 2001
From: Sam Johnson 
Date: Mon, 7 Nov 2022 20:54:10 +0000
Subject: [PATCH 33/33] bump ci