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

chore(sandbox): Use wasmer in embedded executor #4276

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fb7dae0
Initial wasmer in embedded executor
ark0f Oct 3, 2024
10286e0
Log module errors
ark0f Oct 3, 2024
f3dd95d
Use caching in embedded executor
ark0f Oct 3, 2024
a0650e3
Fix host_executor.rs
ark0f Oct 4, 2024
1d89a42
add gear-wasmer-cache to STACKED_DEPENDENCIES
StackOverflowExcept1on Oct 5, 2024
e1c746a
Add debug options to cargo-xwin.sh
ark0f Oct 6, 2024
152b0ec
Try to fix halted tests
ark0f Oct 6, 2024
771db0b
Automatically exit wine when script finished
ark0f Oct 6, 2024
467239b
Fix manifest dir assertion
ark0f Oct 6, 2024
9303c62
Write wasmer cache in `OUT_DIR`
ark0f Oct 10, 2024
0f99bc5
Copy non-default profiles to WASM project
ark0f Oct 10, 2024
f011388
Merge remote-tracking branch 'origin/master' into al/embedded-wasmer
ark0f Oct 10, 2024
e808d69
Fix clippy warnings
ark0f Oct 10, 2024
ab6dbdc
Add feature `sys` to wasmer
ark0f Oct 10, 2024
e1430da
Create `wasmer::RuntimeError` lazily
ark0f Oct 14, 2024
9635e7d
Merge remote-tracking branch 'origin/master' into al/embedded-wasmer
ark0f Oct 14, 2024
607edb4
Always enable `singlepass` feature for wasmer
ark0f Oct 15, 2024
7852ddf
Fix `gsdk-api-gen` compilation
ark0f Oct 15, 2024
efda48a
Initialize executor traps lazily
ark0f Oct 15, 2024
90e4646
Remove `init_traps()` and use `wasmer-vm` directly instead
ark0f Oct 15, 2024
01fea98
A little cleanup
ark0f Oct 15, 2024
02f54f9
Add comment in build.rs
ark0f Oct 19, 2024
53fec3e
`wasmi` -> `wasmer`
ark0f Oct 19, 2024
e13b30c
Merge remote-tracking branch 'origin/master' into al/embedded-wasmer
ark0f Oct 19, 2024
ed5982c
Update comment in build.rs
ark0f Oct 19, 2024
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
175 changes: 85 additions & 90 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ wabt = "0.10.0"
wasmer = "4.3.4"
wasmer-cache = "4.3.4"
wasmer-types = "4.3.4"
wasmer-vm = "4.3.4"
wasmer-compiler = "4.3.4"
gear-wasmer-cache = { path = "utils/gear-wasmer-cache" }
wasmtime = "8.0.1"
wasmparser = { package = "wasmparser-nostd", version = "0.100.1", default-features = false }
which = "4.4.2"
Expand Down
18 changes: 9 additions & 9 deletions core-backend/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{
BackendExternalities,
};
use alloc::{collections::BTreeSet, format, string::String};
use core::{any::Any, fmt::Debug};
use core::{any::Any, fmt::Debug, marker::Send};
use gear_core::{
env::Externalities,
gas::GasAmount,
Expand Down Expand Up @@ -60,7 +60,7 @@ macro_rules! wrap_syscall {
};
}

fn store_host_state_mut<Ext>(
fn store_host_state_mut<Ext: Send + 'static>(
store: &mut Store<HostState<Ext, BackendMemory<ExecutorMemory>>>,
) -> &mut State<Ext, BackendMemory<ExecutorMemory>> {
store.data_mut().as_mut().unwrap_or_else(|| {
Expand Down Expand Up @@ -123,7 +123,7 @@ struct EnvBuilder<Ext: BackendExternalities> {

impl<Ext> EnvBuilder<Ext>
where
Ext: BackendExternalities + 'static,
Ext: BackendExternalities + Send + 'static,
Ext::UnrecoverableError: BackendSyscallError,
RunFallibleError: From<Ext::FallibleError>,
Ext::AllocError: BackendAllocSyscallError<ExtError = Ext::UnrecoverableError>,
Expand Down Expand Up @@ -159,7 +159,7 @@ impl<Ext: BackendExternalities> From<EnvBuilder<Ext>>

impl<Ext, EntryPoint> Environment<Ext, EntryPoint>
where
Ext: BackendExternalities + 'static,
Ext: BackendExternalities + Send + 'static,
Ext::UnrecoverableError: BackendSyscallError,
RunFallibleError: From<Ext::FallibleError>,
Ext::AllocError: BackendAllocSyscallError<ExtError = Ext::UnrecoverableError>,
Expand Down Expand Up @@ -232,9 +232,9 @@ struct GlobalsAccessProvider<Ext: Externalities> {
store: Option<Store<HostState<Ext, BackendMemory<ExecutorMemory>>>>,
}

impl<Ext: Externalities + 'static> GlobalsAccessor for GlobalsAccessProvider<Ext> {
fn get_i64(&self, name: &LimitedStr) -> Result<i64, GlobalsAccessError> {
let store = self.store.as_ref().ok_or(GlobalsAccessError)?;
impl<Ext: Externalities + Send + 'static> GlobalsAccessor for GlobalsAccessProvider<Ext> {
fn get_i64(&mut self, name: &LimitedStr) -> Result<i64, GlobalsAccessError> {
let store = self.store.as_mut().ok_or(GlobalsAccessError)?;
self.instance
.get_global_val(store, name.as_str())
.and_then(i64::try_from_value)
Expand All @@ -255,7 +255,7 @@ impl<Ext: Externalities + 'static> GlobalsAccessor for GlobalsAccessProvider<Ext

impl<EnvExt, EntryPoint> Environment<EnvExt, EntryPoint>
where
EnvExt: BackendExternalities + 'static,
EnvExt: BackendExternalities + Send + 'static,
EnvExt::UnrecoverableError: BackendSyscallError,
RunFallibleError: From<EnvExt::FallibleError>,
EnvExt::AllocError: BackendAllocSyscallError<ExtError = EnvExt::UnrecoverableError>,
Expand Down Expand Up @@ -440,7 +440,7 @@ where

// Fetching global value.
let gas = instance
.get_global_val(&store, GLOBAL_NAME_GAS)
.get_global_val(&mut store, GLOBAL_NAME_GAS)
.and_then(i64::try_from_value)
.ok_or(System(WrongInjectedGas))? as u64;

Expand Down
154 changes: 85 additions & 69 deletions core-backend/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ use crate::{
},
BackendExternalities,
};
use alloc::{collections::BTreeSet, rc::Rc, vec, vec::Vec};
use alloc::{collections::BTreeSet, vec::Vec};
use codec::{Decode, Encode};
use core::{cell::RefCell, fmt, fmt::Debug, mem};
use core::{fmt, fmt::Debug, mem};
use gear_core::{
costs::CostToken,
env::{Externalities, PayloadSliceLock, UnlockPayloadBound},
env_vars::{EnvVars, EnvVarsV1},
gas::{ChargeError, CounterType, CountersOwner, GasAmount, GasCounter, GasLeft},
ids::{MessageId, ProgramId, ReservationId},
memory::{HostPointer, Memory, MemoryError, MemoryInterval},
memory::{Memory, MemoryInterval},
message::{HandlePacket, InitPacket, ReplyPacket},
pages::{WasmPage, WasmPagesAmount},
pages::WasmPage,
};
use gear_core_errors::{ReplyCode, SignalCode};
use gear_lazy_pages_common::ProcessAccessError;
Expand Down Expand Up @@ -310,97 +310,113 @@ impl BackendExternalities for MockExt {
}
}

#[derive(Debug)]
struct InnerMockMemory {
pages: Vec<u8>,
read_attempt_count: u32,
write_attempt_count: u32,
}
#[cfg(feature = "std")]
pub use with_std_feature::*;

impl InnerMockMemory {
fn grow(&mut self, pages: WasmPagesAmount) -> u32 {
let size = self.pages.len() as u32;
let new_size = size + pages.offset() as u32;
self.pages.resize(new_size as usize, 0);
#[cfg(feature = "std")]
mod with_std_feature {
use gear_core::{
memory::{HostPointer, Memory, MemoryError},
pages::{WasmPage, WasmPagesAmount},
};
use std::sync::{Arc, Mutex, MutexGuard};

size / WasmPage::SIZE
#[derive(Debug)]
struct InnerMockMemory {
pages: Vec<u8>,
read_attempt_count: u32,
write_attempt_count: u32,
}

fn write(&mut self, offset: u32, buffer: &[u8]) -> Result<(), MemoryError> {
self.write_attempt_count += 1;
impl InnerMockMemory {
fn grow(&mut self, pages: WasmPagesAmount) -> u32 {
let size = self.pages.len() as u32;
let new_size = size + pages.offset() as u32;
self.pages.resize(new_size as usize, 0);

let offset = offset as usize;
if offset + buffer.len() > self.pages.len() {
return Err(MemoryError::AccessOutOfBounds);
size / WasmPage::SIZE
}

self.pages[offset..offset + buffer.len()].copy_from_slice(buffer);
fn write(&mut self, offset: u32, buffer: &[u8]) -> Result<(), MemoryError> {
self.write_attempt_count += 1;

Ok(())
}
let offset = offset as usize;
if offset + buffer.len() > self.pages.len() {
return Err(MemoryError::AccessOutOfBounds);
}

fn read(&mut self, offset: u32, buffer: &mut [u8]) -> Result<(), MemoryError> {
self.read_attempt_count += 1;
self.pages[offset..offset + buffer.len()].copy_from_slice(buffer);

let offset = offset as usize;
if offset + buffer.len() > self.pages.len() {
return Err(MemoryError::AccessOutOfBounds);
Ok(())
}

buffer.copy_from_slice(&self.pages[offset..(offset + buffer.len())]);
fn read(&mut self, offset: u32, buffer: &mut [u8]) -> Result<(), MemoryError> {
self.read_attempt_count += 1;

Ok(())
}
let offset = offset as usize;
if offset + buffer.len() > self.pages.len() {
return Err(MemoryError::AccessOutOfBounds);
}

buffer.copy_from_slice(&self.pages[offset..(offset + buffer.len())]);

Ok(())
}

fn size(&self) -> WasmPagesAmount {
WasmPage::from_offset(self.pages.len() as u32).into()
fn size(&self) -> WasmPagesAmount {
WasmPage::from_offset(self.pages.len() as u32).into()
}
}
}

#[derive(Debug, Clone)]
pub struct MockMemory(Rc<RefCell<InnerMockMemory>>);
#[derive(Debug, Clone)]
pub struct MockMemory(Arc<Mutex<InnerMockMemory>>);

impl MockMemory {
pub fn new(initial_pages: u32) -> Self {
let pages = vec![0; initial_pages as usize * WasmPage::SIZE as usize];
impl MockMemory {
pub fn new(initial_pages: u32) -> Self {
let pages = vec![0; initial_pages as usize * WasmPage::SIZE as usize];

Self(Rc::new(RefCell::new(InnerMockMemory {
pages,
read_attempt_count: 0,
write_attempt_count: 0,
})))
}
Self(Arc::new(Mutex::new(InnerMockMemory {
pages,
read_attempt_count: 0,
write_attempt_count: 0,
})))
}

pub fn read_attempt_count(&self) -> u32 {
self.0.borrow().read_attempt_count
}
fn lock(&self) -> MutexGuard<'_, InnerMockMemory> {
self.0.lock().unwrap()
}

pub fn write_attempt_count(&self) -> u32 {
self.0.borrow().write_attempt_count
pub fn read_attempt_count(&self) -> u32 {
self.lock().read_attempt_count
}

pub fn write_attempt_count(&self) -> u32 {
self.lock().write_attempt_count
}
}
}

impl<Context> Memory<Context> for MockMemory {
type GrowError = &'static str;
impl<Context> Memory<Context> for MockMemory {
type GrowError = &'static str;

fn grow(&self, _ctx: &mut Context, pages: WasmPagesAmount) -> Result<(), Self::GrowError> {
let _ = self.0.borrow_mut().grow(pages);
Ok(())
}
fn grow(&self, _ctx: &mut Context, pages: WasmPagesAmount) -> Result<(), Self::GrowError> {
let _ = self.lock().grow(pages);
Ok(())
}

fn size(&self, _ctx: &Context) -> WasmPagesAmount {
self.0.borrow_mut().size()
}
fn size(&self, _ctx: &Context) -> WasmPagesAmount {
self.lock().size()
}

fn write(&self, _ctx: &mut Context, offset: u32, buffer: &[u8]) -> Result<(), MemoryError> {
self.0.borrow_mut().write(offset, buffer)
}
fn write(&self, _ctx: &mut Context, offset: u32, buffer: &[u8]) -> Result<(), MemoryError> {
self.lock().write(offset, buffer)
}

fn read(&self, _ctx: &Context, offset: u32, buffer: &mut [u8]) -> Result<(), MemoryError> {
self.0.borrow_mut().read(offset, buffer)
}
fn read(&self, _ctx: &Context, offset: u32, buffer: &mut [u8]) -> Result<(), MemoryError> {
self.lock().read(offset, buffer)
}

unsafe fn get_buffer_host_addr_unsafe(&self, _ctx: &Context) -> HostPointer {
unimplemented!()
unsafe fn get_buffer_host_addr_unsafe(&self, _ctx: &Context) -> HostPointer {
unimplemented!()
}
}
}
4 changes: 2 additions & 2 deletions core-processor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub(crate) fn execute_wasm<Ext>(
msg_ctx_settings: ContextSettings,
) -> Result<DispatchResult, ExecutionError>
where
Ext: ProcessorExternalities + BackendExternalities + 'static,
Ext: ProcessorExternalities + BackendExternalities + Send + 'static,
<Ext as Externalities>::AllocError:
BackendAllocSyscallError<ExtError = Ext::UnrecoverableError>,
RunFallibleError: From<Ext::FallibleError>,
Expand Down Expand Up @@ -266,7 +266,7 @@ pub fn execute_for_reply<Ext, EP>(
block_info: BlockInfo,
) -> Result<Vec<u8>, String>
where
Ext: ProcessorExternalities + BackendExternalities + 'static,
Ext: ProcessorExternalities + BackendExternalities + Send + 'static,
<Ext as Externalities>::AllocError:
BackendAllocSyscallError<ExtError = Ext::UnrecoverableError>,
RunFallibleError: From<Ext::FallibleError>,
Expand Down
2 changes: 1 addition & 1 deletion core-processor/src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn process<Ext>(
random_data: (Vec<u8>, u32),
) -> Result<Vec<JournalNote>, SystemExecutionError>
where
Ext: ProcessorExternalities + BackendExternalities + 'static,
Ext: ProcessorExternalities + BackendExternalities + Send + 'static,
<Ext as Externalities>::AllocError:
BackendAllocSyscallError<ExtError = Ext::UnrecoverableError>,
RunFallibleError: From<Ext::FallibleError>,
Expand Down
8 changes: 4 additions & 4 deletions core/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ impl From<MemoryInterval> for (u32, u32) {

impl Debug for MemoryInterval {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&format!(
"[offset: {:#x}, size: {:#x}]",
self.offset, self.size
))
f.debug_struct("MemoryInterval")
.field("offset", &format_args!("{:#x}", self.offset))
.field("size", &format_args!("{:#x}", self.size))
.finish()
}
}

Expand Down
5 changes: 2 additions & 3 deletions ethexe/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,10 @@ mod tests {
let values: BTreeSet<(Vec<u8>, Vec<u8>)> = db.iter_prefix(b"prefix_").collect();
assert_eq!(
values,
[
BTreeSet::from([
(b"prefix_foo".to_vec(), b"hello".to_vec()),
(b"prefix_bar".to_vec(), b"world".to_vec()),
]
.into(),
]),
);
}

Expand Down
2 changes: 1 addition & 1 deletion ethexe/network/src/custom_connection_limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ mod tests {

assert_eq!(
map.inner.into_keys().collect::<HashSet<PeerId>>(),
Default::default()
HashSet::default()
);
}

Expand Down
5 changes: 4 additions & 1 deletion ethexe/runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ pub fn process_next_message<S: Storage, RI: RuntimeInterface<S>>(
instrumented_code: Option<InstrumentedCode>,
code_id: CodeId,
ri: &RI,
) -> Vec<JournalNote> {
) -> Vec<JournalNote>
where
<RI as RuntimeInterface<S>>::LazyPages: Send,
{
let block_info = ri.block_info();

log::trace!("Processing next message for program {program_id}");
Expand Down
1 change: 1 addition & 0 deletions lazy-pages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ derive_more.workspace = true
numerated.workspace = true

gear-sandbox-host.workspace = true
gear-sandbox.workspace = true
gear-core.workspace = true
gear-lazy-pages-common.workspace = true

Expand Down
2 changes: 1 addition & 1 deletion lazy-pages/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub struct GlobalsAccessError;
/// Globals access trait.
pub trait GlobalsAccessor {
/// Returns global `name` value, if `name` is I64 global export.
fn get_i64(&self, name: &LimitedStr) -> Result<i64, GlobalsAccessError>;
fn get_i64(&mut self, name: &LimitedStr) -> Result<i64, GlobalsAccessError>;
ByteNacked marked this conversation as resolved.
Show resolved Hide resolved

/// Set global `name` == `value`, if `name` is I64 global export.
fn set_i64(&mut self, name: &LimitedStr, value: i64) -> Result<(), GlobalsAccessError>;
Expand Down
4 changes: 2 additions & 2 deletions lazy-pages/src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct GlobalsAccessWasmRuntime<'a> {
}

impl<'a> GlobalsAccessor for GlobalsAccessWasmRuntime<'a> {
fn get_i64(&self, name: &LimitedStr) -> Result<i64, GlobalsAccessError> {
fn get_i64(&mut self, name: &LimitedStr) -> Result<i64, GlobalsAccessError> {
// SAFETY: this is safe because this method is called only from signal handler context
unsafe {
self.instance
Expand Down Expand Up @@ -81,7 +81,7 @@ struct GlobalsAccessNativeRuntime<'a, 'b> {
}

impl<'a, 'b> GlobalsAccessor for GlobalsAccessNativeRuntime<'a, 'b> {
fn get_i64(&self, name: &LimitedStr) -> Result<i64, GlobalsAccessError> {
fn get_i64(&mut self, name: &LimitedStr) -> Result<i64, GlobalsAccessError> {
self.inner_access_provider.get_i64(name)
}

Expand Down
Loading
Loading