Make ExecuteBlock::execute_block return the final block header (#8244)

This pr changes the `ExecuteBlock` trait to return the final header that
results from executing the given block.
This commit is contained in:
Bastian Köcher
2021-03-03 09:44:34 +01:00
committed by GitHub
parent dc190a69f2
commit 4de4662480
9 changed files with 48 additions and 37 deletions
+1 -2
View File
@@ -22,7 +22,6 @@ The Executive module provides functions to:
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 FRAME available from the runtime.
## Usage
@@ -58,4 +57,4 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
pub type Executive = executive::Executive<Runtime, Block, Context, Runtime, AllModules, CustomOnRuntimeUpgrade>;
```
License: Apache-2.0
License: Apache-2.0
+13 -17
View File
@@ -119,26 +119,20 @@
use sp_std::{prelude::*, marker::PhantomData};
use frame_support::{
weights::{GetDispatchInfo, DispatchInfo, DispatchClass},
traits::{OnInitialize, OnFinalize, OnRuntimeUpgrade, OffchainWorker},
traits::{OnInitialize, OnFinalize, OnRuntimeUpgrade, OffchainWorker, ExecuteBlock},
dispatch::PostDispatchInfo,
};
use sp_runtime::{
generic::Digest, ApplyExtrinsicResult,
traits::{
self, Header, Zero, One, Checkable, Applyable, CheckEqual, ValidateUnsigned, NumberFor,
Block as BlockT, Dispatchable, Saturating,
Dispatchable, Saturating,
},
transaction_validity::{TransactionValidity, TransactionSource},
};
use codec::{Codec, Encode};
use frame_system::DigestOf;
/// Trait that can be used to execute a block.
pub trait ExecuteBlock<Block: BlockT> {
/// Actually execute all transitions for `block`.
fn execute_block(block: Block);
}
pub type CheckedOf<E, C> = <E as Checkable<C>>::Checked;
pub type CallOf<E, C> = <CheckedOf<E, C> as Applyable>::Call;
pub type OriginOf<E, C> = <CallOf<E, C> as Dispatchable>::Origin;
@@ -180,8 +174,8 @@ where
OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
UnsignedValidator: ValidateUnsigned<Call=CallOf<Block::Extrinsic, Context>>,
{
fn execute_block(block: Block) {
Executive::<System, Block, Context, UnsignedValidator, AllModules>::execute_block(block);
fn execute_block(block: Block) -> Block::Header {
Executive::<System, Block, Context, UnsignedValidator, AllModules>::execute_block(block)
}
}
@@ -318,11 +312,11 @@ where
}
/// Actually execute all transitions for `block`.
pub fn execute_block(block: Block) {
pub fn execute_block(block: Block) -> Block::Header {
sp_io::init_tracing();
sp_tracing::within_span! {
sp_tracing::info_span!( "execute_block", ?block);
{
sp_tracing::info_span!("execute_block", ?block);
Self::initialize_block(block.header());
// any initial checks
@@ -339,8 +333,8 @@ where
}
// any final checks
Self::final_checks(&header);
} };
Self::final_checks(&header)
}
}
/// Execute given extrinsics and take care of post-extrinsics book-keeping.
@@ -412,7 +406,7 @@ where
Ok(r.map(|_| ()).map_err(|e| e.error))
}
fn final_checks(header: &System::Header) {
fn final_checks(header: &System::Header) -> System::Header {
sp_tracing::enter_span!(sp_tracing::Level::TRACE, "final_checks");
// remove temporaries
let new_header = <frame_system::Module<System>>::finalize();
@@ -438,6 +432,8 @@ where
header.extrinsics_root() == new_header.extrinsics_root(),
"Transaction trie root must be valid.",
);
new_header
}
/// Check a given signed transaction for validity. This doesn't execute any
@@ -502,7 +498,7 @@ mod tests {
use sp_core::H256;
use sp_runtime::{
generic::{Era, DigestItem}, DispatchError, testing::{Digest, Header, Block},
traits::{Header as HeaderT, BlakeTwo256, IdentityLookup},
traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, Block as BlockT},
transaction_validity::{
InvalidTransaction, ValidTransaction, TransactionValidityError, UnknownTransaction
},
+20 -3
View File
@@ -26,9 +26,9 @@ use sp_runtime::{
RuntimeAppPublic, RuntimeDebug, BoundToRuntimeAppPublic,
ConsensusEngineId, DispatchResult, DispatchError,
traits::{
MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero,
BadOrigin, AtLeast32BitUnsigned, Convert, UniqueSaturatedFrom, UniqueSaturatedInto,
SaturatedConversion, StoredMapError,
MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero,
BadOrigin, AtLeast32BitUnsigned, Convert, UniqueSaturatedFrom, UniqueSaturatedInto,
SaturatedConversion, StoredMapError, Block as BlockT,
},
};
use sp_staking::SessionIndex;
@@ -2228,6 +2228,23 @@ pub trait GetPalletVersion {
fn storage_version() -> Option<PalletVersion>;
}
/// Something that can execute a given block.
///
/// Executing a block means that all extrinsics in a given block will be executed and the resulting
/// header will be checked against the header of the given block.
pub trait ExecuteBlock<Block: BlockT> {
/// Execute the given `block`.
///
/// This will execute all extrinsics in the block and check that the resulting header is correct.
///
/// Returns the result header.
///
/// # Panic
///
/// Panics when an extrinsics panics or the resulting header doesn't match the expected header.
fn execute_block(block: Block) -> Block::Header;
}
#[cfg(test)]
mod tests {
use super::*;