Skip to content

Commit

Permalink
Construct Runtime v2 (#1378)
Browse files Browse the repository at this point in the history
Moved from paritytech/substrate#14788

----

Fixes #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
paritytech/substrate#14742
- Optionally avoid the need to specify all runtime types (TBD)

---------

Co-authored-by: Francisco Aguirre <[email protected]>
Co-authored-by: Nikhil Gupta <>
  • Loading branch information
codekitz and franciscoaguirre authored Mar 13, 2024
1 parent a756baf commit 82f3c3e
Show file tree
Hide file tree
Showing 45 changed files with 3,212 additions and 205 deletions.
27 changes: 27 additions & 0 deletions prdoc/pr_1378.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
title: Construct Runtime V2 - An outer macro approach to define the runtime

doc:
- audience: Runtime Dev
description: |
Introduces `#[frame_support::runtime]` that can be attached to a mod to define a runtime. The items
in this mod can be attached to the following attributes to define the key components of the runtime.
1. `#[runtime::runtime]` attached to a struct defines the main runtime
2. `#[runtime::derive]` attached to the runtime struct defines the types generated by the runtime
3. `#[runtime::pallet_index]` must be attached to a pallet to define its index
4. `#[runtime::disable_call]` can be optionally attached to a pallet to disable its calls
5. `#[runtime::disable_unsigned]` can be optionally attached to a pallet to disable unsigned calls
6. 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.

migrations:
db: []

runtime: []

crates:
- name: frame-support
- name: frame-support-procedural

host_functions: []
2 changes: 1 addition & 1 deletion substrate/bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ sp-io = { path = "../../../primitives/io", default-features = false }
frame-executive = { path = "../../../frame/executive", default-features = false }
frame-benchmarking = { path = "../../../frame/benchmarking", default-features = false }
frame-benchmarking-pallet-pov = { path = "../../../frame/benchmarking/pov", default-features = false }
frame-support = { path = "../../../frame/support", default-features = false, features = ["tuples-96"] }
frame-support = { path = "../../../frame/support", default-features = false, features = ["experimental", "tuples-96"] }
frame-system = { path = "../../../frame/system", default-features = false }
frame-system-benchmarking = { path = "../../../frame/system/benchmarking", default-features = false, optional = true }
frame-election-provider-support = { path = "../../../frame/election-provider-support", default-features = false }
Expand Down
342 changes: 255 additions & 87 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use frame_election_provider_support::{
onchain, BalancingConfig, ElectionDataProvider, SequentialPhragmen, VoteWeight,
};
use frame_support::{
construct_runtime, derive_impl,
derive_impl,
dispatch::DispatchClass,
dynamic_params::{dynamic_pallet_params, dynamic_params},
genesis_builder_helper::{build_config, create_default_config},
Expand Down Expand Up @@ -2196,92 +2196,260 @@ impl pallet_parameters::Config for Runtime {
type WeightInfo = ();
}

construct_runtime!(
pub enum Runtime {
System: frame_system,
Utility: pallet_utility,
Babe: pallet_babe,
Timestamp: pallet_timestamp,
// Authorship must be before session in order to note author in the correct session and era
// for im-online and staking.
Authorship: pallet_authorship,
Indices: pallet_indices,
Balances: pallet_balances,
TransactionPayment: pallet_transaction_payment,
AssetTxPayment: pallet_asset_tx_payment,
AssetConversionTxPayment: pallet_asset_conversion_tx_payment,
ElectionProviderMultiPhase: pallet_election_provider_multi_phase,
Staking: pallet_staking,
Session: pallet_session,
Democracy: pallet_democracy,
Council: pallet_collective::<Instance1>,
TechnicalCommittee: pallet_collective::<Instance2>,
Elections: pallet_elections_phragmen,
TechnicalMembership: pallet_membership::<Instance1>,
Grandpa: pallet_grandpa,
Treasury: pallet_treasury,
AssetRate: pallet_asset_rate,
Contracts: pallet_contracts,
Sudo: pallet_sudo,
ImOnline: pallet_im_online,
AuthorityDiscovery: pallet_authority_discovery,
Offences: pallet_offences,
Historical: pallet_session_historical,
RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip,
Identity: pallet_identity,
Society: pallet_society,
Recovery: pallet_recovery,
Vesting: pallet_vesting,
Scheduler: pallet_scheduler,
Glutton: pallet_glutton,
Preimage: pallet_preimage,
Proxy: pallet_proxy,
Multisig: pallet_multisig,
Bounties: pallet_bounties,
Tips: pallet_tips,
Assets: pallet_assets::<Instance1>,
PoolAssets: pallet_assets::<Instance2>,
Beefy: pallet_beefy,
// MMR leaf construction must be after session in order to have a leaf's next_auth_set
// refer to block<N>. See issue polkadot-fellows/runtimes#160 for details.
Mmr: pallet_mmr,
MmrLeaf: pallet_beefy_mmr,
Lottery: pallet_lottery,
Nis: pallet_nis,
Uniques: pallet_uniques,
Nfts: pallet_nfts,
NftFractionalization: pallet_nft_fractionalization,
Salary: pallet_salary,
CoreFellowship: pallet_core_fellowship,
TransactionStorage: pallet_transaction_storage,
VoterList: pallet_bags_list::<Instance1>,
StateTrieMigration: pallet_state_trie_migration,
ChildBounties: pallet_child_bounties,
Referenda: pallet_referenda,
Remark: pallet_remark,
RootTesting: pallet_root_testing,
ConvictionVoting: pallet_conviction_voting,
Whitelist: pallet_whitelist,
AllianceMotion: pallet_collective::<Instance3>,
Alliance: pallet_alliance,
NominationPools: pallet_nomination_pools,
RankedPolls: pallet_referenda::<Instance2>,
RankedCollective: pallet_ranked_collective,
AssetConversion: pallet_asset_conversion,
FastUnstake: pallet_fast_unstake,
MessageQueue: pallet_message_queue,
Pov: frame_benchmarking_pallet_pov,
TxPause: pallet_tx_pause,
SafeMode: pallet_safe_mode,
Statement: pallet_statement,
MultiBlockMigrations: pallet_migrations,
Broker: pallet_broker,
TasksExample: pallet_example_tasks,
Mixnet: pallet_mixnet,
Parameters: pallet_parameters,
SkipFeelessPayment: pallet_skip_feeless_payment,
}
);
#[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 Utility = pallet_utility;

#[runtime::pallet_index(2)]
pub type Babe = pallet_babe;

#[runtime::pallet_index(3)]
pub type Timestamp = pallet_timestamp;

// Authorship must be before session in order to note author in the correct session and era
// for im-online and staking.
#[runtime::pallet_index(4)]
pub type Authorship = pallet_authorship;

#[runtime::pallet_index(5)]
pub type Indices = pallet_indices;

#[runtime::pallet_index(6)]
pub type Balances = pallet_balances;

#[runtime::pallet_index(7)]
pub type TransactionPayment = pallet_transaction_payment;

#[runtime::pallet_index(8)]
pub type AssetTxPayment = pallet_asset_tx_payment;

#[runtime::pallet_index(9)]
pub type AssetConversionTxPayment = pallet_asset_conversion_tx_payment;

#[runtime::pallet_index(10)]
pub type ElectionProviderMultiPhase = pallet_election_provider_multi_phase;

#[runtime::pallet_index(11)]
pub type Staking = pallet_staking;

#[runtime::pallet_index(12)]
pub type Session = pallet_session;

#[runtime::pallet_index(13)]
pub type Democracy = pallet_democracy;

#[runtime::pallet_index(14)]
pub type Council = pallet_collective<Instance1>;

#[runtime::pallet_index(15)]
pub type TechnicalCommittee = pallet_collective<Instance2>;

#[runtime::pallet_index(16)]
pub type Elections = pallet_elections_phragmen;

#[runtime::pallet_index(17)]
pub type TechnicalMembership = pallet_membership<Instance1>;

#[runtime::pallet_index(18)]
pub type Grandpa = pallet_grandpa;

#[runtime::pallet_index(19)]
pub type Treasury = pallet_treasury;

#[runtime::pallet_index(20)]
pub type AssetRate = pallet_asset_rate;

#[runtime::pallet_index(21)]
pub type Contracts = pallet_contracts;

#[runtime::pallet_index(22)]
pub type Sudo = pallet_sudo;

#[runtime::pallet_index(23)]
pub type ImOnline = pallet_im_online;

#[runtime::pallet_index(24)]
pub type AuthorityDiscovery = pallet_authority_discovery;

#[runtime::pallet_index(25)]
pub type Offences = pallet_offences;

#[runtime::pallet_index(26)]
pub type Historical = pallet_session_historical;

#[runtime::pallet_index(27)]
pub type RandomnessCollectiveFlip = pallet_insecure_randomness_collective_flip;

#[runtime::pallet_index(28)]
pub type Identity = pallet_identity;

#[runtime::pallet_index(29)]
pub type Society = pallet_society;

#[runtime::pallet_index(30)]
pub type Recovery = pallet_recovery;

#[runtime::pallet_index(31)]
pub type Vesting = pallet_vesting;

#[runtime::pallet_index(32)]
pub type Scheduler = pallet_scheduler;

#[runtime::pallet_index(33)]
pub type Glutton = pallet_glutton;

#[runtime::pallet_index(34)]
pub type Preimage = pallet_preimage;

#[runtime::pallet_index(35)]
pub type Proxy = pallet_proxy;

#[runtime::pallet_index(36)]
pub type Multisig = pallet_multisig;

#[runtime::pallet_index(37)]
pub type Bounties = pallet_bounties;

#[runtime::pallet_index(38)]
pub type Tips = pallet_tips;

#[runtime::pallet_index(39)]
pub type Assets = pallet_assets<Instance1>;

#[runtime::pallet_index(40)]
pub type PoolAssets = pallet_assets<Instance2>;

#[runtime::pallet_index(41)]
pub type Beefy = pallet_beefy;

// MMR leaf construction must be after session in order to have a leaf's next_auth_set
// refer to block<N>. See issue polkadot-fellows/runtimes#160 for details.
#[runtime::pallet_index(42)]
pub type Mmr = pallet_mmr;

#[runtime::pallet_index(43)]
pub type MmrLeaf = pallet_beefy_mmr;

#[runtime::pallet_index(44)]
pub type Lottery = pallet_lottery;

#[runtime::pallet_index(45)]
pub type Nis = pallet_nis;

#[runtime::pallet_index(46)]
pub type Uniques = pallet_uniques;

#[runtime::pallet_index(47)]
pub type Nfts = pallet_nfts;

#[runtime::pallet_index(48)]
pub type NftFractionalization = pallet_nft_fractionalization;

#[runtime::pallet_index(49)]
pub type Salary = pallet_salary;

#[runtime::pallet_index(50)]
pub type CoreFellowship = pallet_core_fellowship;

#[runtime::pallet_index(51)]
pub type TransactionStorage = pallet_transaction_storage;

#[runtime::pallet_index(52)]
pub type VoterList = pallet_bags_list<Instance1>;

#[runtime::pallet_index(53)]
pub type StateTrieMigration = pallet_state_trie_migration;

#[runtime::pallet_index(54)]
pub type ChildBounties = pallet_child_bounties;

#[runtime::pallet_index(55)]
pub type Referenda = pallet_referenda;

#[runtime::pallet_index(56)]
pub type Remark = pallet_remark;

#[runtime::pallet_index(57)]
pub type RootTesting = pallet_root_testing;

#[runtime::pallet_index(58)]
pub type ConvictionVoting = pallet_conviction_voting;

#[runtime::pallet_index(59)]
pub type Whitelist = pallet_whitelist;

#[runtime::pallet_index(60)]
pub type AllianceMotion = pallet_collective<Instance3>;

#[runtime::pallet_index(61)]
pub type Alliance = pallet_alliance;

#[runtime::pallet_index(62)]
pub type NominationPools = pallet_nomination_pools;

#[runtime::pallet_index(63)]
pub type RankedPolls = pallet_referenda<Instance2>;

#[runtime::pallet_index(64)]
pub type RankedCollective = pallet_ranked_collective;

#[runtime::pallet_index(65)]
pub type AssetConversion = pallet_asset_conversion;

#[runtime::pallet_index(66)]
pub type FastUnstake = pallet_fast_unstake;

#[runtime::pallet_index(67)]
pub type MessageQueue = pallet_message_queue;

#[runtime::pallet_index(68)]
pub type Pov = frame_benchmarking_pallet_pov;

#[runtime::pallet_index(69)]
pub type TxPause = pallet_tx_pause;

#[runtime::pallet_index(70)]
pub type SafeMode = pallet_safe_mode;

#[runtime::pallet_index(71)]
pub type Statement = pallet_statement;

#[runtime::pallet_index(72)]
pub type MultiBlockMigrations = pallet_migrations;

#[runtime::pallet_index(73)]
pub type Broker = pallet_broker;

#[runtime::pallet_index(74)]
pub type TasksExample = pallet_example_tasks;

#[runtime::pallet_index(75)]
pub type Mixnet = pallet_mixnet;

#[runtime::pallet_index(76)]
pub type Parameters = pallet_parameters;

#[runtime::pallet_index(77)]
pub type SkipFeelessPayment = pallet_skip_feeless_payment;
}

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, AccountIndex>;
Expand Down
Loading

0 comments on commit 82f3c3e

Please sign in to comment.