Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Abstract away the executive #14742

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
17 changes: 8 additions & 9 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1874,7 +1874,14 @@ impl pallet_statement::Config for Runtime {
}

construct_runtime!(
pub struct Runtime<Migrations>
// All migrations executed on runtime upgrade as a nested tuple of types implementing
// `OnRuntimeUpgrade`.
type Migrations = (
pallet_nomination_pools::migration::v2::MigrateToV2<Runtime>,
pallet_alliance::migration::Migration<Runtime>,
pallet_contracts::Migration<Runtime>,
);
pub struct Runtime
{
System: frame_system,
Utility: pallet_utility,
Expand Down Expand Up @@ -1983,14 +1990,6 @@ pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra>;

// All migrations executed on runtime upgrade as a nested tuple of types implementing
// `OnRuntimeUpgrade`.
type Migrations = (
pallet_nomination_pools::migration::v2::MigrateToV2<Runtime>,
pallet_alliance::migration::Migration<Runtime>,
pallet_contracts::Migration<Runtime>,
);

type EventRecord = frame_system::EventRecord<
<Runtime as frame_system::Config>::RuntimeEvent,
<Runtime as frame_system::Config>::Hash,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ pub fn expand_executive(
) -> Result<TokenStream> {
let executive = generate_crate_access_2018("frame-executive")?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will play nicely with the new frame crate, it should re-export the 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!(()),
};

Expand Down Expand Up @@ -67,7 +67,7 @@ pub fn expand_executive(
#system::ChainContext<#runtime>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kinda cheating, if you want to be pedantic. There's now no good way to configure this. But I am not sure if this is all that useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I will add the support to provide a custom Executive as well, using the syntax you suggested above.

#runtime,
AllPalletsWithSystem,
#on_runtime_upgrade
(#migrations)
>;

impl #runtime {
Expand Down
67 changes: 56 additions & 11 deletions frame/support/procedural/src/construct_runtime/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -82,6 +82,8 @@ pub struct ExplicitRuntimeDeclaration {

impl Parse for RuntimeDeclaration {
fn parse(input: ParseStream) -> Result<Self> {
let executive_section = if input.peek(Token![type]) { Some(input.parse()?) } else { None };

input.parse::<Token![pub]>()?;

// Support either `enum` or `struct`.
Expand All @@ -93,8 +95,6 @@ impl Parse for RuntimeDeclaration {

let name = input.parse::<syn::Ident>()?;

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::<ext::Braces<ext::Punctuated<PalletDeclaration, Token![,]>>>()?;
Expand Down Expand Up @@ -131,20 +131,65 @@ impl Parse for RuntimeDeclaration {
#[derive(Debug)]
pub struct ExecutiveSection {
pub span: Span,
pub custom_on_runtime_upgrade: Option<Ident>,
pub migration_section: Option<Migrations>,
}

impl Parse for ExecutiveSection {
fn parse(input: ParseStream) -> Result<Self> {
let _ = input.parse::<Token![<]>()?;
let custom_on_runtime_upgrade = if input.peek(Token![_]) {
let _ = input.parse::<Token![_]>()?;
None
let _ = input.parse::<Token![type]>()?;
let name = input.parse::<syn::Ident>()?;

let migration_section = if name.to_string() == "Migrations" {
Some(input.parse::<Migrations>()?)
} else {
Some(input.parse::<syn::Ident>()?)
None
};
let _ = input.parse::<Token![>]>()?;
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<Migration, token::Comma>,
}

impl Parse for Migrations {
fn parse(input: ParseStream) -> Result<Self> {
let _ = input.parse::<Token![=]>()?;

let content;
syn::parenthesized!(content in input);

let migrations = content.parse_terminated(Migration::parse, Token![,])?;
let _ = input.parse::<Token![;]>()?;
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<Self> {
let name = input.parse::<Type>()?;
Ok(Self { span: input.span(), ident: name })
}
}

impl ToTokens for Migration {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.ident.to_tokens(tokens);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ impl frame_system::Config for Runtime {
struct Dummy;

construct_runtime! {
pub struct Runtime<Dummy>
type Migrations = (Dummy);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it work if you use (Dummy,)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it parses correctly and throws the correct error.

pub struct Runtime
{
System: frame_system
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ error[E0599]: the function or associated item `execute_block` exists for struct
| __^
| | _|
| ||
20 | || pub struct Runtime<Dummy>
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
... |
|
Expand Down Expand Up @@ -41,11 +42,12 @@ error[E0599]: the function or associated item `initialize_block` exists for stru
| __^
| | _|
| ||
20 | || pub struct Runtime<Dummy>
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
... |
|
Expand Down Expand Up @@ -74,11 +76,12 @@ error[E0599]: the function or associated item `apply_extrinsic` exists for struc
| __^
| | _|
| ||
20 | || pub struct Runtime<Dummy>
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
... |
|
Expand Down Expand Up @@ -107,11 +110,12 @@ error[E0599]: the function or associated item `finalize_block` exists for struct
| __^
| | _|
| ||
20 | || pub struct Runtime<Dummy>
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
... |
|
Expand Down Expand Up @@ -140,11 +144,12 @@ error[E0599]: the function or associated item `validate_transaction` exists for
| __^
| | _|
| ||
20 | || pub struct Runtime<Dummy>
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
... |
|
Expand Down Expand Up @@ -173,11 +178,12 @@ error[E0599]: the function or associated item `offchain_worker` exists for struc
| __^
| | _|
| ||
20 | || pub struct Runtime<Dummy>
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
... |
|
Expand Down