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] | ||||
| name = "using_queue" | ||||
| name = "wasm" | ||||
| 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]] | ||||
| name = "advapi32-sys" | ||||
| @ -504,6 +512,8 @@ dependencies = [ | ||||
|  "stats 0.1.0", | ||||
|  "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "vm 0.1.0", | ||||
|  "wasm 0.1.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -625,6 +635,7 @@ dependencies = [ | ||||
|  "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "stats 0.1.0", | ||||
|  "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "vm 0.1.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -888,6 +899,7 @@ dependencies = [ | ||||
|  "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "rlp 0.2.0", | ||||
|  "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "vm 0.1.0", | ||||
|  "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", | ||||
| ] | ||||
| 
 | ||||
| @ -1933,7 +1945,6 @@ dependencies = [ | ||||
|  "ethkey 0.2.0", | ||||
|  "ethstore 0.1.0", | ||||
|  "ethsync 1.8.0", | ||||
|  "evm 0.1.0", | ||||
|  "fetch 0.1.0", | ||||
|  "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
| @ -1962,6 +1973,7 @@ dependencies = [ | ||||
|  "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "tokio-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "vm 0.1.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3044,6 +3056,10 @@ dependencies = [ | ||||
|  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "using_queue" | ||||
| version = "0.1.0" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "utf8-ranges" | ||||
| version = "1.0.0" | ||||
| @ -3072,6 +3088,20 @@ dependencies = [ | ||||
|  "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "vm" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "common-types 0.1.0", | ||||
|  "ethcore-util 1.8.0", | ||||
|  "ethjson 0.1.0", | ||||
|  "evmjit 1.8.0", | ||||
|  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "rlp 0.2.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "void" | ||||
| version = "1.0.2" | ||||
|  | ||||
| @ -53,6 +53,8 @@ semver = "0.6" | ||||
| stats = { path = "../util/stats" } | ||||
| time = "0.1" | ||||
| transient-hashmap = "0.4" | ||||
| vm = { path = "vm" } | ||||
| wasm = { path = "wasm" } | ||||
| 
 | ||||
| [dev-dependencies] | ||||
| native-contracts = { path = "native_contracts", features = ["test_contracts"] } | ||||
|  | ||||
| @ -13,6 +13,7 @@ ethjson = { path = "../../json" } | ||||
| lazy_static = "0.2" | ||||
| log = "0.3" | ||||
| rlp = { path = "../../util/rlp" } | ||||
| vm = { path = "../vm" } | ||||
| parity-wasm = "0.12" | ||||
| wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } | ||||
| 
 | ||||
|  | ||||
| @ -25,7 +25,7 @@ extern crate test; | ||||
| use self::test::{Bencher, black_box}; | ||||
| 
 | ||||
| use util::*; | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::ActionParams; | ||||
| use evm::{self, Factory, VMType}; | ||||
| use evm::tests::FakeExt; | ||||
| 
 | ||||
|  | ||||
| @ -17,142 +17,8 @@ | ||||
| //! Evm interface.
 | ||||
| 
 | ||||
| use std::{ops, cmp, fmt}; | ||||
| use util::{U128, U256, U512, trie}; | ||||
| use action_params::ActionParams; | ||||
| use {Ext}; | ||||
| 
 | ||||
| use super::wasm; | ||||
| 
 | ||||
| /// Evm errors.
 | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub enum Error { | ||||
| 	/// `OutOfGas` is returned when transaction execution runs out of gas.
 | ||||
| 	/// The state should be reverted to the state from before the
 | ||||
| 	/// transaction execution. But it does not mean that transaction
 | ||||
| 	/// was invalid. Balance still should be transfered and nonce
 | ||||
| 	/// should be increased.
 | ||||
| 	OutOfGas, | ||||
| 	/// `BadJumpDestination` is returned when execution tried to move
 | ||||
| 	/// to position that wasn't marked with JUMPDEST instruction
 | ||||
| 	BadJumpDestination { | ||||
| 		/// Position the code tried to jump to.
 | ||||
| 		destination: usize | ||||
| 	}, | ||||
| 	/// `BadInstructions` is returned when given instruction is not supported
 | ||||
| 	BadInstruction { | ||||
| 		/// Unrecognized opcode
 | ||||
| 		instruction: u8, | ||||
| 	}, | ||||
| 	/// `StackUnderflow` when there is not enough stack elements to execute instruction
 | ||||
| 	StackUnderflow { | ||||
| 		/// Invoked instruction
 | ||||
| 		instruction: &'static str, | ||||
| 		/// How many stack elements was requested by instruction
 | ||||
| 		wanted: usize, | ||||
| 		/// How many elements were on stack
 | ||||
| 		on_stack: usize | ||||
| 	}, | ||||
| 	/// When execution would exceed defined Stack Limit
 | ||||
| 	OutOfStack { | ||||
| 		/// Invoked instruction
 | ||||
| 		instruction: &'static str, | ||||
| 		/// How many stack elements instruction wanted to push
 | ||||
| 		wanted: usize, | ||||
| 		/// What was the stack limit
 | ||||
| 		limit: usize | ||||
| 	}, | ||||
| 	/// Built-in contract failed on given input
 | ||||
| 	BuiltIn(&'static str), | ||||
| 	/// When execution tries to modify the state in static context
 | ||||
| 	MutableCallInStaticContext, | ||||
| 	/// Likely to cause consensus issues.
 | ||||
| 	Internal(String), | ||||
| 	/// Wasm runtime error
 | ||||
| 	Wasm(String), | ||||
| } | ||||
| 
 | ||||
| impl From<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 | ||||
| 	}, | ||||
| } | ||||
| use util::{U128, U256, U512}; | ||||
| use vm::{Ext, Result, ReturnData, GasLeft, Error}; | ||||
| 
 | ||||
| /// Finalization result. Gas Left: either it is a known value, or it needs to be computed by processing
 | ||||
| /// a return instruction.
 | ||||
| @ -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)] | ||||
| mod tests { | ||||
| 	use util::U256; | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| //! Evm factory.
 | ||||
| //!
 | ||||
| use std::sync::Arc; | ||||
| use evm::Evm; | ||||
| use vm::Vm; | ||||
| use util::U256; | ||||
| use super::interpreter::SharedCache; | ||||
| use super::vmtype::VMType; | ||||
| @ -33,7 +33,7 @@ impl Factory { | ||||
| 	/// Create fresh instance of VM
 | ||||
| 	/// Might choose implementation depending on supplied gas.
 | ||||
| 	#[cfg(feature = "jit")] | ||||
| 	pub fn create(&self, gas: U256) -> Box<Evm> { | ||||
| 	pub fn create(&self, gas: U256) -> Box<Vm> { | ||||
| 		match self.evm { | ||||
| 			VMType::Jit => { | ||||
| 				Box::new(super::jit::JitEvm::default()) | ||||
| @ -49,7 +49,7 @@ impl Factory { | ||||
| 	/// Create fresh instance of VM
 | ||||
| 	/// Might choose implementation depending on supplied gas.
 | ||||
| 	#[cfg(not(feature = "jit"))] | ||||
| 	pub fn create(&self, gas: U256) -> Box<Evm> { | ||||
| 	pub fn create(&self, gas: U256) -> Box<Vm> { | ||||
| 		match self.evm { | ||||
| 			VMType::Interpreter => if Self::can_fit_in_usize(gas) { | ||||
| 				Box::new(super::interpreter::Interpreter::<usize>::new(self.evm_cache.clone())) | ||||
|  | ||||
| @ -17,15 +17,15 @@ | ||||
| use util::*; | ||||
| use super::u256_to_address; | ||||
| 
 | ||||
| use {evm, ext}; | ||||
| use {evm, vm}; | ||||
| use instructions::{self, Instruction, InstructionInfo}; | ||||
| use interpreter::stack::Stack; | ||||
| use schedule::Schedule; | ||||
| use vm::Schedule; | ||||
| 
 | ||||
| macro_rules! overflowing { | ||||
| 	($x: expr) => {{ | ||||
| 		let (v, overflow) = $x; | ||||
| 		if overflow { return Err(evm::Error::OutOfGas); } | ||||
| 		if overflow { return Err(vm::Error::OutOfGas); } | ||||
| 		v | ||||
| 	}} | ||||
| } | ||||
| @ -59,16 +59,16 @@ impl<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 { | ||||
| 			true => Err(evm::Error::OutOfGas), | ||||
| 			true => Err(vm::Error::OutOfGas), | ||||
| 			false => Ok(()) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/// How much gas is provided to a CALL/CREATE, given that we need to deduct `needed` for this operation
 | ||||
| 	/// and that we `requested` some.
 | ||||
| 	pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option<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`)
 | ||||
| 		// but in EIP150 even if we request more we should never fail from OOG
 | ||||
| 		let requested = requested.map(Gas::from_u256); | ||||
| @ -107,12 +107,12 @@ impl<Gas: evm::CostType> Gasometer<Gas> { | ||||
| 	/// it will be the amount of gas that the current context provides to the child context.
 | ||||
| 	pub fn requirements( | ||||
| 		&mut self, | ||||
| 		ext: &ext::Ext, | ||||
| 		ext: &vm::Ext, | ||||
| 		instruction: Instruction, | ||||
| 		info: &InstructionInfo, | ||||
| 		stack: &Stack<U256>, | ||||
| 		current_mem_size: usize, | ||||
| 	) -> evm::Result<InstructionRequirements<Gas>> { | ||||
| 	) -> vm::Result<InstructionRequirements<Gas>> { | ||||
| 		let schedule = ext.schedule(); | ||||
| 		let tier = instructions::get_tier_idx(info.tier); | ||||
| 		let default_gas = Gas::from(schedule.tier_step_gas[tier]); | ||||
| @ -291,7 +291,7 @@ impl<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 s = mem_size >> 5; | ||||
| 			// s * memory_gas + s * s / quad_coeff_div
 | ||||
| @ -319,12 +319,12 @@ impl<Gas: evm::CostType> Gasometer<Gas> { | ||||
| 
 | ||||
| 
 | ||||
| #[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)))) | ||||
| } | ||||
| 
 | ||||
| #[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() { | ||||
| 		return Ok(Gas::from(0)); | ||||
| 	} | ||||
|  | ||||
| @ -15,7 +15,7 @@ | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| use util::U256; | ||||
| use {ReturnData}; | ||||
| use vm::ReturnData; | ||||
| 
 | ||||
| const MAX_RETURN_WASTE_BYTES: usize = 16384; | ||||
| 
 | ||||
|  | ||||
| @ -23,17 +23,21 @@ mod stack; | ||||
| mod memory; | ||||
| 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::stack::{Stack, VecStack}; | ||||
| use self::memory::Memory; | ||||
| pub use self::shared_cache::SharedCache; | ||||
| 
 | ||||
| use std::marker::PhantomData; | ||||
| use action_params::{ActionParams, ActionValue}; | ||||
| use call_type::CallType; | ||||
| use instructions::{self, Instruction, InstructionInfo}; | ||||
| use evm::{self, GasLeft, CostType, ReturnData}; | ||||
| use ext::{self, MessageCallResult, ContractCreateResult, CreateContractAddress}; | ||||
| use bit_set::BitSet; | ||||
| 
 | ||||
| use util::*; | ||||
| @ -107,8 +111,8 @@ pub struct Interpreter<Cost: CostType> { | ||||
| 	_type: PhantomData<Cost>, | ||||
| } | ||||
| 
 | ||||
| impl<Cost: CostType> evm::Evm for Interpreter<Cost> { | ||||
| 	fn exec(&mut self, params: ActionParams, ext: &mut ext::Ext) -> evm::Result<GasLeft> { | ||||
| impl<Cost: CostType> vm::Vm for Interpreter<Cost> { | ||||
| 	fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> { | ||||
| 		self.mem.clear(); | ||||
| 
 | ||||
| 		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(); | ||||
| 
 | ||||
| 		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::REVERT && !schedule.have_revert) { | ||||
| 
 | ||||
| 			return Err(evm::Error::BadInstruction { | ||||
| 			return Err(vm::Error::BadInstruction { | ||||
| 				instruction: instruction | ||||
| 			}); | ||||
| 		} | ||||
| 
 | ||||
| 		if info.tier == instructions::GasPriceTier::Invalid { | ||||
| 			return Err(evm::Error::BadInstruction { | ||||
| 			return Err(vm::Error::BadInstruction { | ||||
| 				instruction: instruction | ||||
| 			}); | ||||
| 		} | ||||
| 
 | ||||
| 		if !stack.has(info.args) { | ||||
| 			Err(evm::Error::StackUnderflow { | ||||
| 			Err(vm::Error::StackUnderflow { | ||||
| 				instruction: info.name, | ||||
| 				wanted: info.args, | ||||
| 				on_stack: stack.size() | ||||
| 			}) | ||||
| 		} else if stack.size() - info.args + info.ret > schedule.stack_limit { | ||||
| 			Err(evm::Error::OutOfStack { | ||||
| 			Err(vm::Error::OutOfStack { | ||||
| 				instruction: info.name, | ||||
| 				wanted: info.ret - info.args, | ||||
| 				limit: schedule.stack_limit | ||||
| @ -272,12 +276,12 @@ impl<Cost: CostType> Interpreter<Cost> { | ||||
| 		&mut self, | ||||
| 		gas: Cost, | ||||
| 		params: &ActionParams, | ||||
| 		ext: &mut ext::Ext, | ||||
| 		ext: &mut vm::Ext, | ||||
| 		instruction: Instruction, | ||||
| 		code: &mut CodeReader, | ||||
| 		stack: &mut Stack<U256>, | ||||
| 		provided: Option<Cost> | ||||
| 	) -> evm::Result<InstructionResult<Cost>> { | ||||
| 	) -> vm::Result<InstructionResult<Cost>> { | ||||
| 		match instruction { | ||||
| 			instructions::JUMP => { | ||||
| 				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; | ||||
| 
 | ||||
| 		if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u { | ||||
| 			Ok(jump) | ||||
| 		} else { | ||||
| 			Err(evm::Error::BadJumpDestination { | ||||
| 			Err(vm::Error::BadJumpDestination { | ||||
| 				destination: jump | ||||
| 			}) | ||||
| 		} | ||||
| @ -617,7 +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 { | ||||
| 			instructions::DUP1...instructions::DUP16 => { | ||||
| 				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 | ||||
| 				}); | ||||
| 			} | ||||
|  | ||||
| @ -19,6 +19,7 @@ use util::*; | ||||
| use evmjit; | ||||
| use evm::{self, GasLeft}; | ||||
| use evm::CallType; | ||||
| use vm::{self, Vm}; | ||||
| 
 | ||||
| /// Should be used to convert jit types to ethcore
 | ||||
| trait FromJit<T>: Sized { | ||||
| @ -318,7 +319,7 @@ pub struct JitEvm { | ||||
| 	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> { | ||||
| 		// 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())) }; | ||||
| @ -370,8 +371,8 @@ impl evm::Evm for JitEvm { | ||||
| 				ext.suicide(&Address::from_jit(&context.suicide_refund_address())); | ||||
| 				Ok(GasLeft::Known(U256::from(context.gas_left()))) | ||||
| 			}, | ||||
| 			evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas), | ||||
| 			_err => Err(evm::Error::Internal) | ||||
| 			evmjit::ReturnCode::OutOfGas => Err(vm::Error::OutOfGas), | ||||
| 			_err => Err(vm::Error::Internal) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -24,11 +24,11 @@ extern crate ethjson; | ||||
| extern crate rlp; | ||||
| extern crate parity_wasm; | ||||
| extern crate wasm_utils; | ||||
| extern crate vm; | ||||
| 
 | ||||
| #[macro_use] | ||||
| extern crate lazy_static; | ||||
| 
 | ||||
| #[macro_use] | ||||
| extern crate log; | ||||
| 
 | ||||
| #[cfg(feature = "jit")] | ||||
| @ -37,14 +37,8 @@ extern crate evmjit; | ||||
| #[cfg(test)] | ||||
| extern crate rustc_hex; | ||||
| 
 | ||||
| pub mod action_params; | ||||
| pub mod call_type; | ||||
| pub mod env_info; | ||||
| pub mod ext; | ||||
| pub mod evm; | ||||
| pub mod interpreter; | ||||
| pub mod schedule; | ||||
| pub mod wasm; | ||||
| 
 | ||||
| #[macro_use] | ||||
| pub mod factory; | ||||
| @ -59,12 +53,12 @@ mod tests; | ||||
| #[cfg(all(feature="benches", test))] | ||||
| mod benches; | ||||
| 
 | ||||
| pub use self::action_params::ActionParams; | ||||
| pub use self::call_type::CallType; | ||||
| pub use self::env_info::EnvInfo; | ||||
| pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData}; | ||||
| pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; | ||||
| pub use vm::{ | ||||
|     Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext, | ||||
|     ContractCreateResult, MessageCallResult, CreateContractAddress, | ||||
|     GasLeft, ReturnData | ||||
| }; | ||||
| pub use self::evm::{Finalize, FinalizationResult, CostType}; | ||||
| pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; | ||||
| pub use self::vmtype::VMType; | ||||
| pub use self::factory::Factory; | ||||
| pub use self::schedule::{Schedule, CleanDustMode}; | ||||
|  | ||||
| @ -17,12 +17,12 @@ | ||||
| use std::fmt::Debug; | ||||
| use rustc_hex::FromHex; | ||||
| use util::*; | ||||
| use action_params::{ActionParams, ActionValue}; | ||||
| use env_info::EnvInfo; | ||||
| use call_type::CallType; | ||||
| use schedule::Schedule; | ||||
| use evm::{self, GasLeft, ReturnData}; | ||||
| use ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; | ||||
| use evm::{self, GasLeft}; | ||||
| use vm::{ | ||||
| 	self, CallType, Schedule, EnvInfo, ActionParams, ActionValue, | ||||
| 	ReturnData, Ext, ContractCreateResult, MessageCallResult, | ||||
| 	CreateContractAddress, | ||||
| }; | ||||
| use factory::Factory; | ||||
| use vmtype::VMType; | ||||
| 
 | ||||
| @ -66,7 +66,7 @@ pub struct FakeExt { | ||||
| } | ||||
| 
 | ||||
| // similar to the normal `finalize` function, but ignoring NeedsReturn.
 | ||||
| fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> { | ||||
| fn test_finalize(res: Result<GasLeft, vm::Error>) -> Result<U256, vm::Error> { | ||||
| 	match res { | ||||
| 		Ok(GasLeft::Known(gas)) => Ok(gas), | ||||
| 		Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented.
 | ||||
| @ -80,35 +80,29 @@ impl FakeExt { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Default for Schedule { | ||||
| 	fn default() -> Self { | ||||
| 		Schedule::new_frontier() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Ext for FakeExt { | ||||
| 	fn storage_at(&self, key: &H256) -> evm::Result<H256> { | ||||
| 	fn storage_at(&self, key: &H256) -> vm::Result<H256> { | ||||
| 		Ok(self.store.get(key).unwrap_or(&H256::new()).clone()) | ||||
| 	} | ||||
| 
 | ||||
| 	fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { | ||||
| 	fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { | ||||
| 		self.store.insert(key, value); | ||||
| 		Ok(()) | ||||
| 	} | ||||
| 
 | ||||
| 	fn exists(&self, address: &Address) -> evm::Result<bool> { | ||||
| 	fn exists(&self, address: &Address) -> vm::Result<bool> { | ||||
| 		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())) | ||||
| 	} | ||||
| 
 | ||||
| 	fn origin_balance(&self) -> evm::Result<U256> { | ||||
| 	fn origin_balance(&self) -> vm::Result<U256> { | ||||
| 		unimplemented!() | ||||
| 	} | ||||
| 
 | ||||
| 	fn balance(&self, address: &Address) -> evm::Result<U256> { | ||||
| 	fn balance(&self, address: &Address) -> vm::Result<U256> { | ||||
| 		Ok(self.balances[address]) | ||||
| 	} | ||||
| 
 | ||||
| @ -152,15 +146,15 @@ impl Ext for FakeExt { | ||||
| 		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()) | ||||
| 	} | ||||
| 
 | ||||
| 	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())) | ||||
| 	} | ||||
| 
 | ||||
| 	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 { | ||||
| 			topics: topics, | ||||
| 			data: data.to_vec() | ||||
| @ -168,11 +162,11 @@ impl Ext for FakeExt { | ||||
| 		Ok(()) | ||||
| 	} | ||||
| 
 | ||||
| 	fn ret(self, _gas: &U256, _data: &ReturnData) -> evm::Result<U256> { | ||||
| 	fn ret(self, _gas: &U256, _data: &ReturnData) -> vm::Result<U256> { | ||||
| 		unimplemented!(); | ||||
| 	} | ||||
| 
 | ||||
| 	fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { | ||||
| 	fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { | ||||
| 		self.suicides.insert(refund_address.clone()); | ||||
| 		Ok(()) | ||||
| 	} | ||||
| @ -211,7 +205,7 @@ fn test_stack_underflow() { | ||||
| 	}; | ||||
| 
 | ||||
| 	match err { | ||||
| 		evm::Error::StackUnderflow {wanted, on_stack, ..} => { | ||||
| 		vm::Error::StackUnderflow {wanted, on_stack, ..} => { | ||||
| 			assert_eq!(wanted, 2); | ||||
| 			assert_eq!(on_stack, 0); | ||||
| 		} | ||||
| @ -849,7 +843,7 @@ fn test_badinstruction_int() { | ||||
| 	}; | ||||
| 
 | ||||
| 	match err { | ||||
| 		evm::Error::BadInstruction { instruction: 0xaf } => (), | ||||
| 		vm::Error::BadInstruction { instruction: 0xaf } => (), | ||||
| 		_ => assert!(false, "Expected bad instruction") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -19,6 +19,7 @@ ethcore-io = { path = "../../util/io" } | ||||
| ethcore-ipc = { path = "../../ipc/rpc", optional = true } | ||||
| ethcore-devtools = { path = "../../devtools" } | ||||
| evm = { path = "../evm" } | ||||
| vm = { path = "../vm" } | ||||
| rlp = { path = "../../util/rlp" } | ||||
| time = "0.1" | ||||
| smallvec = "0.4" | ||||
|  | ||||
| @ -80,6 +80,7 @@ extern crate serde; | ||||
| extern crate smallvec; | ||||
| extern crate stats; | ||||
| extern crate time; | ||||
| extern crate vm; | ||||
| 
 | ||||
| #[cfg(feature = "ipc")] | ||||
| extern crate ethcore_ipc as ipc; | ||||
|  | ||||
| @ -24,7 +24,7 @@ use ethcore::engines::Engine; | ||||
| use ethcore::receipt::Receipt; | ||||
| use ethcore::state::{self, ProvedExecution}; | ||||
| use ethcore::transaction::SignedTransaction; | ||||
| use evm::env_info::EnvInfo; | ||||
| use vm::EnvInfo; | ||||
| 
 | ||||
| use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; | ||||
| 
 | ||||
|  | ||||
| @ -25,7 +25,7 @@ use util::{Bytes, Address, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RL | ||||
| use util::error::{Mismatch, OutOfBounds}; | ||||
| 
 | ||||
| use basic_types::{LogBloom, Seal}; | ||||
| use evm::env_info::{EnvInfo, LastHashes}; | ||||
| use vm::{EnvInfo, LastHashes}; | ||||
| use engines::Engine; | ||||
| use error::{Error, BlockError, TransactionError}; | ||||
| use factory::Factories; | ||||
| @ -667,7 +667,7 @@ mod tests { | ||||
| 	use tests::helpers::*; | ||||
| 	use super::*; | ||||
| 	use engines::Engine; | ||||
| 	use evm::env_info::LastHashes; | ||||
| 	use vm::LastHashes; | ||||
| 	use error::Error; | ||||
| 	use header::Header; | ||||
| 	use factory::Factories; | ||||
|  | ||||
| @ -36,9 +36,9 @@ impl From<&'static str> for Error { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Into<::evm::Error> for Error { | ||||
| 	fn into(self) -> ::evm::Error { | ||||
| 		::evm::Error::BuiltIn(self.0) | ||||
| impl Into<::vm::Error> for Error { | ||||
| 	fn into(self) -> ::vm::Error { | ||||
| 		::vm::Error::BuiltIn(self.0) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -42,9 +42,8 @@ use client::{ | ||||
| }; | ||||
| use encoded; | ||||
| use engines::{Engine, EpochTransition}; | ||||
| use evm::env_info::EnvInfo; | ||||
| use evm::env_info::LastHashes; | ||||
| use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; | ||||
| use vm::{EnvInfo, LastHashes}; | ||||
| use evm::{Factory as EvmFactory, Schedule}; | ||||
| use executive::{Executive, Executed, TransactOptions, contract_address}; | ||||
| use factory::Factories; | ||||
|  | ||||
| @ -23,7 +23,7 @@ use util::kvdb::{self, KeyValueDB}; | ||||
| use {state, state_db, client, executive, trace, db, spec}; | ||||
| use factory::Factories; | ||||
| use evm::{self, VMType}; | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::{self, ActionParams}; | ||||
| 
 | ||||
| /// EVM test Error.
 | ||||
| #[derive(Debug)] | ||||
| @ -31,7 +31,7 @@ pub enum EvmTestError { | ||||
| 	/// Trie integrity error.
 | ||||
| 	Trie(util::TrieError), | ||||
| 	/// EVM error.
 | ||||
| 	Evm(evm::Error), | ||||
| 	Evm(vm::Error), | ||||
| 	/// Initialization error.
 | ||||
| 	Initialization(::error::Error), | ||||
| 	/// Low-level database error.
 | ||||
|  | ||||
| @ -40,7 +40,7 @@ pub use types::pruning_info::PruningInfo; | ||||
| pub use types::call_analytics::CallAnalytics; | ||||
| 
 | ||||
| pub use executive::{Executed, Executive, TransactOptions}; | ||||
| pub use evm::env_info::{LastHashes, EnvInfo}; | ||||
| pub use vm::{LastHashes, EnvInfo}; | ||||
| 
 | ||||
| pub use error::{BlockImportError, TransactionImportError, TransactionImportResult}; | ||||
| pub use verification::VerifierType; | ||||
|  | ||||
| @ -36,7 +36,8 @@ use log_entry::LocalizedLogEntry; | ||||
| use receipt::{Receipt, LocalizedReceipt}; | ||||
| use blockchain::extras::BlockReceipts; | ||||
| use error::{ImportResult, Error as EthcoreError}; | ||||
| use evm::{Factory as EvmFactory, VMType, Schedule}; | ||||
| use evm::{Factory as EvmFactory, VMType}; | ||||
| use vm::Schedule; | ||||
| use miner::{Miner, MinerService, TransactionImportResult}; | ||||
| use spec::Spec; | ||||
| use types::basic_account::BasicAccount; | ||||
|  | ||||
| @ -19,7 +19,7 @@ use std::collections::BTreeMap; | ||||
| use block::{OpenBlock, SealedBlock, ClosedBlock}; | ||||
| use blockchain::TreeRoute; | ||||
| use encoded; | ||||
| use evm::env_info::LastHashes; | ||||
| use vm::LastHashes; | ||||
| use error::{ImportResult, CallError, Error as EthcoreError}; | ||||
| use error::{TransactionImportResult, BlockImportError}; | ||||
| use evm::{Factory as EvmFactory, Schedule}; | ||||
|  | ||||
| @ -514,7 +514,7 @@ impl Engine for AuthorityRound { | ||||
| 	fn on_new_block( | ||||
| 		&self, | ||||
| 		block: &mut ExecutedBlock, | ||||
| 		last_hashes: Arc<::evm::env_info::LastHashes>, | ||||
| 		last_hashes: Arc<::vm::LastHashes>, | ||||
| 		epoch_begin: bool, | ||||
| 	) -> Result<(), Error> { | ||||
| 		let parent_hash = block.fields().header.parent_hash().clone(); | ||||
|  | ||||
| @ -43,15 +43,13 @@ use account_provider::AccountProvider; | ||||
| use block::ExecutedBlock; | ||||
| use builtin::Builtin; | ||||
| use client::Client; | ||||
| use evm::env_info::{EnvInfo, LastHashes}; | ||||
| use vm::{EnvInfo, LastHashes, Schedule, CreateContractAddress}; | ||||
| use error::Error; | ||||
| use evm::Schedule; | ||||
| use header::{Header, BlockNumber}; | ||||
| use receipt::Receipt; | ||||
| use snapshot::SnapshotComponents; | ||||
| use spec::CommonParams; | ||||
| use transaction::{UnverifiedTransaction, SignedTransaction}; | ||||
| use evm::CreateContractAddress; | ||||
| 
 | ||||
| use ethkey::Signature; | ||||
| use util::*; | ||||
| @ -394,12 +392,10 @@ pub trait Engine : Sync + Send { | ||||
| /// Common engine utilities
 | ||||
| pub mod common { | ||||
| 	use block::ExecutedBlock; | ||||
| 	use evm::env_info::{EnvInfo, LastHashes}; | ||||
| 	use error::Error; | ||||
| 	use transaction::SYSTEM_ADDRESS; | ||||
| 	use executive::Executive; | ||||
| 	use evm::CallType; | ||||
| 	use evm::action_params::{ActionParams, ActionValue}; | ||||
| 	use vm::{CallType, ActionParams, ActionValue, EnvInfo, LastHashes}; | ||||
| 	use trace::{NoopTracer, NoopVMTracer}; | ||||
| 	use state::Substate; | ||||
| 
 | ||||
|  | ||||
| @ -299,7 +299,7 @@ impl ValidatorSet for ValidatorSafeContract { | ||||
| 			let (old_header, state_items) = decode_first_proof(&rlp)?; | ||||
| 			let old_hash = old_header.hash(); | ||||
| 
 | ||||
| 			let env_info = ::evm::env_info::EnvInfo { | ||||
| 			let env_info = ::vm::EnvInfo { | ||||
| 				number: old_header.number(), | ||||
| 				author: *old_header.author(), | ||||
| 				difficulty: *old_header.difficulty(), | ||||
|  | ||||
| @ -19,7 +19,7 @@ use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; | ||||
| use util::*; | ||||
| use block::*; | ||||
| use builtin::Builtin; | ||||
| use evm::env_info::EnvInfo; | ||||
| use vm::EnvInfo; | ||||
| use error::{BlockError, Error, TransactionError}; | ||||
| use header::{Header, BlockNumber}; | ||||
| use state::CleanupMode; | ||||
| @ -29,7 +29,7 @@ use engines::{self, Engine}; | ||||
| use evm::Schedule; | ||||
| use ethjson; | ||||
| use rlp::{self, UntrustedRlp}; | ||||
| use evm::env_info::LastHashes; | ||||
| use vm::LastHashes; | ||||
| 
 | ||||
| /// Parity tries to round block.gas_limit to multiple of this constant
 | ||||
| pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| //! Transaction execution format module.
 | ||||
| 
 | ||||
| use util::{Bytes, U256, Address, U512, trie}; | ||||
| use evm; | ||||
| use vm; | ||||
| use trace::{VMTrace, FlatTrace}; | ||||
| use log_entry::LogEntry; | ||||
| use state_diff::StateDiff; | ||||
| @ -28,7 +28,7 @@ use std::fmt; | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| pub struct Executed { | ||||
| 	/// True if the outer call/create resulted in an exceptional exit.
 | ||||
| 	pub exception: Option<evm::Error>, | ||||
| 	pub exception: Option<vm::Error>, | ||||
| 
 | ||||
| 	/// Gas paid up front for execution of transaction.
 | ||||
| 	pub gas: U256, | ||||
|  | ||||
| @ -16,13 +16,13 @@ | ||||
| 
 | ||||
| //! Transaction Execution environment.
 | ||||
| use util::*; | ||||
| use evm::action_params::{ActionParams, ActionValue}; | ||||
| use state::{Backend as StateBackend, State, Substate, CleanupMode}; | ||||
| use engines::Engine; | ||||
| use evm::CallType; | ||||
| use evm::env_info::EnvInfo; | ||||
| use vm::EnvInfo; | ||||
| use error::ExecutionError; | ||||
| use evm::{self, wasm, Factory, Ext, Finalize, CreateContractAddress, FinalizationResult, ReturnData, CleanDustMode}; | ||||
| use evm::{CallType, Factory, Finalize, FinalizationResult}; | ||||
| use vm::{self, Ext, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, ActionValue}; | ||||
| use wasm; | ||||
| use externalities::*; | ||||
| use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer}; | ||||
| use transaction::{Action, SignedTransaction}; | ||||
| @ -75,7 +75,7 @@ pub struct TransactOptions { | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
| 		Box::new( | ||||
| @ -269,7 +269,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 		output_policy: OutputPolicy, | ||||
| 		tracer: &mut T, | ||||
| 		vm_tracer: &mut V | ||||
| 	) -> evm::Result<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 static_call = params.call_type == CallType::StaticCall; | ||||
| @ -299,7 +299,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 	/// Calls contract function with given contract params.
 | ||||
| 	/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
 | ||||
| 	/// Modifies the substate and the output.
 | ||||
| 	/// Returns either gas_left or `evm::Error`.
 | ||||
| 	/// Returns either gas_left or `vm::Error`.
 | ||||
| 	pub fn call<T, V>( | ||||
| 		&mut self, | ||||
| 		params: ActionParams, | ||||
| @ -307,14 +307,14 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 		mut output: BytesRef, | ||||
| 		tracer: &mut T, | ||||
| 		vm_tracer: &mut V | ||||
| 	) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { | ||||
| 	) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { | ||||
| 
 | ||||
| 		trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); | ||||
| 		if (params.call_type == CallType::StaticCall || | ||||
| 				((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) && | ||||
| 				 self.static_flag)) | ||||
| 			&& params.value.value() > 0.into() { | ||||
| 			return Err(evm::Error::MutableCallInStaticContext); | ||||
| 			return Err(vm::Error::MutableCallInStaticContext); | ||||
| 		} | ||||
| 
 | ||||
| 		// backup used in case of running out of gas
 | ||||
| @ -344,7 +344,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 			if cost <= params.gas { | ||||
| 				if let Err(e) = builtin.execute(data, &mut output) { | ||||
| 					self.state.revert_to_checkpoint(); | ||||
| 					let evm_err: evm::evm::Error = e.into(); | ||||
| 					let evm_err: vm::Error = e.into(); | ||||
| 					tracer.trace_failed_call(trace_info, vec![], evm_err.clone().into()); | ||||
| 					Err(evm_err) | ||||
| 				} else { | ||||
| @ -371,9 +371,9 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 				// just drain the whole gas
 | ||||
| 				self.state.revert_to_checkpoint(); | ||||
| 
 | ||||
| 				tracer.trace_failed_call(trace_info, vec![], evm::Error::OutOfGas.into()); | ||||
| 				tracer.trace_failed_call(trace_info, vec![], vm::Error::OutOfGas.into()); | ||||
| 
 | ||||
| 				Err(evm::Error::OutOfGas) | ||||
| 				Err(vm::Error::OutOfGas) | ||||
| 			} | ||||
| 		} else { | ||||
| 			let trace_info = tracer.prepare_trace_call(¶ms); | ||||
| @ -432,17 +432,17 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 		substate: &mut Substate, | ||||
| 		tracer: &mut T, | ||||
| 		vm_tracer: &mut V, | ||||
| 	) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { | ||||
| 	) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { | ||||
| 
 | ||||
| 		let scheme = self.engine.create_address_scheme(self.info.number); | ||||
| 		if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(¶ms.address)? { | ||||
| 			return Err(evm::Error::OutOfGas); | ||||
| 			return Err(vm::Error::OutOfGas); | ||||
| 		} | ||||
| 
 | ||||
| 		if params.call_type == CallType::StaticCall || self.static_flag { | ||||
| 			let trace_info = tracer.prepare_trace_create(¶ms); | ||||
| 			tracer.trace_failed_create(trace_info, vec![], evm::Error::MutableCallInStaticContext.into()); | ||||
| 			return Err(evm::Error::MutableCallInStaticContext); | ||||
| 			tracer.trace_failed_create(trace_info, vec![], vm::Error::MutableCallInStaticContext.into()); | ||||
| 			return Err(vm::Error::MutableCallInStaticContext); | ||||
| 		} | ||||
| 
 | ||||
| 		// backup used in case of running out of gas
 | ||||
| @ -496,7 +496,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 		&mut self, | ||||
| 		t: &SignedTransaction, | ||||
| 		mut substate: Substate, | ||||
| 		result: evm::Result<(U256, ReturnData)>, | ||||
| 		result: vm::Result<(U256, ReturnData)>, | ||||
| 		output: Bytes, | ||||
| 		trace: Vec<FlatTrace>, | ||||
| 		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)?; | ||||
| 
 | ||||
| 		match result { | ||||
| 			Err(evm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), | ||||
| 			Err(vm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), | ||||
| 			Err(exception) => { | ||||
| 				Ok(Executed { | ||||
| 					exception: Some(exception), | ||||
| @ -572,20 +572,20 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn enact_result(&mut self, result: &evm::Result<FinalizationResult>, substate: &mut Substate, un_substate: Substate) { | ||||
| 	fn enact_result(&mut self, result: &vm::Result<FinalizationResult>, substate: &mut Substate, un_substate: Substate) { | ||||
| 		match *result { | ||||
| 			Err(evm::Error::OutOfGas) | ||||
| 				| Err(evm::Error::BadJumpDestination {..}) | ||||
| 				| Err(evm::Error::BadInstruction {.. }) | ||||
| 				| Err(evm::Error::StackUnderflow {..}) | ||||
| 				| Err(evm::Error::BuiltIn {..}) | ||||
| 				| Err(evm::Error::Wasm {..}) | ||||
| 				| Err(evm::Error::OutOfStack {..}) | ||||
| 				| Err(evm::Error::MutableCallInStaticContext) | ||||
| 			Err(vm::Error::OutOfGas) | ||||
| 				| Err(vm::Error::BadJumpDestination {..}) | ||||
| 				| Err(vm::Error::BadInstruction {.. }) | ||||
| 				| Err(vm::Error::StackUnderflow {..}) | ||||
| 				| Err(vm::Error::BuiltIn {..}) | ||||
| 				| Err(vm::Error::Wasm {..}) | ||||
| 				| Err(vm::Error::OutOfStack {..}) | ||||
| 				| Err(vm::Error::MutableCallInStaticContext) | ||||
| 				| Ok(FinalizationResult { apply_state: false, .. }) => { | ||||
| 					self.state.revert_to_checkpoint(); | ||||
| 			}, | ||||
| 			Ok(_) | Err(evm::Error::Internal(_)) => { | ||||
| 			Ok(_) | Err(vm::Error::Internal(_)) => { | ||||
| 				self.state.discard_checkpoint(); | ||||
| 				substate.accrue(un_substate); | ||||
| 			} | ||||
| @ -602,9 +602,8 @@ mod tests { | ||||
| 	use super::*; | ||||
| 	use util::{H256, U256, U512, Address, FromStr}; | ||||
| 	use util::bytes::BytesRef; | ||||
| 	use evm::action_params::{ActionParams, ActionValue}; | ||||
| 	use evm::env_info::EnvInfo; | ||||
| 	use evm::{Factory, VMType, CreateContractAddress}; | ||||
| 	use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; | ||||
| 	use evm::{Factory, VMType}; | ||||
| 	use error::ExecutionError; | ||||
| 	use state::{Substate, CleanupMode}; | ||||
| 	use tests::helpers::*; | ||||
| @ -613,8 +612,6 @@ mod tests { | ||||
| 	use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; | ||||
| 	use transaction::{Action, Transaction}; | ||||
| 
 | ||||
| 	use evm::CallType; | ||||
| 
 | ||||
| 	#[test] | ||||
| 	fn test_contract_address() { | ||||
| 		let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); | ||||
|  | ||||
| @ -16,13 +16,14 @@ | ||||
| 
 | ||||
| //! Transaction Execution environment.
 | ||||
| use util::*; | ||||
| use evm::action_params::{ActionParams, ActionValue}; | ||||
| use state::{Backend as StateBackend, State, Substate, CleanupMode}; | ||||
| use engines::Engine; | ||||
| use evm::env_info::EnvInfo; | ||||
| use executive::*; | ||||
| use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; | ||||
| use evm::CallType; | ||||
| use vm::{ | ||||
| 	self, ActionParams, ActionValue, EnvInfo, CallType, Schedule, | ||||
| 	Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, | ||||
| 	ReturnData | ||||
| }; | ||||
| use transaction::UNSIGNED_SENDER; | ||||
| use trace::{Tracer, VMTracer}; | ||||
| 
 | ||||
| @ -109,31 +110,31 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Externalities<'a, T, V, B, E> | ||||
| impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> | ||||
| 	where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized | ||||
| { | ||||
| 	fn storage_at(&self, key: &H256) -> evm::Result<H256> { | ||||
| 	fn storage_at(&self, key: &H256) -> vm::Result<H256> { | ||||
| 		self.state.storage_at(&self.origin_info.address, key).map_err(Into::into) | ||||
| 	} | ||||
| 
 | ||||
| 	fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { | ||||
| 	fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { | ||||
| 		if self.static_flag { | ||||
| 			Err(evm::Error::MutableCallInStaticContext) | ||||
| 			Err(vm::Error::MutableCallInStaticContext) | ||||
| 		} else { | ||||
| 			self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn exists(&self, address: &Address) -> evm::Result<bool> { | ||||
| 	fn exists(&self, address: &Address) -> vm::Result<bool> { | ||||
| 		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) | ||||
| 	} | ||||
| 
 | ||||
| 	fn origin_balance(&self) -> evm::Result<U256> { | ||||
| 	fn origin_balance(&self) -> vm::Result<U256> { | ||||
| 		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) | ||||
| 	} | ||||
| 
 | ||||
| @ -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![]))) | ||||
| 	} | ||||
| 
 | ||||
| 	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)) | ||||
| 	} | ||||
| 
 | ||||
| 	#[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 { | ||||
| 		let handle_copy = |to: &mut Option<&mut Bytes>| { | ||||
| 			to.as_mut().map(|b| **b = data.to_vec()); | ||||
| @ -307,7 +308,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> | ||||
| 				let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); | ||||
| 				if return_cost > *gas || data.len() > self.schedule.create_data_limit { | ||||
| 					return match self.schedule.exceptional_failed_code_deposit { | ||||
| 						true => Err(evm::Error::OutOfGas), | ||||
| 						true => Err(vm::Error::OutOfGas), | ||||
| 						false => Ok(*gas) | ||||
| 					} | ||||
| 				} | ||||
| @ -320,11 +321,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> evm::Result<()> { | ||||
| 	fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> { | ||||
| 		use log_entry::LogEntry; | ||||
| 
 | ||||
| 		if self.static_flag { | ||||
| 			return Err(evm::Error::MutableCallInStaticContext); | ||||
| 			return Err(vm::Error::MutableCallInStaticContext); | ||||
| 		} | ||||
| 
 | ||||
| 		let address = self.origin_info.address.clone(); | ||||
| @ -337,9 +338,9 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> | ||||
| 		Ok(()) | ||||
| 	} | ||||
| 
 | ||||
| 	fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { | ||||
| 	fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { | ||||
| 		if self.static_flag { | ||||
| 			return Err(evm::Error::MutableCallInStaticContext); | ||||
| 			return Err(vm::Error::MutableCallInStaticContext); | ||||
| 		} | ||||
| 
 | ||||
| 		let address = self.origin_info.address.clone(); | ||||
| @ -396,13 +397,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> | ||||
| mod tests { | ||||
| 	use util::*; | ||||
| 	use engines::Engine; | ||||
| 	use evm::env_info::EnvInfo; | ||||
| 	use evm::Ext; | ||||
| 	use evm::{EnvInfo, Ext, CallType}; | ||||
| 	use state::{State, Substate}; | ||||
| 	use tests::helpers::*; | ||||
| 	use super::*; | ||||
| 	use trace::{NoopTracer, NoopVMTracer}; | ||||
| 	use evm::CallType; | ||||
| 
 | ||||
| 	fn get_test_origin() -> OriginInfo { | ||||
| 		OriginInfo { | ||||
|  | ||||
| @ -15,15 +15,16 @@ | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| use super::test_common::*; | ||||
| use evm::action_params::ActionParams; | ||||
| use state::{Backend as StateBackend, State, Substate}; | ||||
| use executive::*; | ||||
| use engines::Engine; | ||||
| use evm::env_info::EnvInfo; | ||||
| use evm; | ||||
| use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; | ||||
| use evm::{VMType, Finalize}; | ||||
| use vm::{ | ||||
| 	self, ActionParams, CallType, Schedule, Ext, | ||||
| 	ContractCreateResult, EnvInfo, MessageCallResult, | ||||
| 	CreateContractAddress, ReturnData, | ||||
| }; | ||||
| use externalities::*; | ||||
| use evm::CallType; | ||||
| use tests::helpers::*; | ||||
| use ethjson; | ||||
| use trace::{Tracer, NoopTracer}; | ||||
| @ -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> | ||||
| 	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) | ||||
| 	} | ||||
| 
 | ||||
| 	fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { | ||||
| 	fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { | ||||
| 		self.ext.set_storage(key, value) | ||||
| 	} | ||||
| 
 | ||||
| 	fn exists(&self, address: &Address) -> evm::Result<bool> { | ||||
| 	fn exists(&self, address: &Address) -> vm::Result<bool> { | ||||
| 		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) | ||||
| 	} | ||||
| 
 | ||||
| 	fn balance(&self, address: &Address) -> evm::Result<U256> { | ||||
| 	fn balance(&self, address: &Address) -> vm::Result<U256> { | ||||
| 		self.ext.balance(address) | ||||
| 	} | ||||
| 
 | ||||
| 	fn origin_balance(&self) -> evm::Result<U256> { | ||||
| 	fn origin_balance(&self) -> vm::Result<U256> { | ||||
| 		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()) | ||||
| 	} | ||||
| 
 | ||||
| 	fn extcode(&self, address: &Address) -> evm::Result<Arc<Bytes>>  { | ||||
| 	fn extcode(&self, address: &Address) -> vm::Result<Arc<Bytes>>  { | ||||
| 		self.ext.extcode(address) | ||||
| 	} | ||||
| 
 | ||||
| 	fn extcodesize(&self, address: &Address) -> evm::Result<usize> { | ||||
| 	fn extcodesize(&self, address: &Address) -> vm::Result<usize> { | ||||
| 		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) | ||||
| 	} | ||||
| 
 | ||||
| 	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) | ||||
| 	} | ||||
| 
 | ||||
| 	fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { | ||||
| 	fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { | ||||
| 		self.ext.suicide(refund_address) | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -22,7 +22,7 @@ use spec::Spec; | ||||
| use ethjson; | ||||
| use ethjson::state::test::ForkSpec; | ||||
| use transaction::SignedTransaction; | ||||
| use evm::env_info::EnvInfo; | ||||
| use vm::EnvInfo; | ||||
| 
 | ||||
| lazy_static! { | ||||
| 	pub static ref FRONTIER: Spec = ethereum::new_frontier_test(); | ||||
|  | ||||
| @ -106,6 +106,8 @@ extern crate semver; | ||||
| extern crate stats; | ||||
| extern crate time; | ||||
| extern crate transient_hashmap; | ||||
| extern crate vm; | ||||
| extern crate wasm; | ||||
| 
 | ||||
| #[macro_use] | ||||
| extern crate log; | ||||
|  | ||||
| @ -20,10 +20,9 @@ use rustc_hex::FromHex; | ||||
| use super::genesis::Genesis; | ||||
| use super::seal::Generic as GenericSeal; | ||||
| 
 | ||||
| use evm::action_params::{ActionValue, ActionParams}; | ||||
| use builtin::Builtin; | ||||
| use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT}; | ||||
| use evm::env_info::EnvInfo; | ||||
| use vm::{EnvInfo, CallType, ActionValue, ActionParams}; | ||||
| use error::Error; | ||||
| use ethereum; | ||||
| use ethjson; | ||||
| @ -36,7 +35,6 @@ use state_db::StateDB; | ||||
| use state::{Backend, State, Substate}; | ||||
| use state::backend::Basic as BasicBackend; | ||||
| use trace::{NoopTracer, NoopVMTracer}; | ||||
| use evm::CallType; | ||||
| use util::*; | ||||
| 
 | ||||
| /// Parameters common to ethereum-like blockchains.
 | ||||
| @ -102,14 +100,14 @@ pub struct CommonParams { | ||||
| 
 | ||||
| impl CommonParams { | ||||
| 	/// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net.
 | ||||
| 	pub fn schedule(&self, block_number: u64) -> ::evm::Schedule { | ||||
| 		let mut schedule = ::evm::Schedule::new_post_eip150(usize::max_value(), true, true, true); | ||||
| 	pub fn schedule(&self, block_number: u64) -> ::vm::Schedule { | ||||
| 		let mut schedule = ::vm::Schedule::new_post_eip150(usize::max_value(), true, true, true); | ||||
| 		self.update_schedule(block_number, &mut schedule); | ||||
| 		schedule | ||||
| 	} | ||||
| 
 | ||||
| 	/// Apply common spec config parameters to the schedule.
 | ||||
|  	pub fn update_schedule(&self, block_number: u64, schedule: &mut ::evm::Schedule) { | ||||
|  	pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) { | ||||
| 		schedule.have_create2 = block_number >= self.eip86_transition; | ||||
| 		schedule.have_revert = block_number >= self.eip140_transition; | ||||
| 		schedule.have_static_call = block_number >= self.eip214_transition; | ||||
| @ -119,8 +117,8 @@ impl CommonParams { | ||||
| 		} | ||||
| 		if block_number >= self.dust_protection_transition { | ||||
| 			schedule.kill_dust = match self.remove_dust_contracts { | ||||
| 				true => ::evm::CleanDustMode::WithCodeAndStorage, | ||||
| 				false => ::evm::CleanDustMode::BasicOnly, | ||||
| 				true => ::vm::CleanDustMode::WithCodeAndStorage, | ||||
| 				false => ::vm::CleanDustMode::BasicOnly, | ||||
| 			}; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -24,7 +24,7 @@ use std::collections::hash_map::Entry; | ||||
| 
 | ||||
| use receipt::Receipt; | ||||
| use engines::Engine; | ||||
| use evm::env_info::EnvInfo; | ||||
| use vm::EnvInfo; | ||||
| use error::Error; | ||||
| use executive::{Executive, TransactOptions}; | ||||
| use factory::Factories; | ||||
| @ -982,7 +982,7 @@ mod tests { | ||||
| 	use ethkey::Secret; | ||||
| 	use util::{U256, H256, Address, Hashable}; | ||||
| 	use tests::helpers::*; | ||||
| 	use evm::env_info::EnvInfo; | ||||
| 	use vm::EnvInfo; | ||||
| 	use spec::*; | ||||
| 	use transaction::*; | ||||
| 	use ethcore_logger::init_log; | ||||
|  | ||||
| @ -1,9 +1,7 @@ | ||||
| //! Tests of EVM integration with transaction execution.
 | ||||
| 
 | ||||
| use evm::action_params::{ActionParams, ActionValue}; | ||||
| use evm::env_info::EnvInfo; | ||||
| use vm::{EnvInfo, ActionParams, ActionValue, CallType}; | ||||
| use evm::{Factory, VMType}; | ||||
| use evm::call_type::CallType; | ||||
| use executive::Executive; | ||||
| use state::Substate; | ||||
| use tests::helpers::*; | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| //! Simple executive tracer.
 | ||||
| 
 | ||||
| use util::{Bytes, Address, U256}; | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::ActionParams; | ||||
| use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide}; | ||||
| use trace::{Tracer, VMTracer, FlatTrace, TraceError}; | ||||
| 
 | ||||
|  | ||||
| @ -39,7 +39,7 @@ pub use self::types::filter::{Filter, AddressesFilter}; | ||||
| 
 | ||||
| use util::{Bytes, Address, U256, H256, DBTransaction}; | ||||
| use self::trace::{Call, Create}; | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::ActionParams; | ||||
| use header::BlockNumber; | ||||
| 
 | ||||
| /// This trait is used by executive to build traces.
 | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| //! Nonoperative tracer.
 | ||||
| 
 | ||||
| use util::{Bytes, Address, U256}; | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::ActionParams; | ||||
| use trace::{Tracer, VMTracer, FlatTrace, TraceError}; | ||||
| use trace::trace::{Call, Create, VMTrace}; | ||||
| 
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ | ||||
| 
 | ||||
| use std::fmt; | ||||
| use rlp::{Encodable, RlpStream, Decodable, DecoderError, UntrustedRlp}; | ||||
| use evm::Error as EvmError; | ||||
| use vm::Error as VmError; | ||||
| 
 | ||||
| /// Trace evm errors.
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| @ -45,24 +45,24 @@ pub enum Error { | ||||
| 	Wasm, | ||||
| } | ||||
| 
 | ||||
| impl<'a> From<&'a EvmError> for Error { | ||||
| 	fn from(e: &'a EvmError) -> Self { | ||||
| impl<'a> From<&'a VmError> for Error { | ||||
| 	fn from(e: &'a VmError) -> Self { | ||||
| 		match *e { | ||||
| 			EvmError::OutOfGas => Error::OutOfGas, | ||||
| 			EvmError::BadJumpDestination { .. } => Error::BadJumpDestination, | ||||
| 			EvmError::BadInstruction { .. } => Error::BadInstruction, | ||||
| 			EvmError::StackUnderflow { .. } => Error::StackUnderflow, | ||||
| 			EvmError::OutOfStack { .. } => Error::OutOfStack, | ||||
| 			EvmError::BuiltIn { .. } => Error::BuiltIn, | ||||
| 			EvmError::Wasm { .. } => Error::Wasm, | ||||
| 			EvmError::Internal(_) => Error::Internal, | ||||
| 			EvmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, | ||||
| 			VmError::OutOfGas => Error::OutOfGas, | ||||
| 			VmError::BadJumpDestination { .. } => Error::BadJumpDestination, | ||||
| 			VmError::BadInstruction { .. } => Error::BadInstruction, | ||||
| 			VmError::StackUnderflow { .. } => Error::StackUnderflow, | ||||
| 			VmError::OutOfStack { .. } => Error::OutOfStack, | ||||
| 			VmError::BuiltIn { .. } => Error::BuiltIn, | ||||
| 			VmError::Wasm { .. } => Error::Wasm, | ||||
| 			VmError::Internal(_) => Error::Internal, | ||||
| 			VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl From<EvmError> for Error { | ||||
| 	fn from(e: EvmError) -> Self { | ||||
| impl From<VmError> for Error { | ||||
| 	fn from(e: VmError) -> Self { | ||||
| 		Error::from(&e) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -21,7 +21,7 @@ use util::sha3::Hashable; | ||||
| use util::bloom::Bloomable; | ||||
| use rlp::*; | ||||
| 
 | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::ActionParams; | ||||
| use basic_types::LogBloom; | ||||
| use evm::CallType; | ||||
| use super::error::Error; | ||||
|  | ||||
							
								
								
									
										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 ethjson; | ||||
| 
 | ||||
| use {CallType}; | ||||
| use call_type::CallType; | ||||
| 
 | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
							
								
								
									
										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 env_info::EnvInfo; | ||||
| use schedule::Schedule; | ||||
| use evm::{self, ReturnData}; | ||||
| use return_data::ReturnData; | ||||
| use error::Result; | ||||
| 
 | ||||
| /// Result of externalities create function.
 | ||||
| pub enum ContractCreateResult { | ||||
| @ -56,22 +57,22 @@ pub enum CreateContractAddress { | ||||
| /// Externalities interface for EVMs
 | ||||
| pub trait Ext { | ||||
| 	/// 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.
 | ||||
| 	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.
 | ||||
| 	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).
 | ||||
| 	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.
 | ||||
| 	fn origin_balance(&self) -> evm::Result<U256>; | ||||
| 	fn origin_balance(&self) -> Result<U256>; | ||||
| 
 | ||||
| 	/// 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.
 | ||||
| 	fn blockhash(&mut self, number: &U256) -> H256; | ||||
| @ -99,21 +100,21 @@ pub trait Ext { | ||||
| 	) -> MessageCallResult; | ||||
| 
 | ||||
| 	/// 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
 | ||||
| 	fn extcodesize(&self, address: &Address) -> evm::Result<usize>; | ||||
| 	fn extcodesize(&self, address: &Address) -> Result<usize>; | ||||
| 
 | ||||
| 	/// 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.
 | ||||
| 	/// 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.
 | ||||
| 	/// 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.
 | ||||
| 	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] | ||||
| #[cfg(test)] | ||||
| fn schedule_evm_assumptions() { | ||||
| @ -260,3 +266,4 @@ fn schedule_evm_assumptions() { | ||||
| 	assert_eq!(s1.quad_coeff_div, 512); | ||||
| 	assert_eq!(s2.quad_coeff_div, 512); | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										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
 | ||||
| 
 | ||||
| extern crate vm; | ||||
| extern crate ethcore_util as util; | ||||
| #[macro_use] extern crate log; | ||||
| extern crate byteorder; | ||||
| extern crate parity_wasm; | ||||
| extern crate wasm_utils; | ||||
| 
 | ||||
| mod runtime; | ||||
| mod ptr; | ||||
| mod call_args; | ||||
| @ -30,10 +37,8 @@ const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024; | ||||
| 
 | ||||
| use parity_wasm::{interpreter, elements}; | ||||
| use parity_wasm::interpreter::ModuleInstanceInterface; | ||||
| use wasm_utils; | ||||
| 
 | ||||
| use evm::{self, GasLeft, ReturnData}; | ||||
| use action_params::ActionParams; | ||||
| use vm::{GasLeft, ReturnData, ActionParams}; | ||||
| use self::runtime::Runtime; | ||||
| 
 | ||||
| pub use self::runtime::Error as RuntimeError; | ||||
| @ -56,9 +61,9 @@ impl WasmInterpreter { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl evm::Evm for WasmInterpreter { | ||||
| impl vm::Vm for WasmInterpreter { | ||||
| 
 | ||||
| 	fn exec(&mut self, params: ActionParams, ext: &mut ::ext::Ext) -> evm::Result<GasLeft> { | ||||
| 	fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> { | ||||
| 		use parity_wasm::elements::Deserialize; | ||||
| 
 | ||||
| 		let code = params.code.expect("exec is only called on contract with code; qed"); | ||||
| @ -74,7 +79,7 @@ impl evm::Evm for WasmInterpreter { | ||||
| 			.expect("Linear memory to exist in wasm runtime"); | ||||
| 
 | ||||
| 		if params.gas > ::std::u64::MAX.into() { | ||||
| 			return Err(evm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned())); | ||||
| 			return Err(vm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned())); | ||||
| 		} | ||||
| 
 | ||||
| 		let mut runtime = Runtime::with_params( | ||||
| @ -90,7 +95,7 @@ impl evm::Evm for WasmInterpreter { | ||||
| 			elements::Module::deserialize( | ||||
| 				&mut cursor | ||||
| 			).map_err(|err| { | ||||
| 				evm::Error::Wasm(format!("Error deserializing contract code ({:?})", err)) | ||||
| 				vm::Error::Wasm(format!("Error deserializing contract code ({:?})", err)) | ||||
| 			})? | ||||
| 		); | ||||
| 
 | ||||
| @ -111,7 +116,7 @@ impl evm::Evm for WasmInterpreter { | ||||
| 					interpreter::env_native_module(env_instance, native_bindings(&mut runtime)) | ||||
| 						.map_err(|err| { | ||||
| 							// todo: prefer explicit panic here also?
 | ||||
| 							evm::Error::Wasm(format!("Error instantiating native bindings: {:?}", err)) | ||||
| 							vm::Error::Wasm(format!("Error instantiating native bindings: {:?}", err)) | ||||
| 						})? | ||||
| 				) | ||||
| 			).add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32)); | ||||
| @ -119,13 +124,13 @@ impl evm::Evm for WasmInterpreter { | ||||
| 			let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals)) | ||||
| 				.map_err(|err| { | ||||
| 					trace!(target: "wasm", "Error adding contract module: {:?}", err); | ||||
| 					evm::Error::from(RuntimeError::Interpreter(err)) | ||||
| 					vm::Error::from(RuntimeError::Interpreter(err)) | ||||
| 				})?; | ||||
| 
 | ||||
| 			module_instance.execute_export("_call", execution_params) | ||||
| 				.map_err(|err| { | ||||
| 					trace!(target: "wasm", "Error executing contract: {:?}", err); | ||||
| 					evm::Error::from(RuntimeError::Interpreter(err)) | ||||
| 					vm::Error::from(RuntimeError::Interpreter(err)) | ||||
| 				})?; | ||||
| 		} | ||||
| 
 | ||||
| @ -157,3 +162,9 @@ fn native_bindings<'a>(runtime: &'a mut Runtime) -> interpreter::UserFunctions<' | ||||
| 		functions: ::std::borrow::Cow::from(env::SIGNATURES), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl From<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 ext; | ||||
| 
 | ||||
| use vm; | ||||
| use parity_wasm::interpreter; | ||||
| use util::{Address, H256, U256}; | ||||
| 
 | ||||
| @ -62,14 +61,14 @@ pub struct Runtime<'a> { | ||||
| 	gas_counter: u64, | ||||
| 	gas_limit: u64, | ||||
| 	dynamic_top: u32, | ||||
| 	ext: &'a mut ext::Ext, | ||||
| 	ext: &'a mut vm::Ext, | ||||
| 	memory: Arc<interpreter::MemoryInstance>, | ||||
| } | ||||
| 
 | ||||
| impl<'a> Runtime<'a> { | ||||
| 	/// New runtime for wasm contract with specified params
 | ||||
| 	pub fn with_params<'b>( | ||||
| 		ext: &'b mut ext::Ext, | ||||
| 		ext: &'b mut vm::Ext, | ||||
| 		memory: Arc<interpreter::MemoryInstance>, | ||||
| 		stack_space: u32, | ||||
| 		gas_limit: u64, | ||||
| @ -153,14 +152,14 @@ impl<'a> Runtime<'a> { | ||||
| 			.map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? | ||||
| 			.into(); | ||||
| 
 | ||||
| 		match self.ext.create(&gas_left, &endowment, &code, ext::CreateContractAddress::FromSenderAndCodeHash) { | ||||
| 			ext::ContractCreateResult::Created(address, gas_left) => { | ||||
| 		match self.ext.create(&gas_left, &endowment, &code, vm::CreateContractAddress::FromSenderAndCodeHash) { | ||||
| 			vm::ContractCreateResult::Created(address, gas_left) => { | ||||
| 				self.memory.set(result_ptr, &*address)?; | ||||
| 				self.gas_counter = self.gas_limit - gas_left.low_u64(); | ||||
| 				trace!(target: "wasm", "runtime: create contract success (@{:?})", address); | ||||
| 				Ok(Some(0i32.into())) | ||||
| 			}, | ||||
| 			ext::ContractCreateResult::Failed => { | ||||
| 			vm::ContractCreateResult::Failed => { | ||||
| 				trace!(target: "wasm", "runtime: create contract fail"); | ||||
| 				Ok(Some((-1i32).into())) | ||||
| 			} | ||||
| @ -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 { | ||||
| 		Ok(GasLeft::Known(gas)) => Ok(gas), | ||||
| 		Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented.
 | ||||
| @ -31,7 +31,7 @@ extern crate rustc_hex; | ||||
| use self::test::{Bencher, black_box}; | ||||
| 
 | ||||
| use evm::run_vm; | ||||
| use ethcore::evm::action_params::ActionParams; | ||||
| use ethcore::vm::ActionParams; | ||||
| use ethcore_util::U256; | ||||
| use rustc_hex::FromHex; | ||||
| 
 | ||||
|  | ||||
| @ -34,7 +34,7 @@ use docopt::Docopt; | ||||
| use rustc_hex::FromHex; | ||||
| use util::{U256, Bytes, Address}; | ||||
| use ethcore::spec; | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::ActionParams; | ||||
| 
 | ||||
| mod vm; | ||||
| mod display; | ||||
|  | ||||
| @ -20,7 +20,7 @@ use std::time::{Instant, Duration}; | ||||
| use util::U256; | ||||
| use ethcore::{trace, spec}; | ||||
| use ethcore::client::{EvmTestClient, EvmTestError}; | ||||
| use evm::action_params::ActionParams; | ||||
| use vm::ActionParams; | ||||
| 
 | ||||
| /// VM execution informant
 | ||||
| pub trait Informant: trace::VMTracer { | ||||
|  | ||||
| @ -46,7 +46,7 @@ ethjson = { path = "../json" } | ||||
| ethcore-devtools = { path = "../devtools" } | ||||
| ethcore-light = { path = "../ethcore/light" } | ||||
| ethcore-logger = { path = "../logger" } | ||||
| evm = { path = "../ethcore/evm" } | ||||
| vm = { path = "../ethcore/vm" } | ||||
| parity-updater = { path = "../updater" } | ||||
| parity-reactor = { path = "../util/reactor" } | ||||
| rlp = { path = "../util/rlp" } | ||||
|  | ||||
| @ -52,7 +52,7 @@ extern crate ethkey; | ||||
| extern crate ethstore; | ||||
| extern crate ethsync; | ||||
| extern crate ethcore_logger; | ||||
| extern crate evm; | ||||
| extern crate vm; | ||||
| extern crate fetch; | ||||
| extern crate parity_reactor; | ||||
| extern crate parity_updater as updater; | ||||
|  | ||||
| @ -327,7 +327,7 @@ struct ExecuteParams { | ||||
| 	from: Address, | ||||
| 	tx: EthTransaction, | ||||
| 	hdr: encoded::Header, | ||||
| 	env_info: ::evm::env_info::EnvInfo, | ||||
| 	env_info: ::vm::EnvInfo, | ||||
| 	engine: Arc<::ethcore::engines::Engine>, | ||||
| 	on_demand: Arc<OnDemand>, | ||||
| 	sync: Arc<LightSync>, | ||||
|  | ||||
| @ -21,7 +21,7 @@ use ethcore::trace::trace::{Action, Res, Call}; | ||||
| use ethcore::trace::LocalizedTrace; | ||||
| use ethcore::client::TestBlockChainClient; | ||||
| 
 | ||||
| use evm::CallType; | ||||
| use vm::CallType; | ||||
| 
 | ||||
| use jsonrpc_core::IoHandler; | ||||
| use v1::tests::helpers::{TestMinerService}; | ||||
|  | ||||
| @ -22,7 +22,7 @@ use ethcore::trace as et; | ||||
| use ethcore::state_diff; | ||||
| use ethcore::account_diff; | ||||
| use ethcore::client::Executed; | ||||
| use evm; | ||||
| use vm; | ||||
| use v1::types::{Bytes, H160, H256, U256}; | ||||
| 
 | ||||
| #[derive(Debug, Serialize)] | ||||
| @ -256,14 +256,14 @@ pub enum CallType { | ||||
| 	StaticCall, | ||||
| } | ||||
| 
 | ||||
| impl From<evm::CallType> for CallType { | ||||
| 	fn from(c: evm::CallType) -> Self { | ||||
| impl From<vm::CallType> for CallType { | ||||
| 	fn from(c: vm::CallType) -> Self { | ||||
| 		match c { | ||||
| 			evm::CallType::None => CallType::None, | ||||
| 			evm::CallType::Call => CallType::Call, | ||||
| 			evm::CallType::CallCode => CallType::CallCode, | ||||
| 			evm::CallType::DelegateCall => CallType::DelegateCall, | ||||
| 			evm::CallType::StaticCall => CallType::StaticCall, | ||||
| 			vm::CallType::None => CallType::None, | ||||
| 			vm::CallType::Call => CallType::Call, | ||||
| 			vm::CallType::CallCode => CallType::CallCode, | ||||
| 			vm::CallType::DelegateCall => CallType::DelegateCall, | ||||
| 			vm::CallType::StaticCall => CallType::StaticCall, | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user