Decouple virtual machines (#6184)

* work in progress for splitting vms

* evm working

* Evm -> Vm

* wasm converted

* ethcore working

* test fixes
This commit is contained in:
Nikolay Volf 2017-08-01 13:37:57 +03:00 committed by GitHub
parent c4025622de
commit b7006034b1
65 changed files with 534 additions and 400 deletions

34
Cargo.lock generated
View File

@ -1,6 +1,14 @@
[root] [root]
name = "using_queue" name = "wasm"
version = "0.1.0" version = "0.1.0"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.8.0",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"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]] [[package]]
name = "advapi32-sys" name = "advapi32-sys"
@ -504,6 +512,8 @@ dependencies = [
"stats 0.1.0", "stats 0.1.0",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
"wasm 0.1.0",
] ]
[[package]] [[package]]
@ -625,6 +635,7 @@ dependencies = [
"smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0", "stats 0.1.0",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
] ]
[[package]] [[package]]
@ -888,6 +899,7 @@ dependencies = [
"parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0", "rlp 0.2.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
] ]
@ -1933,7 +1945,6 @@ dependencies = [
"ethkey 0.2.0", "ethkey 0.2.0",
"ethstore 0.1.0", "ethstore 0.1.0",
"ethsync 1.8.0", "ethsync 1.8.0",
"evm 0.1.0",
"fetch 0.1.0", "fetch 0.1.0",
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1962,6 +1973,7 @@ dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
] ]
[[package]] [[package]]
@ -3044,6 +3056,10 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "using_queue"
version = "0.1.0"
[[package]] [[package]]
name = "utf8-ranges" name = "utf8-ranges"
version = "1.0.0" version = "1.0.0"
@ -3072,6 +3088,20 @@ dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "void" name = "void"
version = "1.0.2" version = "1.0.2"

View File

@ -53,6 +53,8 @@ semver = "0.6"
stats = { path = "../util/stats" } stats = { path = "../util/stats" }
time = "0.1" time = "0.1"
transient-hashmap = "0.4" transient-hashmap = "0.4"
vm = { path = "vm" }
wasm = { path = "wasm" }
[dev-dependencies] [dev-dependencies]
native-contracts = { path = "native_contracts", features = ["test_contracts"] } native-contracts = { path = "native_contracts", features = ["test_contracts"] }

View File

@ -13,6 +13,7 @@ ethjson = { path = "../../json" }
lazy_static = "0.2" lazy_static = "0.2"
log = "0.3" log = "0.3"
rlp = { path = "../../util/rlp" } rlp = { path = "../../util/rlp" }
vm = { path = "../vm" }
parity-wasm = "0.12" parity-wasm = "0.12"
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }

View File

@ -25,7 +25,7 @@ extern crate test;
use self::test::{Bencher, black_box}; use self::test::{Bencher, black_box};
use util::*; use util::*;
use evm::action_params::ActionParams; use vm::ActionParams;
use evm::{self, Factory, VMType}; use evm::{self, Factory, VMType};
use evm::tests::FakeExt; use evm::tests::FakeExt;

View File

@ -17,142 +17,8 @@
//! Evm interface. //! Evm interface.
use std::{ops, cmp, fmt}; use std::{ops, cmp, fmt};
use util::{U128, U256, U512, trie}; use util::{U128, U256, U512};
use action_params::ActionParams; use vm::{Ext, Result, ReturnData, GasLeft, Error};
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<Box<trie::TrieError>> for Error {
fn from(err: Box<trie::TrieError>) -> Self {
Error::Internal(format!("Internal error: {}", err))
}
}
impl From<wasm::RuntimeError> 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<T> = ::std::result::Result<T, Error>;
/// Return data buffer. Holds memory from a previous call and a slice into that memory.
#[derive(Debug)]
pub struct ReturnData {
mem: Vec<u8>,
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<u8>, offset: usize, size: usize) -> Self {
ReturnData {
mem: mem,
offset: offset,
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
},
}
/// Finalization result. Gas Left: either it is a known value, or it needs to be computed by processing /// Finalization result. Gas Left: either it is a known value, or it needs to be computed by processing
/// a return instruction. /// a return instruction.
@ -281,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<GasLeft>;
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use util::U256; use util::U256;

View File

@ -17,7 +17,7 @@
//! Evm factory. //! Evm factory.
//! //!
use std::sync::Arc; use std::sync::Arc;
use evm::Evm; use vm::Vm;
use util::U256; use util::U256;
use super::interpreter::SharedCache; use super::interpreter::SharedCache;
use super::vmtype::VMType; use super::vmtype::VMType;
@ -33,7 +33,7 @@ impl Factory {
/// Create fresh instance of VM /// Create fresh instance of VM
/// Might choose implementation depending on supplied gas. /// Might choose implementation depending on supplied gas.
#[cfg(feature = "jit")] #[cfg(feature = "jit")]
pub fn create(&self, gas: U256) -> Box<Evm> { pub fn create(&self, gas: U256) -> Box<Vm> {
match self.evm { match self.evm {
VMType::Jit => { VMType::Jit => {
Box::new(super::jit::JitEvm::default()) Box::new(super::jit::JitEvm::default())
@ -49,7 +49,7 @@ impl Factory {
/// Create fresh instance of VM /// Create fresh instance of VM
/// Might choose implementation depending on supplied gas. /// Might choose implementation depending on supplied gas.
#[cfg(not(feature = "jit"))] #[cfg(not(feature = "jit"))]
pub fn create(&self, gas: U256) -> Box<Evm> { pub fn create(&self, gas: U256) -> Box<Vm> {
match self.evm { match self.evm {
VMType::Interpreter => if Self::can_fit_in_usize(gas) { VMType::Interpreter => if Self::can_fit_in_usize(gas) {
Box::new(super::interpreter::Interpreter::<usize>::new(self.evm_cache.clone())) Box::new(super::interpreter::Interpreter::<usize>::new(self.evm_cache.clone()))

View File

@ -17,15 +17,15 @@
use util::*; use util::*;
use super::u256_to_address; use super::u256_to_address;
use {evm, ext}; use {evm, vm};
use instructions::{self, Instruction, InstructionInfo}; use instructions::{self, Instruction, InstructionInfo};
use interpreter::stack::Stack; use interpreter::stack::Stack;
use schedule::Schedule; use vm::Schedule;
macro_rules! overflowing { macro_rules! overflowing {
($x: expr) => {{ ($x: expr) => {{
let (v, overflow) = $x; let (v, overflow) = $x;
if overflow { return Err(evm::Error::OutOfGas); } if overflow { return Err(vm::Error::OutOfGas); }
v v
}} }}
} }
@ -59,16 +59,16 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
} }
} }
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 { match &self.current_gas < gas_cost {
true => Err(evm::Error::OutOfGas), true => Err(vm::Error::OutOfGas),
false => Ok(()) false => Ok(())
} }
} }
/// How much gas is provided to a CALL/CREATE, given that we need to deduct `needed` for this operation /// How much gas is provided to a CALL/CREATE, given that we need to deduct `needed` for this operation
/// and that we `requested` some. /// and that we `requested` some.
pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option<U256>) -> evm::Result<Gas> { pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option<U256>) -> vm::Result<Gas> {
// Try converting requested gas to `Gas` (`U256/u64`) // Try converting requested gas to `Gas` (`U256/u64`)
// but in EIP150 even if we request more we should never fail from OOG // but in EIP150 even if we request more we should never fail from OOG
let requested = requested.map(Gas::from_u256); let requested = requested.map(Gas::from_u256);
@ -107,12 +107,12 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
/// it will be the amount of gas that the current context provides to the child context. /// it will be the amount of gas that the current context provides to the child context.
pub fn requirements( pub fn requirements(
&mut self, &mut self,
ext: &ext::Ext, ext: &vm::Ext,
instruction: Instruction, instruction: Instruction,
info: &InstructionInfo, info: &InstructionInfo,
stack: &Stack<U256>, stack: &Stack<U256>,
current_mem_size: usize, current_mem_size: usize,
) -> evm::Result<InstructionRequirements<Gas>> { ) -> vm::Result<InstructionRequirements<Gas>> {
let schedule = ext.schedule(); let schedule = ext.schedule();
let tier = instructions::get_tier_idx(info.tier); let tier = instructions::get_tier_idx(info.tier);
let default_gas = Gas::from(schedule.tier_step_gas[tier]); let default_gas = Gas::from(schedule.tier_step_gas[tier]);
@ -291,7 +291,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
}) })
} }
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 gas_for_mem = |mem_size: Gas| {
let s = mem_size >> 5; let s = mem_size >> 5;
// s * memory_gas + s * s / quad_coeff_div // s * memory_gas + s * s / quad_coeff_div
@ -319,12 +319,12 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
#[inline] #[inline]
fn mem_needed_const<Gas: evm::CostType>(mem: &U256, add: usize) -> evm::Result<Gas> { fn mem_needed_const<Gas: evm::CostType>(mem: &U256, add: usize) -> vm::Result<Gas> {
Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add)))) Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add))))
} }
#[inline] #[inline]
fn mem_needed<Gas: evm::CostType>(offset: &U256, size: &U256) -> evm::Result<Gas> { fn mem_needed<Gas: evm::CostType>(offset: &U256, size: &U256) -> vm::Result<Gas> {
if size.is_zero() { if size.is_zero() {
return Ok(Gas::from(0)); return Ok(Gas::from(0));
} }

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::U256; use util::U256;
use {ReturnData}; use vm::ReturnData;
const MAX_RETURN_WASTE_BYTES: usize = 16384; const MAX_RETURN_WASTE_BYTES: usize = 16384;

View File

@ -23,17 +23,21 @@ mod stack;
mod memory; mod memory;
mod shared_cache; mod shared_cache;
use std::marker::PhantomData;
use vm::{
self, ActionParams, ActionValue, CallType, MessageCallResult,
ContractCreateResult, CreateContractAddress, ReturnData, GasLeft
};
use evm::CostType;
use instructions::{self, Instruction, InstructionInfo};
use self::gasometer::Gasometer; use self::gasometer::Gasometer;
use self::stack::{Stack, VecStack}; use self::stack::{Stack, VecStack};
use self::memory::Memory; use self::memory::Memory;
pub use self::shared_cache::SharedCache; 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 bit_set::BitSet;
use util::*; use util::*;
@ -107,8 +111,8 @@ pub struct Interpreter<Cost: CostType> {
_type: PhantomData<Cost>, _type: PhantomData<Cost>,
} }
impl<Cost: CostType> evm::Evm for Interpreter<Cost> { impl<Cost: CostType> vm::Vm for Interpreter<Cost> {
fn exec(&mut self, params: ActionParams, ext: &mut ext::Ext) -> evm::Result<GasLeft> { fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
self.mem.clear(); self.mem.clear();
let mut informant = informant::EvmInformant::new(ext.depth()); let mut informant = informant::EvmInformant::new(ext.depth());
@ -205,7 +209,7 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
} }
fn verify_instruction(&self, ext: &ext::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack<U256>) -> evm::Result<()> { fn verify_instruction(&self, ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack<U256>) -> vm::Result<()> {
let schedule = ext.schedule(); let schedule = ext.schedule();
if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) || if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) ||
@ -214,25 +218,25 @@ impl<Cost: CostType> Interpreter<Cost> {
((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) || ((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) ||
(instruction == instructions::REVERT && !schedule.have_revert) { (instruction == instructions::REVERT && !schedule.have_revert) {
return Err(evm::Error::BadInstruction { return Err(vm::Error::BadInstruction {
instruction: instruction instruction: instruction
}); });
} }
if info.tier == instructions::GasPriceTier::Invalid { if info.tier == instructions::GasPriceTier::Invalid {
return Err(evm::Error::BadInstruction { return Err(vm::Error::BadInstruction {
instruction: instruction instruction: instruction
}); });
} }
if !stack.has(info.args) { if !stack.has(info.args) {
Err(evm::Error::StackUnderflow { Err(vm::Error::StackUnderflow {
instruction: info.name, instruction: info.name,
wanted: info.args, wanted: info.args,
on_stack: stack.size() on_stack: stack.size()
}) })
} else if stack.size() - info.args + info.ret > schedule.stack_limit { } else if stack.size() - info.args + info.ret > schedule.stack_limit {
Err(evm::Error::OutOfStack { Err(vm::Error::OutOfStack {
instruction: info.name, instruction: info.name,
wanted: info.ret - info.args, wanted: info.ret - info.args,
limit: schedule.stack_limit limit: schedule.stack_limit
@ -272,12 +276,12 @@ impl<Cost: CostType> Interpreter<Cost> {
&mut self, &mut self,
gas: Cost, gas: Cost,
params: &ActionParams, params: &ActionParams,
ext: &mut ext::Ext, ext: &mut vm::Ext,
instruction: Instruction, instruction: Instruction,
code: &mut CodeReader, code: &mut CodeReader,
stack: &mut Stack<U256>, stack: &mut Stack<U256>,
provided: Option<Cost> provided: Option<Cost>
) -> evm::Result<InstructionResult<Cost>> { ) -> vm::Result<InstructionResult<Cost>> {
match instruction { match instruction {
instructions::JUMP => { instructions::JUMP => {
let jump = stack.pop_back(); let jump = stack.pop_back();
@ -593,13 +597,13 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
} }
fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> evm::Result<usize> { fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> vm::Result<usize> {
let jump = jump_u.low_u64() as usize; let jump = jump_u.low_u64() as usize;
if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u { if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u {
Ok(jump) Ok(jump)
} else { } else {
Err(evm::Error::BadJumpDestination { Err(vm::Error::BadJumpDestination {
destination: jump destination: jump
}) })
} }
@ -617,7 +621,7 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
} }
fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack<U256>) -> evm::Result<()> { fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack<U256>) -> vm::Result<()> {
match instruction { match instruction {
instructions::DUP1...instructions::DUP16 => { instructions::DUP1...instructions::DUP16 => {
let position = instructions::get_dup_position(instruction); let position = instructions::get_dup_position(instruction);
@ -822,7 +826,7 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
}, },
_ => { _ => {
return Err(evm::Error::BadInstruction { return Err(vm::Error::BadInstruction {
instruction: instruction instruction: instruction
}); });
} }

View File

@ -19,6 +19,7 @@ use util::*;
use evmjit; use evmjit;
use evm::{self, GasLeft}; use evm::{self, GasLeft};
use evm::CallType; use evm::CallType;
use vm::{self, Vm};
/// Should be used to convert jit types to ethcore /// Should be used to convert jit types to ethcore
trait FromJit<T>: Sized { trait FromJit<T>: Sized {
@ -318,7 +319,7 @@ pub struct JitEvm {
context: Option<evmjit::ContextHandle>, context: Option<evmjit::ContextHandle>,
} }
impl evm::Evm for JitEvm { impl vm::Vm for JitEvm {
fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result<GasLeft> { fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result<GasLeft> {
// Dirty hack. This is unsafe, but we interact with ffi, so it's justified. // 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())) }; let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext, params.address.clone())) };
@ -370,8 +371,8 @@ impl evm::Evm for JitEvm {
ext.suicide(&Address::from_jit(&context.suicide_refund_address())); ext.suicide(&Address::from_jit(&context.suicide_refund_address()));
Ok(GasLeft::Known(U256::from(context.gas_left()))) Ok(GasLeft::Known(U256::from(context.gas_left())))
}, },
evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas), evmjit::ReturnCode::OutOfGas => Err(vm::Error::OutOfGas),
_err => Err(evm::Error::Internal) _err => Err(vm::Error::Internal)
} }
} }
} }

View File

@ -24,11 +24,11 @@ extern crate ethjson;
extern crate rlp; extern crate rlp;
extern crate parity_wasm; extern crate parity_wasm;
extern crate wasm_utils; extern crate wasm_utils;
extern crate vm;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[macro_use]
extern crate log; extern crate log;
#[cfg(feature = "jit")] #[cfg(feature = "jit")]
@ -37,14 +37,8 @@ extern crate evmjit;
#[cfg(test)] #[cfg(test)]
extern crate rustc_hex; extern crate rustc_hex;
pub mod action_params;
pub mod call_type;
pub mod env_info;
pub mod ext;
pub mod evm; pub mod evm;
pub mod interpreter; pub mod interpreter;
pub mod schedule;
pub mod wasm;
#[macro_use] #[macro_use]
pub mod factory; pub mod factory;
@ -59,12 +53,12 @@ mod tests;
#[cfg(all(feature="benches", test))] #[cfg(all(feature="benches", test))]
mod benches; mod benches;
pub use self::action_params::ActionParams; pub use vm::{
pub use self::call_type::CallType; Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext,
pub use self::env_info::EnvInfo; ContractCreateResult, MessageCallResult, CreateContractAddress,
pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData}; GasLeft, ReturnData
pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; };
pub use self::evm::{Finalize, FinalizationResult, CostType};
pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes};
pub use self::vmtype::VMType; pub use self::vmtype::VMType;
pub use self::factory::Factory; pub use self::factory::Factory;
pub use self::schedule::{Schedule, CleanDustMode};

View File

@ -17,12 +17,12 @@
use std::fmt::Debug; use std::fmt::Debug;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::*; use util::*;
use action_params::{ActionParams, ActionValue}; use evm::{self, GasLeft};
use env_info::EnvInfo; use vm::{
use call_type::CallType; self, CallType, Schedule, EnvInfo, ActionParams, ActionValue,
use schedule::Schedule; ReturnData, Ext, ContractCreateResult, MessageCallResult,
use evm::{self, GasLeft, ReturnData}; CreateContractAddress,
use ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; };
use factory::Factory; use factory::Factory;
use vmtype::VMType; use vmtype::VMType;
@ -66,7 +66,7 @@ pub struct FakeExt {
} }
// similar to the normal `finalize` function, but ignoring NeedsReturn. // similar to the normal `finalize` function, but ignoring NeedsReturn.
fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> { fn test_finalize(res: Result<GasLeft, vm::Error>) -> Result<U256, vm::Error> {
match res { match res {
Ok(GasLeft::Known(gas)) => Ok(gas), Ok(GasLeft::Known(gas)) => Ok(gas),
Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented. 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 { impl Ext for FakeExt {
fn storage_at(&self, key: &H256) -> evm::Result<H256> { fn storage_at(&self, key: &H256) -> vm::Result<H256> {
Ok(self.store.get(key).unwrap_or(&H256::new()).clone()) 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); self.store.insert(key, value);
Ok(()) Ok(())
} }
fn exists(&self, address: &Address) -> evm::Result<bool> { fn exists(&self, address: &Address) -> vm::Result<bool> {
Ok(self.balances.contains_key(address)) Ok(self.balances.contains_key(address))
} }
fn exists_and_not_null(&self, address: &Address) -> evm::Result<bool> { fn exists_and_not_null(&self, address: &Address) -> vm::Result<bool> {
Ok(self.balances.get(address).map_or(false, |b| !b.is_zero())) Ok(self.balances.get(address).map_or(false, |b| !b.is_zero()))
} }
fn origin_balance(&self) -> evm::Result<U256> { fn origin_balance(&self) -> vm::Result<U256> {
unimplemented!() unimplemented!()
} }
fn balance(&self, address: &Address) -> evm::Result<U256> { fn balance(&self, address: &Address) -> vm::Result<U256> {
Ok(self.balances[address]) Ok(self.balances[address])
} }
@ -152,15 +146,15 @@ impl Ext for FakeExt {
MessageCallResult::Success(*gas, ReturnData::empty()) MessageCallResult::Success(*gas, ReturnData::empty())
} }
fn extcode(&self, address: &Address) -> evm::Result<Arc<Bytes>> { fn extcode(&self, address: &Address) -> vm::Result<Arc<Bytes>> {
Ok(self.codes.get(address).unwrap_or(&Arc::new(Bytes::new())).clone()) Ok(self.codes.get(address).unwrap_or(&Arc::new(Bytes::new())).clone())
} }
fn extcodesize(&self, address: &Address) -> evm::Result<usize> { fn extcodesize(&self, address: &Address) -> vm::Result<usize> {
Ok(self.codes.get(address).map_or(0, |c| c.len())) Ok(self.codes.get(address).map_or(0, |c| c.len()))
} }
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> evm::Result<()> { fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> {
self.logs.push(FakeLogEntry { self.logs.push(FakeLogEntry {
topics: topics, topics: topics,
data: data.to_vec() data: data.to_vec()
@ -168,11 +162,11 @@ impl Ext for FakeExt {
Ok(()) Ok(())
} }
fn ret(self, _gas: &U256, _data: &ReturnData) -> evm::Result<U256> { fn ret(self, _gas: &U256, _data: &ReturnData) -> vm::Result<U256> {
unimplemented!(); 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()); self.suicides.insert(refund_address.clone());
Ok(()) Ok(())
} }
@ -211,7 +205,7 @@ fn test_stack_underflow() {
}; };
match err { match err {
evm::Error::StackUnderflow {wanted, on_stack, ..} => { vm::Error::StackUnderflow {wanted, on_stack, ..} => {
assert_eq!(wanted, 2); assert_eq!(wanted, 2);
assert_eq!(on_stack, 0); assert_eq!(on_stack, 0);
} }
@ -849,7 +843,7 @@ fn test_badinstruction_int() {
}; };
match err { match err {
evm::Error::BadInstruction { instruction: 0xaf } => (), vm::Error::BadInstruction { instruction: 0xaf } => (),
_ => assert!(false, "Expected bad instruction") _ => assert!(false, "Expected bad instruction")
} }
} }

View File

@ -19,6 +19,7 @@ ethcore-io = { path = "../../util/io" }
ethcore-ipc = { path = "../../ipc/rpc", optional = true } ethcore-ipc = { path = "../../ipc/rpc", optional = true }
ethcore-devtools = { path = "../../devtools" } ethcore-devtools = { path = "../../devtools" }
evm = { path = "../evm" } evm = { path = "../evm" }
vm = { path = "../vm" }
rlp = { path = "../../util/rlp" } rlp = { path = "../../util/rlp" }
time = "0.1" time = "0.1"
smallvec = "0.4" smallvec = "0.4"

View File

@ -80,6 +80,7 @@ extern crate serde;
extern crate smallvec; extern crate smallvec;
extern crate stats; extern crate stats;
extern crate time; extern crate time;
extern crate vm;
#[cfg(feature = "ipc")] #[cfg(feature = "ipc")]
extern crate ethcore_ipc as ipc; extern crate ethcore_ipc as ipc;

View File

@ -24,7 +24,7 @@ use ethcore::engines::Engine;
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use ethcore::state::{self, ProvedExecution}; use ethcore::state::{self, ProvedExecution};
use ethcore::transaction::SignedTransaction; use ethcore::transaction::SignedTransaction;
use evm::env_info::EnvInfo; use vm::EnvInfo;
use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field};

View File

@ -25,7 +25,7 @@ use util::{Bytes, Address, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RL
use util::error::{Mismatch, OutOfBounds}; use util::error::{Mismatch, OutOfBounds};
use basic_types::{LogBloom, Seal}; use basic_types::{LogBloom, Seal};
use evm::env_info::{EnvInfo, LastHashes}; use vm::{EnvInfo, LastHashes};
use engines::Engine; use engines::Engine;
use error::{Error, BlockError, TransactionError}; use error::{Error, BlockError, TransactionError};
use factory::Factories; use factory::Factories;
@ -667,7 +667,7 @@ mod tests {
use tests::helpers::*; use tests::helpers::*;
use super::*; use super::*;
use engines::Engine; use engines::Engine;
use evm::env_info::LastHashes; use vm::LastHashes;
use error::Error; use error::Error;
use header::Header; use header::Header;
use factory::Factories; use factory::Factories;

View File

@ -36,9 +36,9 @@ impl From<&'static str> for Error {
} }
} }
impl Into<::evm::Error> for Error { impl Into<::vm::Error> for Error {
fn into(self) -> ::evm::Error { fn into(self) -> ::vm::Error {
::evm::Error::BuiltIn(self.0) ::vm::Error::BuiltIn(self.0)
} }
} }

View File

@ -42,9 +42,8 @@ use client::{
}; };
use encoded; use encoded;
use engines::{Engine, EpochTransition}; 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 error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError};
use vm::{EnvInfo, LastHashes};
use evm::{Factory as EvmFactory, Schedule}; use evm::{Factory as EvmFactory, Schedule};
use executive::{Executive, Executed, TransactOptions, contract_address}; use executive::{Executive, Executed, TransactOptions, contract_address};
use factory::Factories; use factory::Factories;

View File

@ -23,7 +23,7 @@ use util::kvdb::{self, KeyValueDB};
use {state, state_db, client, executive, trace, db, spec}; use {state, state_db, client, executive, trace, db, spec};
use factory::Factories; use factory::Factories;
use evm::{self, VMType}; use evm::{self, VMType};
use evm::action_params::ActionParams; use vm::{self, ActionParams};
/// EVM test Error. /// EVM test Error.
#[derive(Debug)] #[derive(Debug)]
@ -31,7 +31,7 @@ pub enum EvmTestError {
/// Trie integrity error. /// Trie integrity error.
Trie(util::TrieError), Trie(util::TrieError),
/// EVM error. /// EVM error.
Evm(evm::Error), Evm(vm::Error),
/// Initialization error. /// Initialization error.
Initialization(::error::Error), Initialization(::error::Error),
/// Low-level database error. /// Low-level database error.

View File

@ -40,7 +40,7 @@ pub use types::pruning_info::PruningInfo;
pub use types::call_analytics::CallAnalytics; pub use types::call_analytics::CallAnalytics;
pub use executive::{Executed, Executive, TransactOptions}; 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 error::{BlockImportError, TransactionImportError, TransactionImportResult};
pub use verification::VerifierType; pub use verification::VerifierType;

View File

@ -36,7 +36,8 @@ use log_entry::LocalizedLogEntry;
use receipt::{Receipt, LocalizedReceipt}; use receipt::{Receipt, LocalizedReceipt};
use blockchain::extras::BlockReceipts; use blockchain::extras::BlockReceipts;
use error::{ImportResult, Error as EthcoreError}; 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 miner::{Miner, MinerService, TransactionImportResult};
use spec::Spec; use spec::Spec;
use types::basic_account::BasicAccount; use types::basic_account::BasicAccount;

View File

@ -19,7 +19,7 @@ use std::collections::BTreeMap;
use block::{OpenBlock, SealedBlock, ClosedBlock}; use block::{OpenBlock, SealedBlock, ClosedBlock};
use blockchain::TreeRoute; use blockchain::TreeRoute;
use encoded; use encoded;
use evm::env_info::LastHashes; use vm::LastHashes;
use error::{ImportResult, CallError, Error as EthcoreError}; use error::{ImportResult, CallError, Error as EthcoreError};
use error::{TransactionImportResult, BlockImportError}; use error::{TransactionImportResult, BlockImportError};
use evm::{Factory as EvmFactory, Schedule}; use evm::{Factory as EvmFactory, Schedule};

View File

@ -514,7 +514,7 @@ impl Engine for AuthorityRound {
fn on_new_block( fn on_new_block(
&self, &self,
block: &mut ExecutedBlock, block: &mut ExecutedBlock,
last_hashes: Arc<::evm::env_info::LastHashes>, last_hashes: Arc<::vm::LastHashes>,
epoch_begin: bool, epoch_begin: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
let parent_hash = block.fields().header.parent_hash().clone(); let parent_hash = block.fields().header.parent_hash().clone();

View File

@ -43,15 +43,13 @@ use account_provider::AccountProvider;
use block::ExecutedBlock; use block::ExecutedBlock;
use builtin::Builtin; use builtin::Builtin;
use client::Client; use client::Client;
use evm::env_info::{EnvInfo, LastHashes}; use vm::{EnvInfo, LastHashes, Schedule, CreateContractAddress};
use error::Error; use error::Error;
use evm::Schedule;
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};
use receipt::Receipt; use receipt::Receipt;
use snapshot::SnapshotComponents; use snapshot::SnapshotComponents;
use spec::CommonParams; use spec::CommonParams;
use transaction::{UnverifiedTransaction, SignedTransaction}; use transaction::{UnverifiedTransaction, SignedTransaction};
use evm::CreateContractAddress;
use ethkey::Signature; use ethkey::Signature;
use util::*; use util::*;
@ -394,12 +392,10 @@ pub trait Engine : Sync + Send {
/// Common engine utilities /// Common engine utilities
pub mod common { pub mod common {
use block::ExecutedBlock; use block::ExecutedBlock;
use evm::env_info::{EnvInfo, LastHashes};
use error::Error; use error::Error;
use transaction::SYSTEM_ADDRESS; use transaction::SYSTEM_ADDRESS;
use executive::Executive; use executive::Executive;
use evm::CallType; use vm::{CallType, ActionParams, ActionValue, EnvInfo, LastHashes};
use evm::action_params::{ActionParams, ActionValue};
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
use state::Substate; use state::Substate;

View File

@ -299,7 +299,7 @@ impl ValidatorSet for ValidatorSafeContract {
let (old_header, state_items) = decode_first_proof(&rlp)?; let (old_header, state_items) = decode_first_proof(&rlp)?;
let old_hash = old_header.hash(); let old_hash = old_header.hash();
let env_info = ::evm::env_info::EnvInfo { let env_info = ::vm::EnvInfo {
number: old_header.number(), number: old_header.number(),
author: *old_header.author(), author: *old_header.author(),
difficulty: *old_header.difficulty(), difficulty: *old_header.difficulty(),

View File

@ -19,7 +19,7 @@ use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager};
use util::*; use util::*;
use block::*; use block::*;
use builtin::Builtin; use builtin::Builtin;
use evm::env_info::EnvInfo; use vm::EnvInfo;
use error::{BlockError, Error, TransactionError}; use error::{BlockError, Error, TransactionError};
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};
use state::CleanupMode; use state::CleanupMode;
@ -29,7 +29,7 @@ use engines::{self, Engine};
use evm::Schedule; use evm::Schedule;
use ethjson; use ethjson;
use rlp::{self, UntrustedRlp}; use rlp::{self, UntrustedRlp};
use evm::env_info::LastHashes; use vm::LastHashes;
/// Parity tries to round block.gas_limit to multiple of this constant /// Parity tries to round block.gas_limit to multiple of this constant
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);

View File

@ -17,7 +17,7 @@
//! Transaction execution format module. //! Transaction execution format module.
use util::{Bytes, U256, Address, U512, trie}; use util::{Bytes, U256, Address, U512, trie};
use evm; use vm;
use trace::{VMTrace, FlatTrace}; use trace::{VMTrace, FlatTrace};
use log_entry::LogEntry; use log_entry::LogEntry;
use state_diff::StateDiff; use state_diff::StateDiff;
@ -28,7 +28,7 @@ use std::fmt;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Executed { pub struct Executed {
/// True if the outer call/create resulted in an exceptional exit. /// True if the outer call/create resulted in an exceptional exit.
pub exception: Option<evm::Error>, pub exception: Option<vm::Error>,
/// Gas paid up front for execution of transaction. /// Gas paid up front for execution of transaction.
pub gas: U256, pub gas: U256,

View File

@ -16,13 +16,13 @@
//! Transaction Execution environment. //! Transaction Execution environment.
use util::*; use util::*;
use evm::action_params::{ActionParams, ActionValue};
use state::{Backend as StateBackend, State, Substate, CleanupMode}; use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine; use engines::Engine;
use evm::CallType; use vm::EnvInfo;
use evm::env_info::EnvInfo;
use error::ExecutionError; 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 externalities::*;
use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer}; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer};
use transaction::{Action, SignedTransaction}; use transaction::{Action, SignedTransaction};
@ -74,8 +74,8 @@ pub struct TransactOptions {
pub check_nonce: bool, pub check_nonce: bool,
} }
pub fn executor<E>(engine: &E, vm_factory: &Factory, params: &ActionParams) pub fn executor<E>(engine: &E, vm_factory: &Factory, params: &ActionParams)
-> Box<evm::Evm> where E: Engine + ?Sized -> Box<vm::Vm> 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) { if engine.supports_wasm() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) {
Box::new( Box::new(
@ -269,7 +269,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
output_policy: OutputPolicy, output_policy: OutputPolicy,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V vm_tracer: &mut V
) -> evm::Result<FinalizationResult> where T: Tracer, V: VMTracer { ) -> vm::Result<FinalizationResult> where T: Tracer, V: VMTracer {
let depth_threshold = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get() / STACK_SIZE_PER_DEPTH); let depth_threshold = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get() / STACK_SIZE_PER_DEPTH);
let static_call = params.call_type == CallType::StaticCall; 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. /// Calls contract function with given contract params.
/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
/// Modifies the substate and the output. /// Modifies the substate and the output.
/// Returns either gas_left or `evm::Error`. /// Returns either gas_left or `vm::Error`.
pub fn call<T, V>( pub fn call<T, V>(
&mut self, &mut self,
params: ActionParams, params: ActionParams,
@ -307,14 +307,14 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
mut output: BytesRef, mut output: BytesRef,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V 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); trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info);
if (params.call_type == CallType::StaticCall || if (params.call_type == CallType::StaticCall ||
((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) && ((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) &&
self.static_flag)) self.static_flag))
&& params.value.value() > 0.into() { && params.value.value() > 0.into() {
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
// backup used in case of running out of gas // 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 cost <= params.gas {
if let Err(e) = builtin.execute(data, &mut output) { if let Err(e) = builtin.execute(data, &mut output) {
self.state.revert_to_checkpoint(); 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()); tracer.trace_failed_call(trace_info, vec![], evm_err.clone().into());
Err(evm_err) Err(evm_err)
} else { } else {
@ -371,9 +371,9 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
// just drain the whole gas // just drain the whole gas
self.state.revert_to_checkpoint(); 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 { } else {
let trace_info = tracer.prepare_trace_call(&params); let trace_info = tracer.prepare_trace_call(&params);
@ -432,17 +432,17 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
substate: &mut Substate, substate: &mut Substate,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V, 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); let scheme = self.engine.create_address_scheme(self.info.number);
if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(&params.address)? { if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(&params.address)? {
return Err(evm::Error::OutOfGas); return Err(vm::Error::OutOfGas);
} }
if params.call_type == CallType::StaticCall || self.static_flag { if params.call_type == CallType::StaticCall || self.static_flag {
let trace_info = tracer.prepare_trace_create(&params); let trace_info = tracer.prepare_trace_create(&params);
tracer.trace_failed_create(trace_info, vec![], evm::Error::MutableCallInStaticContext.into()); tracer.trace_failed_create(trace_info, vec![], vm::Error::MutableCallInStaticContext.into());
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
// backup used in case of running out of gas // 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, &mut self,
t: &SignedTransaction, t: &SignedTransaction,
mut substate: Substate, mut substate: Substate,
result: evm::Result<(U256, ReturnData)>, result: vm::Result<(U256, ReturnData)>,
output: Bytes, output: Bytes,
trace: Vec<FlatTrace>, trace: Vec<FlatTrace>,
vm_trace: Option<VMTrace> vm_trace: Option<VMTrace>
@ -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)?; self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?;
match result { match result {
Err(evm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), Err(vm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)),
Err(exception) => { Err(exception) => {
Ok(Executed { Ok(Executed {
exception: Some(exception), 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<FinalizationResult>, substate: &mut Substate, un_substate: Substate) { fn enact_result(&mut self, result: &vm::Result<FinalizationResult>, substate: &mut Substate, un_substate: Substate) {
match *result { match *result {
Err(evm::Error::OutOfGas) Err(vm::Error::OutOfGas)
| Err(evm::Error::BadJumpDestination {..}) | Err(vm::Error::BadJumpDestination {..})
| Err(evm::Error::BadInstruction {.. }) | Err(vm::Error::BadInstruction {.. })
| Err(evm::Error::StackUnderflow {..}) | Err(vm::Error::StackUnderflow {..})
| Err(evm::Error::BuiltIn {..}) | Err(vm::Error::BuiltIn {..})
| Err(evm::Error::Wasm {..}) | Err(vm::Error::Wasm {..})
| Err(evm::Error::OutOfStack {..}) | Err(vm::Error::OutOfStack {..})
| Err(evm::Error::MutableCallInStaticContext) | Err(vm::Error::MutableCallInStaticContext)
| Ok(FinalizationResult { apply_state: false, .. }) => { | Ok(FinalizationResult { apply_state: false, .. }) => {
self.state.revert_to_checkpoint(); self.state.revert_to_checkpoint();
}, },
Ok(_) | Err(evm::Error::Internal(_)) => { Ok(_) | Err(vm::Error::Internal(_)) => {
self.state.discard_checkpoint(); self.state.discard_checkpoint();
substate.accrue(un_substate); substate.accrue(un_substate);
} }
@ -602,9 +602,8 @@ mod tests {
use super::*; use super::*;
use util::{H256, U256, U512, Address, FromStr}; use util::{H256, U256, U512, Address, FromStr};
use util::bytes::BytesRef; use util::bytes::BytesRef;
use evm::action_params::{ActionParams, ActionValue}; use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress};
use evm::env_info::EnvInfo; use evm::{Factory, VMType};
use evm::{Factory, VMType, CreateContractAddress};
use error::ExecutionError; use error::ExecutionError;
use state::{Substate, CleanupMode}; use state::{Substate, CleanupMode};
use tests::helpers::*; use tests::helpers::*;
@ -613,8 +612,6 @@ mod tests {
use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer};
use transaction::{Action, Transaction}; use transaction::{Action, Transaction};
use evm::CallType;
#[test] #[test]
fn test_contract_address() { fn test_contract_address() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();

View File

@ -16,13 +16,14 @@
//! Transaction Execution environment. //! Transaction Execution environment.
use util::*; use util::*;
use evm::action_params::{ActionParams, ActionValue};
use state::{Backend as StateBackend, State, Substate, CleanupMode}; use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine; use engines::Engine;
use evm::env_info::EnvInfo;
use executive::*; use executive::*;
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; use vm::{
use evm::CallType; self, ActionParams, ActionValue, EnvInfo, CallType, Schedule,
Ext, ContractCreateResult, MessageCallResult, CreateContractAddress,
ReturnData
};
use transaction::UNSIGNED_SENDER; use transaction::UNSIGNED_SENDER;
use trace::{Tracer, VMTracer}; 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> 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 where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized
{ {
fn storage_at(&self, key: &H256) -> evm::Result<H256> { fn storage_at(&self, key: &H256) -> vm::Result<H256> {
self.state.storage_at(&self.origin_info.address, key).map_err(Into::into) 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 { if self.static_flag {
Err(evm::Error::MutableCallInStaticContext) Err(vm::Error::MutableCallInStaticContext)
} else { } else {
self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into) self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into)
} }
} }
fn exists(&self, address: &Address) -> evm::Result<bool> { fn exists(&self, address: &Address) -> vm::Result<bool> {
self.state.exists(address).map_err(Into::into) self.state.exists(address).map_err(Into::into)
} }
fn exists_and_not_null(&self, address: &Address) -> evm::Result<bool> { fn exists_and_not_null(&self, address: &Address) -> vm::Result<bool> {
self.state.exists_and_not_null(address).map_err(Into::into) self.state.exists_and_not_null(address).map_err(Into::into)
} }
fn origin_balance(&self) -> evm::Result<U256> { fn origin_balance(&self) -> vm::Result<U256> {
self.balance(&self.origin_info.address).map_err(Into::into) self.balance(&self.origin_info.address).map_err(Into::into)
} }
fn balance(&self, address: &Address) -> evm::Result<U256> { fn balance(&self, address: &Address) -> vm::Result<U256> {
self.state.balance(address).map_err(Into::into) 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<Arc<Bytes>> { fn extcode(&self, address: &Address) -> vm::Result<Arc<Bytes>> {
Ok(self.state.code(address)?.unwrap_or_else(|| Arc::new(vec![]))) Ok(self.state.code(address)?.unwrap_or_else(|| Arc::new(vec![])))
} }
fn extcodesize(&self, address: &Address) -> evm::Result<usize> { fn extcodesize(&self, address: &Address) -> vm::Result<usize> {
Ok(self.state.code_size(address)?.unwrap_or(0)) Ok(self.state.code_size(address)?.unwrap_or(0))
} }
#[cfg_attr(feature="dev", allow(match_ref_pats))] #[cfg_attr(feature="dev", allow(match_ref_pats))]
fn ret(mut self, gas: &U256, data: &ReturnData) -> evm::Result<U256> fn ret(mut self, gas: &U256, data: &ReturnData) -> vm::Result<U256>
where Self: Sized { where Self: Sized {
let handle_copy = |to: &mut Option<&mut Bytes>| { let handle_copy = |to: &mut Option<&mut Bytes>| {
to.as_mut().map(|b| **b = data.to_vec()); 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); 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 { if return_cost > *gas || data.len() > self.schedule.create_data_limit {
return match self.schedule.exceptional_failed_code_deposit { return match self.schedule.exceptional_failed_code_deposit {
true => Err(evm::Error::OutOfGas), true => Err(vm::Error::OutOfGas),
false => Ok(*gas) 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<H256>, data: &[u8]) -> evm::Result<()> { fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> {
use log_entry::LogEntry; use log_entry::LogEntry;
if self.static_flag { if self.static_flag {
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
let address = self.origin_info.address.clone(); 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(()) Ok(())
} }
fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> {
if self.static_flag { if self.static_flag {
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
let address = self.origin_info.address.clone(); 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 { mod tests {
use util::*; use util::*;
use engines::Engine; use engines::Engine;
use evm::env_info::EnvInfo; use evm::{EnvInfo, Ext, CallType};
use evm::Ext;
use state::{State, Substate}; use state::{State, Substate};
use tests::helpers::*; use tests::helpers::*;
use super::*; use super::*;
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
use evm::CallType;
fn get_test_origin() -> OriginInfo { fn get_test_origin() -> OriginInfo {
OriginInfo { OriginInfo {

View File

@ -15,15 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use super::test_common::*; use super::test_common::*;
use evm::action_params::ActionParams;
use state::{Backend as StateBackend, State, Substate}; use state::{Backend as StateBackend, State, Substate};
use executive::*; use executive::*;
use engines::Engine; use engines::Engine;
use evm::env_info::EnvInfo; use evm::{VMType, Finalize};
use evm; use vm::{
use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; self, ActionParams, CallType, Schedule, Ext,
ContractCreateResult, EnvInfo, MessageCallResult,
CreateContractAddress, ReturnData,
};
use externalities::*; use externalities::*;
use evm::CallType;
use tests::helpers::*; use tests::helpers::*;
use ethjson; use ethjson;
use trace::{Tracer, NoopTracer}; use trace::{Tracer, NoopTracer};
@ -88,27 +89,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> 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 where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized
{ {
fn storage_at(&self, key: &H256) -> evm::Result<H256> { fn storage_at(&self, key: &H256) -> vm::Result<H256> {
self.ext.storage_at(key) 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) self.ext.set_storage(key, value)
} }
fn exists(&self, address: &Address) -> evm::Result<bool> { fn exists(&self, address: &Address) -> vm::Result<bool> {
self.ext.exists(address) self.ext.exists(address)
} }
fn exists_and_not_null(&self, address: &Address) -> evm::Result<bool> { fn exists_and_not_null(&self, address: &Address) -> vm::Result<bool> {
self.ext.exists_and_not_null(address) self.ext.exists_and_not_null(address)
} }
fn balance(&self, address: &Address) -> evm::Result<U256> { fn balance(&self, address: &Address) -> vm::Result<U256> {
self.ext.balance(address) self.ext.balance(address)
} }
fn origin_balance(&self) -> evm::Result<U256> { fn origin_balance(&self) -> vm::Result<U256> {
self.ext.origin_balance() self.ext.origin_balance()
} }
@ -146,23 +147,23 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E>
MessageCallResult::Success(*gas, ReturnData::empty()) MessageCallResult::Success(*gas, ReturnData::empty())
} }
fn extcode(&self, address: &Address) -> evm::Result<Arc<Bytes>> { fn extcode(&self, address: &Address) -> vm::Result<Arc<Bytes>> {
self.ext.extcode(address) self.ext.extcode(address)
} }
fn extcodesize(&self, address: &Address) -> evm::Result<usize> { fn extcodesize(&self, address: &Address) -> vm::Result<usize> {
self.ext.extcodesize(address) self.ext.extcodesize(address)
} }
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> evm::Result<()> { fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> {
self.ext.log(topics, data) self.ext.log(topics, data)
} }
fn ret(self, gas: &U256, data: &ReturnData) -> Result<U256, evm::Error> { fn ret(self, gas: &U256, data: &ReturnData) -> Result<U256, vm::Error> {
self.ext.ret(gas, data) 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) self.ext.suicide(refund_address)
} }

View File

@ -22,7 +22,7 @@ use spec::Spec;
use ethjson; use ethjson;
use ethjson::state::test::ForkSpec; use ethjson::state::test::ForkSpec;
use transaction::SignedTransaction; use transaction::SignedTransaction;
use evm::env_info::EnvInfo; use vm::EnvInfo;
lazy_static! { lazy_static! {
pub static ref FRONTIER: Spec = ethereum::new_frontier_test(); pub static ref FRONTIER: Spec = ethereum::new_frontier_test();

View File

@ -106,6 +106,8 @@ extern crate semver;
extern crate stats; extern crate stats;
extern crate time; extern crate time;
extern crate transient_hashmap; extern crate transient_hashmap;
extern crate vm;
extern crate wasm;
#[macro_use] #[macro_use]
extern crate log; extern crate log;

View File

@ -20,10 +20,9 @@ use rustc_hex::FromHex;
use super::genesis::Genesis; use super::genesis::Genesis;
use super::seal::Generic as GenericSeal; use super::seal::Generic as GenericSeal;
use evm::action_params::{ActionValue, ActionParams};
use builtin::Builtin; use builtin::Builtin;
use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT}; 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 error::Error;
use ethereum; use ethereum;
use ethjson; use ethjson;
@ -36,7 +35,6 @@ use state_db::StateDB;
use state::{Backend, State, Substate}; use state::{Backend, State, Substate};
use state::backend::Basic as BasicBackend; use state::backend::Basic as BasicBackend;
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
use evm::CallType;
use util::*; use util::*;
/// Parameters common to ethereum-like blockchains. /// Parameters common to ethereum-like blockchains.
@ -102,14 +100,14 @@ pub struct CommonParams {
impl CommonParams { impl CommonParams {
/// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net. /// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net.
pub fn schedule(&self, block_number: u64) -> ::evm::Schedule { pub fn schedule(&self, block_number: u64) -> ::vm::Schedule {
let mut schedule = ::evm::Schedule::new_post_eip150(usize::max_value(), true, true, true); let mut schedule = ::vm::Schedule::new_post_eip150(usize::max_value(), true, true, true);
self.update_schedule(block_number, &mut schedule); self.update_schedule(block_number, &mut schedule);
schedule schedule
} }
/// Apply common spec config parameters to the 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_create2 = block_number >= self.eip86_transition;
schedule.have_revert = block_number >= self.eip140_transition; schedule.have_revert = block_number >= self.eip140_transition;
schedule.have_static_call = block_number >= self.eip214_transition; schedule.have_static_call = block_number >= self.eip214_transition;
@ -119,8 +117,8 @@ impl CommonParams {
} }
if block_number >= self.dust_protection_transition { if block_number >= self.dust_protection_transition {
schedule.kill_dust = match self.remove_dust_contracts { schedule.kill_dust = match self.remove_dust_contracts {
true => ::evm::CleanDustMode::WithCodeAndStorage, true => ::vm::CleanDustMode::WithCodeAndStorage,
false => ::evm::CleanDustMode::BasicOnly, false => ::vm::CleanDustMode::BasicOnly,
}; };
} }
} }

View File

@ -24,7 +24,7 @@ use std::collections::hash_map::Entry;
use receipt::Receipt; use receipt::Receipt;
use engines::Engine; use engines::Engine;
use evm::env_info::EnvInfo; use vm::EnvInfo;
use error::Error; use error::Error;
use executive::{Executive, TransactOptions}; use executive::{Executive, TransactOptions};
use factory::Factories; use factory::Factories;
@ -982,7 +982,7 @@ mod tests {
use ethkey::Secret; use ethkey::Secret;
use util::{U256, H256, Address, Hashable}; use util::{U256, H256, Address, Hashable};
use tests::helpers::*; use tests::helpers::*;
use evm::env_info::EnvInfo; use vm::EnvInfo;
use spec::*; use spec::*;
use transaction::*; use transaction::*;
use ethcore_logger::init_log; use ethcore_logger::init_log;

View File

@ -1,9 +1,7 @@
//! Tests of EVM integration with transaction execution. //! Tests of EVM integration with transaction execution.
use evm::action_params::{ActionParams, ActionValue}; use vm::{EnvInfo, ActionParams, ActionValue, CallType};
use evm::env_info::EnvInfo;
use evm::{Factory, VMType}; use evm::{Factory, VMType};
use evm::call_type::CallType;
use executive::Executive; use executive::Executive;
use state::Substate; use state::Substate;
use tests::helpers::*; use tests::helpers::*;

View File

@ -17,7 +17,7 @@
//! Simple executive tracer. //! Simple executive tracer.
use util::{Bytes, Address, U256}; 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::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide};
use trace::{Tracer, VMTracer, FlatTrace, TraceError}; use trace::{Tracer, VMTracer, FlatTrace, TraceError};

View File

@ -39,7 +39,7 @@ pub use self::types::filter::{Filter, AddressesFilter};
use util::{Bytes, Address, U256, H256, DBTransaction}; use util::{Bytes, Address, U256, H256, DBTransaction};
use self::trace::{Call, Create}; use self::trace::{Call, Create};
use evm::action_params::ActionParams; use vm::ActionParams;
use header::BlockNumber; use header::BlockNumber;
/// This trait is used by executive to build traces. /// This trait is used by executive to build traces.

View File

@ -17,7 +17,7 @@
//! Nonoperative tracer. //! Nonoperative tracer.
use util::{Bytes, Address, U256}; use util::{Bytes, Address, U256};
use evm::action_params::ActionParams; use vm::ActionParams;
use trace::{Tracer, VMTracer, FlatTrace, TraceError}; use trace::{Tracer, VMTracer, FlatTrace, TraceError};
use trace::trace::{Call, Create, VMTrace}; use trace::trace::{Call, Create, VMTrace};

View File

@ -18,7 +18,7 @@
use std::fmt; use std::fmt;
use rlp::{Encodable, RlpStream, Decodable, DecoderError, UntrustedRlp}; use rlp::{Encodable, RlpStream, Decodable, DecoderError, UntrustedRlp};
use evm::Error as EvmError; use vm::Error as VmError;
/// Trace evm errors. /// Trace evm errors.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -45,24 +45,24 @@ pub enum Error {
Wasm, Wasm,
} }
impl<'a> From<&'a EvmError> for Error { impl<'a> From<&'a VmError> for Error {
fn from(e: &'a EvmError) -> Self { fn from(e: &'a VmError) -> Self {
match *e { match *e {
EvmError::OutOfGas => Error::OutOfGas, VmError::OutOfGas => Error::OutOfGas,
EvmError::BadJumpDestination { .. } => Error::BadJumpDestination, VmError::BadJumpDestination { .. } => Error::BadJumpDestination,
EvmError::BadInstruction { .. } => Error::BadInstruction, VmError::BadInstruction { .. } => Error::BadInstruction,
EvmError::StackUnderflow { .. } => Error::StackUnderflow, VmError::StackUnderflow { .. } => Error::StackUnderflow,
EvmError::OutOfStack { .. } => Error::OutOfStack, VmError::OutOfStack { .. } => Error::OutOfStack,
EvmError::BuiltIn { .. } => Error::BuiltIn, VmError::BuiltIn { .. } => Error::BuiltIn,
EvmError::Wasm { .. } => Error::Wasm, VmError::Wasm { .. } => Error::Wasm,
EvmError::Internal(_) => Error::Internal, VmError::Internal(_) => Error::Internal,
EvmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext,
} }
} }
} }
impl From<EvmError> for Error { impl From<VmError> for Error {
fn from(e: EvmError) -> Self { fn from(e: VmError) -> Self {
Error::from(&e) Error::from(&e)
} }
} }

View File

@ -21,7 +21,7 @@ use util::sha3::Hashable;
use util::bloom::Bloomable; use util::bloom::Bloomable;
use rlp::*; use rlp::*;
use evm::action_params::ActionParams; use vm::ActionParams;
use basic_types::LogBloom; use basic_types::LogBloom;
use evm::CallType; use evm::CallType;
use super::error::Error; use super::error::Error;

14
ethcore/vm/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "vm"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[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" }

View File

@ -20,7 +20,7 @@ use util::hash::{H256};
use util::sha3::{Hashable, SHA3_EMPTY}; use util::sha3::{Hashable, SHA3_EMPTY};
use ethjson; use ethjson;
use {CallType}; use call_type::CallType;
use std::sync::Arc; use std::sync::Arc;
@ -48,7 +48,7 @@ impl ActionValue {
/// Returns the apparent action value of the U256-convertable raw value /// Returns the apparent action value of the U256-convertable raw value
pub fn apparent<T: Into<U256>>(apparent_value: T) -> ActionValue { pub fn apparent<T: Into<U256>>(apparent_value: T) -> ActionValue {
ActionValue::Apparent(apparent_value.into()) ActionValue::Apparent(apparent_value.into())
} }
} }

100
ethcore/vm/src/error.rs Normal file
View File

@ -0,0 +1,100 @@
// 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 <http://www.gnu.org/licenses/>.
//! VM errors module
use util::trie;
use std::fmt;
/// 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),
}
impl From<Box<trie::TrieError>> for Error {
fn from(err: Box<trie::TrieError>) -> Self {
Error::Internal(format!("Internal error: {}", err))
}
}
// impl From<wasm::RuntimeError> 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<T> = ::std::result::Result<T, Error>;

View File

@ -20,7 +20,8 @@ use util::*;
use call_type::CallType; use call_type::CallType;
use env_info::EnvInfo; use env_info::EnvInfo;
use schedule::Schedule; use schedule::Schedule;
use evm::{self, ReturnData}; use return_data::ReturnData;
use error::Result;
/// Result of externalities create function. /// Result of externalities create function.
pub enum ContractCreateResult { pub enum ContractCreateResult {
@ -56,22 +57,22 @@ pub enum CreateContractAddress {
/// Externalities interface for EVMs /// Externalities interface for EVMs
pub trait Ext { pub trait Ext {
/// Returns a value for given key. /// Returns a value for given key.
fn storage_at(&self, key: &H256) -> evm::Result<H256>; fn storage_at(&self, key: &H256) -> Result<H256>;
/// Stores a value for given key. /// Stores a value for given key.
fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()>; fn set_storage(&mut self, key: H256, value: H256) -> Result<()>;
/// Determine whether an account exists. /// Determine whether an account exists.
fn exists(&self, address: &Address) -> evm::Result<bool>; fn exists(&self, address: &Address) -> Result<bool>;
/// Determine whether an account exists and is not null (zero balance/nonce, no code). /// Determine whether an account exists and is not null (zero balance/nonce, no code).
fn exists_and_not_null(&self, address: &Address) -> evm::Result<bool>; fn exists_and_not_null(&self, address: &Address) -> Result<bool>;
/// Balance of the origin account. /// Balance of the origin account.
fn origin_balance(&self) -> evm::Result<U256>; fn origin_balance(&self) -> Result<U256>;
/// Returns address balance. /// Returns address balance.
fn balance(&self, address: &Address) -> evm::Result<U256>; fn balance(&self, address: &Address) -> Result<U256>;
/// Returns the hash of one of the 256 most recent complete blocks. /// Returns the hash of one of the 256 most recent complete blocks.
fn blockhash(&mut self, number: &U256) -> H256; fn blockhash(&mut self, number: &U256) -> H256;
@ -99,21 +100,21 @@ pub trait Ext {
) -> MessageCallResult; ) -> MessageCallResult;
/// Returns code at given address /// Returns code at given address
fn extcode(&self, address: &Address) -> evm::Result<Arc<Bytes>>; fn extcode(&self, address: &Address) -> Result<Arc<Bytes>>;
/// Returns code size at given address /// Returns code size at given address
fn extcodesize(&self, address: &Address) -> evm::Result<usize>; fn extcodesize(&self, address: &Address) -> Result<usize>;
/// Creates log entry with given topics and data /// Creates log entry with given topics and data
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> evm::Result<()>; fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>;
/// Should be called when transaction calls `RETURN` opcode. /// Should be called when transaction calls `RETURN` opcode.
/// Returns gas_left if cost of returning the data is not too high. /// Returns gas_left if cost of returning the data is not too high.
fn ret(self, gas: &U256, data: &ReturnData) -> evm::Result<U256>; fn ret(self, gas: &U256, data: &ReturnData) -> Result<U256>;
/// Should be called when contract commits suicide. /// Should be called when contract commits suicide.
/// Address to which funds should be refunded. /// Address to which funds should be refunded.
fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> ; fn suicide(&mut self, refund_address: &Address) -> Result<()> ;
/// Returns schedule. /// Returns schedule.
fn schedule(&self) -> &Schedule; fn schedule(&self) -> &Schedule;

46
ethcore/vm/src/lib.rs Normal file
View File

@ -0,0 +1,46 @@
// 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 <http://www.gnu.org/licenses/>.
//! 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, ActionValue};
pub use call_type::CallType;
pub use env_info::{EnvInfo, LastHashes};
pub use schedule::{Schedule, CleanDustMode};
pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress};
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<GasLeft>;
}

View File

@ -0,0 +1,68 @@
// 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 <http://www.gnu.org/licenses/>.
//! Return data structures
use util::U256;
/// Return data buffer. Holds memory from a previous call and a slice into that memory.
#[derive(Debug)]
pub struct ReturnData {
mem: Vec<u8>,
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<u8>, offset: usize, size: usize) -> Self {
ReturnData {
mem: mem,
offset: offset,
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
},
}

View File

@ -250,6 +250,12 @@ impl Schedule {
} }
} }
impl Default for Schedule {
fn default() -> Self {
Schedule::new_frontier()
}
}
#[test] #[test]
#[cfg(test)] #[cfg(test)]
fn schedule_evm_assumptions() { fn schedule_evm_assumptions() {
@ -260,3 +266,4 @@ fn schedule_evm_assumptions() {
assert_eq!(s1.quad_coeff_div, 512); assert_eq!(s1.quad_coeff_div, 512);
assert_eq!(s2.quad_coeff_div, 512); assert_eq!(s2.quad_coeff_div, 512);
} }

12
ethcore/wasm/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "wasm"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
byteorder = "1.0"
ethcore-util = { path = "../../util" }
log = "0.3"
parity-wasm = "0.12"
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
vm = { path = "../vm" }

View File

@ -16,6 +16,13 @@
//! Wasm Interpreter //! 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 runtime;
mod ptr; mod ptr;
mod call_args; mod call_args;
@ -30,10 +37,8 @@ const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024;
use parity_wasm::{interpreter, elements}; use parity_wasm::{interpreter, elements};
use parity_wasm::interpreter::ModuleInstanceInterface; use parity_wasm::interpreter::ModuleInstanceInterface;
use wasm_utils;
use evm::{self, GasLeft, ReturnData}; use vm::{GasLeft, ReturnData, ActionParams};
use action_params::ActionParams;
use self::runtime::Runtime; use self::runtime::Runtime;
pub use self::runtime::Error as RuntimeError; 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<GasLeft> { fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
use parity_wasm::elements::Deserialize; use parity_wasm::elements::Deserialize;
let code = params.code.expect("exec is only called on contract with code; qed"); 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"); .expect("Linear memory to exist in wasm runtime");
if params.gas > ::std::u64::MAX.into() { 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( let mut runtime = Runtime::with_params(
@ -90,7 +95,7 @@ impl evm::Evm for WasmInterpreter {
elements::Module::deserialize( elements::Module::deserialize(
&mut cursor &mut cursor
).map_err(|err| { ).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)) interpreter::env_native_module(env_instance, native_bindings(&mut runtime))
.map_err(|err| { .map_err(|err| {
// todo: prefer explicit panic here also? // 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)); ).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)) let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals))
.map_err(|err| { .map_err(|err| {
trace!(target: "wasm", "Error adding contract module: {:?}", 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) module_instance.execute_export("_call", execution_params)
.map_err(|err| { .map_err(|err| {
trace!(target: "wasm", "Error executing contract: {:?}", 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), functions: ::std::borrow::Cow::from(env::SIGNATURES),
} }
} }
impl From<runtime::Error> for vm::Error {
fn from(err: runtime::Error) -> vm::Error {
vm::Error::Wasm(format!("WASM runtime-error: {:?}", err))
}
}

View File

@ -20,8 +20,7 @@ use std::sync::Arc;
use byteorder::{LittleEndian, ByteOrder}; use byteorder::{LittleEndian, ByteOrder};
use ext; use vm;
use parity_wasm::interpreter; use parity_wasm::interpreter;
use util::{Address, H256, U256}; use util::{Address, H256, U256};
@ -62,14 +61,14 @@ pub struct Runtime<'a> {
gas_counter: u64, gas_counter: u64,
gas_limit: u64, gas_limit: u64,
dynamic_top: u32, dynamic_top: u32,
ext: &'a mut ext::Ext, ext: &'a mut vm::Ext,
memory: Arc<interpreter::MemoryInstance>, memory: Arc<interpreter::MemoryInstance>,
} }
impl<'a> Runtime<'a> { impl<'a> Runtime<'a> {
/// New runtime for wasm contract with specified params /// New runtime for wasm contract with specified params
pub fn with_params<'b>( pub fn with_params<'b>(
ext: &'b mut ext::Ext, ext: &'b mut vm::Ext,
memory: Arc<interpreter::MemoryInstance>, memory: Arc<interpreter::MemoryInstance>,
stack_space: u32, stack_space: u32,
gas_limit: u64, gas_limit: u64,
@ -153,14 +152,14 @@ impl<'a> Runtime<'a> {
.map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))?
.into(); .into();
match self.ext.create(&gas_left, &endowment, &code, ext::CreateContractAddress::FromSenderAndCodeHash) { match self.ext.create(&gas_left, &endowment, &code, vm::CreateContractAddress::FromSenderAndCodeHash) {
ext::ContractCreateResult::Created(address, gas_left) => { vm::ContractCreateResult::Created(address, gas_left) => {
self.memory.set(result_ptr, &*address)?; self.memory.set(result_ptr, &*address)?;
self.gas_counter = self.gas_limit - gas_left.low_u64(); self.gas_counter = self.gas_limit - gas_left.low_u64();
trace!(target: "wasm", "runtime: create contract success (@{:?})", address); trace!(target: "wasm", "runtime: create contract success (@{:?})", address);
Ok(Some(0i32.into())) Ok(Some(0i32.into()))
}, },
ext::ContractCreateResult::Failed => { vm::ContractCreateResult::Failed => {
trace!(target: "wasm", "runtime: create contract fail"); trace!(target: "wasm", "runtime: create contract fail");
Ok(Some((-1i32).into())) Ok(Some((-1i32).into()))
} }

View File

@ -28,7 +28,7 @@ macro_rules! load_sample {
} }
} }
fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> { fn test_finalize(res: Result<GasLeft, vm::Error>) -> Result<U256, vm::Error> {
match res { match res {
Ok(GasLeft::Known(gas)) => Ok(gas), Ok(GasLeft::Known(gas)) => Ok(gas),
Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented. Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented.

View File

@ -31,7 +31,7 @@ extern crate rustc_hex;
use self::test::{Bencher, black_box}; use self::test::{Bencher, black_box};
use evm::run_vm; use evm::run_vm;
use ethcore::evm::action_params::ActionParams; use ethcore::vm::ActionParams;
use ethcore_util::U256; use ethcore_util::U256;
use rustc_hex::FromHex; use rustc_hex::FromHex;

View File

@ -34,7 +34,7 @@ use docopt::Docopt;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::{U256, Bytes, Address}; use util::{U256, Bytes, Address};
use ethcore::spec; use ethcore::spec;
use evm::action_params::ActionParams; use vm::ActionParams;
mod vm; mod vm;
mod display; mod display;

View File

@ -20,7 +20,7 @@ use std::time::{Instant, Duration};
use util::U256; use util::U256;
use ethcore::{trace, spec}; use ethcore::{trace, spec};
use ethcore::client::{EvmTestClient, EvmTestError}; use ethcore::client::{EvmTestClient, EvmTestError};
use evm::action_params::ActionParams; use vm::ActionParams;
/// VM execution informant /// VM execution informant
pub trait Informant: trace::VMTracer { pub trait Informant: trace::VMTracer {

View File

@ -46,7 +46,7 @@ ethjson = { path = "../json" }
ethcore-devtools = { path = "../devtools" } ethcore-devtools = { path = "../devtools" }
ethcore-light = { path = "../ethcore/light" } ethcore-light = { path = "../ethcore/light" }
ethcore-logger = { path = "../logger" } ethcore-logger = { path = "../logger" }
evm = { path = "../ethcore/evm" } vm = { path = "../ethcore/vm" }
parity-updater = { path = "../updater" } parity-updater = { path = "../updater" }
parity-reactor = { path = "../util/reactor" } parity-reactor = { path = "../util/reactor" }
rlp = { path = "../util/rlp" } rlp = { path = "../util/rlp" }

View File

@ -52,7 +52,7 @@ extern crate ethkey;
extern crate ethstore; extern crate ethstore;
extern crate ethsync; extern crate ethsync;
extern crate ethcore_logger; extern crate ethcore_logger;
extern crate evm; extern crate vm;
extern crate fetch; extern crate fetch;
extern crate parity_reactor; extern crate parity_reactor;
extern crate parity_updater as updater; extern crate parity_updater as updater;

View File

@ -327,7 +327,7 @@ struct ExecuteParams {
from: Address, from: Address,
tx: EthTransaction, tx: EthTransaction,
hdr: encoded::Header, hdr: encoded::Header,
env_info: ::evm::env_info::EnvInfo, env_info: ::vm::EnvInfo,
engine: Arc<::ethcore::engines::Engine>, engine: Arc<::ethcore::engines::Engine>,
on_demand: Arc<OnDemand>, on_demand: Arc<OnDemand>,
sync: Arc<LightSync>, sync: Arc<LightSync>,

View File

@ -21,7 +21,7 @@ use ethcore::trace::trace::{Action, Res, Call};
use ethcore::trace::LocalizedTrace; use ethcore::trace::LocalizedTrace;
use ethcore::client::TestBlockChainClient; use ethcore::client::TestBlockChainClient;
use evm::CallType; use vm::CallType;
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;
use v1::tests::helpers::{TestMinerService}; use v1::tests::helpers::{TestMinerService};

View File

@ -22,7 +22,7 @@ use ethcore::trace as et;
use ethcore::state_diff; use ethcore::state_diff;
use ethcore::account_diff; use ethcore::account_diff;
use ethcore::client::Executed; use ethcore::client::Executed;
use evm; use vm;
use v1::types::{Bytes, H160, H256, U256}; use v1::types::{Bytes, H160, H256, U256};
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -256,14 +256,14 @@ pub enum CallType {
StaticCall, StaticCall,
} }
impl From<evm::CallType> for CallType { impl From<vm::CallType> for CallType {
fn from(c: evm::CallType) -> Self { fn from(c: vm::CallType) -> Self {
match c { match c {
evm::CallType::None => CallType::None, vm::CallType::None => CallType::None,
evm::CallType::Call => CallType::Call, vm::CallType::Call => CallType::Call,
evm::CallType::CallCode => CallType::CallCode, vm::CallType::CallCode => CallType::CallCode,
evm::CallType::DelegateCall => CallType::DelegateCall, vm::CallType::DelegateCall => CallType::DelegateCall,
evm::CallType::StaticCall => CallType::StaticCall, vm::CallType::StaticCall => CallType::StaticCall,
} }
} }
} }