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:
		
							parent
							
								
									c4025622de
								
							
						
					
					
						commit
						b7006034b1
					
				
							
								
								
									
										34
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										34
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -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" | ||||||
|  | |||||||
| @ -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"] } | ||||||
|  | |||||||
| @ -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" } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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())) | ||||||
|  | |||||||
| @ -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)); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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 | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -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) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -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}; |  | ||||||
|  | |||||||
| @ -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") | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -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" | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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}; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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.
 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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}; | ||||||
|  | |||||||
| @ -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(); | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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(), | ||||||
|  | |||||||
| @ -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]); | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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(¶ms); | 			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, | 		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(¶ms.address)? { | 		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 { | 		if params.call_type == CallType::StaticCall || self.static_flag { | ||||||
| 			let trace_info = tracer.prepare_trace_create(¶ms); | 			let trace_info = tracer.prepare_trace_create(¶ms); | ||||||
| 			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(); | ||||||
|  | |||||||
| @ -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 { | ||||||
|  | |||||||
| @ -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) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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(); | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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, | ||||||
| 			}; | 			}; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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::*; | ||||||
|  | |||||||
| @ -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}; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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.
 | ||||||
|  | |||||||
| @ -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}; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -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
									
								
							
							
						
						
									
										14
									
								
								ethcore/vm/Cargo.toml
									
									
									
									
									
										Normal 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" } | ||||||
| @ -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
									
								
							
							
						
						
									
										100
									
								
								ethcore/vm/src/error.rs
									
									
									
									
									
										Normal 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>; | ||||||
| @ -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
									
								
							
							
						
						
									
										46
									
								
								ethcore/vm/src/lib.rs
									
									
									
									
									
										Normal 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>; | ||||||
|  | } | ||||||
							
								
								
									
										68
									
								
								ethcore/vm/src/return_data.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								ethcore/vm/src/return_data.rs
									
									
									
									
									
										Normal 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 | ||||||
|  | 	}, | ||||||
|  | } | ||||||
| @ -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
									
								
							
							
						
						
									
										12
									
								
								ethcore/wasm/Cargo.toml
									
									
									
									
									
										Normal 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" } | ||||||
| @ -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)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -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())) | ||||||
| 			} | 			} | ||||||
| @ -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.
 | ||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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 { | ||||||
|  | |||||||
| @ -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" } | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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>, | ||||||
|  | |||||||
| @ -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}; | ||||||
|  | |||||||
| @ -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, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user