Substrate Developer Hub

Substrate Developer Hub

  • Tutorials
  • Knowledge Base
  • Recipes
  • API Reference
  • Languages iconEnglish
    • 简体中文
    • Help Translate

›Runtime

Getting Started

  • Overview
  • Installation
  • Getting Started on Windows
  • Glossary

Learn Substrate

  • Extrinsics
  • Transaction Pool
  • Account Abstractions
  • Session Keys
  • Transaction Weight
  • Off-Chain Features

Runtime

  • Runtime Overview
  • Runtime Primitives
  • FRAME
  • Pallets
  • Runtime Macros
  • Runtime Metadata
  • Runtime Storage
  • Runtime Origin
  • Runtime Execution
  • Runtime Events
  • Runtime Errors
  • Transaction Fees
  • Off-Chain Workers
  • Debugging
  • Runtime Tests
  • On-Chain Randomness
  • Runtime Upgrades

Smart Contracts

  • Overview
  • ink! Smart Contracts
  • ink! Concepts
  • ink! Development
  • EVM Pallet
  • ink! F.A.Q.

Integrate

  • Polkadot-JS
  • Client Libraries
  • Chain Specification
  • The Subkey Tool
  • Memory Profiling

Advanced

  • SCALE Codec
  • Consensus
  • The Block Import Pipeline
  • Executor
  • Cryptography
  • Storage
  • SS58 Address Format

Contribute

  • Help Translate
Edit

Runtime Execution

The execution of the Substrate runtime is orchestrated by the Executive module.

Unlike the other modules within FRAME, this is not a runtime module. Rather it is a normal Rust module that calls into the various runtime modules included in your blockchain.

The Executive module exposes the execute_block function that:

  • Initializes the block
  • Executes extrinsics
  • Finalizes the block

Validating Transactions

Before block execution begins, signed transactions are checked for validity. This doesn't execute any side-effects; it merely checks whether the transaction would panic if it were included or not. Thus, changes made to storage are discarded.

Executing a Block

Once there is a queue of valid transactions, the Executive module begins to execute the block.

Initializing a Block

To initialize a block, the System module and all other included runtime modules have their on_initialize function called which executes any business logic defined by those modules to take place before transactions are executed. The modules are executed in the order which they are defined in the construct_runtime! macro, but with the System module always executing first.

Then, initial checks take place where the parent hash in the block header is verified to be correct and the extrinsics trie root actually represents the extrinsics.

Executing Extrinsics

After the block has been initialized, each valid extrinsic is executed in order of transaction priority. Extrinsics must not cause a panic in the runtime logic or else the system becomes vulnerable to attacks where users can trigger computational execution without any punishment.

When an extrinsic executes, the state is not cached prior to execution and storage mutations operate directly on storage. Therefore, runtime developers should perform all necessary checks that an extrinsic will succeed before mutating storage. If an extrinsic fails mid-execution, previous storage mutations will not be reverted.

Events that are emitted from an extrinsic are also written to storage. Therefore, you should not emit an event before performing the complementary actions. If an extrinsic fails after an event is emitted, the event will not be reverted.

Finalizing a Block

After all queued extrinsics have been executed, the Executive module calls into each module's on_finalize function to perform any final business logic which should take place at the end of the block. The modules are again executed in the order which they are defined in the construct_runtime! macro, but in this case, the System module finalizes last.

Then, final checks take place where the digest and storage root in the block header match what was calculated.

Next Steps

Learn More

  • Learn how you can simulate the orchestration of the Executive module in your runtime tests.

References

  • FRAME executive
  • decl_event! macro
  • decl_storage! macro
  • construct_runtime! macro
  • OnInitialize trait
Last updated on 2/24/2021 by Dan Forbes
← Runtime OriginRuntime Events →
  • Validating Transactions
  • Executing a Block
    • Initializing a Block
    • Executing Extrinsics
    • Finalizing a Block
  • Next Steps
    • Learn More
    • References
Substrate Developer Hub
Developer Hub
TutorialsKnowledge BaseRecipesAPI Reference
Community
Community HomeNewsletterSubstrate Technical ChatSubstrate SeminarStack OverflowTwitterEvents
More
Substrate Builders ProgramBlogSubstrate GitHubDeveloper Hub GitHubPrivacy PolicyTerms of UseCookie Settings
Copyright © 2021 Parity Technologies