From e6c32e63562519fd9a821a33ecb8a017ecf0986e Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 28 Jul 2017 18:37:55 +0300 Subject: [PATCH 1/6] work in progress for splitting vms --- Cargo.lock | 17 +- ethcore/Cargo.toml | 1 + ethcore/vm/Cargo.toml | 14 + ethcore/vm/src/action_params.rs | 121 ++++++++ ethcore/vm/src/call_type.rs | 70 +++++ ethcore/vm/src/env_info.rs | 107 +++++++ ethcore/vm/src/error.rs | 67 +++++ ethcore/vm/src/ext.rs | 142 ++++++++++ ethcore/vm/src/lib.rs | 38 +++ ethcore/vm/src/return_data.rs | 49 ++++ ethcore/vm/src/schedule.rs | 262 ++++++++++++++++++ ethcore/wasm/Cargo.toml | 11 + .../{evm/src/wasm => wasm/src}/call_args.rs | 0 ethcore/{evm/src/wasm => wasm/src}/env.rs | 0 .../{evm/src/wasm/mod.rs => wasm/src/lib.rs} | 0 ethcore/{evm/src/wasm => wasm/src}/ptr.rs | 0 ethcore/{evm/src/wasm => wasm/src}/result.rs | 0 ethcore/{evm/src/wasm => wasm/src}/runtime.rs | 0 ethcore/{evm/src/wasm => wasm/src}/tests.rs | 0 19 files changed, 898 insertions(+), 1 deletion(-) create mode 100644 ethcore/vm/Cargo.toml create mode 100644 ethcore/vm/src/action_params.rs create mode 100644 ethcore/vm/src/call_type.rs create mode 100644 ethcore/vm/src/env_info.rs create mode 100644 ethcore/vm/src/error.rs create mode 100644 ethcore/vm/src/ext.rs create mode 100644 ethcore/vm/src/lib.rs create mode 100644 ethcore/vm/src/return_data.rs create mode 100644 ethcore/vm/src/schedule.rs create mode 100644 ethcore/wasm/Cargo.toml rename ethcore/{evm/src/wasm => wasm/src}/call_args.rs (100%) rename ethcore/{evm/src/wasm => wasm/src}/env.rs (100%) rename ethcore/{evm/src/wasm/mod.rs => wasm/src/lib.rs} (100%) rename ethcore/{evm/src/wasm => wasm/src}/ptr.rs (100%) rename ethcore/{evm/src/wasm => wasm/src}/result.rs (100%) rename ethcore/{evm/src/wasm => wasm/src}/runtime.rs (100%) rename ethcore/{evm/src/wasm => wasm/src}/tests.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 359b2d2f9be..afaf475199d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,16 @@ [root] -name = "using_queue" +name = "vm" version = "0.1.0" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "common-types 0.1.0", + "ethcore-util 1.8.0", + "ethjson 0.1.0", + "evmjit 1.8.0", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.0", +] [[package]] name = "advapi32-sys" @@ -504,6 +514,7 @@ dependencies = [ "stats 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", ] [[package]] @@ -3035,6 +3046,10 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "using_queue" +version = "0.1.0" + [[package]] name = "utf8-ranges" version = "1.0.0" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 71e3292010a..f1193b615b4 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -53,6 +53,7 @@ semver = "0.6" stats = { path = "../util/stats" } time = "0.1" transient-hashmap = "0.4" +vm = { path = "vm" } [dev-dependencies] native-contracts = { path = "native_contracts", features = ["test_contracts"] } diff --git a/ethcore/vm/Cargo.toml b/ethcore/vm/Cargo.toml new file mode 100644 index 00000000000..50efe936c11 --- /dev/null +++ b/ethcore/vm/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "vm" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +byteorder = "1.0" +ethcore-util = { path = "../../util" } +log = "0.3" +common-types = { path = "../types" } +evmjit = { path = "../../evmjit", optional = true } +ethjson = { path = "../../json" } +lazy_static = "0.2" +rlp = { path = "../../util/rlp" } \ No newline at end of file diff --git a/ethcore/vm/src/action_params.rs b/ethcore/vm/src/action_params.rs new file mode 100644 index 00000000000..401d7ee5728 --- /dev/null +++ b/ethcore/vm/src/action_params.rs @@ -0,0 +1,121 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Evm input params. +use util::{Address, Bytes, U256}; +use util::hash::{H256}; +use util::sha3::{Hashable, SHA3_EMPTY}; +use ethjson; + +use call_type::CallType; + +use std::sync::Arc; + +/// Transaction value +#[derive(Clone, Debug)] +pub enum ActionValue { + /// Value that should be transfered + Transfer(U256), + /// Apparent value for transaction (not transfered) + Apparent(U256) +} + +impl ActionValue { + /// Returns action value as U256. + pub fn value(&self) -> U256 { + match *self { + ActionValue::Transfer(x) | ActionValue::Apparent(x) => x + } + } + + /// Returns the transfer action value of the U256-convertable raw value + pub fn transfer>(transfer_value: T) -> ActionValue { + ActionValue::Transfer(transfer_value.into()) + } + + /// Returns the apparent action value of the U256-convertable raw value + pub fn apparent>(apparent_value: T) -> ActionValue { + ActionValue::Apparent(apparent_value.into()) + } +} + +// TODO: should be a trait, possible to avoid cloning everything from a Transaction(/View). +/// Action (call/create) input params. Everything else should be specified in Externalities. +#[derive(Clone, Debug)] +pub struct ActionParams { + /// Address of currently executed code. + pub code_address: Address, + /// Hash of currently executed code. + pub code_hash: Option, + /// Receive address. Usually equal to code_address, + /// except when called using CALLCODE. + pub address: Address, + /// Sender of current part of the transaction. + pub sender: Address, + /// Transaction initiator. + pub origin: Address, + /// Gas paid up front for transaction execution + pub gas: U256, + /// Gas price. + pub gas_price: U256, + /// Transaction value. + pub value: ActionValue, + /// Code being executed. + pub code: Option>, + /// Input data. + pub data: Option, + /// Type of call + pub call_type: CallType, + +} + +impl Default for ActionParams { + /// Returns default ActionParams initialized with zeros + fn default() -> ActionParams { + ActionParams { + code_address: Address::new(), + code_hash: Some(SHA3_EMPTY), + address: Address::new(), + sender: Address::new(), + origin: Address::new(), + gas: U256::zero(), + gas_price: U256::zero(), + value: ActionValue::Transfer(U256::zero()), + code: None, + data: None, + call_type: CallType::None, + } + } +} + +impl From for ActionParams { + fn from(t: ethjson::vm::Transaction) -> Self { + let address: Address = t.address.into(); + ActionParams { + code_address: Address::new(), + code_hash: Some((&*t.code).sha3()), + address: address, + sender: t.sender.into(), + origin: t.origin.into(), + code: Some(Arc::new(t.code.into())), + data: Some(t.data.into()), + gas: t.gas.into(), + gas_price: t.gas_price.into(), + value: ActionValue::Transfer(t.value.into()), + call_type: match address.is_zero() { true => CallType::None, false => CallType::Call }, // TODO @debris is this correct? + } + } +} diff --git a/ethcore/vm/src/call_type.rs b/ethcore/vm/src/call_type.rs new file mode 100644 index 00000000000..08a004053f0 --- /dev/null +++ b/ethcore/vm/src/call_type.rs @@ -0,0 +1,70 @@ +//! EVM call types. + +use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; + +/// The type of the call-like instruction. +#[derive(Debug, PartialEq, Clone)] +pub enum CallType { + /// Not a CALL. + None, + /// CALL. + Call, + /// CALLCODE. + CallCode, + /// DELEGATECALL. + DelegateCall, + /// STATICCALL + StaticCall, +} + +impl Encodable for CallType { + fn rlp_append(&self, s: &mut RlpStream) { + let v = match *self { + CallType::None => 0u32, + CallType::Call => 1, + CallType::CallCode => 2, + CallType::DelegateCall => 3, + CallType::StaticCall => 4, + }; + Encodable::rlp_append(&v, s); + } +} + +impl Decodable for CallType { + fn decode(rlp: &UntrustedRlp) -> Result { + rlp.as_val().and_then(|v| Ok(match v { + 0u32 => CallType::None, + 1 => CallType::Call, + 2 => CallType::CallCode, + 3 => CallType::DelegateCall, + 4 => CallType::StaticCall, + _ => return Err(DecoderError::Custom("Invalid value of CallType item")), + })) + } +} + +#[cfg(test)] +mod tests { + use rlp::*; + use super::CallType; + + #[test] + fn encode_call_type() { + let ct = CallType::Call; + + let mut s = RlpStream::new_list(2); + s.append(&ct); + assert!(!s.is_finished(), "List shouldn't finished yet"); + s.append(&ct); + assert!(s.is_finished(), "List should be finished now"); + s.out(); + } + + #[test] + fn should_encode_and_decode_call_type() { + let original = CallType::Call; + let encoded = encode(&original); + let decoded = decode(&encoded); + assert_eq!(original, decoded); + } +} diff --git a/ethcore/vm/src/env_info.rs b/ethcore/vm/src/env_info.rs new file mode 100644 index 00000000000..8634d9c759e --- /dev/null +++ b/ethcore/vm/src/env_info.rs @@ -0,0 +1,107 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Environment information for transaction execution. + +use std::cmp; +use std::sync::Arc; +use util::{U256, Address, H256, Hashable}; +use types::BlockNumber; +use ethjson; + +/// Simple vector of hashes, should be at most 256 items large, can be smaller if being used +/// for a block whose number is less than 257. +pub type LastHashes = Vec; + +/// Information concerning the execution environment for a message-call/contract-creation. +#[derive(Debug, Clone)] +pub struct EnvInfo { + /// The block number. + pub number: BlockNumber, + /// The block author. + pub author: Address, + /// The block timestamp. + pub timestamp: u64, + /// The block difficulty. + pub difficulty: U256, + /// The block gas limit. + pub gas_limit: U256, + /// The last 256 block hashes. + pub last_hashes: Arc, + /// The gas used. + pub gas_used: U256, +} + +impl Default for EnvInfo { + fn default() -> Self { + EnvInfo { + number: 0, + author: Address::default(), + timestamp: 0, + difficulty: 0.into(), + gas_limit: 0.into(), + last_hashes: Arc::new(vec![]), + gas_used: 0.into(), + } + } +} + +impl From for EnvInfo { + fn from(e: ethjson::vm::Env) -> Self { + let number = e.number.into(); + EnvInfo { + number: number, + author: e.author.into(), + difficulty: e.difficulty.into(), + gas_limit: e.gas_limit.into(), + timestamp: e.timestamp.into(), + last_hashes: Arc::new((1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect()), + gas_used: U256::default(), + } + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use super::*; + use util::{U256, Address}; + use ethjson; + + #[test] + fn it_serializes_from_json() { + let env_info = EnvInfo::from(ethjson::vm::Env { + author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()), + number: ethjson::uint::Uint(U256::from(1_112_339)), + difficulty: ethjson::uint::Uint(U256::from(50_000)), + gas_limit: ethjson::uint::Uint(U256::from(40_000)), + timestamp: ethjson::uint::Uint(U256::from(1_100)) + }); + + assert_eq!(env_info.number, 1112339); + assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()); + assert_eq!(env_info.gas_limit, 40000.into()); + assert_eq!(env_info.difficulty, 50000.into()); + assert_eq!(env_info.gas_used, 0.into()); + } + + #[test] + fn it_can_be_created_as_default() { + let default_env_info = EnvInfo::default(); + + assert_eq!(default_env_info.difficulty, 0.into()); + } +} diff --git a/ethcore/vm/src/error.rs b/ethcore/vm/src/error.rs new file mode 100644 index 00000000000..d93052f5467 --- /dev/null +++ b/ethcore/vm/src/error.rs @@ -0,0 +1,67 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! VM errors module + +/// VM errors. +#[derive(Debug, Clone, PartialEq)] +pub enum Error { + /// `OutOfGas` is returned when transaction execution runs out of gas. + /// The state should be reverted to the state from before the + /// transaction execution. But it does not mean that transaction + /// was invalid. Balance still should be transfered and nonce + /// should be increased. + OutOfGas, + /// `BadJumpDestination` is returned when execution tried to move + /// to position that wasn't marked with JUMPDEST instruction + BadJumpDestination { + /// Position the code tried to jump to. + destination: usize + }, + /// `BadInstructions` is returned when given instruction is not supported + BadInstruction { + /// Unrecognized opcode + instruction: u8, + }, + /// `StackUnderflow` when there is not enough stack elements to execute instruction + StackUnderflow { + /// Invoked instruction + instruction: &'static str, + /// How many stack elements was requested by instruction + wanted: usize, + /// How many elements were on stack + on_stack: usize + }, + /// When execution would exceed defined Stack Limit + OutOfStack { + /// Invoked instruction + instruction: &'static str, + /// How many stack elements instruction wanted to push + wanted: usize, + /// What was the stack limit + limit: usize + }, + /// Built-in contract failed on given input + BuiltIn(&'static str), + /// When execution tries to modify the state in static context + MutableCallInStaticContext, + /// Likely to cause consensus issues. + Internal(String), + /// Wasm runtime error + Wasm(String), +} + +pub type Result = ::std::result::Result; diff --git a/ethcore/vm/src/ext.rs b/ethcore/vm/src/ext.rs new file mode 100644 index 00000000000..e6ce3fbe37a --- /dev/null +++ b/ethcore/vm/src/ext.rs @@ -0,0 +1,142 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Interface for Evm externalities. + +use util::*; +use call_type::CallType; +use env_info::EnvInfo; +use schedule::Schedule; +use return_data::ReturnData; +use error::Result; + +/// Result of externalities create function. +pub enum ContractCreateResult { + /// Returned when creation was successfull. + /// Contains an address of newly created contract and gas left. + Created(Address, U256), + /// Returned when contract creation failed. + /// VM doesn't have to know the reason. + Failed +} + +/// Result of externalities call function. +pub enum MessageCallResult { + /// Returned when message call was successfull. + /// Contains gas left and output data. + Success(U256, ReturnData), + /// Returned when message call failed. + /// VM doesn't have to know the reason. + Failed +} + +/// Specifies how an address is calculated for a new contract. +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum CreateContractAddress { + /// Address is calculated from nonce and sender. Pre EIP-86 (Metropolis) + FromSenderAndNonce, + /// Address is calculated from code hash. Default since EIP-86 + FromCodeHash, + /// Address is calculated from code hash and sender. Used by CREATE_P2SH instruction. + FromSenderAndCodeHash, +} + +/// Externalities interface for EVMs +pub trait Ext { + /// Returns a value for given key. + fn storage_at(&self, key: &H256) -> Result; + + /// Stores a value for given key. + fn set_storage(&mut self, key: H256, value: H256) -> Result<()>; + + /// Determine whether an account exists. + fn exists(&self, address: &Address) -> Result; + + /// Determine whether an account exists and is not null (zero balance/nonce, no code). + fn exists_and_not_null(&self, address: &Address) -> Result; + + /// Balance of the origin account. + fn origin_balance(&self) -> Result; + + /// Returns address balance. + fn balance(&self, address: &Address) -> Result; + + /// Returns the hash of one of the 256 most recent complete blocks. + fn blockhash(&mut self, number: &U256) -> H256; + + /// Creates new contract. + /// + /// Returns gas_left and contract address if contract creation was succesfull. + fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult; + + /// Message call. + /// + /// Returns Err, if we run out of gas. + /// Otherwise returns call_result which contains gas left + /// and true if subcall was successfull. + #[cfg_attr(feature="dev", allow(too_many_arguments))] + fn call(&mut self, + gas: &U256, + sender_address: &Address, + receive_address: &Address, + value: Option, + data: &[u8], + code_address: &Address, + output: &mut [u8], + call_type: CallType + ) -> MessageCallResult; + + /// Returns code at given address + fn extcode(&self, address: &Address) -> Result>; + + /// Returns code size at given address + fn extcodesize(&self, address: &Address) -> Result; + + /// Creates log entry with given topics and data + fn log(&mut self, topics: Vec, data: &[u8]) -> Result<()>; + + /// Should be called when transaction calls `RETURN` opcode. + /// Returns gas_left if cost of returning the data is not too high. + fn ret(self, gas: &U256, data: &ReturnData) -> Result; + + /// Should be called when contract commits suicide. + /// Address to which funds should be refunded. + fn suicide(&mut self, refund_address: &Address) -> Result<()> ; + + /// Returns schedule. + fn schedule(&self) -> &Schedule; + + /// Returns environment info. + fn env_info(&self) -> &EnvInfo; + + /// Returns current depth of execution. + /// + /// If contract A calls contract B, and contract B calls C, + /// then A depth is 0, B is 1, C is 2 and so on. + fn depth(&self) -> usize; + + /// Increments sstore refunds count by 1. + fn inc_sstore_clears(&mut self); + + /// Decide if any more operations should be traced. Passthrough for the VM trace. + fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8) -> bool { false } + + /// Prepare to trace an operation. Passthrough for the VM trace. + fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256) {} + + /// Trace the finalised execution of a single instruction. + fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {} +} diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs new file mode 100644 index 00000000000..92013a84e58 --- /dev/null +++ b/ethcore/vm/src/lib.rs @@ -0,0 +1,38 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Virtual machines support library + +extern crate ethcore_util as util; +extern crate common_types as types; +extern crate ethjson; +extern crate rlp; + +mod action_params; +mod call_type; +mod env_info; +mod schedule; +mod ext; +mod return_data; +mod error; + +pub use action_params::ActionParams; +pub use call_type::CallType; +pub use env_info::EnvInfo; +pub use schedule::Schedule; +pub use ext::Ext; +pub use return_data::ReturnData; +pub use error::{Error, Result}; \ No newline at end of file diff --git a/ethcore/vm/src/return_data.rs b/ethcore/vm/src/return_data.rs new file mode 100644 index 00000000000..d678f4c7408 --- /dev/null +++ b/ethcore/vm/src/return_data.rs @@ -0,0 +1,49 @@ + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Return data structure + +/// Return data buffer. Holds memory from a previous call and a slice into that memory. +#[derive(Debug)] +pub struct ReturnData { + mem: Vec, + offset: usize, + size: usize, +} + +impl ::std::ops::Deref for ReturnData { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.mem[self.offset..self.offset + self.size] + } +} + +impl ReturnData { + /// Create empty `ReturnData`. + pub fn empty() -> Self { + ReturnData { + mem: Vec::new(), + offset: 0, + size: 0, + } + } + /// Create `ReturnData` from give buffer and slice. + pub fn new(mem: Vec, offset: usize, size: usize) -> Self { + ReturnData { + mem: mem, + offset: offset, + size: size, + } + } +} \ No newline at end of file diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs new file mode 100644 index 00000000000..e721dc8035a --- /dev/null +++ b/ethcore/vm/src/schedule.rs @@ -0,0 +1,262 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Cost schedule and other parameterisations for the EVM. + +/// Definition of the cost schedule and other parameterisations for the EVM. +pub struct Schedule { + /// Does it support exceptional failed code deposit + pub exceptional_failed_code_deposit: bool, + /// Does it have a delegate cal + pub have_delegate_call: bool, + /// Does it have a CREATE_P2SH instruction + pub have_create2: bool, + /// Does it have a REVERT instruction + pub have_revert: bool, + /// VM stack limit + pub stack_limit: usize, + /// Max number of nested calls/creates + pub max_depth: usize, + /// Gas prices for instructions in all tiers + pub tier_step_gas: [usize; 8], + /// Gas price for `EXP` opcode + pub exp_gas: usize, + /// Additional gas for `EXP` opcode for each byte of exponent + pub exp_byte_gas: usize, + /// Gas price for `SHA3` opcode + pub sha3_gas: usize, + /// Additional gas for `SHA3` opcode for each word of hashed memory + pub sha3_word_gas: usize, + /// Gas price for loading from storage + pub sload_gas: usize, + /// Gas price for setting new value to storage (`storage==0`, `new!=0`) + pub sstore_set_gas: usize, + /// Gas price for altering value in storage + pub sstore_reset_gas: usize, + /// Gas refund for `SSTORE` clearing (when `storage!=0`, `new==0`) + pub sstore_refund_gas: usize, + /// Gas price for `JUMPDEST` opcode + pub jumpdest_gas: usize, + /// Gas price for `LOG*` + pub log_gas: usize, + /// Additional gas for data in `LOG*` + pub log_data_gas: usize, + /// Additional gas for each topic in `LOG*` + pub log_topic_gas: usize, + /// Gas price for `CREATE` opcode + pub create_gas: usize, + /// Gas price for `*CALL*` opcodes + pub call_gas: usize, + /// Stipend for transfer for `CALL|CALLCODE` opcode when `value>0` + pub call_stipend: usize, + /// Additional gas required for value transfer (`CALL|CALLCODE`) + pub call_value_transfer_gas: usize, + /// Additional gas for creating new account (`CALL|CALLCODE`) + pub call_new_account_gas: usize, + /// Refund for SUICIDE + pub suicide_refund_gas: usize, + /// Gas for used memory + pub memory_gas: usize, + /// Coefficient used to convert memory size to gas price for memory + pub quad_coeff_div: usize, + /// Cost for contract length when executing `CREATE` + pub create_data_gas: usize, + /// Maximum code size when creating a contract. + pub create_data_limit: usize, + /// Transaction cost + pub tx_gas: usize, + /// `CREATE` transaction cost + pub tx_create_gas: usize, + /// Additional cost for empty data transaction + pub tx_data_zero_gas: usize, + /// Aditional cost for non-empty data transaction + pub tx_data_non_zero_gas: usize, + /// Gas price for copying memory + pub copy_gas: usize, + /// Price of EXTCODESIZE + pub extcodesize_gas: usize, + /// Base price of EXTCODECOPY + pub extcodecopy_base_gas: usize, + /// Price of BALANCE + pub balance_gas: usize, + /// Price of SUICIDE + pub suicide_gas: usize, + /// Amount of additional gas to pay when SUICIDE credits a non-existant account + pub suicide_to_new_account_cost: usize, + /// If Some(x): let limit = GAS * (x - 1) / x; let CALL's gas = min(requested, limit). let CREATE's gas = limit. + /// If None: let CALL's gas = (requested > GAS ? [OOG] : GAS). let CREATE's gas = GAS + pub sub_gas_cap_divisor: Option, + /// Don't ever make empty accounts; contracts start with nonce=1. Also, don't charge 25k when sending/suicide zero-value. + pub no_empty: bool, + /// Kill empty accounts if touched. + pub kill_empty: bool, + /// Blockhash instruction gas cost. + pub blockhash_gas: usize, + /// Static Call opcode enabled. + pub have_static_call: bool, + /// RETURNDATA and RETURNDATASIZE opcodes enabled. + pub have_return_data: bool, + /// Kill basic accounts below this balance if touched. + pub kill_dust: CleanDustMode, +} + +/// Dust accounts cleanup mode. +#[derive(PartialEq, Eq)] +pub enum CleanDustMode { + /// Dust cleanup is disabled. + Off, + /// Basic dust accounts will be removed. + BasicOnly, + /// Basic and contract dust accounts will be removed. + WithCodeAndStorage, +} + +impl Schedule { + /// Schedule for the Frontier-era of the Ethereum main net. + pub fn new_frontier() -> Schedule { + Self::new(false, false, 21000) + } + + /// Schedule for the Homestead-era of the Ethereum main net. + pub fn new_homestead() -> Schedule { + Self::new(true, true, 53000) + } + + /// Schedule for the post-EIP-150-era of the Ethereum main net. + pub fn new_post_eip150(max_code_size: usize, fix_exp: bool, no_empty: bool, kill_empty: bool) -> Schedule { + Schedule { + exceptional_failed_code_deposit: true, + have_delegate_call: true, + have_create2: false, + have_revert: false, + have_return_data: false, + stack_limit: 1024, + max_depth: 1024, + tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], + exp_gas: 10, + exp_byte_gas: if fix_exp {50} else {10}, + sha3_gas: 30, + sha3_word_gas: 6, + sload_gas: 200, + sstore_set_gas: 20000, + sstore_reset_gas: 5000, + sstore_refund_gas: 15000, + jumpdest_gas: 1, + log_gas: 375, + log_data_gas: 8, + log_topic_gas: 375, + create_gas: 32000, + call_gas: 700, + call_stipend: 2300, + call_value_transfer_gas: 9000, + call_new_account_gas: 25000, + suicide_refund_gas: 24000, + memory_gas: 3, + quad_coeff_div: 512, + create_data_gas: 200, + create_data_limit: max_code_size, + tx_gas: 21000, + tx_create_gas: 53000, + tx_data_zero_gas: 4, + tx_data_non_zero_gas: 68, + copy_gas: 3, + extcodesize_gas: 700, + extcodecopy_base_gas: 700, + balance_gas: 400, + suicide_gas: 5000, + suicide_to_new_account_cost: 25000, + sub_gas_cap_divisor: Some(64), + no_empty: no_empty, + kill_empty: kill_empty, + blockhash_gas: 20, + have_static_call: false, + kill_dust: CleanDustMode::Off, + } + } + + /// Schedule for the Metropolis of the Ethereum main net. + pub fn new_metropolis() -> Schedule { + let mut schedule = Self::new_post_eip150(24576, true, true, true); + schedule.have_create2 = true; + schedule.have_revert = true; + schedule.have_static_call = true; + schedule.have_return_data = true; + schedule.blockhash_gas = 350; + schedule + } + + fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule { + Schedule { + exceptional_failed_code_deposit: efcd, + have_delegate_call: hdc, + have_create2: false, + have_revert: false, + have_return_data: false, + stack_limit: 1024, + max_depth: 1024, + tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], + exp_gas: 10, + exp_byte_gas: 10, + sha3_gas: 30, + sha3_word_gas: 6, + sload_gas: 50, + sstore_set_gas: 20000, + sstore_reset_gas: 5000, + sstore_refund_gas: 15000, + jumpdest_gas: 1, + log_gas: 375, + log_data_gas: 8, + log_topic_gas: 375, + create_gas: 32000, + call_gas: 40, + call_stipend: 2300, + call_value_transfer_gas: 9000, + call_new_account_gas: 25000, + suicide_refund_gas: 24000, + memory_gas: 3, + quad_coeff_div: 512, + create_data_gas: 200, + create_data_limit: usize::max_value(), + tx_gas: 21000, + tx_create_gas: tcg, + tx_data_zero_gas: 4, + tx_data_non_zero_gas: 68, + copy_gas: 3, + extcodesize_gas: 20, + extcodecopy_base_gas: 20, + balance_gas: 20, + suicide_gas: 0, + suicide_to_new_account_cost: 0, + sub_gas_cap_divisor: None, + no_empty: false, + kill_empty: false, + blockhash_gas: 20, + have_static_call: false, + kill_dust: CleanDustMode::Off, + } + } +} + +#[test] +#[cfg(test)] +fn schedule_evm_assumptions() { + let s1 = Schedule::new_frontier(); + let s2 = Schedule::new_homestead(); + + // To optimize division we assume 2**9 for quad_coeff_div + assert_eq!(s1.quad_coeff_div, 512); + assert_eq!(s2.quad_coeff_div, 512); +} diff --git a/ethcore/wasm/Cargo.toml b/ethcore/wasm/Cargo.toml new file mode 100644 index 00000000000..63edb811e56 --- /dev/null +++ b/ethcore/wasm/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "wasm" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +byteorder = "1.0" +ethcore-util = { path = "../../util" } +log = "0.3" +parity-wasm = "0.12" +wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } diff --git a/ethcore/evm/src/wasm/call_args.rs b/ethcore/wasm/src/call_args.rs similarity index 100% rename from ethcore/evm/src/wasm/call_args.rs rename to ethcore/wasm/src/call_args.rs diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/wasm/src/env.rs similarity index 100% rename from ethcore/evm/src/wasm/env.rs rename to ethcore/wasm/src/env.rs diff --git a/ethcore/evm/src/wasm/mod.rs b/ethcore/wasm/src/lib.rs similarity index 100% rename from ethcore/evm/src/wasm/mod.rs rename to ethcore/wasm/src/lib.rs diff --git a/ethcore/evm/src/wasm/ptr.rs b/ethcore/wasm/src/ptr.rs similarity index 100% rename from ethcore/evm/src/wasm/ptr.rs rename to ethcore/wasm/src/ptr.rs diff --git a/ethcore/evm/src/wasm/result.rs b/ethcore/wasm/src/result.rs similarity index 100% rename from ethcore/evm/src/wasm/result.rs rename to ethcore/wasm/src/result.rs diff --git a/ethcore/evm/src/wasm/runtime.rs b/ethcore/wasm/src/runtime.rs similarity index 100% rename from ethcore/evm/src/wasm/runtime.rs rename to ethcore/wasm/src/runtime.rs diff --git a/ethcore/evm/src/wasm/tests.rs b/ethcore/wasm/src/tests.rs similarity index 100% rename from ethcore/evm/src/wasm/tests.rs rename to ethcore/wasm/src/tests.rs From bdda91114c3bf5b5945fa1199ab882ae87f98f03 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 28 Jul 2017 18:59:29 +0300 Subject: [PATCH 2/6] evm working --- Cargo.lock | 1 + ethcore/evm/Cargo.toml | 1 + ethcore/evm/src/action_params.rs | 121 ----------- ethcore/evm/src/call_type.rs | 70 ------ ethcore/evm/src/env_info.rs | 107 --------- ethcore/evm/src/evm.rs | 121 +---------- ethcore/evm/src/ext.rs | 141 ------------ ethcore/evm/src/interpreter/gasometer.rs | 22 +- ethcore/evm/src/interpreter/memory.rs | 2 +- ethcore/evm/src/interpreter/mod.rs | 37 ++-- ethcore/evm/src/lib.rs | 16 +- ethcore/evm/src/schedule.rs | 262 ----------------------- ethcore/evm/src/tests.rs | 46 ++-- ethcore/vm/src/error.rs | 33 +++ ethcore/vm/src/lib.rs | 6 +- ethcore/vm/src/schedule.rs | 7 + 16 files changed, 101 insertions(+), 892 deletions(-) delete mode 100644 ethcore/evm/src/action_params.rs delete mode 100644 ethcore/evm/src/call_type.rs delete mode 100644 ethcore/evm/src/env_info.rs delete mode 100644 ethcore/evm/src/ext.rs delete mode 100644 ethcore/evm/src/schedule.rs diff --git a/Cargo.lock b/Cargo.lock index afaf475199d..3e08df2d24d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -897,6 +897,7 @@ dependencies = [ "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", ] diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index b48dd2346c0..f3bd208ecb1 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -13,6 +13,7 @@ ethjson = { path = "../../json" } lazy_static = "0.2" log = "0.3" rlp = { path = "../../util/rlp" } +vm = { path = "../vm" } parity-wasm = "0.12" wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } diff --git a/ethcore/evm/src/action_params.rs b/ethcore/evm/src/action_params.rs deleted file mode 100644 index 62bb7fa5b1e..00000000000 --- a/ethcore/evm/src/action_params.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Evm input params. -use util::{Address, Bytes, U256}; -use util::hash::{H256}; -use util::sha3::{Hashable, SHA3_EMPTY}; -use ethjson; - -use {CallType}; - -use std::sync::Arc; - -/// Transaction value -#[derive(Clone, Debug)] -pub enum ActionValue { - /// Value that should be transfered - Transfer(U256), - /// Apparent value for transaction (not transfered) - Apparent(U256) -} - -impl ActionValue { - /// Returns action value as U256. - pub fn value(&self) -> U256 { - match *self { - ActionValue::Transfer(x) | ActionValue::Apparent(x) => x - } - } - - /// Returns the transfer action value of the U256-convertable raw value - pub fn transfer>(transfer_value: T) -> ActionValue { - ActionValue::Transfer(transfer_value.into()) - } - - /// Returns the apparent action value of the U256-convertable raw value - pub fn apparent>(apparent_value: T) -> ActionValue { - ActionValue::Apparent(apparent_value.into()) - } -} - -// TODO: should be a trait, possible to avoid cloning everything from a Transaction(/View). -/// Action (call/create) input params. Everything else should be specified in Externalities. -#[derive(Clone, Debug)] -pub struct ActionParams { - /// Address of currently executed code. - pub code_address: Address, - /// Hash of currently executed code. - pub code_hash: Option, - /// Receive address. Usually equal to code_address, - /// except when called using CALLCODE. - pub address: Address, - /// Sender of current part of the transaction. - pub sender: Address, - /// Transaction initiator. - pub origin: Address, - /// Gas paid up front for transaction execution - pub gas: U256, - /// Gas price. - pub gas_price: U256, - /// Transaction value. - pub value: ActionValue, - /// Code being executed. - pub code: Option>, - /// Input data. - pub data: Option, - /// Type of call - pub call_type: CallType, - -} - -impl Default for ActionParams { - /// Returns default ActionParams initialized with zeros - fn default() -> ActionParams { - ActionParams { - code_address: Address::new(), - code_hash: Some(SHA3_EMPTY), - address: Address::new(), - sender: Address::new(), - origin: Address::new(), - gas: U256::zero(), - gas_price: U256::zero(), - value: ActionValue::Transfer(U256::zero()), - code: None, - data: None, - call_type: CallType::None, - } - } -} - -impl From for ActionParams { - fn from(t: ethjson::vm::Transaction) -> Self { - let address: Address = t.address.into(); - ActionParams { - code_address: Address::new(), - code_hash: Some((&*t.code).sha3()), - address: address, - sender: t.sender.into(), - origin: t.origin.into(), - code: Some(Arc::new(t.code.into())), - data: Some(t.data.into()), - gas: t.gas.into(), - gas_price: t.gas_price.into(), - value: ActionValue::Transfer(t.value.into()), - call_type: match address.is_zero() { true => CallType::None, false => CallType::Call }, // TODO @debris is this correct? - } - } -} diff --git a/ethcore/evm/src/call_type.rs b/ethcore/evm/src/call_type.rs deleted file mode 100644 index 08a004053f0..00000000000 --- a/ethcore/evm/src/call_type.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! EVM call types. - -use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; - -/// The type of the call-like instruction. -#[derive(Debug, PartialEq, Clone)] -pub enum CallType { - /// Not a CALL. - None, - /// CALL. - Call, - /// CALLCODE. - CallCode, - /// DELEGATECALL. - DelegateCall, - /// STATICCALL - StaticCall, -} - -impl Encodable for CallType { - fn rlp_append(&self, s: &mut RlpStream) { - let v = match *self { - CallType::None => 0u32, - CallType::Call => 1, - CallType::CallCode => 2, - CallType::DelegateCall => 3, - CallType::StaticCall => 4, - }; - Encodable::rlp_append(&v, s); - } -} - -impl Decodable for CallType { - fn decode(rlp: &UntrustedRlp) -> Result { - rlp.as_val().and_then(|v| Ok(match v { - 0u32 => CallType::None, - 1 => CallType::Call, - 2 => CallType::CallCode, - 3 => CallType::DelegateCall, - 4 => CallType::StaticCall, - _ => return Err(DecoderError::Custom("Invalid value of CallType item")), - })) - } -} - -#[cfg(test)] -mod tests { - use rlp::*; - use super::CallType; - - #[test] - fn encode_call_type() { - let ct = CallType::Call; - - let mut s = RlpStream::new_list(2); - s.append(&ct); - assert!(!s.is_finished(), "List shouldn't finished yet"); - s.append(&ct); - assert!(s.is_finished(), "List should be finished now"); - s.out(); - } - - #[test] - fn should_encode_and_decode_call_type() { - let original = CallType::Call; - let encoded = encode(&original); - let decoded = decode(&encoded); - assert_eq!(original, decoded); - } -} diff --git a/ethcore/evm/src/env_info.rs b/ethcore/evm/src/env_info.rs deleted file mode 100644 index 8634d9c759e..00000000000 --- a/ethcore/evm/src/env_info.rs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Environment information for transaction execution. - -use std::cmp; -use std::sync::Arc; -use util::{U256, Address, H256, Hashable}; -use types::BlockNumber; -use ethjson; - -/// Simple vector of hashes, should be at most 256 items large, can be smaller if being used -/// for a block whose number is less than 257. -pub type LastHashes = Vec; - -/// Information concerning the execution environment for a message-call/contract-creation. -#[derive(Debug, Clone)] -pub struct EnvInfo { - /// The block number. - pub number: BlockNumber, - /// The block author. - pub author: Address, - /// The block timestamp. - pub timestamp: u64, - /// The block difficulty. - pub difficulty: U256, - /// The block gas limit. - pub gas_limit: U256, - /// The last 256 block hashes. - pub last_hashes: Arc, - /// The gas used. - pub gas_used: U256, -} - -impl Default for EnvInfo { - fn default() -> Self { - EnvInfo { - number: 0, - author: Address::default(), - timestamp: 0, - difficulty: 0.into(), - gas_limit: 0.into(), - last_hashes: Arc::new(vec![]), - gas_used: 0.into(), - } - } -} - -impl From for EnvInfo { - fn from(e: ethjson::vm::Env) -> Self { - let number = e.number.into(); - EnvInfo { - number: number, - author: e.author.into(), - difficulty: e.difficulty.into(), - gas_limit: e.gas_limit.into(), - timestamp: e.timestamp.into(), - last_hashes: Arc::new((1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect()), - gas_used: U256::default(), - } - } -} - -#[cfg(test)] -mod tests { - use std::str::FromStr; - use super::*; - use util::{U256, Address}; - use ethjson; - - #[test] - fn it_serializes_from_json() { - let env_info = EnvInfo::from(ethjson::vm::Env { - author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()), - number: ethjson::uint::Uint(U256::from(1_112_339)), - difficulty: ethjson::uint::Uint(U256::from(50_000)), - gas_limit: ethjson::uint::Uint(U256::from(40_000)), - timestamp: ethjson::uint::Uint(U256::from(1_100)) - }); - - assert_eq!(env_info.number, 1112339); - assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()); - assert_eq!(env_info.gas_limit, 40000.into()); - assert_eq!(env_info.difficulty, 50000.into()); - assert_eq!(env_info.gas_used, 0.into()); - } - - #[test] - fn it_can_be_created_as_default() { - let default_env_info = EnvInfo::default(); - - assert_eq!(default_env_info.difficulty, 0.into()); - } -} diff --git a/ethcore/evm/src/evm.rs b/ethcore/evm/src/evm.rs index c27caf8b389..a6442e759ea 100644 --- a/ethcore/evm/src/evm.rs +++ b/ethcore/evm/src/evm.rs @@ -17,125 +17,8 @@ //! Evm interface. use std::{ops, cmp, fmt}; -use util::{U128, U256, U512, trie}; -use action_params::ActionParams; -use {Ext}; - -use super::wasm; - -/// Evm errors. -#[derive(Debug, Clone, PartialEq)] -pub enum Error { - /// `OutOfGas` is returned when transaction execution runs out of gas. - /// The state should be reverted to the state from before the - /// transaction execution. But it does not mean that transaction - /// was invalid. Balance still should be transfered and nonce - /// should be increased. - OutOfGas, - /// `BadJumpDestination` is returned when execution tried to move - /// to position that wasn't marked with JUMPDEST instruction - BadJumpDestination { - /// Position the code tried to jump to. - destination: usize - }, - /// `BadInstructions` is returned when given instruction is not supported - BadInstruction { - /// Unrecognized opcode - instruction: u8, - }, - /// `StackUnderflow` when there is not enough stack elements to execute instruction - StackUnderflow { - /// Invoked instruction - instruction: &'static str, - /// How many stack elements was requested by instruction - wanted: usize, - /// How many elements were on stack - on_stack: usize - }, - /// When execution would exceed defined Stack Limit - OutOfStack { - /// Invoked instruction - instruction: &'static str, - /// How many stack elements instruction wanted to push - wanted: usize, - /// What was the stack limit - limit: usize - }, - /// Built-in contract failed on given input - BuiltIn(&'static str), - /// When execution tries to modify the state in static context - MutableCallInStaticContext, - /// Likely to cause consensus issues. - Internal(String), - /// Wasm runtime error - Wasm(String), -} - -impl From> for Error { - fn from(err: Box) -> Self { - Error::Internal(format!("Internal error: {}", err)) - } -} - -impl From for Error { - fn from(err: wasm::RuntimeError) -> Self { - Error::Wasm(format!("Runtime error: {:?}", err)) - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; - match *self { - OutOfGas => write!(f, "Out of gas"), - BadJumpDestination { destination } => write!(f, "Bad jump destination {:x}", destination), - BadInstruction { instruction } => write!(f, "Bad instruction {:x}", instruction), - StackUnderflow { instruction, wanted, on_stack } => write!(f, "Stack underflow {} {}/{}", instruction, wanted, on_stack), - OutOfStack { instruction, wanted, limit } => write!(f, "Out of stack {} {}/{}", instruction, wanted, limit), - BuiltIn(name) => write!(f, "Built-in failed: {}", name), - Internal(ref msg) => write!(f, "Internal error: {}", msg), - MutableCallInStaticContext => write!(f, "Mutable call in static context"), - Wasm(ref msg) => write!(f, "Internal error: {}", msg), - } - } -} - -/// A specialized version of Result over EVM errors. -pub type Result = ::std::result::Result; - -/// Return data buffer. Holds memory from a previous call and a slice into that memory. -#[derive(Debug)] -pub struct ReturnData { - mem: Vec, - offset: usize, - size: usize, -} - -impl ::std::ops::Deref for ReturnData { - type Target = [u8]; - fn deref(&self) -> &[u8] { - &self.mem[self.offset..self.offset + self.size] - } -} - -impl ReturnData { - /// Create empty `ReturnData`. - pub fn empty() -> Self { - ReturnData { - mem: Vec::new(), - offset: 0, - size: 0, - } - } - /// Create `ReturnData` from give buffer and slice. - pub fn new(mem: Vec, offset: usize, size: usize) -> Self { - ReturnData { - mem: mem, - offset: offset, - size: size, - } - } -} +use util::{U128, U256, U512}; +use vm::{Ext, ActionParams, Result, ReturnData, Error}; /// Gas Left: either it is a known value, or it needs to be computed by processing /// a return instruction. diff --git a/ethcore/evm/src/ext.rs b/ethcore/evm/src/ext.rs deleted file mode 100644 index 1c3ddb317b8..00000000000 --- a/ethcore/evm/src/ext.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Interface for Evm externalities. - -use util::*; -use call_type::CallType; -use env_info::EnvInfo; -use schedule::Schedule; -use evm::{self, ReturnData}; - -/// Result of externalities create function. -pub enum ContractCreateResult { - /// Returned when creation was successfull. - /// Contains an address of newly created contract and gas left. - Created(Address, U256), - /// Returned when contract creation failed. - /// VM doesn't have to know the reason. - Failed -} - -/// Result of externalities call function. -pub enum MessageCallResult { - /// Returned when message call was successfull. - /// Contains gas left and output data. - Success(U256, ReturnData), - /// Returned when message call failed. - /// VM doesn't have to know the reason. - Failed -} - -/// Specifies how an address is calculated for a new contract. -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum CreateContractAddress { - /// Address is calculated from nonce and sender. Pre EIP-86 (Metropolis) - FromSenderAndNonce, - /// Address is calculated from code hash. Default since EIP-86 - FromCodeHash, - /// Address is calculated from code hash and sender. Used by CREATE_P2SH instruction. - FromSenderAndCodeHash, -} - -/// Externalities interface for EVMs -pub trait Ext { - /// Returns a value for given key. - fn storage_at(&self, key: &H256) -> evm::Result; - - /// Stores a value for given key. - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()>; - - /// Determine whether an account exists. - fn exists(&self, address: &Address) -> evm::Result; - - /// Determine whether an account exists and is not null (zero balance/nonce, no code). - fn exists_and_not_null(&self, address: &Address) -> evm::Result; - - /// Balance of the origin account. - fn origin_balance(&self) -> evm::Result; - - /// Returns address balance. - fn balance(&self, address: &Address) -> evm::Result; - - /// Returns the hash of one of the 256 most recent complete blocks. - fn blockhash(&mut self, number: &U256) -> H256; - - /// Creates new contract. - /// - /// Returns gas_left and contract address if contract creation was succesfull. - fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult; - - /// Message call. - /// - /// Returns Err, if we run out of gas. - /// Otherwise returns call_result which contains gas left - /// and true if subcall was successfull. - #[cfg_attr(feature="dev", allow(too_many_arguments))] - fn call(&mut self, - gas: &U256, - sender_address: &Address, - receive_address: &Address, - value: Option, - data: &[u8], - code_address: &Address, - output: &mut [u8], - call_type: CallType - ) -> MessageCallResult; - - /// Returns code at given address - fn extcode(&self, address: &Address) -> evm::Result>; - - /// Returns code size at given address - fn extcodesize(&self, address: &Address) -> evm::Result; - - /// Creates log entry with given topics and data - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()>; - - /// Should be called when transaction calls `RETURN` opcode. - /// Returns gas_left if cost of returning the data is not too high. - fn ret(self, gas: &U256, data: &ReturnData) -> evm::Result; - - /// Should be called when contract commits suicide. - /// Address to which funds should be refunded. - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> ; - - /// Returns schedule. - fn schedule(&self) -> &Schedule; - - /// Returns environment info. - fn env_info(&self) -> &EnvInfo; - - /// Returns current depth of execution. - /// - /// If contract A calls contract B, and contract B calls C, - /// then A depth is 0, B is 1, C is 2 and so on. - fn depth(&self) -> usize; - - /// Increments sstore refunds count by 1. - fn inc_sstore_clears(&mut self); - - /// Decide if any more operations should be traced. Passthrough for the VM trace. - fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8) -> bool { false } - - /// Prepare to trace an operation. Passthrough for the VM trace. - fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256) {} - - /// Trace the finalised execution of a single instruction. - fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {} -} diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index c2dcf5412e9..1533de83789 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -17,15 +17,15 @@ use util::*; use super::u256_to_address; -use {evm, ext}; +use {evm, vm}; use instructions::{self, Instruction, InstructionInfo}; use interpreter::stack::Stack; -use schedule::Schedule; +use vm::Schedule; macro_rules! overflowing { ($x: expr) => {{ let (v, overflow) = $x; - if overflow { return Err(evm::Error::OutOfGas); } + if overflow { return Err(vm::Error::OutOfGas); } v }} } @@ -59,16 +59,16 @@ impl Gasometer { } } - pub fn verify_gas(&self, gas_cost: &Gas) -> evm::Result<()> { + pub fn verify_gas(&self, gas_cost: &Gas) -> vm::Result<()> { match &self.current_gas < gas_cost { - true => Err(evm::Error::OutOfGas), + true => Err(vm::Error::OutOfGas), false => Ok(()) } } /// How much gas is provided to a CALL/CREATE, given that we need to deduct `needed` for this operation /// and that we `requested` some. - pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option) -> evm::Result { + pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option) -> vm::Result { // Try converting requested gas to `Gas` (`U256/u64`) // but in EIP150 even if we request more we should never fail from OOG let requested = requested.map(Gas::from_u256); @@ -107,12 +107,12 @@ impl Gasometer { /// it will be the amount of gas that the current context provides to the child context. pub fn requirements( &mut self, - ext: &ext::Ext, + ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack, current_mem_size: usize, - ) -> evm::Result> { + ) -> vm::Result> { let schedule = ext.schedule(); let tier = instructions::get_tier_idx(info.tier); let default_gas = Gas::from(schedule.tier_step_gas[tier]); @@ -291,7 +291,7 @@ impl Gasometer { }) } - fn mem_gas_cost(&self, schedule: &Schedule, current_mem_size: usize, mem_size: &Gas) -> evm::Result<(Gas, Gas, usize)> { + fn mem_gas_cost(&self, schedule: &Schedule, current_mem_size: usize, mem_size: &Gas) -> vm::Result<(Gas, Gas, usize)> { let gas_for_mem = |mem_size: Gas| { let s = mem_size >> 5; // s * memory_gas + s * s / quad_coeff_div @@ -319,12 +319,12 @@ impl Gasometer { #[inline] -fn mem_needed_const(mem: &U256, add: usize) -> evm::Result { +fn mem_needed_const(mem: &U256, add: usize) -> vm::Result { Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add)))) } #[inline] -fn mem_needed(offset: &U256, size: &U256) -> evm::Result { +fn mem_needed(offset: &U256, size: &U256) -> vm::Result { if size.is_zero() { return Ok(Gas::from(0)); } diff --git a/ethcore/evm/src/interpreter/memory.rs b/ethcore/evm/src/interpreter/memory.rs index 017b5777d74..a13c99a820e 100644 --- a/ethcore/evm/src/interpreter/memory.rs +++ b/ethcore/evm/src/interpreter/memory.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use util::U256; -use {ReturnData}; +use vm::ReturnData; const MAX_RETURN_WASTE_BYTES: usize = 16384; diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 30b431912e5..89000471f65 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -23,17 +23,18 @@ mod stack; mod memory; mod shared_cache; +use std::marker::PhantomData; + +use vm::{self, ActionParams, ActionValue, CallType, MessageCallResult, ContractCreateResult, CreateContractAddress, ReturnData}; + +use evm::{self, GasLeft, CostType}; +use instructions::{self, Instruction, InstructionInfo}; + use self::gasometer::Gasometer; use self::stack::{Stack, VecStack}; use self::memory::Memory; pub use self::shared_cache::SharedCache; -use std::marker::PhantomData; -use action_params::{ActionParams, ActionValue}; -use call_type::CallType; -use instructions::{self, Instruction, InstructionInfo}; -use evm::{self, GasLeft, CostType, ReturnData}; -use ext::{self, MessageCallResult, ContractCreateResult, CreateContractAddress}; use bit_set::BitSet; use util::*; @@ -108,7 +109,7 @@ pub struct Interpreter { } impl evm::Evm for Interpreter { - fn exec(&mut self, params: ActionParams, ext: &mut ext::Ext) -> evm::Result { + fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result { self.mem.clear(); let mut informant = informant::EvmInformant::new(ext.depth()); @@ -205,7 +206,7 @@ impl Interpreter { } } - fn verify_instruction(&self, ext: &ext::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack) -> evm::Result<()> { + fn verify_instruction(&self, ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack) -> vm::Result<()> { let schedule = ext.schedule(); if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) || @@ -214,25 +215,25 @@ impl Interpreter { ((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) || (instruction == instructions::REVERT && !schedule.have_revert) { - return Err(evm::Error::BadInstruction { + return Err(vm::Error::BadInstruction { instruction: instruction }); } if info.tier == instructions::GasPriceTier::Invalid { - return Err(evm::Error::BadInstruction { + return Err(vm::Error::BadInstruction { instruction: instruction }); } if !stack.has(info.args) { - Err(evm::Error::StackUnderflow { + Err(vm::Error::StackUnderflow { instruction: info.name, wanted: info.args, on_stack: stack.size() }) } else if stack.size() - info.args + info.ret > schedule.stack_limit { - Err(evm::Error::OutOfStack { + Err(vm::Error::OutOfStack { instruction: info.name, wanted: info.ret - info.args, limit: schedule.stack_limit @@ -272,12 +273,12 @@ impl Interpreter { &mut self, gas: Cost, params: &ActionParams, - ext: &mut ext::Ext, + ext: &mut vm::Ext, instruction: Instruction, code: &mut CodeReader, stack: &mut Stack, provided: Option - ) -> evm::Result> { + ) -> vm::Result> { match instruction { instructions::JUMP => { let jump = stack.pop_back(); @@ -593,13 +594,13 @@ impl Interpreter { } } - fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> evm::Result { + fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> vm::Result { let jump = jump_u.low_u64() as usize; if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u { Ok(jump) } else { - Err(evm::Error::BadJumpDestination { + Err(vm::Error::BadJumpDestination { destination: jump }) } @@ -617,7 +618,7 @@ impl Interpreter { } } - fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack) -> evm::Result<()> { + fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack) -> vm::Result<()> { match instruction { instructions::DUP1...instructions::DUP16 => { let position = instructions::get_dup_position(instruction); @@ -822,7 +823,7 @@ impl Interpreter { } }, _ => { - return Err(evm::Error::BadInstruction { + return Err(vm::Error::BadInstruction { instruction: instruction }); } diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index fa4d12315a4..5b43dbec408 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -24,11 +24,11 @@ extern crate ethjson; extern crate rlp; extern crate parity_wasm; extern crate wasm_utils; +extern crate vm; #[macro_use] extern crate lazy_static; -#[macro_use] extern crate log; #[cfg(feature = "jit")] @@ -37,14 +37,8 @@ extern crate evmjit; #[cfg(test)] extern crate rustc_hex; -pub mod action_params; -pub mod call_type; -pub mod env_info; -pub mod ext; pub mod evm; pub mod interpreter; -pub mod schedule; -pub mod wasm; #[macro_use] pub mod factory; @@ -59,12 +53,8 @@ mod tests; #[cfg(all(feature="benches", test))] mod benches; -pub use self::action_params::ActionParams; -pub use self::call_type::CallType; -pub use self::env_info::EnvInfo; -pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData}; -pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; +pub use vm::{Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; +pub use self::evm::{Evm, Finalize, FinalizationResult, GasLeft, CostType}; pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; pub use self::vmtype::VMType; pub use self::factory::Factory; -pub use self::schedule::{Schedule, CleanDustMode}; diff --git a/ethcore/evm/src/schedule.rs b/ethcore/evm/src/schedule.rs deleted file mode 100644 index e721dc8035a..00000000000 --- a/ethcore/evm/src/schedule.rs +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Cost schedule and other parameterisations for the EVM. - -/// Definition of the cost schedule and other parameterisations for the EVM. -pub struct Schedule { - /// Does it support exceptional failed code deposit - pub exceptional_failed_code_deposit: bool, - /// Does it have a delegate cal - pub have_delegate_call: bool, - /// Does it have a CREATE_P2SH instruction - pub have_create2: bool, - /// Does it have a REVERT instruction - pub have_revert: bool, - /// VM stack limit - pub stack_limit: usize, - /// Max number of nested calls/creates - pub max_depth: usize, - /// Gas prices for instructions in all tiers - pub tier_step_gas: [usize; 8], - /// Gas price for `EXP` opcode - pub exp_gas: usize, - /// Additional gas for `EXP` opcode for each byte of exponent - pub exp_byte_gas: usize, - /// Gas price for `SHA3` opcode - pub sha3_gas: usize, - /// Additional gas for `SHA3` opcode for each word of hashed memory - pub sha3_word_gas: usize, - /// Gas price for loading from storage - pub sload_gas: usize, - /// Gas price for setting new value to storage (`storage==0`, `new!=0`) - pub sstore_set_gas: usize, - /// Gas price for altering value in storage - pub sstore_reset_gas: usize, - /// Gas refund for `SSTORE` clearing (when `storage!=0`, `new==0`) - pub sstore_refund_gas: usize, - /// Gas price for `JUMPDEST` opcode - pub jumpdest_gas: usize, - /// Gas price for `LOG*` - pub log_gas: usize, - /// Additional gas for data in `LOG*` - pub log_data_gas: usize, - /// Additional gas for each topic in `LOG*` - pub log_topic_gas: usize, - /// Gas price for `CREATE` opcode - pub create_gas: usize, - /// Gas price for `*CALL*` opcodes - pub call_gas: usize, - /// Stipend for transfer for `CALL|CALLCODE` opcode when `value>0` - pub call_stipend: usize, - /// Additional gas required for value transfer (`CALL|CALLCODE`) - pub call_value_transfer_gas: usize, - /// Additional gas for creating new account (`CALL|CALLCODE`) - pub call_new_account_gas: usize, - /// Refund for SUICIDE - pub suicide_refund_gas: usize, - /// Gas for used memory - pub memory_gas: usize, - /// Coefficient used to convert memory size to gas price for memory - pub quad_coeff_div: usize, - /// Cost for contract length when executing `CREATE` - pub create_data_gas: usize, - /// Maximum code size when creating a contract. - pub create_data_limit: usize, - /// Transaction cost - pub tx_gas: usize, - /// `CREATE` transaction cost - pub tx_create_gas: usize, - /// Additional cost for empty data transaction - pub tx_data_zero_gas: usize, - /// Aditional cost for non-empty data transaction - pub tx_data_non_zero_gas: usize, - /// Gas price for copying memory - pub copy_gas: usize, - /// Price of EXTCODESIZE - pub extcodesize_gas: usize, - /// Base price of EXTCODECOPY - pub extcodecopy_base_gas: usize, - /// Price of BALANCE - pub balance_gas: usize, - /// Price of SUICIDE - pub suicide_gas: usize, - /// Amount of additional gas to pay when SUICIDE credits a non-existant account - pub suicide_to_new_account_cost: usize, - /// If Some(x): let limit = GAS * (x - 1) / x; let CALL's gas = min(requested, limit). let CREATE's gas = limit. - /// If None: let CALL's gas = (requested > GAS ? [OOG] : GAS). let CREATE's gas = GAS - pub sub_gas_cap_divisor: Option, - /// Don't ever make empty accounts; contracts start with nonce=1. Also, don't charge 25k when sending/suicide zero-value. - pub no_empty: bool, - /// Kill empty accounts if touched. - pub kill_empty: bool, - /// Blockhash instruction gas cost. - pub blockhash_gas: usize, - /// Static Call opcode enabled. - pub have_static_call: bool, - /// RETURNDATA and RETURNDATASIZE opcodes enabled. - pub have_return_data: bool, - /// Kill basic accounts below this balance if touched. - pub kill_dust: CleanDustMode, -} - -/// Dust accounts cleanup mode. -#[derive(PartialEq, Eq)] -pub enum CleanDustMode { - /// Dust cleanup is disabled. - Off, - /// Basic dust accounts will be removed. - BasicOnly, - /// Basic and contract dust accounts will be removed. - WithCodeAndStorage, -} - -impl Schedule { - /// Schedule for the Frontier-era of the Ethereum main net. - pub fn new_frontier() -> Schedule { - Self::new(false, false, 21000) - } - - /// Schedule for the Homestead-era of the Ethereum main net. - pub fn new_homestead() -> Schedule { - Self::new(true, true, 53000) - } - - /// Schedule for the post-EIP-150-era of the Ethereum main net. - pub fn new_post_eip150(max_code_size: usize, fix_exp: bool, no_empty: bool, kill_empty: bool) -> Schedule { - Schedule { - exceptional_failed_code_deposit: true, - have_delegate_call: true, - have_create2: false, - have_revert: false, - have_return_data: false, - stack_limit: 1024, - max_depth: 1024, - tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], - exp_gas: 10, - exp_byte_gas: if fix_exp {50} else {10}, - sha3_gas: 30, - sha3_word_gas: 6, - sload_gas: 200, - sstore_set_gas: 20000, - sstore_reset_gas: 5000, - sstore_refund_gas: 15000, - jumpdest_gas: 1, - log_gas: 375, - log_data_gas: 8, - log_topic_gas: 375, - create_gas: 32000, - call_gas: 700, - call_stipend: 2300, - call_value_transfer_gas: 9000, - call_new_account_gas: 25000, - suicide_refund_gas: 24000, - memory_gas: 3, - quad_coeff_div: 512, - create_data_gas: 200, - create_data_limit: max_code_size, - tx_gas: 21000, - tx_create_gas: 53000, - tx_data_zero_gas: 4, - tx_data_non_zero_gas: 68, - copy_gas: 3, - extcodesize_gas: 700, - extcodecopy_base_gas: 700, - balance_gas: 400, - suicide_gas: 5000, - suicide_to_new_account_cost: 25000, - sub_gas_cap_divisor: Some(64), - no_empty: no_empty, - kill_empty: kill_empty, - blockhash_gas: 20, - have_static_call: false, - kill_dust: CleanDustMode::Off, - } - } - - /// Schedule for the Metropolis of the Ethereum main net. - pub fn new_metropolis() -> Schedule { - let mut schedule = Self::new_post_eip150(24576, true, true, true); - schedule.have_create2 = true; - schedule.have_revert = true; - schedule.have_static_call = true; - schedule.have_return_data = true; - schedule.blockhash_gas = 350; - schedule - } - - fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule { - Schedule { - exceptional_failed_code_deposit: efcd, - have_delegate_call: hdc, - have_create2: false, - have_revert: false, - have_return_data: false, - stack_limit: 1024, - max_depth: 1024, - tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], - exp_gas: 10, - exp_byte_gas: 10, - sha3_gas: 30, - sha3_word_gas: 6, - sload_gas: 50, - sstore_set_gas: 20000, - sstore_reset_gas: 5000, - sstore_refund_gas: 15000, - jumpdest_gas: 1, - log_gas: 375, - log_data_gas: 8, - log_topic_gas: 375, - create_gas: 32000, - call_gas: 40, - call_stipend: 2300, - call_value_transfer_gas: 9000, - call_new_account_gas: 25000, - suicide_refund_gas: 24000, - memory_gas: 3, - quad_coeff_div: 512, - create_data_gas: 200, - create_data_limit: usize::max_value(), - tx_gas: 21000, - tx_create_gas: tcg, - tx_data_zero_gas: 4, - tx_data_non_zero_gas: 68, - copy_gas: 3, - extcodesize_gas: 20, - extcodecopy_base_gas: 20, - balance_gas: 20, - suicide_gas: 0, - suicide_to_new_account_cost: 0, - sub_gas_cap_divisor: None, - no_empty: false, - kill_empty: false, - blockhash_gas: 20, - have_static_call: false, - kill_dust: CleanDustMode::Off, - } - } -} - -#[test] -#[cfg(test)] -fn schedule_evm_assumptions() { - let s1 = Schedule::new_frontier(); - let s2 = Schedule::new_homestead(); - - // To optimize division we assume 2**9 for quad_coeff_div - assert_eq!(s1.quad_coeff_div, 512); - assert_eq!(s2.quad_coeff_div, 512); -} diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index d0502f79adf..a80893ac305 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -17,12 +17,12 @@ use std::fmt::Debug; use rustc_hex::FromHex; use util::*; -use action_params::{ActionParams, ActionValue}; -use env_info::EnvInfo; -use call_type::CallType; -use schedule::Schedule; -use evm::{self, GasLeft, ReturnData}; -use ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; +use evm::{self, GasLeft}; +use vm::{ + self, CallType, Schedule, EnvInfo, ActionParams, ActionValue, + ReturnData, Ext, ContractCreateResult, MessageCallResult, + CreateContractAddress, +}; use factory::Factory; use vmtype::VMType; @@ -66,7 +66,7 @@ pub struct FakeExt { } // similar to the normal `finalize` function, but ignoring NeedsReturn. -fn test_finalize(res: Result) -> Result { +fn test_finalize(res: Result) -> Result { match res { Ok(GasLeft::Known(gas)) => Ok(gas), Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented. @@ -80,35 +80,29 @@ impl FakeExt { } } -impl Default for Schedule { - fn default() -> Self { - Schedule::new_frontier() - } -} - impl Ext for FakeExt { - fn storage_at(&self, key: &H256) -> evm::Result { + fn storage_at(&self, key: &H256) -> vm::Result { Ok(self.store.get(key).unwrap_or(&H256::new()).clone()) } - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { + fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { self.store.insert(key, value); Ok(()) } - fn exists(&self, address: &Address) -> evm::Result { + fn exists(&self, address: &Address) -> vm::Result { Ok(self.balances.contains_key(address)) } - fn exists_and_not_null(&self, address: &Address) -> evm::Result { + fn exists_and_not_null(&self, address: &Address) -> vm::Result { Ok(self.balances.get(address).map_or(false, |b| !b.is_zero())) } - fn origin_balance(&self) -> evm::Result { + fn origin_balance(&self) -> vm::Result { unimplemented!() } - fn balance(&self, address: &Address) -> evm::Result { + fn balance(&self, address: &Address) -> vm::Result { Ok(self.balances[address]) } @@ -152,15 +146,15 @@ impl Ext for FakeExt { MessageCallResult::Success(*gas, ReturnData::empty()) } - fn extcode(&self, address: &Address) -> evm::Result> { + fn extcode(&self, address: &Address) -> vm::Result> { Ok(self.codes.get(address).unwrap_or(&Arc::new(Bytes::new())).clone()) } - fn extcodesize(&self, address: &Address) -> evm::Result { + fn extcodesize(&self, address: &Address) -> vm::Result { Ok(self.codes.get(address).map_or(0, |c| c.len())) } - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()> { + fn log(&mut self, topics: Vec, data: &[u8]) -> vm::Result<()> { self.logs.push(FakeLogEntry { topics: topics, data: data.to_vec() @@ -168,11 +162,11 @@ impl Ext for FakeExt { Ok(()) } - fn ret(self, _gas: &U256, _data: &ReturnData) -> evm::Result { + fn ret(self, _gas: &U256, _data: &ReturnData) -> vm::Result { unimplemented!(); } - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { + fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { self.suicides.insert(refund_address.clone()); Ok(()) } @@ -211,7 +205,7 @@ fn test_stack_underflow() { }; match err { - evm::Error::StackUnderflow {wanted, on_stack, ..} => { + vm::Error::StackUnderflow {wanted, on_stack, ..} => { assert_eq!(wanted, 2); assert_eq!(on_stack, 0); } @@ -849,7 +843,7 @@ fn test_badinstruction_int() { }; match err { - evm::Error::BadInstruction { instruction: 0xaf } => (), + vm::Error::BadInstruction { instruction: 0xaf } => (), _ => assert!(false, "Expected bad instruction") } } diff --git a/ethcore/vm/src/error.rs b/ethcore/vm/src/error.rs index d93052f5467..e4b19943830 100644 --- a/ethcore/vm/src/error.rs +++ b/ethcore/vm/src/error.rs @@ -16,6 +16,9 @@ //! VM errors module +use util::trie; +use std::fmt; + /// VM errors. #[derive(Debug, Clone, PartialEq)] pub enum Error { @@ -64,4 +67,34 @@ pub enum Error { Wasm(String), } + +impl From> for Error { + fn from(err: Box) -> Self { + Error::Internal(format!("Internal error: {}", err)) + } +} + +// impl From for Error { +// fn from(err: wasm::RuntimeError) -> Self { +// Error::Wasm(format!("Runtime error: {:?}", err)) +// } +// } + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::Error::*; + match *self { + OutOfGas => write!(f, "Out of gas"), + BadJumpDestination { destination } => write!(f, "Bad jump destination {:x}", destination), + BadInstruction { instruction } => write!(f, "Bad instruction {:x}", instruction), + StackUnderflow { instruction, wanted, on_stack } => write!(f, "Stack underflow {} {}/{}", instruction, wanted, on_stack), + OutOfStack { instruction, wanted, limit } => write!(f, "Out of stack {} {}/{}", instruction, wanted, limit), + BuiltIn(name) => write!(f, "Built-in failed: {}", name), + Internal(ref msg) => write!(f, "Internal error: {}", msg), + MutableCallInStaticContext => write!(f, "Mutable call in static context"), + Wasm(ref msg) => write!(f, "Internal error: {}", msg), + } + } +} + pub type Result = ::std::result::Result; diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs index 92013a84e58..2c3f81adbcb 100644 --- a/ethcore/vm/src/lib.rs +++ b/ethcore/vm/src/lib.rs @@ -29,10 +29,10 @@ mod ext; mod return_data; mod error; -pub use action_params::ActionParams; +pub use action_params::{ActionParams, ActionValue}; pub use call_type::CallType; pub use env_info::EnvInfo; -pub use schedule::Schedule; -pub use ext::Ext; +pub use schedule::{Schedule, CleanDustMode}; +pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress}; pub use return_data::ReturnData; pub use error::{Error, Result}; \ No newline at end of file diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs index e721dc8035a..6966c26e6a5 100644 --- a/ethcore/vm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -250,6 +250,12 @@ impl Schedule { } } +impl Default for Schedule { + fn default() -> Self { + Schedule::new_frontier() + } +} + #[test] #[cfg(test)] fn schedule_evm_assumptions() { @@ -260,3 +266,4 @@ fn schedule_evm_assumptions() { assert_eq!(s1.quad_coeff_div, 512); assert_eq!(s2.quad_coeff_div, 512); } + From f2524e15ad147705e970d6316b8edd408c6d299f Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 28 Jul 2017 19:14:01 +0300 Subject: [PATCH 3/6] Evm -> Vm --- ethcore/evm/src/evm.rs | 28 +--------------------------- ethcore/evm/src/factory.rs | 6 +++--- ethcore/evm/src/interpreter/mod.rs | 9 ++++++--- ethcore/evm/src/jit.rs | 3 ++- ethcore/evm/src/lib.rs | 8 ++++++-- ethcore/vm/src/lib.rs | 12 ++++++++++-- ethcore/vm/src/return_data.rs | 21 ++++++++++++++++++++- 7 files changed, 48 insertions(+), 39 deletions(-) diff --git a/ethcore/evm/src/evm.rs b/ethcore/evm/src/evm.rs index a6442e759ea..d593143a639 100644 --- a/ethcore/evm/src/evm.rs +++ b/ethcore/evm/src/evm.rs @@ -18,24 +18,7 @@ use std::{ops, cmp, fmt}; use util::{U128, U256, U512}; -use vm::{Ext, ActionParams, Result, ReturnData, Error}; - -/// Gas Left: either it is a known value, or it needs to be computed by processing -/// a return instruction. -#[derive(Debug)] -pub enum GasLeft { - /// Known gas left - Known(U256), - /// Return or Revert instruction must be processed. - NeedsReturn { - /// Amount of gas left. - gas_left: U256, - /// Return data buffer. - data: ReturnData, - /// Apply or revert state changes on revert. - apply_state: bool - }, -} +use vm::{Ext, Result, ReturnData, GasLeft, Error}; /// Finalization result. Gas Left: either it is a known value, or it needs to be computed by processing /// a return instruction. @@ -164,15 +147,6 @@ impl CostType for usize { } } -/// Evm interface -pub trait Evm { - /// 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; -} - #[cfg(test)] mod tests { use util::U256; diff --git a/ethcore/evm/src/factory.rs b/ethcore/evm/src/factory.rs index 2d8934ca1f8..20275dbff54 100644 --- a/ethcore/evm/src/factory.rs +++ b/ethcore/evm/src/factory.rs @@ -17,7 +17,7 @@ //! Evm factory. //! use std::sync::Arc; -use evm::Evm; +use vm::Vm; use util::U256; use super::interpreter::SharedCache; use super::vmtype::VMType; @@ -33,7 +33,7 @@ impl Factory { /// Create fresh instance of VM /// Might choose implementation depending on supplied gas. #[cfg(feature = "jit")] - pub fn create(&self, gas: U256) -> Box { + pub fn create(&self, gas: U256) -> Box { match self.evm { VMType::Jit => { Box::new(super::jit::JitEvm::default()) @@ -49,7 +49,7 @@ impl Factory { /// Create fresh instance of VM /// Might choose implementation depending on supplied gas. #[cfg(not(feature = "jit"))] - pub fn create(&self, gas: U256) -> Box { + pub fn create(&self, gas: U256) -> Box { match self.evm { VMType::Interpreter => if Self::can_fit_in_usize(gas) { Box::new(super::interpreter::Interpreter::::new(self.evm_cache.clone())) diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 89000471f65..3c39a89c1f3 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -25,9 +25,12 @@ mod shared_cache; use std::marker::PhantomData; -use vm::{self, ActionParams, ActionValue, CallType, MessageCallResult, ContractCreateResult, CreateContractAddress, ReturnData}; +use vm::{ + self, ActionParams, ActionValue, CallType, MessageCallResult, + ContractCreateResult, CreateContractAddress, ReturnData, GasLeft +}; -use evm::{self, GasLeft, CostType}; +use evm::CostType; use instructions::{self, Instruction, InstructionInfo}; use self::gasometer::Gasometer; @@ -108,7 +111,7 @@ pub struct Interpreter { _type: PhantomData, } -impl evm::Evm for Interpreter { +impl vm::Vm for Interpreter { fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result { self.mem.clear(); diff --git a/ethcore/evm/src/jit.rs b/ethcore/evm/src/jit.rs index f27e9b5d3af..4b2a524034d 100644 --- a/ethcore/evm/src/jit.rs +++ b/ethcore/evm/src/jit.rs @@ -19,6 +19,7 @@ use util::*; use evmjit; use evm::{self, GasLeft}; use evm::CallType; +use vm::{self, Vm}; /// Should be used to convert jit types to ethcore trait FromJit: Sized { @@ -318,7 +319,7 @@ pub struct JitEvm { context: Option, } -impl evm::Evm for JitEvm { +impl vm::Vm for JitEvm { fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result { // Dirty hack. This is unsafe, but we interact with ffi, so it's justified. let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext, params.address.clone())) }; diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index 5b43dbec408..aa4d876977b 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -53,8 +53,12 @@ mod tests; #[cfg(all(feature="benches", test))] mod benches; -pub use vm::{Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; -pub use self::evm::{Evm, Finalize, FinalizationResult, GasLeft, CostType}; +pub use vm::{ + Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext, + ContractCreateResult, MessageCallResult, CreateContractAddress, + GasLeft, ReturnData +}; +pub use self::evm::{Finalize, FinalizationResult, CostType}; pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; pub use self::vmtype::VMType; pub use self::factory::Factory; diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs index 2c3f81adbcb..cd4bd48ae88 100644 --- a/ethcore/vm/src/lib.rs +++ b/ethcore/vm/src/lib.rs @@ -34,5 +34,13 @@ pub use call_type::CallType; pub use env_info::EnvInfo; pub use schedule::{Schedule, CleanDustMode}; pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress}; -pub use return_data::ReturnData; -pub use error::{Error, Result}; \ No newline at end of file +pub use return_data::{ReturnData, GasLeft}; +pub use error::{Error, Result}; + +/// Virtual Machine interface +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; +} \ No newline at end of file diff --git a/ethcore/vm/src/return_data.rs b/ethcore/vm/src/return_data.rs index d678f4c7408..3c8bd182ff5 100644 --- a/ethcore/vm/src/return_data.rs +++ b/ethcore/vm/src/return_data.rs @@ -12,7 +12,9 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Return data structure +//! Return data structures + +use util::U256; /// Return data buffer. Holds memory from a previous call and a slice into that memory. #[derive(Debug)] @@ -46,4 +48,21 @@ impl ReturnData { size: size, } } +} + +/// Gas Left: either it is a known value, or it needs to be computed by processing +/// a return instruction. +#[derive(Debug)] +pub enum GasLeft { + /// Known gas left + Known(U256), + /// Return or Revert instruction must be processed. + NeedsReturn { + /// Amount of gas left. + gas_left: U256, + /// Return data buffer. + data: ReturnData, + /// Apply or revert state changes on revert. + apply_state: bool + }, } \ No newline at end of file From 6c7a6e91b29d0653185f1cb1b4853d8dddc3f4ae Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 28 Jul 2017 19:20:58 +0300 Subject: [PATCH 4/6] wasm converted --- Cargo.lock | 25 +++++++++++++++++++------ ethcore/Cargo.toml | 1 + ethcore/wasm/Cargo.toml | 1 + ethcore/wasm/src/lib.rs | 31 +++++++++++++++++++++---------- ethcore/wasm/src/runtime.rs | 13 ++++++------- 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e08df2d24d..2515e2bd86b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,15 +1,13 @@ [root] -name = "vm" +name = "wasm" version = "0.1.0" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "common-types 0.1.0", "ethcore-util 1.8.0", - "ethjson 0.1.0", - "evmjit 1.8.0", - "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.2.0", + "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", + "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", ] [[package]] @@ -515,6 +513,7 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", + "wasm 0.1.0", ] [[package]] @@ -3079,6 +3078,20 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "vm" +version = "0.1.0" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "common-types 0.1.0", + "ethcore-util 1.8.0", + "ethjson 0.1.0", + "evmjit 1.8.0", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.0", +] + [[package]] name = "void" version = "1.0.2" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index f1193b615b4..60f14590248 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -54,6 +54,7 @@ stats = { path = "../util/stats" } time = "0.1" transient-hashmap = "0.4" vm = { path = "vm" } +wasm = { path = "wasm" } [dev-dependencies] native-contracts = { path = "native_contracts", features = ["test_contracts"] } diff --git a/ethcore/wasm/Cargo.toml b/ethcore/wasm/Cargo.toml index 63edb811e56..bda35e3ef71 100644 --- a/ethcore/wasm/Cargo.toml +++ b/ethcore/wasm/Cargo.toml @@ -9,3 +9,4 @@ ethcore-util = { path = "../../util" } log = "0.3" parity-wasm = "0.12" wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } +vm = { path = "../vm" } \ No newline at end of file diff --git a/ethcore/wasm/src/lib.rs b/ethcore/wasm/src/lib.rs index a7186add542..9ca3869efb0 100644 --- a/ethcore/wasm/src/lib.rs +++ b/ethcore/wasm/src/lib.rs @@ -16,6 +16,13 @@ //! Wasm Interpreter +extern crate vm; +extern crate ethcore_util as util; +#[macro_use] extern crate log; +extern crate byteorder; +extern crate parity_wasm; +extern crate wasm_utils; + mod runtime; mod ptr; mod call_args; @@ -30,10 +37,8 @@ const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024; use parity_wasm::{interpreter, elements}; use parity_wasm::interpreter::ModuleInstanceInterface; -use wasm_utils; -use evm::{self, GasLeft, ReturnData}; -use action_params::ActionParams; +use vm::{GasLeft, ReturnData, ActionParams}; use self::runtime::Runtime; pub use self::runtime::Error as RuntimeError; @@ -56,9 +61,9 @@ impl WasmInterpreter { } } -impl evm::Evm for WasmInterpreter { +impl vm::Vm for WasmInterpreter { - fn exec(&mut self, params: ActionParams, ext: &mut ::ext::Ext) -> evm::Result { + fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result { use parity_wasm::elements::Deserialize; let code = params.code.expect("exec is only called on contract with code; qed"); @@ -74,7 +79,7 @@ impl evm::Evm for WasmInterpreter { .expect("Linear memory to exist in wasm runtime"); if params.gas > ::std::u64::MAX.into() { - return Err(evm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned())); + return Err(vm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned())); } let mut runtime = Runtime::with_params( @@ -90,7 +95,7 @@ impl evm::Evm for WasmInterpreter { elements::Module::deserialize( &mut cursor ).map_err(|err| { - evm::Error::Wasm(format!("Error deserializing contract code ({:?})", err)) + vm::Error::Wasm(format!("Error deserializing contract code ({:?})", err)) })? ); @@ -111,7 +116,7 @@ impl evm::Evm for WasmInterpreter { interpreter::env_native_module(env_instance, native_bindings(&mut runtime)) .map_err(|err| { // todo: prefer explicit panic here also? - evm::Error::Wasm(format!("Error instantiating native bindings: {:?}", err)) + vm::Error::Wasm(format!("Error instantiating native bindings: {:?}", err)) })? ) ).add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32)); @@ -119,13 +124,13 @@ impl evm::Evm for WasmInterpreter { let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals)) .map_err(|err| { trace!(target: "wasm", "Error adding contract module: {:?}", err); - evm::Error::from(RuntimeError::Interpreter(err)) + vm::Error::from(RuntimeError::Interpreter(err)) })?; module_instance.execute_export("_call", execution_params) .map_err(|err| { trace!(target: "wasm", "Error executing contract: {:?}", err); - evm::Error::from(RuntimeError::Interpreter(err)) + vm::Error::from(RuntimeError::Interpreter(err)) })?; } @@ -157,3 +162,9 @@ fn native_bindings<'a>(runtime: &'a mut Runtime) -> interpreter::UserFunctions<' functions: ::std::borrow::Cow::from(env::SIGNATURES), } } + +impl From for vm::Error { + fn from(err: runtime::Error) -> vm::Error { + vm::Error::Wasm(format!("WASM runtime-error: {:?}", err)) + } +} \ No newline at end of file diff --git a/ethcore/wasm/src/runtime.rs b/ethcore/wasm/src/runtime.rs index 7beb4c59971..5c6a4a626b2 100644 --- a/ethcore/wasm/src/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -20,8 +20,7 @@ use std::sync::Arc; use byteorder::{LittleEndian, ByteOrder}; -use ext; - +use vm; use parity_wasm::interpreter; use util::{Address, H256, U256}; @@ -62,14 +61,14 @@ pub struct Runtime<'a> { gas_counter: u64, gas_limit: u64, dynamic_top: u32, - ext: &'a mut ext::Ext, + ext: &'a mut vm::Ext, memory: Arc, } impl<'a> Runtime<'a> { /// New runtime for wasm contract with specified params pub fn with_params<'b>( - ext: &'b mut ext::Ext, + ext: &'b mut vm::Ext, memory: Arc, stack_space: u32, gas_limit: u64, @@ -153,14 +152,14 @@ impl<'a> Runtime<'a> { .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? .into(); - match self.ext.create(&gas_left, &endowment, &code, ext::CreateContractAddress::FromSenderAndCodeHash) { - ext::ContractCreateResult::Created(address, gas_left) => { + match self.ext.create(&gas_left, &endowment, &code, vm::CreateContractAddress::FromSenderAndCodeHash) { + vm::ContractCreateResult::Created(address, gas_left) => { self.memory.set(result_ptr, &*address)?; self.gas_counter = self.gas_limit - gas_left.low_u64(); trace!(target: "wasm", "runtime: create contract success (@{:?})", address); Ok(Some(0i32.into())) }, - ext::ContractCreateResult::Failed => { + vm::ContractCreateResult::Failed => { trace!(target: "wasm", "runtime: create contract fail"); Ok(Some((-1i32).into())) } From 21fcf01f06eae4ae50b6cfdf5edadbc2f4f792b6 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 28 Jul 2017 19:46:11 +0300 Subject: [PATCH 5/6] ethcore working --- ethcore/evm/src/benches/mod.rs | 2 +- ethcore/evm/src/jit.rs | 4 +- ethcore/light/src/on_demand/request.rs | 2 +- ethcore/src/block.rs | 4 +- ethcore/src/builtin.rs | 6 +- ethcore/src/client/client.rs | 3 +- ethcore/src/client/evm_test_client.rs | 4 +- ethcore/src/client/mod.rs | 2 +- ethcore/src/client/test_client.rs | 3 +- ethcore/src/client/traits.rs | 2 +- ethcore/src/engines/authority_round/mod.rs | 2 +- ethcore/src/engines/mod.rs | 8 +-- .../engines/validator_set/safe_contract.rs | 2 +- ethcore/src/ethereum/ethash.rs | 4 +- ethcore/src/executed.rs | 4 +- ethcore/src/executive.rs | 65 +++++++++---------- ethcore/src/externalities.rs | 43 ++++++------ ethcore/src/json_tests/executive.rs | 26 ++++---- ethcore/src/json_tests/state.rs | 2 +- ethcore/src/lib.rs | 2 + ethcore/src/spec/spec.rs | 14 ++-- ethcore/src/state/mod.rs | 4 +- ethcore/src/tests/evm.rs | 4 +- ethcore/src/trace/executive_tracer.rs | 2 +- ethcore/src/trace/mod.rs | 2 +- ethcore/src/trace/noop_tracer.rs | 2 +- ethcore/src/trace/types/error.rs | 28 ++++---- ethcore/src/trace/types/trace.rs | 2 +- ethcore/vm/src/lib.rs | 2 +- ethcore/wasm/src/tests.rs | 2 +- evmbin/benches/mod.rs | 2 +- evmbin/src/main.rs | 2 +- evmbin/src/vm.rs | 2 +- rpc/src/v1/helpers/light_fetch.rs | 2 +- 34 files changed, 125 insertions(+), 135 deletions(-) diff --git a/ethcore/evm/src/benches/mod.rs b/ethcore/evm/src/benches/mod.rs index 4463696d668..ecb7d379adf 100644 --- a/ethcore/evm/src/benches/mod.rs +++ b/ethcore/evm/src/benches/mod.rs @@ -25,7 +25,7 @@ extern crate test; use self::test::{Bencher, black_box}; use util::*; -use evm::action_params::ActionParams; +use vm::ActionParams; use evm::{self, Factory, VMType}; use evm::tests::FakeExt; diff --git a/ethcore/evm/src/jit.rs b/ethcore/evm/src/jit.rs index 4b2a524034d..22262cbb6d4 100644 --- a/ethcore/evm/src/jit.rs +++ b/ethcore/evm/src/jit.rs @@ -371,8 +371,8 @@ impl vm::Vm for JitEvm { ext.suicide(&Address::from_jit(&context.suicide_refund_address())); Ok(GasLeft::Known(U256::from(context.gas_left()))) }, - evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas), - _err => Err(evm::Error::Internal) + evmjit::ReturnCode::OutOfGas => Err(vm::Error::OutOfGas), + _err => Err(vm::Error::Internal) } } } diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index 9587dd8edcd..6a220134941 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -24,7 +24,7 @@ use ethcore::engines::Engine; use ethcore::receipt::Receipt; use ethcore::state::{self, ProvedExecution}; use ethcore::transaction::SignedTransaction; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 8cd1e22b6f2..64958700eb2 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -25,7 +25,7 @@ use util::{Bytes, Address, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RL use util::error::{Mismatch, OutOfBounds}; use basic_types::{LogBloom, Seal}; -use evm::env_info::{EnvInfo, LastHashes}; +use vm::{EnvInfo, LastHashes}; use engines::Engine; use error::{Error, BlockError, TransactionError}; use factory::Factories; @@ -667,7 +667,7 @@ mod tests { use tests::helpers::*; use super::*; use engines::Engine; - use evm::env_info::LastHashes; + use vm::LastHashes; use error::Error; use header::Header; use factory::Factories; diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index 7f71802b3c1..9e49e610cbf 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -36,9 +36,9 @@ impl From<&'static str> for Error { } } -impl Into<::evm::Error> for Error { - fn into(self) -> ::evm::Error { - ::evm::Error::BuiltIn(self.0) +impl Into<::vm::Error> for Error { + fn into(self) -> ::vm::Error { + ::vm::Error::BuiltIn(self.0) } } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 48cf481f1b5..94a5e09f34b 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -42,9 +42,8 @@ use client::{ }; use encoded; use engines::{Engine, EpochTransition}; -use evm::env_info::EnvInfo; -use evm::env_info::LastHashes; use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; +use vm::{EnvInfo, LastHashes}; use evm::{Factory as EvmFactory, Schedule}; use executive::{Executive, Executed, TransactOptions, contract_address}; use factory::Factories; diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index 5f23f449ddb..cd8501c310d 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -23,7 +23,7 @@ use util::kvdb::{self, KeyValueDB}; use {state, state_db, client, executive, trace, db, spec}; use factory::Factories; use evm::{self, VMType}; -use evm::action_params::ActionParams; +use vm::{self, ActionParams}; /// EVM test Error. #[derive(Debug)] @@ -31,7 +31,7 @@ pub enum EvmTestError { /// Trie integrity error. Trie(util::TrieError), /// EVM error. - Evm(evm::Error), + Evm(vm::Error), /// Initialization error. Initialization(::error::Error), /// Low-level database error. diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index b2d1ce99154..f7c7417ad72 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -40,7 +40,7 @@ pub use types::pruning_info::PruningInfo; pub use types::call_analytics::CallAnalytics; pub use executive::{Executed, Executive, TransactOptions}; -pub use evm::env_info::{LastHashes, EnvInfo}; +pub use vm::{LastHashes, EnvInfo}; pub use error::{BlockImportError, TransactionImportError, TransactionImportResult}; pub use verification::VerifierType; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 5dfdf5c2585..a8c99efe2b3 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -36,7 +36,8 @@ use log_entry::LocalizedLogEntry; use receipt::{Receipt, LocalizedReceipt}; use blockchain::extras::BlockReceipts; use error::{ImportResult, Error as EthcoreError}; -use evm::{Factory as EvmFactory, VMType, Schedule}; +use evm::{Factory as EvmFactory, VMType}; +use vm::Schedule; use miner::{Miner, MinerService, TransactionImportResult}; use spec::Spec; use types::basic_account::BasicAccount; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index aca369b2160..e76da60bd16 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -19,7 +19,7 @@ use std::collections::BTreeMap; use block::{OpenBlock, SealedBlock, ClosedBlock}; use blockchain::TreeRoute; use encoded; -use evm::env_info::LastHashes; +use vm::LastHashes; use error::{ImportResult, CallError, Error as EthcoreError}; use error::{TransactionImportResult, BlockImportError}; use evm::{Factory as EvmFactory, Schedule}; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 3210368dbac..882ddc3f45f 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -532,7 +532,7 @@ impl Engine for AuthorityRound { fn on_new_block( &self, block: &mut ExecutedBlock, - last_hashes: Arc<::evm::env_info::LastHashes>, + last_hashes: Arc<::vm::LastHashes>, epoch_begin: bool, ) -> Result<(), Error> { let parent_hash = block.fields().header.parent_hash().clone(); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index c5fa4818e14..5e415cb7adb 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -43,15 +43,13 @@ use account_provider::AccountProvider; use block::ExecutedBlock; use builtin::Builtin; use client::Client; -use evm::env_info::{EnvInfo, LastHashes}; +use vm::{EnvInfo, LastHashes, Schedule, CreateContractAddress}; use error::Error; -use evm::Schedule; use header::{Header, BlockNumber}; use receipt::Receipt; use snapshot::SnapshotComponents; use spec::CommonParams; use transaction::{UnverifiedTransaction, SignedTransaction}; -use evm::CreateContractAddress; use ethkey::Signature; use util::*; @@ -394,12 +392,10 @@ pub trait Engine : Sync + Send { /// Common engine utilities pub mod common { use block::ExecutedBlock; - use evm::env_info::{EnvInfo, LastHashes}; use error::Error; use transaction::SYSTEM_ADDRESS; use executive::Executive; - use evm::CallType; - use evm::action_params::{ActionParams, ActionValue}; + use vm::{CallType, ActionParams, ActionValue, EnvInfo, LastHashes}; use trace::{NoopTracer, NoopVMTracer}; use state::Substate; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 2c42323be24..f90a3cf0caa 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -299,7 +299,7 @@ impl ValidatorSet for ValidatorSafeContract { let (old_header, state_items) = decode_first_proof(&rlp)?; let old_hash = old_header.hash(); - let env_info = ::evm::env_info::EnvInfo { + let env_info = ::vm::EnvInfo { number: old_header.number(), author: *old_header.author(), difficulty: *old_header.difficulty(), diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 1fbd711c9eb..83eb6f53567 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -19,7 +19,7 @@ use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use util::*; use block::*; use builtin::Builtin; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use error::{BlockError, Error, TransactionError}; use header::{Header, BlockNumber}; use state::CleanupMode; @@ -29,7 +29,7 @@ use engines::{self, Engine}; use evm::Schedule; use ethjson; use rlp::{self, UntrustedRlp}; -use evm::env_info::LastHashes; +use vm::LastHashes; /// Parity tries to round block.gas_limit to multiple of this constant pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index f6508668f36..3154903ca0f 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -17,7 +17,7 @@ //! Transaction execution format module. use util::{Bytes, U256, Address, U512, trie}; -use evm; +use vm; use trace::{VMTrace, FlatTrace}; use log_entry::LogEntry; use state_diff::StateDiff; @@ -28,7 +28,7 @@ use std::fmt; #[derive(Debug, PartialEq, Clone)] pub struct Executed { /// True if the outer call/create resulted in an exceptional exit. - pub exception: Option, + pub exception: Option, /// Gas paid up front for execution of transaction. pub gas: U256, diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 9e25b667121..26e6037004c 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -16,13 +16,13 @@ //! Transaction Execution environment. use util::*; -use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; use engines::Engine; -use evm::CallType; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use error::ExecutionError; -use evm::{self, wasm, Factory, Ext, Finalize, CreateContractAddress, FinalizationResult, ReturnData, CleanDustMode}; +use evm::{CallType, Factory, Finalize, FinalizationResult}; +use vm::{self, Ext, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, ActionValue}; +use wasm; use externalities::*; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer}; use transaction::{Action, SignedTransaction}; @@ -74,8 +74,8 @@ pub struct TransactOptions { pub check_nonce: bool, } -pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) - -> Box where E: Engine + ?Sized +pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) + -> Box where E: Engine + ?Sized { if engine.supports_wasm() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) { Box::new( @@ -269,7 +269,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { output_policy: OutputPolicy, tracer: &mut T, vm_tracer: &mut V - ) -> evm::Result where T: Tracer, V: VMTracer { + ) -> vm::Result where T: Tracer, V: VMTracer { let depth_threshold = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get() / STACK_SIZE_PER_DEPTH); let static_call = params.call_type == CallType::StaticCall; @@ -299,7 +299,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { /// Calls contract function with given contract params. /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). /// Modifies the substate and the output. - /// Returns either gas_left or `evm::Error`. + /// Returns either gas_left or `vm::Error`. pub fn call( &mut self, params: ActionParams, @@ -307,14 +307,14 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { mut output: BytesRef, tracer: &mut T, vm_tracer: &mut V - ) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { + ) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); if (params.call_type == CallType::StaticCall || ((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) && self.static_flag)) && params.value.value() > 0.into() { - return Err(evm::Error::MutableCallInStaticContext); + return Err(vm::Error::MutableCallInStaticContext); } // backup used in case of running out of gas @@ -344,7 +344,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { if cost <= params.gas { if let Err(e) = builtin.execute(data, &mut output) { self.state.revert_to_checkpoint(); - let evm_err: evm::evm::Error = e.into(); + let evm_err: vm::Error = e.into(); tracer.trace_failed_call(trace_info, vec![], evm_err.clone().into()); Err(evm_err) } else { @@ -371,9 +371,9 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { // just drain the whole gas self.state.revert_to_checkpoint(); - tracer.trace_failed_call(trace_info, vec![], evm::Error::OutOfGas.into()); + tracer.trace_failed_call(trace_info, vec![], vm::Error::OutOfGas.into()); - Err(evm::Error::OutOfGas) + Err(vm::Error::OutOfGas) } } else { let trace_info = tracer.prepare_trace_call(¶ms); @@ -432,17 +432,17 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V, - ) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { + ) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { let scheme = self.engine.create_address_scheme(self.info.number); if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(¶ms.address)? { - return Err(evm::Error::OutOfGas); + return Err(vm::Error::OutOfGas); } if params.call_type == CallType::StaticCall || self.static_flag { let trace_info = tracer.prepare_trace_create(¶ms); - tracer.trace_failed_create(trace_info, vec![], evm::Error::MutableCallInStaticContext.into()); - return Err(evm::Error::MutableCallInStaticContext); + tracer.trace_failed_create(trace_info, vec![], vm::Error::MutableCallInStaticContext.into()); + return Err(vm::Error::MutableCallInStaticContext); } // backup used in case of running out of gas @@ -496,7 +496,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { &mut self, t: &SignedTransaction, mut substate: Substate, - result: evm::Result<(U256, ReturnData)>, + result: vm::Result<(U256, ReturnData)>, output: Bytes, trace: Vec, vm_trace: Option @@ -538,7 +538,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?; match result { - Err(evm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), + Err(vm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), Err(exception) => { Ok(Executed { exception: Some(exception), @@ -572,20 +572,20 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { } } - fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate) { + fn enact_result(&mut self, result: &vm::Result, substate: &mut Substate, un_substate: Substate) { match *result { - Err(evm::Error::OutOfGas) - | Err(evm::Error::BadJumpDestination {..}) - | Err(evm::Error::BadInstruction {.. }) - | Err(evm::Error::StackUnderflow {..}) - | Err(evm::Error::BuiltIn {..}) - | Err(evm::Error::Wasm {..}) - | Err(evm::Error::OutOfStack {..}) - | Err(evm::Error::MutableCallInStaticContext) + Err(vm::Error::OutOfGas) + | Err(vm::Error::BadJumpDestination {..}) + | Err(vm::Error::BadInstruction {.. }) + | Err(vm::Error::StackUnderflow {..}) + | Err(vm::Error::BuiltIn {..}) + | Err(vm::Error::Wasm {..}) + | Err(vm::Error::OutOfStack {..}) + | Err(vm::Error::MutableCallInStaticContext) | Ok(FinalizationResult { apply_state: false, .. }) => { self.state.revert_to_checkpoint(); }, - Ok(_) | Err(evm::Error::Internal(_)) => { + Ok(_) | Err(vm::Error::Internal(_)) => { self.state.discard_checkpoint(); substate.accrue(un_substate); } @@ -602,9 +602,8 @@ mod tests { use super::*; use util::{H256, U256, U512, Address, FromStr}; use util::bytes::BytesRef; - use evm::action_params::{ActionParams, ActionValue}; - use evm::env_info::EnvInfo; - use evm::{Factory, VMType, CreateContractAddress}; + use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; + use evm::{Factory, VMType}; use error::ExecutionError; use state::{Substate, CleanupMode}; use tests::helpers::*; @@ -613,8 +612,6 @@ mod tests { use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; use transaction::{Action, Transaction}; - use evm::CallType; - #[test] fn test_contract_address() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 39c8673a944..b581acf749f 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -16,13 +16,14 @@ //! Transaction Execution environment. use util::*; -use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; use engines::Engine; -use evm::env_info::EnvInfo; use executive::*; -use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; -use evm::CallType; +use vm::{ + self, ActionParams, ActionValue, EnvInfo, CallType, Schedule, + Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, + ReturnData +}; use transaction::UNSIGNED_SENDER; use trace::{Tracer, VMTracer}; @@ -109,31 +110,31 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Externalities<'a, T, V, B, E> impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized { - fn storage_at(&self, key: &H256) -> evm::Result { + fn storage_at(&self, key: &H256) -> vm::Result { self.state.storage_at(&self.origin_info.address, key).map_err(Into::into) } - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { + fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { if self.static_flag { - Err(evm::Error::MutableCallInStaticContext) + Err(vm::Error::MutableCallInStaticContext) } else { self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into) } } - fn exists(&self, address: &Address) -> evm::Result { + fn exists(&self, address: &Address) -> vm::Result { self.state.exists(address).map_err(Into::into) } - fn exists_and_not_null(&self, address: &Address) -> evm::Result { + fn exists_and_not_null(&self, address: &Address) -> vm::Result { self.state.exists_and_not_null(address).map_err(Into::into) } - fn origin_balance(&self) -> evm::Result { + fn origin_balance(&self) -> vm::Result { self.balance(&self.origin_info.address).map_err(Into::into) } - fn balance(&self, address: &Address) -> evm::Result { + fn balance(&self, address: &Address) -> vm::Result { self.state.balance(address).map_err(Into::into) } @@ -274,16 +275,16 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> } } - fn extcode(&self, address: &Address) -> evm::Result> { + fn extcode(&self, address: &Address) -> vm::Result> { Ok(self.state.code(address)?.unwrap_or_else(|| Arc::new(vec![]))) } - fn extcodesize(&self, address: &Address) -> evm::Result { + fn extcodesize(&self, address: &Address) -> vm::Result { Ok(self.state.code_size(address)?.unwrap_or(0)) } #[cfg_attr(feature="dev", allow(match_ref_pats))] - fn ret(mut self, gas: &U256, data: &ReturnData) -> evm::Result + fn ret(mut self, gas: &U256, data: &ReturnData) -> vm::Result where Self: Sized { let handle_copy = |to: &mut Option<&mut Bytes>| { to.as_mut().map(|b| **b = data.to_vec()); @@ -307,7 +308,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); if return_cost > *gas || data.len() > self.schedule.create_data_limit { return match self.schedule.exceptional_failed_code_deposit { - true => Err(evm::Error::OutOfGas), + true => Err(vm::Error::OutOfGas), false => Ok(*gas) } } @@ -320,11 +321,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> } } - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()> { + fn log(&mut self, topics: Vec, data: &[u8]) -> vm::Result<()> { use log_entry::LogEntry; if self.static_flag { - return Err(evm::Error::MutableCallInStaticContext); + return Err(vm::Error::MutableCallInStaticContext); } let address = self.origin_info.address.clone(); @@ -337,9 +338,9 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> Ok(()) } - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { + fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { if self.static_flag { - return Err(evm::Error::MutableCallInStaticContext); + return Err(vm::Error::MutableCallInStaticContext); } let address = self.origin_info.address.clone(); @@ -396,13 +397,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> mod tests { use util::*; use engines::Engine; - use evm::env_info::EnvInfo; - use evm::Ext; + use evm::{EnvInfo, Ext, CallType}; use state::{State, Substate}; use tests::helpers::*; use super::*; use trace::{NoopTracer, NoopVMTracer}; - use evm::CallType; fn get_test_origin() -> OriginInfo { OriginInfo { diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 0c5a6a90d92..a1ff66d58f7 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -15,11 +15,11 @@ // along with Parity. If not, see . use super::test_common::*; -use evm::action_params::ActionParams; +use vm::ActionParams; use state::{Backend as StateBackend, State, Substate}; use executive::*; use engines::Engine; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use evm; use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; use externalities::*; @@ -88,27 +88,27 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> TestExt<'a, T, V, B, E> impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E> where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized { - fn storage_at(&self, key: &H256) -> evm::Result { + fn storage_at(&self, key: &H256) -> vm::Result { self.ext.storage_at(key) } - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { + fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { self.ext.set_storage(key, value) } - fn exists(&self, address: &Address) -> evm::Result { + fn exists(&self, address: &Address) -> vm::Result { self.ext.exists(address) } - fn exists_and_not_null(&self, address: &Address) -> evm::Result { + fn exists_and_not_null(&self, address: &Address) -> vm::Result { self.ext.exists_and_not_null(address) } - fn balance(&self, address: &Address) -> evm::Result { + fn balance(&self, address: &Address) -> vm::Result { self.ext.balance(address) } - fn origin_balance(&self) -> evm::Result { + fn origin_balance(&self) -> vm::Result { self.ext.origin_balance() } @@ -146,23 +146,23 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E> MessageCallResult::Success(*gas, ReturnData::empty()) } - fn extcode(&self, address: &Address) -> evm::Result> { + fn extcode(&self, address: &Address) -> vm::Result> { self.ext.extcode(address) } - fn extcodesize(&self, address: &Address) -> evm::Result { + fn extcodesize(&self, address: &Address) -> vm::Result { self.ext.extcodesize(address) } - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()> { + fn log(&mut self, topics: Vec, data: &[u8]) -> vm::Result<()> { self.ext.log(topics, data) } - fn ret(self, gas: &U256, data: &ReturnData) -> Result { + fn ret(self, gas: &U256, data: &ReturnData) -> Result { self.ext.ret(gas, data) } - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { + fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { self.ext.suicide(refund_address) } diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index 74bbfb266ff..2fdf8875f62 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -22,7 +22,7 @@ use spec::Spec; use ethjson; use ethjson::state::test::ForkSpec; use transaction::SignedTransaction; -use evm::env_info::EnvInfo; +use vm::EnvInfo; lazy_static! { pub static ref FRONTIER: Spec = ethereum::new_frontier_test(); diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 89f9d2e577d..fe8696b569b 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -106,6 +106,8 @@ extern crate semver; extern crate stats; extern crate time; extern crate transient_hashmap; +extern crate vm; +extern crate wasm; #[macro_use] extern crate log; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 7d3900f2ccd..1f881035ccf 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -20,10 +20,9 @@ use rustc_hex::FromHex; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; -use evm::action_params::{ActionValue, ActionParams}; use builtin::Builtin; use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT}; -use evm::env_info::EnvInfo; +use vm::{EnvInfo, CallType, ActionValue, ActionParams}; use error::Error; use ethereum; use ethjson; @@ -36,7 +35,6 @@ use state_db::StateDB; use state::{Backend, State, Substate}; use state::backend::Basic as BasicBackend; use trace::{NoopTracer, NoopVMTracer}; -use evm::CallType; use util::*; /// Parameters common to all engines. @@ -89,14 +87,14 @@ pub struct CommonParams { impl CommonParams { /// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net. - pub fn schedule(&self, block_number: u64) -> ::evm::Schedule { - let mut schedule = ::evm::Schedule::new_post_eip150(usize::max_value(), true, true, true); + pub fn schedule(&self, block_number: u64) -> ::vm::Schedule { + let mut schedule = ::vm::Schedule::new_post_eip150(usize::max_value(), true, true, true); self.update_schedule(block_number, &mut schedule); schedule } /// Apply common spec config parameters to the schedule. - pub fn update_schedule(&self, block_number: u64, schedule: &mut ::evm::Schedule) { + pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) { schedule.have_create2 = block_number >= self.eip86_transition; schedule.have_revert = block_number >= self.eip140_transition; schedule.have_static_call = block_number >= self.eip214_transition; @@ -106,8 +104,8 @@ impl CommonParams { } if block_number >= self.dust_protection_transition { schedule.kill_dust = match self.remove_dust_contracts { - true => ::evm::CleanDustMode::WithCodeAndStorage, - false => ::evm::CleanDustMode::BasicOnly, + true => ::vm::CleanDustMode::WithCodeAndStorage, + false => ::vm::CleanDustMode::BasicOnly, }; } } diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 354da2cc318..593ec86a630 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -24,7 +24,7 @@ use std::collections::hash_map::Entry; use receipt::Receipt; use engines::Engine; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use error::Error; use executive::{Executive, TransactOptions}; use factory::Factories; @@ -982,7 +982,7 @@ mod tests { use ethkey::Secret; use util::{U256, H256, Address, Hashable}; use tests::helpers::*; - use evm::env_info::EnvInfo; + use vm::EnvInfo; use spec::*; use transaction::*; use ethcore_logger::init_log; diff --git a/ethcore/src/tests/evm.rs b/ethcore/src/tests/evm.rs index c97fd4ac080..c7208b995a0 100644 --- a/ethcore/src/tests/evm.rs +++ b/ethcore/src/tests/evm.rs @@ -1,9 +1,7 @@ //! Tests of EVM integration with transaction execution. -use evm::action_params::{ActionParams, ActionValue}; -use evm::env_info::EnvInfo; +use vm::{EnvInfo, ActionParams, ActionValue, CallType}; use evm::{Factory, VMType}; -use evm::call_type::CallType; use executive::Executive; use state::Substate; use tests::helpers::*; diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index cdfe1e0046c..860c7422389 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -17,7 +17,7 @@ //! Simple executive tracer. use util::{Bytes, Address, U256}; -use evm::action_params::ActionParams; +use vm::ActionParams; use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide}; use trace::{Tracer, VMTracer, FlatTrace, TraceError}; diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index 39af8a08aca..be830430ba3 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -39,7 +39,7 @@ pub use self::types::filter::{Filter, AddressesFilter}; use util::{Bytes, Address, U256, H256, DBTransaction}; use self::trace::{Call, Create}; -use evm::action_params::ActionParams; +use vm::ActionParams; use header::BlockNumber; /// This trait is used by executive to build traces. diff --git a/ethcore/src/trace/noop_tracer.rs b/ethcore/src/trace/noop_tracer.rs index 5fb8a7c55ca..2c0e1b83026 100644 --- a/ethcore/src/trace/noop_tracer.rs +++ b/ethcore/src/trace/noop_tracer.rs @@ -17,7 +17,7 @@ //! Nonoperative tracer. use util::{Bytes, Address, U256}; -use evm::action_params::ActionParams; +use vm::ActionParams; use trace::{Tracer, VMTracer, FlatTrace, TraceError}; use trace::trace::{Call, Create, VMTrace}; diff --git a/ethcore/src/trace/types/error.rs b/ethcore/src/trace/types/error.rs index 4242bfad434..5cedefd09f4 100644 --- a/ethcore/src/trace/types/error.rs +++ b/ethcore/src/trace/types/error.rs @@ -18,7 +18,7 @@ use std::fmt; use rlp::{Encodable, RlpStream, Decodable, DecoderError, UntrustedRlp}; -use evm::Error as EvmError; +use vm::Error as VmError; /// Trace evm errors. #[derive(Debug, PartialEq, Clone)] @@ -45,24 +45,24 @@ pub enum Error { Wasm, } -impl<'a> From<&'a EvmError> for Error { - fn from(e: &'a EvmError) -> Self { +impl<'a> From<&'a VmError> for Error { + fn from(e: &'a VmError) -> Self { match *e { - EvmError::OutOfGas => Error::OutOfGas, - EvmError::BadJumpDestination { .. } => Error::BadJumpDestination, - EvmError::BadInstruction { .. } => Error::BadInstruction, - EvmError::StackUnderflow { .. } => Error::StackUnderflow, - EvmError::OutOfStack { .. } => Error::OutOfStack, - EvmError::BuiltIn { .. } => Error::BuiltIn, - EvmError::Wasm { .. } => Error::Wasm, - EvmError::Internal(_) => Error::Internal, - EvmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, + VmError::OutOfGas => Error::OutOfGas, + VmError::BadJumpDestination { .. } => Error::BadJumpDestination, + VmError::BadInstruction { .. } => Error::BadInstruction, + VmError::StackUnderflow { .. } => Error::StackUnderflow, + VmError::OutOfStack { .. } => Error::OutOfStack, + VmError::BuiltIn { .. } => Error::BuiltIn, + VmError::Wasm { .. } => Error::Wasm, + VmError::Internal(_) => Error::Internal, + VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, } } } -impl From for Error { - fn from(e: EvmError) -> Self { +impl From for Error { + fn from(e: VmError) -> Self { Error::from(&e) } } diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index 24250935f05..17c498676a6 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -21,7 +21,7 @@ use util::sha3::Hashable; use util::bloom::Bloomable; use rlp::*; -use evm::action_params::ActionParams; +use vm::ActionParams; use basic_types::LogBloom; use evm::CallType; use super::error::Error; diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs index cd4bd48ae88..2bf66995129 100644 --- a/ethcore/vm/src/lib.rs +++ b/ethcore/vm/src/lib.rs @@ -31,7 +31,7 @@ mod error; pub use action_params::{ActionParams, ActionValue}; pub use call_type::CallType; -pub use env_info::EnvInfo; +pub use env_info::{EnvInfo, LastHashes}; pub use schedule::{Schedule, CleanDustMode}; pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress}; pub use return_data::{ReturnData, GasLeft}; diff --git a/ethcore/wasm/src/tests.rs b/ethcore/wasm/src/tests.rs index 8ae13daaed0..cdba25e0e31 100644 --- a/ethcore/wasm/src/tests.rs +++ b/ethcore/wasm/src/tests.rs @@ -28,7 +28,7 @@ macro_rules! load_sample { } } -fn test_finalize(res: Result) -> Result { +fn test_finalize(res: Result) -> Result { match res { Ok(GasLeft::Known(gas)) => Ok(gas), Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented. diff --git a/evmbin/benches/mod.rs b/evmbin/benches/mod.rs index d7d67a55118..f4deda88e6f 100644 --- a/evmbin/benches/mod.rs +++ b/evmbin/benches/mod.rs @@ -31,7 +31,7 @@ extern crate rustc_hex; use self::test::{Bencher, black_box}; use evm::run_vm; -use ethcore::evm::action_params::ActionParams; +use ethcore::vm::ActionParams; use ethcore_util::U256; use rustc_hex::FromHex; diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index 7e89c7c7f71..eda0aee668c 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -34,7 +34,7 @@ use docopt::Docopt; use rustc_hex::FromHex; use util::{U256, Bytes, Address}; use ethcore::spec; -use evm::action_params::ActionParams; +use vm::ActionParams; mod vm; mod display; diff --git a/evmbin/src/vm.rs b/evmbin/src/vm.rs index c4530bb9e6e..617ebc7b904 100644 --- a/evmbin/src/vm.rs +++ b/evmbin/src/vm.rs @@ -20,7 +20,7 @@ use std::time::{Instant, Duration}; use util::U256; use ethcore::{trace, spec}; use ethcore::client::{EvmTestClient, EvmTestError}; -use evm::action_params::ActionParams; +use vm::ActionParams; /// VM execution informant pub trait Informant: trace::VMTracer { diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 4b5e0f815b3..972315272db 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -327,7 +327,7 @@ struct ExecuteParams { from: Address, tx: EthTransaction, hdr: encoded::Header, - env_info: ::evm::env_info::EnvInfo, + env_info: ::vm::EnvInfo, engine: Arc<::ethcore::engines::Engine>, on_demand: Arc, sync: Arc, From 17dcc9fc4f64850e4d4dbe431568bdd6ad056ea9 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 31 Jul 2017 12:59:38 +0300 Subject: [PATCH 6/6] test fixes --- Cargo.lock | 3 ++- ethcore/light/Cargo.toml | 1 + ethcore/light/src/lib.rs | 1 + ethcore/src/json_tests/executive.rs | 11 ++++++----- rpc/Cargo.toml | 2 +- rpc/src/lib.rs | 2 +- rpc/src/v1/tests/mocked/traces.rs | 2 +- rpc/src/v1/types/trace.rs | 16 ++++++++-------- 8 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2515e2bd86b..b3602951a62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -635,6 +635,7 @@ dependencies = [ "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", ] [[package]] @@ -1935,7 +1936,6 @@ dependencies = [ "ethkey 0.2.0", "ethstore 0.1.0", "ethsync 1.8.0", - "evm 0.1.0", "fetch 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1964,6 +1964,7 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", ] [[package]] diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 09f2e0e1aed..b652050d2d3 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -19,6 +19,7 @@ ethcore-io = { path = "../../util/io" } ethcore-ipc = { path = "../../ipc/rpc", optional = true } ethcore-devtools = { path = "../../devtools" } evm = { path = "../evm" } +vm = { path = "../vm" } rlp = { path = "../../util/rlp" } time = "0.1" smallvec = "0.4" diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index 49928bd98ac..b172134cf1a 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -80,6 +80,7 @@ extern crate serde; extern crate smallvec; extern crate stats; extern crate time; +extern crate vm; #[cfg(feature = "ipc")] extern crate ethcore_ipc as ipc; diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index a1ff66d58f7..7ec84fbd6ba 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -15,15 +15,16 @@ // along with Parity. If not, see . use super::test_common::*; -use vm::ActionParams; use state::{Backend as StateBackend, State, Substate}; use executive::*; use engines::Engine; -use vm::EnvInfo; -use evm; -use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; +use evm::{VMType, Finalize}; +use vm::{ + self, ActionParams, CallType, Schedule, Ext, + ContractCreateResult, EnvInfo, MessageCallResult, + CreateContractAddress, ReturnData, +}; use externalities::*; -use evm::CallType; use tests::helpers::*; use ethjson; use trace::{Tracer, NoopTracer}; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index e1212100c4e..2619c754fc8 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -46,7 +46,7 @@ ethjson = { path = "../json" } ethcore-devtools = { path = "../devtools" } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../logger" } -evm = { path = "../ethcore/evm" } +vm = { path = "../ethcore/vm" } parity-updater = { path = "../updater" } parity-reactor = { path = "../util/reactor" } rlp = { path = "../util/rlp" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 0e96ac509b2..fec19f78afa 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -52,7 +52,7 @@ extern crate ethkey; extern crate ethstore; extern crate ethsync; extern crate ethcore_logger; -extern crate evm; +extern crate vm; extern crate fetch; extern crate parity_reactor; extern crate parity_updater as updater; diff --git a/rpc/src/v1/tests/mocked/traces.rs b/rpc/src/v1/tests/mocked/traces.rs index b1b297eb16f..f64142f8c0a 100644 --- a/rpc/src/v1/tests/mocked/traces.rs +++ b/rpc/src/v1/tests/mocked/traces.rs @@ -21,7 +21,7 @@ use ethcore::trace::trace::{Action, Res, Call}; use ethcore::trace::LocalizedTrace; use ethcore::client::TestBlockChainClient; -use evm::CallType; +use vm::CallType; use jsonrpc_core::IoHandler; use v1::tests::helpers::{TestMinerService}; diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index b01d04c3f34..f9cf0bb4033 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -22,7 +22,7 @@ use ethcore::trace as et; use ethcore::state_diff; use ethcore::account_diff; use ethcore::client::Executed; -use evm; +use vm; use v1::types::{Bytes, H160, H256, U256}; #[derive(Debug, Serialize)] @@ -256,14 +256,14 @@ pub enum CallType { StaticCall, } -impl From for CallType { - fn from(c: evm::CallType) -> Self { +impl From for CallType { + fn from(c: vm::CallType) -> Self { match c { - evm::CallType::None => CallType::None, - evm::CallType::Call => CallType::Call, - evm::CallType::CallCode => CallType::CallCode, - evm::CallType::DelegateCall => CallType::DelegateCall, - evm::CallType::StaticCall => CallType::StaticCall, + vm::CallType::None => CallType::None, + vm::CallType::Call => CallType::Call, + vm::CallType::CallCode => CallType::CallCode, + vm::CallType::DelegateCall => CallType::DelegateCall, + vm::CallType::StaticCall => CallType::StaticCall, } } }