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