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

fix(deps): no-std compile #6

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
3,038 changes: 1,562 additions & 1,476 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ members = [
"substrate/bin/node/testing",
"substrate/bin/utils/chain-spec-builder",
"substrate/bin/utils/subkey",
"substrate/client/allocator",
"substrate/client/api",
"substrate/client/authority-discovery",
"substrate/client/basic-authorship",
Expand Down Expand Up @@ -443,6 +442,7 @@ members = [
"substrate/frame/utility",
"substrate/frame/vesting",
"substrate/frame/whitelist",
"substrate/primitives/allocator",
"substrate/primitives/api",
"substrate/primitives/api/proc-macro",
"substrate/primitives/api/test",
Expand Down Expand Up @@ -1117,7 +1117,6 @@ rustix = { version = "0.36.7", default-features = false }
rustversion = { version = "1.0.17" }
rusty-fork = { version = "0.3.0", default-features = false }
safe-mix = { version = "1.0", default-features = false }
sc-allocator = { path = "substrate/client/allocator", default-features = false, version = "29.0.0" }
sc-authority-discovery = { path = "substrate/client/authority-discovery", default-features = false, version = "0.45.0" }
sc-basic-authorship = { path = "substrate/client/basic-authorship", default-features = false, version = "0.45.0" }
sc-block-builder = { path = "substrate/client/block-builder", default-features = false, version = "0.42.0" }
Expand Down Expand Up @@ -1215,6 +1214,7 @@ snowbridge-runtime-test-common = { path = "bridges/snowbridge/runtime/test-commo
snowbridge-system-runtime-api = { path = "bridges/snowbridge/pallets/system/runtime-api", default-features = false, version = "0.10.0" }
soketto = { version = "0.7.1" }
solochain-template-runtime = { path = "templates/solochain/runtime", version = "0.1.0" }
sp-allocator = { path = "substrate/primitives/allocator", default-features = false, version = "29.0.0" }
sp-api = { path = "substrate/primitives/api", default-features = false, version = "34.0.0" }
sp-api-proc-macro = { path = "substrate/primitives/api/proc-macro", default-features = false, version = "20.0.0" }
sp-application-crypto = { path = "substrate/primitives/application-crypto", default-features = false, version = "38.0.0" }
Expand Down Expand Up @@ -1272,6 +1272,7 @@ sp-trie = { path = "substrate/primitives/trie", default-features = false, versio
sp-version = { path = "substrate/primitives/version", default-features = false, version = "37.0.0" }
sp-version-proc-macro = { path = "substrate/primitives/version/proc-macro", default-features = false, version = "14.0.0" }
sp-wasm-interface = { path = "substrate/primitives/wasm-interface", default-features = false, version = "21.0.1" }
sp-wasm-interface-common = { path = "substrate/primitives/wasm-interface-common", default-features = false, version = "7.0.0" }
sp-weights = { path = "substrate/primitives/weights", default-features = false, version = "31.0.0" }
spinners = { version = "4.1.1" }
ss58-registry = { version = "1.34.0", default-features = false }
Expand Down
4 changes: 2 additions & 2 deletions substrate/client/executor/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
thiserror = { workspace = true }
wasm-instrument = { workspace = true, default-features = true }
sc-allocator.workspace = true
sc-allocator.default-features = true
sp-allocator.workspace = true
sp-allocator.default-features = true
sp-maybe-compressed-blob.workspace = true
sp-maybe-compressed-blob.default-features = true
sp-wasm-interface.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion substrate/client/executor/common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub enum Error {
Other(String),

#[error(transparent)]
Allocator(#[from] sc_allocator::Error),
Allocator(#[from] sp_allocator::Error),

#[error("Host function {0} execution failed with: {1}")]
FunctionExecution(String, String),
Expand Down
8 changes: 0 additions & 8 deletions substrate/client/executor/common/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@

use crate::error::Result;
use sp_wasm_interface::Pointer;
use std::ops::Range;

/// Construct a range from an offset to a data length after the offset.
/// Returns None if the end of the range would exceed some maximum offset.
pub fn checked_range(offset: usize, len: usize, max: usize) -> Option<Range<usize>> {
let end = offset.checked_add(len)?;
(end <= max).then(|| offset..end)
}

/// Provides safe memory access interface using an external buffer
pub trait MemoryTransfer {
Expand Down
7 changes: 6 additions & 1 deletion substrate/client/executor/common/src/wasm_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

use crate::error::Error;

pub use sc_allocator::AllocationStats;
pub use sp_allocator::AllocationStats;

/// Default heap allocation strategy.
pub const DEFAULT_HEAP_ALLOC_STRATEGY: HeapAllocStrategy =
Expand Down Expand Up @@ -69,6 +69,11 @@ pub trait WasmInstance: Send {
fn call_export(&mut self, method: &str, data: &[u8]) -> Result<Vec<u8>, Error> {
self.call(method.into(), data)
}

/// Get the value from a global with the given `name`.
///
/// This method is only suitable for getting immutable globals.
fn get_global_const(&mut self, name: &str) -> Result<Option<sp_wasm_interface::Value>, Error>;
}

/// Defines the heap pages allocation strategy the wasm runtime should use.
Expand Down
8 changes: 8 additions & 0 deletions substrate/client/executor/polkavm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ impl WasmInstance for Instance {

(Ok(output), None)
}

fn get_global_const(&mut self, _name: &str) -> Result<Option<sp_wasm_interface::Value>, Error> {
unimplemented!()
}
}

struct Context<'r, 'a>(&'r mut polkavm::Caller<'a, ()>);
Expand Down Expand Up @@ -153,6 +157,10 @@ impl<'r, 'a> FunctionContext for Context<'r, 'a> {
fn register_panic_error_message(&mut self, _message: &str) {
unimplemented!("'register_panic_error_message' is never used when running under PolkaVM");
}
fn with_caller_mut_impl(&mut self, _: sp_wasm_interface::FunctionContextToken, _context: *mut (), _callback: fn(*mut (), &mut sp_wasm_interface::Caller<sp_wasm_interface::StoreData>)) {

unimplemented!("unsupported under PolkaVM");
}
}

fn call_host_function(
Expand Down
10 changes: 5 additions & 5 deletions substrate/client/executor/wasmi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ readme = "README.md"
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
log = "0.4.17"
log = { workspace = true }
wasmi = { git = "https://github.com/gear-tech/wasmi", branch = "v0.13.2-sign-ext", features = ["virtual_memory"] }
sc-executor-common = { version = "0.10.0-dev", path = "../common" }
sp-allocator = { version = "4.1.0-dev", path = "../../../primitives/allocator" }
sp-runtime-interface = { version = "7.0.0", path = "../../../primitives/runtime-interface" }
sp-wasm-interface = { version = "7.0.0", path = "../../../primitives/wasm-interface" }
sc-executor-common = { workspace = true }
sp-allocator = { workspace = true }
sp-runtime-interface = { workspace = true }
sp-wasm-interface = { workspace = true }
4 changes: 2 additions & 2 deletions substrate/client/executor/wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ wasmtime = { features = [
"pooling-allocator",
], workspace = true }
anyhow = { workspace = true }
sc-allocator.workspace = true
sc-allocator.default-features = true
sp-allocator.workspace = true
sp-allocator.default-features = true
sc-executor-common.workspace = true
sc-executor-common.default-features = true
sp-runtime-interface.workspace = true
Expand Down
93 changes: 19 additions & 74 deletions substrate/client/executor/wasmtime/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,10 @@

use wasmtime::Caller;

use sc_allocator::{AllocationStats, FreeingBumpHeapAllocator};
use sp_wasm_interface::{Pointer, WordSize};
pub use sp_wasm_interface::HostState;
use sp_wasm_interface::{util, FunctionContextToken, Pointer, WordSize};

use crate::{instance_wrapper::MemoryWrapper, runtime::StoreData, util};

/// The state required to construct a HostContext context. The context only lasts for one host
/// call, whereas the state is maintained for the duration of a Wasm runtime call, which may make
/// many different host calls that must share state.
pub struct HostState {
/// The allocator instance to keep track of allocated memory.
///
/// This is stored as an `Option` as we need to temporarily set this to `None` when we are
/// allocating/deallocating memory. The problem being that we can only mutable access `caller`
/// once.
allocator: Option<FreeingBumpHeapAllocator>,
panic_message: Option<String>,
}

impl HostState {
/// Constructs a new `HostState`.
pub fn new(allocator: FreeingBumpHeapAllocator) -> Self {
HostState { allocator: Some(allocator), panic_message: None }
}

/// Takes the error message out of the host state, leaving a `None` in its place.
pub fn take_panic_message(&mut self) -> Option<String> {
self.panic_message.take()
}

pub(crate) fn allocation_stats(&self) -> AllocationStats {
self.allocator.as_ref()
.expect("Allocator is always set and only unavailable when doing an allocation/deallocation; qed")
.stats()
}
}
use crate::runtime::StoreData;

/// A `HostContext` implements `FunctionContext` for making host calls from a Wasmtime
/// runtime. The `HostContext` exists only for the lifetime of the call and borrows state from
Expand All @@ -64,15 +33,6 @@ pub(crate) struct HostContext<'a> {
pub(crate) caller: Caller<'a, StoreData>,
}

impl<'a> HostContext<'a> {
fn host_state_mut(&mut self) -> &mut HostState {
self.caller
.data_mut()
.host_state_mut()
.expect("host state is not empty when calling a function in wasm; qed")
}
}

impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> {
fn read_memory_into(
&self,
Expand All @@ -87,42 +47,27 @@ impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> {
}

fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result<Pointer<u8>> {
let memory = self.caller.data().memory();
let mut allocator = self
.host_state_mut()
.allocator
.take()
.expect("allocator is not empty when calling a function in wasm; qed");

// We can not return on error early, as we need to store back allocator.
let res = allocator
.allocate(&mut MemoryWrapper(&memory, &mut self.caller), size)
.map_err(|e| e.to_string());

self.host_state_mut().allocator = Some(allocator);

res
util::allocate_memory(&mut self.caller, size)
}

fn deallocate_memory(&mut self, ptr: Pointer<u8>) -> sp_wasm_interface::Result<()> {
let memory = self.caller.data().memory();
let mut allocator = self
.host_state_mut()
.allocator
.take()
.expect("allocator is not empty when calling a function in wasm; qed");

// We can not return on error early, as we need to store back allocator.
let res = allocator
.deallocate(&mut MemoryWrapper(&memory, &mut self.caller), ptr)
.map_err(|e| e.to_string());

self.host_state_mut().allocator = Some(allocator);

res
util::deallocate_memory(&mut self.caller, ptr)
}

fn register_panic_error_message(&mut self, message: &str) {
self.host_state_mut().panic_message = Some(message.to_owned());
self.caller
.data_mut()
.host_state_mut()
.expect("host state is not empty when calling a function in wasm; qed")
.panic_message = Some(message.to_owned());
}

fn with_caller_mut_impl(
&mut self,
_: FunctionContextToken,
context: *mut (),
callback: fn(*mut (), &mut Caller<StoreData>),
) {
callback(context, &mut self.caller)
}
}
59 changes: 22 additions & 37 deletions substrate/client/executor/wasmtime/src/instance_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ use std::sync::Arc;

use crate::runtime::{InstanceCounter, ReleaseInstanceHandle, Store, StoreData};
use sc_executor_common::error::{Backtrace, Error, MessageWithBacktrace, Result, WasmError};
use sp_wasm_interface::{Pointer, WordSize};
use wasmtime::{AsContext, AsContextMut, Engine, Instance, InstancePre, Memory};
use sp_wasm_interface::{Pointer, Value, WordSize};
use wasmtime::{
AsContext, AsContextMut, Engine, Extern, Instance, InstancePre, Memory, Table, Val,
};

/// Wasm blob entry point.
pub struct EntryPoint(wasmtime::TypedFunc<(u32, u32), u64>);
Expand Down Expand Up @@ -73,41 +75,6 @@ impl EntryPoint {
}
}

/// Wrapper around [`Memory`] that implements [`sc_allocator::Memory`].
pub(crate) struct MemoryWrapper<'a, C>(pub &'a wasmtime::Memory, pub &'a mut C);

impl<C: AsContextMut> sc_allocator::Memory for MemoryWrapper<'_, C> {
fn with_access_mut<R>(&mut self, run: impl FnOnce(&mut [u8]) -> R) -> R {
run(self.0.data_mut(&mut self.1))
}

fn with_access<R>(&self, run: impl FnOnce(&[u8]) -> R) -> R {
run(self.0.data(&self.1))
}

fn grow(&mut self, additional: u32) -> std::result::Result<(), ()> {
self.0
.grow(&mut self.1, additional as u64)
.map_err(|e| {
log::error!(
target: "wasm-executor",
"Failed to grow memory by {} pages: {}",
additional,
e,
)
})
.map(drop)
}

fn pages(&self) -> u32 {
self.0.size(&self.1) as u32
}

fn max_pages(&self) -> Option<u32> {
self.0.ty(&self.1).maximum().map(|p| p as _)
}
}

/// Wrap the given WebAssembly Instance of a wasm module with Substrate-runtime.
///
/// This struct is a handy wrapper around a wasmtime `Instance` that provides substrate specific
Expand Down Expand Up @@ -181,6 +148,24 @@ impl InstanceWrapper {

Ok(heap_base as u32)
}

/// Get the value from a global with the given `name`.
pub fn get_global_val(&mut self, name: &str) -> Result<Option<Value>> {
let global = match self.instance.get_export(&mut self.store, name) {
Some(global) => global,
None => return Ok(None),
};

let global = global.into_global().ok_or_else(|| format!("`{}` is not a global", name))?;

match global.get(&mut self.store) {
Val::I32(val) => Ok(Some(Value::I32(val))),
Val::I64(val) => Ok(Some(Value::I64(val))),
Val::F32(val) => Ok(Some(Value::F32(val))),
Val::F64(val) => Ok(Some(Value::F64(val))),
_ => Err("Unknown value type".into()),
}
}
}

/// Extract linear memory instance from the given instance.
Expand Down
Loading
Loading