Make wasm runtime cache size configurable (#10177)

* Make wasm runtime cache size configurable

* apply review comments

* remove VersionedRuntimeValue

* fix compilation

* VersionedRuntime: replace clone by Arc

* fmt

* fix warnings

* fix tests compilation

* fmt
This commit is contained in:
Éloïs
2021-12-09 16:10:16 +01:00
committed by GitHub
parent 6ce90f583c
commit 3acd335a8d
30 changed files with 139 additions and 79 deletions
+1
View File
@@ -8035,6 +8035,7 @@ dependencies = [
"lazy_static", "lazy_static",
"libsecp256k1", "libsecp256k1",
"log 0.4.14", "log 0.4.14",
"lru 0.6.6",
"parity-scale-codec", "parity-scale-codec",
"parking_lot 0.11.1", "parking_lot 0.11.1",
"paste 1.0.6", "paste 1.0.6",
@@ -78,6 +78,7 @@ pub fn new_partial(
config.wasm_method, config.wasm_method,
config.default_heap_pages, config.default_heap_pages,
config.max_runtime_instances, config.max_runtime_instances,
config.runtime_cache_size,
); );
let (client, backend, keystore_container, task_manager) = let (client, backend, keystore_container, task_manager) =
@@ -104,6 +104,7 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase {
tracing_targets: None, tracing_targets: None,
tracing_receiver: Default::default(), tracing_receiver: Default::default(),
max_runtime_instances: 8, max_runtime_instances: 8,
runtime_cache_size: 2,
announce_block: true, announce_block: true,
base_path: Some(base_path), base_path: Some(base_path),
informant_output_format: Default::default(), informant_output_format: Default::default(),
@@ -96,6 +96,7 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase {
tracing_targets: None, tracing_targets: None,
tracing_receiver: Default::default(), tracing_receiver: Default::default(),
max_runtime_instances: 8, max_runtime_instances: 8,
runtime_cache_size: 2,
announce_block: true, announce_block: true,
base_path: Some(base_path), base_path: Some(base_path),
informant_output_format: Default::default(), informant_output_format: Default::default(),
+1
View File
@@ -161,6 +161,7 @@ pub fn new_partial(
config.wasm_method, config.wasm_method,
config.default_heap_pages, config.default_heap_pages,
config.max_runtime_instances, config.max_runtime_instances,
config.runtime_cache_size,
); );
let (client, backend, keystore_container, task_manager) = let (client, backend, keystore_container, task_manager) =
+1 -1
View File
@@ -194,7 +194,7 @@ fn bench_execute_block(c: &mut Criterion) {
ExecutionMethod::Wasm(wasm_method) => (false, wasm_method), ExecutionMethod::Wasm(wasm_method) => (false, wasm_method),
}; };
let executor = NativeElseWasmExecutor::new(wasm_method, None, 8); let executor = NativeElseWasmExecutor::new(wasm_method, None, 8, 2);
let runtime_code = RuntimeCode { let runtime_code = RuntimeCode {
code_fetcher: &sp_core::traits::WrappedRuntimeCode(compact_code_unwrap().into()), code_fetcher: &sp_core::traits::WrappedRuntimeCode(compact_code_unwrap().into()),
hash: vec![1, 2, 3], hash: vec![1, 2, 3],
+1 -1
View File
@@ -96,7 +96,7 @@ pub fn from_block_number(n: u32) -> Header {
} }
pub fn executor() -> NativeElseWasmExecutor<ExecutorDispatch> { pub fn executor() -> NativeElseWasmExecutor<ExecutorDispatch> {
NativeElseWasmExecutor::new(WasmExecutionMethod::Interpreted, None, 8) NativeElseWasmExecutor::new(WasmExecutionMethod::Interpreted, None, 8, 2)
} }
pub fn executor_call< pub fn executor_call<
@@ -41,6 +41,7 @@ impl InspectCmd {
config.wasm_method, config.wasm_method,
config.default_heap_pages, config.default_heap_pages,
config.max_runtime_instances, config.max_runtime_instances,
config.runtime_cache_size,
); );
let client = new_full_client::<B, RA, _>(&config, None, executor)?; let client = new_full_client::<B, RA, _>(&config, None, executor)?;
+1 -1
View File
@@ -400,7 +400,7 @@ impl BenchDb {
let backend = sc_service::new_db_backend(db_config).expect("Should not fail"); let backend = sc_service::new_db_backend(db_config).expect("Should not fail");
let client = sc_service::new_client( let client = sc_service::new_client(
backend.clone(), backend.clone(),
NativeElseWasmExecutor::new(WasmExecutionMethod::Compiled, None, 8), NativeElseWasmExecutor::new(WasmExecutionMethod::Compiled, None, 8, 2),
&keyring.generate_genesis(), &keyring.generate_genesis(),
None, None,
None, None,
@@ -238,6 +238,10 @@ pub struct RunCmd {
#[structopt(long)] #[structopt(long)]
pub max_runtime_instances: Option<usize>, pub max_runtime_instances: Option<usize>,
/// Maximum number of different runtimes that can be cached.
#[structopt(long, default_value = "2")]
pub runtime_cache_size: u8,
/// Run a temporary node. /// Run a temporary node.
/// ///
/// A temporary directory will be created to store the configuration and will be deleted /// A temporary directory will be created to store the configuration and will be deleted
@@ -453,6 +457,10 @@ impl CliConfiguration for RunCmd {
Ok(self.max_runtime_instances.map(|x| x.min(256))) Ok(self.max_runtime_instances.map(|x| x.min(256)))
} }
fn runtime_cache_size(&self) -> Result<u8> {
Ok(self.runtime_cache_size)
}
fn base_path(&self) -> Result<Option<BasePath>> { fn base_path(&self) -> Result<Option<BasePath>> {
Ok(if self.tmp { Ok(if self.tmp {
Some(BasePath::new_temp_dir()?) Some(BasePath::new_temp_dir()?)
+9
View File
@@ -452,6 +452,13 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
Ok(Default::default()) Ok(Default::default())
} }
/// Get maximum different runtimes in cache
///
/// By default this is `2`.
fn runtime_cache_size(&self) -> Result<u8> {
Ok(2)
}
/// Activate or not the automatic announcing of blocks after import /// Activate or not the automatic announcing of blocks after import
/// ///
/// By default this is `false`. /// By default this is `false`.
@@ -482,6 +489,7 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
let is_validator = role.is_authority(); let is_validator = role.is_authority();
let (keystore_remote, keystore) = self.keystore_config(&config_dir)?; let (keystore_remote, keystore) = self.keystore_config(&config_dir)?;
let telemetry_endpoints = self.telemetry_endpoints(&chain_spec)?; let telemetry_endpoints = self.telemetry_endpoints(&chain_spec)?;
let runtime_cache_size = self.runtime_cache_size()?;
let unsafe_pruning = self.import_params().map(|p| p.unsafe_pruning).unwrap_or(false); let unsafe_pruning = self.import_params().map(|p| p.unsafe_pruning).unwrap_or(false);
@@ -534,6 +542,7 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
role, role,
base_path: Some(base_path), base_path: Some(base_path),
informant_output_format: Default::default(), informant_output_format: Default::default(),
runtime_cache_size,
}) })
} }
+1
View File
@@ -34,6 +34,7 @@ parking_lot = "0.11.1"
log = "0.4.8" log = "0.4.8"
libsecp256k1 = "0.7" libsecp256k1 = "0.7"
sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "../../primitives/core/hashing/proc-macro" } sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "../../primitives/core/hashing/proc-macro" }
lru = "0.6.6"
[dev-dependencies] [dev-dependencies]
wat = "1.0" wat = "1.0"
@@ -130,6 +130,7 @@ fn call_in_wasm<E: Externalities>(
HostFunctions::host_functions(), HostFunctions::host_functions(),
8, 8,
None, None,
2,
); );
executor.uncached_call( executor.uncached_call(
RuntimeBlob::uncompress_if_needed(&wasm_binary_unwrap()[..]).unwrap(), RuntimeBlob::uncompress_if_needed(&wasm_binary_unwrap()[..]).unwrap(),
@@ -480,6 +481,7 @@ fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) {
HostFunctions::host_functions(), HostFunctions::host_functions(),
8, 8,
None, None,
2,
); );
let err = executor let err = executor
@@ -593,6 +595,7 @@ fn parallel_execution(wasm_method: WasmExecutionMethod) {
HostFunctions::host_functions(), HostFunctions::host_functions(),
8, 8,
None, None,
2,
)); ));
let threads: Vec<_> = (0..8) let threads: Vec<_> = (0..8)
.map(|_| { .map(|_| {
+1
View File
@@ -80,6 +80,7 @@ mod tests {
sp_io::SubstrateHostFunctions::host_functions(), sp_io::SubstrateHostFunctions::host_functions(),
8, 8,
None, None,
2,
); );
let res = executor let res = executor
.uncached_call( .uncached_call(
@@ -130,12 +130,17 @@ impl WasmExecutor {
host_functions: Vec<&'static dyn Function>, host_functions: Vec<&'static dyn Function>,
max_runtime_instances: usize, max_runtime_instances: usize,
cache_path: Option<PathBuf>, cache_path: Option<PathBuf>,
runtime_cache_size: u8,
) -> Self { ) -> Self {
WasmExecutor { WasmExecutor {
method, method,
default_heap_pages: default_heap_pages.unwrap_or(DEFAULT_HEAP_PAGES), default_heap_pages: default_heap_pages.unwrap_or(DEFAULT_HEAP_PAGES),
host_functions: Arc::new(host_functions), host_functions: Arc::new(host_functions),
cache: Arc::new(RuntimeCache::new(max_runtime_instances, cache_path.clone())), cache: Arc::new(RuntimeCache::new(
max_runtime_instances,
cache_path.clone(),
runtime_cache_size,
)),
cache_path, cache_path,
} }
} }
@@ -330,6 +335,7 @@ impl<D: NativeExecutionDispatch> NativeElseWasmExecutor<D> {
fallback_method: WasmExecutionMethod, fallback_method: WasmExecutionMethod,
default_heap_pages: Option<u64>, default_heap_pages: Option<u64>,
max_runtime_instances: usize, max_runtime_instances: usize,
runtime_cache_size: u8,
) -> Self { ) -> Self {
let extended = D::ExtendHostFunctions::host_functions(); let extended = D::ExtendHostFunctions::host_functions();
let mut host_functions = sp_io::SubstrateHostFunctions::host_functions() let mut host_functions = sp_io::SubstrateHostFunctions::host_functions()
@@ -351,6 +357,7 @@ impl<D: NativeExecutionDispatch> NativeElseWasmExecutor<D> {
host_functions, host_functions,
max_runtime_instances, max_runtime_instances,
None, None,
runtime_cache_size,
); );
NativeElseWasmExecutor { NativeElseWasmExecutor {
@@ -636,6 +643,7 @@ mod tests {
WasmExecutionMethod::Interpreted, WasmExecutionMethod::Interpreted,
None, None,
8, 8,
2,
); );
my_interface::HostFunctions::host_functions().iter().for_each(|function| { my_interface::HostFunctions::host_functions().iter().for_each(|function| {
assert_eq!(executor.wasm.host_functions.iter().filter(|f| f == &function).count(), 2); assert_eq!(executor.wasm.host_functions.iter().filter(|f| f == &function).count(), 2);
+67 -70
View File
@@ -23,6 +23,7 @@
use crate::error::{Error, WasmError}; use crate::error::{Error, WasmError};
use codec::Decode; use codec::Decode;
use lru::LruCache;
use parking_lot::Mutex; use parking_lot::Mutex;
use sc_executor_common::{ use sc_executor_common::{
runtime_blob::RuntimeBlob, runtime_blob::RuntimeBlob,
@@ -54,20 +55,24 @@ impl Default for WasmExecutionMethod {
} }
} }
/// A Wasm runtime object along with its cached runtime version. #[derive(Debug, PartialEq, Eq, Hash, Clone)]
struct VersionedRuntime { struct VersionedRuntimeId {
/// Runtime code hash. /// Runtime code hash.
code_hash: Vec<u8>, code_hash: Vec<u8>,
/// Wasm runtime type. /// Wasm runtime type.
wasm_method: WasmExecutionMethod, wasm_method: WasmExecutionMethod,
/// Shared runtime that can spawn instances.
module: Arc<dyn WasmModule>,
/// The number of WebAssembly heap pages this instance was created with. /// The number of WebAssembly heap pages this instance was created with.
heap_pages: u64, heap_pages: u64,
}
/// A Wasm runtime object along with its cached runtime version.
struct VersionedRuntime {
/// Shared runtime that can spawn instances.
module: Arc<dyn WasmModule>,
/// Runtime version according to `Core_version` if any. /// Runtime version according to `Core_version` if any.
version: Option<RuntimeVersion>, version: Option<RuntimeVersion>,
/// Cached instance pool. /// Cached instance pool.
instances: Vec<Mutex<Option<Box<dyn WasmInstance>>>>, instances: Arc<Vec<Mutex<Option<Box<dyn WasmInstance>>>>>,
} }
impl VersionedRuntime { impl VersionedRuntime {
@@ -137,8 +142,6 @@ impl VersionedRuntime {
} }
} }
const MAX_RUNTIMES: usize = 2;
/// Cache for the runtimes. /// Cache for the runtimes.
/// ///
/// When an instance is requested for the first time it is added to this cache. Metadata is kept /// When an instance is requested for the first time it is added to this cache. Metadata is kept
@@ -149,12 +152,12 @@ const MAX_RUNTIMES: usize = 2;
/// the memory reset to the initial memory. So, one runtime instance is reused for every fetch /// the memory reset to the initial memory. So, one runtime instance is reused for every fetch
/// request. /// request.
/// ///
/// The size of cache is equal to `MAX_RUNTIMES`. /// The size of cache is configurable via the cli option `--runtime-cache-size`.
pub struct RuntimeCache { pub struct RuntimeCache {
/// A cache of runtimes along with metadata. /// A cache of runtimes along with metadata.
/// ///
/// Runtimes sorted by recent usage. The most recently used is at the front. /// Runtimes sorted by recent usage. The most recently used is at the front.
runtimes: Mutex<[Option<Arc<VersionedRuntime>>; MAX_RUNTIMES]>, runtimes: Mutex<LruCache<VersionedRuntimeId, Arc<VersionedRuntime>>>,
/// The size of the instances cache for each runtime. /// The size of the instances cache for each runtime.
max_runtime_instances: usize, max_runtime_instances: usize,
cache_path: Option<PathBuf>, cache_path: Option<PathBuf>,
@@ -163,13 +166,24 @@ pub struct RuntimeCache {
impl RuntimeCache { impl RuntimeCache {
/// Creates a new instance of a runtimes cache. /// Creates a new instance of a runtimes cache.
/// ///
/// `max_runtime_instances` specifies the number of runtime instances preserved in an in-memory /// `max_runtime_instances` specifies the number of instances per runtime preserved in an
/// cache. /// in-memory cache.
/// ///
/// `cache_path` allows to specify an optional directory where the executor can store files /// `cache_path` allows to specify an optional directory where the executor can store files
/// for caching. /// for caching.
pub fn new(max_runtime_instances: usize, cache_path: Option<PathBuf>) -> RuntimeCache { ///
RuntimeCache { runtimes: Default::default(), max_runtime_instances, cache_path } /// `runtime_cache_size` specifies the number of different runtimes versions preserved in an
/// in-memory cache.
pub fn new(
max_runtime_instances: usize,
cache_path: Option<PathBuf>,
runtime_cache_size: u8,
) -> RuntimeCache {
RuntimeCache {
runtimes: Mutex::new(LruCache::new(runtime_cache_size.into())),
max_runtime_instances,
cache_path,
}
} }
/// Prepares a WASM module instance and executes given function for it. /// Prepares a WASM module instance and executes given function for it.
@@ -221,71 +235,55 @@ impl RuntimeCache {
let code_hash = &runtime_code.hash; let code_hash = &runtime_code.hash;
let heap_pages = runtime_code.heap_pages.unwrap_or(default_heap_pages); let heap_pages = runtime_code.heap_pages.unwrap_or(default_heap_pages);
let versioned_runtime_id =
VersionedRuntimeId { code_hash: code_hash.clone(), heap_pages, wasm_method };
let mut runtimes = self.runtimes.lock(); // this must be released prior to calling f let mut runtimes = self.runtimes.lock(); // this must be released prior to calling f
let pos = runtimes.iter().position(|r| { let versioned_runtime = if let Some(versioned_runtime) = runtimes.get(&versioned_runtime_id)
r.as_ref().map_or(false, |r| { {
r.wasm_method == wasm_method && versioned_runtime.clone()
r.code_hash == *code_hash && } else {
r.heap_pages == heap_pages let code = runtime_code.fetch_runtime_code().ok_or(WasmError::CodeNotFound)?;
})
});
let runtime = match pos { let time = std::time::Instant::now();
Some(n) => runtimes[n]
.clone()
.expect("`position` only returns `Some` for entries that are `Some`"),
None => {
let code = runtime_code.fetch_runtime_code().ok_or(WasmError::CodeNotFound)?;
let time = std::time::Instant::now(); let result = create_versioned_wasm_runtime(
&code,
ext,
wasm_method,
heap_pages,
host_functions.into(),
allow_missing_func_imports,
self.max_runtime_instances,
self.cache_path.as_deref(),
);
let result = create_versioned_wasm_runtime( match result {
&code, Ok(ref result) => {
code_hash.clone(), log::debug!(
ext, target: "wasm-runtime",
wasm_method, "Prepared new runtime version {:?} in {} ms.",
heap_pages, result.version,
host_functions.into(), time.elapsed().as_millis(),
allow_missing_func_imports, );
self.max_runtime_instances, },
self.cache_path.as_deref(), Err(ref err) => {
); log::warn!(target: "wasm-runtime", "Cannot create a runtime: {:?}", err);
},
}
match result { let versioned_runtime = Arc::new(result?);
Ok(ref result) => {
log::debug!(
target: "wasm-runtime",
"Prepared new runtime version {:?} in {} ms.",
result.version,
time.elapsed().as_millis(),
);
},
Err(ref err) => {
log::warn!(target: "wasm-runtime", "Cannot create a runtime: {:?}", err);
},
}
Arc::new(result?) // Save new versioned wasm runtime in cache
}, runtimes.put(versioned_runtime_id, versioned_runtime.clone());
versioned_runtime
}; };
// Rearrange runtimes by last recently used. // Lock must be released prior to calling f
match pos {
Some(0) => {},
Some(n) =>
for i in (1..n + 1).rev() {
runtimes.swap(i, i - 1);
},
None => {
runtimes[MAX_RUNTIMES - 1] = Some(runtime.clone());
for i in (1..MAX_RUNTIMES).rev() {
runtimes.swap(i, i - 1);
}
},
}
drop(runtimes); drop(runtimes);
Ok(runtime.with_instance(ext, f)) Ok(versioned_runtime.with_instance(ext, f))
} }
} }
@@ -396,7 +394,6 @@ pub fn read_embedded_version(blob: &RuntimeBlob) -> Result<Option<RuntimeVersion
fn create_versioned_wasm_runtime( fn create_versioned_wasm_runtime(
code: &[u8], code: &[u8],
code_hash: Vec<u8>,
ext: &mut dyn Externalities, ext: &mut dyn Externalities,
wasm_method: WasmExecutionMethod, wasm_method: WasmExecutionMethod,
heap_pages: u64, heap_pages: u64,
@@ -449,7 +446,7 @@ fn create_versioned_wasm_runtime(
let mut instances = Vec::with_capacity(max_instances); let mut instances = Vec::with_capacity(max_instances);
instances.resize_with(max_instances, || Mutex::new(None)); instances.resize_with(max_instances, || Mutex::new(None));
Ok(VersionedRuntime { code_hash, module: runtime, version, heap_pages, wasm_method, instances }) Ok(VersionedRuntime { module: runtime, version, instances: Arc::new(instances) })
} }
#[cfg(test)] #[cfg(test)]
@@ -360,6 +360,7 @@ mod tests {
WasmExecutionMethod::Interpreted, WasmExecutionMethod::Interpreted,
Some(128), Some(128),
1, 1,
2,
); );
let overrides = crate::client::wasm_override::dummy_overrides(); let overrides = crate::client::wasm_override::dummy_overrides();
@@ -282,6 +282,7 @@ mod tests {
WasmExecutionMethod::Interpreted, WasmExecutionMethod::Interpreted,
Some(128), Some(128),
1, 1,
2,
); );
let bytes = substrate_test_runtime::wasm_binary_unwrap(); let bytes = substrate_test_runtime::wasm_binary_unwrap();
let dir = tempfile::tempdir().expect("Create a temporary directory"); let dir = tempfile::tempdir().expect("Create a temporary directory");
@@ -295,6 +296,7 @@ mod tests {
WasmExecutionMethod::Interpreted, WasmExecutionMethod::Interpreted,
Some(128), Some(128),
1, 1,
2,
); );
let version = WasmOverride::runtime_version( let version = WasmOverride::runtime_version(
+2
View File
@@ -132,6 +132,8 @@ pub struct Configuration {
pub base_path: Option<BasePath>, pub base_path: Option<BasePath>,
/// Configuration of the output format that the informant uses. /// Configuration of the output format that the informant uses.
pub informant_output_format: sc_informant::OutputFormat, pub informant_output_format: sc_informant::OutputFormat,
/// Maximum number of different runtime versions that can be cached.
pub runtime_cache_size: u8,
} }
/// Type for tasks spawned by the executor. /// Type for tasks spawned by the executor.
@@ -72,7 +72,12 @@ impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
} }
fn executor() -> sc_executor::NativeElseWasmExecutor<ExecutorDispatch> { fn executor() -> sc_executor::NativeElseWasmExecutor<ExecutorDispatch> {
sc_executor::NativeElseWasmExecutor::new(sc_executor::WasmExecutionMethod::Interpreted, None, 8) sc_executor::NativeElseWasmExecutor::new(
sc_executor::WasmExecutionMethod::Interpreted,
None,
8,
2,
)
} }
fn construct_block( fn construct_block(
+1
View File
@@ -261,6 +261,7 @@ fn node_config<
announce_block: true, announce_block: true,
base_path: Some(BasePath::new(root)), base_path: Some(BasePath::new(root)),
informant_output_format: Default::default(), informant_output_format: Default::default(),
runtime_cache_size: 2,
} }
} }
@@ -210,6 +210,7 @@ fn record_proof_works() {
WasmExecutionMethod::Interpreted, WasmExecutionMethod::Interpreted,
None, None,
8, 8,
2,
); );
execution_proof_check_on_trie_backend( execution_proof_check_on_trie_backend(
&backend, &backend,
@@ -48,6 +48,7 @@ fn call_wasm_method_with_result<HF: HostFunctionsT>(
host_functions, host_functions,
8, 8,
None, None,
2,
); );
executor executor
.uncached_call( .uncached_call(
+1 -1
View File
@@ -283,7 +283,7 @@ impl<Block: BlockT, D, Backend, G: GenesisInit>
Backend: sc_client_api::backend::Backend<Block> + 'static, Backend: sc_client_api::backend::Backend<Block> + 'static,
{ {
let executor = executor.into().unwrap_or_else(|| { let executor = executor.into().unwrap_or_else(|| {
NativeElseWasmExecutor::new(WasmExecutionMethod::Interpreted, None, 8) NativeElseWasmExecutor::new(WasmExecutionMethod::Interpreted, None, 8, 2)
}); });
let executor = LocalCallExecutor::new( let executor = LocalCallExecutor::new(
self.backend.clone(), self.backend.clone(),
@@ -287,5 +287,10 @@ pub fn new() -> Client<Backend> {
/// Create a new native executor. /// Create a new native executor.
pub fn new_native_executor() -> sc_executor::NativeElseWasmExecutor<LocalExecutorDispatch> { pub fn new_native_executor() -> sc_executor::NativeElseWasmExecutor<LocalExecutorDispatch> {
sc_executor::NativeElseWasmExecutor::new(sc_executor::WasmExecutionMethod::Interpreted, None, 8) sc_executor::NativeElseWasmExecutor::new(
sc_executor::WasmExecutionMethod::Interpreted,
None,
8,
2,
)
} }
+1 -1
View File
@@ -342,7 +342,7 @@ mod tests {
} }
fn executor() -> NativeElseWasmExecutor<NativeDispatch> { fn executor() -> NativeElseWasmExecutor<NativeDispatch> {
NativeElseWasmExecutor::new(WasmExecutionMethod::Interpreted, None, 8) NativeElseWasmExecutor::new(WasmExecutionMethod::Interpreted, None, 8, 2)
} }
fn new_test_ext() -> TestExternalities { fn new_test_ext() -> TestExternalities {
@@ -111,6 +111,7 @@ where
config.wasm_method, config.wasm_method,
config.default_heap_pages, config.default_heap_pages,
config.max_runtime_instances, config.max_runtime_instances,
config.runtime_cache_size,
); );
let (client, backend, keystore, mut task_manager) = let (client, backend, keystore, mut task_manager) =
@@ -113,5 +113,6 @@ pub fn default_config(tokio_handle: Handle, mut chain_spec: Box<dyn ChainSpec>)
keep_blocks: KeepBlocks::All, keep_blocks: KeepBlocks::All,
state_pruning: Default::default(), state_pruning: Default::default(),
transaction_storage: TransactionStorageMode::BlockBody, transaction_storage: TransactionStorageMode::BlockBody,
runtime_cache_size: 2,
} }
} }
@@ -137,6 +137,7 @@ impl BenchmarkCmd {
wasm_method, wasm_method,
self.heap_pages, self.heap_pages,
2, // The runtime instances cache size. 2, // The runtime instances cache size.
2, // The runtime cache size
); );
let extensions = || -> Extensions { let extensions = || -> Extensions {
@@ -678,8 +678,14 @@ pub(crate) fn build_executor<D: NativeExecutionDispatch + 'static>(
let wasm_method = shared.wasm_method; let wasm_method = shared.wasm_method;
let heap_pages = shared.heap_pages.or(config.default_heap_pages); let heap_pages = shared.heap_pages.or(config.default_heap_pages);
let max_runtime_instances = config.max_runtime_instances; let max_runtime_instances = config.max_runtime_instances;
let runtime_cache_size = config.runtime_cache_size;
NativeElseWasmExecutor::<D>::new(wasm_method.into(), heap_pages, max_runtime_instances) NativeElseWasmExecutor::<D>::new(
wasm_method.into(),
heap_pages,
max_runtime_instances,
runtime_cache_size,
)
} }
/// Execute the given `method` and `data` on top of `ext`, returning the results (encoded) and the /// Execute the given `method` and `data` on top of `ext`, returning the results (encoded) and the