diff --git a/Cargo.lock b/Cargo.lock index 7d164149b..b330851e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,6 +253,16 @@ dependencies = [ "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "common-types" +version = "0.1.0" +dependencies = [ + "ethcore-util 1.7.0", + "ethjson 0.1.0", + "rlp 0.2.0", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "conv" version = "0.3.3" @@ -436,6 +446,7 @@ dependencies = [ "bn 0.4.4 (git+https://github.com/paritytech/bn)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "common-types 0.1.0", "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -452,7 +463,7 @@ dependencies = [ "ethjson 0.1.0", "ethkey 0.2.0", "ethstore 0.1.0", - "evmjit 1.7.0", + "evm 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "hardware-wallet 1.7.0", "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", @@ -464,7 +475,6 @@ dependencies = [ "native-contracts 0.1.0", "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.0", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -474,7 +484,6 @@ 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)", - "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", ] [[package]] @@ -585,6 +594,7 @@ dependencies = [ "ethcore-ipc-codegen 1.7.0", "ethcore-network 1.7.0", "ethcore-util 1.7.0", + "evm 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -839,6 +849,24 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "evm" +version = "0.1.0" +dependencies = [ + "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "common-types 0.1.0", + "ethcore-util 1.7.0", + "ethjson 0.1.0", + "evmjit 1.7.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)", + "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)", + "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", +] + [[package]] name = "evmbin" version = "0.1.0" @@ -846,6 +874,7 @@ dependencies = [ "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.7.0", "ethcore-util 1.7.0", + "evm 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1850,6 +1879,7 @@ dependencies = [ "ethkey 0.2.0", "ethstore 0.1.0", "ethsync 1.7.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.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 90baf5c9b..2ec89c005 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -16,6 +16,7 @@ bloomchain = "0.1" bn = { git = "https://github.com/paritytech/bn" } byteorder = "1.0" clippy = { version = "0.0.103", optional = true} +common-types = { path = "types" } crossbeam = "0.2.9" env_logger = "0.4" ethabi = "2.0" @@ -31,7 +32,7 @@ ethcore-util = { path = "../util" } ethjson = { path = "../json" } ethkey = { path = "../ethkey" } ethstore = { path = "../ethstore" } -evmjit = { path = "../evmjit", optional = true } +evm = { path = "evm" } futures = "0.1" hardware-wallet = { path = "../hw" } hyper = { git = "https://github.com/paritytech/hyper", default-features = false } @@ -52,14 +53,12 @@ semver = "0.6" stats = { path = "../util/stats" } time = "0.1" transient-hashmap = "0.4" -parity-wasm = "0.12" -wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } [dev-dependencies] native-contracts = { path = "native_contracts", features = ["test_contracts"] } [features] -jit = ["evmjit"] +jit = ["evm/jit"] evm-debug = ["slow-blocks"] evm-debug-tests = ["evm-debug"] slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms diff --git a/ethcore/build.rs b/ethcore/build.rs index f45181b5c..8fe38e757 100644 --- a/ethcore/build.rs +++ b/ethcore/build.rs @@ -17,7 +17,6 @@ extern crate ethcore_ipc_codegen; fn main() { - ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap(); ethcore_ipc_codegen::derive_ipc_cond("src/client/traits.rs", cfg!(feature="ipc")).unwrap(); ethcore_ipc_codegen::derive_ipc_cond("src/snapshot/snapshot_service_trait.rs", cfg!(feature="ipc")).unwrap(); ethcore_ipc_codegen::derive_ipc_cond("src/client/chain_notify.rs", cfg!(feature="ipc")).unwrap(); diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml new file mode 100644 index 000000000..b48dd2346 --- /dev/null +++ b/ethcore/evm/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "evm" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +bit-set = "0.4" +byteorder = "1.0" +common-types = { path = "../types" } +ethcore-util = { path = "../../util" } +evmjit = { path = "../../evmjit", optional = true } +ethjson = { path = "../../json" } +lazy_static = "0.2" +log = "0.3" +rlp = { path = "../../util/rlp" } +parity-wasm = "0.12" +wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } + +[dev-dependencies] +rustc-hex = "1.0" + +[features] +jit = ["evmjit"] diff --git a/ethcore/src/action_params.rs b/ethcore/evm/src/action_params.rs similarity index 99% rename from ethcore/src/action_params.rs rename to ethcore/evm/src/action_params.rs index 2ec71c1f3..62bb7fa5b 100644 --- a/ethcore/src/action_params.rs +++ b/ethcore/evm/src/action_params.rs @@ -19,7 +19,8 @@ use util::{Address, Bytes, U256}; use util::hash::{H256}; use util::sha3::{Hashable, SHA3_EMPTY}; use ethjson; -use types::executed::CallType; + +use {CallType}; use std::sync::Arc; diff --git a/ethcore/src/evm/benches/mod.rs b/ethcore/evm/src/benches/mod.rs similarity index 98% rename from ethcore/src/evm/benches/mod.rs rename to ethcore/evm/src/benches/mod.rs index a085cf054..4463696d6 100644 --- a/ethcore/src/evm/benches/mod.rs +++ b/ethcore/evm/src/benches/mod.rs @@ -25,7 +25,7 @@ extern crate test; use self::test::{Bencher, black_box}; use util::*; -use action_params::ActionParams; +use evm::action_params::ActionParams; use evm::{self, Factory, VMType}; use evm::tests::FakeExt; diff --git a/ethcore/evm/src/call_type.rs b/ethcore/evm/src/call_type.rs new file mode 100644 index 000000000..08a004053 --- /dev/null +++ b/ethcore/evm/src/call_type.rs @@ -0,0 +1,70 @@ +//! EVM call types. + +use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; + +/// The type of the call-like instruction. +#[derive(Debug, PartialEq, Clone)] +pub enum CallType { + /// Not a CALL. + None, + /// CALL. + Call, + /// CALLCODE. + CallCode, + /// DELEGATECALL. + DelegateCall, + /// STATICCALL + StaticCall, +} + +impl Encodable for CallType { + fn rlp_append(&self, s: &mut RlpStream) { + let v = match *self { + CallType::None => 0u32, + CallType::Call => 1, + CallType::CallCode => 2, + CallType::DelegateCall => 3, + CallType::StaticCall => 4, + }; + Encodable::rlp_append(&v, s); + } +} + +impl Decodable for CallType { + fn decode(rlp: &UntrustedRlp) -> Result { + rlp.as_val().and_then(|v| Ok(match v { + 0u32 => CallType::None, + 1 => CallType::Call, + 2 => CallType::CallCode, + 3 => CallType::DelegateCall, + 4 => CallType::StaticCall, + _ => return Err(DecoderError::Custom("Invalid value of CallType item")), + })) + } +} + +#[cfg(test)] +mod tests { + use rlp::*; + use super::CallType; + + #[test] + fn encode_call_type() { + let ct = CallType::Call; + + let mut s = RlpStream::new_list(2); + s.append(&ct); + assert!(!s.is_finished(), "List shouldn't finished yet"); + s.append(&ct); + assert!(s.is_finished(), "List should be finished now"); + s.out(); + } + + #[test] + fn should_encode_and_decode_call_type() { + let original = CallType::Call; + let encoded = encode(&original); + let decoded = decode(&encoded); + assert_eq!(original, decoded); + } +} diff --git a/ethcore/src/env_info.rs b/ethcore/evm/src/env_info.rs similarity index 98% rename from ethcore/src/env_info.rs rename to ethcore/evm/src/env_info.rs index 4f6a330b0..8634d9c75 100644 --- a/ethcore/src/env_info.rs +++ b/ethcore/evm/src/env_info.rs @@ -19,7 +19,7 @@ use std::cmp; use std::sync::Arc; use util::{U256, Address, H256, Hashable}; -use header::BlockNumber; +use types::BlockNumber; use ethjson; /// Simple vector of hashes, should be at most 256 items large, can be smaller if being used @@ -82,7 +82,7 @@ mod tests { use ethjson; #[test] - fn it_serializes_form_json() { + fn it_serializes_from_json() { let env_info = EnvInfo::from(ethjson::vm::Env { author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()), number: ethjson::uint::Uint(U256::from(1_112_339)), diff --git a/ethcore/src/evm/evm.rs b/ethcore/evm/src/evm.rs similarity index 98% rename from ethcore/src/evm/evm.rs rename to ethcore/evm/src/evm.rs index 7a1b9952d..c27caf8b3 100644 --- a/ethcore/src/evm/evm.rs +++ b/ethcore/evm/src/evm.rs @@ -19,8 +19,8 @@ use std::{ops, cmp, fmt}; use util::{U128, U256, U512, trie}; use action_params::ActionParams; -use evm::Ext; -use builtin; +use {Ext}; + use super::wasm; /// Evm errors. @@ -77,12 +77,6 @@ impl From> for Error { } } -impl From for Error { - fn from(err: builtin::Error) -> Self { - Error::BuiltIn(err.0) - } -} - impl From for Error { fn from(err: wasm::RuntimeError) -> Self { Error::Wasm(format!("Runtime error: {:?}", err)) @@ -109,7 +103,6 @@ impl fmt::Display for Error { /// A specialized version of Result over EVM errors. pub type Result = ::std::result::Result; - /// Return data buffer. Holds memory from a previous call and a slice into that memory. #[derive(Debug)] pub struct ReturnData { diff --git a/ethcore/src/evm/ext.rs b/ethcore/evm/src/ext.rs similarity index 97% rename from ethcore/src/evm/ext.rs rename to ethcore/evm/src/ext.rs index 3a8dafc37..1c3ddb317 100644 --- a/ethcore/src/evm/ext.rs +++ b/ethcore/evm/src/ext.rs @@ -17,9 +17,10 @@ //! Interface for Evm externalities. use util::*; -use evm::{self, Schedule, ReturnData}; -use env_info::*; -use types::executed::CallType; +use call_type::CallType; +use env_info::EnvInfo; +use schedule::Schedule; +use evm::{self, ReturnData}; /// Result of externalities create function. pub enum ContractCreateResult { diff --git a/ethcore/src/evm/factory.rs b/ethcore/evm/src/factory.rs similarity index 100% rename from ethcore/src/evm/factory.rs rename to ethcore/evm/src/factory.rs diff --git a/ethcore/src/evm/instructions.rs b/ethcore/evm/src/instructions.rs similarity index 100% rename from ethcore/src/evm/instructions.rs rename to ethcore/evm/src/instructions.rs diff --git a/ethcore/src/evm/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs similarity index 93% rename from ethcore/src/evm/interpreter/gasometer.rs rename to ethcore/evm/src/interpreter/gasometer.rs index 426b8ffd0..c2dcf5412 100644 --- a/ethcore/src/evm/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -16,10 +16,11 @@ use util::*; use super::u256_to_address; -use evm::{self, CostType}; -use evm::instructions::{self, Instruction, InstructionInfo}; -use evm::interpreter::stack::Stack; -use evm::schedule::Schedule; + +use {evm, ext}; +use instructions::{self, Instruction, InstructionInfo}; +use interpreter::stack::Stack; +use schedule::Schedule; macro_rules! overflowing { ($x: expr) => {{ @@ -30,26 +31,26 @@ macro_rules! overflowing { } #[cfg_attr(feature="dev", allow(enum_variant_names))] -enum Request { +enum Request { Gas(Cost), GasMem(Cost, Cost), GasMemProvide(Cost, Cost, Option), GasMemCopy(Cost, Cost, Cost) } -pub struct InstructionRequirements { +pub struct InstructionRequirements { pub gas_cost: Cost, pub provide_gas: Option, pub memory_total_gas: Cost, pub memory_required_size: usize, } -pub struct Gasometer { +pub struct Gasometer { pub current_gas: Gas, pub current_mem_gas: Gas, } -impl Gasometer { +impl Gasometer { pub fn new(current_gas: Gas) -> Self { Gasometer { @@ -106,7 +107,7 @@ impl Gasometer { /// it will be the amount of gas that the current context provides to the child context. pub fn requirements( &mut self, - ext: &evm::Ext, + ext: &ext::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack, @@ -290,7 +291,7 @@ impl Gasometer { }) } - fn mem_gas_cost(&self, schedule: &evm::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) -> evm::Result<(Gas, Gas, usize)> { let gas_for_mem = |mem_size: Gas| { let s = mem_size >> 5; // s * memory_gas + s * s / quad_coeff_div @@ -318,12 +319,12 @@ impl Gasometer { #[inline] -fn mem_needed_const(mem: &U256, add: usize) -> evm::Result { +fn mem_needed_const(mem: &U256, add: usize) -> evm::Result { Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add)))) } #[inline] -fn mem_needed(offset: &U256, size: &U256) -> evm::Result { +fn mem_needed(offset: &U256, size: &U256) -> evm::Result { if size.is_zero() { return Ok(Gas::from(0)); } @@ -332,7 +333,7 @@ fn mem_needed(offset: &U256, size: &U256) -> evm::Result { } #[inline] -fn add_gas_usize(value: Gas, num: usize) -> (Gas, bool) { +fn add_gas_usize(value: Gas, num: usize) -> (Gas, bool) { value.overflow_add(Gas::from(num)) } @@ -340,7 +341,7 @@ fn add_gas_usize(value: Gas, num: usize) -> (Gas, bool) { fn test_mem_gas_cost() { // given let gasometer = Gasometer::::new(U256::zero()); - let schedule = evm::Schedule::default(); + let schedule = Schedule::default(); let current_mem_size = 5; let mem_size = !U256::zero(); @@ -357,7 +358,7 @@ fn test_mem_gas_cost() { fn test_calculate_mem_cost() { // given let gasometer = Gasometer::::new(0); - let schedule = evm::Schedule::default(); + let schedule = Schedule::default(); let current_mem_size = 0; let mem_size = 5; diff --git a/ethcore/src/evm/interpreter/informant.rs b/ethcore/evm/src/interpreter/informant.rs similarity index 100% rename from ethcore/src/evm/interpreter/informant.rs rename to ethcore/evm/src/interpreter/informant.rs diff --git a/ethcore/src/evm/interpreter/memory.rs b/ethcore/evm/src/interpreter/memory.rs similarity index 99% rename from ethcore/src/evm/interpreter/memory.rs rename to ethcore/evm/src/interpreter/memory.rs index 00f7a7d79..017b5777d 100644 --- a/ethcore/src/evm/interpreter/memory.rs +++ b/ethcore/evm/src/interpreter/memory.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use util::U256; -use evm::ReturnData; +use {ReturnData}; const MAX_RETURN_WASTE_BYTES: usize = 16384; diff --git a/ethcore/src/evm/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs similarity index 98% rename from ethcore/src/evm/interpreter/mod.rs rename to ethcore/evm/src/interpreter/mod.rs index 304d93b54..885557dd3 100644 --- a/ethcore/src/evm/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -30,9 +30,10 @@ pub use self::shared_cache::SharedCache; use std::marker::PhantomData; use action_params::{ActionParams, ActionValue}; -use types::executed::CallType; -use evm::instructions::{self, Instruction, InstructionInfo}; -use evm::{self, MessageCallResult, ContractCreateResult, GasLeft, CostType, CreateContractAddress, ReturnData}; +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,7 +108,7 @@ pub struct Interpreter { } impl evm::Evm for Interpreter { - fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result { + fn exec(&mut self, params: ActionParams, ext: &mut ext::Ext) -> evm::Result { self.mem.clear(); let mut informant = informant::EvmInformant::new(ext.depth()); @@ -204,7 +205,7 @@ impl Interpreter { } } - fn verify_instruction(&self, ext: &evm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack) -> evm::Result<()> { + fn verify_instruction(&self, ext: &ext::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack) -> evm::Result<()> { let schedule = ext.schedule(); if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) || @@ -270,7 +271,7 @@ impl Interpreter { &mut self, gas: Cost, params: &ActionParams, - ext: &mut evm::Ext, + ext: &mut ext::Ext, instruction: Instruction, code: &mut CodeReader, stack: &mut Stack, diff --git a/ethcore/src/evm/interpreter/shared_cache.rs b/ethcore/evm/src/interpreter/shared_cache.rs similarity index 100% rename from ethcore/src/evm/interpreter/shared_cache.rs rename to ethcore/evm/src/interpreter/shared_cache.rs diff --git a/ethcore/src/evm/interpreter/stack.rs b/ethcore/evm/src/interpreter/stack.rs similarity index 99% rename from ethcore/src/evm/interpreter/stack.rs rename to ethcore/evm/src/interpreter/stack.rs index 39af798ba..cbe40fb67 100644 --- a/ethcore/src/evm/interpreter/stack.rs +++ b/ethcore/evm/src/interpreter/stack.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use std::fmt; -use evm::instructions; +use instructions; /// Stack trait with VM-friendly API pub trait Stack { diff --git a/ethcore/src/evm/jit.rs b/ethcore/evm/src/jit.rs similarity index 99% rename from ethcore/src/evm/jit.rs rename to ethcore/evm/src/jit.rs index b624e6ec7..f27e9b5d3 100644 --- a/ethcore/src/evm/jit.rs +++ b/ethcore/evm/src/jit.rs @@ -18,7 +18,7 @@ use util::*; use evmjit; use evm::{self, GasLeft}; -use types::executed::CallType; +use evm::CallType; /// Should be used to convert jit types to ethcore trait FromJit: Sized { diff --git a/ethcore/src/evm/mod.rs b/ethcore/evm/src/lib.rs similarity index 71% rename from ethcore/src/evm/mod.rs rename to ethcore/evm/src/lib.rs index db334ffa0..fa4d12315 100644 --- a/ethcore/src/evm/mod.rs +++ b/ethcore/evm/src/lib.rs @@ -16,16 +16,41 @@ //! Ethereum virtual machine. +extern crate byteorder; +extern crate bit_set; +extern crate common_types as types; +extern crate ethcore_util as util; +extern crate ethjson; +extern crate rlp; +extern crate parity_wasm; +extern crate wasm_utils; + +#[macro_use] +extern crate lazy_static; + +#[macro_use] +extern crate log; + +#[cfg(feature = "jit")] +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; -#[macro_use] -pub mod factory; pub mod schedule; pub mod wasm; +#[macro_use] +pub mod factory; mod vmtype; mod instructions; + #[cfg(feature = "jit" )] mod jit; @@ -34,10 +59,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 self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; pub use self::vmtype::VMType; pub use self::factory::Factory; pub use self::schedule::{Schedule, CleanDustMode}; -pub use types::executed::CallType; diff --git a/ethcore/src/evm/schedule.rs b/ethcore/evm/src/schedule.rs similarity index 89% rename from ethcore/src/evm/schedule.rs rename to ethcore/evm/src/schedule.rs index 8971aa16c..a8dd09645 100644 --- a/ethcore/src/evm/schedule.rs +++ b/ethcore/evm/src/schedule.rs @@ -15,7 +15,6 @@ // along with Parity. If not, see . //! Cost schedule and other parameterisations for the EVM. -use spec::CommonParams; /// Definition of the cost schedule and other parameterisations for the EVM. pub struct Schedule { @@ -185,26 +184,6 @@ impl Schedule { } } - /// Schedule for the post-EIP-150-era of the Ethereum main net. - pub fn from_params(block_number: u64, params: &CommonParams) -> Schedule { - let mut schedule = Schedule::new_post_eip150(usize::max_value(), true, true, true); - schedule.apply_params(block_number, params); - schedule - } - - /// Apply common spec config parameters to the schedule. - pub fn apply_params(&mut self, block_number: u64, params: &CommonParams) { - self.have_create2 = block_number >= params.eip86_transition; - self.have_revert = block_number >= params.eip140_transition; - self.have_static_call = block_number >= params.eip214_transition; - if block_number >= params.eip210_transition { - self.blockhash_gas = 350; - } - if block_number >= params.dust_protection_transition { - self.kill_dust = if params.remove_dust_contracts { CleanDustMode::WithCodeAndStorage } else { CleanDustMode::BasicOnly }; - } - } - /// Schedule for the Metropolis of the Ethereum main net. pub fn new_metropolis() -> Schedule { let mut schedule = Self::new_post_eip150(24576, true, true, true); diff --git a/ethcore/src/evm/tests.rs b/ethcore/evm/src/tests.rs similarity index 90% rename from ethcore/src/evm/tests.rs rename to ethcore/evm/src/tests.rs index 61e0b62be..d0502f79a 100644 --- a/ethcore/src/evm/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -19,13 +19,12 @@ use rustc_hex::FromHex; use util::*; use action_params::{ActionParams, ActionValue}; use env_info::EnvInfo; -use types::executed::CallType; -use evm::{self, Ext, Schedule, Factory, GasLeft, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; -use tests::helpers::*; -use types::transaction::SYSTEM_ADDRESS; -use executive::Executive; -use state::Substate; -use trace::{NoopVMTracer, NoopTracer}; +use call_type::CallType; +use schedule::Schedule; +use evm::{self, GasLeft, ReturnData}; +use ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; +use factory::Factory; +use vmtype::VMType; pub struct FakeLogEntry { topics: Vec, @@ -438,67 +437,6 @@ fn test_blockhash(factory: super::Factory) { assert_eq!(ext.store.get(&H256::new()).unwrap(), &blockhash); } -evm_test!{test_blockhash_eip210: test_blockhash_eip210_jit, test_blockhash_eip210_int} -fn test_blockhash_eip210(factory: super::Factory) { - let get_prev_hash_code = Arc::new("600143034060205260206020f3".from_hex().unwrap()); // this returns previous block hash - let get_prev_hash_code_hash = get_prev_hash_code.sha3(); - // This is same as DEFAULT_BLOCKHASH_CONTRACT except for metropolis transition block check removed. - let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b"; - let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap()); - let blockhash_contract_code_hash = blockhash_contract_code.sha3(); - let engine = TestEngine::new_metropolis(); - let mut env_info = EnvInfo::default(); - - // populate state with 256 last hashes - let mut state = get_temp_state_with_factory(factory); - let contract_address: Address = 0xf0.into(); - state.init_code(&contract_address, (*blockhash_contract_code).clone()).unwrap(); - for i in 1 .. 257 { - env_info.number = i.into(); - let params = ActionParams { - code_address: contract_address.clone(), - address: contract_address, - sender: SYSTEM_ADDRESS.clone(), - origin: SYSTEM_ADDRESS.clone(), - gas: 100000.into(), - gas_price: 0.into(), - value: ActionValue::Transfer(0.into()), - code: Some(blockhash_contract_code.clone()), - code_hash: Some(blockhash_contract_code_hash), - data: Some(H256::from(i - 1).to_vec()), - call_type: CallType::Call, - }; - let mut ex = Executive::new(&mut state, &env_info, &engine); - let mut substate = Substate::new(); - let mut output = []; - if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) { - panic!("Encountered error on updating last hashes: {}", e); - } - } - - env_info.number = 256; - let params = ActionParams { - code_address: Address::new(), - address: Address::new(), - sender: Address::new(), - origin: Address::new(), - gas: 100000.into(), - gas_price: 0.into(), - value: ActionValue::Transfer(0.into()), - code: Some(get_prev_hash_code), - code_hash: Some(get_prev_hash_code_hash), - data: None, - call_type: CallType::Call, - }; - let mut ex = Executive::new(&mut state, &env_info, &engine); - let mut substate = Substate::new(); - let mut output = H256::new(); - if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) { - panic!("Encountered error on getting last hash: {}", e); - } - assert_eq!(output, 255.into()); -} - evm_test!{test_calldataload: test_calldataload_jit, test_calldataload_int} fn test_calldataload(factory: super::Factory) { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); diff --git a/ethcore/src/evm/vmtype.rs b/ethcore/evm/src/vmtype.rs similarity index 100% rename from ethcore/src/evm/vmtype.rs rename to ethcore/evm/src/vmtype.rs diff --git a/ethcore/src/evm/wasm/call_args.rs b/ethcore/evm/src/wasm/call_args.rs similarity index 100% rename from ethcore/src/evm/wasm/call_args.rs rename to ethcore/evm/src/wasm/call_args.rs diff --git a/ethcore/src/evm/wasm/env.rs b/ethcore/evm/src/wasm/env.rs similarity index 100% rename from ethcore/src/evm/wasm/env.rs rename to ethcore/evm/src/wasm/env.rs diff --git a/ethcore/src/evm/wasm/mod.rs b/ethcore/evm/src/wasm/mod.rs similarity index 95% rename from ethcore/src/evm/wasm/mod.rs rename to ethcore/evm/src/wasm/mod.rs index 3965cc529..a7186add5 100644 --- a/ethcore/src/evm/wasm/mod.rs +++ b/ethcore/evm/src/wasm/mod.rs @@ -58,7 +58,7 @@ impl WasmInterpreter { impl evm::Evm for WasmInterpreter { - fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result { + fn exec(&mut self, params: ActionParams, ext: &mut ::ext::Ext) -> evm::Result { use parity_wasm::elements::Deserialize; let code = params.code.expect("exec is only called on contract with code; qed"); @@ -76,7 +76,7 @@ impl evm::Evm for WasmInterpreter { if params.gas > ::std::u64::MAX.into() { return Err(evm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned())); } - + let mut runtime = Runtime::with_params( ext, env_memory, @@ -106,7 +106,7 @@ impl evm::Evm for WasmInterpreter { { let execution_params = interpreter::ExecutionParams::with_external( - "env".into(), + "env".into(), Arc::new( interpreter::env_native_module(env_instance, native_bindings(&mut runtime)) .map_err(|err| { @@ -115,7 +115,7 @@ impl evm::Evm for WasmInterpreter { })? ) ).add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32)); - + 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); @@ -138,11 +138,11 @@ impl evm::Evm for WasmInterpreter { // todo: use memory views to avoid copy self.result.extend(result.pop(&*runtime.memory())?); let len = self.result.len(); - Ok(GasLeft::NeedsReturn { - gas_left: runtime.gas_left()?.into(), + Ok(GasLeft::NeedsReturn { + gas_left: runtime.gas_left()?.into(), data: ReturnData::new( - ::std::mem::replace(&mut self.result, Vec::with_capacity(DEFAULT_RESULT_BUFFER)), - 0, + ::std::mem::replace(&mut self.result, Vec::with_capacity(DEFAULT_RESULT_BUFFER)), + 0, len, ), apply_state: true, @@ -156,4 +156,4 @@ fn native_bindings<'a>(runtime: &'a mut Runtime) -> interpreter::UserFunctions<' executor: runtime, functions: ::std::borrow::Cow::from(env::SIGNATURES), } -} \ No newline at end of file +} diff --git a/ethcore/src/evm/wasm/ptr.rs b/ethcore/evm/src/wasm/ptr.rs similarity index 100% rename from ethcore/src/evm/wasm/ptr.rs rename to ethcore/evm/src/wasm/ptr.rs diff --git a/ethcore/src/evm/wasm/result.rs b/ethcore/evm/src/wasm/result.rs similarity index 100% rename from ethcore/src/evm/wasm/result.rs rename to ethcore/evm/src/wasm/result.rs diff --git a/ethcore/src/evm/wasm/runtime.rs b/ethcore/evm/src/wasm/runtime.rs similarity index 89% rename from ethcore/src/evm/wasm/runtime.rs rename to ethcore/evm/src/wasm/runtime.rs index eb1fc55fb..7beb4c599 100644 --- a/ethcore/src/evm/wasm/runtime.rs +++ b/ethcore/evm/src/wasm/runtime.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use byteorder::{LittleEndian, ByteOrder}; -use evm; +use ext; use parity_wasm::interpreter; use util::{Address, H256, U256}; @@ -62,16 +62,16 @@ pub struct Runtime<'a> { gas_counter: u64, gas_limit: u64, dynamic_top: u32, - ext: &'a mut evm::Ext, + ext: &'a mut ext::Ext, memory: Arc, } impl<'a> Runtime<'a> { /// New runtime for wasm contract with specified params pub fn with_params<'b>( - ext: &'b mut evm::Ext, - memory: Arc, - stack_space: u32, + ext: &'b mut ext::Ext, + memory: Arc, + stack_space: u32, gas_limit: u64, ) -> Runtime<'b> { Runtime { @@ -84,7 +84,7 @@ impl<'a> Runtime<'a> { } /// Write to the storage from wasm memory - pub fn storage_write(&mut self, context: interpreter::CallerContext) + pub fn storage_write(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> { let mut context = context; @@ -99,12 +99,12 @@ impl<'a> Runtime<'a> { } /// Read from the storage to wasm memory - pub fn storage_read(&mut self, context: interpreter::CallerContext) + pub fn storage_read(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> { let mut context = context; let val_ptr = context.value_stack.pop_as::()?; - let key = self.pop_h256(&mut context)?; + let key = self.pop_h256(&mut context)?; let val = self.ext.storage_at(&key) .map_err(|_| interpreter::Error::Trap("Storage read error".to_owned()))?; @@ -115,11 +115,11 @@ impl<'a> Runtime<'a> { } /// Pass suicide to state runtime - pub fn suicide(&mut self, context: interpreter::CallerContext) + pub fn suicide(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> { let mut context = context; - let refund_address = self.pop_address(&mut context)?; + let refund_address = self.pop_address(&mut context)?; self.ext.suicide(&refund_address) .map_err(|_| interpreter::Error::Trap("Suicide error".to_owned()))?; @@ -128,7 +128,7 @@ impl<'a> Runtime<'a> { } /// Invoke create in the state runtime - pub fn create(&mut self, context: interpreter::CallerContext) + pub fn create(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> { // @@ -139,11 +139,11 @@ impl<'a> Runtime<'a> { trace!(target: "wasm", "runtime: create contract"); let mut context = context; let result_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " result_ptr: {:?}", result_ptr); + trace!(target: "wasm", " result_ptr: {:?}", result_ptr); let code_len = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_len: {:?}", code_len); + trace!(target: "wasm", " code_len: {:?}", code_len); let code_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_ptr: {:?}", code_ptr); + trace!(target: "wasm", " code_ptr: {:?}", code_ptr); let endowment = self.pop_u256(&mut context)?; trace!(target: "wasm", " val: {:?}", endowment); @@ -152,15 +152,15 @@ impl<'a> Runtime<'a> { let gas_left = self.gas_left() .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? .into(); - - match self.ext.create(&gas_left, &endowment, &code, evm::CreateContractAddress::FromSenderAndCodeHash) { - evm::ContractCreateResult::Created(address, gas_left) => { + + match self.ext.create(&gas_left, &endowment, &code, ext::CreateContractAddress::FromSenderAndCodeHash) { + ext::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())) }, - evm::ContractCreateResult::Failed => { + ext::ContractCreateResult::Failed => { trace!(target: "wasm", "runtime: create contract fail"); Ok(Some((-1i32).into())) } @@ -168,7 +168,7 @@ impl<'a> Runtime<'a> { } /// Allocate memory using the wasm stack params - pub fn malloc(&mut self, context: interpreter::CallerContext) + pub fn malloc(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> { let amount = context.value_stack.pop_as::()? as u32; @@ -185,14 +185,14 @@ impl<'a> Runtime<'a> { } /// Report gas cost with the params passed in wasm stack - fn gas(&mut self, context: interpreter::CallerContext) - -> Result, interpreter::Error> + fn gas(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> { let amount = context.value_stack.pop_as::()? as u64; if self.charge_gas(amount) { Ok(None) } else { - Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit))) + Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit))) } } @@ -204,13 +204,13 @@ impl<'a> Runtime<'a> { } else { self.gas_counter = prev + amount; true - } + } } fn h256_at(&self, ptr: WasmPtr) -> Result { Ok(H256::from_slice(&ptr.slice(32, &*self.memory) .map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))? - )) + )) } fn pop_h256(&self, context: &mut interpreter::CallerContext) -> Result { @@ -228,7 +228,7 @@ impl<'a> Runtime<'a> { fn address_at(&self, ptr: WasmPtr) -> Result { Ok(Address::from_slice(&ptr.slice(20, &*self.memory) .map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))? - )) + )) } fn pop_address(&self, context: &mut interpreter::CallerContext) -> Result { @@ -237,13 +237,13 @@ impl<'a> Runtime<'a> { self.address_at(ptr) } - fn user_trap(&mut self, _context: interpreter::CallerContext) - -> Result, interpreter::Error> + fn user_trap(&mut self, _context: interpreter::CallerContext) + -> Result, interpreter::Error> { Err(interpreter::Error::Trap("unknown trap".to_owned())) } - fn user_noop(&mut self, + fn user_noop(&mut self, _context: interpreter::CallerContext ) -> Result, interpreter::Error> { Ok(None) @@ -270,16 +270,16 @@ impl<'a> Runtime<'a> { self.memory.set(args_ptr+40, &call_args.origin)?; self.memory.set(args_ptr+60, &call_args.value)?; self.memory.set(args_ptr+92, &call_args.data)?; - + Ok(d_ptr.into()) } - fn debug_log(&mut self, context: interpreter::CallerContext) - -> Result, interpreter::Error> + fn debug_log(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> { let msg_len = context.value_stack.pop_as::()? as u32; let msg_ptr = context.value_stack.pop_as::()? as u32; - + let msg = String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?) .map_err(|_| interpreter::Error::Trap("Debug log utf-8 decoding error".to_owned()))?; @@ -299,8 +299,8 @@ impl<'a> Runtime<'a> { &*self.memory } - fn mem_copy(&self, context: interpreter::CallerContext) - -> Result, interpreter::Error> + fn mem_copy(&self, context: interpreter::CallerContext) + -> Result, interpreter::Error> { let len = context.value_stack.pop_as::()? as u32; let dst = context.value_stack.pop_as::()? as u32; @@ -314,7 +314,7 @@ impl<'a> Runtime<'a> { } impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { - fn execute(&mut self, name: &str, context: interpreter::CallerContext) + fn execute(&mut self, name: &str, context: interpreter::CallerContext) -> Result, interpreter::Error> { match name { @@ -353,4 +353,4 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { } } } -} \ No newline at end of file +} diff --git a/ethcore/src/evm/wasm/tests.rs b/ethcore/evm/src/wasm/tests.rs similarity index 86% rename from ethcore/src/evm/wasm/tests.rs rename to ethcore/evm/src/wasm/tests.rs index 7fd98db08..8ae13daae 100644 --- a/ethcore/src/evm/wasm/tests.rs +++ b/ethcore/evm/src/wasm/tests.rs @@ -1,22 +1,31 @@ -use std::path::PathBuf; -use std::fs::File; -use std::io::Read; +// 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 . + use std::sync::Arc; -use ethcore_logger::init_log; use super::super::tests::{FakeExt, FakeCall, FakeCallType}; use super::WasmInterpreter; use evm::{self, Evm, GasLeft}; use action_params::{ActionParams, ActionValue}; use util::{U256, H256, Address}; -fn load_sample(name: &str) -> Vec { - let mut path = PathBuf::from("./res/wasm-tests/compiled"); - path.push(name); - let mut file = File::open(path).expect(&format!("File {} for test to exist", name)); - let mut data = vec![]; - file.read_to_end(&mut data).expect(&format!("Test {} to load ok", name)); - data +macro_rules! load_sample { + ($name: expr) => { + include_bytes!(concat!("../../../res/wasm-tests/compiled/", $name)).to_vec() + } } fn test_finalize(res: Result) -> Result { @@ -34,9 +43,7 @@ fn wasm_interpreter() -> WasmInterpreter { /// Empty contract does almost nothing except producing 1 (one) local node debug log message #[test] fn empty() { - init_log(); - - let code = load_sample("empty.wasm"); + let code = load_sample!("empty.wasm"); let address: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); let mut params = ActionParams::default(); @@ -58,9 +65,7 @@ fn empty() { // logger.wasm writes all these provided fixed header fields to some arbitrary storage keys. #[test] fn logger() { - init_log(); - - let code = load_sample("logger.wasm"); + let code = load_sample!("logger.wasm"); let address: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); let sender: Address = "0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d".parse().unwrap(); let origin: Address = "0102030405060708090a0b0c0d0e0f1011121314".parse().unwrap(); @@ -113,9 +118,7 @@ fn logger() { // if it has any result. #[test] fn identity() { - init_log(); - - let code = load_sample("identity.wasm"); + let code = load_sample!("identity.wasm"); let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); let mut params = ActionParams::default(); @@ -143,14 +146,12 @@ fn identity() { } // Dispersion test sends byte array and expect the contract to 'disperse' the original elements with -// their modulo 19 dopant. +// their modulo 19 dopant. // The result is always twice as long as the input. -// This also tests byte-perfect memory allocation and in/out ptr lifecycle. +// This also tests byte-perfect memory allocation and in/out ptr lifecycle. #[test] fn dispersion() { - init_log(); - - let code = load_sample("dispersion.wasm"); + let code = load_sample!("dispersion.wasm"); let mut params = ActionParams::default(); params.gas = U256::from(100_000); @@ -179,9 +180,7 @@ fn dispersion() { #[test] fn suicide_not() { - init_log(); - - let code = load_sample("suicidal.wasm"); + let code = load_sample!("suicidal.wasm"); let mut params = ActionParams::default(); params.gas = U256::from(100_000); @@ -205,14 +204,12 @@ fn suicide_not() { assert_eq!( result, vec![0u8] - ); + ); } #[test] fn suicide() { - init_log(); - - let code = load_sample("suicidal.wasm"); + let code = load_sample!("suicidal.wasm"); let refund: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); let mut params = ActionParams::default(); @@ -242,11 +239,9 @@ fn suicide() { #[test] fn create() { - init_log(); - let mut params = ActionParams::default(); params.gas = U256::from(100_000); - params.code = Some(Arc::new(load_sample("creator.wasm"))); + params.code = Some(Arc::new(load_sample!("creator.wasm"))); params.data = Some(vec![0u8, 2, 4, 8, 16, 32, 64, 128]); params.value = ActionValue::transfer(1_000_000_000); @@ -276,4 +271,4 @@ fn create() { } )); assert_eq!(gas_left, U256::from(99_768)); -} \ No newline at end of file +} diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index ab45eedbe..f4fb3cd0d 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -18,6 +18,7 @@ ethcore-network = { path = "../../util/network" } ethcore-io = { path = "../../util/io" } ethcore-ipc = { path = "../../ipc/rpc", optional = true } ethcore-devtools = { path = "../../devtools" } +evm = { path = "../evm" } rlp = { path = "../../util/rlp" } time = "0.1" smallvec = "0.4" diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index ba580b905..db0d3ad25 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -18,10 +18,10 @@ use std::sync::{Weak, Arc}; -use ethcore::block_import_error::BlockImportError; use ethcore::block_status::BlockStatus; use ethcore::client::{ClientReport, EnvInfo}; use ethcore::engines::Engine; +use ethcore::error::BlockImportError; use ethcore::ids::BlockId; use ethcore::header::Header; use ethcore::verification::queue::{self, HeaderQueue}; diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index 18908a3f2..49928bd98 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -71,6 +71,7 @@ extern crate ethcore_io as io; extern crate ethcore_network as network; extern crate ethcore_util as util; extern crate ethcore; +extern crate evm; extern crate futures; extern crate itertools; extern crate rand; diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index ea90fa97b..9587dd8ed 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -21,10 +21,10 @@ use std::sync::Arc; use ethcore::basic_account::BasicAccount; use ethcore::encoded; use ethcore::engines::Engine; -use ethcore::env_info::EnvInfo; use ethcore::receipt::Receipt; use ethcore::state::{self, ProvedExecution}; use ethcore::transaction::SignedTransaction; +use evm::env_info::EnvInfo; use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; diff --git a/ethcore/light/src/transaction_queue.rs b/ethcore/light/src/transaction_queue.rs index 7ce2bd53d..b0e7483a3 100644 --- a/ethcore/light/src/transaction_queue.rs +++ b/ethcore/light/src/transaction_queue.rs @@ -26,9 +26,8 @@ use std::collections::{BTreeMap, HashMap}; use std::collections::hash_map::Entry; -use ethcore::error::TransactionError; +use ethcore::error::{TransactionError, TransactionImportResult}; use ethcore::transaction::{Condition, PendingTransaction, SignedTransaction}; -use ethcore::transaction_import::TransactionImportResult; use util::{Address, U256, H256, H256FastMap}; // Knowledge of an account's current nonce. diff --git a/ethcore/src/basic_types.rs b/ethcore/src/basic_types.rs index 64ddd5bc9..1f07e748f 100644 --- a/ethcore/src/basic_types.rs +++ b/ethcore/src/basic_types.rs @@ -16,13 +16,11 @@ //! Ethcore basic typenames. -use util::hash::H2048; - /// Type for a 2048-bit log-bloom, as used by our blocks. -pub type LogBloom = H2048; +pub type LogBloom = ::log_entry::LogBloom; /// Constant 2048-bit datum for 0. Often used as a default. -pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]); +pub static ZERO_LOGBLOOM: LogBloom = ::util::hash::H2048([0x00; 256]); #[cfg_attr(feature="dev", allow(enum_variant_names))] /// Semantic boolean for when a seal/signature is included. diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index c0294c364..ccb6a0501 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -25,7 +25,7 @@ use util::{Bytes, Address, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RL use util::error::{Mismatch, OutOfBounds}; use basic_types::{LogBloom, Seal}; -use env_info::{EnvInfo, LastHashes}; +use evm::env_info::{EnvInfo, LastHashes}; use engines::Engine; use error::{Error, BlockError, TransactionError}; use factory::Factories; @@ -656,7 +656,7 @@ mod tests { use tests::helpers::*; use super::*; use engines::Engine; - use env_info::LastHashes; + use evm::env_info::LastHashes; use error::Error; use header::Header; use factory::Factories; diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index 084be4666..d5dc459b2 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -36,6 +36,12 @@ impl From<&'static str> for Error { } } +impl Into<::evm::Error> for Error { + fn into(self) -> ::evm::Error { + ::evm::Error::BuiltIn(self.0) + } +} + /// Native implementation of a built-in contract. pub trait Impl: Send + Sync { /// execute this built-in on the given input, writing to the given output. diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index c6be9daf9..d6945c020 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -17,7 +17,6 @@ use std::collections::{HashSet, HashMap, BTreeMap, VecDeque}; use std::str::FromStr; use std::sync::{Arc, Weak}; -use std::fmt; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::time::{Instant}; use time::precise_time_ns; @@ -43,8 +42,8 @@ use client::{ }; use encoded; use engines::{Engine, EpochTransition}; -use env_info::EnvInfo; -use env_info::LastHashes; +use evm::env_info::EnvInfo; +use evm::env_info::LastHashes; use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; use evm::{Factory as EvmFactory, Schedule}; use executive::{Executive, Executed, TransactOptions, contract_address}; @@ -84,12 +83,6 @@ const MAX_TX_QUEUE_SIZE: usize = 4096; const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2; const MIN_HISTORY_SIZE: u64 = 8; -impl fmt::Display for BlockChainInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "#{}.{}", self.best_block_number, self.best_block_hash) - } -} - /// Report on the status of a client. #[derive(Default, Clone, Debug, Eq, PartialEq)] pub struct ClientReport { diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index b58ae83cb..43a7a821a 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -17,14 +17,16 @@ use std::str::FromStr; use std::path::Path; use std::fmt::{Display, Formatter, Error as FmtError}; + +use mode::Mode as IpcMode; +use verification::{VerifierType, QueueConfig}; +use util::{journaldb, CompactionProfile}; + pub use std::time::Duration; pub use blockchain::Config as BlockChainConfig; pub use trace::Config as TraceConfig; pub use evm::VMType; -use verification::{VerifierType, QueueConfig}; -use util::{journaldb, CompactionProfile}; - /// Client state db compaction profile #[derive(Debug, PartialEq, Clone)] pub enum DatabaseCompactionProfile { @@ -98,6 +100,29 @@ impl Display for Mode { } } +impl Into for Mode { + fn into(self) -> IpcMode { + match self { + Mode::Off => IpcMode::Off, + Mode::Dark(timeout) => IpcMode::Dark(timeout.as_secs()), + Mode::Passive(timeout, alarm) => IpcMode::Passive(timeout.as_secs(), alarm.as_secs()), + Mode::Active => IpcMode::Active, + } + } +} + +impl From for Mode { + fn from(mode: IpcMode) -> Self { + match mode { + IpcMode::Off => Mode::Off, + IpcMode::Dark(timeout) => Mode::Dark(Duration::from_secs(timeout)), + IpcMode::Passive(timeout, alarm) => Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm)), + IpcMode::Active => Mode::Active, + } + } +} + + /// Client configuration. Includes configs for all sub-systems. #[derive(Debug, PartialEq, Default)] pub struct ClientConfig { diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index 300e2fc92..5f23f449d 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -23,7 +23,7 @@ use util::kvdb::{self, KeyValueDB}; use {state, state_db, client, executive, trace, db, spec}; use factory::Factories; use evm::{self, VMType}; -use action_params::ActionParams; +use evm::action_params::ActionParams; /// EVM test Error. #[derive(Debug)] diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index cd5c867e5..b2d1ce991 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -40,11 +40,9 @@ pub use types::pruning_info::PruningInfo; pub use types::call_analytics::CallAnalytics; pub use executive::{Executed, Executive, TransactOptions}; -pub use env_info::{LastHashes, EnvInfo}; +pub use evm::env_info::{LastHashes, EnvInfo}; -pub use block_import_error::BlockImportError; -pub use transaction_import::TransactionImportResult; -pub use transaction_import::TransactionImportError; +pub use error::{BlockImportError, TransactionImportError, TransactionImportResult}; pub use verification::VerifierType; /// IPC interfaces diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index da765ad07..aca369b21 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -15,24 +15,27 @@ // along with Parity. If not, see . use std::collections::BTreeMap; -use util::{U256, Address, H256, H2048, Bytes, Itertools}; -use util::hashdb::DBValue; -use blockchain::TreeRoute; -use verification::queue::QueueInfo as BlockQueueInfo; + use block::{OpenBlock, SealedBlock, ClosedBlock}; -use header::{BlockNumber}; -use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction}; -use transaction_import::TransactionImportResult; -use log_entry::LocalizedLogEntry; -use filter::Filter; +use blockchain::TreeRoute; +use encoded; +use evm::env_info::LastHashes; use error::{ImportResult, CallError, Error as EthcoreError}; -use receipt::LocalizedReceipt; -use trace::LocalizedTrace; +use error::{TransactionImportResult, BlockImportError}; use evm::{Factory as EvmFactory, Schedule}; use executive::Executed; -use env_info::LastHashes; -use block_import_error::BlockImportError; +use filter::Filter; +use header::{BlockNumber}; use ipc::IpcConfig; +use log_entry::LocalizedLogEntry; +use receipt::LocalizedReceipt; +use trace::LocalizedTrace; +use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction}; +use verification::queue::QueueInfo as BlockQueueInfo; + +use util::{U256, Address, H256, H2048, Bytes, Itertools}; +use util::hashdb::DBValue; + use types::ids::*; use types::basic_account::BasicAccount; use types::trace_filter::Filter as TraceFilter; @@ -41,7 +44,6 @@ use types::blockchain_info::BlockChainInfo; use types::block_status::BlockStatus; use types::mode::Mode; use types::pruning_info::PruningInfo; -use encoded; #[ipc(client_ident="RemoteClient")] /// Blockchain database client. Owns and manages a blockchain and a block queue. diff --git a/ethcore/src/types/encoded.rs b/ethcore/src/encoded.rs similarity index 100% rename from ethcore/src/types/encoded.rs rename to ethcore/src/encoded.rs diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index ba9ab6745..b38948f37 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -532,7 +532,7 @@ impl Engine for AuthorityRound { fn on_new_block( &self, block: &mut ExecutedBlock, - last_hashes: Arc<::env_info::LastHashes>, + last_hashes: Arc<::evm::env_info::LastHashes>, epoch_begin: bool, ) -> Result<(), Error> { let parent_hash = block.fields().header.parent_hash().clone(); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 676bb1aae..c5fa4818e 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -43,7 +43,7 @@ use account_provider::AccountProvider; use block::ExecutedBlock; use builtin::Builtin; use client::Client; -use env_info::{EnvInfo, LastHashes}; +use evm::env_info::{EnvInfo, LastHashes}; use error::Error; use evm::Schedule; use header::{Header, BlockNumber}; @@ -193,7 +193,7 @@ pub trait Engine : Sync + Send { /// Get the EVM schedule for the given `block_number`. fn schedule(&self, block_number: BlockNumber) -> Schedule { - Schedule::from_params(block_number, self.params()) + self.params().schedule(block_number) } /// Builtin-contracts we would like to see in the chain. @@ -394,12 +394,12 @@ pub trait Engine : Sync + Send { /// Common engine utilities pub mod common { use block::ExecutedBlock; - use env_info::{EnvInfo, LastHashes}; + use evm::env_info::{EnvInfo, LastHashes}; use error::Error; use transaction::SYSTEM_ADDRESS; use executive::Executive; - use types::executed::CallType; - use action_params::{ActionParams, ActionValue}; + use evm::CallType; + use evm::action_params::{ActionParams, ActionValue}; use trace::{NoopTracer, NoopVMTracer}; use state::Substate; diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index e7d0dab86..defc8a2dd 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -901,7 +901,7 @@ mod tests { #[test] fn seal_submission() { use ethkey::{Generator, Random}; - use types::transaction::{Transaction, Action}; + use transaction::{Transaction, Action}; use client::BlockChainClient; let tap = Arc::new(AccountProvider::transient_provider()); diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 45c9a6912..8fb530be3 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -297,7 +297,7 @@ impl ValidatorSet for ValidatorSafeContract { let (old_header, state_items) = decode_first_proof(&rlp)?; let old_hash = old_header.hash(); - let env_info = ::env_info::EnvInfo { + let env_info = ::evm::env_info::EnvInfo { number: old_header.number(), author: *old_header.author(), difficulty: *old_header.difficulty(), diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 066a9d31a..2d908cdb6 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -22,13 +22,12 @@ use header::BlockNumber; use basic_types::LogBloom; use client::Error as ClientError; use ipc::binary::{BinaryConvertError, BinaryConvertable}; -use types::block_import_error::BlockImportError; use snapshot::Error as SnapshotError; use engines::EngineError; use ethkey::Error as EthkeyError; use account_provider::SignError as AccountsError; -pub use types::executed::{ExecutionError, CallError}; +pub use executed::{ExecutionError, CallError}; #[derive(Debug, PartialEq, Clone, Copy)] /// Errors concerning transaction processing. @@ -239,6 +238,53 @@ impl fmt::Display for ImportError { f.write_fmt(format_args!("Block import error ({})", msg)) } } +/// Error dedicated to import block function +#[derive(Debug)] +pub enum BlockImportError { + /// Import error + Import(ImportError), + /// Block error + Block(BlockError), + /// Other error + Other(String), +} + +impl From for BlockImportError { + fn from(e: Error) -> Self { + match e { + Error::Block(block_error) => BlockImportError::Block(block_error), + Error::Import(import_error) => BlockImportError::Import(import_error), + _ => BlockImportError::Other(format!("other block import error: {:?}", e)), + } + } +} + +/// Represents the result of importing transaction. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum TransactionImportResult { + /// Transaction was imported to current queue. + Current, + /// Transaction was imported to future queue. + Future +} + +/// Api-level error for transaction import +#[derive(Debug, Clone)] +pub enum TransactionImportError { + /// Transaction error + Transaction(TransactionError), + /// Other error + Other(String), +} + +impl From for TransactionImportError { + fn from(e: Error) -> Self { + match e { + Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error), + _ => TransactionImportError::Other(format!("other block import error: {:?}", e)), + } + } +} #[derive(Debug)] /// General error type which should be capable of representing all errors in ethcore. diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index f29c0421a..1fbd711c9 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -19,7 +19,7 @@ use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use util::*; use block::*; use builtin::Builtin; -use env_info::EnvInfo; +use evm::env_info::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 env_info::LastHashes; +use evm::env_info::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]); @@ -209,7 +209,8 @@ impl Engine for Arc { block_number >= self.ethash_params.eip160_transition, block_number >= self.ethash_params.eip161abc_transition, block_number >= self.ethash_params.eip161d_transition); - schedule.apply_params(block_number, self.params()); + + self.params().update_schedule(block_number, &mut schedule); schedule } } @@ -1027,7 +1028,7 @@ mod tests { #[test] fn rejects_transactions_below_min_gas_price() { use ethkey::{Generator, Random}; - use types::transaction::{Transaction, Action}; + use transaction::{Transaction, Action}; let spec = new_homestead_test(); let mut ethparams = get_default_ethash_params(); diff --git a/ethcore/src/types/executed.rs b/ethcore/src/executed.rs similarity index 78% rename from ethcore/src/types/executed.rs rename to ethcore/src/executed.rs index 37c8748aa..f6508668f 100644 --- a/ethcore/src/types/executed.rs +++ b/ethcore/src/executed.rs @@ -17,58 +17,15 @@ //! Transaction execution format module. use util::{Bytes, U256, Address, U512, trie}; -use rlp::*; use evm; use trace::{VMTrace, FlatTrace}; -use types::log_entry::LogEntry; -use types::state_diff::StateDiff; +use log_entry::LogEntry; +use state_diff::StateDiff; + use std::fmt; -/// The type of the call-like instruction. -#[derive(Debug, PartialEq, Clone)] -#[cfg_attr(feature = "ipc", binary)] -pub enum CallType { - /// Not a CALL. - None, - /// CALL. - Call, - /// CALLCODE. - CallCode, - /// DELEGATECALL. - DelegateCall, - /// STATICCALL - StaticCall, -} - -impl Encodable for CallType { - fn rlp_append(&self, s: &mut RlpStream) { - let v = match *self { - CallType::None => 0u32, - CallType::Call => 1, - CallType::CallCode => 2, - CallType::DelegateCall => 3, - CallType::StaticCall => 4, - }; - Encodable::rlp_append(&v, s); - } -} - -impl Decodable for CallType { - fn decode(rlp: &UntrustedRlp) -> Result { - rlp.as_val().and_then(|v| Ok(match v { - 0u32 => CallType::None, - 1 => CallType::Call, - 2 => CallType::CallCode, - 3 => CallType::DelegateCall, - 4 => CallType::StaticCall, - _ => return Err(DecoderError::Custom("Invalid value of CallType item")), - })) - } -} - /// Transaction execution receipt. #[derive(Debug, PartialEq, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct Executed { /// True if the outer call/create resulted in an exceptional exit. pub exception: Option, @@ -112,7 +69,6 @@ pub struct Executed { /// Result of executing the transaction. #[derive(PartialEq, Debug, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub enum ExecutionError { /// Returned when there gas paid for transaction execution is /// lower than base gas required. @@ -192,7 +148,6 @@ impl fmt::Display for ExecutionError { /// Result of executing the transaction. #[derive(PartialEq, Debug, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub enum CallError { /// Couldn't find the transaction in the chain. TransactionNotFound, @@ -230,29 +185,3 @@ impl fmt::Display for CallError { /// Transaction execution result. pub type ExecutionResult = Result; - -#[cfg(test)] -mod tests { - use rlp::*; - use super::CallType; - - #[test] - fn encode_call_type() { - let ct = CallType::Call; - - let mut s = RlpStream::new_list(2); - s.append(&ct); - assert!(!s.is_finished(), "List shouldn't finished yet"); - s.append(&ct); - assert!(s.is_finished(), "List should be finished now"); - s.out(); - } - - #[test] - fn should_encode_and_decode_call_type() { - let original = CallType::Call; - let encoded = encode(&original); - let decoded = decode(&encoded); - assert_eq!(original, decoded); - } -} diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index d7a6fbc28..9e25b6671 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -16,18 +16,18 @@ //! Transaction Execution environment. use util::*; -use action_params::{ActionParams, ActionValue}; +use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; use engines::Engine; -use types::executed::CallType; -use env_info::EnvInfo; +use evm::CallType; +use evm::env_info::EnvInfo; use error::ExecutionError; use evm::{self, wasm, Factory, Ext, Finalize, CreateContractAddress, FinalizationResult, ReturnData, CleanDustMode}; use externalities::*; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer}; use transaction::{Action, SignedTransaction}; use crossbeam; -pub use types::executed::{Executed, ExecutionResult}; +pub use executed::{Executed, ExecutionResult}; /// Roughly estimate what stack size each level of evm depth will use /// TODO [todr] We probably need some more sophisticated calculations here (limit on my machine 132) @@ -602,8 +602,8 @@ mod tests { use super::*; use util::{H256, U256, U512, Address, FromStr}; use util::bytes::BytesRef; - use action_params::{ActionParams, ActionValue}; - use env_info::EnvInfo; + use evm::action_params::{ActionParams, ActionValue}; + use evm::env_info::EnvInfo; use evm::{Factory, VMType, CreateContractAddress}; use error::ExecutionError; use state::{Substate, CleanupMode}; @@ -613,7 +613,7 @@ mod tests { use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; use transaction::{Action, Transaction}; - use types::executed::CallType; + use evm::CallType; #[test] fn test_contract_address() { diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 0f0310649..39c8673a9 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -16,14 +16,14 @@ //! Transaction Execution environment. use util::*; -use action_params::{ActionParams, ActionValue}; +use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; use engines::Engine; -use env_info::EnvInfo; +use evm::env_info::EnvInfo; use executive::*; use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; -use types::executed::CallType; -use types::transaction::UNSIGNED_SENDER; +use evm::CallType; +use transaction::UNSIGNED_SENDER; use trace::{Tracer, VMTracer}; /// Policy for handling output data on `RETURN` opcode. @@ -396,13 +396,13 @@ 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 env_info::EnvInfo; + use evm::env_info::EnvInfo; use evm::Ext; use state::{State, Substate}; use tests::helpers::*; use super::*; use trace::{NoopTracer, NoopVMTracer}; - use types::executed::CallType; + use evm::CallType; fn get_test_origin() -> OriginInfo { OriginInfo { diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index f5bf1dcfd..83c69e97d 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -25,8 +25,7 @@ use std::cell::RefCell; pub use basic_types::Seal; -/// Type for Block number -pub type BlockNumber = u64; +pub use types::BlockNumber; /// A block header. /// diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index b7fad2787..0c5a6a90d 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -15,15 +15,15 @@ // along with Parity. If not, see . use super::test_common::*; -use action_params::ActionParams; +use evm::action_params::ActionParams; use state::{Backend as StateBackend, State, Substate}; use executive::*; use engines::Engine; -use env_info::EnvInfo; +use evm::env_info::EnvInfo; use evm; use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; use externalities::*; -use types::executed::CallType; +use evm::CallType; use tests::helpers::*; use ethjson; use trace::{Tracer, NoopTracer}; diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index d0d5e9746..74bbfb266 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -21,8 +21,8 @@ use ethereum; use spec::Spec; use ethjson; use ethjson::state::test::ForkSpec; -use types::transaction::SignedTransaction; -use env_info::EnvInfo; +use transaction::SignedTransaction; +use evm::env_info::EnvInfo; lazy_static! { pub static ref FRONTIER: Spec = ethereum::new_frontier_test(); diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 7ffa61288..af7922c20 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -76,6 +76,7 @@ extern crate bloomchain; extern crate bn; extern crate byteorder; extern crate crossbeam; +extern crate common_types as types; extern crate crypto; extern crate env_logger; extern crate ethabi; @@ -105,8 +106,6 @@ extern crate semver; extern crate stats; extern crate time; extern crate transient_hashmap; -extern crate parity_wasm; -extern crate wasm_utils; #[macro_use] extern crate log; @@ -116,6 +115,8 @@ extern crate ethcore_util as util; extern crate lazy_static; #[macro_use] extern crate ethcore_ipc as ipc; +#[cfg_attr(test, macro_use)] +extern crate evm; #[cfg(feature = "jit" )] extern crate evmjit; @@ -123,26 +124,26 @@ extern crate evmjit; pub extern crate ethstore; pub mod account_provider; -pub mod engines; pub mod block; pub mod client; +pub mod db; +pub mod encoded; +pub mod engines; pub mod error; pub mod ethereum; +pub mod executed; pub mod header; -pub mod service; -pub mod trace; -pub mod spec; -pub mod views; -pub mod pod_state; pub mod migrations; pub mod miner; +pub mod pod_state; +pub mod service; pub mod snapshot; -pub mod action_params; -pub mod db; -pub mod verification; +pub mod spec; pub mod state; -pub mod env_info; -#[macro_use] pub mod evm; +pub mod trace; +pub mod transaction; +pub mod verification; +pub mod views; mod cache_manager; mod blooms; @@ -154,7 +155,6 @@ mod builtin; mod executive; mod externalities; mod blockchain; -mod types; mod factory; #[cfg(test)] diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index c5042abc8..f037052ce 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1280,7 +1280,7 @@ mod tests { use ethkey::{Generator, Random}; use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult}; use header::BlockNumber; - use types::transaction::{SignedTransaction, Transaction, PendingTransaction, Action}; + use transaction::{SignedTransaction, Transaction, PendingTransaction, Action}; use spec::Spec; use tests::helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts}; diff --git a/ethcore/src/snapshot/block.rs b/ethcore/src/snapshot/block.rs index 75aa8e13e..e7b100f69 100644 --- a/ethcore/src/snapshot/block.rs +++ b/ethcore/src/snapshot/block.rs @@ -134,7 +134,7 @@ mod tests { use views::BlockView; use block::Block; use super::AbridgedBlock; - use types::transaction::{Action, Transaction}; + use transaction::{Action, Transaction}; use util::{Address, H256, U256, Bytes}; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 6e7403e43..40893ad6d 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -20,10 +20,10 @@ use rustc_hex::FromHex; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; -use action_params::{ActionValue, ActionParams}; +use evm::action_params::{ActionValue, ActionParams}; use builtin::Builtin; use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT}; -use env_info::EnvInfo; +use evm::env_info::EnvInfo; use error::Error; use ethereum; use ethjson; @@ -36,7 +36,7 @@ use state_db::StateDB; use state::{Backend, State, Substate}; use state::backend::Basic as BasicBackend; use trace::{NoopTracer, NoopVMTracer}; -use types::executed::CallType; +use evm::CallType; use util::*; /// Parameters common to all engines. @@ -87,6 +87,31 @@ pub struct CommonParams { pub wasm: bool, } +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); + 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) { + 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; + if block_number >= self.eip210_transition { + schedule.blockhash_gas = 350; + } + if block_number >= self.dust_protection_transition { + schedule.kill_dust = match self.remove_dust_contracts { + true => ::evm::CleanDustMode::WithCodeAndStorage, + false => ::evm::CleanDustMode::BasicOnly, + }; + } + } +} + impl From for CommonParams { fn from(p: ethjson::spec::Params) -> Self { CommonParams { diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index a9e05b7fd..354da2cc3 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -24,7 +24,7 @@ use std::collections::hash_map::Entry; use receipt::Receipt; use engines::Engine; -use env_info::EnvInfo; +use evm::env_info::EnvInfo; use error::Error; use executive::{Executive, TransactOptions}; use factory::Factories; @@ -32,7 +32,7 @@ use trace::FlatTrace; use pod_account::*; use pod_state::{self, PodState}; use types::basic_account::BasicAccount; -use types::executed::{Executed, ExecutionError}; +use executed::{Executed, ExecutionError}; use types::state_diff::StateDiff; use transaction::SignedTransaction; use state_db::StateDB; @@ -982,12 +982,12 @@ mod tests { use ethkey::Secret; use util::{U256, H256, Address, Hashable}; use tests::helpers::*; - use env_info::EnvInfo; + use evm::env_info::EnvInfo; use spec::*; use transaction::*; use ethcore_logger::init_log; use trace::{FlatTrace, TraceError, trace}; - use types::executed::CallType; + use evm::CallType; fn secret() -> Secret { "".sha3().into() diff --git a/ethcore/src/tests/evm.rs b/ethcore/src/tests/evm.rs new file mode 100644 index 000000000..c97fd4ac0 --- /dev/null +++ b/ethcore/src/tests/evm.rs @@ -0,0 +1,76 @@ +//! Tests of EVM integration with transaction execution. + +use evm::action_params::{ActionParams, ActionValue}; +use evm::env_info::EnvInfo; +use evm::{Factory, VMType}; +use evm::call_type::CallType; +use executive::Executive; +use state::Substate; +use tests::helpers::*; +use trace::{NoopVMTracer, NoopTracer}; +use transaction::SYSTEM_ADDRESS; + +use rustc_hex::FromHex; + +use util::*; + +evm_test!{test_blockhash_eip210: test_blockhash_eip210_jit, test_blockhash_eip210_int} +fn test_blockhash_eip210(factory: Factory) { + let get_prev_hash_code = Arc::new("600143034060205260206020f3".from_hex().unwrap()); // this returns previous block hash + let get_prev_hash_code_hash = get_prev_hash_code.sha3(); + // This is same as DEFAULT_BLOCKHASH_CONTRACT except for metropolis transition block check removed. + let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b"; + let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap()); + let blockhash_contract_code_hash = blockhash_contract_code.sha3(); + let engine = TestEngine::new_metropolis(); + let mut env_info = EnvInfo::default(); + + // populate state with 256 last hashes + let mut state = get_temp_state_with_factory(factory); + let contract_address: Address = 0xf0.into(); + state.init_code(&contract_address, (*blockhash_contract_code).clone()).unwrap(); + for i in 1 .. 257 { + env_info.number = i.into(); + let params = ActionParams { + code_address: contract_address.clone(), + address: contract_address, + sender: SYSTEM_ADDRESS.clone(), + origin: SYSTEM_ADDRESS.clone(), + gas: 100000.into(), + gas_price: 0.into(), + value: ActionValue::Transfer(0.into()), + code: Some(blockhash_contract_code.clone()), + code_hash: Some(blockhash_contract_code_hash), + data: Some(H256::from(i - 1).to_vec()), + call_type: CallType::Call, + }; + let mut ex = Executive::new(&mut state, &env_info, &engine); + let mut substate = Substate::new(); + let mut output = []; + if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) { + panic!("Encountered error on updating last hashes: {}", e); + } + } + + env_info.number = 256; + let params = ActionParams { + code_address: Address::new(), + address: Address::new(), + sender: Address::new(), + origin: Address::new(), + gas: 100000.into(), + gas_price: 0.into(), + value: ActionValue::Transfer(0.into()), + code: Some(get_prev_hash_code), + code_hash: Some(get_prev_hash_code_hash), + data: None, + call_type: CallType::Call, + }; + let mut ex = Executive::new(&mut state, &env_info, &engine); + let mut substate = Substate::new(); + let mut output = H256::new(); + if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) { + panic!("Encountered error on getting last hash: {}", e); + } + assert_eq!(output, 255.into()); +} diff --git a/ethcore/src/tests/mod.rs b/ethcore/src/tests/mod.rs index d0fc3e949..31f195725 100644 --- a/ethcore/src/tests/mod.rs +++ b/ethcore/src/tests/mod.rs @@ -16,5 +16,8 @@ pub mod helpers; mod client; +mod evm; + #[cfg(feature="ipc")] mod rpc; + diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index 68c846519..fe90ffe41 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -410,7 +410,7 @@ mod tests { use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError}; use trace::trace::{Call, Action, Res}; use trace::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces}; - use types::executed::CallType; + use evm::CallType; struct NoopExtras; diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index 9dddd214a..cdfe1e004 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -17,7 +17,7 @@ //! Simple executive tracer. use util::{Bytes, Address, U256}; -use action_params::ActionParams; +use evm::action_params::ActionParams; use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide}; use trace::{Tracer, VMTracer, FlatTrace, TraceError}; diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index c6320b34c..39af8a08a 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -22,21 +22,24 @@ mod db; mod executive_tracer; mod import; mod noop_tracer; +mod types; -pub use types::trace_types::{filter, flat, localized, trace}; -pub use types::trace_types::error::Error as TraceError; pub use self::config::Config; pub use self::db::TraceDB; -pub use types::trace_types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff}; -pub use types::trace_types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces}; pub use self::noop_tracer::{NoopTracer, NoopVMTracer}; pub use self::executive_tracer::{ExecutiveTracer, ExecutiveVMTracer}; -pub use types::trace_types::filter::{Filter, AddressesFilter}; pub use self::import::ImportRequest; pub use self::localized::LocalizedTrace; + +pub use self::types::{filter, flat, localized, trace}; +pub use self::types::error::Error as TraceError; +pub use self::types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff}; +pub use self::types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces}; +pub use self::types::filter::{Filter, AddressesFilter}; + use util::{Bytes, Address, U256, H256, DBTransaction}; use self::trace::{Call, Create}; -use action_params::ActionParams; +use evm::action_params::ActionParams; use header::BlockNumber; /// This trait is used by executive to build traces. diff --git a/ethcore/src/trace/noop_tracer.rs b/ethcore/src/trace/noop_tracer.rs index 694d1b094..5fb8a7c55 100644 --- a/ethcore/src/trace/noop_tracer.rs +++ b/ethcore/src/trace/noop_tracer.rs @@ -17,7 +17,7 @@ //! Nonoperative tracer. use util::{Bytes, Address, U256}; -use action_params::ActionParams; +use evm::action_params::ActionParams; use trace::{Tracer, VMTracer, FlatTrace, TraceError}; use trace::trace::{Call, Create, VMTrace}; diff --git a/ethcore/src/types/trace_types/error.rs b/ethcore/src/trace/types/error.rs similarity index 98% rename from ethcore/src/types/trace_types/error.rs rename to ethcore/src/trace/types/error.rs index f10f2d1bb..4242bfad4 100644 --- a/ethcore/src/types/trace_types/error.rs +++ b/ethcore/src/trace/types/error.rs @@ -22,7 +22,6 @@ use evm::Error as EvmError; /// Trace evm errors. #[derive(Debug, PartialEq, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub enum Error { /// `OutOfGas` is returned when transaction execution runs out of gas. OutOfGas, @@ -34,7 +33,7 @@ pub enum Error { /// `StackUnderflow` when there is not enough stack elements to execute instruction StackUnderflow, /// When execution would exceed defined Stack Limit - OutOfStack, + OutOfStack, /// When builtin contract failed on input data BuiltIn, /// Returned on evm internal error. Should never be ignored during development. diff --git a/ethcore/src/types/trace_types/filter.rs b/ethcore/src/trace/types/filter.rs similarity index 98% rename from ethcore/src/types/trace_types/filter.rs rename to ethcore/src/trace/types/filter.rs index d7a57dd69..2dc810442 100644 --- a/ethcore/src/types/trace_types/filter.rs +++ b/ethcore/src/trace/types/filter.rs @@ -23,13 +23,12 @@ use util::sha3::Hashable; use util::bloom::Bloomable; use basic_types::LogBloom; use trace::flat::FlatTrace; -use types::trace_types::trace::{Action, Res}; +use super::trace::{Action, Res}; /// Addresses filter. /// /// Used to create bloom possibilities and match filters. #[derive(Debug)] -#[cfg_attr(feature = "ipc", binary)] pub struct AddressesFilter { list: Vec
} @@ -76,7 +75,6 @@ impl AddressesFilter { } #[derive(Debug)] -#[cfg_attr(feature = "ipc", binary)] /// Traces filter. pub struct Filter { /// Block range. @@ -143,7 +141,7 @@ mod tests { use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide}; use trace::flat::FlatTrace; use trace::{Filter, AddressesFilter, TraceError}; - use types::executed::CallType; + use evm::CallType; #[test] fn empty_trace_filter_bloom_possibilities() { diff --git a/ethcore/src/types/trace_types/flat.rs b/ethcore/src/trace/types/flat.rs similarity index 98% rename from ethcore/src/types/trace_types/flat.rs rename to ethcore/src/trace/types/flat.rs index 90b770beb..da304694d 100644 --- a/ethcore/src/types/trace_types/flat.rs +++ b/ethcore/src/trace/types/flat.rs @@ -26,7 +26,6 @@ use super::trace::{Action, Res}; /// /// Parent and children indexes refer to positions in this vector. #[derive(Debug, PartialEq, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct FlatTrace { /// Type of action performed by a transaction. pub action: Action, @@ -164,7 +163,7 @@ mod tests { use rlp::*; use super::{FlatBlockTraces, FlatTransactionTraces, FlatTrace}; use trace::trace::{Action, Res, CallResult, Call, Suicide}; - use types::executed::CallType; + use evm::CallType; #[test] fn encode_flat_transaction_traces() { diff --git a/ethcore/src/types/trace_types/localized.rs b/ethcore/src/trace/types/localized.rs similarity index 97% rename from ethcore/src/types/trace_types/localized.rs rename to ethcore/src/trace/types/localized.rs index 575f9eb45..39a4b08cc 100644 --- a/ethcore/src/types/trace_types/localized.rs +++ b/ethcore/src/trace/types/localized.rs @@ -22,7 +22,6 @@ use header::BlockNumber; /// Localized trace. #[derive(Debug, PartialEq, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedTrace { /// Type of action performed by a transaction. pub action: Action, diff --git a/ethcore/src/types/trace_types/mod.rs b/ethcore/src/trace/types/mod.rs similarity index 100% rename from ethcore/src/types/trace_types/mod.rs rename to ethcore/src/trace/types/mod.rs diff --git a/ethcore/src/types/trace_types/trace.rs b/ethcore/src/trace/types/trace.rs similarity index 99% rename from ethcore/src/types/trace_types/trace.rs rename to ethcore/src/trace/types/trace.rs index ed5dfb9f1..24250935f 100644 --- a/ethcore/src/types/trace_types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -21,9 +21,9 @@ use util::sha3::Hashable; use util::bloom::Bloomable; use rlp::*; -use action_params::ActionParams; +use evm::action_params::ActionParams; use basic_types::LogBloom; -use types::executed::CallType; +use evm::CallType; use super::error::Error; /// `Call` result. diff --git a/ethcore/src/types/transaction.rs b/ethcore/src/transaction.rs similarity index 74% rename from ethcore/src/types/transaction.rs rename to ethcore/src/transaction.rs index db17221fb..6f5470028 100644 --- a/ethcore/src/types/transaction.rs +++ b/ethcore/src/transaction.rs @@ -32,9 +32,8 @@ pub const UNSIGNED_SENDER: Address = ::util::H160([0xff; 20]); /// System sender address for internal state updates. pub const SYSTEM_ADDRESS: Address = ::util::H160([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xfe]); -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] /// Transaction action type. +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Action { /// Create creates new contract. Create, @@ -59,7 +58,6 @@ impl Decodable for Action { /// Transaction activation condition. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub enum Condition { /// Valid at this block number or later. Number(BlockNumber), @@ -70,7 +68,6 @@ pub enum Condition { /// A set of information describing an externally-originating message call /// or contract creation operation. #[derive(Default, Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct Transaction { /// Nonce. pub nonce: U256, @@ -241,9 +238,8 @@ impl Transaction { } } -/// Signed transaction information. +/// Signed transaction information without verified signature. #[derive(Debug, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] pub struct UnverifiedTransaction { /// Plain Transaction. unsigned: Transaction, @@ -470,7 +466,6 @@ impl SignedTransaction { /// Signed Transaction that is a part of canon blockchain. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedTransaction { /// Signed part. pub signed: UnverifiedTransaction, @@ -511,7 +506,6 @@ impl Deref for LocalizedTransaction { /// Queued transaction with additional information. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct PendingTransaction { /// Signed transaction data. pub transaction: SignedTransaction, @@ -544,91 +538,97 @@ impl From for PendingTransaction { } } -#[test] -fn sender_test() { - let t: UnverifiedTransaction = decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap()); - assert_eq!(t.data, b""); - assert_eq!(t.gas, U256::from(0x5208u64)); - assert_eq!(t.gas_price, U256::from(0x01u64)); - assert_eq!(t.nonce, U256::from(0x00u64)); - if let Action::Call(ref to) = t.action { - assert_eq!(*to, "095e7baea6a6c7c4c2dfeb977efac326af552d87".into()); - } else { panic!(); } - assert_eq!(t.value, U256::from(0x0au64)); - assert_eq!(public_to_address(&t.recover_public().unwrap()), "0f65fe9276bc9a24ae7083ae28e2660ef72df99e".into()); - assert_eq!(t.network_id(), None); -} - -#[test] -fn signing() { - use ethkey::{Random, Generator}; - - let key = Random.generate().unwrap(); - let t = Transaction { - action: Action::Create, - nonce: U256::from(42), - gas_price: U256::from(3000), - gas: U256::from(50_000), - value: U256::from(1), - data: b"Hello!".to_vec() - }.sign(&key.secret(), None); - assert_eq!(Address::from(key.public().sha3()), t.sender()); - assert_eq!(t.network_id(), None); -} - -#[test] -fn fake_signing() { - let t = Transaction { - action: Action::Create, - nonce: U256::from(42), - gas_price: U256::from(3000), - gas: U256::from(50_000), - value: U256::from(1), - data: b"Hello!".to_vec() - }.fake_sign(Address::from(0x69)); - assert_eq!(Address::from(0x69), t.sender()); - assert_eq!(t.network_id(), None); - - let t = t.clone(); - assert_eq!(Address::from(0x69), t.sender()); - assert_eq!(t.network_id(), None); -} - -#[test] -fn should_recover_from_network_specific_signing() { - use ethkey::{Random, Generator}; - let key = Random.generate().unwrap(); - let t = Transaction { - action: Action::Create, - nonce: U256::from(42), - gas_price: U256::from(3000), - gas: U256::from(50_000), - value: U256::from(1), - data: b"Hello!".to_vec() - }.sign(&key.secret(), Some(69)); - assert_eq!(Address::from(key.public().sha3()), t.sender()); - assert_eq!(t.network_id(), Some(69)); -} - -#[test] -fn should_agree_with_vitalik() { - use rustc_hex::FromHex; - - let test_vector = |tx_data: &str, address: &'static str| { - let signed = decode(&FromHex::from_hex(tx_data).unwrap()); - let signed = SignedTransaction::new(signed).unwrap(); - assert_eq!(signed.sender(), address.into()); - flushln!("networkid: {:?}", signed.network_id()); - }; - - test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce"); - test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112"); - test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be"); - test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0"); - test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554"); - test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4"); - test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35"); - test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332"); - test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029"); - test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f"); +#[cfg(test)] +mod tests { + use super::*; + use util::{Hashable, U256}; + + #[test] + fn sender_test() { + let t: UnverifiedTransaction = decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap()); + assert_eq!(t.data, b""); + assert_eq!(t.gas, U256::from(0x5208u64)); + assert_eq!(t.gas_price, U256::from(0x01u64)); + assert_eq!(t.nonce, U256::from(0x00u64)); + if let Action::Call(ref to) = t.action { + assert_eq!(*to, "095e7baea6a6c7c4c2dfeb977efac326af552d87".into()); + } else { panic!(); } + assert_eq!(t.value, U256::from(0x0au64)); + assert_eq!(public_to_address(&t.recover_public().unwrap()), "0f65fe9276bc9a24ae7083ae28e2660ef72df99e".into()); + assert_eq!(t.network_id(), None); + } + + #[test] + fn signing() { + use ethkey::{Random, Generator}; + + let key = Random.generate().unwrap(); + let t = Transaction { + action: Action::Create, + nonce: U256::from(42), + gas_price: U256::from(3000), + gas: U256::from(50_000), + value: U256::from(1), + data: b"Hello!".to_vec() + }.sign(&key.secret(), None); + assert_eq!(Address::from(key.public().sha3()), t.sender()); + assert_eq!(t.network_id(), None); + } + + #[test] + fn fake_signing() { + let t = Transaction { + action: Action::Create, + nonce: U256::from(42), + gas_price: U256::from(3000), + gas: U256::from(50_000), + value: U256::from(1), + data: b"Hello!".to_vec() + }.fake_sign(Address::from(0x69)); + assert_eq!(Address::from(0x69), t.sender()); + assert_eq!(t.network_id(), None); + + let t = t.clone(); + assert_eq!(Address::from(0x69), t.sender()); + assert_eq!(t.network_id(), None); + } + + #[test] + fn should_recover_from_network_specific_signing() { + use ethkey::{Random, Generator}; + let key = Random.generate().unwrap(); + let t = Transaction { + action: Action::Create, + nonce: U256::from(42), + gas_price: U256::from(3000), + gas: U256::from(50_000), + value: U256::from(1), + data: b"Hello!".to_vec() + }.sign(&key.secret(), Some(69)); + assert_eq!(Address::from(key.public().sha3()), t.sender()); + assert_eq!(t.network_id(), Some(69)); + } + + #[test] + fn should_agree_with_vitalik() { + use rustc_hex::FromHex; + + let test_vector = |tx_data: &str, address: &'static str| { + let signed = decode(&FromHex::from_hex(tx_data).unwrap()); + let signed = SignedTransaction::new(signed).unwrap(); + assert_eq!(signed.sender(), address.into()); + flushln!("networkid: {:?}", signed.network_id()); + }; + + test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce"); + test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112"); + test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be"); + test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0"); + test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554"); + test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4"); + test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35"); + test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332"); + test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029"); + test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f"); + } } diff --git a/ethcore/src/types/block_import_error.rs b/ethcore/src/types/block_import_error.rs deleted file mode 100644 index 119e48437..000000000 --- a/ethcore/src/types/block_import_error.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Block import error related types - -use error::{ImportError, BlockError, Error}; -use std::convert::From; - -/// Error dedicated to import block function -#[derive(Debug)] -#[cfg_attr(feature = "ipc", binary)] -pub enum BlockImportError { - /// Import error - Import(ImportError), - /// Block error - Block(BlockError), - /// Other error - Other(String), -} - -impl From for BlockImportError { - fn from(e: Error) -> Self { - match e { - Error::Block(block_error) => BlockImportError::Block(block_error), - Error::Import(import_error) => BlockImportError::Import(import_error), - _ => BlockImportError::Other(format!("other block import error: {:?}", e)), - } - } -} diff --git a/ethcore/src/types/block_status.rs b/ethcore/src/types/block_status.rs deleted file mode 100644 index c5a779c09..000000000 --- a/ethcore/src/types/block_status.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Block status description module -use verification::queue::Status as QueueStatus; - -/// General block status -#[derive(Debug, Eq, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] -pub enum BlockStatus { - /// Part of the blockchain. - InChain, - /// Queued for import. - Queued, - /// Known as bad. - Bad, - /// Unknown. - Unknown, -} - -impl From for BlockStatus { - fn from(status: QueueStatus) -> Self { - match status { - QueueStatus::Queued => BlockStatus::Queued, - QueueStatus::Bad => BlockStatus::Bad, - QueueStatus::Unknown => BlockStatus::Unknown, - } - } -} diff --git a/ethcore/src/types/transaction_import.rs b/ethcore/src/types/transaction_import.rs deleted file mode 100644 index c5f4f955d..000000000 --- a/ethcore/src/types/transaction_import.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Transaction import result related types - -use ipc::binary::{BinaryConvertError, BinaryConvertable}; -use error::{TransactionError, Error}; - -#[derive(Debug, Clone, Copy, PartialEq)] -/// Represents the result of importing transaction. -pub enum TransactionImportResult { - /// Transaction was imported to current queue. - Current, - /// Transaction was imported to future queue. - Future -} - -binary_fixed_size!(TransactionImportResult); - -/// Api-level error for transaction import -#[derive(Debug, Clone)] -#[cfg_attr(feature = "ipc", binary)] -pub enum TransactionImportError { - /// Transaction error - Transaction(TransactionError), - /// Other error - Other(String), -} - -impl From for TransactionImportError { - fn from(e: Error) -> Self { - match e { - Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error), - _ => TransactionImportError::Other(format!("other block import error: {:?}", e)), - } - } -} diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index fa090a0cf..7e9a70f7c 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -115,6 +115,17 @@ pub enum Status { Unknown, } +impl Into<::block_status::BlockStatus> for Status { + fn into(self) -> ::block_status::BlockStatus { + use ::block_status::BlockStatus; + match self { + Status::Queued => BlockStatus::Queued, + Status::Bad => BlockStatus::Bad, + Status::Unknown => BlockStatus::Unknown, + } + } +} + // the internal queue sizes. struct Sizes { unverified: AtomicUsize, diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 1be636adc..823d2ef70 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -585,7 +585,7 @@ mod tests { #[test] fn dust_protection() { use ethkey::{Generator, Random}; - use types::transaction::{Transaction, Action}; + use transaction::{Transaction, Action}; use engines::NullEngine; let mut params = CommonParams::default(); diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml new file mode 100644 index 000000000..2a3ac6a80 --- /dev/null +++ b/ethcore/types/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "common-types" +description = "Common types used throughout the codebase" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +rlp = { path = "../../util/rlp" } +ethcore-util = { path = "../../util" } +ethjson = { path = "../../json" } + +[dev-dependencies] +rustc-hex= "1.0" diff --git a/ethcore/src/types/account_diff.rs b/ethcore/types/src/account_diff.rs similarity index 96% rename from ethcore/src/types/account_diff.rs rename to ethcore/types/src/account_diff.rs index 4ed0f5ee9..337c5df1b 100644 --- a/ethcore/src/types/account_diff.rs +++ b/ethcore/types/src/account_diff.rs @@ -20,12 +20,10 @@ use std::cmp::*; use std::fmt; use std::collections::BTreeMap; use util::{U256, H256, Bytes}; -use ipc::binary::BinaryConvertable; #[derive(Debug, PartialEq, Eq, Clone)] -#[cfg_attr(feature = "ipc", binary)] /// Diff type for specifying a change (or not). -pub enum Diff where T: Eq + BinaryConvertable { +pub enum Diff where T: Eq { /// Both sides are the same. Same, /// Left (pre, source) side doesn't include value, right side (post, destination) does. @@ -36,7 +34,7 @@ pub enum Diff where T: Eq + BinaryConvertable { Died(T), } -impl Diff where T: Eq + BinaryConvertable { +impl Diff where T: Eq { /// Construct new object with given `pre` and `post`. pub fn new(pre: T, post: T) -> Self { if pre == post { Diff::Same } else { Diff::Changed(pre, post) } } diff --git a/ethcore/src/types/basic_account.rs b/ethcore/types/src/basic_account.rs similarity index 100% rename from ethcore/src/types/basic_account.rs rename to ethcore/types/src/basic_account.rs diff --git a/ethcore/src/types/mod.rs b/ethcore/types/src/block_status.rs similarity index 72% rename from ethcore/src/types/mod.rs rename to ethcore/types/src/block_status.rs index 59f2d5bb3..937077795 100644 --- a/ethcore/src/types/mod.rs +++ b/ethcore/types/src/block_status.rs @@ -14,12 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Types used in the public api - -#![cfg_attr(feature = "ipc", allow(dead_code, unused_assignments, unused_variables))] // codegen issues - -#[cfg(feature = "ipc")] -include!(concat!(env!("OUT_DIR"), "/mod.rs.in")); - -#[cfg(not(feature = "ipc"))] -include!("mod.rs.in"); +/// General block status +#[derive(Debug, Eq, PartialEq)] +pub enum BlockStatus { + /// Part of the blockchain. + InChain, + /// Queued for import. + Queued, + /// Known as bad. + Bad, + /// Unknown. + Unknown, +} diff --git a/ethcore/src/types/blockchain_info.rs b/ethcore/types/src/blockchain_info.rs similarity index 89% rename from ethcore/src/types/blockchain_info.rs rename to ethcore/types/src/blockchain_info.rs index 6f46f07d4..4ab1432b7 100644 --- a/ethcore/src/types/blockchain_info.rs +++ b/ethcore/types/src/blockchain_info.rs @@ -16,13 +16,14 @@ //! Blockhain info type definition +use std::fmt; + use util::{U256, H256}; -use header::BlockNumber; -use types::security_level::SecurityLevel; +use security_level::SecurityLevel; +use {BlockNumber}; /// Information about the blockchain gathered together. #[derive(Clone, Debug)] -#[cfg_attr(feature = "ipc", binary)] pub struct BlockChainInfo { /// Blockchain difficulty. pub total_difficulty: U256, @@ -57,3 +58,9 @@ impl BlockChainInfo { } } } + +impl fmt::Display for BlockChainInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "#{}.{}", self.best_block_number, self.best_block_hash) + } +} diff --git a/ethcore/src/types/call_analytics.rs b/ethcore/types/src/call_analytics.rs similarity index 96% rename from ethcore/src/types/call_analytics.rs rename to ethcore/types/src/call_analytics.rs index e38117680..b0520a0d3 100644 --- a/ethcore/src/types/call_analytics.rs +++ b/ethcore/types/src/call_analytics.rs @@ -18,7 +18,6 @@ /// Options concerning what analytics we run on the call. #[derive(Eq, PartialEq, Default, Clone, Copy, Debug)] -#[cfg_attr(feature = "ipc", binary)] pub struct CallAnalytics { /// Make a transaction trace. pub transaction_tracing: bool, diff --git a/ethcore/src/types/filter.rs b/ethcore/types/src/filter.rs similarity index 99% rename from ethcore/src/types/filter.rs rename to ethcore/types/src/filter.rs index 1b6043129..6ab53b536 100644 --- a/ethcore/src/types/filter.rs +++ b/ethcore/types/src/filter.rs @@ -18,12 +18,11 @@ use util::{Address, H256, Hashable, H2048}; use util::bloom::Bloomable; -use client::BlockId; +use ids::BlockId; use log_entry::LogEntry; /// Blockchain Filter. #[derive(Debug, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] pub struct Filter { /// Blockchain will be searched from this block. pub from_block: BlockId, @@ -114,7 +113,7 @@ impl Filter { #[cfg(test)] mod tests { use filter::Filter; - use client::BlockId; + use ids::BlockId; use log_entry::LogEntry; #[test] diff --git a/ethcore/src/types/ids.rs b/ethcore/types/src/ids.rs similarity index 90% rename from ethcore/src/types/ids.rs rename to ethcore/types/src/ids.rs index ded3f2172..feda18307 100644 --- a/ethcore/src/types/ids.rs +++ b/ethcore/types/src/ids.rs @@ -17,11 +17,10 @@ //! Unique identifiers. use util::hash::H256; -use header::BlockNumber; +use {BlockNumber}; /// Uniquely identifies block. #[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub enum BlockId { /// Block's sha3. /// Querying by hash is always faster. @@ -38,7 +37,6 @@ pub enum BlockId { /// Uniquely identifies transaction. #[derive(Debug, PartialEq, Clone, Hash, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub enum TransactionId { /// Transaction's sha3. Hash(H256), @@ -48,7 +46,6 @@ pub enum TransactionId { } /// Uniquely identifies Trace. -#[cfg_attr(feature = "ipc", binary)] pub struct TraceId { /// Transaction pub transaction: TransactionId, @@ -58,7 +55,6 @@ pub struct TraceId { /// Uniquely identifies Uncle. #[derive(Debug, PartialEq, Eq, Copy, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct UncleId { /// Block id. pub block: BlockId, diff --git a/ethcore/src/types/mod.rs.in b/ethcore/types/src/lib.rs similarity index 84% rename from ethcore/src/types/mod.rs.in rename to ethcore/types/src/lib.rs index d5f4d6ff4..589034066 100644 --- a/ethcore/src/types/mod.rs.in +++ b/ethcore/types/src/lib.rs @@ -14,27 +14,33 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -pub mod transaction; -pub mod ids; -pub mod receipt; -pub mod tree_route; -pub mod blockchain_info; -pub mod log_entry; -pub mod trace_types; -pub mod executed; -pub mod block_status; +//! Types used in the public API + +extern crate ethcore_util as util; +extern crate ethjson; +extern crate rlp; + +#[cfg(test)] +extern crate rustc_hex; + pub mod account_diff; -pub mod state_diff; -pub mod verification_queue_info; -pub mod filter; -pub mod trace_filter; +pub mod basic_account; +pub mod block_status; +pub mod blockchain_info; pub mod call_analytics; -pub mod transaction_import; -pub mod block_import_error; -pub mod restoration_status; -pub mod snapshot_manifest; +pub mod filter; +pub mod ids; +pub mod log_entry; pub mod mode; pub mod pruning_info; +pub mod receipt; +pub mod restoration_status; pub mod security_level; -pub mod encoded; -pub mod basic_account; +pub mod snapshot_manifest; +pub mod state_diff; +pub mod trace_filter; +pub mod tree_route; +pub mod verification_queue_info; + +/// Type for block number. +pub type BlockNumber = u64; diff --git a/ethcore/src/types/log_entry.rs b/ethcore/types/src/log_entry.rs similarity index 96% rename from ethcore/src/types/log_entry.rs rename to ethcore/types/src/log_entry.rs index f3260c114..724e6a7dc 100644 --- a/ethcore/src/types/log_entry.rs +++ b/ethcore/types/src/log_entry.rs @@ -21,13 +21,13 @@ use util::{H256, Address, Bytes, HeapSizeOf, Hashable}; use util::bloom::Bloomable; use rlp::*; -use basic_types::LogBloom; -use header::BlockNumber; +use {BlockNumber}; use ethjson; +pub type LogBloom = ::util::H2048; + /// A record of execution for a `LOG` operation. #[derive(Default, Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct LogEntry { /// The address of the contract executing at the point of the `LOG` operation. pub address: Address, @@ -82,7 +82,6 @@ impl From for LogEntry { /// Log localized in a blockchain. #[derive(Default, Debug, PartialEq, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedLogEntry { /// Plain log entry. pub entry: LogEntry, diff --git a/ethcore/src/types/mode.rs b/ethcore/types/src/mode.rs similarity index 59% rename from ethcore/src/types/mode.rs rename to ethcore/types/src/mode.rs index a1a716013..539ebcdbd 100644 --- a/ethcore/src/types/mode.rs +++ b/ethcore/types/src/mode.rs @@ -17,11 +17,9 @@ //! Mode type pub use std::time::Duration; -use client::Mode as ClientMode; /// IPC-capable shadow-type for `client::config::Mode` #[derive(Clone, Debug)] -#[cfg_attr(feature = "ipc", binary)] pub enum Mode { /// Same as `ClientMode::Off`. Off, @@ -32,25 +30,3 @@ pub enum Mode { /// Same as `ClientMode::Active`. Active, } - -impl From for Mode { - fn from(mode: ClientMode) -> Self { - match mode { - ClientMode::Off => Mode::Off, - ClientMode::Dark(timeout) => Mode::Dark(timeout.as_secs()), - ClientMode::Passive(timeout, alarm) => Mode::Passive(timeout.as_secs(), alarm.as_secs()), - ClientMode::Active => Mode::Active, - } - } -} - -impl From for ClientMode { - fn from(mode: Mode) -> Self { - match mode { - Mode::Off => ClientMode::Off, - Mode::Dark(timeout) => ClientMode::Dark(Duration::from_secs(timeout)), - Mode::Passive(timeout, alarm) => ClientMode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm)), - Mode::Active => ClientMode::Active, - } - } -} diff --git a/ethcore/src/types/pruning_info.rs b/ethcore/types/src/pruning_info.rs similarity index 97% rename from ethcore/src/types/pruning_info.rs rename to ethcore/types/src/pruning_info.rs index 8fb118a52..8a47fdd8b 100644 --- a/ethcore/src/types/pruning_info.rs +++ b/ethcore/types/src/pruning_info.rs @@ -22,7 +22,6 @@ /// Client pruning info. See module-level docs for more details. #[derive(Debug, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct PruningInfo { /// The first block which everything can be served after. pub earliest_chain: u64, diff --git a/ethcore/src/types/receipt.rs b/ethcore/types/src/receipt.rs similarity index 69% rename from ethcore/src/types/receipt.rs rename to ethcore/types/src/receipt.rs index e0fb6d820..81439ecdf 100644 --- a/ethcore/src/types/receipt.rs +++ b/ethcore/types/src/receipt.rs @@ -20,13 +20,11 @@ use util::{H256, U256, Address}; use util::HeapSizeOf; use rlp::*; -use basic_types::LogBloom; -use header::BlockNumber; -use log_entry::{LogEntry, LocalizedLogEntry}; +use {BlockNumber}; +use log_entry::{LogBloom, LogEntry, LocalizedLogEntry}; /// Information describing execution of a transaction. #[derive(Default, Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct Receipt { /// The state root after executing the transaction. Optional since EIP98 pub state_root: Option, @@ -92,7 +90,6 @@ impl HeapSizeOf for Receipt { /// Receipt with additional info. #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] pub struct RichReceipt { /// Transaction hash. pub transaction_hash: H256, @@ -114,7 +111,6 @@ pub struct RichReceipt { /// Receipt with additional info. #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] pub struct LocalizedReceipt { /// Transaction hash. pub transaction_hash: H256, @@ -138,35 +134,41 @@ pub struct LocalizedReceipt { pub state_root: Option, } -#[test] -fn test_no_state_root() { - let expected = ::rustc_hex::FromHex::from_hex("f9014183040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); - let r = Receipt::new( - None, - 0x40cae.into(), - vec![LogEntry { - address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(), - topics: vec![], - data: vec![0u8; 32] - }] - ); - assert_eq!(&encode(&r)[..], &expected[..]); -} +#[cfg(test)] +mod tests { + use super::Receipt; + use log_entry::LogEntry; -#[test] -fn test_basic() { - let expected = ::rustc_hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); - let r = Receipt::new( - Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()), - 0x40cae.into(), - vec![LogEntry { - address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(), - topics: vec![], - data: vec![0u8; 32] - }] - ); - let encoded = encode(&r); - assert_eq!(&encoded[..], &expected[..]); - let decoded: Receipt = decode(&encoded); - assert_eq!(decoded, r); + #[test] + fn test_no_state_root() { + let expected = ::rustc_hex::FromHex::from_hex("f9014183040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let r = Receipt::new( + None, + 0x40cae.into(), + vec![LogEntry { + address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(), + topics: vec![], + data: vec![0u8; 32] + }] + ); + assert_eq!(&::rlp::encode(&r)[..], &expected[..]); + } + + #[test] + fn test_basic() { + let expected = ::rustc_hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let r = Receipt::new( + Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()), + 0x40cae.into(), + vec![LogEntry { + address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(), + topics: vec![], + data: vec![0u8; 32] + }] + ); + let encoded = ::rlp::encode(&r); + assert_eq!(&encoded[..], &expected[..]); + let decoded: Receipt = ::rlp::decode(&encoded); + assert_eq!(decoded, r); + } } diff --git a/ethcore/src/types/restoration_status.rs b/ethcore/types/src/restoration_status.rs similarity index 97% rename from ethcore/src/types/restoration_status.rs rename to ethcore/types/src/restoration_status.rs index ff47bc06b..0cc7fccc0 100644 --- a/ethcore/src/types/restoration_status.rs +++ b/ethcore/types/src/restoration_status.rs @@ -18,7 +18,6 @@ /// Statuses for restorations. #[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[cfg_attr(feature = "ipc", binary)] pub enum RestorationStatus { /// No restoration. Inactive, diff --git a/ethcore/src/types/security_level.rs b/ethcore/types/src/security_level.rs similarity index 95% rename from ethcore/src/types/security_level.rs rename to ethcore/types/src/security_level.rs index da4f650bd..ea39dc328 100644 --- a/ethcore/src/types/security_level.rs +++ b/ethcore/types/src/security_level.rs @@ -16,11 +16,10 @@ //! Indication of how secure the chain is. -use header::BlockNumber; +use {BlockNumber}; /// Indication of how secure the chain is. #[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub enum SecurityLevel { /// All blocks from genesis to chain head are known to have valid state transitions and PoW. FullState, diff --git a/ethcore/src/types/snapshot_manifest.rs b/ethcore/types/src/snapshot_manifest.rs similarity index 98% rename from ethcore/src/types/snapshot_manifest.rs rename to ethcore/types/src/snapshot_manifest.rs index 58b25b6a7..2dcce2904 100644 --- a/ethcore/src/types/snapshot_manifest.rs +++ b/ethcore/types/src/snapshot_manifest.rs @@ -22,7 +22,6 @@ use util::Bytes; /// Manifest data. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct ManifestData { /// Snapshot format version. pub version: u64, diff --git a/ethcore/src/types/state_diff.rs b/ethcore/types/src/state_diff.rs similarity index 97% rename from ethcore/src/types/state_diff.rs rename to ethcore/types/src/state_diff.rs index 45bd2b533..af28f550f 100644 --- a/ethcore/src/types/state_diff.rs +++ b/ethcore/types/src/state_diff.rs @@ -22,10 +22,9 @@ use std::collections::BTreeMap; use util::Address; use account_diff::*; -#[derive(Debug, PartialEq, Eq, Clone)] -#[cfg_attr(feature = "ipc", binary)] /// Expression for the delta between two system states. Encoded the /// delta of every altered account. +#[derive(Debug, PartialEq, Eq, Clone)] pub struct StateDiff { /// Raw diff key-value pub raw: BTreeMap diff --git a/ethcore/src/types/trace_filter.rs b/ethcore/types/src/trace_filter.rs similarity index 94% rename from ethcore/src/types/trace_filter.rs rename to ethcore/types/src/trace_filter.rs index dd356f64b..4eed19b4c 100644 --- a/ethcore/src/types/trace_filter.rs +++ b/ethcore/types/src/trace_filter.rs @@ -18,10 +18,9 @@ use std::ops::Range; use util::{Address}; -use types::ids::BlockId; +use ids::BlockId; /// Easy to use trace filter. -#[cfg_attr(feature = "ipc", binary)] pub struct Filter { /// Range of filtering. pub range: Range, diff --git a/ethcore/src/types/tree_route.rs b/ethcore/types/src/tree_route.rs similarity index 96% rename from ethcore/src/types/tree_route.rs rename to ethcore/types/src/tree_route.rs index 0b40c8b07..a47e94ee5 100644 --- a/ethcore/src/types/tree_route.rs +++ b/ethcore/types/src/tree_route.rs @@ -20,7 +20,6 @@ use util::H256; /// Represents a tree route between `from` block and `to` block: #[derive(Debug)] -#[cfg_attr(feature = "ipc", binary)] pub struct TreeRoute { /// A vector of hashes of all blocks, ordered from `from` to `to`. pub blocks: Vec, @@ -29,4 +28,3 @@ pub struct TreeRoute { /// An index where best common ancestor would be. pub index: usize, } - diff --git a/ethcore/src/types/verification_queue_info.rs b/ethcore/types/src/verification_queue_info.rs similarity index 98% rename from ethcore/src/types/verification_queue_info.rs rename to ethcore/types/src/verification_queue_info.rs index 570277f09..db818590a 100644 --- a/ethcore/src/types/verification_queue_info.rs +++ b/ethcore/types/src/verification_queue_info.rs @@ -18,7 +18,6 @@ /// Verification queue status #[derive(Debug, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct VerificationQueueInfo { /// Number of queued items pending verification pub unverified_queue_size: usize, diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index 43f3ee38f..e3de99f2b 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -15,6 +15,7 @@ serde = "1.0" serde_derive = "1.0" ethcore = { path = "../ethcore" } ethcore-util = { path = "../util" } +evm = { path = "../ethcore/evm" } [features] evm-debug = ["ethcore/evm-debug-tests"] diff --git a/evmbin/benches/mod.rs b/evmbin/benches/mod.rs index a3017c37e..d7d67a551 100644 --- a/evmbin/benches/mod.rs +++ b/evmbin/benches/mod.rs @@ -31,7 +31,7 @@ extern crate rustc_hex; use self::test::{Bencher, black_box}; use evm::run_vm; -use ethcore::action_params::ActionParams; +use ethcore::evm::action_params::ActionParams; use ethcore_util::U256; use rustc_hex::FromHex; diff --git a/evmbin/src/display/json.rs b/evmbin/src/display/json.rs index 13cba90bb..f12657579 100644 --- a/evmbin/src/display/json.rs +++ b/evmbin/src/display/json.rs @@ -16,7 +16,7 @@ //! JSON VM output. -use ethcore::{evm, trace}; +use ethcore::trace; use std::collections::HashMap; use util::{U256, H256, ToPretty}; @@ -94,7 +94,7 @@ impl trace::VMTracer for Informant { } fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) { - let info = evm::INSTRUCTIONS[self.instruction as usize]; + let info = ::evm::INSTRUCTIONS[self.instruction as usize]; println!( "{{\"pc\":{pc},\"op\":{op},\"opName\":\"{name}\",\"gas\":{gas},\"gasCost\":{gas_cost},\"memory\":{memory},\"stack\":{stack},\"storage\":{storage},\"depth\":{depth}}}", diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index ac060d586..df9b088d0 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -25,6 +25,7 @@ extern crate serde; extern crate serde_derive; extern crate docopt; extern crate ethcore_util as util; +extern crate evm; use std::sync::Arc; use std::{fmt, fs}; @@ -32,7 +33,7 @@ use docopt::Docopt; use rustc_hex::FromHex; use util::{U256, Bytes, Address}; use ethcore::spec; -use ethcore::action_params::ActionParams; +use evm::action_params::ActionParams; mod vm; mod display; diff --git a/evmbin/src/vm.rs b/evmbin/src/vm.rs index 51a8425a1..c4530bb9e 100644 --- a/evmbin/src/vm.rs +++ b/evmbin/src/vm.rs @@ -20,7 +20,7 @@ use std::time::{Instant, Duration}; use util::U256; use ethcore::{trace, spec}; use ethcore::client::{EvmTestClient, EvmTestError}; -use ethcore::action_params::ActionParams; +use evm::action_params::ActionParams; /// VM execution informant pub trait Informant: trace::VMTracer { diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 05cfe1057..e8720e361 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -46,6 +46,7 @@ ethjson = { path = "../json" } ethcore-devtools = { path = "../devtools" } ethcore-light = { path = "../ethcore/light" } ethcore-logger = { path = "../logger" } +evm = { path = "../ethcore/evm" } parity-updater = { path = "../updater" } parity-reactor = { path = "../util/reactor" } rlp = { path = "../util/rlp" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 64e1fc463..0e96ac509 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -52,6 +52,7 @@ extern crate ethkey; extern crate ethstore; extern crate ethsync; extern crate ethcore_logger; +extern crate evm; extern crate fetch; extern crate parity_reactor; extern crate parity_updater as updater; diff --git a/rpc/src/v1/tests/mocked/traces.rs b/rpc/src/v1/tests/mocked/traces.rs index 369cf726a..b1b297eb1 100644 --- a/rpc/src/v1/tests/mocked/traces.rs +++ b/rpc/src/v1/tests/mocked/traces.rs @@ -16,11 +16,13 @@ use std::sync::Arc; -use ethcore::executed::{CallType, Executed, CallError}; +use ethcore::executed::{Executed, CallError}; use ethcore::trace::trace::{Action, Res, Call}; use ethcore::trace::LocalizedTrace; use ethcore::client::TestBlockChainClient; +use evm::CallType; + use jsonrpc_core::IoHandler; use v1::tests::helpers::{TestMinerService}; use v1::{Traces, TracesClient}; diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index 084c19cd1..b01d04c3f 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -21,8 +21,8 @@ use ethcore::trace::{FlatTrace, LocalizedTrace as EthLocalizedTrace, trace, Trac use ethcore::trace as et; use ethcore::state_diff; use ethcore::account_diff; -use ethcore::executed; use ethcore::client::Executed; +use evm; use v1::types::{Bytes, H160, H256, U256}; #[derive(Debug, Serialize)] @@ -256,14 +256,14 @@ pub enum CallType { StaticCall, } -impl From for CallType { - fn from(c: executed::CallType) -> Self { +impl From for CallType { + fn from(c: evm::CallType) -> Self { match c { - executed::CallType::None => CallType::None, - executed::CallType::Call => CallType::Call, - executed::CallType::CallCode => CallType::CallCode, - executed::CallType::DelegateCall => CallType::DelegateCall, - executed::CallType::StaticCall => CallType::StaticCall, + 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, } } }