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

Commit

Permalink
[Enhancement] Throw an error when there are too many pallets (#13763)
Browse files Browse the repository at this point in the history
* [Enhancement] Throw an error when there are too many pallets

* fix ui test

* fix PR comments

* Update frame/support/procedural/src/construct_runtime/mod.rs

Co-authored-by: Bastian Köcher <git@kchr.de>

* Update frame/support/procedural/src/construct_runtime/mod.rs

Co-authored-by: Bastian Köcher <git@kchr.de>

* ".git/.scripts/commands/fmt/fmt.sh"

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: command-bot <>
  • Loading branch information
2 people authored and gpestana committed Apr 20, 2023
1 parent cb3869d commit daf303f
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 3 deletions.
40 changes: 37 additions & 3 deletions frame/support/procedural/src/construct_runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use std::{collections::HashSet, str::FromStr};
use syn::{Ident, Result};
use syn::{spanned::Spanned, Ident, Result};

/// The fixed name of the system pallet.
const SYSTEM_PALLET_NAME: &str = "System";
Expand All @@ -170,9 +170,12 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream {

let res = match definition {
RuntimeDeclaration::Implicit(implicit_def) =>
construct_runtime_intermediary_expansion(input_copy.into(), implicit_def),
check_pallet_number(input_copy.clone().into(), implicit_def.pallets.len()).and_then(
|_| construct_runtime_intermediary_expansion(input_copy.into(), implicit_def),
),
RuntimeDeclaration::Explicit(explicit_decl) =>
construct_runtime_final_expansion(explicit_decl),
check_pallet_number(input_copy.into(), explicit_decl.pallets.len())
.and_then(|_| construct_runtime_final_expansion(explicit_decl)),
};

res.unwrap_or_else(|e| e.to_compile_error()).into()
Expand Down Expand Up @@ -616,3 +619,34 @@ fn decl_static_assertions(
#(#error_encoded_size_check)*
}
}

fn check_pallet_number(input: TokenStream2, pallet_num: usize) -> Result<()> {
let max_pallet_num = {
if cfg!(feature = "tuples-96") {
96
} else if cfg!(feature = "tuples-128") {
128
} else {
64
}
};

if pallet_num > max_pallet_num {
let no_feature = max_pallet_num == 128;
return Err(syn::Error::new(
input.span(),
format!(
"{} To increase this limit, enable the tuples-{} feature of [frame_support]. {}",
"The number of pallets exceeds the maximum number of tuple elements.",
max_pallet_num + 32,
if no_feature {
"If the feature does not exist - it needs to be implemented."
} else {
""
},
),
))
}

Ok(())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
use frame_support::construct_runtime;
use sp_core::sr25519;
use sp_runtime::{generic, traits::BlakeTwo256};

#[frame_support::pallet]
mod pallet {
#[pallet::config]
pub trait Config: frame_system::Config {}

#[pallet::pallet]
pub struct Pallet<T>(core::marker::PhantomData<T>);
}

pub type Signature = sr25519::Signature;
pub type BlockNumber = u32;
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, RuntimeCall, Signature, ()>;

impl pallet::Config for Runtime {}

impl frame_system::Config for Runtime {
type BaseCallFilter = frame_support::traits::Everything;
type RuntimeOrigin = RuntimeOrigin;
type Index = u64;
type BlockNumber = u32;
type RuntimeCall = RuntimeCall;
type Hash = sp_runtime::testing::H256;
type Hashing = sp_runtime::traits::BlakeTwo256;
type AccountId = u64;
type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
type Header = Header;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = frame_support::traits::ConstU32<250>;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

construct_runtime! {
pub struct Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
Pallet1: pallet::{Pallet},
Pallet2: pallet::{Pallet},
Pallet3: pallet::{Pallet},
Pallet4: pallet::{Pallet},
Pallet5: pallet::{Pallet},
Pallet6: pallet::{Pallet},
Pallet7: pallet::{Pallet},
Pallet8: pallet::{Pallet},
Pallet9: pallet::{Pallet},
Pallet10: pallet::{Pallet},
Pallet11: pallet::{Pallet},
Pallet12: pallet::{Pallet},
Pallet13: pallet::{Pallet},
Pallet14: pallet::{Pallet},
Pallet15: pallet::{Pallet},
Pallet16: pallet::{Pallet},
Pallet17: pallet::{Pallet},
Pallet18: pallet::{Pallet},
Pallet19: pallet::{Pallet},
Pallet20: pallet::{Pallet},
Pallet21: pallet::{Pallet},
Pallet22: pallet::{Pallet},
Pallet23: pallet::{Pallet},
Pallet24: pallet::{Pallet},
Pallet25: pallet::{Pallet},
Pallet26: pallet::{Pallet},
Pallet27: pallet::{Pallet},
Pallet28: pallet::{Pallet},
Pallet29: pallet::{Pallet},
Pallet30: pallet::{Pallet},
Pallet31: pallet::{Pallet},
Pallet32: pallet::{Pallet},
Pallet33: pallet::{Pallet},
Pallet34: pallet::{Pallet},
Pallet35: pallet::{Pallet},
Pallet36: pallet::{Pallet},
Pallet37: pallet::{Pallet},
Pallet38: pallet::{Pallet},
Pallet39: pallet::{Pallet},
Pallet40: pallet::{Pallet},
Pallet41: pallet::{Pallet},
Pallet42: pallet::{Pallet},
Pallet43: pallet::{Pallet},
Pallet44: pallet::{Pallet},
Pallet45: pallet::{Pallet},
Pallet46: pallet::{Pallet},
Pallet47: pallet::{Pallet},
Pallet48: pallet::{Pallet},
Pallet49: pallet::{Pallet},
Pallet50: pallet::{Pallet},
Pallet51: pallet::{Pallet},
Pallet52: pallet::{Pallet},
Pallet53: pallet::{Pallet},
Pallet54: pallet::{Pallet},
Pallet55: pallet::{Pallet},
Pallet56: pallet::{Pallet},
Pallet57: pallet::{Pallet},
Pallet58: pallet::{Pallet},
Pallet59: pallet::{Pallet},
Pallet60: pallet::{Pallet},
Pallet61: pallet::{Pallet},
Pallet62: pallet::{Pallet},
Pallet63: pallet::{Pallet},
Pallet64: pallet::{Pallet},
Pallet65: pallet::{Pallet},
Pallet66: pallet::{Pallet},
Pallet67: pallet::{Pallet},
Pallet68: pallet::{Pallet},
Pallet69: pallet::{Pallet},
Pallet70: pallet::{Pallet},
Pallet71: pallet::{Pallet},
Pallet72: pallet::{Pallet},
Pallet73: pallet::{Pallet},
Pallet74: pallet::{Pallet},
Pallet75: pallet::{Pallet},
Pallet76: pallet::{Pallet},
Pallet77: pallet::{Pallet},
Pallet78: pallet::{Pallet},
Pallet79: pallet::{Pallet},
Pallet80: pallet::{Pallet},
Pallet81: pallet::{Pallet},
Pallet82: pallet::{Pallet},
Pallet83: pallet::{Pallet},
Pallet84: pallet::{Pallet},
Pallet85: pallet::{Pallet},
Pallet86: pallet::{Pallet},
Pallet87: pallet::{Pallet},
Pallet88: pallet::{Pallet},
Pallet89: pallet::{Pallet},
Pallet90: pallet::{Pallet},
Pallet91: pallet::{Pallet},
Pallet92: pallet::{Pallet},
Pallet93: pallet::{Pallet},
Pallet94: pallet::{Pallet},
Pallet95: pallet::{Pallet},
Pallet96: pallet::{Pallet},
Pallet97: pallet::{Pallet},
Pallet98: pallet::{Pallet},
Pallet99: pallet::{Pallet},
Pallet100: pallet::{Pallet},
Pallet101: pallet::{Pallet},
Pallet102: pallet::{Pallet},
Pallet103: pallet::{Pallet},
Pallet104: pallet::{Pallet},
Pallet105: pallet::{Pallet},
Pallet106: pallet::{Pallet},
Pallet107: pallet::{Pallet},
Pallet108: pallet::{Pallet},
Pallet109: pallet::{Pallet},
Pallet110: pallet::{Pallet},
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
error: The number of pallets exceeds the maximum number of tuple elements. To increase this limit, enable the tuples-96 feature of [frame_support].
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:50:2
|
50 | pub struct Runtime where
| ^^^

error[E0412]: cannot find type `RuntimeCall` in this scope
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:18:64
|
18 | pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, RuntimeCall, Signature, ()>;
| ^^^^^^^^^^^ not found in this scope
|
help: you might be missing a type parameter
|
18 | pub type UncheckedExtrinsic<RuntimeCall> = generic::UncheckedExtrinsic<u32, RuntimeCall, Signature, ()>;
| +++++++++++++

error[E0412]: cannot find type `Runtime` in this scope
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:20:25
|
20 | impl pallet::Config for Runtime {}
| ^^^^^^^ not found in this scope

error[E0412]: cannot find type `Runtime` in this scope
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:22:31
|
22 | impl frame_system::Config for Runtime {
| ^^^^^^^ not found in this scope

error[E0412]: cannot find type `RuntimeOrigin` in this scope
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:24:23
|
24 | type RuntimeOrigin = RuntimeOrigin;
| ^^^^^^^^^^^^^ help: you might have meant to use the associated type: `Self::RuntimeOrigin`

error[E0412]: cannot find type `RuntimeCall` in this scope
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:27:21
|
27 | type RuntimeCall = RuntimeCall;
| ^^^^^^^^^^^ help: you might have meant to use the associated type: `Self::RuntimeCall`

error[E0412]: cannot find type `RuntimeEvent` in this scope
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:33:22
|
33 | type RuntimeEvent = RuntimeEvent;
| ^^^^^^^^^^^^ help: you might have meant to use the associated type: `Self::RuntimeEvent`

error[E0412]: cannot find type `PalletInfo` in this scope
--> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:39:20
|
39 | type PalletInfo = PalletInfo;
| ^^^^^^^^^^
|
help: you might have meant to use the associated type
|
39 | type PalletInfo = Self::PalletInfo;
| ~~~~~~~~~~~~~~~~
help: consider importing this trait
|
1 | use frame_support::traits::PalletInfo;
|

0 comments on commit daf303f

Please sign in to comment.