Move create_inherents into the block-builder (#6553)

* Move `create_inherents` into the block-builder

This moves the `create_inherents` call into the block-builder. This has
the advantage that `create_inherents` will be able to reuse the same
context that will be used when applying the extrinsics and we also save
one call to `on_initialize`. To make sure that `create_inherents` does
not modify any state, we execute it in a transaction that is
rolled-back after doing the runtime call.

* Feedback and build fix

* Update primitives/runtime/src/lib.rs

Co-authored-by: Sergei Shulepov <sergei@parity.io>

* Update client/block-builder/src/lib.rs

Co-authored-by: Sergei Shulepov <sergei@parity.io>
This commit is contained in:
Bastian Köcher
2020-07-02 15:17:14 +02:00
committed by GitHub
parent e1d0f84c67
commit 4f7f312be5
9 changed files with 78 additions and 48 deletions
+33 -6
View File
@@ -34,7 +34,10 @@ use sp_runtime::{
};
use sp_blockchain::{ApplyExtrinsicFailed, Error};
use sp_core::ExecutionContext;
use sp_api::{Core, ApiExt, ApiErrorFor, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof};
use sp_api::{
Core, ApiExt, ApiErrorFor, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof,
TransactionOutcome,
};
use sp_consensus::RecordProof;
pub use sp_block_builder::BlockBuilder as BlockBuilderApi;
@@ -156,17 +159,22 @@ where
let block_id = &self.block_id;
let extrinsics = &mut self.extrinsics;
self.api.map_api_result(|api| {
self.api.execute_in_transaction(|api| {
match api.apply_extrinsic_with_context(
block_id,
ExecutionContext::BlockConstruction,
xt.clone(),
)? {
Ok(_) => {
) {
Ok(Ok(_)) => {
extrinsics.push(xt);
Ok(())
TransactionOutcome::Commit(Ok(()))
}
Err(tx_validity) => Err(ApplyExtrinsicFailed::Validity(tx_validity).into()),
Ok(Err(tx_validity)) => {
TransactionOutcome::Rollback(
Err(ApplyExtrinsicFailed::Validity(tx_validity).into()),
)
},
Err(e) => TransactionOutcome::Rollback(Err(e)),
}
})
}
@@ -212,6 +220,25 @@ where
proof,
})
}
/// Create the inherents for the block.
///
/// Returns the inherents created by the runtime or an error if something failed.
pub fn create_inherents(
&mut self,
inherent_data: sp_inherents::InherentData,
) -> Result<Vec<Block::Extrinsic>, ApiErrorFor<A, Block>> {
let block_id = self.block_id;
self.api.execute_in_transaction(move |api| {
// `create_inherents` should not change any state, to ensure this we always rollback
// the transaction.
TransactionOutcome::Rollback(api.inherent_extrinsics_with_context(
&block_id,
ExecutionContext::BlockConstruction,
inherent_data
))
})
}
}
#[cfg(test)]