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

Commit

Permalink
Make parachain validation wasm executor functional (#1574)
Browse files Browse the repository at this point in the history
* Make parachain validation wasm executor functional

- Increase the size of the validation result in the shared memory. The
validation result holds the new runtime when a runtime upgrade is
scheduled. So, we need to give it enough memory to send the data between
the validator and the wasm execution host.
- Add the `CallInWasmExt`. This is required when doing a runtime upgrade
to check that we upgrade to something meaningful.

* Update parachain/src/wasm_executor/mod.rs

* Update parachain/src/wasm_executor/mod.rs

Co-authored-by: Nikolay Volf <nikvolf@gmail.com>

Co-authored-by: Nikolay Volf <nikvolf@gmail.com>
  • Loading branch information
bkchr and NikVolf committed Aug 13, 2020
1 parent ae445ef commit 700f86a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
13 changes: 8 additions & 5 deletions parachain/src/wasm_executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mod validation_host;
// maximum memory in bytes
const MAX_RUNTIME_MEM: usize = 1024 * 1024 * 1024; // 1 GiB
const MAX_CODE_MEM: usize = 16 * 1024 * 1024; // 16 MiB
const MAX_VALIDATION_RESULT_HEADER_MEM: usize = MAX_CODE_MEM + 1024; // 16.001 MiB

/// A stub validation-pool defined when compiling for Android or WASM.
#[cfg(any(target_os = "android", target_os = "unknown"))]
Expand Down Expand Up @@ -176,18 +177,20 @@ pub fn validate_candidate_internal(
encoded_call_data: &[u8],
spawner: impl SpawnNamed + 'static,
) -> Result<ValidationResult, ValidationError> {
let mut extensions = Extensions::new();
extensions.register(sp_core::traits::TaskExecutorExt::new(spawner));

let mut ext = ValidationExternalities(extensions);

let executor = sc_executor::WasmExecutor::new(
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 mut extensions = Extensions::new();
extensions.register(sp_core::traits::TaskExecutorExt::new(spawner));
extensions.register(sp_core::traits::CallInWasmExt::new(executor.clone()));

let mut ext = ValidationExternalities(extensions);

let res = executor.call_in_wasm(
validation_code,
None,
Expand Down
21 changes: 15 additions & 6 deletions parachain/src/wasm_executor/validation_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
use std::{process, env, sync::Arc, sync::atomic};
use codec::{Decode, Encode};
use crate::primitives::{ValidationParams, ValidationResult};
use super::{validate_candidate_internal, ValidationError, InvalidCandidate, InternalError,
MAX_CODE_MEM, MAX_RUNTIME_MEM};
use super::{
validate_candidate_internal, ValidationError, InvalidCandidate, InternalError,
MAX_CODE_MEM, MAX_RUNTIME_MEM, MAX_VALIDATION_RESULT_HEADER_MEM,
};
use shared_memory::{SharedMem, SharedMemConf, EventState, WriteLockable, EventWait, EventSet};
use parking_lot::Mutex;
use log::{debug, trace};
Expand Down Expand Up @@ -113,7 +115,7 @@ pub fn run_worker(mem_id: &str) -> Result<(), String> {
};

let exit = Arc::new(atomic::AtomicBool::new(false));
let task_executor = TaskExecutor::new()?;
let task_executor = TaskExecutor::new()?;
// spawn parent monitor thread
let watch_exit = exit.clone();
std::thread::spawn(move || {
Expand Down Expand Up @@ -220,7 +222,7 @@ impl Drop for ValidationHost {

impl ValidationHost {
fn create_memory() -> Result<SharedMem, InternalError> {
let mem_size = MAX_RUNTIME_MEM + MAX_CODE_MEM + 1024;
let mem_size = MAX_RUNTIME_MEM + MAX_CODE_MEM + MAX_VALIDATION_RESULT_HEADER_MEM;
let mem_config = SharedMemConf::default()
.set_size(mem_size)
.add_lock(shared_memory::LockType::Mutex, 0, mem_size)?
Expand Down Expand Up @@ -318,9 +320,16 @@ impl ValidationHost {
debug!("{} Reading results", self.id);
let data: &[u8] = &**memory.wlock_as_slice(0)
.map_err(|e| ValidationError::Internal(e.into()))?;
let (header_buf, _) = data.split_at(1024);
let (header_buf, _) = data.split_at(MAX_VALIDATION_RESULT_HEADER_MEM);
let mut header_buf: &[u8] = header_buf;
let header = ValidationResultHeader::decode(&mut header_buf).unwrap();
let header = ValidationResultHeader::decode(&mut header_buf)
.map_err(|e|
InternalError::System(
Box::<dyn std::error::Error + Send + Sync>::from(
format!("Failed to decode `ValidationResultHeader`: {:?}", e)
) as Box<_>
)
)?;
match header {
ValidationResultHeader::Ok(result) => Ok(result),
ValidationResultHeader::Error(WorkerValidationError::InternalError(e)) => {
Expand Down

0 comments on commit 700f86a

Please sign in to comment.