Do not call initialize_block before any runtime api (#8953)

* Do not call `initialize_block` before any runtime api

Before this change we always called `initialize_block` before calling
into the runtime. There was already support with `skip_initialize` to skip
the initialization. Almost no runtime_api requires that
`initialize_block` is called before. Actually this only leads to higher
execution times most of the time, because all runtime modules are
initialized and this is especially expensive when the block contained a
runtime upgrade.

TLDR: Do not call `initialize_block` before calling a runtime api.

* Change `validate_transaction` interface

* Fix rpc test

* Fixes and comments

* Some docs
This commit is contained in:
Bastian Köcher
2021-07-01 17:50:42 +02:00
committed by GitHub
parent 73a6e3effc
commit d489bd70b5
23 changed files with 192 additions and 301 deletions
@@ -15,11 +15,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use sp_api::ProvideRuntimeApi;
use sp_api::{ProvideRuntimeApi, Core};
use substrate_test_runtime_client::{
prelude::*,
DefaultTestClientBuilderExt, TestClientBuilder,
runtime::{TestAPI, DecodeFails, Transfer, Block},
runtime::{TestAPI, DecodeFails, Transfer, Block, Header},
};
use sp_runtime::{generic::BlockId, traits::{Header as HeaderT, HashFor}};
use sp_state_machine::{
@@ -133,26 +133,13 @@ fn initialize_block_works() {
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
runtime_api.initialize_block(
&block_id,
&Header::new(1, Default::default(), Default::default(), Default::default(), Default::default()),
).unwrap();
assert_eq!(runtime_api.get_block_number(&block_id).unwrap(), 1);
}
#[test]
fn initialize_block_is_called_only_once() {
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
assert_eq!(runtime_api.take_block_number(&block_id).unwrap(), Some(1));
assert_eq!(runtime_api.take_block_number(&block_id).unwrap(), None);
}
#[test]
fn initialize_block_is_skipped() {
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
assert!(runtime_api.without_initialize_block(&block_id).unwrap());
}
#[test]
fn record_proof_works() {
let (client, longest_chain) = TestClientBuilder::new()