mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 20:31:13 +00:00
SRML Executive Documentation (#2144)
* executive docs first draft * link updates * gautam update * capitalization * typo fix
This commit is contained in:
committed by
Bastian Köcher
parent
600d0cafaa
commit
29e9273579
@@ -14,7 +14,45 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Executive: Handles all of the top-level stuff; essentially just executing blocks/extrinsics.
|
||||
//! # Executive Module
|
||||
//!
|
||||
//! The Executive module acts as the orchestration layer for the runtime. It dispatches incoming
|
||||
//! extrinsic calls to the respective modules in the runtime.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The executive module is not a typical SRML module providing functionality around a specific feature.
|
||||
//! It is a cross-cutting framework component for the SRML. It works in conjunction with the
|
||||
//! [SRML System module](../srml_system/index.html) to perform these cross-cutting functions.
|
||||
//!
|
||||
//! The Executive module provides functions to:
|
||||
//!
|
||||
//! - Check transaction validity.
|
||||
//! - Initialize a block.
|
||||
//! - Apply extrinsics.
|
||||
//! - Execute a block.
|
||||
//! - Finalize a block.
|
||||
//! - Start an off-chain worker.
|
||||
//!
|
||||
//! ### Implementations
|
||||
//!
|
||||
//! The Executive module provides the following implementations:
|
||||
//!
|
||||
//! - `ExecuteBlock`: Trait that can be used to execute a block.
|
||||
//! - `Executive`: Type that can be used to make the SRML available from the runtime.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! The default Substrate node template declares the [`Executive`](./struct.Executive.html) type in its library.
|
||||
//!
|
||||
//! ### Example
|
||||
//!
|
||||
//! `Executive` type declaration from the node template.
|
||||
//!
|
||||
//! ```ignore
|
||||
//! /// Executive: handles dispatch to the various modules.
|
||||
//! pub type Executive = executive::Executive<Runtime, Block, Context, Balances, AllModules>;
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
@@ -48,9 +86,9 @@ mod internal {
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that can be used to execute a block.
|
||||
/// Trait that can be used to execute a block.
|
||||
pub trait ExecuteBlock<Block: BlockT> {
|
||||
/// Actually execute all transitioning for `block`.
|
||||
/// Actually execute all transitions for `block`.
|
||||
fn execute_block(block: Block);
|
||||
}
|
||||
|
||||
@@ -100,20 +138,20 @@ impl<
|
||||
fn initial_checks(block: &Block) {
|
||||
let header = block.header();
|
||||
|
||||
// check parent_hash is correct.
|
||||
// Check that `parent_hash` is correct.
|
||||
let n = header.number().clone();
|
||||
assert!(
|
||||
n > System::BlockNumber::zero() && <system::Module<System>>::block_hash(n - System::BlockNumber::one()) == *header.parent_hash(),
|
||||
"Parent hash should be valid."
|
||||
);
|
||||
|
||||
// check transaction trie root represents the transactions.
|
||||
// Check that transaction trie root represents the transactions.
|
||||
let xts_root = extrinsics_root::<System::Hashing, _>(&block.extrinsics());
|
||||
header.extrinsics_root().check_equal(&xts_root);
|
||||
assert!(header.extrinsics_root() == &xts_root, "Transaction trie root must be valid.");
|
||||
}
|
||||
|
||||
/// Actually execute all transitioning for `block`.
|
||||
/// Actually execute all transitions for `block`.
|
||||
pub fn execute_block(block: Block) {
|
||||
Self::initialize_block(block.header());
|
||||
|
||||
@@ -128,11 +166,11 @@ impl<
|
||||
Self::final_checks(&header);
|
||||
}
|
||||
|
||||
/// Execute given extrinsics and take care of post-extrinsics book-keeping
|
||||
/// Execute given extrinsics and take care of post-extrinsics book-keeping.
|
||||
fn execute_extrinsics_with_book_keeping(extrinsics: Vec<Block::Extrinsic>, block_number: NumberFor<Block>) {
|
||||
extrinsics.into_iter().for_each(Self::apply_extrinsic_no_note);
|
||||
|
||||
// post-extrinsics book-keeping.
|
||||
// post-extrinsics book-keeping
|
||||
<system::Module<System>>::note_finished_extrinsics();
|
||||
<AllModules as OnFinalize<System::BlockNumber>>::on_finalize(block_number);
|
||||
}
|
||||
@@ -143,7 +181,7 @@ impl<
|
||||
<system::Module<System>>::note_finished_extrinsics();
|
||||
<AllModules as OnFinalize<System::BlockNumber>>::on_finalize(<system::Module<System>>::block_number());
|
||||
|
||||
// setup extrinsics
|
||||
// set up extrinsics
|
||||
<system::Module<System>>::derive_extrinsics();
|
||||
<system::Module<System>>::finalize()
|
||||
}
|
||||
@@ -180,7 +218,7 @@ impl<
|
||||
|
||||
/// Actually apply an extrinsic given its `encoded_len`; this doesn't note its hash.
|
||||
fn apply_extrinsic_with_len(uxt: Block::Extrinsic, encoded_len: usize, to_note: Option<Vec<u8>>) -> result::Result<internal::ApplyOutcome, internal::ApplyError> {
|
||||
// Verify the signature is good.
|
||||
// Verify that the signature is good.
|
||||
let xt = uxt.check(&Default::default()).map_err(internal::ApplyError::BadSignature)?;
|
||||
|
||||
// Check the size of the block if that extrinsic is applied.
|
||||
@@ -195,7 +233,7 @@ impl<
|
||||
if index < &expected_index { internal::ApplyError::Stale } else { internal::ApplyError::Future }
|
||||
) }
|
||||
|
||||
// pay any fees.
|
||||
// pay any fees
|
||||
Payment::make_payment(sender, encoded_len).map_err(|_| internal::ApplyError::CantPay)?;
|
||||
|
||||
// AUDIT: Under no circumstances may this function panic from here onwards.
|
||||
@@ -204,13 +242,13 @@ impl<
|
||||
<system::Module<System>>::inc_account_nonce(sender);
|
||||
}
|
||||
|
||||
// make sure to `note_extrinsic` only after we know it's going to be executed
|
||||
// Make sure to `note_extrinsic` only after we know it's going to be executed
|
||||
// to prevent it from leaking in storage.
|
||||
if let Some(encoded) = to_note {
|
||||
<system::Module<System>>::note_extrinsic(encoded);
|
||||
}
|
||||
|
||||
// decode parameters and dispatch
|
||||
// Decode parameters and dispatch
|
||||
let (f, s) = xt.deconstruct();
|
||||
let r = f.dispatch(s.into());
|
||||
<system::Module<System>>::note_applied_extrinsic(&r, encoded_len as u32);
|
||||
@@ -222,10 +260,10 @@ impl<
|
||||
}
|
||||
|
||||
fn final_checks(header: &System::Header) {
|
||||
// remove temporaries.
|
||||
// remove temporaries
|
||||
let new_header = <system::Module<System>>::finalize();
|
||||
|
||||
// check digest.
|
||||
// check digest
|
||||
assert_eq!(
|
||||
header.digest().logs().len(),
|
||||
new_header.digest().logs().len(),
|
||||
@@ -246,7 +284,7 @@ impl<
|
||||
/// Check a given transaction for validity. This doesn't execute any
|
||||
/// side-effects; it merely checks whether the transaction would panic if it were included or not.
|
||||
///
|
||||
/// Changes made to the storage should be discarded.
|
||||
/// Changes made to storage should be discarded.
|
||||
pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity {
|
||||
// Note errors > 0 are from ApplyError
|
||||
const UNKNOWN_ERROR: i8 = -127;
|
||||
@@ -267,7 +305,7 @@ impl<
|
||||
};
|
||||
|
||||
if let (Some(sender), Some(index)) = (xt.sender(), xt.index()) {
|
||||
// pay any fees.
|
||||
// pay any fees
|
||||
if Payment::make_payment(sender, encoded_len).is_err() {
|
||||
return TransactionValidity::Invalid(ApplyError::CantPay as i8)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user