sp-sandbox: move the sandbox module of sp-core into sp-sandbox (#11027)

* sp-sandbox: move the sandbox module of sp-core into sp-sandbox

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Fix

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Fix

Signed-off-by: koushiro <koushiro.cqx@gmail.com>
This commit is contained in:
Qinxuan Chen
2022-04-26 17:25:41 +08:00
committed by GitHub
parent 94dac682b4
commit e9b69bc1b0
17 changed files with 198 additions and 177 deletions
-1
View File
@@ -62,7 +62,6 @@ pub mod hash;
#[cfg(feature = "std")]
mod hasher;
pub mod offchain;
pub mod sandbox;
pub mod sr25519;
pub mod testing;
#[cfg(feature = "std")]
+14 -13
View File
@@ -19,28 +19,29 @@ wasmi = { version = "0.9.1", default-features = false, features = ["core"] }
wasmi = "0.9.0"
[dependencies]
wasmi = { version = "0.9.0", optional = true }
sp-core = { version = "6.0.0", default-features = false, path = "../core" }
sp-std = { version = "4.0.0", default-features = false, path = "../std" }
sp-io = { version = "6.0.0", default-features = false, path = "../io" }
sp-wasm-interface = { version = "6.0.0", default-features = false, path = "../wasm-interface" }
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false }
log = { version = "0.4", default-features = false }
wasmi = { version = "0.9.0", optional = true }
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false }
sp-core = { version = "6.0.0", default-features = false, path = "../core" }
sp-io = { version = "6.0.0", default-features = false, path = "../io" }
sp-std = { version = "4.0.0", default-features = false, path = "../std" }
sp-wasm-interface = { version = "6.0.0", default-features = false, path = "../wasm-interface" }
[dev-dependencies]
wat = "1.0"
assert_matches = "1.3.0"
wat = "1.0"
[features]
default = ["std"]
std = [
"wasmi",
"sp-core/std",
"sp-std/std",
"codec/std",
"sp-io/std",
"sp-wasm-interface/std",
"log/std",
"wasmi",
"codec/std",
"sp-core/std",
"sp-io/std",
"sp-std/std",
"sp-wasm-interface/std",
]
strict = []
wasmer-sandbox = []
+23 -11
View File
@@ -17,18 +17,20 @@
//! An embedded WASM executor utilizing `wasmi`.
use super::{Error, HostError, HostFuncType, ReturnValue, Value, TARGET};
use alloc::string::String;
use log::debug;
use sp_std::{
borrow::ToOwned, collections::btree_map::BTreeMap, fmt, marker::PhantomData, prelude::*,
};
use wasmi::{
memory_units::Pages, Externals, FuncInstance, FuncRef, GlobalDescriptor, GlobalRef,
ImportResolver, MemoryDescriptor, MemoryInstance, MemoryRef, Module, ModuleInstance, ModuleRef,
RuntimeArgs, RuntimeValue, Signature, TableDescriptor, TableRef, Trap, TrapKind,
};
use sp_std::{
borrow::ToOwned, collections::btree_map::BTreeMap, fmt, marker::PhantomData, prelude::*,
};
use crate::{Error, HostError, HostFuncType, ReturnValue, Value, TARGET};
/// The linear memory used by the sandbox.
#[derive(Clone)]
pub struct Memory {
@@ -162,13 +164,18 @@ impl<T> ImportResolver for EnvironmentDefinitionBuilder<T> {
) -> Result<FuncRef, wasmi::Error> {
let key = (module_name.as_bytes().to_owned(), field_name.as_bytes().to_owned());
let externval = self.map.get(&key).ok_or_else(|| {
debug!(target: TARGET, "Export {}:{} not found", module_name, field_name);
log::debug!(target: TARGET, "Export {}:{} not found", module_name, field_name);
wasmi::Error::Instantiation(String::new())
})?;
let host_func_idx = match *externval {
ExternVal::HostFunc(ref idx) => idx,
_ => {
debug!(target: TARGET, "Export {}:{} is not a host func", module_name, field_name);
log::debug!(
target: TARGET,
"Export {}:{} is not a host func",
module_name,
field_name,
);
return Err(wasmi::Error::Instantiation(String::new()))
},
};
@@ -181,7 +188,7 @@ impl<T> ImportResolver for EnvironmentDefinitionBuilder<T> {
_field_name: &str,
_global_type: &GlobalDescriptor,
) -> Result<GlobalRef, wasmi::Error> {
debug!(target: TARGET, "Importing globals is not supported yet");
log::debug!(target: TARGET, "Importing globals is not supported yet");
Err(wasmi::Error::Instantiation(String::new()))
}
@@ -193,13 +200,18 @@ impl<T> ImportResolver for EnvironmentDefinitionBuilder<T> {
) -> Result<MemoryRef, wasmi::Error> {
let key = (module_name.as_bytes().to_owned(), field_name.as_bytes().to_owned());
let externval = self.map.get(&key).ok_or_else(|| {
debug!(target: TARGET, "Export {}:{} not found", module_name, field_name);
log::debug!(target: TARGET, "Export {}:{} not found", module_name, field_name);
wasmi::Error::Instantiation(String::new())
})?;
let memory = match *externval {
ExternVal::Memory(ref m) => m,
_ => {
debug!(target: TARGET, "Export {}:{} is not a memory", module_name, field_name);
log::debug!(
target: TARGET,
"Export {}:{} is not a memory",
module_name,
field_name,
);
return Err(wasmi::Error::Instantiation(String::new()))
},
};
@@ -212,7 +224,7 @@ impl<T> ImportResolver for EnvironmentDefinitionBuilder<T> {
_field_name: &str,
_table_type: &TableDescriptor,
) -> Result<TableRef, wasmi::Error> {
debug!("Importing tables is not supported yet");
log::debug!("Importing tables is not supported yet");
Err(wasmi::Error::Instantiation(String::new()))
}
}
@@ -18,14 +18,16 @@
//! Definition of a sandbox environment.
use codec::{Decode, Encode};
use sp_core::RuntimeDebug;
use sp_std::vec::Vec;
/// Error error that can be returned from host function.
#[derive(Encode, Decode, crate::RuntimeDebug)]
#[derive(Encode, Decode, RuntimeDebug)]
pub struct HostError;
/// Describes an entity to define or import into the environment.
#[derive(Clone, PartialEq, Eq, Encode, Decode, crate::RuntimeDebug)]
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
pub enum ExternEntity {
/// Function that is specified by an index in a default table of
/// a module that creates the sandbox.
@@ -42,7 +44,7 @@ pub enum ExternEntity {
///
/// Each entry has a two-level name and description of an entity
/// being defined.
#[derive(Clone, PartialEq, Eq, Encode, Decode, crate::RuntimeDebug)]
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
pub struct Entry {
/// Module name of which corresponding entity being defined.
pub module_name: Vec<u8>,
@@ -53,7 +55,7 @@ pub struct Entry {
}
/// Definition of runtime that could be used by sandboxed code.
#[derive(Clone, PartialEq, Eq, Encode, Decode, crate::RuntimeDebug)]
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
pub struct EnvironmentDefinition {
/// Vector of all entries in the environment definition.
pub entries: Vec<Entry>,
+20 -24
View File
@@ -17,12 +17,13 @@
//! A WASM executor utilizing the sandbox runtime interface of the host.
use super::{Error, HostFuncType, ReturnValue, Value};
use codec::{Decode, Encode};
use sp_core::sandbox as sandbox_primitives;
use sp_io::sandbox;
use sp_std::{marker, mem, prelude::*, rc::Rc, slice, vec};
use crate::{env, Error, HostFuncType, ReturnValue, Value};
mod ffi {
use super::HostFuncType;
use sp_std::mem;
@@ -68,11 +69,10 @@ pub struct Memory {
impl super::SandboxMemory for Memory {
fn new(initial: u32, maximum: Option<u32>) -> Result<Memory, Error> {
let maximum =
if let Some(maximum) = maximum { maximum } else { sandbox_primitives::MEM_UNLIMITED };
let maximum = if let Some(maximum) = maximum { maximum } else { env::MEM_UNLIMITED };
match sandbox::memory_new(initial, maximum) {
sandbox_primitives::ERR_MODULE => Err(Error::Module),
env::ERR_MODULE => Err(Error::Module),
memory_idx => Ok(Memory { handle: Rc::new(MemoryHandle { memory_idx }) }),
}
}
@@ -81,8 +81,8 @@ impl super::SandboxMemory for Memory {
let result =
sandbox::memory_get(self.handle.memory_idx, offset, buf.as_mut_ptr(), buf.len() as u32);
match result {
sandbox_primitives::ERR_OK => Ok(()),
sandbox_primitives::ERR_OUT_OF_BOUNDS => Err(Error::OutOfBounds),
env::ERR_OK => Ok(()),
env::ERR_OUT_OF_BOUNDS => Err(Error::OutOfBounds),
_ => unreachable!(),
}
}
@@ -95,8 +95,8 @@ impl super::SandboxMemory for Memory {
val.len() as u32,
);
match result {
sandbox_primitives::ERR_OK => Ok(()),
sandbox_primitives::ERR_OUT_OF_BOUNDS => Err(Error::OutOfBounds),
env::ERR_OK => Ok(()),
env::ERR_OUT_OF_BOUNDS => Err(Error::OutOfBounds),
_ => unreachable!(),
}
}
@@ -104,22 +104,18 @@ impl super::SandboxMemory for Memory {
/// A builder for the environment of the sandboxed WASM module.
pub struct EnvironmentDefinitionBuilder<T> {
env_def: sandbox_primitives::EnvironmentDefinition,
env_def: env::EnvironmentDefinition,
retained_memories: Vec<Memory>,
_marker: marker::PhantomData<T>,
}
impl<T> EnvironmentDefinitionBuilder<T> {
fn add_entry<N1, N2>(
&mut self,
module: N1,
field: N2,
extern_entity: sandbox_primitives::ExternEntity,
) where
fn add_entry<N1, N2>(&mut self, module: N1, field: N2, extern_entity: env::ExternEntity)
where
N1: Into<Vec<u8>>,
N2: Into<Vec<u8>>,
{
let entry = sandbox_primitives::Entry {
let entry = env::Entry {
module_name: module.into(),
field_name: field.into(),
entity: extern_entity,
@@ -131,7 +127,7 @@ impl<T> EnvironmentDefinitionBuilder<T> {
impl<T> super::SandboxEnvironmentBuilder<T, Memory> for EnvironmentDefinitionBuilder<T> {
fn new() -> EnvironmentDefinitionBuilder<T> {
EnvironmentDefinitionBuilder {
env_def: sandbox_primitives::EnvironmentDefinition { entries: Vec::new() },
env_def: env::EnvironmentDefinition { entries: Vec::new() },
retained_memories: Vec::new(),
_marker: marker::PhantomData::<T>,
}
@@ -142,7 +138,7 @@ impl<T> super::SandboxEnvironmentBuilder<T, Memory> for EnvironmentDefinitionBui
N1: Into<Vec<u8>>,
N2: Into<Vec<u8>>,
{
let f = sandbox_primitives::ExternEntity::Function(f as u32);
let f = env::ExternEntity::Function(f as u32);
self.add_entry(module, field, f);
}
@@ -154,7 +150,7 @@ impl<T> super::SandboxEnvironmentBuilder<T, Memory> for EnvironmentDefinitionBui
// We need to retain memory to keep it alive while the EnvironmentDefinitionBuilder alive.
self.retained_memories.push(mem.clone());
let mem = sandbox_primitives::ExternEntity::Memory(mem.handle.memory_idx as u32);
let mem = env::ExternEntity::Memory(mem.handle.memory_idx as u32);
self.add_entry(module, field, mem);
}
}
@@ -228,8 +224,8 @@ impl<T> super::SandboxInstance<T> for Instance<T> {
);
let instance_idx = match result {
sandbox_primitives::ERR_MODULE => return Err(Error::Module),
sandbox_primitives::ERR_EXECUTION => return Err(Error::Execution),
env::ERR_MODULE => return Err(Error::Module),
env::ERR_EXECUTION => return Err(Error::Execution),
instance_idx => instance_idx,
};
@@ -256,12 +252,12 @@ impl<T> super::SandboxInstance<T> for Instance<T> {
);
match result {
sandbox_primitives::ERR_OK => {
env::ERR_OK => {
let return_val =
ReturnValue::decode(&mut &return_val[..]).map_err(|_| Error::Execution)?;
Ok(return_val)
},
sandbox_primitives::ERR_EXECUTION => Err(Error::Execution),
env::ERR_EXECUTION => Err(Error::Execution),
_ => unreachable!(),
}
}
+13 -12
View File
@@ -40,26 +40,27 @@
extern crate alloc;
pub mod embedded_executor;
pub mod env;
#[cfg(not(feature = "std"))]
pub mod host_executor;
use sp_core::RuntimeDebug;
use sp_std::prelude::*;
pub use sp_core::sandbox::HostError;
pub use sp_wasm_interface::{ReturnValue, Value};
#[cfg(not(all(feature = "wasmer-sandbox", not(feature = "std"))))]
pub use self::embedded_executor as default_executor;
pub use self::env::HostError;
#[cfg(all(feature = "wasmer-sandbox", not(feature = "std")))]
pub use self::host_executor as default_executor;
/// The target used for logging.
const TARGET: &str = "runtime::sandbox";
pub mod embedded_executor;
#[cfg(not(feature = "std"))]
pub mod host_executor;
#[cfg(all(feature = "wasmer-sandbox", not(feature = "std")))]
pub use host_executor as default_executor;
#[cfg(not(all(feature = "wasmer-sandbox", not(feature = "std"))))]
pub use embedded_executor as default_executor;
/// Error that can occur while using this crate.
#[derive(sp_core::RuntimeDebug)]
#[derive(RuntimeDebug)]
pub enum Error {
/// Module is not valid, couldn't be instantiated.
Module,