Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 7086091

Browse files
rphmeierbkchr
andauthored
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: Bastian Köcher <[email protected]> Co-authored-by: Bastian Köcher <[email protected]>
1 parent 25694f6 commit 7086091

File tree

3 files changed

+41
-14
lines changed

3 files changed

+41
-14
lines changed

core-primitives/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
//!
2121
//! These core Polkadot types are used by the relay chain and the Parachains.
2222
23-
use sp_runtime::{generic, MultiSignature, traits::{Verify, BlakeTwo256, IdentifyAccount}};
23+
use sp_runtime::{generic, MultiSignature, traits::{Verify, IdentifyAccount}};
2424
use parity_scale_codec::{Encode, Decode};
2525
#[cfg(feature = "std")]
2626
use parity_util_mem::MallocSizeOf;
2727

28+
pub use sp_runtime::traits::{BlakeTwo256, Hash as HashT};
29+
2830
/// The block number type used by Polkadot.
2931
/// 32-bits will allow for 136 years of blocks assuming 1 block per second.
3032
pub type BlockNumber = u32;

parachain/src/wasm_executor/mod.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,25 @@ pub enum InternalError {
160160
WasmWorker(String),
161161
}
162162

163+
/// A cache of executors for different parachain Wasm instances.
164+
///
165+
/// This should be reused across candidate validation instances.
166+
pub struct ExecutorCache(sc_executor::WasmExecutor);
167+
168+
impl Default for ExecutorCache {
169+
fn default() -> Self {
170+
ExecutorCache(sc_executor::WasmExecutor::new(
171+
#[cfg(all(feature = "wasmtime", not(any(target_os = "android", target_os = "unknown"))))]
172+
sc_executor::WasmExecutionMethod::Compiled,
173+
#[cfg(any(not(feature = "wasmtime"), target_os = "android", target_os = "unknown"))]
174+
sc_executor::WasmExecutionMethod::Interpreted,
175+
// TODO: Make sure we don't use more than 1GB: https://github.com/paritytech/polkadot/issues/699
176+
Some(1024),
177+
HostFunctions::host_functions(),
178+
8
179+
))
180+
}
181+
}
163182

164183
/// Validate a candidate under the given validation code.
165184
///
@@ -172,7 +191,12 @@ pub fn validate_candidate(
172191
) -> Result<ValidationResult, ValidationError> {
173192
match isolation_strategy {
174193
IsolationStrategy::InProcess => {
175-
validate_candidate_internal(validation_code, &params.encode(), spawner)
194+
validate_candidate_internal(
195+
&ExecutorCache::default(),
196+
validation_code,
197+
&params.encode(),
198+
spawner,
199+
)
176200
},
177201
#[cfg(not(any(target_os = "android", target_os = "unknown")))]
178202
IsolationStrategy::ExternalProcessSelfHost(pool) => {
@@ -193,30 +217,29 @@ type HostFunctions = sp_io::SubstrateHostFunctions;
193217
///
194218
/// This will fail if the validation code is not a proper parachain validation module.
195219
pub fn validate_candidate_internal(
220+
executor: &ExecutorCache,
196221
validation_code: &[u8],
197222
encoded_call_data: &[u8],
198223
spawner: impl SpawnNamed + 'static,
199224
) -> Result<ValidationResult, ValidationError> {
200-
let executor = sc_executor::WasmExecutor::new(
201-
#[cfg(all(feature = "wasmtime", not(any(target_os = "android", target_os = "unknown"))))]
202-
sc_executor::WasmExecutionMethod::Compiled,
203-
#[cfg(any(not(feature = "wasmtime"), target_os = "android", target_os = "unknown"))]
204-
sc_executor::WasmExecutionMethod::Interpreted,
205-
// TODO: Make sure we don't use more than 1GB: https://github.com/paritytech/polkadot/issues/699
206-
Some(1024),
207-
HostFunctions::host_functions(),
208-
8
209-
);
225+
let executor = &executor.0;
210226

211227
let mut extensions = Extensions::new();
212228
extensions.register(sp_core::traits::TaskExecutorExt::new(spawner));
213229
extensions.register(sp_core::traits::CallInWasmExt::new(executor.clone()));
214230

215231
let mut ext = ValidationExternalities(extensions);
216232

233+
// Expensive, but not more-so than recompiling the wasm module.
234+
// And we need this hash to access the `sc_executor` cache.
235+
let code_hash = {
236+
use polkadot_core_primitives::{BlakeTwo256, HashT};
237+
BlakeTwo256::hash(validation_code)
238+
};
239+
217240
let res = executor.call_in_wasm(
218241
validation_code,
219-
None,
242+
Some(code_hash.as_bytes().to_vec()),
220243
"validate_block",
221244
encoded_call_data,
222245
&mut ext,

parachain/src/wasm_executor/validation_host.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ pub fn run_worker(mem_id: &str) -> Result<(), String> {
151151
memory.set(Event::WorkerReady as usize, EventState::Signaled)
152152
.map_err(|e| format!("{} Error setting shared event: {:?}", process::id(), e))?;
153153

154+
let executor = super::ExecutorCache::default();
155+
154156
loop {
155157
if watch_exit.load(atomic::Ordering::Relaxed) {
156158
break;
@@ -184,7 +186,7 @@ pub fn run_worker(mem_id: &str) -> Result<(), String> {
184186
let (call_data, _) = rest.split_at_mut(MAX_RUNTIME_MEM);
185187
let (call_data, _) = call_data.split_at_mut(header.params_size as usize);
186188

187-
let result = validate_candidate_internal(code, call_data, task_executor.clone());
189+
let result = validate_candidate_internal(&executor, code, call_data, task_executor.clone());
188190
debug!(target: LOG_TARGET, "{} Candidate validated: {:?}", process::id(), result);
189191

190192
match result {

0 commit comments

Comments
 (0)