Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(runtime): Wasmer 1.0 runner #3799

Merged
merged 60 commits into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
17c9c7d
initial add wasmer 1.0 and features
ailisp Jan 5, 2021
bef831c
wasmtime neard compiles
ailisp Jan 5, 2021
22a3610
wasmtime neard compiles
ailisp Jan 5, 2021
d248733
all driver code
ailisp Jan 5, 2021
4408a0e
wip wasmer 1.0
ailisp Jan 6, 2021
ee61fbc
translate unsafe wasmer 0.17 ctx.data as safe 1.0 myEnv.logic
ailisp Jan 7, 2021
7b82b8d
fix most compile errors except wasmer error conversion
ailisp Jan 7, 2021
cac1740
fix more errors, stuck in wasmer 1.0 cannot import native func return…
ailisp Jan 9, 2021
3e52892
fix HostFunction trait not implemented issue
ailisp Jan 9, 2021
e064e6a
fix HostFunction trait not implemented issue
ailisp Jan 9, 2021
cd5d291
fix compilation errors
ailisp Jan 9, 2021
746ea2b
fix vmlogic inject
ailisp Jan 11, 2021
a63ec4a
adding all into_vm_errors, fixed some tests
ailisp Jan 12, 2021
a83d0ab
avx check and no nan check needed now
ailisp Jan 12, 2021
e563ad3
fix two more tests
ailisp Jan 12, 2021
2d1c129
fix runner stuck infinite
ailisp Jan 14, 2021
6c7ad15
fix runtime error downcast error
ailisp Jan 14, 2021
6e064f6
refactor vmlogicerror into vmerror
ailisp Jan 14, 2021
11be303
fix runtime error on call initializer
ailisp Jan 14, 2021
beccd74
fix all vm error test
ailisp Jan 14, 2021
fc4aca9
rename VMKind::Wasmer to Wasmer0
ailisp Jan 15, 2021
b3264ee
add cranelift-frontend to cargo deny
ailisp Jan 15, 2021
c5417e8
resolve conflict
ailisp Jan 15, 2021
cbd5169
fix cargo deny
ailisp Jan 15, 2021
69a77e0
fix test workspace
ailisp Jan 15, 2021
43fb8a3
workaround all-features
ailisp Jan 15, 2021
20dbb3f
reuse import reference to vmlogicreference
ailisp Jan 15, 2021
d3f2ad2
test_stack_overflow for wasmer1
ailisp Jan 15, 2021
1a2c845
fix test_stack_overflow for wasmer1
ailisp Jan 15, 2021
672e029
Merge branch 'master' into wasmer-1.0
ailisp Jan 15, 2021
b802df2
upgrade to git wasmer to get internal of RuntimeError
ailisp Jan 16, 2021
5061b4c
test wasmer trap and user error
ailisp Jan 16, 2021
5d632f5
merge master
ailisp Jan 19, 2021
841482d
rename
ailisp Jan 20, 2021
50911ae
Merge branch 'master' into wasmer-1.0
ailisp Jan 20, 2021
0f0751e
Merge branch 'master' into wasmer-1.0
olonho Jan 27, 2021
1638987
fix a compilation error from merge
ailisp Feb 1, 2021
82f69a8
actix 0.9 also works, so undo it
ailisp Feb 2, 2021
d4c8ad3
merge master resolve conflict
ailisp Feb 3, 2021
d0f377b
enable ability to build neard with wasmer 1.0
ailisp Feb 3, 2021
f452f9d
cache in wasmer1
ailisp Feb 4, 2021
afa9b25
remove delay detector
ailisp Feb 5, 2021
df0b5bf
fix feature set for ci
ailisp Feb 5, 2021
1848478
use fork released wasmer
ailisp Feb 5, 2021
e202e37
merge master
ailisp Feb 5, 2021
6f32f4e
resolve conflict in Cargo.lock
ailisp Feb 5, 2021
bae0e08
cargo deny
ailisp Feb 5, 2021
7fc2454
wasmer 1.0.2
ailisp Feb 5, 2021
9ca118e
error into
ailisp Feb 12, 2021
56e3786
typo
ailisp Feb 12, 2021
51ffe38
precompile wasmer1
ailisp Feb 12, 2021
cc338ff
wasmer1 by default, optional wasmer 0
ailisp Feb 13, 2021
b1fb114
test pass again
ailisp Feb 13, 2021
e22752a
resolve conflict
ailisp Feb 13, 2021
365ccbf
fix all tests
ailisp Feb 17, 2021
ee1b5ea
wasmer0 as default, all vm enabled in tests
ailisp Feb 17, 2021
61b8514
fix cargo check all features
ailisp Feb 17, 2021
c565693
Merge branch 'master' into wasmer-1.0
ailisp Feb 17, 2021
d7e2e1c
nit
ailisp Feb 23, 2021
6cec70f
Merge branch 'master' into wasmer-1.0
ailisp Feb 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
603 changes: 539 additions & 64 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ delay_detector = ["neard/delay_detector"]
rosetta_rpc = ["neard/rosetta_rpc"]
protocol_feature_forward_chunk_parts = ["neard/protocol_feature_forward_chunk_parts"]
nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"]
wasmtime_vm = ["neard/wasmtime_vm"]
wasmer1_vm = ["neard/wasmer1_vm"]
nightly_protocol_features = ["nightly_protocol", "neard/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_block_ordinal"]
protocol_feature_evm = ["neard/protocol_feature_evm", "testlib/protocol_feature_evm", "runtime-params-estimator/protocol_feature_evm"]
protocol_feature_block_ordinal = ["neard/protocol_feature_block_ordinal", "near-primitives/protocol_feature_block_ordinal"]
Expand Down
13 changes: 13 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,17 @@ skip = [

{ name = "parking_lot", version = "=0.9.0" },

# wasmer 1.0 use some newer version of crates than wasmer 0.17 & wasmtime, old ones are skipped here
ailisp marked this conversation as resolved.
Show resolved Hide resolved
{ name = "cranelift-bforest", version = "=0.67.0" },
{ name = "cranelift-codegen", version = "=0.67.0" },
{ name = "cranelift-codegen-meta", version = "=0.67.0" },
{ name = "cranelift-codegen-shared", version = "=0.67.0" },
{ name = "cranelift-entity", version = "=0.67.0" },
{ name = "cranelift-frontend", version = "=0.67.0" },
{ name = "gimli", version = "=0.21.0" },
{ name = "libloading", version = "=0.5.2" },
{ name = "regalloc", version = "=0.0.30" },
{ name = "strsim", version = "=0.8.0" },
{ name = "wasmparser", version = "=0.57.0" },
{ name = "which", version = "=3.1.1" },
]
2 changes: 2 additions & 0 deletions neard/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ protocol_feature_evm = ["near-primitives/protocol_feature_evm", "node-runtime/pr
protocol_feature_block_ordinal = ["near-primitives/protocol_feature_block_ordinal"]
nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_forward_chunk_parts", "protocol_feature_rectify_inflation", "protocol_feature_evm"]
nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"]
wasmtime_vm = ["node-runtime/wasmtime_vm"]
wasmer1_vm = ["node-runtime/wasmer1_vm"]
costs_counting = ["node-runtime/costs_counting"]

[[bin]]
Expand Down
10 changes: 10 additions & 0 deletions runtime/near-vm-errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ pub enum FunctionCallError {
WasmUnknownError,
HostError(HostError),
EvmError(EvmError),
/// An error message when wasmer 1.0 returns a wasmer::RuntimeError
WasmerRuntimeError(String),
/// A trap in Wasmer 1.0, not same as WasmTrap above, String is a machine readable form like "stk_ovf"
/// String is used instead of wasmer internal enum is because of BorshSerializable.
/// It can be convert back by wasmer_vm::TrapCode::from_str
Wasmer1Trap(String),
}
#[derive(
Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize, Deserialize, Serialize, RpcError,
Expand Down Expand Up @@ -278,6 +284,8 @@ pub enum VMLogicError {
EvmError(EvmError),
}

impl std::error::Error for VMLogicError {}

/// An error that is caused by an operation on an inconsistent state.
/// E.g. a deserialization error or an integer overflow.
#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize, Deserialize, Serialize)]
Expand Down Expand Up @@ -342,6 +350,8 @@ impl fmt::Display for FunctionCallError {
write!(f, "Unknown error during Wasm contract execution")
}
FunctionCallError::EvmError(e) => write!(f, "EVM: {:?}", e),
FunctionCallError::WasmerRuntimeError(e) => write!(f, "Wasmer Runtime: {}", e),
FunctionCallError::Wasmer1Trap(e) => write!(f, "Wasmer 1.0 trap: {}", e),
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions runtime/near-vm-logic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ num-rational = { version = "0.2.4" }
serde_json = {version= "1", features= ["preserve_order"]}

[features]
default = ["costs_counting"]
default = ["costs_counting", "wasmer_default"]
protocol_feature_evm = ["near-runtime-fees/protocol_feature_evm"]
wasmer_default = []
wasmtime_default = []

wasmer1_default = []

# Use this feature to enable counting of fees and costs applied.
costs_counting = []
Expand Down
47 changes: 40 additions & 7 deletions runtime/near-vm-logic/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,59 @@ use std::hash::{Hash, Hasher};

#[derive(Clone, Copy, Debug, Hash, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
pub enum VMKind {
/// Wasmer VM.
Wasmer,
/// Wasmer 0.17.x VM.
Wasmer0,
/// Wasmtime VM.
Wasmtime,
/// Wasmer 1.x VM.
Wasmer1,
}

impl Default for VMKind {
#[cfg(feature = "wasmer_default")]
#[cfg(all(
feature = "wasmer_default",
not(feature = "wasmer1_default"),
not(feature = "wasmtime_default")
))]
fn default() -> Self {
VMKind::Wasmer
VMKind::Wasmer0
}

#[cfg(feature = "wasmtime_default")]
#[cfg(all(
not(feature = "wasmer_default"),
feature = "wasmer1_default",
not(feature = "wasmtime_default")
))]
fn default() -> Self {
VMKind::Wasmer1
}

#[cfg(all(
not(feature = "wasmer_default"),
not(feature = "wasmer1_default"),
feature = "wasmtime_default"
))]
fn default() -> Self {
VMKind::Wasmtime
}

#[cfg(all(not(feature = "wasmer_default"), not(feature = "wasmtime_default")))]
#[cfg(all(
not(feature = "wasmer_default"),
not(feature = "wasmer1_default"),
not(feature = "wasmtime_default")
))]
fn default() -> Self {
VMKind::Wasmer0
}

// These features should be mutually exclusive, but implement this to --all-features
#[cfg(all(
feature = "wasmer_default",
feature = "wasmer1_default",
feature = "wasmtime_default"
))]
fn default() -> Self {
VMKind::Wasmer
VMKind::Wasmer0
}
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/near-vm-runner-standalone/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ strum = "0.18"
num-rational = { version = "0.2.4" }

near-vm-logic = { path = "../near-vm-logic", version = "2.3.0", features = ["costs_counting"]}
near-vm-runner = { path = "../near-vm-runner", version = "2.3.0", features = ["wasmtime_vm"] }
near-vm-runner = { path = "../near-vm-runner", version = "2.3.0", features = ["wasmtime_vm", "wasmer1_vm"] }
near-runtime-fees = { path = "../near-runtime-fees", version = "2.3.0" }

[features]
Expand Down
3 changes: 2 additions & 1 deletion runtime/near-vm-runner-standalone/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ fn main() {
let vm_kind: VMKind = match matches.value_of("vm-kind") {
Some(value) => match value {
"wasmtime" => VMKind::Wasmtime,
"wasmer" => VMKind::Wasmer,
"wasmer" => VMKind::Wasmer0,
"wasmer1" => VMKind::Wasmer1,
_ => VMKind::default(),
},
None => VMKind::default(),
Expand Down
7 changes: 6 additions & 1 deletion runtime/near-vm-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ This crate implements the specification of the interface that Near blockchain ex
borsh = "0.7.1"
wasmer-runtime = { version="0.17.1", features = ["default-backend-singlepass"], default-features = false, package = "wasmer-runtime-near" }
wasmer-runtime-core = {version = "0.17.1", package = "wasmer-runtime-core-near" }
ailisp marked this conversation as resolved.
Show resolved Hide resolved
wasmer = { git = "https://github.com/wasmerio/wasmer", rev="b4d2d8ee804a45850af2b3e012fdbbbdcb1185cb", optional = true }
ailisp marked this conversation as resolved.
Show resolved Hide resolved
wasmer-types = { git = "https://github.com/wasmerio/wasmer", rev="b4d2d8ee804a45850af2b3e012fdbbbdcb1185cb", optional = true }
wasmer-compiler-singlepass = { git = "https://github.com/wasmerio/wasmer", rev="b4d2d8ee804a45850af2b3e012fdbbbdcb1185cb", optional = true }
pwasm-utils = "0.12"
parity-wasm = "0.41"
wasmtime = { version = "0.20.0", default-features = false, optional = true }
Expand All @@ -33,11 +36,13 @@ wabt = "0.9"
bencher = "^0.1.5"

[features]
default = [ "wasmer_default" ]
default = [ "wasmer_default", "wasmer", "wasmer-types" ]
wasmtime_vm = [ "wasmtime", "anyhow"]
wasmer1_vm = [ "wasmer", "wasmer-types", "wasmer-compiler-singlepass" ]
lightbeam = ["wasmtime/lightbeam"]
wasmer_default = []
wasmtime_default = ["wasmtime_vm"]
wasmer1_default = [ "wasmer1_vm" ]
no_cpu_compatibility_checks = []
protocol_feature_evm = ["near-runtime-fees/protocol_feature_evm", "near-evm-runner/protocol_feature_evm"]

Expand Down
2 changes: 1 addition & 1 deletion runtime/near-vm-runner/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub(crate) fn compile_module_cached_wasmer(
if cache.is_none() {
return compile_module(wasm_code, config);
}
let key = get_key(wasm_code_hash, wasm_code, VMKind::Wasmer, config);
let key = get_key(wasm_code_hash, wasm_code, VMKind::Wasmer0, config);
let cache = cache.unwrap();
match cache.get(&(key.0).0) {
Ok(serialized) => match serialized {
Expand Down
16 changes: 14 additions & 2 deletions runtime/near-vm-runner/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
use near_vm_errors::VMError;

ailisp marked this conversation as resolved.
Show resolved Hide resolved
use near_vm_errors::{FunctionCallError, VMError, VMLogicError};
pub trait IntoVMError {
fn into_vm_error(self) -> VMError;
}

impl IntoVMError for &VMLogicError {
ailisp marked this conversation as resolved.
Show resolved Hide resolved
fn into_vm_error(self) -> VMError {
match self {
VMLogicError::HostError(h) => {
VMError::FunctionCallError(FunctionCallError::HostError(h.clone()))
}
VMLogicError::ExternalError(s) => VMError::ExternalError(s.clone()),
VMLogicError::InconsistentStateError(e) => VMError::InconsistentStateError(e.clone()),
VMLogicError::EvmError(_) => unreachable!("Wasm can't return EVM error"),
}
}
}
39 changes: 38 additions & 1 deletion runtime/near-vm-runner/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ use near_vm_logic::VMLogic;

use std::ffi::c_void;

struct ImportReference(*mut c_void);
#[derive(Clone)]
pub struct ImportReference(pub *mut c_void);
ailisp marked this conversation as resolved.
Show resolved Hide resolved
unsafe impl Send for ImportReference {}
unsafe impl Sync for ImportReference {}

use wasmer::{Memory, WasmerEnv};
ailisp marked this conversation as resolved.
Show resolved Hide resolved
#[derive(WasmerEnv, Clone)]
pub struct MyEnv {
ailisp marked this conversation as resolved.
Show resolved Hide resolved
pub memory: Memory,
pub logic: ImportReference,
}

// Wasm has only i32/i64 types, so Wasmtime 0.17 only accepts
// external functions taking i32/i64 type.
// Remove, once using version with https://github.com/bytecodealliance/wasmtime/issues/1829
Expand Down Expand Up @@ -38,6 +46,21 @@ macro_rules! wrapped_imports {
)*
}

#[cfg(feature = "wasmer1_vm")]
pub mod wasmer1_ext {
use near_vm_logic::VMLogic;
use crate::imports::MyEnv;

type VMResult<T> = ::std::result::Result<T, near_vm_logic::VMLogicError>;
$(
#[allow(unused_parens)]
pub fn $func(env: &MyEnv, $( $arg_name: $arg_type ),* ) -> VMResult<($( $returns ),*)> {
let logic: &mut VMLogic = unsafe { &mut *(env.logic.0 as *mut VMLogic<'_>) };
logic.$func( $( $arg_name, )* )
}
)*
}

#[cfg(feature = "wasmtime_vm")]
pub mod wasmtime_ext {
use near_vm_logic::{VMLogic, VMLogicError};
Expand Down Expand Up @@ -94,6 +117,20 @@ macro_rules! wrapped_imports {
}
}

#[cfg(feature = "wasmer1_vm")]
pub(crate) fn build_wasmer1(store: &wasmer::Store, memory: wasmer::Memory, logic: &mut VMLogic<'_>) ->
wasmer::ImportObject {
let env = MyEnv {logic: ImportReference(logic as * mut _ as * mut c_void), memory: memory.clone()};
wasmer::imports! {
"env" => {
"memory" => memory,
$(
stringify!($func) => wasmer::Function::new_native_with_env(&store, env.clone(), wasmer1_ext::$func),
)*
ailisp marked this conversation as resolved.
Show resolved Hide resolved
},
}
}

#[cfg(feature = "wasmtime_vm")]
pub(crate) fn link_wasmtime(
linker: &mut wasmtime::Linker,
Expand Down
5 changes: 5 additions & 0 deletions runtime/near-vm-runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ mod memory;
pub mod prepare;
mod runner;
mod wasmer_runner;

#[cfg(feature = "wasmtime_vm")]
mod wasmtime_runner;

#[cfg(feature = "wasmer1_vm")]
mod wasmer1_runner;

pub use near_vm_errors::VMError;
pub use runner::compile_module;
pub use runner::run;
Expand Down
Loading