Unverified Commit 70860910 authored by asynchronous rob's avatar asynchronous rob Committed by GitHub
Browse files

use executor cache in polkadot-parachain executor (#2342)



* use executor cache in polkadot-parachain executor

* Update parachain/src/wasm_executor/mod.rs
Co-authored-by: default avatarBastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: default avatarBastian Köcher <bkchr@users.noreply.github.com>
parent 25694f6f
Pipeline #122211 passed with stages
in 29 minutes and 6 seconds
......@@ -20,11 +20,13 @@
//!
//! These core Polkadot types are used by the relay chain and the Parachains.
use sp_runtime::{generic, MultiSignature, traits::{Verify, BlakeTwo256, IdentifyAccount}};
use sp_runtime::{generic, MultiSignature, traits::{Verify, IdentifyAccount}};
use parity_scale_codec::{Encode, Decode};
#[cfg(feature = "std")]
use parity_util_mem::MallocSizeOf;
pub use sp_runtime::traits::{BlakeTwo256, Hash as HashT};
/// The block number type used by Polkadot.
/// 32-bits will allow for 136 years of blocks assuming 1 block per second.
pub type BlockNumber = u32;
......
......@@ -160,6 +160,25 @@ pub enum InternalError {
WasmWorker(String),
}
/// A cache of executors for different parachain Wasm instances.
///
/// This should be reused across candidate validation instances.
pub struct ExecutorCache(sc_executor::WasmExecutor);
impl Default for ExecutorCache {
fn default() -> Self {
ExecutorCache(sc_executor::WasmExecutor::new(
#[cfg(all(feature = "wasmtime", not(any(target_os = "android", target_os = "unknown"))))]
sc_executor::WasmExecutionMethod::Compiled,
#[cfg(any(not(feature = "wasmtime"), target_os = "android", target_os = "unknown"))]
sc_executor::WasmExecutionMethod::Interpreted,
// TODO: Make sure we don't use more than 1GB: https://github.com/paritytech/polkadot/issues/699
Some(1024),
HostFunctions::host_functions(),
8
))
}
}
/// Validate a candidate under the given validation code.
///
......@@ -172,7 +191,12 @@ pub fn validate_candidate(
) -> Result<ValidationResult, ValidationError> {
match isolation_strategy {
IsolationStrategy::InProcess => {
validate_candidate_internal(validation_code, &params.encode(), spawner)
validate_candidate_internal(
&ExecutorCache::default(),
validation_code,
&params.encode(),
spawner,
)
},
#[cfg(not(any(target_os = "android", target_os = "unknown")))]
IsolationStrategy::ExternalProcessSelfHost(pool) => {
......@@ -193,20 +217,12 @@ type HostFunctions = sp_io::SubstrateHostFunctions;
///
/// This will fail if the validation code is not a proper parachain validation module.
pub fn validate_candidate_internal(
executor: &ExecutorCache,
validation_code: &[u8],
encoded_call_data: &[u8],
spawner: impl SpawnNamed + 'static,
) -> Result<ValidationResult, ValidationError> {
let executor = sc_executor::WasmExecutor::new(
#[cfg(all(feature = "wasmtime", not(any(target_os = "android", target_os = "unknown"))))]
sc_executor::WasmExecutionMethod::Compiled,
#[cfg(any(not(feature = "wasmtime"), target_os = "android", target_os = "unknown"))]
sc_executor::WasmExecutionMethod::Interpreted,
// TODO: Make sure we don't use more than 1GB: https://github.com/paritytech/polkadot/issues/699
Some(1024),
HostFunctions::host_functions(),
8
);
let executor = &executor.0;
let mut extensions = Extensions::new();
extensions.register(sp_core::traits::TaskExecutorExt::new(spawner));
......@@ -214,9 +230,16 @@ pub fn validate_candidate_internal(
let mut ext = ValidationExternalities(extensions);
// Expensive, but not more-so than recompiling the wasm module.
// And we need this hash to access the `sc_executor` cache.
let code_hash = {
use polkadot_core_primitives::{BlakeTwo256, HashT};
BlakeTwo256::hash(validation_code)
};
let res = executor.call_in_wasm(
validation_code,
None,
Some(code_hash.as_bytes().to_vec()),
"validate_block",
encoded_call_data,
&mut ext,
......
......@@ -151,6 +151,8 @@ pub fn run_worker(mem_id: &str) -> Result<(), String> {
memory.set(Event::WorkerReady as usize, EventState::Signaled)
.map_err(|e| format!("{} Error setting shared event: {:?}", process::id(), e))?;
let executor = super::ExecutorCache::default();
loop {
if watch_exit.load(atomic::Ordering::Relaxed) {
break;
......@@ -184,7 +186,7 @@ pub fn run_worker(mem_id: &str) -> Result<(), String> {
let (call_data, _) = rest.split_at_mut(MAX_RUNTIME_MEM);
let (call_data, _) = call_data.split_at_mut(header.params_size as usize);
let result = validate_candidate_internal(code, call_data, task_executor.clone());
let result = validate_candidate_internal(&executor, code, call_data, task_executor.clone());
debug!(target: LOG_TARGET, "{} Candidate validated: {:?}", process::id(), result);
match result {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment