referrerpolicy=no-referrer-when-downgrade

frame_executive/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18#![cfg_attr(not(feature = "std"), no_std)]
19
20//! # Executive Module
21//!
22//! The Executive module acts as the orchestration layer for the runtime. It dispatches incoming
23//! extrinsic calls to the respective modules in the runtime.
24//!
25//! ## Overview
26//!
27//! The executive module is not a typical pallet providing functionality around a specific feature.
28//! It is a cross-cutting framework component for the FRAME. It works in conjunction with the
29//! [FRAME System module](../frame_system/index.html) to perform these cross-cutting functions.
30//!
31//! The Executive module provides functions to:
32//!
33//! - Check transaction validity.
34//! - Initialize a block.
35//! - Apply extrinsics.
36//! - Execute a block.
37//! - Finalize a block.
38//! - Start an off-chain worker.
39//!
40//! The flow of their application in a block is explained in the [block flowchart](block_flowchart).
41//!
42//! ### Implementations
43//!
44//! The Executive module provides the following implementations:
45//!
46//! - `ExecuteBlock`: Trait that can be used to execute a block.
47//! - `Executive`: Type that can be used to make the FRAME available from the runtime.
48//!
49//! ## Usage
50//!
51//! The default Substrate node template declares the [`Executive`](./struct.Executive.html) type in
52//! its library.
53//!
54//! ### Example
55//!
56//! `Executive` type declaration from the node template.
57//!
58//! ```
59//! # use sp_runtime::generic;
60//! # use frame_executive as executive;
61//! # pub struct UncheckedExtrinsic {};
62//! # pub struct Header {};
63//! # type Context = frame_system::ChainContext<Runtime>;
64//! # pub type Block = generic::Block<Header, UncheckedExtrinsic>;
65//! # pub type Balances = u64;
66//! # pub type AllPalletsWithSystem = u64;
67//! # pub enum Runtime {};
68//! # use sp_runtime::transaction_validity::{
69//! #    TransactionValidity, UnknownTransaction, TransactionSource,
70//! # };
71//! # use sp_runtime::traits::ValidateUnsigned;
72//! # impl ValidateUnsigned for Runtime {
73//! #     type Call = ();
74//! #
75//! #     fn validate_unsigned(_source: TransactionSource, _call: &Self::Call) -> TransactionValidity {
76//! #         UnknownTransaction::NoUnsignedValidator.into()
77//! #     }
78//! # }
79//! /// Executive: handles dispatch to the various modules.
80//! pub type Executive = executive::Executive<Runtime, Block, Context, Runtime, AllPalletsWithSystem>;
81//! ```
82
83#[cfg(doc)]
84#[cfg_attr(doc, aquamarine::aquamarine)]
85/// # Block Execution
86///
87/// These are the steps of block execution as done by [`Executive::execute_block`]. A block is
88/// invalid if any of them fail.
89///
90/// ```mermaid
91/// flowchart TD
92///     Executive::execute_block --> on_runtime_upgrade
93///     on_runtime_upgrade --> System::initialize
94///     Executive::initialize_block --> System::initialize
95///     System::initialize --> on_initialize
96///     on_initialize --> PreInherents[System::PreInherents]
97///     PreInherents --> Inherents[Apply Inherents]
98///     Inherents --> PostInherents[System::PostInherents]
99///     PostInherents --> Check{MBM ongoing?}
100///     Check -->|No| poll
101///     Check -->|Yes| post_transactions_2[System::PostTransaction]
102///     post_transactions_2 --> Step[MBMs::step]
103///     Step --> on_finalize
104///     poll --> transactions[Apply Transactions]
105///     transactions --> post_transactions_1[System::PostTransaction]
106///     post_transactions_1 --> CheckIdle{Weight remaining?}
107///     CheckIdle -->|Yes| on_idle
108///     CheckIdle -->|No| on_finalize
109///     on_idle --> on_finalize
110/// ```
111pub mod block_flowchart {}
112
113#[cfg(test)]
114mod tests;
115
116extern crate alloc;
117
118use codec::{Codec, Encode};
119use core::marker::PhantomData;
120use frame_support::{
121	defensive_assert,
122	dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo},
123	migrations::MultiStepMigrator,
124	pallet_prelude::InvalidTransaction,
125	traits::{
126		BeforeAllRuntimeMigrations, ExecuteBlock, Get, IsInherent, OffchainWorker, OnFinalize,
127		OnIdle, OnInitialize, OnPoll, OnRuntimeUpgrade, PostInherents, PostTransactions,
128		PreInherents,
129	},
130	weights::{Weight, WeightMeter},
131	MAX_EXTRINSIC_DEPTH,
132};
133use frame_system::pallet_prelude::BlockNumberFor;
134use sp_runtime::{
135	generic::Digest,
136	traits::{
137		self, Applyable, CheckEqual, Checkable, Dispatchable, Header, LazyBlock, NumberFor, One,
138		ValidateUnsigned, Zero,
139	},
140	transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
141	ApplyExtrinsicResult, ExtrinsicInclusionMode,
142};
143
144#[cfg(feature = "try-runtime")]
145use ::{
146	frame_support::{
147		traits::{TryDecodeEntireStorage, TryDecodeEntireStorageError, TryState},
148		StorageNoopGuard,
149	},
150	frame_try_runtime::{TryStateSelect, UpgradeCheckSelect},
151	log,
152	sp_runtime::TryRuntimeError,
153};
154
155#[allow(dead_code)]
156const LOG_TARGET: &str = "runtime::executive";
157
158pub type CheckedOf<E, C> = <E as Checkable<C>>::Checked;
159pub type CallOf<E, C> = <CheckedOf<E, C> as Applyable>::Call;
160pub type OriginOf<E, C> = <CallOf<E, C> as Dispatchable>::RuntimeOrigin;
161
162/// Configuration for try-runtime upgrade checks.
163#[cfg(feature = "try-runtime")]
164#[derive(Debug, Clone)]
165pub struct TryRuntimeUpgradeConfig {
166	/// Whether to execute `pre/post_upgrade` and `try_state` hooks.
167	pub checks: UpgradeCheckSelect,
168	/// Which pallets' try_state hooks to execute.
169	pub try_state_select: TryStateSelect,
170}
171
172#[cfg(feature = "try-runtime")]
173impl TryRuntimeUpgradeConfig {
174	/// Create a new config with default settings (run all checks for all pallets).
175	pub fn new(checks: UpgradeCheckSelect) -> Self {
176		Self { checks, try_state_select: TryStateSelect::All }
177	}
178
179	/// Set which pallets' try_state hooks to execute.
180	pub fn with_try_state_select(mut self, try_state_select: TryStateSelect) -> Self {
181		self.try_state_select = try_state_select;
182		self
183	}
184}
185
186#[derive(PartialEq)]
187pub enum ExecutiveError {
188	UnableToDecodeExtrinsic,
189	InvalidInherentPosition(usize),
190	OnlyInherentsAllowed,
191	ApplyExtrinsic(TransactionValidityError),
192	Custom(&'static str),
193}
194
195impl core::fmt::Debug for ExecutiveError {
196	fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
197		match self {
198			ExecutiveError::UnableToDecodeExtrinsic =>
199				write!(fmt, "The extrinsic could not be decoded correctly"),
200			ExecutiveError::InvalidInherentPosition(i) =>
201				write!(fmt, "Invalid inherent position for extrinsic at index {}", i),
202			ExecutiveError::OnlyInherentsAllowed =>
203				write!(fmt, "Only inherents are allowed in this block"),
204			ExecutiveError::ApplyExtrinsic(e) => write!(
205				fmt,
206				"ExecuteBlockError applying extrinsic: {}",
207				Into::<&'static str>::into(*e)
208			),
209			ExecutiveError::Custom(err) => write!(fmt, "{err}"),
210		}
211	}
212}
213
214/// Main entry point for certain runtime actions as e.g. `execute_block`.
215///
216/// Generic parameters:
217/// - `System`: Something that implements `frame_system::Config`
218/// - `Block`: The block type of the runtime
219/// - `Context`: The context that is used when checking an extrinsic.
220/// - `UnsignedValidator`: The unsigned transaction validator of the runtime.
221/// - `AllPalletsWithSystem`: Tuple that contains all pallets including frame system pallet. Will be
222///   used to call hooks e.g. `on_initialize`.
223/// - [**DEPRECATED** `OnRuntimeUpgrade`]: This parameter is deprecated and will be removed after
224///   September 2026. Use type `SingleBlockMigrations` in frame_system::Config instead.
225#[allow(deprecated)]
226pub struct Executive<
227	System,
228	Block,
229	Context,
230	UnsignedValidator,
231	AllPalletsWithSystem,
232	OnRuntimeUpgrade = (),
233>(
234	PhantomData<(
235		System,
236		Block,
237		Context,
238		UnsignedValidator,
239		AllPalletsWithSystem,
240		OnRuntimeUpgrade,
241	)>,
242);
243
244/// TODO: The `OnRuntimeUpgrade` generic parameter in `Executive` is deprecated and will be
245/// removed in a future version. Once removed, this `#[allow(deprecated)]` attribute
246/// can be safely deleted.
247#[allow(deprecated)]
248impl<
249		System: frame_system::Config + IsInherent<Block::Extrinsic>,
250		Block: traits::Block<
251			Header = frame_system::pallet_prelude::HeaderFor<System>,
252			Hash = System::Hash,
253		>,
254		Context: Default,
255		UnsignedValidator,
256		AllPalletsWithSystem: OnRuntimeUpgrade
257			+ BeforeAllRuntimeMigrations
258			+ OnInitializeWithWeightRegistration<System>
259			+ OnIdle<BlockNumberFor<System>>
260			+ OnFinalize<BlockNumberFor<System>>
261			+ OffchainWorker<BlockNumberFor<System>>
262			+ OnPoll<BlockNumberFor<System>>,
263		COnRuntimeUpgrade: OnRuntimeUpgrade,
264	> ExecuteBlock<Block>
265	for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
266where
267	Block::Extrinsic: Checkable<Context> + Codec,
268	CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
269	CallOf<Block::Extrinsic, Context>:
270		Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
271	OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
272	UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
273{
274	fn verify_and_remove_seal(_: &mut <Block as traits::Block>::LazyBlock) {
275		// Nothing to do here.
276	}
277
278	fn execute_verified_block(block: Block::LazyBlock) {
279		Executive::<
280			System,
281			Block,
282			Context,
283			UnsignedValidator,
284			AllPalletsWithSystem,
285			COnRuntimeUpgrade,
286		>::execute_block(block);
287	}
288}
289
290/// TODO: The `OnRuntimeUpgrade` generic parameter in `Executive` is deprecated and will be
291/// removed in a future version. Once removed, this `#[allow(deprecated)]` attribute
292/// can be safely deleted.
293#[allow(deprecated)]
294#[cfg(feature = "try-runtime")]
295impl<
296		System: frame_system::Config + IsInherent<Block::Extrinsic>,
297		Block: traits::Block<
298			Header = frame_system::pallet_prelude::HeaderFor<System>,
299			Hash = System::Hash,
300		>,
301		Context: Default,
302		UnsignedValidator,
303		AllPalletsWithSystem: OnRuntimeUpgrade
304			+ BeforeAllRuntimeMigrations
305			+ OnInitializeWithWeightRegistration<System>
306			+ OnIdle<BlockNumberFor<System>>
307			+ OnFinalize<BlockNumberFor<System>>
308			+ OffchainWorker<BlockNumberFor<System>>
309			+ OnPoll<BlockNumberFor<System>>
310			+ TryState<BlockNumberFor<System>>
311			+ TryDecodeEntireStorage,
312		COnRuntimeUpgrade: OnRuntimeUpgrade,
313	> Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
314where
315	Block::Extrinsic: Checkable<Context> + Codec,
316	CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
317	CallOf<Block::Extrinsic, Context>:
318		Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
319	OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
320	UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
321{
322	/// Execute given block, but don't as strict is the normal block execution.
323	///
324	/// Some checks can be disabled via:
325	///
326	/// - `state_root_check`
327	/// - `signature_check`
328	///
329	/// Should only be used for testing ONLY.
330	pub fn try_execute_block(
331		block: Block::LazyBlock,
332		state_root_check: bool,
333		signature_check: bool,
334		select: frame_try_runtime::TryStateSelect,
335	) -> Result<Weight, ExecutiveError> {
336		log::info!(
337			target: LOG_TARGET,
338			"try-runtime: executing block #{:?} / state root check: {:?} / signature check: {:?} / try-state-select: {:?}",
339			block.header().number(),
340			state_root_check,
341			signature_check,
342			select,
343		);
344
345		let mode = Self::initialize_block(block.header());
346		Self::initial_checks(block.header());
347
348		// Apply extrinsics:
349		let signature_check = if signature_check {
350			Block::Extrinsic::check
351		} else {
352			Block::Extrinsic::unchecked_into_checked_i_know_what_i_am_doing
353		};
354		Self::apply_extrinsics(mode, block.extrinsics(), |uxt, is_inherent| {
355			Self::do_apply_extrinsic(uxt, is_inherent, signature_check)
356		})?;
357
358		// In this case there were no transactions to trigger this state transition:
359		if !<frame_system::Pallet<System>>::inherents_applied() {
360			Self::inherents_applied();
361		}
362
363		// post-extrinsics book-keeping
364		<frame_system::Pallet<System>>::note_finished_extrinsics();
365		<System as frame_system::Config>::PostTransactions::post_transactions();
366
367		let header = block.header();
368		Self::on_idle_hook(*header.number());
369		Self::on_finalize_hook(*header.number());
370
371		// run the try-state checks of all pallets, ensuring they don't alter any state.
372		let _guard = frame_support::StorageNoopGuard::default();
373		<AllPalletsWithSystem as frame_support::traits::TryState<
374			BlockNumberFor<System>,
375		>>::try_state(*header.number(), select.clone())
376		.map_err(|e| {
377			log::error!(target: LOG_TARGET, "failure: {:?}", e);
378			ExecutiveError::Custom(e.into())
379		})?;
380		if select.any() {
381			let res = AllPalletsWithSystem::try_decode_entire_state();
382			Self::log_decode_result(res).map_err(|e| ExecutiveError::Custom(e.into()))?;
383		}
384		drop(_guard);
385
386		// do some of the checks that would normally happen in `final_checks`, but perhaps skip
387		// the state root check.
388		{
389			let new_header = <frame_system::Pallet<System>>::finalize();
390			let items_zip = header.digest().logs().iter().zip(new_header.digest().logs().iter());
391			for (header_item, computed_item) in items_zip {
392				header_item.check_equal(computed_item);
393				assert!(header_item == computed_item, "Digest item must match that calculated.");
394			}
395
396			if state_root_check {
397				let storage_root = new_header.state_root();
398				header.state_root().check_equal(storage_root);
399				assert!(
400					header.state_root() == storage_root,
401					"Storage root must match that calculated."
402				);
403			}
404
405			assert!(
406				header.extrinsics_root() == new_header.extrinsics_root(),
407				"Transaction trie root must be valid.",
408			);
409		}
410
411		log::info!(
412			target: LOG_TARGET,
413			"try-runtime: Block #{:?} successfully executed",
414			header.number(),
415		);
416
417		Ok(frame_system::Pallet::<System>::block_weight().total())
418	}
419
420	/// Execute all Migrations of this runtime.
421	///
422	/// The `checks` param determines whether to execute `pre/post_upgrade` and `try_state` hooks.
423	///
424	/// [`frame_system::LastRuntimeUpgrade`] is set to the current runtime version after
425	/// migrations execute. This is important for idempotency checks, because some migrations use
426	/// this value to determine whether or not they should execute.
427	///
428	/// This function runs `try_state` hooks for all pallets. Use
429	/// [`Self::try_runtime_upgrade_with_config`] if you need more control over which pallets'
430	/// `try_state` hooks to execute.
431	pub fn try_runtime_upgrade(checks: UpgradeCheckSelect) -> Result<Weight, TryRuntimeError> {
432		Self::try_runtime_upgrade_with_config(TryRuntimeUpgradeConfig::new(checks))
433	}
434
435	/// Execute all Migrations of this runtime with custom configuration.
436	///
437	/// This function provides more granular control over runtime upgrade testing compared to
438	/// [`Self::try_runtime_upgrade`]. Use [`TryRuntimeUpgradeConfig`] to specify which checks
439	/// to run and which pallets' try_state hooks to execute.
440	///
441	/// [`frame_system::LastRuntimeUpgrade`] is set to the current runtime version after
442	/// migrations execute. This is important for idempotency checks, because some migrations use
443	/// this value to determine whether or not they should execute.
444	pub fn try_runtime_upgrade_with_config(
445		config: TryRuntimeUpgradeConfig,
446	) -> Result<Weight, TryRuntimeError> {
447		let checks = config.checks;
448		let try_state_select = config.try_state_select;
449		let before_all_weight =
450			<AllPalletsWithSystem as BeforeAllRuntimeMigrations>::before_all_runtime_migrations();
451
452		let try_on_runtime_upgrade_weight =
453			<(
454				COnRuntimeUpgrade,
455				<System as frame_system::Config>::SingleBlockMigrations,
456				// We want to run the migrations before we call into the pallets as they may
457				// access any state that would then not be migrated.
458				AllPalletsWithSystem,
459			) as OnRuntimeUpgrade>::try_on_runtime_upgrade(checks.pre_and_post())?;
460
461		frame_system::LastRuntimeUpgrade::<System>::put(
462			frame_system::LastRuntimeUpgradeInfo::from(
463				<System::Version as frame_support::traits::Get<_>>::get(),
464			),
465		);
466
467		// Nothing should modify the state after the migrations ran:
468		let _guard = StorageNoopGuard::default();
469
470		// The state must be decodable:
471		if checks.any() {
472			let res = AllPalletsWithSystem::try_decode_entire_state();
473			Self::log_decode_result(res)?;
474		}
475
476		// Check all storage invariants:
477		if checks.try_state() {
478			AllPalletsWithSystem::try_state(
479				frame_system::Pallet::<System>::block_number(),
480				try_state_select,
481			)?;
482		}
483
484		Ok(before_all_weight.saturating_add(try_on_runtime_upgrade_weight))
485	}
486
487	/// Logs the result of trying to decode the entire state.
488	fn log_decode_result(
489		res: Result<usize, alloc::vec::Vec<TryDecodeEntireStorageError>>,
490	) -> Result<(), TryRuntimeError> {
491		match res {
492			Ok(bytes) => {
493				log::info!(
494					target: LOG_TARGET,
495					"✅ Entire runtime state decodes without error. {} bytes total.",
496					bytes
497				);
498
499				Ok(())
500			},
501			Err(errors) => {
502				log::error!(
503					target: LOG_TARGET,
504					"`try_decode_entire_state` failed with {} errors",
505					errors.len(),
506				);
507
508				for (i, err) in errors.iter().enumerate() {
509					// We log the short version to `error` and then the full debug info to `debug`:
510					log::error!(target: LOG_TARGET, "- {i}. error: {err}");
511					log::debug!(target: LOG_TARGET, "- {i}. error: {err:?}");
512				}
513
514				Err("`try_decode_entire_state` failed".into())
515			},
516		}
517	}
518}
519
520/// Extension trait for [`OnInitialize`].
521///
522/// It takes care to register the weight of each pallet directly after executing its
523/// `on_initialize`.
524///
525/// The trait is sealed.
526pub trait OnInitializeWithWeightRegistration<T: frame_system::Config> {
527	/// The actual logic that calls `on_initialize` and registers the weight.
528	fn on_initialize_with_weight_registration(_n: BlockNumberFor<T>) -> Weight;
529}
530
531frame_support::impl_for_tuples_attr! {
532	#[tuple_types_custom_trait_bound(OnInitialize<frame_system::pallet_prelude::BlockNumberFor<T>>)]
533	impl<T: frame_system::Config> OnInitializeWithWeightRegistration<T> for Tuple {
534		fn on_initialize_with_weight_registration(n: BlockNumberFor<T>) -> Weight {
535			let mut weight = Weight::zero();
536			for_tuples!( #(
537				let individual_weight = Tuple::on_initialize(n);
538
539				<frame_system::Pallet<T>>::register_extra_weight_unchecked(
540					individual_weight,
541					DispatchClass::Mandatory,
542				);
543
544				weight = weight.saturating_add(individual_weight);
545			)* );
546
547			weight
548		}
549	}
550}
551
552/// TODO: The `OnRuntimeUpgrade` generic parameter in `Executive` is deprecated and will be
553/// removed in a future version. Once removed, this `#[allow(deprecated)]` attribute
554/// can be safely deleted.
555#[allow(deprecated)]
556impl<
557		System: frame_system::Config + IsInherent<Block::Extrinsic>,
558		Block: traits::Block<
559			Header = frame_system::pallet_prelude::HeaderFor<System>,
560			Hash = System::Hash,
561		>,
562		Context: Default,
563		UnsignedValidator,
564		AllPalletsWithSystem: OnRuntimeUpgrade
565			+ BeforeAllRuntimeMigrations
566			+ OnInitializeWithWeightRegistration<System>
567			+ OnIdle<BlockNumberFor<System>>
568			+ OnFinalize<BlockNumberFor<System>>
569			+ OffchainWorker<BlockNumberFor<System>>
570			+ OnPoll<BlockNumberFor<System>>,
571		COnRuntimeUpgrade: OnRuntimeUpgrade,
572	> Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
573where
574	Block::Extrinsic: Checkable<Context> + Codec,
575	CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
576	CallOf<Block::Extrinsic, Context>:
577		Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
578	OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
579	UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
580{
581	/// Execute all `OnRuntimeUpgrade` of this runtime, and return the aggregate weight.
582	pub fn execute_on_runtime_upgrade() -> Weight {
583		let before_all_weight =
584			<AllPalletsWithSystem as BeforeAllRuntimeMigrations>::before_all_runtime_migrations();
585
586		let runtime_upgrade_weight = <(
587			COnRuntimeUpgrade,
588			<System as frame_system::Config>::SingleBlockMigrations,
589			// We want to run the migrations before we call into the pallets as they may
590			// access any state that would then not be migrated.
591			AllPalletsWithSystem,
592		) as OnRuntimeUpgrade>::on_runtime_upgrade();
593
594		before_all_weight.saturating_add(runtime_upgrade_weight)
595	}
596
597	/// Start the execution of a particular block.
598	pub fn initialize_block(
599		header: &frame_system::pallet_prelude::HeaderFor<System>,
600	) -> ExtrinsicInclusionMode {
601		sp_io::init_tracing();
602		sp_tracing::enter_span!(sp_tracing::Level::TRACE, "init_block");
603		let digests = Self::extract_pre_digest(header);
604		Self::initialize_block_impl(header.number(), header.parent_hash(), &digests);
605
606		Self::extrinsic_mode()
607	}
608
609	fn extrinsic_mode() -> ExtrinsicInclusionMode {
610		if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
611			ExtrinsicInclusionMode::OnlyInherents
612		} else {
613			ExtrinsicInclusionMode::AllExtrinsics
614		}
615	}
616
617	fn extract_pre_digest(header: &frame_system::pallet_prelude::HeaderFor<System>) -> Digest {
618		let mut digest = <Digest>::default();
619		header.digest().logs().iter().for_each(|d| {
620			if d.as_pre_runtime().is_some() {
621				digest.push(d.clone())
622			}
623		});
624		digest
625	}
626
627	fn initialize_block_impl(
628		block_number: &BlockNumberFor<System>,
629		parent_hash: &System::Hash,
630		digest: &Digest,
631	) {
632		// Reset events before apply runtime upgrade hook.
633		// This is required to preserve events from runtime upgrade hook.
634		// This means the format of all the event related storage must always be compatible.
635		<frame_system::Pallet<System>>::reset_events();
636
637		let mut weight = Weight::zero();
638		if Self::runtime_upgraded() {
639			weight = weight.saturating_add(Self::execute_on_runtime_upgrade());
640
641			frame_system::LastRuntimeUpgrade::<System>::put(
642				frame_system::LastRuntimeUpgradeInfo::from(
643					<System::Version as frame_support::traits::Get<_>>::get(),
644				),
645			);
646		}
647		<frame_system::Pallet<System>>::initialize(block_number, parent_hash, digest);
648
649		weight = System::BlockWeights::get().base_block.saturating_add(weight);
650		// Register the base block weight and optional `on_runtime_upgrade` weight.
651		<frame_system::Pallet<System>>::register_extra_weight_unchecked(
652			weight,
653			DispatchClass::Mandatory,
654		);
655
656		weight = weight
657			.saturating_add(<AllPalletsWithSystem as OnInitializeWithWeightRegistration<
658			System,
659		>>::on_initialize_with_weight_registration(*block_number));
660
661		log::debug!(
662			target: LOG_TARGET,
663			"[{block_number:?}]: Block initialization weight consumption: {weight:?}",
664		);
665
666		frame_system::Pallet::<System>::note_finished_initialize();
667		<System as frame_system::Config>::PreInherents::pre_inherents();
668	}
669
670	/// Returns if the runtime has been upgraded, based on [`frame_system::LastRuntimeUpgrade`].
671	fn runtime_upgraded() -> bool {
672		let last = frame_system::LastRuntimeUpgrade::<System>::get();
673		let current = <System::Version as frame_support::traits::Get<_>>::get();
674
675		last.map(|v| v.was_upgraded(&current)).unwrap_or(true)
676	}
677
678	fn initial_checks(header: &Block::Header) {
679		sp_tracing::enter_span!(sp_tracing::Level::TRACE, "initial_checks");
680
681		// Check that `parent_hash` is correct.
682		let n = *header.number();
683		assert!(
684			n > BlockNumberFor::<System>::zero() &&
685				<frame_system::Pallet<System>>::block_hash(n - BlockNumberFor::<System>::one()) ==
686					*header.parent_hash(),
687			"Parent hash should be valid.",
688		);
689	}
690
691	/// Actually execute all transitions for `block`.
692	pub fn execute_block(block: Block::LazyBlock) {
693		sp_io::init_tracing();
694		sp_tracing::within_span! {
695			sp_tracing::info_span!("execute_block", ?block);
696			// Execute `on_runtime_upgrade` and `on_initialize`.
697			let mode = Self::initialize_block(block.header());
698			Self::initial_checks(block.header());
699
700			let extrinsics = block.extrinsics();
701			if let Err(e) = Self::apply_extrinsics(
702				mode,
703				extrinsics,
704				|uxt, is_inherent| {
705					Self::do_apply_extrinsic(uxt, is_inherent, Block::Extrinsic::check)
706				}
707			) {
708				panic!("{:?}", e)
709			}
710
711			// In this case there were no transactions to trigger this state transition:
712			if !<frame_system::Pallet<System>>::inherents_applied() {
713				Self::inherents_applied();
714			}
715
716			<frame_system::Pallet<System>>::note_finished_extrinsics();
717			<System as frame_system::Config>::PostTransactions::post_transactions();
718
719			let header = block.header();
720			Self::on_idle_hook(*header.number());
721			Self::on_finalize_hook(*header.number());
722			Self::final_checks(&header);
723		}
724	}
725
726	/// Logic that runs directly after inherent application.
727	///
728	/// It advances the Multi-Block-Migrations or runs the `on_poll` hook.
729	pub fn inherents_applied() {
730		<frame_system::Pallet<System>>::note_inherents_applied();
731		<System as frame_system::Config>::PostInherents::post_inherents();
732
733		if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
734			let used_weight = <System as frame_system::Config>::MultiBlockMigrator::step();
735			<frame_system::Pallet<System>>::register_extra_weight_unchecked(
736				used_weight,
737				DispatchClass::Mandatory,
738			);
739		} else {
740			let block_number = <frame_system::Pallet<System>>::block_number();
741			Self::on_poll_hook(block_number);
742		}
743	}
744
745	/// Execute given extrinsics.
746	fn apply_extrinsics(
747		mode: ExtrinsicInclusionMode,
748		extrinsics: impl Iterator<Item = Result<Block::Extrinsic, codec::Error>>,
749		mut apply_extrinsic: impl FnMut(Block::Extrinsic, bool) -> ApplyExtrinsicResult,
750	) -> Result<(), ExecutiveError> {
751		let mut first_non_inherent_idx = 0;
752		for (idx, maybe_uxt) in extrinsics.into_iter().enumerate() {
753			let uxt = maybe_uxt.map_err(|_| ExecutiveError::UnableToDecodeExtrinsic)?;
754			let is_inherent = System::is_inherent(&uxt);
755			if is_inherent {
756				// Check if inherents are first
757				if first_non_inherent_idx != idx {
758					return Err(ExecutiveError::InvalidInherentPosition(idx));
759				}
760				first_non_inherent_idx += 1;
761			} else {
762				// Check if there are any forbidden non-inherents in the block.
763				if mode == ExtrinsicInclusionMode::OnlyInherents {
764					return Err(ExecutiveError::OnlyInherentsAllowed)
765				}
766			}
767
768			log::debug!(target: LOG_TARGET, "Executing transaction: {:?}", uxt);
769			if let Err(e) = apply_extrinsic(uxt, is_inherent) {
770				log::error!(
771					target: LOG_TARGET,
772					"Transaction({idx}) failed due to {e:?}. \
773					Aborting the rest of the block execution.",
774				);
775				return Err(ExecutiveError::ApplyExtrinsic(e.into()));
776			}
777		}
778
779		Ok(())
780	}
781
782	/// Finalize the block - it is up the caller to ensure that all header fields are valid
783	/// except state-root.
784	// Note: Only used by the block builder - not Executive itself.
785	pub fn finalize_block() -> frame_system::pallet_prelude::HeaderFor<System> {
786		sp_io::init_tracing();
787		sp_tracing::enter_span!(sp_tracing::Level::TRACE, "finalize_block");
788
789		// In this case there were no transactions to trigger this state transition:
790		if !<frame_system::Pallet<System>>::inherents_applied() {
791			Self::inherents_applied();
792		}
793
794		<frame_system::Pallet<System>>::note_finished_extrinsics();
795		<System as frame_system::Config>::PostTransactions::post_transactions();
796		let block_number = <frame_system::Pallet<System>>::block_number();
797		Self::on_idle_hook(block_number);
798		Self::on_finalize_hook(block_number);
799		<frame_system::Pallet<System>>::finalize()
800	}
801
802	/// Run the `on_idle` hook of all pallet, but only if there is weight remaining and there are no
803	/// ongoing MBMs.
804	fn on_idle_hook(block_number: NumberFor<Block>) {
805		if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
806			return
807		}
808
809		let weight = <frame_system::Pallet<System>>::block_weight();
810		let max_weight = <System::BlockWeights as frame_support::traits::Get<_>>::get().max_block;
811		let remaining_weight = max_weight.saturating_sub(weight.total());
812
813		if remaining_weight.all_gt(Weight::zero()) {
814			let used_weight = <AllPalletsWithSystem as OnIdle<BlockNumberFor<System>>>::on_idle(
815				block_number,
816				remaining_weight,
817			);
818			<frame_system::Pallet<System>>::register_extra_weight_unchecked(
819				used_weight,
820				DispatchClass::Mandatory,
821			);
822		}
823	}
824
825	fn on_poll_hook(block_number: NumberFor<Block>) {
826		defensive_assert!(
827			!<System as frame_system::Config>::MultiBlockMigrator::ongoing(),
828			"on_poll should not be called during migrations"
829		);
830
831		let weight = <frame_system::Pallet<System>>::block_weight();
832		let max_weight = <System::BlockWeights as frame_support::traits::Get<_>>::get().max_block;
833		let remaining = max_weight.saturating_sub(weight.total());
834
835		if remaining.all_gt(Weight::zero()) {
836			let mut meter = WeightMeter::with_limit(remaining);
837			<AllPalletsWithSystem as OnPoll<BlockNumberFor<System>>>::on_poll(
838				block_number,
839				&mut meter,
840			);
841			<frame_system::Pallet<System>>::register_extra_weight_unchecked(
842				meter.consumed(),
843				DispatchClass::Mandatory,
844			);
845		}
846	}
847
848	/// Run the `on_finalize` hook of all pallet.
849	fn on_finalize_hook(block_number: NumberFor<Block>) {
850		<AllPalletsWithSystem as OnFinalize<BlockNumberFor<System>>>::on_finalize(block_number);
851	}
852
853	/// Apply extrinsic outside of the block execution function.
854	///
855	/// This doesn't attempt to validate anything regarding the block, but it builds a list of uxt
856	/// hashes.
857	fn do_apply_extrinsic(
858		uxt: Block::Extrinsic,
859		is_inherent: bool,
860		check: impl FnOnce(
861			Block::Extrinsic,
862			&Context,
863		) -> Result<CheckedOf<Block::Extrinsic, Context>, TransactionValidityError>,
864	) -> ApplyExtrinsicResult {
865		sp_io::init_tracing();
866		let encoded = uxt.encode();
867		let encoded_len = encoded.len();
868		sp_tracing::enter_span!(sp_tracing::info_span!("apply_extrinsic",
869			ext=?sp_core::hexdisplay::HexDisplay::from(&encoded)));
870
871		let uxt = <Block::Extrinsic as codec::DecodeLimit>::decode_all_with_depth_limit(
872			MAX_EXTRINSIC_DEPTH,
873			&mut &encoded[..],
874		)
875		.map_err(|_| InvalidTransaction::Call)?;
876
877		// Verify that the signature is good.
878		let xt = check(uxt, &Context::default())?;
879
880		let dispatch_info = xt.get_dispatch_info();
881
882		if !is_inherent && !<frame_system::Pallet<System>>::inherents_applied() {
883			Self::inherents_applied();
884		}
885
886		// We don't need to make sure to `note_extrinsic` only after we know it's going to be
887		// executed to prevent it from leaking in storage since at this point, it will either
888		// execute or panic (and revert storage changes).
889		<frame_system::Pallet<System>>::note_extrinsic(encoded);
890
891		// AUDIT: Under no circumstances may this function panic from here onwards.
892
893		let r = Applyable::apply::<UnsignedValidator>(xt, &dispatch_info, encoded_len)?;
894
895		// Mandatory(inherents) are not allowed to fail.
896		//
897		// The entire block should be discarded if an inherent fails to apply. Otherwise
898		// it may open an attack vector.
899		if r.is_err() && dispatch_info.class == DispatchClass::Mandatory {
900			return Err(InvalidTransaction::BadMandatory.into())
901		}
902
903		<frame_system::Pallet<System>>::note_applied_extrinsic(&r, dispatch_info);
904
905		Ok(r.map(|_| ()).map_err(|e| e.error))
906	}
907
908	/// Apply extrinsic outside of the block execution function.
909	///
910	/// This doesn't attempt to validate anything regarding the block, but it builds a list of uxt
911	/// hashes.
912	pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyExtrinsicResult {
913		let is_inherent = System::is_inherent(&uxt);
914		Self::do_apply_extrinsic(uxt, is_inherent, Block::Extrinsic::check)
915	}
916
917	fn final_checks(header: &frame_system::pallet_prelude::HeaderFor<System>) {
918		sp_tracing::enter_span!(sp_tracing::Level::TRACE, "final_checks");
919		// remove temporaries
920		let new_header = <frame_system::Pallet<System>>::finalize();
921
922		// check digest
923		assert_eq!(
924			header.digest().logs().len(),
925			new_header.digest().logs().len(),
926			"Number of digest items must match that calculated."
927		);
928		let items_zip = header.digest().logs().iter().zip(new_header.digest().logs().iter());
929		for (header_item, computed_item) in items_zip {
930			header_item.check_equal(computed_item);
931			assert!(header_item == computed_item, "Digest item must match that calculated.");
932		}
933
934		// check storage root.
935		let storage_root = new_header.state_root();
936		header.state_root().check_equal(storage_root);
937		assert!(header.state_root() == storage_root, "Storage root must match that calculated.");
938
939		assert!(
940			header.extrinsics_root() == new_header.extrinsics_root(),
941			"Transaction trie root must be valid.",
942		);
943	}
944
945	/// Check a given signed transaction for validity. This doesn't execute any
946	/// side-effects; it merely checks whether the transaction would panic if it were included or
947	/// not.
948	///
949	/// Changes made to storage should be discarded.
950	pub fn validate_transaction(
951		source: TransactionSource,
952		uxt: Block::Extrinsic,
953		block_hash: Block::Hash,
954	) -> TransactionValidity {
955		sp_io::init_tracing();
956		use sp_tracing::{enter_span, within_span};
957
958		<frame_system::Pallet<System>>::initialize(
959			&(frame_system::Pallet::<System>::block_number() + One::one()),
960			&block_hash,
961			&Default::default(),
962		);
963
964		enter_span! { sp_tracing::Level::TRACE, "validate_transaction" };
965
966		let encoded = within_span! { sp_tracing::Level::TRACE, "using_encoded";
967			uxt.encode()
968		};
969
970		let uxt = <Block::Extrinsic as codec::DecodeLimit>::decode_all_with_depth_limit(
971			MAX_EXTRINSIC_DEPTH,
972			&mut &encoded[..],
973		)
974		.map_err(|_| InvalidTransaction::Call)?;
975
976		let xt = within_span! { sp_tracing::Level::TRACE, "check";
977			uxt.check(&Default::default())
978		}?;
979
980		let dispatch_info = within_span! { sp_tracing::Level::TRACE, "dispatch_info";
981			xt.get_dispatch_info()
982		};
983
984		if dispatch_info.class == DispatchClass::Mandatory {
985			return Err(InvalidTransaction::MandatoryValidation.into())
986		}
987
988		within_span! {
989			sp_tracing::Level::TRACE, "validate";
990			xt.validate::<UnsignedValidator>(source, &dispatch_info, encoded.len())
991		}
992	}
993
994	/// Start an offchain worker and generate extrinsics.
995	pub fn offchain_worker(header: &frame_system::pallet_prelude::HeaderFor<System>) {
996		sp_io::init_tracing();
997		// We need to keep events available for offchain workers,
998		// hence we initialize the block manually.
999		// OffchainWorker RuntimeApi should skip initialization.
1000		let digests = header.digest().clone();
1001
1002		// Let's deposit all the logs we are not yet aware of. These are the logs set by the `node`.
1003		let existing_digest = frame_system::Pallet::<System>::digest();
1004		for digest in digests.logs().iter().filter(|d| !existing_digest.logs.contains(d)) {
1005			frame_system::Pallet::<System>::deposit_log(digest.clone());
1006		}
1007
1008		// Initialize the intra block entropy, which is maybe used by offchain workers.
1009		frame_system::Pallet::<System>::initialize_intra_block_entropy(header.parent_hash());
1010
1011		// Frame system only inserts the parent hash into the block hashes as normally we don't know
1012		// the hash for the header before. However, here we are aware of the hash and we can add it
1013		// as well.
1014		frame_system::BlockHash::<System>::insert(header.number(), header.hash());
1015
1016		<AllPalletsWithSystem as OffchainWorker<BlockNumberFor<System>>>::offchain_worker(
1017			*header.number(),
1018		)
1019	}
1020}