mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 01:11:10 +00:00
contracts: Replace sp-sandbox and wasmi-validation by newest wasmi (#12501)
* Replace sp-sandbox and wasmi-validation by just wasmi * ".git/.scripts/bench-bot.sh" pallet dev pallet_contracts * Re-check original code on re-instrumentation * Fix clippy * ".git/.scripts/bench-bot.sh" pallet dev pallet_contracts * Apply suggestions from code review Co-authored-by: Robin Freyler <robin.freyler@gmail.com> * Replace wasmi by ::wasmi * Bump wasmi to 0.20 * Add explanation for `unreachable` * Change proof * Fixup master merge * ".git/.scripts/bench-bot.sh" pallet dev pallet_contracts * Fixup naming inconsistencies introduced by reentrancy PR * Fix `scan_imports` docs * Apply suggestions from code review Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * Fixup suggestions * Remove unnecessary &mut * Fix test * ".git/.scripts/bench-bot.sh" pallet dev pallet_contracts * Fix benchmark merge fail * ".git/.scripts/bench-bot.sh" pallet dev pallet_contracts * Fix docs as suggested by code review * Improve docs for `CodeRejected` * Apply suggestions from code review Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * Fix logic bug when setting `deterministic_only` * Don't panic when module fails to compile * Apply suggestions from code review Co-authored-by: Robin Freyler <robin.freyler@gmail.com> Co-authored-by: command-bot <> Co-authored-by: Robin Freyler <robin.freyler@gmail.com> Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>
This commit is contained in:
committed by
GitHub
parent
e69c3649b5
commit
08657f14b7
@@ -28,10 +28,6 @@ use crate::{Config, Determinism};
|
||||
use frame_support::traits::Get;
|
||||
use sp_core::crypto::UncheckedFrom;
|
||||
use sp_runtime::traits::Hash;
|
||||
use sp_sandbox::{
|
||||
default_executor::{EnvironmentDefinitionBuilder, Memory},
|
||||
SandboxEnvironmentBuilder, SandboxMemory,
|
||||
};
|
||||
use sp_std::{borrow::ToOwned, prelude::*};
|
||||
use wasm_instrument::parity_wasm::{
|
||||
builder,
|
||||
@@ -128,7 +124,7 @@ pub struct ImportedFunction {
|
||||
pub struct WasmModule<T: Config> {
|
||||
pub code: Vec<u8>,
|
||||
pub hash: <T::Hashing as Hash>::Output,
|
||||
memory: Option<ImportedMemory>,
|
||||
pub memory: Option<ImportedMemory>,
|
||||
}
|
||||
|
||||
impl<T: Config> From<ModuleDefinition> for WasmModule<T>
|
||||
@@ -395,16 +391,6 @@ where
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Creates a memory instance for use in a sandbox with dimensions declared in this module
|
||||
/// and adds it to `env`. A reference to that memory is returned so that it can be used to
|
||||
/// access the memory contents from the supervisor.
|
||||
pub fn add_memory<S>(&self, env: &mut EnvironmentDefinitionBuilder<S>) -> Option<Memory> {
|
||||
let memory = if let Some(memory) = &self.memory { memory } else { return None };
|
||||
let memory = Memory::new(memory.min_pages, Some(memory.max_pages)).unwrap();
|
||||
env.add_memory("env", "memory", memory.clone());
|
||||
Some(memory)
|
||||
}
|
||||
|
||||
pub fn unary_instr(instr: Instruction, repeat: u32) -> Self {
|
||||
use body::DynInstr::{RandomI64Repeated, Regular};
|
||||
ModuleDefinition {
|
||||
|
||||
@@ -425,7 +425,7 @@ benchmarks! {
|
||||
.map(|n| account::<T::AccountId>("account", n, 0))
|
||||
.collect::<Vec<_>>();
|
||||
let account_len = accounts.get(0).map(|i| i.encode().len()).unwrap_or(0);
|
||||
let accounts_bytes = accounts.iter().map(|a| a.encode()).flatten().collect::<Vec<_>>();
|
||||
let accounts_bytes = accounts.iter().flat_map(|a| a.encode()).collect::<Vec<_>>();
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
memory: Some(ImportedMemory::max::<T>()),
|
||||
imported_functions: vec![ImportedFunction {
|
||||
@@ -462,7 +462,7 @@ benchmarks! {
|
||||
.map(|n| account::<T::AccountId>("account", n, 0))
|
||||
.collect::<Vec<_>>();
|
||||
let account_len = accounts.get(0).map(|i| i.encode().len()).unwrap_or(0);
|
||||
let accounts_bytes = accounts.iter().map(|a| a.encode()).flatten().collect::<Vec<_>>();
|
||||
let accounts_bytes = accounts.iter().flat_map(|a| a.encode()).collect::<Vec<_>>();
|
||||
let accounts_len = accounts_bytes.len();
|
||||
let pages = code::max_pages::<T>();
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
@@ -2014,10 +2014,9 @@ benchmarks! {
|
||||
let r in 0 .. 1;
|
||||
let key_type = sp_core::crypto::KeyTypeId(*b"code");
|
||||
let pub_keys_bytes = (0..r * API_BENCHMARK_BATCH_SIZE)
|
||||
.map(|_| {
|
||||
.flat_map(|_| {
|
||||
sp_io::crypto::ecdsa_generate(key_type, None).0
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
let pub_keys_bytes_len = pub_keys_bytes.len() as i32;
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
@@ -2086,13 +2085,13 @@ benchmarks! {
|
||||
let origin = RawOrigin::Signed(instance.caller.clone());
|
||||
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
|
||||
|
||||
reentrant_count {
|
||||
seal_reentrance_count {
|
||||
let r in 0 .. API_BENCHMARK_BATCHES;
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
memory: Some(ImportedMemory::max::<T>()),
|
||||
imported_functions: vec![ImportedFunction {
|
||||
module: "__unstable__",
|
||||
name: "reentrant_count",
|
||||
name: "reentrance_count",
|
||||
params: vec![],
|
||||
return_type: Some(ValueType::I32),
|
||||
}],
|
||||
@@ -2106,7 +2105,7 @@ benchmarks! {
|
||||
let origin = RawOrigin::Signed(instance.caller.clone());
|
||||
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
|
||||
|
||||
account_reentrance_count {
|
||||
seal_account_reentrance_count {
|
||||
let r in 0 .. API_BENCHMARK_BATCHES;
|
||||
let dummy_code = WasmModule::<T>::dummy_with_bytes(0);
|
||||
let accounts = (0..r * API_BENCHMARK_BATCH_SIZE)
|
||||
@@ -2921,7 +2920,7 @@ benchmarks! {
|
||||
#[extra]
|
||||
ink_erc20_transfer {
|
||||
let g in 0 .. 1;
|
||||
let gas_metering = if g == 0 { false } else { true };
|
||||
let gas_metering = g != 0;
|
||||
let code = load_benchmark!("ink_erc20");
|
||||
let data = {
|
||||
let new: ([u8; 4], BalanceOf<T>) = ([0x9b, 0xae, 0x9d, 0x5e], 1000u32.into());
|
||||
@@ -2959,7 +2958,7 @@ benchmarks! {
|
||||
#[extra]
|
||||
solang_erc20_transfer {
|
||||
let g in 0 .. 1;
|
||||
let gas_metering = if g == 0 { false } else { true };
|
||||
let gas_metering = g != 0;
|
||||
let code = include_bytes!("../../benchmarks/solang_erc20.wasm");
|
||||
let caller = account::<T::AccountId>("instantiator", 0, 0);
|
||||
let mut balance = [0u8; 32];
|
||||
|
||||
@@ -19,22 +19,20 @@
|
||||
/// ! sandbox to execute the wasm code. This is because we do not need the full
|
||||
/// ! environment that provides the seal interface as imported functions.
|
||||
use super::{code::WasmModule, Config};
|
||||
use crate::wasm::{Environment, PrefabWasmModule};
|
||||
use sp_core::crypto::UncheckedFrom;
|
||||
use sp_sandbox::{
|
||||
default_executor::{EnvironmentDefinitionBuilder, Instance, Memory},
|
||||
SandboxEnvironmentBuilder, SandboxInstance,
|
||||
};
|
||||
use wasmi::{errors::LinkerError, Func, Linker, StackLimits, Store};
|
||||
|
||||
/// Minimal execution environment without any exported functions.
|
||||
/// Minimal execution environment without any imported functions.
|
||||
pub struct Sandbox {
|
||||
instance: Instance<()>,
|
||||
_memory: Option<Memory>,
|
||||
entry_point: Func,
|
||||
store: Store<()>,
|
||||
}
|
||||
|
||||
impl Sandbox {
|
||||
/// Invoke the `call` function of a contract code and panic on any execution error.
|
||||
pub fn invoke(&mut self) {
|
||||
self.instance.invoke("call", &[], &mut ()).unwrap();
|
||||
self.entry_point.call(&mut self.store, &[], &mut []).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +44,27 @@ where
|
||||
/// Creates an instance from the supplied module and supplies as much memory
|
||||
/// to the instance as the module declares as imported.
|
||||
fn from(module: &WasmModule<T>) -> Self {
|
||||
let mut env_builder = EnvironmentDefinitionBuilder::new();
|
||||
let memory = module.add_memory(&mut env_builder);
|
||||
let instance = Instance::new(&module.code, &env_builder, &mut ())
|
||||
.expect("Failed to create benchmarking Sandbox instance");
|
||||
Self { instance, _memory: memory }
|
||||
let memory = module
|
||||
.memory
|
||||
.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,
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
struct EmptyEnv;
|
||||
|
||||
impl Environment<()> for EmptyEnv {
|
||||
fn define(_store: &mut Store<()>, _linker: &mut Linker<()>) -> Result<(), LinkerError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user