mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-26 04:11:09 +00:00
Construct Runtime v2 (#1378)
Moved from https://github.com/paritytech/substrate/pull/14788 ---- Fixes https://github.com/paritytech/polkadot-sdk/issues/232 This PR introduces outer-macro approach for `construct_runtime` as discussed in the linked issue. It looks like the following: ```rust #[frame_support::runtime] mod runtime { #[runtime::runtime] #[runtime::derive( RuntimeCall, RuntimeEvent, RuntimeError, RuntimeOrigin, RuntimeFreezeReason, RuntimeHoldReason, RuntimeSlashReason, RuntimeLockId, RuntimeTask, )] pub struct Runtime; #[runtime::pallet_index(0)] pub type System = frame_system; #[runtime::pallet_index(1)] pub type Timestamp = pallet_timestamp; #[runtime::pallet_index(2)] pub type Aura = pallet_aura; #[runtime::pallet_index(3)] pub type Grandpa = pallet_grandpa; #[runtime::pallet_index(4)] pub type Balances = pallet_balances; #[runtime::pallet_index(5)] pub type TransactionPayment = pallet_transaction_payment; #[runtime::pallet_index(6)] pub type Sudo = pallet_sudo; // Include the custom logic from the pallet-template in the runtime. #[runtime::pallet_index(7)] pub type TemplateModule = pallet_template; } ``` ## Features - `#[runtime::runtime]` attached to a struct defines the main runtime - `#[runtime::derive]` attached to this struct defines the types generated by runtime - `#[runtime::pallet_index]` must be attached to a pallet to define its index - `#[runtime::disable_call]` can be optionally attached to a pallet to disable its calls - `#[runtime::disable_unsigned]` can be optionally attached to a pallet to disable unsigned calls - A pallet instance can be defined as `TemplateModule: pallet_template<Instance>` - An optional attribute can be defined as `#[frame_support::runtime(legacy_ordering)]` to ensure that the order of hooks is same as the order of pallets (and not based on the pallet_index). This is to support legacy runtimes and should be avoided for new ones. ## Todo - [x] Update the latest syntax in kitchensink and tests - [x] Update UI tests - [x] Docs ## Extension - Abstract away the Executive similar to https://github.com/paritytech/substrate/pull/14742 - Optionally avoid the need to specify all runtime types (TBD) --------- Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com> Co-authored-by: Nikhil Gupta <>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
// 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 crate::construct_runtime::parse::{Pallet, PalletPart, PalletPartKeyword, PalletPath};
|
||||
use quote::ToTokens;
|
||||
use syn::{punctuated::Punctuated, spanned::Spanned, token, Error, Ident, PathArguments};
|
||||
|
||||
impl Pallet {
|
||||
pub fn try_from(
|
||||
attr_span: proc_macro2::Span,
|
||||
item: &syn::ItemType,
|
||||
pallet_index: u8,
|
||||
disable_call: bool,
|
||||
disable_unsigned: bool,
|
||||
bounds: &Punctuated<syn::TypeParamBound, token::Plus>,
|
||||
) -> syn::Result<Self> {
|
||||
let name = item.ident.clone();
|
||||
|
||||
let mut pallet_path = None;
|
||||
let mut pallet_parts = vec![];
|
||||
|
||||
for (index, bound) in bounds.into_iter().enumerate() {
|
||||
if let syn::TypeParamBound::Trait(syn::TraitBound { path, .. }) = bound {
|
||||
if index == 0 {
|
||||
pallet_path = Some(PalletPath { inner: path.clone() });
|
||||
} else {
|
||||
let pallet_part = syn::parse2::<PalletPart>(bound.into_token_stream())?;
|
||||
pallet_parts.push(pallet_part);
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
attr_span,
|
||||
"Invalid pallet declaration, expected a path or a trait object",
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
let mut path = pallet_path.ok_or(Error::new(
|
||||
attr_span,
|
||||
"Invalid pallet declaration, expected a path or a trait object",
|
||||
))?;
|
||||
|
||||
let mut instance = None;
|
||||
if let Some(segment) = path.inner.segments.iter_mut().find(|seg| !seg.arguments.is_empty())
|
||||
{
|
||||
if let PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
|
||||
args, ..
|
||||
}) = segment.arguments.clone()
|
||||
{
|
||||
if let Some(syn::GenericArgument::Type(syn::Type::Path(arg_path))) = args.first() {
|
||||
instance =
|
||||
Some(Ident::new(&arg_path.to_token_stream().to_string(), arg_path.span()));
|
||||
segment.arguments = PathArguments::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pallet_parts = pallet_parts
|
||||
.into_iter()
|
||||
.filter(|part| {
|
||||
if let (true, &PalletPartKeyword::Call(_)) = (disable_call, &part.keyword) {
|
||||
false
|
||||
} else if let (true, &PalletPartKeyword::ValidateUnsigned(_)) =
|
||||
(disable_unsigned, &part.keyword)
|
||||
{
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let cfg_pattern = vec![];
|
||||
|
||||
Ok(Pallet {
|
||||
is_expanded: true,
|
||||
name,
|
||||
index: pallet_index,
|
||||
path,
|
||||
instance,
|
||||
cfg_pattern,
|
||||
pallet_parts,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user