Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Only use a minimal stack when never executing module
Browse files Browse the repository at this point in the history
  • Loading branch information
athei committed Oct 18, 2022
1 parent fa1605f commit eafd0dd
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
12 changes: 8 additions & 4 deletions frame/contracts/src/benchmarking/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::{code::WasmModule, Config};
/// ! environment that provides the seal interface as imported functions.
use crate::wasm::{Environment, PrefabWasmModule};
use sp_core::crypto::UncheckedFrom;
use wasmi::{errors::LinkerError, Func, Linker, Store};
use wasmi::{errors::LinkerError, Func, Linker, StackLimits, Store};

/// Minimal execution environment without any imported functions.
pub struct Sandbox {
Expand Down Expand Up @@ -49,9 +49,13 @@ where
.as_ref()
.map(|mem| (mem.min_pages, mem.max_pages))
.unwrap_or((0, 0));
let (store, _memory, instance) =
PrefabWasmModule::<T>::instantiate::<EmptyEnv, _>(&module.code, (), memory)
.expect("Failed to create benchmarking Sandbox instance");
let (store, _memory, instance) = PrefabWasmModule::<T>::instantiate::<EmptyEnv, _>(
&module.code,
(),
memory,
StackLimits::default(),
)
.expect("Failed to create benchmarking Sandbox instance");
let entry_point = instance.get_export(&store, "call").unwrap().into_func().unwrap();
Self { entry_point, store }
}
Expand Down
7 changes: 6 additions & 1 deletion frame/contracts/src/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ use sp_core::crypto::UncheckedFrom;
use sp_std::prelude::*;
#[cfg(test)]
pub use tests::MockExt;
use wasmi::{Config as WasmiConfig, Engine, Instance, Linker, Memory, MemoryType, Module, Store};
use wasmi::{
Config as WasmiConfig, Engine, Instance, Linker, Memory, MemoryType, Module, StackLimits, Store,
};

/// A prepared wasm module ready for execution.
///
Expand Down Expand Up @@ -170,12 +172,14 @@ where
code: &[u8],
host_state: H,
memory: (u32, u32),
stack_limits: StackLimits,
) -> Result<(Store<H>, Memory, Instance), wasmi::Error>
where
E: Environment<H>,
{
let mut config = WasmiConfig::default();
config
.set_stack_limits(stack_limits)
.wasm_multi_value(false)
.wasm_mutable_global(false)
.wasm_sign_extension(false)
Expand Down Expand Up @@ -260,6 +264,7 @@ where
self.code.as_slice(),
runtime,
(self.initial, self.maximum),
StackLimits::default(),
)
.map_err(|msg| {
log::debug!(target: "runtime::contracts", "failed to instantiate code: {}", msg);
Expand Down
19 changes: 14 additions & 5 deletions frame/contracts/src/wasm/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use sp_std::prelude::*;
use wasm_instrument::parity_wasm::elements::{
self, External, Internal, MemoryType, Type, ValueType,
};
use wasmi::StackLimits;

/// Imported memory must be located inside this module. The reason for hardcoding is that current
/// compiler toolchains might not support specifying other modules than "env" for memory imports.
Expand Down Expand Up @@ -447,11 +448,19 @@ where
// - Doesn't use any unknown imports.
// - Doesn't explode the wasmi bytecode generation.
if matches!(try_instantiate, TryInstantiate::Instantiate) {
PrefabWasmModule::<T>::instantiate::<E, _>(original_code.as_ref(), (), (initial, maximum))
.map_err(|err| {
log::debug!(target: "runtime::contracts", "{}", err);
(Error::<T>::CodeRejected.into(), "new code rejected after instrumentation")
})?;
// We don't actually ever run any code so we can get away with a minimal stack which
// reduces the amount of memory that needs to be zeroed.
let stack_limits = StackLimits::new(1, 1, 0).expect("initial <= max; qed");
PrefabWasmModule::<T>::instantiate::<E, _>(
original_code.as_ref(),
(),
(initial, maximum),
stack_limits,
)
.map_err(|err| {
log::debug!(target: "runtime::contracts", "{}", err);
(Error::<T>::CodeRejected.into(), "new code rejected after instrumentation")
})?;
}

let original_code_len = original_code.len();
Expand Down

0 comments on commit eafd0dd

Please sign in to comment.