mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-30 09:37:55 +00:00
ae0210c1cc
* Companion for removal of execution strategies https://github.com/paritytech/substrate/pull/14387 * Update Cargo.lock * Remove patches * Delete file again * update lockfile for {"polkadot", "substrate"} * Fix * FMT --------- Co-authored-by: parity-processbot <>
211 lines
7.1 KiB
Rust
211 lines
7.1 KiB
Rust
// This file is part of Cumulus.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use codec::{Decode, Encode};
|
|
use core::time::Duration;
|
|
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
|
use cumulus_primitives_core::{relay_chain::AccountId, PersistedValidationData, ValidationParams};
|
|
use cumulus_test_client::{
|
|
generate_extrinsic_with_pair, BuildParachainBlockData, Client, InitBlockBuilder,
|
|
ParachainBlockData, TestClientBuilder, ValidationResult,
|
|
};
|
|
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
|
|
use cumulus_test_runtime::{Block, GluttonCall, Header, SudoCall};
|
|
use polkadot_primitives::HeadData;
|
|
use sc_client_api::UsageProvider;
|
|
use sc_consensus::{BlockImport, BlockImportParams, ForkChoiceStrategy, ImportResult, StateAction};
|
|
use sc_executor_common::wasm_runtime::WasmModule;
|
|
use sp_api::ProvideRuntimeApi;
|
|
|
|
use frame_system_rpc_runtime_api::AccountNonceApi;
|
|
use sp_arithmetic::{
|
|
traits::{One, Zero},
|
|
FixedU64,
|
|
};
|
|
use sp_consensus::BlockOrigin;
|
|
use sp_keyring::Sr25519Keyring::Alice;
|
|
use sp_runtime::traits::Header as HeaderT;
|
|
|
|
use cumulus_test_service::bench_utils as utils;
|
|
|
|
async fn import_block(
|
|
mut client: &cumulus_test_client::Client,
|
|
built: cumulus_test_runtime::Block,
|
|
import_existing: bool,
|
|
) {
|
|
let mut params = BlockImportParams::new(BlockOrigin::File, built.header.clone());
|
|
params.body = Some(built.extrinsics.clone());
|
|
params.state_action = StateAction::Execute;
|
|
params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
|
|
params.import_existing = import_existing;
|
|
let import_result = client.import_block(params).await;
|
|
assert!(matches!(import_result, Ok(ImportResult::Imported(_))));
|
|
}
|
|
|
|
fn benchmark_block_validation(c: &mut Criterion) {
|
|
sp_tracing::try_init_simple();
|
|
let runtime = tokio::runtime::Runtime::new().expect("creating tokio runtime doesn't fail; qed");
|
|
|
|
let endowed_accounts = vec![AccountId::from(Alice.public())];
|
|
let mut test_client_builder = TestClientBuilder::with_default_backend();
|
|
let genesis_init = test_client_builder.genesis_init_mut();
|
|
*genesis_init = cumulus_test_client::GenesisParameters { endowed_accounts };
|
|
|
|
let client = test_client_builder.build_with_native_executor(None).0;
|
|
|
|
let mut group = c.benchmark_group("Block validation");
|
|
group.sample_size(20);
|
|
group.measurement_time(Duration::from_secs(120));
|
|
|
|
// In the first iteration we want to initialize the glutton pallet.
|
|
let mut is_first = true;
|
|
for (compute_ratio, storage_ratio) in &[(One::one(), Zero::zero()), (One::one(), One::one())] {
|
|
let parachain_block =
|
|
set_glutton_parameters(&client, is_first, compute_ratio, storage_ratio);
|
|
is_first = false;
|
|
|
|
runtime.block_on(import_block(&client, parachain_block.clone().into_block(), false));
|
|
|
|
// Build benchmark block
|
|
let parent_hash = client.usage_info().chain.best_hash;
|
|
let parent_header = client.header(parent_hash).expect("Just fetched this hash.").unwrap();
|
|
let validation_data = PersistedValidationData {
|
|
relay_parent_number: 1,
|
|
parent_head: parent_header.encode().into(),
|
|
..Default::default()
|
|
};
|
|
let block_builder = client.init_block_builder(Some(validation_data), Default::default());
|
|
let parachain_block = block_builder.build_parachain_block(*parent_header.state_root());
|
|
|
|
let proof_size_in_kb = parachain_block.storage_proof().encode().len() as f64 / 1024f64;
|
|
runtime.block_on(import_block(&client, parachain_block.clone().into_block(), false));
|
|
let runtime = utils::get_wasm_module();
|
|
|
|
let sproof_builder: RelayStateSproofBuilder = Default::default();
|
|
let (relay_parent_storage_root, _) = sproof_builder.clone().into_state_root_and_proof();
|
|
let encoded_params = ValidationParams {
|
|
block_data: cumulus_test_client::BlockData(parachain_block.clone().encode()),
|
|
parent_head: HeadData(parent_header.encode()),
|
|
relay_parent_number: 1,
|
|
relay_parent_storage_root,
|
|
}
|
|
.encode();
|
|
|
|
// This is not strictly necessary for this benchmark, but
|
|
// let us make sure that the result of `validate_block` is what
|
|
// we expect.
|
|
verify_expected_result(&runtime, &encoded_params, parachain_block.into_block());
|
|
|
|
group.bench_function(
|
|
format!(
|
|
"(compute = {:?}, storage = {:?}, proof_size = {}kb) block validation",
|
|
compute_ratio, storage_ratio, proof_size_in_kb
|
|
),
|
|
|b| {
|
|
b.iter_batched(
|
|
|| runtime.new_instance().unwrap(),
|
|
|mut instance| {
|
|
instance.call_export("validate_block", &encoded_params).unwrap();
|
|
},
|
|
BatchSize::SmallInput,
|
|
)
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
fn verify_expected_result(runtime: &Box<dyn WasmModule>, encoded_params: &[u8], block: Block) {
|
|
let res = runtime
|
|
.new_instance()
|
|
.unwrap()
|
|
.call_export("validate_block", encoded_params)
|
|
.expect("Call `validate_block`.");
|
|
let validation_result =
|
|
ValidationResult::decode(&mut &res[..]).expect("Decode `ValidationResult`.");
|
|
let header =
|
|
Header::decode(&mut &validation_result.head_data.0[..]).expect("Decodes `Header`.");
|
|
assert_eq!(block.header, header);
|
|
}
|
|
|
|
fn set_glutton_parameters(
|
|
client: &Client,
|
|
initialize: bool,
|
|
compute_ratio: &FixedU64,
|
|
storage_ratio: &FixedU64,
|
|
) -> ParachainBlockData {
|
|
let parent_hash = client.usage_info().chain.best_hash;
|
|
let parent_header = client.header(parent_hash).expect("Just fetched this hash.").unwrap();
|
|
|
|
let mut last_nonce = client
|
|
.runtime_api()
|
|
.account_nonce(parent_hash, Alice.into())
|
|
.expect("Fetching account nonce works; qed");
|
|
|
|
let validation_data = PersistedValidationData {
|
|
relay_parent_number: 1,
|
|
parent_head: parent_header.encode().into(),
|
|
..Default::default()
|
|
};
|
|
|
|
let mut extrinsics = vec![];
|
|
if initialize {
|
|
extrinsics.push(generate_extrinsic_with_pair(
|
|
client,
|
|
Alice.into(),
|
|
SudoCall::sudo {
|
|
call: Box::new(
|
|
GluttonCall::initialize_pallet { new_count: 5000, witness_count: None }.into(),
|
|
),
|
|
},
|
|
Some(last_nonce),
|
|
));
|
|
last_nonce += 1;
|
|
}
|
|
|
|
let set_compute = generate_extrinsic_with_pair(
|
|
client,
|
|
Alice.into(),
|
|
SudoCall::sudo {
|
|
call: Box::new(GluttonCall::set_compute { compute: *compute_ratio }.into()),
|
|
},
|
|
Some(last_nonce),
|
|
);
|
|
last_nonce += 1;
|
|
extrinsics.push(set_compute);
|
|
|
|
let set_storage = generate_extrinsic_with_pair(
|
|
client,
|
|
Alice.into(),
|
|
SudoCall::sudo {
|
|
call: Box::new(GluttonCall::set_storage { storage: *storage_ratio }.into()),
|
|
},
|
|
Some(last_nonce),
|
|
);
|
|
extrinsics.push(set_storage);
|
|
|
|
let mut block_builder = client.init_block_builder(Some(validation_data), Default::default());
|
|
|
|
for extrinsic in extrinsics {
|
|
block_builder.push(extrinsic).unwrap();
|
|
}
|
|
|
|
block_builder.build_parachain_block(*parent_header.state_root())
|
|
}
|
|
|
|
criterion_group!(benches, benchmark_block_validation);
|
|
criterion_main!(benches);
|