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