Allow single opcode stepping for EVM (#9051)
* Feed in ActionParams on VM creation * Fix ethcore after Vm interface change * Move informant inside Interpreter struct * Move do_trace to Interpreter struct * Move all remaining exec variables to Interpreter struct * Refactor VM to allow single opcode step * Fix all EVM tests * Fix all wasm tests * Fix wasm runner tests * Fix a check case where code length is zero * Fix jsontests compile * Fix cargo lock * Use match instead of expect * Use cheaper check reader.len() == 0 for the initial special case * Get rid of try_and_done! macro by using Result<(), ReturnType> * Use Never instead of () * Fix parity-bytes path * Bypass gasometer lifetime problem by borrow only for a instance * typo: missing { * Fix ethcore test compile * Fix evm tests
This commit is contained in:
parent
98dbd1fdc7
commit
9c595aff95
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1007,6 +1007,7 @@ dependencies = [
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory-cache 0.1.0",
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
|
@ -5,6 +5,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
bit-set = "0.4"
|
||||
parity-bytes = { git = "https://github.com/paritytech/parity-common" }
|
||||
ethereum-types = "0.3"
|
||||
heapsize = "0.4"
|
||||
lazy_static = "1.0"
|
||||
|
@ -55,6 +55,12 @@ impl Finalize for Result<GasLeft> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Finalize for Error {
|
||||
fn finalize<E: Ext>(self, _ext: E) -> Result<FinalizationResult> {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Cost calculation type. For low-gas usage we calculate costs using usize instead of U256
|
||||
pub trait CostType: Sized + From<usize> + Copy
|
||||
+ ops::Mul<Output=Self> + ops::Div<Output=Self> + ops::Add<Output=Self> +ops::Sub<Output=Self>
|
||||
|
@ -17,8 +17,9 @@
|
||||
//! Evm factory.
|
||||
//!
|
||||
use std::sync::Arc;
|
||||
use vm::Vm;
|
||||
use vm::{Vm, Schedule};
|
||||
use ethereum_types::U256;
|
||||
use super::vm::ActionParams;
|
||||
use super::interpreter::SharedCache;
|
||||
use super::vmtype::VMType;
|
||||
|
||||
@ -32,12 +33,12 @@ pub struct Factory {
|
||||
impl Factory {
|
||||
/// Create fresh instance of VM
|
||||
/// Might choose implementation depending on supplied gas.
|
||||
pub fn create(&self, gas: &U256) -> Box<Vm> {
|
||||
pub fn create(&self, params: ActionParams, schedule: &Schedule, depth: usize) -> Box<Vm> {
|
||||
match self.evm {
|
||||
VMType::Interpreter => if Self::can_fit_in_usize(gas) {
|
||||
Box::new(super::interpreter::Interpreter::<usize>::new(self.evm_cache.clone()))
|
||||
VMType::Interpreter => if Self::can_fit_in_usize(¶ms.gas) {
|
||||
Box::new(super::interpreter::Interpreter::<usize>::new(params, self.evm_cache.clone(), schedule, depth))
|
||||
} else {
|
||||
Box::new(super::interpreter::Interpreter::<U256>::new(self.evm_cache.clone()))
|
||||
Box::new(super::interpreter::Interpreter::<U256>::new(params, self.evm_cache.clone(), schedule, depth))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,7 +69,14 @@ impl Default for Factory {
|
||||
|
||||
#[test]
|
||||
fn test_create_vm() {
|
||||
let _vm = Factory::default().create(&U256::zero());
|
||||
use vm::Ext;
|
||||
use vm::tests::FakeExt;
|
||||
use bytes::Bytes;
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.code = Some(Arc::new(Bytes::default()));
|
||||
let ext = FakeExt::new();
|
||||
let _vm = Factory::default().create(params, ext.schedule(), ext.depth());
|
||||
}
|
||||
|
||||
/// Create tests by injecting different VM factories
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@ extern crate heapsize;
|
||||
extern crate vm;
|
||||
extern crate keccak_hash as hash;
|
||||
extern crate memory_cache;
|
||||
extern crate parity_bytes as bytes;
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
@ -21,7 +21,7 @@ use std::sync::Arc;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use rustc_hex::FromHex;
|
||||
use ethereum_types::{U256, H256, Address};
|
||||
use vm::{self, ActionParams, ActionValue};
|
||||
use vm::{self, ActionParams, ActionValue, Ext};
|
||||
use vm::tests::{FakeExt, FakeCall, FakeCallType, test_finalize};
|
||||
use factory::Factory;
|
||||
use vmtype::VMType;
|
||||
@ -38,8 +38,8 @@ fn test_add(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_988));
|
||||
@ -58,8 +58,8 @@ fn test_sha3(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_961));
|
||||
@ -78,8 +78,8 @@ fn test_address(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -100,8 +100,8 @@ fn test_origin(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -122,8 +122,8 @@ fn test_sender(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -157,8 +157,8 @@ fn test_extcodecopy(factory: super::Factory) {
|
||||
ext.codes.insert(sender, Arc::new(sender_code));
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_935));
|
||||
@ -177,8 +177,8 @@ fn test_log_empty(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(99_619));
|
||||
@ -209,8 +209,8 @@ fn test_log_sender(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(98_974));
|
||||
@ -234,8 +234,8 @@ fn test_blockhash(factory: super::Factory) {
|
||||
ext.blockhashes.insert(U256::zero(), blockhash.clone());
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_974));
|
||||
@ -256,8 +256,8 @@ fn test_calldataload(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_991));
|
||||
@ -277,8 +277,8 @@ fn test_author(factory: super::Factory) {
|
||||
ext.info.author = author;
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -297,8 +297,8 @@ fn test_timestamp(factory: super::Factory) {
|
||||
ext.info.timestamp = timestamp;
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -317,8 +317,8 @@ fn test_number(factory: super::Factory) {
|
||||
ext.info.number = number;
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -337,8 +337,8 @@ fn test_difficulty(factory: super::Factory) {
|
||||
ext.info.difficulty = difficulty;
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -357,8 +357,8 @@ fn test_gas_limit(factory: super::Factory) {
|
||||
ext.info.gas_limit = gas_limit;
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(79_995));
|
||||
@ -375,8 +375,8 @@ fn test_mul(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "000000000000000000000000000000000000000000000000734349397b853383");
|
||||
@ -393,8 +393,8 @@ fn test_sub(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000012364ad0302");
|
||||
@ -411,8 +411,8 @@ fn test_div(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "000000000000000000000000000000000000000000000000000000000002e0ac");
|
||||
@ -429,8 +429,8 @@ fn test_div_zero(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
@ -447,8 +447,8 @@ fn test_mod(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000076b4b");
|
||||
@ -466,8 +466,8 @@ fn test_smod(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000076b4b");
|
||||
@ -485,8 +485,8 @@ fn test_sdiv(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "000000000000000000000000000000000000000000000000000000000002e0ac");
|
||||
@ -504,8 +504,8 @@ fn test_exp(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "90fd23767b60204c3d6fc8aec9e70a42a3f127140879c133a20129a597ed0c59");
|
||||
@ -524,8 +524,8 @@ fn test_comparison(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
@ -545,8 +545,8 @@ fn test_signed_comparison(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
@ -566,8 +566,8 @@ fn test_bitops(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "00000000000000000000000000000000000000000000000000000000000000f0");
|
||||
@ -589,8 +589,8 @@ fn test_addmod_mulmod(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000001");
|
||||
@ -610,8 +610,8 @@ fn test_byte(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
@ -629,8 +629,8 @@ fn test_signextend(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000fff");
|
||||
@ -649,8 +649,8 @@ fn test_badinstruction_int() {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let err = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap_err()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap_err()
|
||||
};
|
||||
|
||||
match err {
|
||||
@ -669,8 +669,8 @@ fn test_pop(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "00000000000000000000000000000000000000000000000000000000000000f0");
|
||||
@ -689,8 +689,8 @@ fn test_extops(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000004"); // PC / CALLDATASIZE
|
||||
@ -712,8 +712,8 @@ fn test_jumps(factory: super::Factory) {
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(ext.sstore_clears, 1);
|
||||
@ -740,8 +740,8 @@ fn test_calls(factory: super::Factory) {
|
||||
};
|
||||
|
||||
let gas_left = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_set_contains(&ext.calls, &FakeCall {
|
||||
@ -781,8 +781,8 @@ fn test_create_in_staticcall(factory: super::Factory) {
|
||||
ext.is_static = true;
|
||||
|
||||
let err = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap_err()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap_err()
|
||||
};
|
||||
|
||||
assert_eq!(err, vm::Error::MutableCallInStaticContext);
|
||||
@ -1049,8 +1049,8 @@ fn push_two_pop_one_constantinople_test(factory: &super::Factory, opcode: u8, pu
|
||||
let mut ext = FakeExt::new_constantinople();
|
||||
|
||||
let _ = {
|
||||
let mut vm = factory.create(¶ms.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap()
|
||||
let mut vm = factory.create(params, ext.schedule(), ext.depth());
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_store(&ext, 0, result);
|
||||
|
@ -354,23 +354,22 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
// Ordinary execution - keep VM in same thread
|
||||
if self.depth != depth_threshold {
|
||||
let vm_factory = self.state.vm_factory();
|
||||
let wasm = self.schedule.wasm.is_some();
|
||||
let origin_info = OriginInfo::from(¶ms);
|
||||
trace!(target: "executive", "ext.schedule.have_delegate_call: {}", self.schedule.have_delegate_call);
|
||||
let mut ext = self.as_externalities(OriginInfo::from(¶ms), unconfirmed_substate, output_policy, tracer, vm_tracer, static_call);
|
||||
let mut vm = vm_factory.create(¶ms, wasm);
|
||||
return vm.exec(params, &mut ext).finalize(ext);
|
||||
let mut vm = vm_factory.create(params, self.schedule, self.depth);
|
||||
let mut ext = self.as_externalities(origin_info, unconfirmed_substate, output_policy, tracer, vm_tracer, static_call);
|
||||
return vm.exec(&mut ext).finalize(ext);
|
||||
}
|
||||
|
||||
// Start in new thread with stack size needed up to max depth
|
||||
crossbeam::scope(|scope| {
|
||||
let vm_factory = self.state.vm_factory();
|
||||
let max_depth = self.schedule.max_depth;
|
||||
let wasm = self.schedule.wasm.is_some();
|
||||
let mut ext = self.as_externalities(OriginInfo::from(¶ms), unconfirmed_substate, output_policy, tracer, vm_tracer, static_call);
|
||||
let origin_info = OriginInfo::from(¶ms);
|
||||
|
||||
scope.builder().stack_size(::std::cmp::max(max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
|
||||
let mut vm = vm_factory.create(¶ms, wasm);
|
||||
vm.exec(params, &mut ext).finalize(ext)
|
||||
scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
|
||||
let mut vm = vm_factory.create(params, self.schedule, self.depth);
|
||||
let mut ext = self.as_externalities(origin_info, unconfirmed_substate, output_policy, tracer, vm_tracer, static_call);
|
||||
vm.exec(&mut ext).finalize(ext)
|
||||
}).expect("Sub-thread creation cannot fail; the host might run out of resources; qed")
|
||||
}).join()
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use trie::TrieFactory;
|
||||
use ethtrie::RlpCodec;
|
||||
use account_db::Factory as AccountFactory;
|
||||
use evm::{Factory as EvmFactory, VMType};
|
||||
use vm::{Vm, ActionParams};
|
||||
use vm::{Vm, ActionParams, Schedule};
|
||||
use wasm::WasmInterpreter;
|
||||
use keccak_hasher::KeccakHasher;
|
||||
|
||||
@ -31,11 +31,11 @@ pub struct VmFactory {
|
||||
}
|
||||
|
||||
impl VmFactory {
|
||||
pub fn create(&self, params: &ActionParams, wasm: bool) -> Box<Vm> {
|
||||
if wasm && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) {
|
||||
Box::new(WasmInterpreter)
|
||||
pub fn create(&self, params: ActionParams, schedule: &Schedule, depth: usize) -> Box<Vm> {
|
||||
if schedule.wasm.is_some() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) {
|
||||
Box::new(WasmInterpreter::new(params))
|
||||
} else {
|
||||
self.evm.create(¶ms.gas)
|
||||
self.evm.create(params, schedule, depth)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,8 +281,8 @@ fn do_json_test_for<H: FnMut(&str, HookType)>(vm_type: &VMType, json_data: &[u8]
|
||||
&mut tracer,
|
||||
&mut vm_tracer,
|
||||
));
|
||||
let mut evm = vm_factory.create(¶ms, schedule.wasm.is_some());
|
||||
let res = evm.exec(params, &mut ex);
|
||||
let mut evm = vm_factory.create(params, &schedule, 0);
|
||||
let res = evm.exec(&mut ex);
|
||||
// a return in finalize will not alter callcreates
|
||||
let callcreates = ex.callcreates.clone();
|
||||
(res.finalize(ex), callcreates)
|
||||
|
@ -48,5 +48,5 @@ pub trait Vm {
|
||||
/// This function should be used to execute transaction.
|
||||
/// It returns either an error, a known amount of gas left, or parameters to be used
|
||||
/// to compute the final gas left.
|
||||
fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft>;
|
||||
fn exec(&mut self, ext: &mut Ext) -> Result<GasLeft>;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ fn load_code<P: AsRef<path::Path>>(p: P) -> io::Result<Vec<u8>> {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn wasm_interpreter() -> WasmInterpreter {
|
||||
WasmInterpreter
|
||||
fn wasm_interpreter(params: ActionParams) -> WasmInterpreter {
|
||||
WasmInterpreter::new(params)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -131,7 +131,7 @@ pub fn construct(
|
||||
params.params_type = ParamsType::Separate;
|
||||
|
||||
Ok(
|
||||
match wasm_interpreter().exec(params, ext)? {
|
||||
match wasm_interpreter(params).exec(ext)? {
|
||||
GasLeft::Known(_) => Vec::new(),
|
||||
GasLeft::NeedsReturn { data, .. } => data.to_vec(),
|
||||
}
|
||||
@ -192,9 +192,9 @@ pub fn run_fixture(fixture: &Fixture) -> Vec<Fail> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
|
||||
let interpreter_return = match interpreter.exec(params, &mut ext) {
|
||||
let interpreter_return = match interpreter.exec(&mut ext) {
|
||||
Ok(ret) => ret,
|
||||
Err(e) => { return Fail::runtime(e); }
|
||||
};
|
||||
|
@ -69,7 +69,15 @@ impl From<Error> for vm::Error {
|
||||
}
|
||||
|
||||
/// Wasm interpreter instance
|
||||
pub struct WasmInterpreter;
|
||||
pub struct WasmInterpreter {
|
||||
params: ActionParams,
|
||||
}
|
||||
|
||||
impl WasmInterpreter {
|
||||
pub fn new(params: ActionParams) -> Self {
|
||||
WasmInterpreter { params }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<runtime::Error> for vm::Error {
|
||||
fn from(e: runtime::Error) -> Self {
|
||||
@ -85,8 +93,8 @@ enum ExecutionOutcome {
|
||||
|
||||
impl vm::Vm for WasmInterpreter {
|
||||
|
||||
fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
|
||||
let (module, data) = parser::payload(¶ms, ext.schedule().wasm())?;
|
||||
fn exec(&mut self, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
|
||||
let (module, data) = parser::payload(&self.params, ext.schedule().wasm())?;
|
||||
|
||||
let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error::Interpreter)?;
|
||||
|
||||
@ -97,7 +105,7 @@ impl vm::Vm for WasmInterpreter {
|
||||
&wasmi::ImportsBuilder::new().with_resolver("env", &instantiation_resolver)
|
||||
).map_err(Error::Interpreter)?;
|
||||
|
||||
let adjusted_gas = params.gas * U256::from(ext.schedule().wasm().opcodes_div) /
|
||||
let adjusted_gas = self.params.gas * U256::from(ext.schedule().wasm().opcodes_div) /
|
||||
U256::from(ext.schedule().wasm().opcodes_mul);
|
||||
|
||||
if adjusted_gas > ::std::u64::MAX.into()
|
||||
@ -116,11 +124,11 @@ impl vm::Vm for WasmInterpreter {
|
||||
adjusted_gas.low_u64(),
|
||||
data.to_vec(),
|
||||
RuntimeContext {
|
||||
address: params.address,
|
||||
sender: params.sender,
|
||||
origin: params.origin,
|
||||
code_address: params.code_address,
|
||||
value: params.value.value(),
|
||||
address: self.params.address,
|
||||
sender: self.params.sender,
|
||||
origin: self.params.origin,
|
||||
code_address: self.params.code_address,
|
||||
value: self.params.value.value(),
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -47,8 +47,8 @@ macro_rules! reqrep_test {
|
||||
fake_ext.info = $info;
|
||||
fake_ext.blockhashes = $block_hashes;
|
||||
|
||||
let mut interpreter = wasm_interpreter();
|
||||
interpreter.exec(params, &mut fake_ext)
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
interpreter.exec(&mut fake_ext)
|
||||
.map(|result| match result {
|
||||
GasLeft::Known(_) => { panic!("Test is expected to return payload to check"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -65,8 +65,8 @@ fn test_finalize(res: Result<GasLeft, vm::Error>) -> Result<U256, vm::Error> {
|
||||
}
|
||||
}
|
||||
|
||||
fn wasm_interpreter() -> WasmInterpreter {
|
||||
WasmInterpreter
|
||||
fn wasm_interpreter(params: ActionParams) -> WasmInterpreter {
|
||||
WasmInterpreter::new(params)
|
||||
}
|
||||
|
||||
/// Empty contract does almost nothing except producing 1 (one) local node debug log message
|
||||
@ -82,8 +82,8 @@ fn empty() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let gas_left = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
test_finalize(interpreter.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_926));
|
||||
@ -111,8 +111,8 @@ fn logger() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let gas_left = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
test_finalize(interpreter.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
let address_val: H256 = address.into();
|
||||
@ -160,8 +160,8 @@ fn identity() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("Identity contract should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -195,8 +195,8 @@ fn dispersion() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("Dispersion routine should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -223,8 +223,8 @@ fn suicide_not() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("Suicidal contract should return payload when had not actualy killed himself"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -256,8 +256,8 @@ fn suicide() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let gas_left = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(gas) => gas,
|
||||
GasLeft::NeedsReturn { .. } => {
|
||||
@ -284,8 +284,8 @@ fn create() {
|
||||
ext.schedule.wasm.as_mut().unwrap().have_create2 = true;
|
||||
|
||||
let gas_left = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => {
|
||||
panic!("Create contract always return 40 bytes of the creation address, or in the case where it fails, return 40 bytes of zero.");
|
||||
@ -346,8 +346,8 @@ fn call_msg() {
|
||||
ext.balances.insert(receiver.clone(), U256::from(10000000000u64));
|
||||
|
||||
let gas_left = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(gas_left) => gas_left,
|
||||
GasLeft::NeedsReturn { .. } => { panic!("Call test should not return payload"); },
|
||||
@ -389,8 +389,8 @@ fn call_code() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("Call test should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -437,8 +437,8 @@ fn call_static() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("Static call test should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -478,8 +478,8 @@ fn realloc() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("Realloc should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -500,8 +500,8 @@ fn alloc() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("alloc test should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -527,8 +527,8 @@ fn storage_read() {
|
||||
ext.store.insert("0100000000000000000000000000000000000000000000000000000000000000".into(), address.into());
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("storage_read should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -553,8 +553,8 @@ fn keccak() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("keccak should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -700,8 +700,8 @@ fn storage_metering() {
|
||||
]);
|
||||
|
||||
let gas_left = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
test_finalize(interpreter.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
// 0 -> not 0
|
||||
@ -719,8 +719,8 @@ fn storage_metering() {
|
||||
]);
|
||||
|
||||
let gas_left = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
test_finalize(interpreter.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
// not 0 -> not 0
|
||||
@ -829,8 +829,8 @@ fn embedded_keccak() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("keccak should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -857,8 +857,8 @@ fn events() {
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("events should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
@ -897,8 +897,8 @@ fn recursive() {
|
||||
|
||||
let mut ext = FakeExt::new().with_wasm();
|
||||
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext);
|
||||
let mut interpreter = wasm_interpreter(params);
|
||||
let result = interpreter.exec(&mut ext);
|
||||
|
||||
// We expect that stack overflow will occur and it should be generated by
|
||||
// deterministic stack metering. Exceeding deterministic stack height limit
|
||||
|
Loading…
Reference in New Issue
Block a user