Skip to content

Commit

Permalink
near-vm-runner: make runtimes non-default features (#10423)
Browse files Browse the repository at this point in the history
Helps end users who want to use just the data structures representing
the host interface available for contracts and such.

For nearcore specifically this changes very little – the
`runtime/runtime` crate enables all of these features so unless you're
building something that specifically depends on `near-vm` but not on
`node-runtime` (e.g. `cargo check -p near-vm-runner`) the features will
still get enabled.

The build of the `near-vm-runner` crate like this becomes quite minimal
by default (transitively "just" 150-ish common dependencies, many of
which come from `near-crypto`…)

Missing parts currently:

* [x] The `-p near-vm-runner --no-default-features` is not a test case
that's checked in the CI despite the changes to the Justfile. Something
is not missing in our Justfile setup if I need to maintain both in
parallel :/

Fixes? #10421
  • Loading branch information
nagisa authored Jan 15, 2024
1 parent ddbb531 commit 4772e05
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 76 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,16 @@ jobs:
with:
fail: true

check_non_default:
name: "Non-default configuration builds"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: baptiste0928/cargo-install@21a18ba3bf4a184d1804e8b759930d3471b1c941
with:
crate: just
- run: just check-non-default

cargo_audit:
name: "Cargo Audit"
runs-on: ubuntu-latest
Expand Down
21 changes: 0 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ export RUST_BACKTRACE := env("RUST_BACKTRACE", "short")
ci_hack_nextest_profile := if env("CI_HACKS", "0") == "1" { "--profile ci" } else { "" }

# all the tests, as close to CI as possible
test: test-ci test-extra
test *FLAGS: (test-ci FLAGS) test-extra

# only the tests that are exactly the same as the ones in CI
test-ci: (nextest "stable") (nextest "nightly") python-style-checks
test-ci *FLAGS: (nextest "stable" FLAGS) (nextest "nightly" FLAGS) check-non-default python-style-checks

# tests that are as close to CI as possible, but not exactly the same code
test-extra: check-lychee
Expand Down Expand Up @@ -54,6 +54,12 @@ nextest-integration TYPE *FLAGS:
nextest-integration TYPE *FLAGS:
@echo "Nextest integration tests are currently disabled on macos!"

# Check various build configurations that aren’t exercised by a plain `cargo nextest` work as
# anticipated.
check-non-default:
# Ensure that near-vm-runner always builds without default features enabled
cargo check -p near-vm-runner --no-default-features

# generate a codecov report for RULE
codecov RULE:
#!/usr/bin/env bash
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ near-telemetry.workspace = true
near-test-contracts.workspace = true
near-performance-metrics.workspace = true
near-undo-block.workspace = true
near-vm-runner.workspace = true
near-vm-runner = { workspace = true, features = [ "prepare" ] }
near-wallet-contract.workspace = true
nearcore.workspace = true
node-runtime.workspace = true
Expand Down
31 changes: 13 additions & 18 deletions runtime/near-vm-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ bn.workspace = true
borsh.workspace = true
ed25519-dalek.workspace = true
enum-map.workspace = true
finite-wasm = { workspace = true, features = ["instrument"] }
loupe.workspace = true
finite-wasm = { workspace = true, features = ["instrument"], optional = true }
memoffset.workspace = true
num-rational.workspace = true
once_cell.workspace = true
parity-wasm.workspace = true
parity-wasm = { workspace = true, optional = true }
prefix-sum-vec.workspace = true
ripemd.workspace = true
serde_repr.workspace = true
Expand All @@ -36,8 +35,8 @@ stdx.workspace = true
strum.workspace = true
thiserror.workspace = true
tracing.workspace = true
wasm-encoder.workspace = true
wasmparser.workspace = true
wasm-encoder = { workspace = true, optional = true }
wasmparser = { workspace = true, optional = true }
wasmtime = { workspace = true, optional = true }

near-crypto.workspace = true
Expand All @@ -46,8 +45,8 @@ near-parameters.workspace = true

# Old versions of pwasm-utils we need to preserve backwards compatibility under
# old protocol versions.
pwasm-utils_12.workspace = true
parity-wasm_41.workspace = true
pwasm-utils_12 = { workspace = true, optional = true }
parity-wasm_41 = { workspace = true, optional = true }

[target.'cfg(target_arch = "x86_64")'.dependencies]
wasmer-runtime = { workspace = true, optional = true }
Expand Down Expand Up @@ -82,30 +81,26 @@ nightly_protocol = [
"near-parameters/nightly_protocol",
"near-primitives-core/nightly_protocol",
]
# all vms enabled for now
default = [
"wasmer0_vm",
"wasmtime_vm",
"wasmer2_vm",
"near_vm",
]
wasmer0_vm = [ "wasmer-runtime", "wasmer-runtime-core" ]
wasmtime_vm = [ "wasmtime", "anyhow"]
wasmer0_vm = [ "wasmer-runtime", "wasmer-runtime-core", "prepare" ]
wasmtime_vm = [ "wasmtime", "anyhow", "prepare" ]
wasmer2_vm = [
"wasmer-compiler",
"wasmer-compiler-singlepass",
"wasmer-engine",
"wasmer-engine-universal",
"wasmer-types",
"wasmer-vm"
"wasmer-vm",
"prepare",
]
near_vm = [
"near-vm-compiler",
"near-vm-compiler-singlepass",
"near-vm-engine",
"near-vm-types",
"near-vm-vm"
"near-vm-vm",
"prepare",
]
prepare = [ "finite-wasm", "wasm-encoder", "wasmparser", "parity-wasm", "parity-wasm_41", "pwasm-utils_12" ]

no_cpu_compatibility_checks = []

Expand Down
39 changes: 23 additions & 16 deletions runtime/near-vm-runner/src/features.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
const REFERENCE_TYPES: bool = false;
const MULTI_VALUE: bool = false;
const BULK_MEMORY: bool = false;
const SIMD: bool = false;
const THREADS: bool = false;
const TAIL_CALL: bool = false;
const MULTI_MEMORY: bool = false;
const MEMORY64: bool = false;
const SATURATING_FLOAT_TO_INT: bool = false;
const EXCEPTIONS: bool = false;
const RELAXED_SIMD: bool = false;
const EXTENDED_COST: bool = false;
const COMPONENT_MODEL: bool = false;
const GC: bool = false;
const FUNCTION_REFERENCES: bool = false;
const MEMORY_CONTROL: bool = false;
#[allow(dead_code)]
mod opts {
pub(super) const REFERENCE_TYPES: bool = false;
pub(super) const MULTI_VALUE: bool = false;
pub(super) const BULK_MEMORY: bool = false;
pub(super) const SIMD: bool = false;
pub(super) const THREADS: bool = false;
pub(super) const TAIL_CALL: bool = false;
pub(super) const MULTI_MEMORY: bool = false;
pub(super) const MEMORY64: bool = false;
pub(super) const SATURATING_FLOAT_TO_INT: bool = false;
pub(super) const EXCEPTIONS: bool = false;
pub(super) const RELAXED_SIMD: bool = false;
pub(super) const EXTENDED_COST: bool = false;
pub(super) const COMPONENT_MODEL: bool = false;
pub(super) const GC: bool = false;
pub(super) const FUNCTION_REFERENCES: bool = false;
pub(super) const MEMORY_CONTROL: bool = false;
}
#[allow(unused_imports)]
use opts::*;

#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) struct WasmFeatures {
Expand All @@ -31,6 +36,7 @@ impl From<crate::logic::ContractPrepareVersion> for WasmFeatures {
}
}

#[cfg(feature = "finite-wasm")]
impl From<WasmFeatures> for finite_wasm::wasmparser::WasmFeatures {
fn from(f: WasmFeatures) -> Self {
finite_wasm::wasmparser::WasmFeatures {
Expand Down Expand Up @@ -59,6 +65,7 @@ impl From<WasmFeatures> for finite_wasm::wasmparser::WasmFeatures {
}
}

#[cfg(feature = "wasmparser")]
impl From<WasmFeatures> for wasmparser::WasmFeatures {
fn from(_: WasmFeatures) -> Self {
// /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\
Expand Down
18 changes: 18 additions & 0 deletions runtime/near-vm-runner/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
//! `for_each_available_import` takes care to invoke `M!` only for currently
//! available imports.
#[cfg(any(
feature = "wasmer0_vm",
feature = "wasmer2_vm",
feature = "near_vm",
feature = "wasmtime_vm"
))]
macro_rules! call_with_name {
( $M:ident => @in $mod:ident : $func:ident < [ $( $arg_name:ident : $arg_type:ident ),* ] -> [ $( $returns:ident ),* ] > ) => {
$M!($mod / $func : $func < [ $( $arg_name : $arg_type ),* ] -> [ $( $returns ),* ] >)
Expand All @@ -67,6 +73,12 @@ macro_rules! imports {
$( @as $name:ident : )?
$func:ident < [ $( $arg_name:ident : $arg_type:ident ),* ] -> [ $( $returns:ident ),* ] >,)*
) => {
#[cfg(any(
feature = "wasmer0_vm",
feature = "wasmer2_vm",
feature = "near_vm",
feature = "wasmtime_vm"
))]
macro_rules! for_each_available_import {
($config:expr, $M:ident) => {$(
$(#[cfg(feature = $feature_name)])?
Expand Down Expand Up @@ -705,6 +717,12 @@ pub(crate) mod wasmtime {

/// Constant-time string equality, work-around for `"foo" == "bar"` not working
/// in const context yet.
#[cfg(any(
feature = "wasmer0_vm",
feature = "wasmer2_vm",
feature = "near_vm",
feature = "wasmtime_vm"
))]
const fn str_eq(s1: &str, s2: &str) -> bool {
let s1 = s1.as_bytes();
let s2 = s2.as_bytes();
Expand Down
3 changes: 3 additions & 0 deletions runtime/near-vm-runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ mod code;
mod errors;
mod features;
mod imports;
#[cfg(feature = "prepare")]
mod instrument;
pub mod logic;
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
mod memory;
#[cfg(all(feature = "near_vm", target_arch = "x86_64"))]
mod near_vm_runner;
#[cfg(feature = "prepare")]
pub mod prepare;
mod profile;
mod runner;
Expand All @@ -35,5 +37,6 @@ pub use runner::{run, VM};
#[doc(hidden)]
pub mod internal {
pub use crate::runner::VMKindExt;
#[cfg(feature = "prepare")]
pub use wasmparser;
}
14 changes: 13 additions & 1 deletion runtime/near-vm-runner/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ pub trait VM {
}

pub trait VMKindExt {
fn is_available(&self) -> bool;
/// Make a [`VM`] for this [`VMKind`].
///
/// This is not intended to be used by code other than internal tools like
Expand All @@ -119,6 +120,14 @@ pub trait VMKindExt {
}

impl VMKindExt for VMKind {
fn is_available(&self) -> bool {
match self {
Self::Wasmer0 => cfg!(all(feature = "wasmer0_vm", target_arch = "x86_64")),
Self::Wasmtime => cfg!(feature = "wasmtime_vm"),
Self::Wasmer2 => cfg!(all(feature = "wasmer2_vm", target_arch = "x86_64")),
Self::NearVm => cfg!(all(feature = "near_vm", target_arch = "x86_64")),
}
}
fn runtime(&self, config: Config) -> Option<Box<dyn VM>> {
match self {
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
Expand All @@ -130,7 +139,10 @@ impl VMKindExt for VMKind {
#[cfg(all(feature = "near_vm", target_arch = "x86_64"))]
Self::NearVm => Some(Box::new(crate::near_vm_runner::NearVM::new(config))),
#[allow(unreachable_patterns)] // reachable when some of the VMs are disabled.
_ => None,
_ => {
let _ = config;
None
}
}
}
}
12 changes: 8 additions & 4 deletions runtime/near-vm-runner/src/tests/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ use crate::logic::Config;
use crate::logic::{CompiledContract, CompiledContractCache};
use crate::runner::VMKindExt;
use crate::runner::VMResult;
use crate::wasmer2_runner::Wasmer2VM;
use crate::ContractCode;
use crate::{prepare, MockCompiledContractCache};
use crate::MockCompiledContractCache;
use assert_matches::assert_matches;
use near_parameters::vm::VMKind;
use near_parameters::RuntimeFeesConfig;
use near_primitives_core::hash::CryptoHash;
use std::io;
use std::sync::atomic::{AtomicBool, Ordering};
use wasmer_compiler::{CpuFeature, Target};
use wasmer_engine::Executable;

#[test]
fn test_caches_compilation_error() {
Expand Down Expand Up @@ -102,7 +99,12 @@ fn make_cached_contract_call_vm(
}

#[test]
#[cfg(feature = "wasmer2_vm")]
fn test_wasmer2_artifact_output_stability() {
use crate::prepare;
use crate::wasmer2_runner::Wasmer2VM;
use wasmer_compiler::{CpuFeature, Target};
use wasmer_engine::Executable;
// If this test has failed, you want to adjust the necessary constants so that `cache::vm_hash`
// changes (and only then the hashes here).
//
Expand Down Expand Up @@ -171,8 +173,10 @@ fn test_wasmer2_artifact_output_stability() {
}

#[test]
#[cfg(feature = "near_vm")]
fn test_near_vm_artifact_output_stability() {
use crate::near_vm_runner::NearVM;
use crate::prepare;
use near_vm_compiler::{CpuFeature, Target};
// If this test has failed, you want to adjust the necessary constants so that `cache::vm_hash`
// changes (and only then the hashes here).
Expand Down
16 changes: 10 additions & 6 deletions runtime/near-vm-runner/src/tests/fuzzers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,19 @@ fn run_fuzz(code: &ContractCode, vm_kind: VMKind) -> VMResult {

#[test]
fn current_vm_does_not_crash_fuzzer() {
bolero::check!().with_arbitrary::<ArbitraryModule>().for_each(|module: &ArbitraryModule| {
let code = ContractCode::new(module.0.module.to_bytes(), None);
let config = test_vm_config();
let _result = run_fuzz(&code, config.vm_kind);
});
let config = test_vm_config();
if config.vm_kind.is_available() {
bolero::check!().with_arbitrary::<ArbitraryModule>().for_each(
|module: &ArbitraryModule| {
let code = ContractCode::new(module.0.module.to_bytes(), None);
let _result = run_fuzz(&code, config.vm_kind);
},
);
}
}

#[test]
#[cfg_attr(not(all(feature = "near_vm", target_arch = "x86_64")), ignore)]
#[cfg_attr(not(all(feature = "wasmtime_vm", feature = "near_vm", target_arch = "x86_64")), ignore)]
fn near_vm_and_wasmtime_agree_fuzzer() {
bolero::check!().with_arbitrary::<ArbitraryModule>().for_each(|module: &ArbitraryModule| {
let code = ContractCode::new(module.0.module.to_bytes(), None);
Expand Down
Loading

0 comments on commit 4772e05

Please sign in to comment.