From 84c4e25489feaf653412e1692ac98ce473de78b9 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Mon, 31 Jul 2023 15:48:54 +0530 Subject: [PATCH 01/11] Abstracts away the executive --- bin/node-template/runtime/src/lib.rs | 24 ++--- .../src/construct_runtime/expand/executive.rs | 90 +++++++++++++++++++ .../src/construct_runtime/expand/mod.rs | 2 + .../procedural/src/construct_runtime/mod.rs | 3 + 4 files changed, 103 insertions(+), 16 deletions(-) create mode 100644 frame/support/procedural/src/construct_runtime/expand/executive.rs diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 8fae73ef08571..cd3e2dde83413 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -313,14 +313,6 @@ pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, ->; #[cfg(feature = "runtime-benchmarks")] #[macro_use] @@ -345,11 +337,11 @@ impl_runtime_apis! { } fn execute_block(block: Block) { - Executive::execute_block(block); + Runtime::api_impl_core_execute_block(block); } fn initialize_block(header: &::Header) { - Executive::initialize_block(header) + Runtime::api_impl_core_initialize_block(header) } } @@ -369,11 +361,11 @@ impl_runtime_apis! { impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) + Runtime::api_impl_builder_apply_extrinsic(extrinsic) } fn finalize_block() -> ::Header { - Executive::finalize_block() + Runtime::api_impl_builder_finalize_block() } fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { @@ -394,13 +386,13 @@ impl_runtime_apis! { tx: ::Extrinsic, block_hash: ::Hash, ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) + Runtime::api_impl_validate_transaction(source, tx, block_hash) } } impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) + Runtime::api_impl_offchain_worker(header) } } @@ -553,7 +545,7 @@ impl_runtime_apis! { // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to // have a backtrace here. If any of the pre/post migration checks fail, we shall stop // right here and right now. - let weight = Executive::try_runtime_upgrade(checks).unwrap(); + let weight = Runtime::api_impl_try_runtime_upgrade(checks).unwrap(); (weight, BlockWeights::get().max_block) } @@ -565,7 +557,7 @@ impl_runtime_apis! { ) -> Weight { // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to // have a backtrace here. - Executive::try_execute_block(block, state_root_check, signature_check, select).expect("execute-block failed") + Runtime::api_impl_try_execute_block(block, state_root_check, signature_check, select).expect("execute-block failed") } } } diff --git a/frame/support/procedural/src/construct_runtime/expand/executive.rs b/frame/support/procedural/src/construct_runtime/expand/executive.rs new file mode 100644 index 0000000000000..1d739d2f2138d --- /dev/null +++ b/frame/support/procedural/src/construct_runtime/expand/executive.rs @@ -0,0 +1,90 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License + +use frame_support_procedural_tools::generate_crate_access_2018; +use proc_macro2::{Ident, TokenStream}; +use quote::quote; +use syn::Result; + +pub fn expand_executive( + runtime: &Ident, + system: &Ident, + scrate: &TokenStream, + block: &TokenStream, +) -> Result { + let executive = generate_crate_access_2018("frame-executive")?; + let try_runtime = generate_crate_access_2018("frame-try-runtime")?; + + let res = quote! { + /// Executive: handles dispatch to the various modules. + pub type Executive = #executive::Executive< + #runtime, + #block, + #system::ChainContext<#runtime>, + #runtime, + AllPalletsWithSystem, + >; + + impl #runtime { + pub fn api_impl_core_execute_block(block: #block) { + Executive::execute_block(block); + } + + pub fn api_impl_core_initialize_block(header: &<#block as #scrate::sp_runtime::traits::Block>::Header) { + Executive::initialize_block(header); + } + + pub fn api_impl_builder_apply_extrinsic(extrinsic: <#block as #scrate::sp_runtime::traits::Block>::Extrinsic) -> #scrate::sp_runtime::ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + pub fn api_impl_builder_finalize_block() -> <#block as #scrate::sp_runtime::traits::Block>::Header { + Executive::finalize_block() + } + + pub fn api_impl_validate_transaction( + source: #scrate::sp_runtime::transaction_validity::TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> #scrate::sp_runtime::transaction_validity::TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + + pub fn api_impl_offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + #[cfg(feature = "try-runtime")] + impl #runtime { + fn api_impl_try_runtime_upgrade(checks: #try_runtime::UpgradeCheckSelect) -> Result { + Executive::try_runtime_upgrade(checks) + } + + fn api_impl_try_execute_block( + block: #block, + state_root_check: bool, + signature_check: bool, + select: #try_runtime::TryStateSelect + ) -> Result { + Executive::try_execute_block(block, state_root_check, signature_check, select) + } + } + }; + + Ok(res) +} diff --git a/frame/support/procedural/src/construct_runtime/expand/mod.rs b/frame/support/procedural/src/construct_runtime/expand/mod.rs index 830338f9265ff..d284aca6ab2d7 100644 --- a/frame/support/procedural/src/construct_runtime/expand/mod.rs +++ b/frame/support/procedural/src/construct_runtime/expand/mod.rs @@ -17,6 +17,7 @@ mod call; mod config; +mod executive; mod freeze_reason; mod hold_reason; mod inherent; @@ -29,6 +30,7 @@ mod unsigned; pub use call::expand_outer_dispatch; pub use config::expand_outer_config; +pub use executive::expand_executive; pub use freeze_reason::expand_outer_freeze_reason; pub use hold_reason::expand_outer_hold_reason; pub use inherent::expand_outer_inherent; diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index efc2244154479..e4421fd607cdb 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -402,6 +402,7 @@ fn construct_runtime_final_expansion( let slash_reason = expand::expand_outer_slash_reason(&pallets, &scrate); let integrity_test = decl_integrity_test(&scrate); let static_assertions = decl_static_assertions(&name, &pallets, &scrate); + let executive = expand::expand_executive(&name, &frame_system, &scrate, &block)?; let warning = where_section.map_or(None, |where_section| { @@ -491,6 +492,8 @@ fn construct_runtime_final_expansion( #integrity_test #static_assertions + + #executive ); Ok(res) From b1e5d3e9b0d54af06f7fe2beed405c7e828f82da Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 09:52:37 +0530 Subject: [PATCH 02/11] Abstracts away the executive in node and test-utils --- bin/node/runtime/src/lib.rs | 25 ++++++++----------------- test-utils/runtime/src/lib.rs | 18 +++++------------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 29aaaf5fdad5a..2ff86bbae2f30 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1982,15 +1982,6 @@ pub type UncheckedExtrinsic = pub type SignedPayload = generic::SignedPayload; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, - Migrations, ->; // All migrations executed on runtime upgrade as a nested tuple of types implementing // `OnRuntimeUpgrade`. @@ -2085,11 +2076,11 @@ impl_runtime_apis! { } fn execute_block(block: Block) { - Executive::execute_block(block); + Runtime::api_impl_core_execute_block(block); } fn initialize_block(header: &::Header) { - Executive::initialize_block(header) + Runtime::api_impl_core_initialize_block(header) } } @@ -2109,11 +2100,11 @@ impl_runtime_apis! { impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) + Runtime::api_impl_builder_apply_extrinsic(extrinsic) } fn finalize_block() -> ::Header { - Executive::finalize_block() + Runtime::api_impl_builder_finalize_block() } fn inherent_extrinsics(data: InherentData) -> Vec<::Extrinsic> { @@ -2131,7 +2122,7 @@ impl_runtime_apis! { tx: ::Extrinsic, block_hash: ::Hash, ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) + Runtime::api_impl_validate_transaction(source, tx, block_hash) } } @@ -2146,7 +2137,7 @@ impl_runtime_apis! { impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) + Runtime::api_impl_offchain_worker(header) } } @@ -2520,7 +2511,7 @@ impl_runtime_apis! { // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to // have a backtrace here. If any of the pre/post migration checks fail, we shall stop // right here and right now. - let weight = Executive::try_runtime_upgrade(checks).unwrap(); + let weight = Runtime::api_impl_try_runtime_upgrade(checks).unwrap(); (weight, RuntimeBlockWeights::get().max_block) } @@ -2532,7 +2523,7 @@ impl_runtime_apis! { ) -> Weight { // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to // have a backtrace here. - Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + Runtime::api_impl_try_execute_block(block, state_root_check, signature_check, select).unwrap() } } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 0cc32e50956c8..525bf76e989a2 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -226,14 +226,6 @@ decl_runtime_apis! { } } -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, ->; - #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct CheckSubstrateCall; @@ -478,12 +470,12 @@ impl_runtime_apis! { fn execute_block(block: Block) { log::trace!(target: LOG_TARGET, "execute_block: {block:#?}"); - Executive::execute_block(block); + Runtime::api_impl_core_execute_block(block); } fn initialize_block(header: &::Header) { log::trace!(target: LOG_TARGET, "initialize_block: {header:#?}"); - Executive::initialize_block(header); + Runtime::api_impl_core_initialize_block(header) } } @@ -506,7 +498,7 @@ impl_runtime_apis! { utx: ::Extrinsic, block_hash: ::Hash, ) -> TransactionValidity { - let validity = Executive::validate_transaction(source, utx.clone(), block_hash); + let validity = Runtime::api_impl_validate_transaction(source, utx.clone(), block_hash); log::trace!(target: LOG_TARGET, "validate_transaction {:?} {:?}", utx, validity); validity } @@ -514,12 +506,12 @@ impl_runtime_apis! { impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) + Runtime::api_impl_builder_apply_extrinsic(extrinsic) } fn finalize_block() -> ::Header { log::trace!(target: LOG_TARGET, "finalize_block"); - Executive::finalize_block() + Runtime::api_impl_builder_finalize_block() } fn inherent_extrinsics(_data: InherentData) -> Vec<::Extrinsic> { From 74ea0d8a3a6668d8c9d59f862c58225f20ba4557 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 10:11:59 +0530 Subject: [PATCH 03/11] Fixes tests --- frame/support/procedural/src/construct_runtime/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index e4421fd607cdb..f2d97b9c631b7 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -402,7 +402,8 @@ fn construct_runtime_final_expansion( let slash_reason = expand::expand_outer_slash_reason(&pallets, &scrate); let integrity_test = decl_integrity_test(&scrate); let static_assertions = decl_static_assertions(&name, &pallets, &scrate); - let executive = expand::expand_executive(&name, &frame_system, &scrate, &block)?; + let executive = + expand::expand_executive(&name, &frame_system, &scrate, &block).unwrap_or(quote!()); let warning = where_section.map_or(None, |where_section| { From 6c76f2c0df46bcba77cbfc744198f653ada863d7 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:51:00 +0530 Subject: [PATCH 04/11] Handles custom runtime upgrade --- bin/node-template/runtime/src/lib.rs | 2 +- bin/node/runtime/src/lib.rs | 2 +- .../src/construct_runtime/expand/executive.rs | 7 +++++ .../procedural/src/construct_runtime/mod.rs | 15 ++++++++-- .../procedural/src/construct_runtime/parse.rs | 28 +++++++++++++++++++ test-utils/runtime/src/lib.rs | 2 +- 6 files changed, 50 insertions(+), 6 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 6ba4cf5a52b4d..8c39c88852b6d 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -280,7 +280,7 @@ impl pallet_template::Config for Runtime { // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub struct Runtime { + pub struct Runtime<_> { System: frame_system, Timestamp: pallet_timestamp, Aura: pallet_aura, diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2ff86bbae2f30..bdd3fd3e909dc 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1874,7 +1874,7 @@ impl pallet_statement::Config for Runtime { } construct_runtime!( - pub struct Runtime + pub struct Runtime<_> { System: frame_system, Utility: pallet_utility, diff --git a/frame/support/procedural/src/construct_runtime/expand/executive.rs b/frame/support/procedural/src/construct_runtime/expand/executive.rs index 1d739d2f2138d..6a49179a75023 100644 --- a/frame/support/procedural/src/construct_runtime/expand/executive.rs +++ b/frame/support/procedural/src/construct_runtime/expand/executive.rs @@ -15,6 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License +use crate::construct_runtime::parse::ExecutiveSection; use frame_support_procedural_tools::generate_crate_access_2018; use proc_macro2::{Ident, TokenStream}; use quote::quote; @@ -25,9 +26,14 @@ pub fn expand_executive( system: &Ident, scrate: &TokenStream, block: &TokenStream, + executive_section: ExecutiveSection, ) -> Result { let executive = generate_crate_access_2018("frame-executive")?; let try_runtime = generate_crate_access_2018("frame-try-runtime")?; + let on_runtime_upgrade = match executive_section.custom_on_runtime_upgrade { + Some(custom) => quote!(Some(#custom)), + None => quote!(()), + }; let res = quote! { /// Executive: handles dispatch to the various modules. @@ -37,6 +43,7 @@ pub fn expand_executive( #system::ChainContext<#runtime>, #runtime, AllPalletsWithSystem, + #on_runtime_upgrade >; impl #runtime { diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index f2d97b9c631b7..0fc016ff30b8b 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -334,7 +334,13 @@ fn construct_runtime_explicit_to_explicit_expanded( fn construct_runtime_final_expansion( definition: ExplicitRuntimeDeclaration, ) -> Result { - let ExplicitRuntimeDeclaration { name, pallets, pallets_token, where_section } = definition; + let ExplicitRuntimeDeclaration { + name, + pallets, + pallets_token, + where_section, + executive_section, + } = definition; let system_pallet = pallets.iter().find(|decl| decl.name == SYSTEM_PALLET_NAME).ok_or_else(|| { @@ -402,8 +408,11 @@ fn construct_runtime_final_expansion( let slash_reason = expand::expand_outer_slash_reason(&pallets, &scrate); let integrity_test = decl_integrity_test(&scrate); let static_assertions = decl_static_assertions(&name, &pallets, &scrate); - let executive = - expand::expand_executive(&name, &frame_system, &scrate, &block).unwrap_or(quote!()); + let executive = if let Some(executive_section) = executive_section { + expand::expand_executive(&name, &frame_system, &scrate, &block, executive_section)? + } else { + quote!() + }; let warning = where_section.map_or(None, |where_section| { diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index 9b08e16469754..1252adfe0d2a5 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -67,6 +67,7 @@ pub struct ImplicitRuntimeDeclaration { pub name: Ident, pub where_section: Option, pub pallets: Vec, + pub executive_section: Option, } /// Declaration of a runtime with all pallet having explicit declaration of parts. @@ -76,6 +77,7 @@ pub struct ExplicitRuntimeDeclaration { pub where_section: Option, pub pallets: Vec, pub pallets_token: token::Brace, + pub executive_section: Option, } impl Parse for RuntimeDeclaration { @@ -90,6 +92,9 @@ impl Parse for RuntimeDeclaration { } let name = input.parse::()?; + + let executive_section = if input.peek(Token![<]) { Some(input.parse()?) } else { None }; + let where_section = if input.peek(token::Where) { Some(input.parse()?) } else { None }; let pallets = input.parse::>>()?; @@ -101,6 +106,7 @@ impl Parse for RuntimeDeclaration { name, where_section, pallets, + executive_section, })), PalletsConversion::Explicit(pallets) => Ok(RuntimeDeclaration::Explicit(ExplicitRuntimeDeclaration { @@ -108,6 +114,7 @@ impl Parse for RuntimeDeclaration { where_section, pallets, pallets_token, + executive_section, })), PalletsConversion::ExplicitExpanded(pallets) => Ok(RuntimeDeclaration::ExplicitExpanded(ExplicitRuntimeDeclaration { @@ -115,11 +122,32 @@ impl Parse for RuntimeDeclaration { where_section, pallets, pallets_token, + executive_section, })), } } } +#[derive(Debug)] +pub struct ExecutiveSection { + pub span: Span, + pub custom_on_runtime_upgrade: Option, +} + +impl Parse for ExecutiveSection { + fn parse(input: ParseStream) -> Result { + let _ = input.parse::()?; + let custom_on_runtime_upgrade = if input.peek(Token![_]) { + let _ = input.parse::()?; + None + } else { + Some(input.parse::()?) + }; + let _ = input.parse::]>()?; + Ok(Self { span: input.span(), custom_on_runtime_upgrade }) + } +} + #[derive(Debug)] pub struct WhereSection { pub span: Span, diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 525bf76e989a2..535dd38ac2899 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -289,7 +289,7 @@ impl sp_runtime::traits::SignedExtension for CheckSubstrateCall { } construct_runtime!( - pub enum Runtime + pub enum Runtime<_> { System: frame_system, Babe: pallet_babe, From 10eac867d221ca9ab4ae2156a86ac0b7b469065f Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:09:41 +0530 Subject: [PATCH 05/11] Fixes try-runtime section --- .../src/construct_runtime/expand/executive.rs | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/expand/executive.rs b/frame/support/procedural/src/construct_runtime/expand/executive.rs index 6a49179a75023..13817f4c9a8a3 100644 --- a/frame/support/procedural/src/construct_runtime/expand/executive.rs +++ b/frame/support/procedural/src/construct_runtime/expand/executive.rs @@ -29,12 +29,36 @@ pub fn expand_executive( executive_section: ExecutiveSection, ) -> Result { let executive = generate_crate_access_2018("frame-executive")?; - let try_runtime = generate_crate_access_2018("frame-try-runtime")?; + let on_runtime_upgrade = match executive_section.custom_on_runtime_upgrade { Some(custom) => quote!(Some(#custom)), None => quote!(()), }; + let try_runtime_section = if let Ok(try_runtime) = + generate_crate_access_2018("frame-try-runtime") + { + quote! { + #[cfg(feature = "try-runtime")] + impl #runtime { + fn api_impl_try_runtime_upgrade(checks: #try_runtime::UpgradeCheckSelect) -> Result { + Executive::try_runtime_upgrade(checks) + } + + fn api_impl_try_execute_block( + block: #block, + state_root_check: bool, + signature_check: bool, + select: #try_runtime::TryStateSelect + ) -> Result { + Executive::try_execute_block(block, state_root_check, signature_check, select) + } + } + } + } else { + quote!() + }; + let res = quote! { /// Executive: handles dispatch to the various modules. pub type Executive = #executive::Executive< @@ -74,22 +98,8 @@ pub fn expand_executive( pub fn api_impl_offchain_worker(header: &::Header) { Executive::offchain_worker(header) } - } - #[cfg(feature = "try-runtime")] - impl #runtime { - fn api_impl_try_runtime_upgrade(checks: #try_runtime::UpgradeCheckSelect) -> Result { - Executive::try_runtime_upgrade(checks) - } - - fn api_impl_try_execute_block( - block: #block, - state_root_check: bool, - signature_check: bool, - select: #try_runtime::TryStateSelect - ) -> Result { - Executive::try_execute_block(block, state_root_check, signature_check, select) - } + #try_runtime_section } }; From 22755555e5d80013e782d7a0f79daf3412d85bcb Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:20:07 +0530 Subject: [PATCH 06/11] Minor fix --- .../procedural/src/construct_runtime/expand/executive.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/expand/executive.rs b/frame/support/procedural/src/construct_runtime/expand/executive.rs index 13817f4c9a8a3..c6d1a95d81df3 100644 --- a/frame/support/procedural/src/construct_runtime/expand/executive.rs +++ b/frame/support/procedural/src/construct_runtime/expand/executive.rs @@ -98,9 +98,9 @@ pub fn expand_executive( pub fn api_impl_offchain_worker(header: &::Header) { Executive::offchain_worker(header) } - - #try_runtime_section } + + #try_runtime_section }; Ok(res) From d80224031c6bd78288285959de804d1fb9065616 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:29:23 +0530 Subject: [PATCH 07/11] Minor fix --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index bdd3fd3e909dc..475d3e9e245f7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1874,7 +1874,7 @@ impl pallet_statement::Config for Runtime { } construct_runtime!( - pub struct Runtime<_> + pub struct Runtime { System: frame_system, Utility: pallet_utility, From 99adead3e5fc2641d3644815a6d262523b2e1edf Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:08:10 +0530 Subject: [PATCH 08/11] Minor fix --- .../procedural/src/construct_runtime/expand/executive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/procedural/src/construct_runtime/expand/executive.rs b/frame/support/procedural/src/construct_runtime/expand/executive.rs index c6d1a95d81df3..1b866c6e468e0 100644 --- a/frame/support/procedural/src/construct_runtime/expand/executive.rs +++ b/frame/support/procedural/src/construct_runtime/expand/executive.rs @@ -31,7 +31,7 @@ pub fn expand_executive( let executive = generate_crate_access_2018("frame-executive")?; let on_runtime_upgrade = match executive_section.custom_on_runtime_upgrade { - Some(custom) => quote!(Some(#custom)), + Some(custom) => quote!(#custom), None => quote!(()), }; From b3b0afedf32a9aad18ba9aaf8313aaf76ea75f59 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 10 Aug 2023 20:26:14 +0530 Subject: [PATCH 09/11] Adds a UI Test --- .../invalid_migration_param.rs | 26 +++ .../invalid_migration_param.stderr | 197 ++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs create mode 100644 frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs new file mode 100644 index 0000000000000..aa199999cfcd5 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs @@ -0,0 +1,26 @@ +use frame_support::{construct_runtime, derive_impl, traits::ConstU64}; + +type Block = frame_system::mocking::MockBlock; + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type Block = Block; + type BlockHashCount = ConstU64<10>; + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type PalletInfo = PalletInfo; + type OnSetCode = (); +} + +struct Dummy; + +construct_runtime! { + pub struct Runtime + { + System: frame_system + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr new file mode 100644 index 0000000000000..ebf06eac7b166 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr @@ -0,0 +1,197 @@ +error[E0599]: the function or associated item `execute_block` exists for struct `Executive, ...>, ..., ..., ..., ...>`, but its trait bounds were not satisfied + --> tests/construct_runtime_ui/invalid_migration_param.rs:19:1 + | +17 | struct Dummy; + | ------------ doesn't satisfy `Dummy: OnRuntimeUpgrade` +18 | +19 | construct_runtime! { + | __^ + | | _| + | || +20 | || pub struct Runtime +21 | || { +22 | || System: frame_system +23 | || } +24 | || } + | ||_- in this macro invocation +... | + | + ::: $WORKSPACE/primitives/runtime/src/generic/unchecked_extrinsic.rs + | + | pub struct UncheckedExtrinsic + | -------------------------------------------------------------- doesn't satisfy `_: Checkable>` + | + = note: the following trait bounds were not satisfied: + `Dummy: OnRuntimeUpgrade` + `UncheckedExtrinsic: Checkable>` +note: the trait `OnRuntimeUpgrade` must be implemented + --> $WORKSPACE/frame/support/src/traits/hooks.rs + | + | pub trait OnRuntimeUpgrade { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0599]: the function or associated item `initialize_block` exists for struct `Executive, ...>, ..., ..., ..., ...>`, but its trait bounds were not satisfied + --> tests/construct_runtime_ui/invalid_migration_param.rs:19:1 + | +17 | struct Dummy; + | ------------ doesn't satisfy `Dummy: OnRuntimeUpgrade` +18 | +19 | construct_runtime! { + | __^ + | | _| + | || +20 | || pub struct Runtime +21 | || { +22 | || System: frame_system +23 | || } +24 | || } + | ||_- in this macro invocation +... | + | + ::: $WORKSPACE/primitives/runtime/src/generic/unchecked_extrinsic.rs + | + | pub struct UncheckedExtrinsic + | -------------------------------------------------------------- doesn't satisfy `_: Checkable>` + | + = note: the following trait bounds were not satisfied: + `Dummy: OnRuntimeUpgrade` + `UncheckedExtrinsic: Checkable>` +note: the trait `OnRuntimeUpgrade` must be implemented + --> $WORKSPACE/frame/support/src/traits/hooks.rs + | + | pub trait OnRuntimeUpgrade { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0599]: the function or associated item `apply_extrinsic` exists for struct `Executive, ...>, ..., ..., ..., ...>`, but its trait bounds were not satisfied + --> tests/construct_runtime_ui/invalid_migration_param.rs:19:1 + | +17 | struct Dummy; + | ------------ doesn't satisfy `Dummy: OnRuntimeUpgrade` +18 | +19 | construct_runtime! { + | __^ + | | _| + | || +20 | || pub struct Runtime +21 | || { +22 | || System: frame_system +23 | || } +24 | || } + | ||_- in this macro invocation +... | + | + ::: $WORKSPACE/primitives/runtime/src/generic/unchecked_extrinsic.rs + | + | pub struct UncheckedExtrinsic + | -------------------------------------------------------------- doesn't satisfy `_: Checkable>` + | + = note: the following trait bounds were not satisfied: + `Dummy: OnRuntimeUpgrade` + `UncheckedExtrinsic: Checkable>` +note: the trait `OnRuntimeUpgrade` must be implemented + --> $WORKSPACE/frame/support/src/traits/hooks.rs + | + | pub trait OnRuntimeUpgrade { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0599]: the function or associated item `finalize_block` exists for struct `Executive, ...>, ..., ..., ..., ...>`, but its trait bounds were not satisfied + --> tests/construct_runtime_ui/invalid_migration_param.rs:19:1 + | +17 | struct Dummy; + | ------------ doesn't satisfy `Dummy: OnRuntimeUpgrade` +18 | +19 | construct_runtime! { + | __^ + | | _| + | || +20 | || pub struct Runtime +21 | || { +22 | || System: frame_system +23 | || } +24 | || } + | ||_- in this macro invocation +... | + | + ::: $WORKSPACE/primitives/runtime/src/generic/unchecked_extrinsic.rs + | + | pub struct UncheckedExtrinsic + | -------------------------------------------------------------- doesn't satisfy `_: Checkable>` + | + = note: the following trait bounds were not satisfied: + `Dummy: OnRuntimeUpgrade` + `UncheckedExtrinsic: Checkable>` +note: the trait `OnRuntimeUpgrade` must be implemented + --> $WORKSPACE/frame/support/src/traits/hooks.rs + | + | pub trait OnRuntimeUpgrade { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0599]: the function or associated item `validate_transaction` exists for struct `Executive, ...>, ..., ..., ..., ...>`, but its trait bounds were not satisfied + --> tests/construct_runtime_ui/invalid_migration_param.rs:19:1 + | +17 | struct Dummy; + | ------------ doesn't satisfy `Dummy: OnRuntimeUpgrade` +18 | +19 | construct_runtime! { + | __^ + | | _| + | || +20 | || pub struct Runtime +21 | || { +22 | || System: frame_system +23 | || } +24 | || } + | ||_- in this macro invocation +... | + | + ::: $WORKSPACE/primitives/runtime/src/generic/unchecked_extrinsic.rs + | + | pub struct UncheckedExtrinsic + | -------------------------------------------------------------- doesn't satisfy `_: Checkable>` + | + = note: the following trait bounds were not satisfied: + `Dummy: OnRuntimeUpgrade` + `UncheckedExtrinsic: Checkable>` +note: the trait `OnRuntimeUpgrade` must be implemented + --> $WORKSPACE/frame/support/src/traits/hooks.rs + | + | pub trait OnRuntimeUpgrade { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0599]: the function or associated item `offchain_worker` exists for struct `Executive, ...>, ..., ..., ..., ...>`, but its trait bounds were not satisfied + --> tests/construct_runtime_ui/invalid_migration_param.rs:19:1 + | +17 | struct Dummy; + | ------------ doesn't satisfy `Dummy: OnRuntimeUpgrade` +18 | +19 | construct_runtime! { + | __^ + | | _| + | || +20 | || pub struct Runtime +21 | || { +22 | || System: frame_system +23 | || } +24 | || } + | ||_- in this macro invocation +... | + | + ::: $WORKSPACE/primitives/runtime/src/generic/unchecked_extrinsic.rs + | + | pub struct UncheckedExtrinsic + | -------------------------------------------------------------- doesn't satisfy `_: Checkable>` + | + = note: the following trait bounds were not satisfied: + `Dummy: OnRuntimeUpgrade` + `UncheckedExtrinsic: Checkable>` +note: the trait `OnRuntimeUpgrade` must be implemented + --> $WORKSPACE/frame/support/src/traits/hooks.rs + | + | pub trait OnRuntimeUpgrade { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) From 2fbed4725442ca90cc6154be2b500d33e4a81efd Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:21:07 +0530 Subject: [PATCH 10/11] Updates syntax --- bin/node-template/runtime/src/lib.rs | 3 +- bin/node/runtime/src/lib.rs | 17 +++-- .../src/construct_runtime/expand/executive.rs | 6 +- .../procedural/src/construct_runtime/parse.rs | 67 ++++++++++++++++--- .../invalid_migration_param.rs | 3 +- .../invalid_migration_param.stderr | 66 +++++++++--------- 6 files changed, 107 insertions(+), 55 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 8c39c88852b6d..6a3328d8864af 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -280,7 +280,8 @@ impl pallet_template::Config for Runtime { // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub struct Runtime<_> { + type Migrations = (); + pub struct Runtime { System: frame_system, Timestamp: pallet_timestamp, Aura: pallet_aura, diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 475d3e9e245f7..2b7425d7dac90 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1874,7 +1874,14 @@ impl pallet_statement::Config for Runtime { } construct_runtime!( - pub struct Runtime + // All migrations executed on runtime upgrade as a nested tuple of types implementing + // `OnRuntimeUpgrade`. + type Migrations = ( + pallet_nomination_pools::migration::v2::MigrateToV2, + pallet_alliance::migration::Migration, + pallet_contracts::Migration, + ); + pub struct Runtime { System: frame_system, Utility: pallet_utility, @@ -1983,14 +1990,6 @@ pub type SignedPayload = generic::SignedPayload; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; -// All migrations executed on runtime upgrade as a nested tuple of types implementing -// `OnRuntimeUpgrade`. -type Migrations = ( - pallet_nomination_pools::migration::v2::MigrateToV2, - pallet_alliance::migration::Migration, - pallet_contracts::Migration, -); - type EventRecord = frame_system::EventRecord< ::RuntimeEvent, ::Hash, diff --git a/frame/support/procedural/src/construct_runtime/expand/executive.rs b/frame/support/procedural/src/construct_runtime/expand/executive.rs index 1b866c6e468e0..29e22ba7b74d2 100644 --- a/frame/support/procedural/src/construct_runtime/expand/executive.rs +++ b/frame/support/procedural/src/construct_runtime/expand/executive.rs @@ -30,8 +30,8 @@ pub fn expand_executive( ) -> Result { let executive = generate_crate_access_2018("frame-executive")?; - let on_runtime_upgrade = match executive_section.custom_on_runtime_upgrade { - Some(custom) => quote!(#custom), + let migrations = match executive_section.migration_section { + Some(migrations) => quote!(#migrations), None => quote!(()), }; @@ -67,7 +67,7 @@ pub fn expand_executive( #system::ChainContext<#runtime>, #runtime, AllPalletsWithSystem, - #on_runtime_upgrade + (#migrations) >; impl #runtime { diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index 1252adfe0d2a5..21a27e8b225ae 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -24,7 +24,7 @@ use syn::{ parse::{Parse, ParseStream}, punctuated::Punctuated, spanned::Spanned, - token, Attribute, Error, Ident, Path, Result, Token, + token, Attribute, Error, Ident, Path, Result, Token, Type, }; mod keyword { @@ -82,6 +82,8 @@ pub struct ExplicitRuntimeDeclaration { impl Parse for RuntimeDeclaration { fn parse(input: ParseStream) -> Result { + let executive_section = if input.peek(Token![type]) { Some(input.parse()?) } else { None }; + input.parse::()?; // Support either `enum` or `struct`. @@ -93,8 +95,6 @@ impl Parse for RuntimeDeclaration { let name = input.parse::()?; - let executive_section = if input.peek(Token![<]) { Some(input.parse()?) } else { None }; - let where_section = if input.peek(token::Where) { Some(input.parse()?) } else { None }; let pallets = input.parse::>>()?; @@ -131,20 +131,65 @@ impl Parse for RuntimeDeclaration { #[derive(Debug)] pub struct ExecutiveSection { pub span: Span, - pub custom_on_runtime_upgrade: Option, + pub migration_section: Option, } impl Parse for ExecutiveSection { fn parse(input: ParseStream) -> Result { - let _ = input.parse::()?; - let custom_on_runtime_upgrade = if input.peek(Token![_]) { - let _ = input.parse::()?; - None + let _ = input.parse::()?; + let name = input.parse::()?; + + let migration_section = if name.to_string() == "Migrations" { + Some(input.parse::()?) } else { - Some(input.parse::()?) + None }; - let _ = input.parse::]>()?; - Ok(Self { span: input.span(), custom_on_runtime_upgrade }) + + Ok(Self { span: input.span(), migration_section }) + } +} + +#[derive(Debug)] +pub struct Migrations { + pub span: Span, + pub migrations: Punctuated, +} + +impl Parse for Migrations { + fn parse(input: ParseStream) -> Result { + let _ = input.parse::()?; + + let content; + syn::parenthesized!(content in input); + + let migrations = content.parse_terminated(Migration::parse, Token![,])?; + let _ = input.parse::()?; + Ok(Self { span: input.span(), migrations }) + } +} + +impl ToTokens for Migrations { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.migrations.to_tokens(tokens); + } +} + +#[derive(Debug)] +pub struct Migration { + pub span: Span, + pub ident: Type, +} + +impl Parse for Migration { + fn parse(input: ParseStream) -> Result { + let name = input.parse::()?; + Ok(Self { span: input.span(), ident: name }) + } +} + +impl ToTokens for Migration { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.ident.to_tokens(tokens); } } diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs index aa199999cfcd5..499735b275ca9 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs +++ b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.rs @@ -17,7 +17,8 @@ impl frame_system::Config for Runtime { struct Dummy; construct_runtime! { - pub struct Runtime + type Migrations = (Dummy); + pub struct Runtime { System: frame_system } diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr index ebf06eac7b166..744c22eccef1d 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr +++ b/frame/support/test/tests/construct_runtime_ui/invalid_migration_param.stderr @@ -8,11 +8,12 @@ error[E0599]: the function or associated item `execute_block` exists for struct | __^ | | _| | || -20 | || pub struct Runtime -21 | || { -22 | || System: frame_system -23 | || } -24 | || } +20 | || type Migrations = (Dummy); +21 | || pub struct Runtime +22 | || { +23 | || System: frame_system +24 | || } +25 | || } | ||_- in this macro invocation ... | | @@ -41,11 +42,12 @@ error[E0599]: the function or associated item `initialize_block` exists for stru | __^ | | _| | || -20 | || pub struct Runtime -21 | || { -22 | || System: frame_system -23 | || } -24 | || } +20 | || type Migrations = (Dummy); +21 | || pub struct Runtime +22 | || { +23 | || System: frame_system +24 | || } +25 | || } | ||_- in this macro invocation ... | | @@ -74,11 +76,12 @@ error[E0599]: the function or associated item `apply_extrinsic` exists for struc | __^ | | _| | || -20 | || pub struct Runtime -21 | || { -22 | || System: frame_system -23 | || } -24 | || } +20 | || type Migrations = (Dummy); +21 | || pub struct Runtime +22 | || { +23 | || System: frame_system +24 | || } +25 | || } | ||_- in this macro invocation ... | | @@ -107,11 +110,12 @@ error[E0599]: the function or associated item `finalize_block` exists for struct | __^ | | _| | || -20 | || pub struct Runtime -21 | || { -22 | || System: frame_system -23 | || } -24 | || } +20 | || type Migrations = (Dummy); +21 | || pub struct Runtime +22 | || { +23 | || System: frame_system +24 | || } +25 | || } | ||_- in this macro invocation ... | | @@ -140,11 +144,12 @@ error[E0599]: the function or associated item `validate_transaction` exists for | __^ | | _| | || -20 | || pub struct Runtime -21 | || { -22 | || System: frame_system -23 | || } -24 | || } +20 | || type Migrations = (Dummy); +21 | || pub struct Runtime +22 | || { +23 | || System: frame_system +24 | || } +25 | || } | ||_- in this macro invocation ... | | @@ -173,11 +178,12 @@ error[E0599]: the function or associated item `offchain_worker` exists for struc | __^ | | _| | || -20 | || pub struct Runtime -21 | || { -22 | || System: frame_system -23 | || } -24 | || } +20 | || type Migrations = (Dummy); +21 | || pub struct Runtime +22 | || { +23 | || System: frame_system +24 | || } +25 | || } | ||_- in this macro invocation ... | | From 747084da4da9662c13a46b717c523edd10529f9c Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:26:18 +0530 Subject: [PATCH 11/11] Minor fix --- test-utils/runtime/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 535dd38ac2899..528881c950e16 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -289,7 +289,8 @@ impl sp_runtime::traits::SignedExtension for CheckSubstrateCall { } construct_runtime!( - pub enum Runtime<_> + type Migrations = (); + pub enum Runtime { System: frame_system, Babe: pallet_babe,