From ddeef456d726cb281050eb1377967b4e48a87641 Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 6 Aug 2019 18:33:03 +0200 Subject: [PATCH 01/43] Add client-traits crate Move the BlockInfo trait to new crate --- ethcore/client-traits/Cargo.toml | 12 +++++++++++ ethcore/client-traits/src/lib.rs | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 ethcore/client-traits/Cargo.toml create mode 100644 ethcore/client-traits/src/lib.rs diff --git a/ethcore/client-traits/Cargo.toml b/ethcore/client-traits/Cargo.toml new file mode 100644 index 00000000000..cbc5b1934f1 --- /dev/null +++ b/ethcore/client-traits/Cargo.toml @@ -0,0 +1,12 @@ +[package] +description = "Trait definitions relative the ethereum client" +name = "client-traits" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" + +[dependencies] +ethereum-types = "0.6.0" +common-types = { path = "../types" } + diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs new file mode 100644 index 00000000000..84b418e3bda --- /dev/null +++ b/ethcore/client-traits/src/lib.rs @@ -0,0 +1,37 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +use ethereum_types::{Address, H256}; +use common_types::{ + header::Header, + encoded, + ids::BlockId, +}; + +/// Provides various information on a block by it's ID +pub trait BlockInfo { + /// Get raw block header data by block id. + fn block_header(&self, id: BlockId) -> Option; + + /// Get the best block header. + fn best_block_header(&self) -> Header; + + /// Get raw block data by block header hash. + fn block(&self, id: BlockId) -> Option; + + /// Get address code hash at given block's state. + fn code_hash(&self, address: &Address, id: BlockId) -> Option; +} From 0d49c454813ed93b1dcdc8df899b3ef6b6a3b32d Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 6 Aug 2019 18:35:54 +0200 Subject: [PATCH 02/43] New crate `machine` Contains code extracted from ethcore that defines `Machine`, `Externalities` and other execution related code. --- ethcore/machine/Cargo.toml | 46 + ethcore/machine/src/executed.rs | 73 + ethcore/machine/src/executed_block.rs | 101 ++ ethcore/machine/src/executive.rs | 2282 ++++++++++++++++++++++++ ethcore/machine/src/externalities.rs | 672 +++++++ ethcore/machine/src/lib.rs | 40 + ethcore/machine/src/machine.rs | 493 +++++ ethcore/machine/src/substate.rs | 96 + ethcore/machine/src/test_helpers.rs | 60 + ethcore/machine/src/transaction_ext.rs | 43 + ethcore/machine/src/tx_filter.rs | 297 +++ 11 files changed, 4203 insertions(+) create mode 100644 ethcore/machine/Cargo.toml create mode 100644 ethcore/machine/src/executed.rs create mode 100644 ethcore/machine/src/executed_block.rs create mode 100644 ethcore/machine/src/executive.rs create mode 100644 ethcore/machine/src/externalities.rs create mode 100644 ethcore/machine/src/lib.rs create mode 100644 ethcore/machine/src/machine.rs create mode 100644 ethcore/machine/src/substate.rs create mode 100644 ethcore/machine/src/test_helpers.rs create mode 100644 ethcore/machine/src/transaction_ext.rs create mode 100644 ethcore/machine/src/tx_filter.rs diff --git a/ethcore/machine/Cargo.toml b/ethcore/machine/Cargo.toml new file mode 100644 index 00000000000..cd0cfd66bb6 --- /dev/null +++ b/ethcore/machine/Cargo.toml @@ -0,0 +1,46 @@ +[package] +description = "Ethereum state machine" +name = "machine" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" + +[dependencies] +account-state = { path = "../account-state" } +client-traits = { path = "../client-traits" } +common-types = { path = "../types" } +crossbeam-utils = "0.6" +ethabi = "8.0.0" +ethabi-contract = "8.0.0" +ethabi-derive = "8.0.0" +ethcore-builtin = { path = "../builtin" } +ethcore-call-contract = { path = "../call-contract" } +ethcore-io = { path = "../../util/io" } +ethereum-types = "0.6.0" +# Used for tests in other crates through the `test-helpers` feature +ethjson = { path = "../../json", optional = true } +evm = { path = "../evm" } +keccak-hash = "0.2.0" +log = "0.4" +lru-cache = "0.1.2" +parity-bytes = "0.1.0" +parking_lot = "0.8.0" +rlp = "0.4.2" +state-db = { path = "../state-db" } +trace = { path = "../trace" } +trie-vm-factories = { path = "../trie-vm-factories" } +vm = { path = "../vm" } + +[dev-dependencies] +ethcore = { path = "../", features = ["test-helpers"] } +ethcore-io = { path = "../../util/io" } +ethjson = { path = "../../json" } +ethkey = { path = "../../accounts/ethkey" } +macros = { path = "../../util/macros" } +rustc-hex = "1.0" +tempdir = "0.3" +trace = { path = "../trace" } + +[features] +test-helpers = ["ethjson"] diff --git a/ethcore/machine/src/executed.rs b/ethcore/machine/src/executed.rs new file mode 100644 index 00000000000..42c165bcb96 --- /dev/null +++ b/ethcore/machine/src/executed.rs @@ -0,0 +1,73 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Transaction execution format module. + +use ethereum_types::{U256, Address}; +use parity_bytes::Bytes; +use vm; +use trace::{VMTrace, FlatTrace}; +use common_types::{ + state_diff::StateDiff, + log_entry::LogEntry, + errors::ExecutionError, +}; + +/// Transaction execution receipt. +#[derive(Debug, PartialEq, Clone)] +pub struct Executed { + /// True if the outer call/create resulted in an exceptional exit. + pub exception: Option, + + /// Gas paid up front for execution of transaction. + pub gas: U256, + + /// Gas used during execution of transaction. + pub gas_used: U256, + + /// Gas refunded after the execution of transaction. + /// To get gas that was required up front, add `refunded` and `gas_used`. + pub refunded: U256, + + /// Cumulative gas used in current block so far. + /// + /// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)` + /// + /// where `tn` is current transaction. + pub cumulative_gas_used: U256, + + /// Vector of logs generated by transaction. + pub logs: Vec, + + /// Addresses of contracts created during execution of transaction. + /// Ordered from earliest creation. + /// + /// eg. sender creates contract A and A in constructor creates contract B + /// + /// B creation ends first, and it will be the first element of the vector. + pub contracts_created: Vec
, + /// Transaction output. + pub output: Bytes, + /// The trace of this transaction. + pub trace: Vec, + /// The VM trace of this transaction. + pub vm_trace: Option, + /// The state diff, if we traced it. + pub state_diff: Option, +} + +/// Transaction execution result. +pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/machine/src/executed_block.rs b/ethcore/machine/src/executed_block.rs new file mode 100644 index 00000000000..ebe6de1fa2c --- /dev/null +++ b/ethcore/machine/src/executed_block.rs @@ -0,0 +1,101 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +// todo[dvdplm] improve docs +//! `ExecutedBlock` is an underlying data structure used by other block types to store block +//! related info. + +use std::{ + collections::HashSet, + sync::Arc, +}; + +use ethereum_types::{H256, U256}; + +use account_state::State; +use common_types::{ + header::Header, + receipt::Receipt, + transaction::SignedTransaction, +}; +use state_db::StateDB; +use trace::Tracing; +use vm::{EnvInfo, LastHashes}; + +/// An internal type for a block's common elements. +#[derive(Clone)] +pub struct ExecutedBlock { + /// Executed block header. + pub header: Header, + /// Executed transactions. + pub transactions: Vec, + /// Uncles. + pub uncles: Vec
, + /// Transaction receipts. + pub receipts: Vec, + /// Hashes of already executed transactions. + pub transactions_set: HashSet, + /// Underlying state. + pub state: State, + /// Transaction traces. + pub traces: Tracing, + /// Hashes of last 256 blocks. + pub last_hashes: Arc, +} + +impl ExecutedBlock { + /// Create a new block from the given `state`. + pub fn new(state: State, last_hashes: Arc, tracing: bool) -> ExecutedBlock { + ExecutedBlock { + header: Default::default(), + transactions: Default::default(), + uncles: Default::default(), + receipts: Default::default(), + transactions_set: Default::default(), + state, + traces: if tracing { + Tracing::enabled() + } else { + Tracing::Disabled + }, + last_hashes, + } + } + + /// Get the environment info concerning this block. + pub fn env_info(&self) -> EnvInfo { + // TODO: memoise. + EnvInfo { + number: self.header.number(), + author: self.header.author().clone(), + timestamp: self.header.timestamp(), + difficulty: self.header.difficulty().clone(), + last_hashes: self.last_hashes.clone(), + gas_used: self.receipts.last().map_or(U256::zero(), |r| r.gas_used), + gas_limit: self.header.gas_limit().clone(), + } + } + + /// Get mutable access to a state. + pub fn state_mut(&mut self) -> &mut State { + &mut self.state + } + + /// Get mutable reference to traces. + pub fn traces_mut(&mut self) -> &mut Tracing { + &mut self.traces + } +} diff --git a/ethcore/machine/src/executive.rs b/ethcore/machine/src/executive.rs new file mode 100644 index 00000000000..4c81c517ebc --- /dev/null +++ b/ethcore/machine/src/executive.rs @@ -0,0 +1,2282 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Transaction Execution environment. + +use std::{cmp, convert::TryFrom, sync::Arc}; + +use crossbeam_utils::thread; +use ethereum_types::{H256, U256, U512, Address}; +use keccak_hash::keccak; +use parity_bytes::{Bytes, BytesRef}; +use rlp::RlpStream; +use log::trace; + +use account_state::{Backend as StateBackend, State, CleanupMode}; +use evm::{CallType, Finalize, FinalizationResult}; +use vm::{ + self, EnvInfo, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, + ActionValue, Schedule, TrapError, ResumeCall, ResumeCreate +}; +use trie_vm_factories::VmFactory; +use trace::{self, Tracer, VMTracer}; +use common_types::{ + errors::ExecutionError, + transaction::{Action, SignedTransaction}, +}; + +use crate::{ + Machine, + substate::Substate, + externalities::{Externalities, OutputPolicy, OriginInfo}, // todo: make explicit + transaction_ext::Transaction, + executed::Executed, +}; + +#[cfg(debug_assertions)] +/// Roughly estimate what stack size each level of evm depth will use. (Debug build) +const STACK_SIZE_PER_DEPTH: usize = 128 * 1024; + +#[cfg(not(debug_assertions))] +/// Roughly estimate what stack size each level of evm depth will use. +const STACK_SIZE_PER_DEPTH: usize = 24 * 1024; + +#[cfg(debug_assertions)] +/// Entry stack overhead prior to execution. (Debug build) +const STACK_SIZE_ENTRY_OVERHEAD: usize = 100 * 1024; + +#[cfg(not(debug_assertions))] +/// Entry stack overhead prior to execution. +const STACK_SIZE_ENTRY_OVERHEAD: usize = 20 * 1024; + +/// Returns new address created from address, nonce, and code hash +pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address, nonce: &U256, code: &[u8]) -> (Address, Option) { + match address_scheme { + CreateContractAddress::FromSenderAndNonce => { + let mut stream = RlpStream::new_list(2); + stream.append(sender); + stream.append(nonce); + (From::from(keccak(stream.as_raw())), None) + }, + CreateContractAddress::FromSenderSaltAndCodeHash(salt) => { + let code_hash = keccak(code); + let mut buffer = [0u8; 1 + 20 + 32 + 32]; + buffer[0] = 0xff; + &mut buffer[1..(1+20)].copy_from_slice(&sender[..]); + &mut buffer[(1+20)..(1+20+32)].copy_from_slice(&salt[..]); + &mut buffer[(1+20+32)..].copy_from_slice(&code_hash[..]); + (From::from(keccak(&buffer[..])), Some(code_hash)) + }, + CreateContractAddress::FromSenderAndCodeHash => { + let code_hash = keccak(code); + let mut buffer = [0u8; 20 + 32]; + &mut buffer[..20].copy_from_slice(&sender[..]); + &mut buffer[20..].copy_from_slice(&code_hash[..]); + (From::from(keccak(&buffer[..])), Some(code_hash)) + }, + } +} + +/// Convert a finalization result into a VM message call result. +pub fn into_message_call_result(result: vm::Result) -> vm::MessageCallResult { + match result { + Ok(FinalizationResult { gas_left, return_data, apply_state: true }) => vm::MessageCallResult::Success(gas_left, return_data), + Ok(FinalizationResult { gas_left, return_data, apply_state: false }) => vm::MessageCallResult::Reverted(gas_left, return_data), + _ => vm::MessageCallResult::Failed + } +} + +/// Convert a finalization result into a VM contract create result. +pub fn into_contract_create_result(result: vm::Result, address: &Address, substate: &mut Substate) -> vm::ContractCreateResult { + match result { + Ok(FinalizationResult { gas_left, apply_state: true, .. }) => { + substate.contracts_created.push(address.clone()); + vm::ContractCreateResult::Created(address.clone(), gas_left) + }, + Ok(FinalizationResult { gas_left, apply_state: false, return_data }) => { + vm::ContractCreateResult::Reverted(gas_left, return_data) + }, + _ => vm::ContractCreateResult::Failed, + } +} + +/// Get the cleanup mode object from this. +pub fn cleanup_mode<'a>(substate: &'a mut Substate, schedule: &Schedule) -> CleanupMode<'a> { + match (schedule.kill_dust != CleanDustMode::Off, schedule.no_empty, schedule.kill_empty) { + (false, false, _) => CleanupMode::ForceCreate, + (false, true, false) => CleanupMode::NoEmpty, + (false, true, true) | (true, _, _,) => CleanupMode::TrackTouched(&mut substate.touched), + } +} + +/// Transaction execution options. +#[derive(Copy, Clone, PartialEq)] +pub struct TransactOptions { + /// Enable call tracing. + pub tracer: T, + /// Enable VM tracing. + pub vm_tracer: V, + /// Check transaction nonce before execution. + pub check_nonce: bool, + /// Records the output from init contract calls. + pub output_from_init_contract: bool, +} + +impl TransactOptions { + /// Create new `TransactOptions` with given tracer and VM tracer. + pub fn new(tracer: T, vm_tracer: V) -> Self { + TransactOptions { + tracer, + vm_tracer, + check_nonce: true, + output_from_init_contract: false, + } + } + + /// Disables the nonce check + pub fn dont_check_nonce(mut self) -> Self { + self.check_nonce = false; + self + } + + /// Saves the output from contract creation. + pub fn save_output_from_contract(mut self) -> Self { + self.output_from_init_contract = true; + self + } +} + +impl TransactOptions { + /// Creates new `TransactOptions` with default tracing and VM tracing. + pub fn with_tracing_and_vm_tracing() -> Self { + TransactOptions { + tracer: trace::ExecutiveTracer::default(), + vm_tracer: trace::ExecutiveVMTracer::toplevel(), + check_nonce: true, + output_from_init_contract: false, + } + } +} + +impl TransactOptions { + /// Creates new `TransactOptions` with default tracing and no VM tracing. + pub fn with_tracing() -> Self { + TransactOptions { + tracer: trace::ExecutiveTracer::default(), + vm_tracer: trace::NoopVMTracer, + check_nonce: true, + output_from_init_contract: false, + } + } +} + +impl TransactOptions { + /// Creates new `TransactOptions` with no tracing and default VM tracing. + pub fn with_vm_tracing() -> Self { + TransactOptions { + tracer: trace::NoopTracer, + vm_tracer: trace::ExecutiveVMTracer::toplevel(), + check_nonce: true, + output_from_init_contract: false, + } + } +} + +impl TransactOptions { + /// Creates new `TransactOptions` without any tracing. + pub fn with_no_tracing() -> Self { + TransactOptions { + tracer: trace::NoopTracer, + vm_tracer: trace::NoopVMTracer, + check_nonce: true, + output_from_init_contract: false, + } + } +} + +/// Trap result returned by executive. +pub type ExecutiveTrapResult<'a, T> = vm::TrapResult, CallCreateExecutive<'a>>; +/// Trap error for executive. +pub type ExecutiveTrapError<'a> = vm::TrapError, CallCreateExecutive<'a>>; + +enum CallCreateExecutiveKind { + Transfer(ActionParams), + CallBuiltin(ActionParams), + ExecCall(ActionParams, Substate), + ExecCreate(ActionParams, Substate), + ResumeCall(OriginInfo, Box, Substate), + ResumeCreate(OriginInfo, Box, Substate), +} + +/// Executive for a raw call/create action. +pub struct CallCreateExecutive<'a> { + info: &'a EnvInfo, + machine: &'a Machine, + schedule: &'a Schedule, + factory: &'a VmFactory, + depth: usize, + stack_depth: usize, + static_flag: bool, + is_create: bool, + gas: U256, + kind: CallCreateExecutiveKind, +} + +impl<'a> CallCreateExecutive<'a> { + /// Create a new call executive using raw data. + pub fn new_call_raw(params: ActionParams, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule, factory: &'a VmFactory, depth: usize, stack_depth: usize, parent_static_flag: bool) -> Self { + trace!("Executive::call(params={:?}) self.env_info={:?}, parent_static={}", params, info, parent_static_flag); + + let gas = params.gas; + let static_flag = parent_static_flag || params.call_type == CallType::StaticCall; + + // if destination is builtin, try to execute it + let kind = if let Some(builtin) = machine.builtin(¶ms.code_address, info.number) { + // Engines aren't supposed to return builtins until activation, but + // prefer to fail rather than silently break consensus. + if !builtin.is_active(info.number) { + panic!("Consensus failure: engine implementation prematurely enabled built-in at {}", params.code_address); + } + + CallCreateExecutiveKind::CallBuiltin(params) + } else { + if params.code.is_some() { + CallCreateExecutiveKind::ExecCall(params, Substate::new()) + } else { + CallCreateExecutiveKind::Transfer(params) + } + }; + + Self { + info, machine, schedule, factory, depth, stack_depth, static_flag, kind, gas, + is_create: false, + } + } + + /// Create a new create executive using raw data. + pub fn new_create_raw(params: ActionParams, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule, factory: &'a VmFactory, depth: usize, stack_depth: usize, static_flag: bool) -> Self { + trace!("Executive::create(params={:?}) self.env_info={:?}, static={}", params, info, static_flag); + + let gas = params.gas; + + let kind = CallCreateExecutiveKind::ExecCreate(params, Substate::new()); + + Self { + info, machine, schedule, factory, depth, stack_depth, static_flag, kind, gas, + is_create: true, + } + } + + /// If this executive contains an unconfirmed substate, returns a mutable reference to it. + pub fn unconfirmed_substate(&mut self) -> Option<&mut Substate> { + match self.kind { + CallCreateExecutiveKind::ExecCall(_, ref mut unsub) => Some(unsub), + CallCreateExecutiveKind::ExecCreate(_, ref mut unsub) => Some(unsub), + CallCreateExecutiveKind::ResumeCreate(_, _, ref mut unsub) => Some(unsub), + CallCreateExecutiveKind::ResumeCall(_, _, ref mut unsub) => Some(unsub), + CallCreateExecutiveKind::Transfer(..) | CallCreateExecutiveKind::CallBuiltin(..) => None, + } + } + + fn check_static_flag(params: &ActionParams, static_flag: bool, is_create: bool) -> vm::Result<()> { + if is_create { + if static_flag { + return Err(vm::Error::MutableCallInStaticContext); + } + } else { + if (static_flag && + (params.call_type == CallType::StaticCall || params.call_type == CallType::Call)) && + params.value.value() > U256::zero() + { + return Err(vm::Error::MutableCallInStaticContext); + } + } + + Ok(()) + } + + fn check_eip684(params: &ActionParams, state: &State) -> vm::Result<()> { + if state.exists_and_has_code_or_nonce(¶ms.address)? { + return Err(vm::Error::OutOfGas); + } + + Ok(()) + } + + fn transfer_exec_balance(params: &ActionParams, schedule: &Schedule, state: &mut State, substate: &mut Substate) -> vm::Result<()> { + if let ActionValue::Transfer(val) = params.value { + state.transfer_balance(¶ms.sender, ¶ms.address, &val, cleanup_mode(substate, &schedule))?; + } + + Ok(()) + } + + fn transfer_exec_balance_and_init_contract(params: &ActionParams, schedule: &Schedule, state: &mut State, substate: &mut Substate) -> vm::Result<()> { + let nonce_offset = if schedule.no_empty { 1 } else { 0 }.into(); + let prev_bal = state.balance(¶ms.address)?; + if let ActionValue::Transfer(val) = params.value { + state.sub_balance(¶ms.sender, &val, &mut cleanup_mode(substate, &schedule))?; + state.new_contract(¶ms.address, val.saturating_add(prev_bal), nonce_offset, params.code_version)?; + } else { + state.new_contract(¶ms.address, prev_bal, nonce_offset, params.code_version)?; + } + + Ok(()) + } + + fn enact_result(result: &vm::Result, state: &mut State, substate: &mut Substate, un_substate: Substate) { + match *result { + Err(vm::Error::OutOfGas) + | Err(vm::Error::BadJumpDestination {..}) + | Err(vm::Error::BadInstruction {.. }) + | Err(vm::Error::StackUnderflow {..}) + | Err(vm::Error::BuiltIn {..}) + | Err(vm::Error::Wasm {..}) + | Err(vm::Error::OutOfStack {..}) + | Err(vm::Error::MutableCallInStaticContext) + | Err(vm::Error::OutOfBounds) + | Err(vm::Error::Reverted) + | Ok(FinalizationResult { apply_state: false, .. }) => { + state.revert_to_checkpoint(); + }, + Ok(_) | Err(vm::Error::Internal(_)) => { + state.discard_checkpoint(); + substate.accrue(un_substate); + } + } + } + + /// Creates `Externalities` from `Executive`. + fn as_externalities<'any, B: 'any + StateBackend, T, V>( + state: &'any mut State, + info: &'any EnvInfo, + machine: &'any Machine, + schedule: &'any Schedule, + depth: usize, + stack_depth: usize, + static_flag: bool, + origin_info: &'any OriginInfo, + substate: &'any mut Substate, + output: OutputPolicy, + tracer: &'any mut T, + vm_tracer: &'any mut V, + ) -> Externalities<'any, T, V, B> where T: Tracer, V: VMTracer { + Externalities::new(state, info, machine, schedule, depth, stack_depth, origin_info, substate, output, tracer, vm_tracer, static_flag) + } + + /// Execute the executive. If a sub-call/create action is required, a resume trap error is returned. The caller is + /// then expected to call `resume_call` or `resume_create` to continue the execution. + /// + /// Current-level tracing is expected to be handled by caller. + pub fn exec(mut self, state: &mut State, substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> ExecutiveTrapResult<'a, FinalizationResult> { + match self.kind { + CallCreateExecutiveKind::Transfer(ref params) => { + assert!(!self.is_create); + + let mut inner = || { + Self::check_static_flag(params, self.static_flag, self.is_create)?; + Self::transfer_exec_balance(params, self.schedule, state, substate)?; + + Ok(FinalizationResult { + gas_left: params.gas, + return_data: ReturnData::empty(), + apply_state: true, + }) + }; + + Ok(inner()) + }, + CallCreateExecutiveKind::CallBuiltin(ref params) => { + assert!(!self.is_create); + + let mut inner = || { + let builtin = self.machine.builtin(¶ms.code_address, self.info.number).expect("Builtin is_some is checked when creating this kind in new_call_raw; qed"); + + Self::check_static_flag(¶ms, self.static_flag, self.is_create)?; + state.checkpoint(); + Self::transfer_exec_balance(¶ms, self.schedule, state, substate)?; + + let default = []; + let data = if let Some(ref d) = params.data { d as &[u8] } else { &default as &[u8] }; + + let cost = builtin.cost(data); + if cost <= params.gas { + let mut builtin_out_buffer = Vec::new(); + let result = { + let mut builtin_output = BytesRef::Flexible(&mut builtin_out_buffer); + builtin.execute(data, &mut builtin_output) + }; + if let Err(e) = result { + state.revert_to_checkpoint(); + + Err(vm::Error::BuiltIn(e)) + } else { + state.discard_checkpoint(); + + let out_len = builtin_out_buffer.len(); + Ok(FinalizationResult { + gas_left: params.gas - cost, + return_data: ReturnData::new(builtin_out_buffer, 0, out_len), + apply_state: true, + }) + } + } else { + // just drain the whole gas + state.revert_to_checkpoint(); + + Err(vm::Error::OutOfGas) + } + }; + + Ok(inner()) + }, + CallCreateExecutiveKind::ExecCall(params, mut unconfirmed_substate) => { + assert!(!self.is_create); + + { + let static_flag = self.static_flag; + let is_create = self.is_create; + let schedule = self.schedule; + + let mut pre_inner = || { + Self::check_static_flag(¶ms, static_flag, is_create)?; + state.checkpoint(); + Self::transfer_exec_balance(¶ms, schedule, state, substate)?; + Ok(()) + }; + + match pre_inner() { + Ok(()) => (), + Err(err) => return Ok(Err(err)), + } + } + + let origin_info = OriginInfo::from(¶ms); + let exec = self.factory.create(params, self.schedule, self.depth); + + let out = match exec { + Some(exec) => { + let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, OutputPolicy::Return, tracer, vm_tracer); + match exec.exec(&mut ext) { + Ok(val) => Ok(val.finalize(ext)), + Err(err) => Err(err), + } + }, + None => Ok(Err(vm::Error::OutOfGas)), + }; + + let res = match out { + Ok(val) => val, + Err(TrapError::Call(subparams, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Call(subparams, self)); + }, + Err(TrapError::Create(subparams, address, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Create(subparams, address, self)); + }, + }; + + Self::enact_result(&res, state, substate, unconfirmed_substate); + Ok(res) + }, + CallCreateExecutiveKind::ExecCreate(params, mut unconfirmed_substate) => { + assert!(self.is_create); + + { + let static_flag = self.static_flag; + let is_create = self.is_create; + let schedule = self.schedule; + + let mut pre_inner = || { + Self::check_eip684(¶ms, state)?; + Self::check_static_flag(¶ms, static_flag, is_create)?; + state.checkpoint(); + Self::transfer_exec_balance_and_init_contract(¶ms, schedule, state, substate)?; + Ok(()) + }; + + match pre_inner() { + Ok(()) => (), + Err(err) => return Ok(Err(err)), + } + } + + let origin_info = OriginInfo::from(¶ms); + let exec = self.factory.create(params, self.schedule, self.depth); + + let out = match exec { + Some(exec) => { + let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, OutputPolicy::InitContract, tracer, vm_tracer); + match exec.exec(&mut ext) { + Ok(val) => Ok(val.finalize(ext)), + Err(err) => Err(err), + } + }, + None => Ok(Err(vm::Error::OutOfGas)), + }; + + let res = match out { + Ok(val) => val, + Err(TrapError::Call(subparams, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Call(subparams, self)); + }, + Err(TrapError::Create(subparams, address, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Create(subparams, address, self)); + }, + }; + + Self::enact_result(&res, state, substate, unconfirmed_substate); + Ok(res) + }, + CallCreateExecutiveKind::ResumeCall(..) | CallCreateExecutiveKind::ResumeCreate(..) => panic!("This executive has already been executed once."), + } + } + + /// Resume execution from a call trap previsouly trapped by `exec`. + /// + /// Current-level tracing is expected to be handled by caller. + pub fn resume_call(mut self, result: vm::MessageCallResult, state: &mut State, substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> ExecutiveTrapResult<'a, FinalizationResult> { + match self.kind { + CallCreateExecutiveKind::ResumeCall(origin_info, resume, mut unconfirmed_substate) => { + let out = { + let exec = resume.resume_call(result); + + let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, if self.is_create { OutputPolicy::InitContract } else { OutputPolicy::Return }, tracer, vm_tracer); + match exec.exec(&mut ext) { + Ok(val) => Ok(val.finalize(ext)), + Err(err) => Err(err), + } + }; + + let res = match out { + Ok(val) => val, + Err(TrapError::Call(subparams, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Call(subparams, self)); + }, + Err(TrapError::Create(subparams, address, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Create(subparams, address, self)); + }, + }; + + Self::enact_result(&res, state, substate, unconfirmed_substate); + Ok(res) + }, + CallCreateExecutiveKind::ResumeCreate(..) => + panic!("Resumable as create, but called resume_call"), + CallCreateExecutiveKind::Transfer(..) | CallCreateExecutiveKind::CallBuiltin(..) | + CallCreateExecutiveKind::ExecCall(..) | CallCreateExecutiveKind::ExecCreate(..) => + panic!("Not resumable"), + } + } + + /// Resume execution from a create trap previsouly trapped by `exec`. + /// + /// Current-level tracing is expected to be handled by caller. + pub fn resume_create(mut self, result: vm::ContractCreateResult, state: &mut State, substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> ExecutiveTrapResult<'a, FinalizationResult> { + match self.kind { + CallCreateExecutiveKind::ResumeCreate(origin_info, resume, mut unconfirmed_substate) => { + let out = { + let exec = resume.resume_create(result); + + let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, if self.is_create { OutputPolicy::InitContract } else { OutputPolicy::Return }, tracer, vm_tracer); + match exec.exec(&mut ext) { + Ok(val) => Ok(val.finalize(ext)), + Err(err) => Err(err), + } + }; + + let res = match out { + Ok(val) => val, + Err(TrapError::Call(subparams, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Call(subparams, self)); + }, + Err(TrapError::Create(subparams, address, resume)) => { + self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); + return Err(TrapError::Create(subparams, address, self)); + }, + }; + + Self::enact_result(&res, state, substate, unconfirmed_substate); + Ok(res) + }, + CallCreateExecutiveKind::ResumeCall(..) => + panic!("Resumable as call, but called resume_create"), + CallCreateExecutiveKind::Transfer(..) | CallCreateExecutiveKind::CallBuiltin(..) | + CallCreateExecutiveKind::ExecCall(..) | CallCreateExecutiveKind::ExecCreate(..) => + panic!("Not resumable"), + } + } + + /// Execute and consume the current executive. This function handles resume traps and sub-level tracing. The caller is expected to handle current-level tracing. + pub fn consume(self, state: &mut State, top_substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> vm::Result { + let mut last_res = Some((false, self.gas, self.exec(state, top_substate, tracer, vm_tracer))); + + let mut callstack: Vec<(Option
, CallCreateExecutive<'a>)> = Vec::new(); + loop { + match last_res { + None => { + match callstack.pop() { + Some((_, exec)) => { + let second_last = callstack.last_mut(); + let parent_substate = match second_last { + Some((_, ref mut second_last)) => second_last.unconfirmed_substate().expect("Current stack value is created from second last item; second last item must be call or create; qed"), + None => top_substate, + }; + + last_res = Some((exec.is_create, exec.gas, exec.exec(state, parent_substate, tracer, vm_tracer))); + }, + None => panic!("When callstack only had one item and it was executed, this function would return; callstack never reaches zero item; qed"), + } + }, + Some((is_create, gas, Ok(val))) => { + let current = callstack.pop(); + + match current { + Some((address, mut exec)) => { + if is_create { + let address = address.expect("If the last executed status was from a create executive, then the destination address was pushed to the callstack; address is_some if it is_create; qed"); + + match val { + Ok(ref val) if val.apply_state => { + tracer.done_trace_create( + gas - val.gas_left, + &val.return_data, + address + ); + }, + Ok(_) => { + tracer.done_trace_failed(&vm::Error::Reverted); + }, + Err(ref err) => { + tracer.done_trace_failed(err); + }, + } + + vm_tracer.done_subtrace(); + + let second_last = callstack.last_mut(); + let parent_substate = match second_last { + Some((_, ref mut second_last)) => second_last.unconfirmed_substate().expect("Current stack value is created from second last item; second last item must be call or create; qed"), + None => top_substate, + }; + + let contract_create_result = into_contract_create_result(val, &address, exec.unconfirmed_substate().expect("Executive is resumed from a create; it has an unconfirmed substate; qed")); + last_res = Some((exec.is_create, exec.gas, exec.resume_create( + contract_create_result, + state, + parent_substate, + tracer, + vm_tracer + ))); + } else { + match val { + Ok(ref val) if val.apply_state => { + tracer.done_trace_call( + gas - val.gas_left, + &val.return_data, + ); + }, + Ok(_) => { + tracer.done_trace_failed(&vm::Error::Reverted); + }, + Err(ref err) => { + tracer.done_trace_failed(err); + }, + } + + vm_tracer.done_subtrace(); + + let second_last = callstack.last_mut(); + let parent_substate = match second_last { + Some((_, ref mut second_last)) => second_last.unconfirmed_substate().expect("Current stack value is created from second last item; second last item must be call or create; qed"), + None => top_substate, + }; + + last_res = Some((exec.is_create, exec.gas, exec.resume_call( + into_message_call_result(val), + state, + parent_substate, + tracer, + vm_tracer + ))); + } + }, + None => return val, + } + }, + Some((_, _, Err(TrapError::Call(subparams, resume)))) => { + tracer.prepare_trace_call(&subparams, resume.depth + 1, resume.machine.builtin(&subparams.address, resume.info.number).is_some()); + vm_tracer.prepare_subtrace(subparams.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); + + let sub_exec = CallCreateExecutive::new_call_raw( + subparams, + resume.info, + resume.machine, + resume.schedule, + resume.factory, + resume.depth + 1, + resume.stack_depth, + resume.static_flag, + ); + + callstack.push((None, resume)); + callstack.push((None, sub_exec)); + last_res = None; + }, + Some((_, _, Err(TrapError::Create(subparams, address, resume)))) => { + tracer.prepare_trace_create(&subparams); + vm_tracer.prepare_subtrace(subparams.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); + + let sub_exec = CallCreateExecutive::new_create_raw( + subparams, + resume.info, + resume.machine, + resume.schedule, + resume.factory, + resume.depth + 1, + resume.stack_depth, + resume.static_flag + ); + + callstack.push((Some(address), resume)); + callstack.push((None, sub_exec)); + last_res = None; + }, + } + } + } +} + +/// Transaction executor. +pub struct Executive<'a, B: 'a> { + state: &'a mut State, + info: &'a EnvInfo, + machine: &'a Machine, + schedule: &'a Schedule, + depth: usize, + static_flag: bool, +} + +impl<'a, B: 'a + StateBackend> Executive<'a, B> { + /// Basic constructor. + pub fn new(state: &'a mut State, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule) -> Self { + Executive { + state: state, + info: info, + machine: machine, + schedule: schedule, + depth: 0, + static_flag: false, + } + } + + /// Populates executive from parent properties. Increments executive depth. + pub fn from_parent(state: &'a mut State, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule, parent_depth: usize, static_flag: bool) -> Self { + Executive { + state: state, + info: info, + machine: machine, + schedule: schedule, + depth: parent_depth + 1, + static_flag: static_flag, + } + } + + /// This function should be used to execute transaction. + pub fn transact(&'a mut self, t: &SignedTransaction, options: TransactOptions) + -> Result, ExecutionError> where T: Tracer, V: VMTracer, + { + self.transact_with_tracer(t, options.check_nonce, options.output_from_init_contract, options.tracer, options.vm_tracer) + } + + /// Execute a transaction in a "virtual" context. + /// This will ensure the caller has enough balance to execute the desired transaction. + /// Used for extra-block executions for things like consensus contracts and RPCs + pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) + -> Result, ExecutionError> where T: Tracer, V: VMTracer, + { + let sender = t.sender(); + let balance = self.state.balance(&sender)?; + let needed_balance = t.value.saturating_add(t.gas.saturating_mul(t.gas_price)); + if balance < needed_balance { + // give the sender a sufficient balance + self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?; + } + + self.transact(t, options) + } + + /// Execute transaction/call with tracing enabled + fn transact_with_tracer( + &'a mut self, + t: &SignedTransaction, + check_nonce: bool, + output_from_create: bool, + mut tracer: T, + mut vm_tracer: V + ) -> Result, ExecutionError> where T: Tracer, V: VMTracer { + let sender = t.sender(); + let nonce = self.state.nonce(&sender)?; + + let schedule = self.schedule; + let base_gas_required = U256::from(t.gas_required(&schedule)); + + if t.gas < base_gas_required { + return Err(ExecutionError::NotEnoughBaseGas { required: base_gas_required, got: t.gas }); + } + + if !t.is_unsigned() && check_nonce && schedule.kill_dust != CleanDustMode::Off && !self.state.exists(&sender)? { + return Err(ExecutionError::SenderMustExist); + } + + let init_gas = t.gas - base_gas_required; + + // validate transaction nonce + if check_nonce && t.nonce != nonce { + return Err(ExecutionError::InvalidNonce { expected: nonce, got: t.nonce }); + } + + // validate if transaction fits into given block + if self.info.gas_used + t.gas > self.info.gas_limit { + return Err(ExecutionError::BlockGasLimitReached { + gas_limit: self.info.gas_limit, + gas_used: self.info.gas_used, + gas: t.gas + }); + } + + // TODO: we might need bigints here, or at least check overflows. + let balance = self.state.balance(&sender)?; + let gas_cost = t.gas.full_mul(t.gas_price); + let total_cost = U512::from(t.value) + gas_cost; + + // avoid unaffordable transactions + let balance512 = U512::from(balance); + if balance512 < total_cost { + return Err(ExecutionError::NotEnoughCash { required: total_cost, got: balance512 }); + } + + let mut substate = Substate::new(); + + // NOTE: there can be no invalid transactions from this point. + if !schedule.keep_unsigned_nonce || !t.is_unsigned() { + self.state.inc_nonce(&sender)?; + } + self.state.sub_balance( + &sender, + &U256::try_from(gas_cost).expect("Total cost (value + gas_cost) is lower than max allowed balance (U256); gas_cost has to fit U256; qed"), + &mut cleanup_mode(&mut substate, &schedule) + )?; + + let (result, output) = match t.action { + Action::Create => { + let (new_address, code_hash) = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &nonce, &t.data); + let params = ActionParams { + code_address: new_address.clone(), + code_hash: code_hash, + address: new_address, + sender: sender.clone(), + origin: sender.clone(), + gas: init_gas, + gas_price: t.gas_price, + value: ActionValue::Transfer(t.value), + code: Some(Arc::new(t.data.clone())), + code_version: schedule.latest_version, + data: None, + call_type: CallType::None, + params_type: vm::ParamsType::Embedded, + }; + let res = self.create(params, &mut substate, &mut tracer, &mut vm_tracer); + let out = match &res { + Ok(res) if output_from_create => res.return_data.to_vec(), + _ => Vec::new(), + }; + (res, out) + }, + Action::Call(ref address) => { + let params = ActionParams { + code_address: address.clone(), + address: address.clone(), + sender: sender.clone(), + origin: sender.clone(), + gas: init_gas, + gas_price: t.gas_price, + value: ActionValue::Transfer(t.value), + code: self.state.code(address)?, + code_hash: self.state.code_hash(address)?, + code_version: self.state.code_version(address)?, + data: Some(t.data.clone()), + call_type: CallType::Call, + params_type: vm::ParamsType::Separate, + }; + let res = self.call(params, &mut substate, &mut tracer, &mut vm_tracer); + let out = match &res { + Ok(res) => res.return_data.to_vec(), + _ => Vec::new(), + }; + (res, out) + } + }; + + // finalize here! + Ok(self.finalize(t, substate, result, output, tracer.drain(), vm_tracer.drain())?) + } + + /// Calls contract function with given contract params and stack depth. + /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). + /// Modifies the substate and the output. + /// Returns either gas_left or `vm::Error`. + pub fn call_with_stack_depth( + &mut self, + params: ActionParams, + substate: &mut Substate, + stack_depth: usize, + tracer: &mut T, + vm_tracer: &mut V + ) -> vm::Result where T: Tracer, V: VMTracer { + tracer.prepare_trace_call(¶ms, self.depth, self.machine.builtin(¶ms.address, self.info.number).is_some()); + vm_tracer.prepare_subtrace(params.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); + + let gas = params.gas; + + let vm_factory = self.state.vm_factory(); + let result = CallCreateExecutive::new_call_raw( + params, + self.info, + self.machine, + self.schedule, + &vm_factory, + self.depth, + stack_depth, + self.static_flag + ).consume(self.state, substate, tracer, vm_tracer); + + match result { + Ok(ref val) if val.apply_state => { + tracer.done_trace_call( + gas - val.gas_left, + &val.return_data, + ); + }, + Ok(_) => { + tracer.done_trace_failed(&vm::Error::Reverted); + }, + Err(ref err) => { + tracer.done_trace_failed(err); + }, + } + vm_tracer.done_subtrace(); + + result + } + + /// Calls contract function with given contract params, if the stack depth is above a threshold, create a new thread + /// to execute it. + pub fn call_with_crossbeam( + &mut self, + params: ActionParams, + substate: &mut Substate, + stack_depth: usize, + tracer: &mut T, + vm_tracer: &mut V + ) -> vm::Result where T: Tracer, V: VMTracer { + let local_stack_size = ethcore_io::LOCAL_STACK_SIZE.with(|sz| sz.get()); + let depth_threshold = local_stack_size.saturating_sub(STACK_SIZE_ENTRY_OVERHEAD) / STACK_SIZE_PER_DEPTH; + + if stack_depth != depth_threshold { + self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) + } else { + thread::scope(|scope| { + let stack_size = cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size); + scope.builder() + .stack_size(stack_size) + .spawn(|_| { + self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) + }) + .expect("Sub-thread creation cannot fail; the host might run out of resources; qed") + .join() + }) + .expect("Sub-thread never panics; qed") + .expect("Sub-thread never panics; qed") + } + } + + /// Calls contract function with given contract params. + pub fn call( + &mut self, + params: ActionParams, + substate: &mut Substate, + tracer: &mut T, + vm_tracer: &mut V + ) -> vm::Result where T: Tracer, V: VMTracer { + self.call_with_stack_depth(params, substate, 0, tracer, vm_tracer) + } + + /// Creates contract with given contract params and stack depth. + /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). + /// Modifies the substate. + pub fn create_with_stack_depth( + &mut self, + params: ActionParams, + substate: &mut Substate, + stack_depth: usize, + tracer: &mut T, + vm_tracer: &mut V, + ) -> vm::Result where T: Tracer, V: VMTracer { + tracer.prepare_trace_create(¶ms); + vm_tracer.prepare_subtrace(params.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); + + let address = params.address; + let gas = params.gas; + + let vm_factory = self.state.vm_factory(); + let result = CallCreateExecutive::new_create_raw( + params, + self.info, + self.machine, + self.schedule, + &vm_factory, + self.depth, + stack_depth, + self.static_flag + ).consume(self.state, substate, tracer, vm_tracer); + + match result { + Ok(ref val) if val.apply_state => { + tracer.done_trace_create( + gas - val.gas_left, + &val.return_data, + address, + ); + }, + Ok(_) => { + tracer.done_trace_failed(&vm::Error::Reverted); + }, + Err(ref err) => { + tracer.done_trace_failed(err); + }, + } + vm_tracer.done_subtrace(); + + result + } + + /// Creates contract with given contract params, if the stack depth is above a threshold, create a new thread to + /// execute it. + pub fn create_with_crossbeam( + &mut self, + params: ActionParams, + substate: &mut Substate, + stack_depth: usize, + tracer: &mut T, + vm_tracer: &mut V, + ) -> vm::Result where T: Tracer, V: VMTracer { + let local_stack_size = ethcore_io::LOCAL_STACK_SIZE.with(|sz| sz.get()); + let depth_threshold = local_stack_size.saturating_sub(STACK_SIZE_ENTRY_OVERHEAD) / STACK_SIZE_PER_DEPTH; + + if stack_depth != depth_threshold { + self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) + } else { + thread::scope(|scope| { + let stack_size = cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size); + scope.builder() + .stack_size(stack_size) + .spawn(|_| { + self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) + }) + .expect("Sub-thread creation cannot fail; the host might run out of resources; qed") + .join() + }) + .expect("Sub-thread never panics; qed") + .expect("Sub-thread never panics; qed") + } + } + + /// Creates contract with given contract params. + pub fn create( + &mut self, + params: ActionParams, + substate: &mut Substate, + tracer: &mut T, + vm_tracer: &mut V, + ) -> vm::Result where T: Tracer, V: VMTracer { + self.create_with_stack_depth(params, substate, 0, tracer, vm_tracer) + } + + /// Finalizes the transaction (does refunds and suicides). + fn finalize( + &mut self, + t: &SignedTransaction, + mut substate: Substate, + result: vm::Result, + output: Bytes, + trace: Vec, + vm_trace: Option + ) -> Result, ExecutionError> { + let schedule = self.schedule; + + // refunds from SSTORE nonzero -> zero + assert!(substate.sstore_clears_refund >= 0, "On transaction level, sstore clears refund cannot go below zero."); + let sstore_refunds = U256::from(substate.sstore_clears_refund as u64); + // refunds from contract suicides + let suicide_refunds = U256::from(schedule.suicide_refund_gas) * U256::from(substate.suicides.len()); + let refunds_bound = sstore_refunds + suicide_refunds; + + // real ammount to refund + let gas_left_prerefund = match result { Ok(FinalizationResult{ gas_left, .. }) => gas_left, _ => 0.into() }; + let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) >> 1); + let gas_left = gas_left_prerefund + refunded; + + let gas_used = t.gas.saturating_sub(gas_left); + let (refund_value, overflow_1) = gas_left.overflowing_mul(t.gas_price); + let (fees_value, overflow_2) = gas_used.overflowing_mul(t.gas_price); + if overflow_1 || overflow_2 { + return Err(ExecutionError::TransactionMalformed("U256 Overflow".to_string())); + } + + + trace!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n", + t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value); + + let sender = t.sender(); + trace!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, sender); + // Below: NoEmpty is safe since the sender must already be non-null to have sent this transaction + self.state.add_balance(&sender, &refund_value, CleanupMode::NoEmpty)?; + trace!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author); + self.state.add_balance(&self.info.author, &fees_value, cleanup_mode(&mut substate, &schedule))?; + + // perform suicides + for address in &substate.suicides { + self.state.kill_account(address); + } + + // perform garbage-collection + let min_balance = if schedule.kill_dust != CleanDustMode::Off { Some(U256::from(schedule.tx_gas).overflowing_mul(t.gas_price).0) } else { None }; + self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?; + + match result { + Err(vm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), + Err(exception) => { + Ok(Executed { + exception: Some(exception), + gas: t.gas, + gas_used: t.gas, + refunded: U256::zero(), + cumulative_gas_used: self.info.gas_used + t.gas, + logs: vec![], + contracts_created: vec![], + output: output, + trace: trace, + vm_trace: vm_trace, + state_diff: None, + }) + }, + Ok(r) => { + Ok(Executed { + exception: if r.apply_state { None } else { Some(vm::Error::Reverted) }, + gas: t.gas, + gas_used: gas_used, + refunded: refunded, + cumulative_gas_used: self.info.gas_used + gas_used, + logs: substate.logs, + contracts_created: substate.contracts_created, + output: output, + trace: trace, + vm_trace: vm_trace, + state_diff: None, + }) + }, + } + } +} + +#[cfg(test)] +#[allow(dead_code)] +mod tests { + use std::{ + sync::Arc, + str::FromStr, + collections::HashSet, + }; + + use rustc_hex::FromHex; + use ethereum_types::{H256, U256, U512, Address, BigEndianHash}; + + use account_state::CleanupMode; + use common_types::{ + errors::ExecutionError, + transaction::{Action, Transaction}, + }; +// use ethcore::ethereum; + use ethkey::{Generator, Random}; + use evm::{Factory, VMType, evm_test, evm_test_ignore}; + use macros::vec_into; + use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; + use ::trace::{ + trace, + FlatTrace, Tracer, NoopTracer, ExecutiveTracer, + VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer, + }; + + use super::*; + + use crate::{ + Machine, + substate::Substate, + test_helpers::{ + new_frontier_test_machine, + new_byzantium_test_machine, + new_constantinople_test_machine, + new_kovan_wasm_test_machine, + }, + }; + use ethcore::test_helpers::{get_temp_state_with_factory, get_temp_state}; + + fn make_frontier_machine(max_depth: usize) -> Machine { + let mut machine = new_frontier_test_machine(); + machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth)); + machine + } + + fn make_byzantium_machine(max_depth: usize) -> Machine { + let mut machine = new_byzantium_test_machine(); + machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth)); + machine + } + + #[test] + fn test_cleanup_mode() { + let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let mut touched = HashSet::new(); + touched.insert(address); + + let mut substate = Substate::default(); + substate.touched = touched.clone(); + + assert_eq!(CleanupMode::ForceCreate, cleanup_mode(&mut substate, &Schedule::new_frontier())); + assert_eq!(CleanupMode::ForceCreate, cleanup_mode(&mut substate, &Schedule::new_homestead())); + assert_eq!(CleanupMode::TrackTouched(&mut touched), cleanup_mode(&mut substate, &Schedule::new_byzantium())); + assert_eq!(CleanupMode::TrackTouched(&mut touched), cleanup_mode(&mut substate, &Schedule::new_constantinople())); + + assert_eq!(CleanupMode::TrackTouched(&mut touched), cleanup_mode(&mut substate, &{ + let mut schedule = Schedule::new_homestead(); + schedule.kill_dust = CleanDustMode::BasicOnly; + schedule + })); + + assert_eq!(CleanupMode::NoEmpty, cleanup_mode(&mut substate, &{ + let mut schedule = Schedule::new_homestead(); + schedule.no_empty = true; + schedule + })); + } + + #[test] + fn test_contract_address() { + let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let expected_address = Address::from_str("3f09c73a5ed19289fb9bdc72f1742566df146f56").unwrap(); + assert_eq!(expected_address, contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::from(88), &[]).0); + } + + // TODO: replace params with transactions! + evm_test!{test_sender_balance: test_sender_balance_int} + fn test_sender_balance(factory: Factory) { + let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + let mut params = ActionParams::default(); + params.address = address.clone(); + params.sender = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new("3331600055".from_hex().unwrap())); + params.value = ActionValue::Transfer(U256::from(0x7)); + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(0x100u64), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(79_975)); + assert_eq!(state.storage_at(&address, &H256::zero()).unwrap(), BigEndianHash::from_uint(&U256::from(0xf9u64))); + assert_eq!(state.balance(&sender).unwrap(), U256::from(0xf9)); + assert_eq!(state.balance(&address).unwrap(), U256::from(0x7)); + assert_eq!(substate.contracts_created.len(), 0); + + // TODO: just test state root. + } + + evm_test!{test_create_contract_out_of_depth: test_create_contract_out_of_depth_int} + fn test_create_contract_out_of_depth(factory: Factory) { + // code: + // + // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? + // 60 00 - push 0 + // 52 + // 60 1d - push 29 + // 60 03 - push 3 + // 60 17 - push 17 + // f0 - create + // 60 00 - push 0 + // 55 sstore + // + // other code: + // + // 60 10 - push 16 + // 80 - duplicate first stack item + // 60 0c - push 12 + // 60 00 - push 0 + // 39 - copy current code to memory + // 60 00 - push 0 + // f3 - return + + let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); + + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + // TODO: add tests for 'callcreate' + //let next_address = contract_address(&address, &U256::zero()); + let mut params = ActionParams::default(); + params.address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from(100)); + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(62_976)); + // ended with max depth + assert_eq!(substate.contracts_created.len(), 0); + } + + #[test] + fn test_call_to_precompiled_tracing() { + // code: + // + // 60 00 - push 00 out size + // 60 00 - push 00 out offset + // 60 00 - push 00 in size + // 60 00 - push 00 in offset + // 60 01 - push 01 value + // 60 03 - push 03 to + // 61 ffff - push fff gas + // f1 - CALL + + let code = "60006000600060006001600361fffff1".from_hex().unwrap(); + let sender = Address::from_str("4444444444444444444444444444444444444444").unwrap(); + let address = Address::from_str("5555555555555555555555555555555555555555").unwrap(); + + let mut params = ActionParams::default(); + params.address = address.clone(); + params.code_address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from(100)); + params.call_type = CallType::Call; + let mut state = get_temp_state(); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_byzantium_machine(5); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + let mut tracer = ExecutiveTracer::default(); + let mut vm_tracer = ExecutiveVMTracer::toplevel(); + + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params, &mut substate, &mut tracer, &mut vm_tracer).unwrap(); + + assert_eq!(tracer.drain(), vec![FlatTrace { + action: trace::Action::Call(trace::Call { + from: Address::from_str("4444444444444444444444444444444444444444").unwrap(), + to: Address::from_str("5555555555555555555555555555555555555555").unwrap(), + value: 100.into(), + gas: 100_000.into(), + input: vec![], + call_type: CallType::Call + }), + result: trace::Res::Call(trace::CallResult { + gas_used: 33021.into(), + output: vec![] + }), + subtraces: 1, + trace_address: Default::default() + }, FlatTrace { + action: trace::Action::Call(trace::Call { + from: Address::from_str("5555555555555555555555555555555555555555").unwrap(), + to: Address::from_str("0000000000000000000000000000000000000003").unwrap(), + value: 1.into(), + gas: 66560.into(), + input: vec![], + call_type: CallType::Call + }), result: trace::Res::Call(trace::CallResult { + gas_used: 600.into(), + output: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 17, 133, 165, 197, 233, 252, 84, 97, 40, 8, 151, 126, 232, 245, 72, 178, 37, 141, 49] + }), + subtraces: 0, + trace_address: vec![0].into_iter().collect(), + }]); + } + + #[test] + // Tracing is not suported in JIT + fn test_call_to_create() { + // code: + // + // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? + // 60 00 - push 0 + // 52 + // 60 1d - push 29 + // 60 03 - push 3 + // 60 17 - push 23 + // f0 - create + // 60 00 - push 0 + // 55 sstore + // + // other code: + // + // 60 10 - push 16 + // 80 - duplicate first stack item + // 60 0c - push 12 + // 60 00 - push 0 + // 39 - copy current code to memory + // 60 00 - push 0 + // f3 - return + + let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); + + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + // TODO: add tests for 'callcreate' + //let next_address = contract_address(&address, &U256::zero()); + let mut params = ActionParams::default(); + params.address = address.clone(); + params.code_address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from(100)); + params.call_type = CallType::Call; + let mut state = get_temp_state(); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(5); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + let mut tracer = ExecutiveTracer::default(); + let mut vm_tracer = ExecutiveVMTracer::toplevel(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params, &mut substate, &mut tracer, &mut vm_tracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(44_752)); + + let expected_trace = vec![FlatTrace { + trace_address: Default::default(), + subtraces: 1, + action: trace::Action::Call(trace::Call { + from: Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(), + to: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), + value: 100.into(), + gas: 100000.into(), + input: vec![], + call_type: CallType::Call, + }), + result: trace::Res::Call(trace::CallResult { + gas_used: U256::from(55_248), + output: vec![], + }), + }, FlatTrace { + trace_address: vec![0].into_iter().collect(), + subtraces: 0, + action: trace::Action::Create(trace::Create { + from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), + value: 23.into(), + gas: 67979.into(), + init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85] + }), + result: trace::Res::Create(trace::CreateResult { + gas_used: U256::from(3224), + address: Address::from_str("c6d80f262ae5e0f164e5fde365044d7ada2bfa34").unwrap(), + code: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] + }), + }]; + + assert_eq!(tracer.drain(), expected_trace); + + let expected_vm_trace = VMTrace { + parent_step: 0, + code: vec![124, 96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85, 96, 0, 82, 96, 29, 96, 3, 96, 23, 240, 96, 0, 85], + operations: vec![ + VMOperation { pc: 0, instruction: 124, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99997.into(), stack_push: vec_into![U256::from_dec_str("2589892687202724018173567190521546555304938078595079151649957320078677").unwrap()], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 30, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99994.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 32, instruction: 82, gas_cost: 6.into(), executed: Some(VMExecutedOperation { gas_used: 99988.into(), stack_push: vec_into![], mem_diff: Some(MemoryDiff { offset: 0, data: vec![0, 0, 0, 96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85] }), store_diff: None }) }, + VMOperation { pc: 33, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99985.into(), stack_push: vec_into![29], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 35, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99982.into(), stack_push: vec_into![3], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 37, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99979.into(), stack_push: vec_into![23], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 39, instruction: 240, gas_cost: 99979.into(), executed: Some(VMExecutedOperation { gas_used: 64755.into(), stack_push: vec_into![U256::from_dec_str("1135198453258042933984631383966629874710669425204").unwrap()], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 40, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 64752.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 42, instruction: 85, gas_cost: 20000.into(), executed: Some(VMExecutedOperation { gas_used: 44752.into(), stack_push: vec_into![], mem_diff: None, store_diff: Some(StorageDiff { location: 0.into(), value: U256::from_dec_str("1135198453258042933984631383966629874710669425204").unwrap() }) }) } + ], + subs: vec![ + VMTrace { + parent_step: 6, + code: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], + operations: vec![ + VMOperation { pc: 0, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67976.into(), stack_push: vec_into![16], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 2, instruction: 128, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67973.into(), stack_push: vec_into![16, 16], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 3, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67970.into(), stack_push: vec_into![12], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 5, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67967.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 7, instruction: 57, gas_cost: 9.into(), executed: Some(VMExecutedOperation { gas_used: 67958.into(), stack_push: vec_into![], mem_diff: Some(MemoryDiff { offset: 0, data: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] }), store_diff: None }) }, + VMOperation { pc: 8, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67955.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 10, instruction: 243, gas_cost: 0.into(), executed: Some(VMExecutedOperation { gas_used: 67955.into(), stack_push: vec_into![], mem_diff: None, store_diff: None }) } + ], + subs: vec![] + } + ] + }; + assert_eq!(vm_tracer.drain().unwrap(), expected_vm_trace); + } + + #[test] + fn test_trace_reverted_create() { + // code: + // + // 65 60016000fd - push 5 bytes + // 60 00 - push 0 + // 52 mstore + // 60 05 - push 5 + // 60 1b - push 27 + // 60 17 - push 23 + // f0 - create + // 60 00 - push 0 + // 55 sstore + // + // other code: + // + // 60 01 + // 60 00 + // fd - revert + + let code = "6460016000fd6000526005601b6017f0600055".from_hex().unwrap(); + + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + let mut params = ActionParams::default(); + params.address = address.clone(); + params.code_address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from(100)); + params.call_type = CallType::Call; + let mut state = get_temp_state(); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = new_byzantium_test_machine(); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + let mut tracer = ExecutiveTracer::default(); + let mut vm_tracer = ExecutiveVMTracer::toplevel(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params, &mut substate, &mut tracer, &mut vm_tracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(62967)); + + let expected_trace = vec![FlatTrace { + trace_address: Default::default(), + subtraces: 1, + action: trace::Action::Call(trace::Call { + from: Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(), + to: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), + value: 100.into(), + gas: 100_000.into(), + input: vec![], + call_type: CallType::Call, + }), + result: trace::Res::Call(trace::CallResult { + gas_used: U256::from(37_033), + output: vec![], + }), + }, FlatTrace { + trace_address: vec![0].into_iter().collect(), + subtraces: 0, + action: trace::Action::Create(trace::Create { + from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), + value: 23.into(), + gas: 66_917.into(), + init: vec![0x60, 0x01, 0x60, 0x00, 0xfd] + }), + result: trace::Res::FailedCreate(vm::Error::Reverted.into()), + }]; + + assert_eq!(tracer.drain(), expected_trace); + } + + #[test] + fn test_create_contract() { + // Tracing is not supported in JIT + // code: + // + // 60 10 - push 16 + // 80 - duplicate first stack item + // 60 0c - push 12 + // 60 00 - push 0 + // 39 - copy current code to memory + // 60 00 - push 0 + // f3 - return + + let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(); + + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + // TODO: add tests for 'callcreate' + //let next_address = contract_address(&address, &U256::zero()); + let mut params = ActionParams::default(); + params.address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(100.into()); + let mut state = get_temp_state(); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(5); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + let mut tracer = ExecutiveTracer::default(); + let mut vm_tracer = ExecutiveVMTracer::toplevel(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.create(params.clone(), &mut substate, &mut tracer, &mut vm_tracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(96_776)); + + let expected_trace = vec![FlatTrace { + trace_address: Default::default(), + subtraces: 0, + action: trace::Action::Create(trace::Create { + from: params.sender, + value: 100.into(), + gas: params.gas, + init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], + }), + result: trace::Res::Create(trace::CreateResult { + gas_used: U256::from(3224), + address: params.address, + code: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] + }), + }]; + + assert_eq!(tracer.drain(), expected_trace); + + let expected_vm_trace = VMTrace { + parent_step: 0, + code: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], + operations: vec![ + VMOperation { pc: 0, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99997.into(), stack_push: vec_into![16], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 2, instruction: 128, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99994.into(), stack_push: vec_into![16, 16], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 3, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99991.into(), stack_push: vec_into![12], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 5, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99988.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 7, instruction: 57, gas_cost: 9.into(), executed: Some(VMExecutedOperation { gas_used: 99979.into(), stack_push: vec_into![], mem_diff: Some(MemoryDiff { offset: 0, data: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] }), store_diff: None }) }, + VMOperation { pc: 8, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99976.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, + VMOperation { pc: 10, instruction: 243, gas_cost: 0.into(), executed: Some(VMExecutedOperation { gas_used: 99976.into(), stack_push: vec_into![], mem_diff: None, store_diff: None }) } + ], + subs: vec![] + }; + assert_eq!(vm_tracer.drain().unwrap(), expected_vm_trace); + } + + evm_test!{test_create_contract_value_too_high: test_create_contract_value_too_high_int} + fn test_create_contract_value_too_high(factory: Factory) { + // code: + // + // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? + // 60 00 - push 0 + // 52 + // 60 1d - push 29 + // 60 03 - push 3 + // 60 e6 - push 230 + // f0 - create a contract trying to send 230. + // 60 00 - push 0 + // 55 sstore + // + // other code: + // + // 60 10 - push 16 + // 80 - duplicate first stack item + // 60 0c - push 12 + // 60 00 - push 0 + // 39 - copy current code to memory + // 60 00 - push 0 + // f3 - return + + let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().unwrap(); + + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + // TODO: add tests for 'callcreate' + //let next_address = contract_address(&address, &U256::zero()); + let mut params = ActionParams::default(); + params.address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from(100)); + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(62_976)); + assert_eq!(substate.contracts_created.len(), 0); + } + + evm_test!{test_create_contract_without_max_depth: test_create_contract_without_max_depth_int} + fn test_create_contract_without_max_depth(factory: Factory) { + // code: + // + // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? + // 60 00 - push 0 + // 52 + // 60 1d - push 29 + // 60 03 - push 3 + // 60 17 - push 17 + // f0 - create + // 60 00 - push 0 + // 55 sstore + // + // other code: + // + // 60 10 - push 16 + // 80 - duplicate first stack item + // 60 0c - push 12 + // 60 00 - push 0 + // 39 - copy current code to memory + // 60 00 - push 0 + // f3 - return + + let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap(); + + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &[]).0; + let mut params = ActionParams::default(); + params.address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from(100)); + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(1024); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap(); + } + + assert_eq!(substate.contracts_created.len(), 1); + assert_eq!(substate.contracts_created[0], next_address); + } + + // test is incorrect, mk + // TODO: fix (preferred) or remove + evm_test_ignore!{test_aba_calls: test_aba_calls_int} + fn test_aba_calls(factory: Factory) { + // 60 00 - push 0 + // 60 00 - push 0 + // 60 00 - push 0 + // 60 00 - push 0 + // 60 18 - push 18 + // 73 945304eb96065b2a98b57a48a06ae28d285a71b5 - push this address + // 61 03e8 - push 1000 + // f1 - message call + // 58 - get PC + // 55 - sstore + + let code_a = "6000600060006000601873945304eb96065b2a98b57a48a06ae28d285a71b56103e8f15855".from_hex().unwrap(); + + // 60 00 - push 0 + // 60 00 - push 0 + // 60 00 - push 0 + // 60 00 - push 0 + // 60 17 - push 17 + // 73 0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 - push this address + // 61 0x01f4 - push 500 + // f1 - message call + // 60 01 - push 1 + // 01 - add + // 58 - get PC + // 55 - sstore + let code_b = "60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66101f4f16001015855".from_hex().unwrap(); + + let address_a = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let address_b = Address::from_str("945304eb96065b2a98b57a48a06ae28d285a71b5" ).unwrap(); + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + + let mut params = ActionParams::default(); + params.address = address_a.clone(); + params.sender = sender.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code_a.clone())); + params.value = ActionValue::Transfer(U256::from(100_000)); + + let mut state = get_temp_state_with_factory(factory); + state.init_code(&address_a, code_a.clone()).unwrap(); + state.init_code(&address_b, code_b.clone()).unwrap(); + state.add_balance(&sender, &U256::from(100_000), CleanupMode::NoEmpty).unwrap(); + + let info = EnvInfo::default(); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(73_237)); + assert_eq!( + state.storage_at( + &address_a, + &BigEndianHash::from_uint(&U256::from(0x23)), + ).unwrap(), + BigEndianHash::from_uint(&U256::from(1)), + ); + } + + // test is incorrect, mk + // TODO: fix (preferred) or remove + evm_test_ignore!{test_recursive_bomb1: test_recursive_bomb1_int} + fn test_recursive_bomb1(factory: Factory) { + // 60 01 - push 1 + // 60 00 - push 0 + // 54 - sload + // 01 - add + // 60 00 - push 0 + // 55 - sstore + // 60 00 - push 0 + // 60 00 - push 0 + // 60 00 - push 0 + // 60 00 - push 0 + // 60 00 - push 0 + // 30 - load address + // 60 e0 - push e0 + // 5a - get gas + // 03 - sub + // f1 - message call (self in this case) + // 60 01 - push 1 + // 55 - sstore + let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + let mut params = ActionParams::default(); + params.address = address.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code.clone())); + let mut state = get_temp_state_with_factory(factory); + state.init_code(&address, code).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + let FinalizationResult { gas_left, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + + assert_eq!(gas_left, U256::from(59_870)); + assert_eq!(state.storage_at(&address, &BigEndianHash::from_uint(&U256::zero())).unwrap(), BigEndianHash::from_uint(&U256::from(1))); + assert_eq!(state.storage_at(&address, &BigEndianHash::from_uint(&U256::one())).unwrap(), BigEndianHash::from_uint(&U256::from(1))); + } + + // test is incorrect, mk + // TODO: fix (preferred) or remove + evm_test_ignore!{test_transact_simple: test_transact_simple_int} + fn test_transact_simple(factory: Factory) { + let keypair = Random.generate().unwrap(); + let t = Transaction { + action: Action::Create, + value: U256::from(17), + data: "3331600055".from_hex().unwrap(), + gas: U256::from(100_000), + gas_price: U256::zero(), + nonce: U256::zero() + }.sign(keypair.secret(), None); + let sender = t.sender(); + let contract = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap(); + let mut info = EnvInfo::default(); + info.gas_limit = U256::from(100_000); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + + let executed = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + let opts = TransactOptions::with_no_tracing(); + ex.transact(&t, opts).unwrap() + }; + + assert_eq!(executed.gas, U256::from(100_000)); + assert_eq!(executed.gas_used, U256::from(41_301)); + assert_eq!(executed.refunded, U256::from(58_699)); + assert_eq!(executed.cumulative_gas_used, U256::from(41_301)); + assert_eq!(executed.logs.len(), 0); + assert_eq!(executed.contracts_created.len(), 0); + assert_eq!(state.balance(&sender).unwrap(), U256::from(1)); + assert_eq!(state.balance(&contract).unwrap(), U256::from(17)); + assert_eq!(state.nonce(&sender).unwrap(), U256::from(1)); + assert_eq!(state.storage_at(&contract, &H256::zero()).unwrap(), BigEndianHash::from_uint(&U256::from(1))); + } + + evm_test!{test_transact_invalid_nonce: test_transact_invalid_nonce_int} + fn test_transact_invalid_nonce(factory: Factory) { + let keypair = Random.generate().unwrap(); + let t = Transaction { + action: Action::Create, + value: U256::from(17), + data: "3331600055".from_hex().unwrap(), + gas: U256::from(100_000), + gas_price: U256::zero(), + nonce: U256::one() + }.sign(keypair.secret(), None); + let sender = t.sender(); + + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); + let mut info = EnvInfo::default(); + info.gas_limit = U256::from(100_000); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + + let res = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + let opts = TransactOptions::with_no_tracing(); + ex.transact(&t, opts) + }; + + match res { + Err(ExecutionError::InvalidNonce { expected, got }) + if expected == U256::zero() && got == U256::one() => (), + _ => assert!(false, "Expected invalid nonce error.") + } + } + + evm_test!{test_transact_gas_limit_reached: test_transact_gas_limit_reached_int} + fn test_transact_gas_limit_reached(factory: Factory) { + let keypair = Random.generate().unwrap(); + let t = Transaction { + action: Action::Create, + value: U256::from(17), + data: "3331600055".from_hex().unwrap(), + gas: U256::from(80_001), + gas_price: U256::zero(), + nonce: U256::zero() + }.sign(keypair.secret(), None); + let sender = t.sender(); + + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); + let mut info = EnvInfo::default(); + info.gas_used = U256::from(20_000); + info.gas_limit = U256::from(100_000); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + + let res = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + let opts = TransactOptions::with_no_tracing(); + ex.transact(&t, opts) + }; + + match res { + Err(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, gas }) + if gas_limit == U256::from(100_000) && gas_used == U256::from(20_000) && gas == U256::from(80_001) => (), + _ => assert!(false, "Expected block gas limit error.") + } + } + + evm_test!{test_not_enough_cash: test_not_enough_cash_int} + fn test_not_enough_cash(factory: Factory) { + + let keypair = Random.generate().unwrap(); + let t = Transaction { + action: Action::Create, + value: U256::from(18), + data: "3331600055".from_hex().unwrap(), + gas: U256::from(100_000), + gas_price: U256::one(), + nonce: U256::zero() + }.sign(keypair.secret(), None); + let sender = t.sender(); + + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from(100_017), CleanupMode::NoEmpty).unwrap(); + let mut info = EnvInfo::default(); + info.gas_limit = U256::from(100_000); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + + let res = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + let opts = TransactOptions::with_no_tracing(); + ex.transact(&t, opts) + }; + + match res { + Err(ExecutionError::NotEnoughCash { required , got }) + if required == U512::from(100_018) && got == U512::from(100_017) => (), + _ => assert!(false, "Expected not enough cash error. {:?}", res) + } + } + + evm_test!{test_keccak: test_keccak_int} + fn test_keccak(factory: Factory) { + let code = "6064640fffffffff20600055".from_hex().unwrap(); + + let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; + // TODO: add tests for 'callcreate' + //let next_address = contract_address(&address, &U256::zero()); + let mut params = ActionParams::default(); + params.address = address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(0x0186a0); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::from_str("0de0b6b3a7640000").unwrap()); + let mut state = get_temp_state_with_factory(factory); + state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap(), CleanupMode::NoEmpty).unwrap(); + let info = EnvInfo::default(); + let machine = make_frontier_machine(0); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + let result = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) + }; + + match result { + Err(_) => {}, + _ => panic!("Expected OutOfGas"), + } + } + + evm_test!{test_revert: test_revert_int} + fn test_revert(factory: Factory) { + let contract_address = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + // EIP-140 test case + let code = "6c726576657274656420646174616000557f726576657274206d657373616765000000000000000000000000000000000000600052600e6000fd".from_hex().unwrap(); + let returns = "726576657274206d657373616765".from_hex().unwrap(); + let mut state = get_temp_state_with_factory(factory.clone()); + state.add_balance(&sender, &U256::from_str("152d02c7e14af68000000").unwrap(), CleanupMode::NoEmpty).unwrap(); + state.commit().unwrap(); + + let mut params = ActionParams::default(); + params.address = contract_address.clone(); + params.sender = sender.clone(); + params.origin = sender.clone(); + params.gas = U256::from(20025); + params.code = Some(Arc::new(code)); + params.value = ActionValue::Transfer(U256::zero()); + let info = EnvInfo::default(); + let machine = new_byzantium_test_machine(); + let schedule = machine.schedule(info.number); + let mut substate = Substate::new(); + + let mut output = [0u8; 14]; + let FinalizationResult { gas_left: result, return_data, .. } = { + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + (&mut output).copy_from_slice(&return_data[..(cmp::min(14, return_data.len()))]); + + assert_eq!(result, U256::from(1)); + assert_eq!(output[..], returns[..]); + assert_eq!(state.storage_at(&contract_address, &H256::zero()).unwrap(), H256::zero()); + } + + evm_test!{test_eip1283: test_eip1283_int} + fn test_eip1283(factory: Factory) { + let x1 = Address::from_low_u64_be(0x1000); + let x2 = Address::from_low_u64_be(0x1001); + let y1 = Address::from_low_u64_be(0x2001); + let y2 = Address::from_low_u64_be(0x2002); + let operating_address = Address::zero(); + let k = H256::zero(); + + let mut state = get_temp_state_with_factory(factory.clone()); + state.new_contract(&x1, U256::zero(), U256::from(1), U256::zero()).unwrap(); + state.init_code(&x1, "600160005560006000556001600055".from_hex().unwrap()).unwrap(); + state.new_contract(&x2, U256::zero(), U256::from(1), U256::zero()).unwrap(); + state.init_code(&x2, "600060005560016000556000600055".from_hex().unwrap()).unwrap(); + state.new_contract(&y1, U256::zero(), U256::from(1), U256::zero()).unwrap(); + state.init_code(&y1, "600060006000600061100062fffffff4".from_hex().unwrap()).unwrap(); + state.new_contract(&y2, U256::zero(), U256::from(1), U256::zero()).unwrap(); + state.init_code(&y2, "600060006000600061100162fffffff4".from_hex().unwrap()).unwrap(); + + let info = EnvInfo::default(); + let machine = new_constantinople_test_machine(); + let schedule = machine.schedule(info.number); + + assert_eq!(state.storage_at(&operating_address, &k).unwrap(), BigEndianHash::from_uint(&U256::from(0))); + // Test a call via top-level -> y1 -> x1 + let (FinalizationResult { gas_left, .. }, refund, gas) = { + let gas = U256::from(0xffffffffffu64); + let mut params = ActionParams::default(); + params.code = Some(Arc::new("6001600055600060006000600061200163fffffffff4".from_hex().unwrap())); + params.gas = gas; + let mut substate = Substate::new(); + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + let res = ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap(); + + (res, substate.sstore_clears_refund, gas) + }; + let gas_used = gas - gas_left; + // sstore: 0 -> (1) -> () -> (1 -> 0 -> 1) + assert_eq!(gas_used, U256::from(41860)); + assert_eq!(refund, 19800); + + assert_eq!(state.storage_at(&operating_address, &k).unwrap(), BigEndianHash::from_uint(&U256::from(1))); + // Test a call via top-level -> y2 -> x2 + let (FinalizationResult { gas_left, .. }, refund, gas) = { + let gas = U256::from(0xffffffffffu64); + let mut params = ActionParams::default(); + params.code = Some(Arc::new("6001600055600060006000600061200263fffffffff4".from_hex().unwrap())); + params.gas = gas; + let mut substate = Substate::new(); + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + let res = ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap(); + + (res, substate.sstore_clears_refund, gas) + }; + let gas_used = gas - gas_left; + // sstore: 1 -> (1) -> () -> (0 -> 1 -> 0) + assert_eq!(gas_used, U256::from(11860)); + assert_eq!(refund, 19800); + } + + fn wasm_sample_code() -> Arc> { + Arc::new( + "0061736d01000000010d0360027f7f0060017f0060000002270303656e7603726574000003656e760673656e646572000103656e76066d656d6f727902010110030201020404017000000501000708010463616c6c00020901000ac10101be0102057f017e4100410028020441c0006b22043602042004412c6a41106a220041003602002004412c6a41086a22014200370200200441186a41106a22024100360200200441186a41086a220342003703002004420037022c2004410036021c20044100360218200441186a1001200020022802002202360200200120032903002205370200200441106a2002360200200441086a200537030020042004290318220537022c200420053703002004411410004100200441c0006a3602040b0b0a010041040b0410c00000" + .from_hex() + .unwrap() + ) + } + + #[test] + fn wasm_activated_test() { + let contract_address = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); + let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + + let mut state = get_temp_state(); + state.add_balance(&sender, &U256::from(10000000000u64), CleanupMode::NoEmpty).unwrap(); + state.commit().unwrap(); + + let mut params = ActionParams::default(); + params.origin = sender.clone(); + params.sender = sender.clone(); + params.address = contract_address.clone(); + params.gas = U256::from(20025); + params.code = Some(wasm_sample_code()); + + let mut info = EnvInfo::default(); + + // 100 > 10 + info.number = 100; + + // Network with wasm activated at block 10 + let machine = new_kovan_wasm_test_machine(); + + let mut output = [0u8; 20]; + let FinalizationResult { gas_left: result, return_data, .. } = { + let schedule = machine.schedule(info.number); + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params.clone(), &mut Substate::new(), &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + (&mut output).copy_from_slice(&return_data[..(cmp::min(20, return_data.len()))]); + + assert_eq!(result, U256::from(18433)); + // Transaction successfully returned sender + assert_eq!(output[..], sender[..]); + + // 1 < 10 + info.number = 1; + + let mut output = [0u8; 20]; + let FinalizationResult { gas_left: result, return_data, .. } = { + let schedule = machine.schedule(info.number); + let mut ex = Executive::new(&mut state, &info, &machine, &schedule); + ex.call(params, &mut Substate::new(), &mut NoopTracer, &mut NoopVMTracer).unwrap() + }; + (&mut output[..((cmp::min(20, return_data.len())))]).copy_from_slice(&return_data[..(cmp::min(20, return_data.len()))]); + + assert_eq!(result, U256::from(20025)); + // Since transaction errored due to wasm was not activated, result is just empty + assert_eq!(output[..], [0u8; 20][..]); + } +} diff --git a/ethcore/machine/src/externalities.rs b/ethcore/machine/src/externalities.rs new file mode 100644 index 00000000000..edd7af489f4 --- /dev/null +++ b/ethcore/machine/src/externalities.rs @@ -0,0 +1,672 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Transaction Execution environment. +use std::{cmp, sync::Arc}; + +use ethereum_types::{H256, U256, Address, BigEndianHash}; +use parity_bytes::Bytes; +use log::{debug, trace, warn}; + +use account_state::{Backend as StateBackend, State, CleanupMode}; +use common_types::{ + transaction::UNSIGNED_SENDER, + log_entry::LogEntry, +}; +use trace::{Tracer, VMTracer}; +use vm::{ + self, ActionParams, ActionValue, EnvInfo, CallType, Schedule, + Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, + ReturnData, TrapKind +}; + +use crate::{ + Machine, + substate::Substate, + executive::{ + Executive, + contract_address, + into_message_call_result, + into_contract_create_result, + cleanup_mode + }, +}; + +/// Policy for handling output data on `RETURN` opcode. +pub enum OutputPolicy { + /// Return reference to fixed sized output. + /// Used for message calls. + Return, + /// Init new contract as soon as `RETURN` is called. + InitContract, +} + +/// Transaction properties that externalities need to know about. +pub struct OriginInfo { + address: Address, + origin: Address, + gas_price: U256, + value: U256, +} + +impl OriginInfo { + /// Populates origin info from action params. + pub fn from(params: &ActionParams) -> Self { + OriginInfo { + address: params.address.clone(), + origin: params.origin.clone(), + gas_price: params.gas_price, + value: match params.value { + ActionValue::Transfer(val) | ActionValue::Apparent(val) => val + }, + } + } +} + +/// Implementation of evm Externalities. +pub struct Externalities<'a, T: 'a, V: 'a, B: 'a> { + state: &'a mut State, + env_info: &'a EnvInfo, + depth: usize, + stack_depth: usize, + origin_info: &'a OriginInfo, + substate: &'a mut Substate, + machine: &'a Machine, + schedule: &'a Schedule, + output: OutputPolicy, + tracer: &'a mut T, + vm_tracer: &'a mut V, + static_flag: bool, +} + +impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B> + where T: Tracer, V: VMTracer, B: StateBackend +{ + /// Basic `Externalities` constructor. + pub fn new( + state: &'a mut State, + env_info: &'a EnvInfo, + machine: &'a Machine, + schedule: &'a Schedule, + depth: usize, + stack_depth: usize, + origin_info: &'a OriginInfo, + substate: &'a mut Substate, + output: OutputPolicy, + tracer: &'a mut T, + vm_tracer: &'a mut V, + static_flag: bool, + ) -> Self { + Externalities { + state, + env_info, + depth, + stack_depth, + origin_info, + substate, + machine, + schedule, + output, + tracer, + vm_tracer, + static_flag, + } + } +} + +impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> + where T: Tracer, V: VMTracer, B: StateBackend +{ + fn initial_storage_at(&self, key: &H256) -> vm::Result { + if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? { + self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or_default()).map_err(Into::into) + } else { + warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address); + Ok(H256::zero()) + } + } + + fn storage_at(&self, key: &H256) -> vm::Result { + self.state.storage_at(&self.origin_info.address, key).map_err(Into::into) + } + + fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { + if self.static_flag { + Err(vm::Error::MutableCallInStaticContext) + } else { + self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into) + } + } + + fn exists(&self, address: &Address) -> vm::Result { + self.state.exists(address).map_err(Into::into) + } + + fn exists_and_not_null(&self, address: &Address) -> vm::Result { + self.state.exists_and_not_null(address).map_err(Into::into) + } + + fn origin_balance(&self) -> vm::Result { + self.balance(&self.origin_info.address).map_err(Into::into) + } + + fn balance(&self, address: &Address) -> vm::Result { + self.state.balance(address).map_err(Into::into) + } + + fn blockhash(&mut self, number: &U256) -> H256 { + if self.env_info.number + 256 >= self.machine.params().eip210_transition { + let blockhash_contract_address = self.machine.params().eip210_contract_address; + let code_res = self.state.code(&blockhash_contract_address) + .and_then(|code| self.state.code_hash(&blockhash_contract_address).map(|hash| (code, hash))) + .and_then(|(code, hash)| self.state.code_version(&blockhash_contract_address).map(|version| (code, hash, version))); + + let (code, code_hash, code_version) = match code_res { + Ok((code, hash, version)) => (code, hash, version), + Err(_) => return H256::zero(), + }; + let data: H256 = BigEndianHash::from_uint(number); + + let params = ActionParams { + sender: self.origin_info.address.clone(), + address: blockhash_contract_address.clone(), + value: ActionValue::Apparent(self.origin_info.value), + code_address: blockhash_contract_address.clone(), + origin: self.origin_info.origin.clone(), + gas: self.machine.params().eip210_contract_gas, + gas_price: 0.into(), + code, + code_hash, + code_version, + data: Some(data.as_bytes().to_vec()), + call_type: CallType::Call, + params_type: vm::ParamsType::Separate, + }; + + let mut ex = Executive::new(self.state, self.env_info, self.machine, self.schedule); + let r = ex.call_with_crossbeam(params, self.substate, self.stack_depth + 1, self.tracer, self.vm_tracer); + let output = match &r { + Ok(ref r) => H256::from_slice(&r.return_data[..32]), + _ => H256::zero(), + }; + trace!("ext: blockhash contract({}) -> {:?}({}) self.env_info.number={}\n", number, r, output, self.env_info.number); + output + } else { + // TODO: comment out what this function expects from env_info, since it will produce panics if the latter is inconsistent + match *number < U256::from(self.env_info.number) && number.low_u64() >= cmp::max(256, self.env_info.number) - 256 { + true => { + let index = self.env_info.number - number.low_u64() - 1; + assert!(index < self.env_info.last_hashes.len() as u64, format!("Inconsistent env_info, should contain at least {:?} last hashes", index+1)); + let r = self.env_info.last_hashes[index as usize].clone(); + trace!("ext: blockhash({}) -> {} self.env_info.number={}\n", number, r, self.env_info.number); + r + }, + false => { + trace!("ext: blockhash({}) -> null self.env_info.number={}\n", number, self.env_info.number); + H256::zero() + }, + } + } + } + + fn create( + &mut self, + gas: &U256, + value: &U256, + code: &[u8], + parent_version: &U256, + address_scheme: CreateContractAddress, + trap: bool, + ) -> ::std::result::Result { + // create new contract address + let (address, code_hash) = match self.state.nonce(&self.origin_info.address) { + Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code), + Err(e) => { + debug!(target: "ext", "Database corruption encountered: {:?}", e); + return Ok(ContractCreateResult::Failed) + } + }; + + // prepare the params + let params = ActionParams { + code_address: address.clone(), + address: address.clone(), + sender: self.origin_info.address.clone(), + origin: self.origin_info.origin.clone(), + gas: *gas, + gas_price: self.origin_info.gas_price, + value: ActionValue::Transfer(*value), + code: Some(Arc::new(code.to_vec())), + code_hash, + code_version: *parent_version, + data: None, + call_type: CallType::None, + params_type: vm::ParamsType::Embedded, + }; + + if !self.static_flag { + if !self.schedule.keep_unsigned_nonce || params.sender != UNSIGNED_SENDER { + if let Err(e) = self.state.inc_nonce(&self.origin_info.address) { + debug!(target: "ext", "Database corruption encountered: {:?}", e); + return Ok(ContractCreateResult::Failed) + } + } + } + + if trap { + return Err(TrapKind::Create(params, address)); + } + + // TODO: handle internal error separately + let mut ex = Executive::from_parent(self.state, self.env_info, self.machine, self.schedule, self.depth, self.static_flag); + let out = ex.create_with_crossbeam(params, self.substate, self.stack_depth + 1, self.tracer, self.vm_tracer); + Ok(into_contract_create_result(out, &address, self.substate)) + } + + fn call( + &mut self, + gas: &U256, + sender_address: &Address, + receive_address: &Address, + value: Option, + data: &[u8], + code_address: &Address, + call_type: CallType, + trap: bool, + ) -> ::std::result::Result { + trace!(target: "externalities", "call"); + + let code_res = self.state.code(code_address) + .and_then(|code| self.state.code_hash(code_address).map(|hash| (code, hash))) + .and_then(|(code, hash)| self.state.code_version(code_address).map(|version| (code, hash, version))); + + let (code, code_hash, code_version) = match code_res { + Ok((code, hash, version)) => (code, hash, version), + Err(_) => return Ok(MessageCallResult::Failed), + }; + + let mut params = ActionParams { + sender: sender_address.clone(), + address: receive_address.clone(), + value: ActionValue::Apparent(self.origin_info.value), + code_address: code_address.clone(), + origin: self.origin_info.origin.clone(), + gas: *gas, + gas_price: self.origin_info.gas_price, + code, + code_hash, + code_version, + data: Some(data.to_vec()), + call_type, + params_type: vm::ParamsType::Separate, + }; + + if let Some(value) = value { + params.value = ActionValue::Transfer(value); + } + + if trap { + return Err(TrapKind::Call(params)); + } + + let mut ex = Executive::from_parent(self.state, self.env_info, self.machine, self.schedule, self.depth, self.static_flag); + let out = ex.call_with_crossbeam(params, self.substate, self.stack_depth + 1, self.tracer, self.vm_tracer); + Ok(into_message_call_result(out)) + } + + fn extcode(&self, address: &Address) -> vm::Result>> { + Ok(self.state.code(address)?) + } + + fn extcodehash(&self, address: &Address) -> vm::Result> { + if self.state.exists_and_not_null(address)? { + Ok(self.state.code_hash(address)?) + } else { + Ok(None) + } + } + + fn extcodesize(&self, address: &Address) -> vm::Result> { + Ok(self.state.code_size(address)?) + } + + fn log(&mut self, topics: Vec, data: &[u8]) -> vm::Result<()> { + if self.static_flag { + return Err(vm::Error::MutableCallInStaticContext); + } + + let address = self.origin_info.address.clone(); + self.substate.logs.push(LogEntry { + address, + topics, + data: data.to_vec() + }); + + Ok(()) + } + + fn ret(self, gas: &U256, data: &ReturnData, apply_state: bool) -> vm::Result + where Self: Sized { + match self.output { + OutputPolicy::Return => { + Ok(*gas) + }, + OutputPolicy::InitContract if apply_state => { + let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); + if return_cost > *gas || data.len() > self.schedule.create_data_limit { + return match self.schedule.exceptional_failed_code_deposit { + true => Err(vm::Error::OutOfGas), + false => Ok(*gas) + } + } + self.state.init_code(&self.origin_info.address, data.to_vec())?; + Ok(*gas - return_cost) + }, + OutputPolicy::InitContract => { + Ok(*gas) + }, + } + } + + fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { + if self.static_flag { + return Err(vm::Error::MutableCallInStaticContext); + } + + let address = self.origin_info.address.clone(); + let balance = self.balance(&address)?; + if &address == refund_address { + // TODO [todr] To be consistent with CPP client we set balance to 0 in that case. + self.state.sub_balance(&address, &balance, &mut CleanupMode::NoEmpty)?; + } else { + trace!(target: "ext", "Suiciding {} -> {} (xfer: {})", address, refund_address, balance); + self.state.transfer_balance( + &address, + refund_address, + &balance, + cleanup_mode(&mut self.substate, &self.schedule) + )?; + } + + self.tracer.trace_suicide(address, balance, refund_address.clone()); + self.substate.suicides.insert(address); + + Ok(()) + } + + fn schedule(&self) -> &Schedule { + &self.schedule + } + + fn env_info(&self) -> &EnvInfo { + self.env_info + } + + fn depth(&self) -> usize { + self.depth + } + + fn add_sstore_refund(&mut self, value: usize) { + self.substate.sstore_clears_refund += value as i128; + } + + fn sub_sstore_refund(&mut self, value: usize) { + self.substate.sstore_clears_refund -= value as i128; + } + + fn trace_next_instruction(&mut self, pc: usize, instruction: u8, current_gas: U256) -> bool { + self.vm_tracer.trace_next_instruction(pc, instruction, current_gas) + } + + fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: U256, mem_written: Option<(usize, usize)>, store_written: Option<(U256, U256)>) { + self.vm_tracer.trace_prepare_execute(pc, instruction, gas_cost, mem_written, store_written) + } + + fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) { + self.vm_tracer.trace_executed(gas_used, stack_push, mem) + } + + fn is_static(&self) -> bool { + return self.static_flag + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use ethereum_types::{U256, Address}; + use evm::{EnvInfo, Ext, CallType}; + use account_state::State; + use ethcore::{ +// spec, + test_helpers::get_temp_state + }; + use trace::{NoopTracer, NoopVMTracer}; + + use crate::{ + machine::Machine, + substate::Substate, + test_helpers, + }; + use super::*; + + fn get_test_origin() -> OriginInfo { + OriginInfo { + address: Address::zero(), + origin: Address::zero(), + gas_price: U256::zero(), + value: U256::zero() + } + } + + fn get_test_env_info() -> EnvInfo { + EnvInfo { + number: 100, + author: Address::from_low_u64_be(0), + timestamp: 0, + difficulty: 0.into(), + last_hashes: Arc::new(vec![]), + gas_used: 0.into(), + gas_limit: 0.into(), + } + } + + struct TestSetup { + state: State<::state_db::StateDB>, + machine: Machine, + schedule: Schedule, + sub_state: Substate, + env_info: EnvInfo + } + + impl Default for TestSetup { + fn default() -> Self { + TestSetup::new() + } + } + + impl TestSetup { + fn new() -> Self { + let machine = test_helpers::load_machine(include_bytes!("../../res/null_morden.json")); + let env_info = get_test_env_info(); + let schedule = machine.schedule(env_info.number); + TestSetup { + state: get_temp_state(), + schedule, + machine, + sub_state: Substate::new(), + env_info, + } + } + } + + #[test] + fn can_be_created() { + let mut setup = TestSetup::new(); + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + let ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + + assert_eq!(ext.env_info().number, 100); + } + + #[test] + fn can_return_block_hash_no_env() { + let mut setup = TestSetup::new(); + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); + + assert_eq!(hash, H256::zero()); + } + + #[test] + fn can_return_block_hash() { + let test_hash = H256::from_str("afafafafafafafafafafafbcbcbcbcbcbcbcbcbcbeeeeeeeeeeeeedddddddddd").unwrap(); + let test_env_number = 0x120001; + + let mut setup = TestSetup::new(); + { + let env_info = &mut setup.env_info; + env_info.number = test_env_number; + let mut last_hashes = (*env_info.last_hashes).clone(); + last_hashes.push(test_hash.clone()); + env_info.last_hashes = Arc::new(last_hashes); + } + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); + + assert_eq!(test_hash, hash); + } + + #[test] + #[should_panic] + fn can_call_fail_empty() { + let mut setup = TestSetup::new(); + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + + // this should panic because we have no balance on any account + ext.call( + &"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap(), + &Address::zero(), + &Address::zero(), + Some("0000000000000000000000000000000000000000000000000000000000150000".parse::().unwrap()), + &[], + &Address::zero(), + CallType::Call, + false, + ).ok().unwrap(); + } + + #[test] + fn can_log() { + let log_data = vec![120u8, 110u8]; + let log_topics = vec![H256::from_str("af0fa234a6af46afa23faf23bcbc1c1cb4bcb7bcbe7e7e7ee3ee2edddddddddd").unwrap()]; + + let mut setup = TestSetup::new(); + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + { + let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + ext.log(log_topics, &log_data).unwrap(); + } + + assert_eq!(setup.sub_state.logs.len(), 1); + } + + #[test] + fn can_suicide() { + let refund_account = &Address::zero(); + + let mut setup = TestSetup::new(); + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + { + let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + ext.suicide(refund_account).unwrap(); + } + + assert_eq!(setup.sub_state.suicides.len(), 1); + } + + #[test] + fn can_create() { + use std::str::FromStr; + + let mut setup = TestSetup::new(); + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + let address = { + let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + match ext.create(&U256::max_value(), &U256::zero(), &[], &U256::zero(), CreateContractAddress::FromSenderAndNonce, false) { + Ok(ContractCreateResult::Created(address, _)) => address, + _ => panic!("Test create failed; expected Created, got Failed/Reverted."), + } + }; + + assert_eq!(address, Address::from_str("bd770416a3345f91e4b34576cb804a576fa48eb1").unwrap()); + } + + #[test] + fn can_create2() { + use std::str::FromStr; + + let mut setup = TestSetup::new(); + let state = &mut setup.state; + let mut tracer = NoopTracer; + let mut vm_tracer = NoopVMTracer; + let origin_info = get_test_origin(); + + let address = { + let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); + + match ext.create(&U256::max_value(), &U256::zero(), &[], &U256::zero(), CreateContractAddress::FromSenderSaltAndCodeHash(H256::zero()), false) { + Ok(ContractCreateResult::Created(address, _)) => address, + _ => panic!("Test create failed; expected Created, got Failed/Reverted."), + } + }; + + assert_eq!(address, Address::from_str("e33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0").unwrap()); + } +} diff --git a/ethcore/machine/src/lib.rs b/ethcore/machine/src/lib.rs new file mode 100644 index 00000000000..c89e6514e02 --- /dev/null +++ b/ethcore/machine/src/lib.rs @@ -0,0 +1,40 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +// todo[dvdplm]: document all modules + +// todo[dvdplm]: fix ethabi for use with edition 2018 +#[macro_use] +extern crate ethabi_derive; +#[macro_use] +extern crate ethabi_contract; + +pub mod executed; +pub mod executed_block; +pub mod executive; +pub mod externalities; +pub mod machine; +pub mod substate; +pub mod transaction_ext; +pub mod tx_filter; + +pub use crate::{ + executed_block::ExecutedBlock, + machine::Machine +}; + +#[cfg(any(test, feature = "test-helpers"))] +pub mod test_helpers; diff --git a/ethcore/machine/src/machine.rs b/ethcore/machine/src/machine.rs new file mode 100644 index 00000000000..dfd4c724e88 --- /dev/null +++ b/ethcore/machine/src/machine.rs @@ -0,0 +1,493 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Ethereum-like state machine definition. + +use std::collections::BTreeMap; +use std::cmp; +use std::sync::Arc; + +use ethereum_types::{U256, H256, Address}; +use rlp::Rlp; +use log::debug; + +use common_types::{ + BlockNumber, + header::Header, + engines::{ + EthashExtensions, + params::CommonParams, + }, + errors::{EngineError, EthcoreError as Error}, + transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction}, +}; +use vm::{CallType, ActionParams, ActionValue, ParamsType}; +use vm::{EnvInfo, Schedule}; + +use account_state::CleanupMode; +use client_traits::BlockInfo; +use ethcore_builtin::Builtin; +use ethcore_call_contract::CallContract; +use trace::{NoopTracer, NoopVMTracer}; + +use crate::{ + executed_block::ExecutedBlock, + executive::Executive, + substate::Substate, + tx_filter::TransactionFilter, +}; + +/// Parity tries to round block.gas_limit to multiple of this constant +pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); + +/// Special rules to be applied to the schedule. +pub type ScheduleCreationRules = dyn Fn(&mut Schedule, BlockNumber) + Sync + Send; + +/// An ethereum-like state machine. +pub struct Machine { + params: CommonParams, + builtins: Arc>, + tx_filter: Option>, + ethash_extensions: Option, + schedule_rules: Option>, +} + +impl Machine { + /// Regular ethereum machine. + pub fn regular(params: CommonParams, builtins: BTreeMap) -> Machine { + let tx_filter = TransactionFilter::from_params(¶ms).map(Arc::new); + Machine { + params, + builtins: Arc::new(builtins), + tx_filter, + ethash_extensions: None, + schedule_rules: None, + } + } + + /// Ethereum machine with ethash extensions. + // TODO: either unify or specify to mainnet specifically and include other specific-chain HFs? + pub fn with_ethash_extensions(params: CommonParams, builtins: BTreeMap, extensions: EthashExtensions) -> Machine { + let mut machine = Machine::regular(params, builtins); + machine.ethash_extensions = Some(extensions); + machine + } + + /// Attach special rules to the creation of schedule. + pub fn set_schedule_creation_rules(&mut self, rules: Box) { + self.schedule_rules = Some(rules); + } + + /// Get a reference to the ethash-specific extensions. + pub fn ethash_extensions(&self) -> Option<&EthashExtensions> { + self.ethash_extensions.as_ref() + } + + /// Execute a call as the system address. Block environment information passed to the + /// VM is modified to have its gas limit bounded at the upper limit of possible used + /// gases including this system call, capped at the maximum value able to be + /// represented by U256. This system call modifies the block state, but discards other + /// information. If suicides, logs or refunds happen within the system call, they + /// will not be executed or recorded. Gas used by this system call will not be counted + /// on the block. + pub fn execute_as_system( + &self, + block: &mut ExecutedBlock, + contract_address: Address, + gas: U256, + data: Option>, + ) -> Result, Error> { + let (code, code_hash) = { + let state = &block.state; + + (state.code(&contract_address)?, + state.code_hash(&contract_address)?) + }; + + self.execute_code_as_system( + block, + Some(contract_address), + code, + code_hash, + None, + gas, + data, + None, + ) + } + + /// Same as execute_as_system, but execute code directly. If contract address is None, use the null sender + /// address. If code is None, then this function has no effect. The call is executed without finalization, and does + /// not form a transaction. + pub fn execute_code_as_system( + &self, + block: &mut ExecutedBlock, + contract_address: Option
, + code: Option>>, + code_hash: Option, + value: Option, + gas: U256, + data: Option>, + call_type: Option, + ) -> Result, Error> { + let env_info = { + let mut env_info = block.env_info(); + env_info.gas_limit = env_info.gas_used.saturating_add(gas); + env_info + }; + + let mut state = block.state_mut(); + + let params = ActionParams { + code_address: contract_address.unwrap_or(UNSIGNED_SENDER), + address: contract_address.unwrap_or(UNSIGNED_SENDER), + sender: SYSTEM_ADDRESS, + origin: SYSTEM_ADDRESS, + gas, + gas_price: 0.into(), + value: value.unwrap_or_else(|| ActionValue::Transfer(0.into())), + code, + code_hash, + code_version: 0.into(), + data, + call_type: call_type.unwrap_or(CallType::Call), + params_type: ParamsType::Separate, + }; + let schedule = self.schedule(env_info.number); + let mut ex = Executive::new(&mut state, &env_info, self, &schedule); + let mut substate = Substate::new(); + + let res = ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).map_err(|e| EngineError::FailedSystemCall(format!("{}", e)))?; + let output = res.return_data.to_vec(); + + Ok(output) + } + + /// Push last known block hash to the state. + fn push_last_hash(&self, block: &mut ExecutedBlock) -> Result<(), Error> { + let params = self.params(); + if block.header.number() == params.eip210_transition { + let state = block.state_mut(); + state.init_code(¶ms.eip210_contract_address, params.eip210_contract_code.clone())?; + } + if block.header.number() >= params.eip210_transition { + let parent_hash = *block.header.parent_hash(); + let _ = self.execute_as_system( + block, + params.eip210_contract_address, + params.eip210_contract_gas, + Some(parent_hash.as_bytes().to_vec()), + )?; + } + Ok(()) + } + + /// Logic to perform on a new block: updating last hashes and the DAO + /// fork, for ethash. + pub fn on_new_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { + self.push_last_hash(block)?; + + if let Some(ref ethash_params) = self.ethash_extensions { + if block.header.number() == ethash_params.dao_hardfork_transition { + let state = block.state_mut(); + for child in ðash_params.dao_hardfork_accounts { + let beneficiary = ðash_params.dao_hardfork_beneficiary; + state.balance(child) + .and_then(|b| state.transfer_balance(child, beneficiary, &b, CleanupMode::NoEmpty))?; + } + } + } + + Ok(()) + } + + /// Populate a header's fields based on its parent's header. + /// Usually implements the chain scoring rule based on weight. + /// The gas floor target must not be lower than the engine's minimum gas limit. + pub fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, gas_ceil_target: U256) { + header.set_difficulty(parent.difficulty().clone()); + let gas_limit = parent.gas_limit().clone(); + assert!(!gas_limit.is_zero(), "Gas limit should be > 0"); + + if let Some(ref ethash_params) = self.ethash_extensions { + let gas_limit = { + let bound_divisor = self.params().gas_limit_bound_divisor; + let lower_limit = gas_limit - gas_limit / bound_divisor + 1; + let upper_limit = gas_limit + gas_limit / bound_divisor - 1; + let gas_limit = if gas_limit < gas_floor_target { + let gas_limit = cmp::min(gas_floor_target, upper_limit); + round_block_gas_limit(gas_limit, lower_limit, upper_limit) + } else if gas_limit > gas_ceil_target { + let gas_limit = cmp::max(gas_ceil_target, lower_limit); + round_block_gas_limit(gas_limit, lower_limit, upper_limit) + } else { + let total_lower_limit = cmp::max(lower_limit, gas_floor_target); + let total_upper_limit = cmp::min(upper_limit, gas_ceil_target); + let gas_limit = cmp::max(gas_floor_target, cmp::min(total_upper_limit, + lower_limit + (header.gas_used().clone() * 6u32 / 5) / bound_divisor)); + round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit) + }; + // ensure that we are not violating protocol limits + debug_assert!(gas_limit >= lower_limit); + debug_assert!(gas_limit <= upper_limit); + gas_limit + }; + + header.set_gas_limit(gas_limit); + if header.number() >= ethash_params.dao_hardfork_transition && + header.number() <= ethash_params.dao_hardfork_transition + 9 { + header.set_extra_data(b"dao-hard-fork"[..].to_owned()); + } + return + } + + header.set_gas_limit({ + let bound_divisor = self.params().gas_limit_bound_divisor; + if gas_limit < gas_floor_target { + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1) + } else { + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1) + } + }); + } + + /// Get the general parameters of the chain. + pub fn params(&self) -> &CommonParams { + &self.params + } + + /// Get the EVM schedule for the given block number. + pub fn schedule(&self, block_number: BlockNumber) -> Schedule { + let mut schedule = match self.ethash_extensions { + None => self.params.schedule(block_number), + Some(ref ext) => { + if block_number < ext.homestead_transition { + Schedule::new_frontier() + } else { + self.params.schedule(block_number) + } + } + }; + + if let Some(ref rules) = self.schedule_rules { + (rules)(&mut schedule, block_number) + } + + schedule + } + + /// Builtin-contracts for the chain.. + pub fn builtins(&self) -> &BTreeMap { + &*self.builtins + } + + /// Attempt to get a handle to a built-in contract. + /// Only returns references to activated built-ins. + // TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic + // from Spec into here and removing the Spec::builtins field. + pub fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> { + self.builtins() + .get(a) + .and_then(|b| if b.is_active(block_number) { Some(b) } else { None }) + } + + /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. + pub fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size } + + /// The nonce with which accounts begin at given block. + pub fn account_start_nonce(&self, block: u64) -> U256 { + let params = self.params(); + + if block >= params.dust_protection_transition { + U256::from(params.nonce_cap_increment) * U256::from(block) + } else { + params.account_start_nonce + } + } + + /// The network ID that transactions should be signed with. + pub fn signing_chain_id(&self, env_info: &EnvInfo) -> Option { + let params = self.params(); + + if env_info.number >= params.eip155_transition { + Some(params.chain_id) + } else { + None + } + } + + /// Does basic verification of the transaction. + pub fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> { + let check_low_s = match self.ethash_extensions { + Some(ref ext) => header.number() >= ext.homestead_transition, + None => true, + }; + + let chain_id = if header.number() < self.params().validate_chain_id_transition { + t.chain_id() + } else if header.number() >= self.params().eip155_transition { + Some(self.params().chain_id) + } else { + None + }; + t.verify_basic(check_low_s, chain_id, false)?; + + Ok(()) + } + + /// Does verification of the transaction against the parent state. + pub fn verify_transaction( + &self, + t: &SignedTransaction, + parent: &Header, + client: &C + ) -> Result<(), transaction::Error> { + if let Some(ref filter) = self.tx_filter.as_ref() { + if !filter.transaction_allowed(&parent.hash(), parent.number() + 1, t, client) { + return Err(transaction::Error::NotAllowed.into()) + } + } + + Ok(()) + } + + /// Performs pre-validation of RLP decoded transaction before other processing + pub fn decode_transaction(&self, transaction: &[u8]) -> Result { + let rlp = Rlp::new(&transaction); + if rlp.as_raw().len() > self.params().max_transaction_size { + debug!("Rejected oversized transaction of {} bytes", rlp.as_raw().len()); + return Err(transaction::Error::TooBig) + } + rlp.as_val().map_err(|e| transaction::Error::InvalidRlp(e.to_string())) + } + + /// Get the balance, in base units, associated with an account. + /// Extracts data from the live block. + pub fn balance(&self, live: &ExecutedBlock, address: &Address) -> Result { + live.state.balance(address).map_err(Into::into) + } + + /// Increment the balance of an account in the state of the live block. + pub fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Error> { + live.state_mut().add_balance(address, amount, CleanupMode::NoEmpty).map_err(Into::into) + } +} + +// Try to round gas_limit a bit so that: +// 1) it will still be in desired range +// 2) it will be a nearest (with tendency to increase) multiple of PARITY_GAS_LIMIT_DETERMINANT +fn round_block_gas_limit(gas_limit: U256, lower_limit: U256, upper_limit: U256) -> U256 { + let increased_gas_limit = gas_limit + (PARITY_GAS_LIMIT_DETERMINANT - gas_limit % PARITY_GAS_LIMIT_DETERMINANT); + if increased_gas_limit > upper_limit { + let decreased_gas_limit = increased_gas_limit - PARITY_GAS_LIMIT_DETERMINANT; + if decreased_gas_limit < lower_limit { + gas_limit + } else { + decreased_gas_limit + } + } else { + increased_gas_limit + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use ethcore::ethereum; + use rustc_hex::FromHex; + use common_types::header::Header; + use super::*; + + fn get_default_ethash_extensions() -> EthashExtensions { + EthashExtensions { + homestead_transition: 1150000, + dao_hardfork_transition: u64::max_value(), + dao_hardfork_beneficiary: Address::from_str("0000000000000000000000000000000000000001").unwrap(), + dao_hardfork_accounts: Vec::new(), + } + } + + #[test] + fn should_disallow_unsigned_transactions() { + let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080"; + let transaction: UnverifiedTransaction = rlp::decode(&FromHex::from_hex(rlp).unwrap()).unwrap(); + let spec = ethereum::new_ropsten_test(); + let ethparams = get_default_ethash_extensions(); + + let machine = Machine::with_ethash_extensions( + spec.params().clone(), + Default::default(), + ethparams, + ); + let mut header = Header::new(); + header.set_number(15); + + let res = machine.verify_transaction_basic(&transaction, &header); + assert_eq!(res, Err(transaction::Error::InvalidSignature("Crypto error (Invalid EC signature)".into()))); + } + + #[test] + fn ethash_gas_limit_is_multiple_of_determinant() { + use ethereum_types::U256; + + let spec = ethereum::new_homestead_test(); + let ethparams = get_default_ethash_extensions(); + + let machine = Machine::with_ethash_extensions( + spec.params().clone(), + Default::default(), + ethparams, + ); + + let mut parent = Header::new(); + let mut header = Header::new(); + header.set_number(1); + + // this test will work for this constant only + assert_eq!(PARITY_GAS_LIMIT_DETERMINANT, U256::from(37)); + + // when parent.gas_limit < gas_floor_target: + parent.set_gas_limit(U256::from(50_000)); + machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000)); + assert_eq!(*header.gas_limit(), U256::from(50_024)); + + // when parent.gas_limit > gas_ceil_target: + parent.set_gas_limit(U256::from(250_000)); + machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000)); + assert_eq!(*header.gas_limit(), U256::from(249_787)); + + // when parent.gas_limit is in miner's range + header.set_gas_used(U256::from(150_000)); + parent.set_gas_limit(U256::from(150_000)); + machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000)); + assert_eq!(*header.gas_limit(), U256::from(150_035)); + + // when parent.gas_limit is in miner's range + // && we can NOT increase it to be multiple of constant + header.set_gas_used(U256::from(150_000)); + parent.set_gas_limit(U256::from(150_000)); + machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(150_002)); + assert_eq!(*header.gas_limit(), U256::from(149_998)); + + // when parent.gas_limit is in miner's range + // && we can NOT increase it to be multiple of constant + // && we can NOT decrease it to be multiple of constant + header.set_gas_used(U256::from(150_000)); + parent.set_gas_limit(U256::from(150_000)); + machine.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002)); + assert_eq!(*header.gas_limit(), U256::from(150_002)); + } +} diff --git a/ethcore/machine/src/substate.rs b/ethcore/machine/src/substate.rs new file mode 100644 index 00000000000..48bf675207c --- /dev/null +++ b/ethcore/machine/src/substate.rs @@ -0,0 +1,96 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Execution environment substate. +use std::collections::HashSet; +use ethereum_types::Address; +use common_types::log_entry::LogEntry; + +/// State changes which should be applied in finalize, +/// after transaction is fully executed. +#[derive(Debug, Default)] +pub struct Substate { + /// Any accounts that have suicided. + pub suicides: HashSet
, + + /// Any accounts that are touched. + pub touched: HashSet
, + + /// Any logs. + pub logs: Vec, + + /// Refund counter of SSTORE. + pub sstore_clears_refund: i128, + + /// Created contracts. + pub contracts_created: Vec
, +} + +impl Substate { + /// Creates new substate. + pub fn new() -> Self { + Substate::default() + } + + /// Merge secondary substate `s` into self, accruing each element correspondingly. + pub fn accrue(&mut self, s: Substate) { + self.suicides.extend(s.suicides); + self.touched.extend(s.touched); + self.logs.extend(s.logs); + self.sstore_clears_refund += s.sstore_clears_refund; + self.contracts_created.extend(s.contracts_created); + } +} + +#[cfg(test)] +mod tests { + use ethereum_types::Address; + use common_types::log_entry::LogEntry; + use super::Substate; + + #[test] + fn created() { + let sub_state = Substate::new(); + assert_eq!(sub_state.suicides.len(), 0); + } + + #[test] + fn accrue() { + let mut sub_state = Substate::new(); + sub_state.contracts_created.push(Address::from_low_u64_be(1)); + sub_state.logs.push(LogEntry { + address: Address::from_low_u64_be(1), + topics: vec![], + data: vec![] + }); + sub_state.sstore_clears_refund = (15000 * 5).into(); + sub_state.suicides.insert(Address::from_low_u64_be(10)); + + let mut sub_state_2 = Substate::new(); + sub_state_2.contracts_created.push(Address::from_low_u64_be(2u64)); + sub_state_2.logs.push(LogEntry { + address: Address::from_low_u64_be(1), + topics: vec![], + data: vec![] + }); + sub_state_2.sstore_clears_refund = (15000 * 7).into(); + + sub_state.accrue(sub_state_2); + assert_eq!(sub_state.contracts_created.len(), 2); + assert_eq!(sub_state.sstore_clears_refund, (15000 * 12).into()); + assert_eq!(sub_state.suicides.len(), 1); + } +} diff --git a/ethcore/machine/src/test_helpers.rs b/ethcore/machine/src/test_helpers.rs new file mode 100644 index 00000000000..616b60e50a5 --- /dev/null +++ b/ethcore/machine/src/test_helpers.rs @@ -0,0 +1,60 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +// Creating test Machines + +use common_types::engines::params::CommonParams; +use ethjson; +use crate::Machine; + + +pub fn load_machine(reader: &[u8]) -> Machine { + let spec = ethjson::spec::Spec::load(reader).expect("chain spec is invalid"); + + let builtins = spec.accounts.builtins().into_iter().map(|p| (p.0.into(), From::from(p.1))).collect(); + let params = CommonParams::from(spec.params); + + if let ethjson::spec::Engine::Ethash(ref ethash) = spec.engine { + Machine::with_ethash_extensions(params, builtins, ethash.params.clone().into()) + } else { + Machine::regular(params, builtins) + } +} + + +/// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead. +pub fn new_frontier_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/frontier_test.json")) } + +/// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier. +pub fn new_homestead_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/homestead_test.json")) } + +/// Create a new Foundation Homestead-EIP210-era chain spec as though it never changed from Homestead/Frontier. +pub fn new_eip210_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/eip210_test.json")) } + +/// Create a new Foundation Byzantium era spec. +pub fn new_byzantium_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/byzantium_test.json")) } + +/// Create a new Foundation Constantinople era spec. +pub fn new_constantinople_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/constantinople_test.json")) } + +/// Create a new Foundation St. Peter's (Contantinople Fix) era spec. +pub fn new_constantinople_fix_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/st_peters_test.json")) } + +/// Create a new Musicoin-MCIP3-era spec. +pub fn new_mcip3_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) } + +/// Create new Kovan spec with wasm activated at certain block +pub fn new_kovan_wasm_test_machine() -> Machine { load_machine(include_bytes!("../../res/ethereum/kovan_wasm_test.json")) } diff --git a/ethcore/machine/src/transaction_ext.rs b/ethcore/machine/src/transaction_ext.rs new file mode 100644 index 00000000000..9e89d88771b --- /dev/null +++ b/ethcore/machine/src/transaction_ext.rs @@ -0,0 +1,43 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Ethereum transaction + +use evm::Schedule; +use common_types::transaction::{self, Action}; + +/// Extends transaction with gas verification method. +pub trait Transaction { + /// Get the transaction cost in gas for this transaction. + fn gas_required(&self, schedule: &Schedule) -> u64; +} + +impl Transaction for transaction::Transaction { + fn gas_required(&self, schedule: &Schedule) -> u64 { + gas_required_for(match self.action { + Action::Create => true, + Action::Call(_) => false + }, &self.data, schedule) + } +} + +/// Get the transaction cost in gas for the given params. +fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule) -> u64 { + data.iter().fold( + (if is_create {schedule.tx_create_gas} else {schedule.tx_gas}) as u64, + |g, b| g + (match *b { 0 => schedule.tx_data_zero_gas, _ => schedule.tx_data_non_zero_gas }) as u64 + ) +} diff --git a/ethcore/machine/src/tx_filter.rs b/ethcore/machine/src/tx_filter.rs new file mode 100644 index 00000000000..83d5c9a709b --- /dev/null +++ b/ethcore/machine/src/tx_filter.rs @@ -0,0 +1,297 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Smart contract based transaction filter. + +use ethabi::FunctionOutputDecoder; +use ethereum_types::{H256, U256, Address}; +use log::{trace, error}; +use lru_cache::LruCache; + +use ethcore_call_contract::CallContract; +use client_traits::BlockInfo; +use parking_lot::Mutex; +use common_types::{ + BlockNumber, + ids::BlockId, + engines::params::CommonParams, + transaction::{Action, SignedTransaction} +}; +use keccak_hash::KECCAK_EMPTY; + +use_contract!(transact_acl_deprecated, "../res/contracts/tx_acl_deprecated.json"); +use_contract!(transact_acl, "../res/contracts/tx_acl.json"); + +const MAX_CACHE_SIZE: usize = 4096; + +mod tx_permissions { + pub const _ALL: u32 = 0xffffffff; + pub const NONE: u32 = 0x0; + pub const BASIC: u32 = 0b00000001; + pub const CALL: u32 = 0b00000010; + pub const CREATE: u32 = 0b00000100; + pub const _PRIVATE: u32 = 0b00001000; +} + +/// Connection filter that uses a contract to manage permissions. +pub struct TransactionFilter { + contract_address: Address, + transition_block: BlockNumber, + permission_cache: Mutex>, + contract_version_cache: Mutex>> +} + +impl TransactionFilter { + /// Create a new instance if address is specified in params. + pub fn from_params(params: &CommonParams) -> Option { + params.transaction_permission_contract.map(|address| + TransactionFilter { + contract_address: address, + transition_block: params.transaction_permission_contract_transition, + permission_cache: Mutex::new(LruCache::new(MAX_CACHE_SIZE)), + contract_version_cache: Mutex::new(LruCache::new(MAX_CACHE_SIZE)), + } + ) + } + + /// Check if transaction is allowed at given block. + pub fn transaction_allowed(&self, parent_hash: &H256, block_number: BlockNumber, transaction: &SignedTransaction, client: &C) -> bool { + if block_number < self.transition_block { return true; } + + let mut permission_cache = self.permission_cache.lock(); + let mut contract_version_cache = self.contract_version_cache.lock(); + + let (tx_type, to) = match transaction.action { + Action::Create => (tx_permissions::CREATE, Address::zero()), + Action::Call(address) => if client.code_hash(&address, BlockId::Hash(*parent_hash)).map_or(false, |c| c != KECCAK_EMPTY) { + (tx_permissions::CALL, address) + } else { + (tx_permissions::BASIC, address) + } + }; + + let sender = transaction.sender(); + let value = transaction.value; + let key = (*parent_hash, sender); + + if let Some(permissions) = permission_cache.get_mut(&key) { + return *permissions & tx_type != 0; + } + + let contract_address = self.contract_address; + let contract_version = contract_version_cache.get_mut(parent_hash).and_then(|v| *v).or_else(|| { + let (data, decoder) = transact_acl::functions::contract_version::call(); + decoder.decode(&client.call_contract(BlockId::Hash(*parent_hash), contract_address, data).ok()?).ok() + }); + contract_version_cache.insert(*parent_hash, contract_version); + + // Check permissions in smart contract based on its version + let (permissions, filter_only_sender) = match contract_version { + Some(version) => { + let version_u64 = version.low_u64(); + trace!(target: "tx_filter", "Version of tx permission contract: {}", version); + match version_u64 { + 2 => { + let (data, decoder) = transact_acl::functions::allowed_tx_types::call(sender, to, value); + client.call_contract(BlockId::Hash(*parent_hash), contract_address, data) + .and_then(|value| decoder.decode(&value).map_err(|e| e.to_string())) + .map(|(p, f)| (p.low_u32(), f)) + .unwrap_or_else(|e| { + error!(target: "tx_filter", "Error calling tx permissions contract: {:?}", e); + (tx_permissions::NONE, true) + }) + }, + _ => { + error!(target: "tx_filter", "Unknown version of tx permissions contract is used"); + (tx_permissions::NONE, true) + } + } + }, + None => { + trace!(target: "tx_filter", "Fallback to the deprecated version of tx permission contract"); + let (data, decoder) = transact_acl_deprecated::functions::allowed_tx_types::call(sender); + (client.call_contract(BlockId::Hash(*parent_hash), contract_address, data) + .and_then(|value| decoder.decode(&value).map_err(|e| e.to_string())) + .map(|p| p.low_u32()) + .unwrap_or_else(|e| { + error!(target: "tx_filter", "Error calling tx permissions contract: {:?}", e); + tx_permissions::NONE + }), true) + } + }; + + if filter_only_sender { + permission_cache.insert((*parent_hash, sender), permissions); + } + trace!(target: "tx_filter", + "Given transaction data: sender: {:?} to: {:?} value: {}. Permissions required: {:X}, got: {:X}", + sender, to, value, tx_type, permissions + ); + permissions & tx_type != 0 + } +} + +#[cfg(test)] +mod test { + use std::sync::Arc; + use std::str::FromStr; + + use tempdir::TempDir; + use ethereum_types::{U256, Address}; + + use common_types::transaction::{Transaction, Action}; + use ethcore::{ + client::{BlockChainClient, Client, ClientConfig, BlockId}, + spec::Spec, + miner::Miner, + test_helpers, + }; + use ethkey::{Secret, KeyPair}; + use ethcore_io::IoChannel; + + use super::TransactionFilter; + + /// Contract code: https://gist.github.com/VladLupashevskyi/84f18eabb1e4afadf572cf92af3e7e7f + #[test] + fn transaction_filter() { + let spec_data = include_str!("../../res/tx_permission_tests/contract_ver_2_genesis.json"); + + let db = test_helpers::new_db(); + let tempdir = TempDir::new("").unwrap(); + let spec = Spec::load(&tempdir.path(), spec_data.as_bytes()).unwrap(); + + let client = Client::new( + ClientConfig::default(), + &spec, + db, + Arc::new(Miner::new_for_tests(&spec, None)), + IoChannel::disconnected(), + ).unwrap(); + let key1 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000001")).unwrap(); + let key2 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000002")).unwrap(); + let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000003")).unwrap(); + let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000004")).unwrap(); + let key5 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000005")).unwrap(); + let key6 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000006")).unwrap(); + let key7 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000007")).unwrap(); + + let filter = TransactionFilter::from_params(spec.params()).unwrap(); + let mut basic_tx = Transaction::default(); + basic_tx.action = Action::Call(Address::from_str("d41c057fd1c78805aac12b0a94a405c0461a6fbb").unwrap()); + let create_tx = Transaction::default(); + let mut call_tx = Transaction::default(); + call_tx.action = Action::Call(Address::from_str("0000000000000000000000000000000000000005").unwrap()); + + let mut basic_tx_with_ether_and_to_key7 = Transaction::default(); + basic_tx_with_ether_and_to_key7.action = Action::Call(Address::from_str("d41c057fd1c78805aac12b0a94a405c0461a6fbb").unwrap()); + basic_tx_with_ether_and_to_key7.value = U256::from(123123); + let mut call_tx_with_ether = Transaction::default(); + call_tx_with_ether.action = Action::Call(Address::from_str("0000000000000000000000000000000000000005").unwrap()); + call_tx_with_ether.value = U256::from(123123); + + let mut basic_tx_to_key6 = Transaction::default(); + basic_tx_to_key6.action = Action::Call(Address::from_str("e57bfe9f44b819898f47bf37e5af72a0783e1141").unwrap()); + let mut basic_tx_with_ether_and_to_key6 = Transaction::default(); + basic_tx_with_ether_and_to_key6.action = Action::Call(Address::from_str("e57bfe9f44b819898f47bf37e5af72a0783e1141").unwrap()); + basic_tx_with_ether_and_to_key6.value = U256::from(123123); + + let genesis = client.block_hash(BlockId::Latest).unwrap(); + let block_number = 1; + + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); + // same tx but request is allowed because the contract only enables at block #1 + assert!(filter.transaction_allowed(&genesis, 0, &create_tx.clone().sign(key2.secret(), None), &*client)); + + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key1.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key1.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key1.secret(), None), &*client)); + + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key2.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key2.secret(), None), &*client)); + + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key3.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key3.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key3.secret(), None), &*client)); + + assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key4.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key4.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key4.secret(), None), &*client)); + + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key1.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key1.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key1.secret(), None), &*client)); + + assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx_with_ether_and_to_key7.clone().sign(key5.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx_with_ether.clone().sign(key5.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key6.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx_with_ether_and_to_key7.clone().sign(key6.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx_to_key6.clone().sign(key7.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx_with_ether_and_to_key6.clone().sign(key7.secret(), None), &*client)); + } + + /// Contract code: https://gist.github.com/arkpar/38a87cb50165b7e683585eec71acb05a + #[test] + fn transaction_filter_deprecated() { + let spec_data = include_str!("../../res/tx_permission_tests/deprecated_contract_genesis.json"); + + let db = test_helpers::new_db(); + let tempdir = TempDir::new("").unwrap(); + let spec = Spec::load(&tempdir.path(), spec_data.as_bytes()).unwrap(); + + let client = Client::new( + ClientConfig::default(), + &spec, + db, + Arc::new(Miner::new_for_tests(&spec, None)), + IoChannel::disconnected(), + ).unwrap(); + let key1 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000001")).unwrap(); + let key2 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000002")).unwrap(); + let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000003")).unwrap(); + let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000004")).unwrap(); + + let filter = TransactionFilter::from_params(spec.params()).unwrap(); + let mut basic_tx = Transaction::default(); + basic_tx.action = Action::Call(Address::from_str("0000000000000000000000000000000000000032").unwrap()); + let create_tx = Transaction::default(); + let mut call_tx = Transaction::default(); + call_tx.action = Action::Call(Address::from_str("0000000000000000000000000000000000000005").unwrap()); + + let genesis = client.block_hash(BlockId::Latest).unwrap(); + let block_number = 1; + + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); + // same tx but request is allowed because the contract only enables at block #1 + assert!(filter.transaction_allowed(&genesis, 0, &create_tx.clone().sign(key2.secret(), None), &*client)); + + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key1.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key1.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key1.secret(), None), &*client)); + + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key2.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); + assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key2.secret(), None), &*client)); + + assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key3.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key3.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key3.secret(), None), &*client)); + + assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key4.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key4.secret(), None), &*client)); + assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key4.secret(), None), &*client)); + } +} From 0465e6b6866057bd414cc89981a18b76d43cb6a2 Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 6 Aug 2019 18:40:13 +0200 Subject: [PATCH 03/43] Use new machine and client-traits crates in ethcore --- ethcore/Cargo.toml | 3 + ethcore/light/Cargo.toml | 2 + ethcore/light/src/lib.rs | 2 + ethcore/light/src/on_demand/mod.rs | 3 +- ethcore/light/src/provider.rs | 13 +- ethcore/private-tx/Cargo.toml | 2 + ethcore/private-tx/src/lib.rs | 12 +- ethcore/src/block.rs | 69 +- ethcore/src/client/client.rs | 13 +- ethcore/src/client/evm_test_client.rs | 7 +- ethcore/src/client/mod.rs | 9 +- ethcore/src/client/test_client.rs | 4 +- ethcore/src/client/traits.rs | 18 +- ethcore/src/engines/authority_round/mod.rs | 6 +- ethcore/src/engines/basic_authority.rs | 6 +- ethcore/src/engines/block_reward.rs | 3 +- ethcore/src/engines/clique/mod.rs | 6 +- ethcore/src/engines/ethash.rs | 9 +- ethcore/src/engines/instant_seal.rs | 6 +- ethcore/src/engines/mod.rs | 10 +- ethcore/src/engines/null_engine.rs | 6 +- ethcore/src/engines/validator_set/contract.rs | 2 +- ethcore/src/engines/validator_set/multi.rs | 2 +- .../engines/validator_set/safe_contract.rs | 2 +- ethcore/src/ethereum.rs | 31 - ethcore/src/executed.rs | 73 - ethcore/src/executive.rs | 2260 ----------------- ethcore/src/executive_state.rs | 15 +- ethcore/src/externalities.rs | 652 ----- ethcore/src/json_tests/executive.rs | 14 +- ethcore/src/lib.rs | 18 +- ethcore/src/machine.rs | 485 ---- ethcore/src/miner/miner.rs | 4 +- ethcore/src/miner/pool_client.rs | 11 +- ethcore/src/snapshot/service.rs | 3 +- ethcore/src/snapshot/tests/service.rs | 2 +- ethcore/src/snapshot/watcher.rs | 3 +- ethcore/src/spec/spec.rs | 10 +- ethcore/src/substate.rs | 96 - ethcore/src/tests/client.rs | 4 +- ethcore/src/tests/evm.rs | 9 +- ethcore/src/transaction_ext.rs | 43 - ethcore/src/tx_filter.rs | 290 --- ethcore/src/verification/canon_verifier.rs | 2 +- ethcore/src/verification/mod.rs | 2 +- ethcore/src/verification/noop_verifier.rs | 2 +- ethcore/src/verification/queue/kind.rs | 4 +- ethcore/src/verification/verification.rs | 2 +- ethcore/src/verification/verifier.rs | 2 +- 49 files changed, 149 insertions(+), 4103 deletions(-) delete mode 100644 ethcore/src/executed.rs delete mode 100644 ethcore/src/executive.rs delete mode 100644 ethcore/src/externalities.rs delete mode 100644 ethcore/src/machine.rs delete mode 100644 ethcore/src/substate.rs delete mode 100644 ethcore/src/transaction_ext.rs delete mode 100644 ethcore/src/tx_filter.rs diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 90a33c7fd55..b61932b0ceb 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -10,6 +10,7 @@ authors = ["Parity Technologies "] account-db = { path = "account-db" } ansi_term = "0.11" blooms-db = { path = "../util/blooms-db", optional = true } +client-traits = { path = "./client-traits" } common-types = { path = "types" } crossbeam-utils = "0.6" env_logger = { version = "0.5", optional = true } @@ -44,6 +45,7 @@ lazy_static = "1.2.0" len-caching-lock = { path = "../util/len-caching-lock" } log = "0.4" lru-cache = "0.1" +machine = { path = "./machine" } macros = { path = "../util/macros" } memory-cache = { path = "../util/memory-cache" } num_cpus = "1.2" @@ -85,6 +87,7 @@ rlp_compress = { path = "../util/rlp-compress" } serde_json = "1.0" tempdir = "0.3" trie-standardmap = "0.12.4" +machine = { path = "./machine", features = ["test-helpers"] } [features] parity = ["work-notify", "price-info", "stratum"] diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index be6f1b1640f..998d82b6229 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -9,12 +9,14 @@ authors = ["Parity Technologies "] [dependencies] log = "0.4" parity-bytes = "0.1" +client-traits = { path = "../client-traits" } common-types = { path = "../types" } derive_more = "0.14.0" ethcore = { path = ".."} ethcore-db = { path = "../db" } ethcore-blockchain = { path = "../blockchain" } ethereum-types = "0.6.0" +machine = { path = "../machine" } memory-db = "0.12.4" trie-db = "0.12.4" patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index d169c6925e2..64b7f7d69dc 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -54,6 +54,7 @@ extern crate serde_derive; extern crate log; extern crate bincode; +extern crate client_traits; extern crate common_types; extern crate ethcore_blockchain; extern crate ethcore_db; @@ -71,6 +72,7 @@ extern crate failsafe; extern crate futures; extern crate itertools; extern crate keccak_hasher; +extern crate machine; extern crate memory_db; extern crate trie_db as trie; extern crate patricia_trie_ethereum as ethtrie; diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index d9a6b23ef8a..cdac4fdc184 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -40,7 +40,8 @@ use cache::Cache; use request::{self as basic_request, Request as NetworkRequest}; use self::request::CheckedRequest; -pub use ethcore::executed::ExecutionResult; +use machine::executed::ExecutionResult; // todo[dvdplm] why was this re-exported? + pub use self::request::{Request, Response, HeaderRef, Error as ValidityError}; pub use self::request_guard::{RequestGuard, Error as RequestError}; pub use self::response_guard::{ResponseGuard, Error as ResponseGuardError, Inner as ResponseGuardInner}; diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index 309ff6ec115..5e9533d5bc5 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -19,11 +19,14 @@ use std::sync::Arc; -use common_types::blockchain_info::BlockChainInfo; -use common_types::encoded; -use common_types::ids::BlockId; -use common_types::transaction::PendingTransaction; -use ethcore::client::{BlockChainClient, ProvingBlockChainClient, ChainInfo, BlockInfo as ClientBlockInfo}; +use common_types::{ + blockchain_info::BlockChainInfo, + encoded, + ids::BlockId, + transaction::PendingTransaction, +}; +use ethcore::client::{BlockChainClient, ProvingBlockChainClient, ChainInfo}; +use client_traits::BlockInfo as ClientBlockInfo; use ethereum_types::H256; use parking_lot::RwLock; diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 5d2cdececc2..b7a27bfb711 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -7,6 +7,7 @@ authors = ["Parity Technologies "] [dependencies] account-state = { path = "../account-state" } +client-traits = { path = "../client-traits" } common-types = { path = "../types" } derive_more = "0.14.0" ethabi = "8.0" @@ -24,6 +25,7 @@ futures = "0.1" parity-util-mem = "0.1" keccak-hash = "0.2.0" log = "0.4" +machine = { path = "../machine" } parity-bytes = "0.1" parity-crypto = "0.4.0" parking_lot = "0.8" diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 5cfcde041f6..30878f8784e 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -24,6 +24,7 @@ mod error; mod log; extern crate account_state; +extern crate client_traits; extern crate common_types as types; extern crate ethabi; extern crate ethcore; @@ -37,6 +38,7 @@ extern crate fetch; extern crate futures; extern crate parity_util_mem; extern crate keccak_hash as hash; +extern crate machine; extern crate parity_bytes as bytes; extern crate parity_crypto as crypto; extern crate parking_lot; @@ -87,14 +89,16 @@ use parking_lot::RwLock; use bytes::Bytes; use ethkey::{Signature, recover, public_to_address}; use io::IoChannel; -use ethcore::executive::{Executive, TransactOptions}; -use ethcore::executed::{Executed}; +use machine::{ + executive::{Executive, TransactOptions, contract_address as ethcore_contract_address}, + executed::Executed, +}; use types::transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}; -use ethcore::{contract_address as ethcore_contract_address}; use ethcore::client::{ Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId, - Call, BlockInfo + Call }; +use client_traits::BlockInfo; use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache}; use state_db::StateDB; use account_state::State; diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 19a4a70b6a6..3bc6f4373c6 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -32,7 +32,6 @@ //! related info. use std::{cmp, ops}; -use std::collections::HashSet; use std::sync::Arc; use bytes::Bytes; @@ -45,7 +44,7 @@ use account_state::State; use trace::Tracing; use triehash::ordered_trie_root; use unexpected::{Mismatch, OutOfBounds}; -use vm::{EnvInfo, LastHashes}; +use vm::LastHashes; use hash::keccak; use rlp::{RlpStream, Encodable, encode_list}; @@ -57,6 +56,7 @@ use types::{ receipt::{Receipt, TransactionOutcome}, }; use executive_state::ExecutiveState; +use machine::ExecutedBlock; /// Block that is ready for transactions to be added. /// @@ -94,71 +94,6 @@ pub struct SealedBlock { block: ExecutedBlock, } -/// An internal type for a block's common elements. -#[derive(Clone)] -pub struct ExecutedBlock { - /// Executed block header. - pub header: Header, - /// Executed transactions. - pub transactions: Vec, - /// Uncles. - pub uncles: Vec
, - /// Transaction receipts. - pub receipts: Vec, - /// Hashes of already executed transactions. - pub transactions_set: HashSet, - /// Underlying state. - pub state: State, - /// Transaction traces. - pub traces: Tracing, - /// Hashes of last 256 blocks. - pub last_hashes: Arc, -} - -impl ExecutedBlock { - /// Create a new block from the given `state`. - fn new(state: State, last_hashes: Arc, tracing: bool) -> ExecutedBlock { - ExecutedBlock { - header: Default::default(), - transactions: Default::default(), - uncles: Default::default(), - receipts: Default::default(), - transactions_set: Default::default(), - state, - traces: if tracing { - Tracing::enabled() - } else { - Tracing::Disabled - }, - last_hashes, - } - } - - /// Get the environment info concerning this block. - pub fn env_info(&self) -> EnvInfo { - // TODO: memoise. - EnvInfo { - number: self.header.number(), - author: self.header.author().clone(), - timestamp: self.header.timestamp(), - difficulty: self.header.difficulty().clone(), - last_hashes: self.last_hashes.clone(), - gas_used: self.receipts.last().map_or(U256::zero(), |r| r.gas_used), - gas_limit: self.header.gas_limit().clone(), - } - } - - /// Get mutable access to a state. - pub fn state_mut(&mut self) -> &mut State { - &mut self.state - } - - /// Get mutable reference to traces. - pub fn traces_mut(&mut self) -> &mut Tracing { - &mut self.traces - } -} - /// Trait for an object that owns an `ExecutedBlock` pub trait Drain { /// Returns `ExecutedBlock` diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index e0633f5cb83..0b2eaf4367c 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -46,13 +46,18 @@ use client::{ BlockChainReset }; use client::{ - BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, + ClientConfig, BlockChainClient, TraceFilter, CallAnalytics, Mode, ChainNotify, NewBlocks, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType, - IoClient, BadBlocks, bad_blocks, BlockInfo, ClientIoMessage, + IoClient, BadBlocks, bad_blocks, ClientIoMessage, }; +use client_traits::BlockInfo; use engines::{Engine, EpochTransition, ForkChoice}; -use executive::{Executive, Executed, TransactOptions, contract_address}; +use machine::{ + executed::Executed, + executive::{Executive, TransactOptions, contract_address}, + transaction_ext::Transaction, +}; use trie_vm_factories::{Factories, VmFactory}; use miner::{Miner, MinerService}; use snapshot::{self, io as snapshot_io, SnapshotClient}; @@ -61,7 +66,6 @@ use account_state::State; use executive_state; use state_db::StateDB; use trace::{self, TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase}; -use transaction_ext::Transaction; use types::{ ancestry_action::AncestryAction, BlockNumber, @@ -74,6 +78,7 @@ use types::{ machine::{AuxiliaryData, Call as MachineCall}, }, errors::{EngineError, ExecutionError, BlockError, EthcoreError, SnapshotError, ImportError, EthcoreResult}, + ids::{BlockId, TransactionId, UncleId, TraceId}, transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Action, CallError}, filter::Filter, log_entry::LocalizedLogEntry, diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index 8d0419e2e11..4f0c4293c96 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use ethereum_types::{H256, U256, H160}; use {trie_vm_factories, journaldb, trie, kvdb_memorydb}; use kvdb::{self, KeyValueDB}; -use {state_db, client, executive, trace, db, spec}; +use {state_db, client, trace, db, spec}; use pod::PodState; use types::{ errors::EthcoreError, @@ -34,7 +34,10 @@ use evm::{VMType, FinalizationResult}; use vm::{self, ActionParams, CreateContractAddress}; use ethtrie; use account_state::{CleanupMode, State}; -use substate::Substate; +use machine::{ + executive, + substate::Substate, +}; use executive_state::ExecutiveState; diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index a7260b82509..05051aec04b 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -35,19 +35,18 @@ pub use self::io_message::ClientIoMessage; pub use self::test_client::{TestBlockChainClient, EachBlockWith, TestState}; pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ - Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, + Nonce, Balance, ChainInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks, - BlockChainReset + BlockChainReset, BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient }; pub use account_state::state::StateInfo; -pub use self::traits::{BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient}; -pub use types::ids::*; +pub use types::ids::*; // todo[dvdplm] Why these re-exports? pub use types::trace_filter::Filter as TraceFilter; pub use types::pruning_info::PruningInfo; pub use types::call_analytics::CallAnalytics; -pub use executive::{Executed, Executive, TransactOptions}; +//pub use executive::{Executed, Executive, TransactOptions}; // todo[dvdplm] Why these re-exports? pub use vm::{LastHashes, EnvInfo}; pub use verification::VerifierType; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 6b0ae3c81e3..baea824d33a 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -60,9 +60,9 @@ use client::{ Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, IoClient, BadBlocks }; -use client::BlockInfo; +use client_traits::BlockInfo; use engines::Engine; -use executive::Executed; +use machine::executed::Executed; use journaldb; use miner::{self, Miner, MinerService}; use spec::Spec; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 69787efa9f9..72c221772ce 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -20,6 +20,7 @@ use std::sync::Arc; use blockchain::{BlockReceipts, TreeRoute}; use bytes::Bytes; use call_contract::{CallContract, RegistryInfo}; +use client_traits::BlockInfo; use ethcore_miner::pool::VerifiedTransaction; use ethereum_types::{H256, U256, Address}; use evm::Schedule; @@ -49,7 +50,7 @@ use vm::LastHashes; use block::{OpenBlock, SealedBlock, ClosedBlock}; use client::Mode; use engines::Engine; -use executive::Executed; +use machine::executed::Executed; use account_state::state::StateInfo; use trace::LocalizedTrace; use verification::queue::kind::blocks::Unverified; // todo this is reexported from common_types @@ -114,21 +115,6 @@ pub trait ChainInfo { fn chain_info(&self) -> BlockChainInfo; } -/// Provides various information on a block by it's ID -pub trait BlockInfo { - /// Get raw block header data by block id. - fn block_header(&self, id: BlockId) -> Option; - - /// Get the best block header. - fn best_block_header(&self) -> Header; - - /// Get raw block data by block header hash. - fn block(&self, id: BlockId) -> Option; - - /// Get address code hash at given block's state. - fn code_hash(&self, address: &Address, id: BlockId) -> Option; -} - /// Provides various information on a transaction by it's ID pub trait TransactionInfo { /// Get the hash of block that contains the transaction, if any. diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 951e66a2d32..211ab388b28 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -24,13 +24,15 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Weak, Arc}; use std::time::{UNIX_EPOCH, Duration}; -use block::*; use client::EngineClient; use engines::{Engine, Seal, ConstructedVerifier}; use engines::block_reward; use engines::block_reward::{BlockRewardContract, RewardKind}; use ethjson; -use machine::Machine; +use machine::{ + ExecutedBlock, + Machine, +}; use hash::keccak; use super::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index d5247da3470..632e2a0e8c9 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -20,12 +20,14 @@ use std::sync::Weak; use ethereum_types::{H256, H520}; use parking_lot::RwLock; use ethkey::{self, Signature}; -use block::*; use engines::{Engine, Seal, ConstructedVerifier}; use engines::signer::EngineSigner; use ethjson; use client::EngineClient; -use machine::Machine; +use machine::{ + Machine, + executed_block::ExecutedBlock, +}; use types::{ header::Header, engines::{ diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index 8df88d9f282..062e0b2e90d 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -22,7 +22,7 @@ use ethereum_types::{Address, U256}; use std::sync::Arc; use hash::keccak; -use machine::Machine; +use machine::{Machine, ExecutedBlock}; use trace; use types::{ BlockNumber, @@ -30,7 +30,6 @@ use types::{ }; use super::{SystemOrCodeCall, SystemOrCodeCallKind}; use trace::{Tracer, ExecutiveTracer, Tracing}; -use block::ExecutedBlock; use_contract!(block_reward_contract, "res/contracts/block_reward.json"); diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index 84d45a2840d..2e3259e3f77 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -65,7 +65,6 @@ use std::thread; use std::time; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; -use block::ExecutedBlock; use client::{BlockId, EngineClient}; use engines::clique::util::{extract_signers, recover_creator}; use engines::{Engine, Seal, SealingState, EthashSeal}; @@ -74,7 +73,10 @@ use ethkey::Signature; use hash::KECCAK_EMPTY_LIST_RLP; use itertools::Itertools; use lru_cache::LruCache; -use machine::Machine; +use machine::{ + ExecutedBlock, + Machine, +}; use parking_lot::RwLock; use rand::Rng; use super::signer::EngineSigner; diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index 21aeca87c99..f715518f438 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -32,11 +32,13 @@ use types::{ use unexpected::{OutOfBounds, Mismatch}; -use block::ExecutedBlock; use engines::block_reward::{self, BlockRewardContract, RewardKind}; use engines::{self, Engine}; use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor}; -use machine::Machine; +use machine::{ + ExecutedBlock, + Machine, +}; /// Number of blocks in an ethash snapshot. // make dependent on difficulty increment divisor? @@ -501,7 +503,8 @@ mod tests { }; use spec::Spec; use engines::Engine; - use ethereum::{new_morden, new_mcip3_test, new_homestead_test_machine}; + use ethereum::{new_morden, new_mcip3_test}; + use machine::test_helpers::new_homestead_test_machine; use super::{Ethash, EthashParams, ecip1017_eras_block_reward}; use rlp; use tempdir::TempDir; diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 51dd8ff3c18..e0124d5c5db 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -15,7 +15,10 @@ // along with Parity Ethereum. If not, see . use engines::{Engine, Seal}; -use machine::Machine; +use machine::{ + ExecutedBlock, + Machine +}; use types::{ header::Header, engines::{ @@ -25,7 +28,6 @@ use types::{ errors::EthcoreError as Error, }; -use block::ExecutedBlock; /// `InstantSeal` params. #[derive(Default, Debug, PartialEq)] diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index ddbbbef1020..b5391c0b226 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -60,11 +60,13 @@ use types::{ use snapshot::SnapshotComponents; use client::EngineClient; -use ethkey::{Signature}; -use machine::Machine; +use ethkey::Signature; +use machine::{ + Machine, + executed_block::ExecutedBlock, +}; use ethereum_types::{H256, U256, Address}; use bytes::Bytes; -use block::ExecutedBlock; /// Seal type. #[derive(Debug, PartialEq, Eq)] @@ -91,7 +93,7 @@ pub enum SystemOrCodeCallKind { } /// Default SystemOrCodeCall implementation. -pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut ::block::ExecutedBlock) -> impl FnMut(SystemOrCodeCallKind, Vec) -> Result, String> + 'a { +pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut ExecutedBlock) -> impl FnMut(SystemOrCodeCallKind, Vec) -> Result, String> + 'a { move |to, data| { let result = match to { SystemOrCodeCallKind::Address(address) => { diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index c62c64681e3..549bf22e053 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -17,14 +17,16 @@ use engines::Engine; use engines::block_reward::{self, RewardKind}; use ethereum_types::U256; -use machine::Machine; +use machine::{ + ExecutedBlock, + Machine, +}; use types::{ BlockNumber, header::Header, engines::params::CommonParams, errors::EthcoreError as Error, }; -use block::ExecutedBlock; /// Params for a null engine. #[derive(Clone, Default)] diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index ca3f3cd3d8e..efafb833c11 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -152,7 +152,7 @@ mod tests { use test_helpers::generate_dummy_client_with_spec; use call_contract::CallContract; use client::{BlockChainClient, ChainInfo}; - use client::BlockInfo; + use client_traits::BlockInfo; use super::super::ValidatorSet; use super::ValidatorContract; diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index d43edf10f29..463d42dec9f 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -156,7 +156,7 @@ mod tests { use hash::keccak; use accounts::AccountProvider; use client::{BlockChainClient, ChainInfo, ImportBlock}; - use client::BlockInfo; + use client_traits::BlockInfo; use engines::EpochChange; use engines::validator_set::ValidatorSet; use ethkey::Secret; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index cc2aafc4cf7..08c9b37602c 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -458,7 +458,7 @@ mod tests { use accounts::AccountProvider; use types::transaction::{Transaction, Action}; use client::{ChainInfo, ImportBlock}; - use client::BlockInfo; + use client_traits::BlockInfo; use ethkey::Secret; use miner::{self, MinerService}; use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data}; diff --git a/ethcore/src/ethereum.rs b/ethcore/src/ethereum.rs index 458da478101..59d3f27d2e0 100644 --- a/ethcore/src/ethereum.rs +++ b/ethcore/src/ethereum.rs @@ -19,7 +19,6 @@ //! Contains all Ethereum network specific stuff, such as denominations and //! consensus specifications. -use machine::Machine; use crate::spec::{Spec, SpecParams}; /// Load chain spec from `SpecParams` and JSON. @@ -30,10 +29,6 @@ pub fn load<'a, T: Into>>>(params: T, b: &[u8]) -> Spec { }.expect("chain spec is invalid") } -fn load_machine(b: &[u8]) -> Machine { - Spec::load_machine(b).expect("chain spec is invalid") -} - /// Create a new Foundation mainnet chain spec. pub fn new_foundation<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../res/ethereum/foundation.json")) @@ -151,32 +146,6 @@ pub fn new_constantinople_fix_test() -> Spec { load(None, include_bytes!("../res /// Create a new Musicoin-MCIP3-era spec. pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../res/ethereum/mcip3_test.json")) } -// For tests - -/// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead. -pub fn new_frontier_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/frontier_test.json")) } - -/// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier. -pub fn new_homestead_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/homestead_test.json")) } - -/// Create a new Foundation Homestead-EIP210-era chain spec as though it never changed from Homestead/Frontier. -pub fn new_eip210_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/eip210_test.json")) } - -/// Create a new Foundation Byzantium era spec. -pub fn new_byzantium_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/byzantium_test.json")) } - -/// Create a new Foundation Constantinople era spec. -pub fn new_constantinople_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/constantinople_test.json")) } - -/// Create a new Foundation St. Peter's (Contantinople Fix) era spec. -pub fn new_constantinople_fix_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/st_peters_test.json")) } - -/// Create a new Musicoin-MCIP3-era spec. -pub fn new_mcip3_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/mcip3_test.json")) } - -/// Create new Kovan spec with wasm activated at certain block -pub fn new_kovan_wasm_test_machine() -> Machine { load_machine(include_bytes!("../res/ethereum/kovan_wasm_test.json")) } - #[cfg(test)] mod tests { use account_state::State; diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs deleted file mode 100644 index 6b503942cd1..00000000000 --- a/ethcore/src/executed.rs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Transaction execution format module. - -use ethereum_types::{U256, Address}; -use bytes::Bytes; -use vm; -use trace::{VMTrace, FlatTrace}; -use types::{ - state_diff::StateDiff, - log_entry::LogEntry, - errors::ExecutionError, -}; - -/// Transaction execution receipt. -#[derive(Debug, PartialEq, Clone)] -pub struct Executed { - /// True if the outer call/create resulted in an exceptional exit. - pub exception: Option, - - /// Gas paid up front for execution of transaction. - pub gas: U256, - - /// Gas used during execution of transaction. - pub gas_used: U256, - - /// Gas refunded after the execution of transaction. - /// To get gas that was required up front, add `refunded` and `gas_used`. - pub refunded: U256, - - /// Cumulative gas used in current block so far. - /// - /// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)` - /// - /// where `tn` is current transaction. - pub cumulative_gas_used: U256, - - /// Vector of logs generated by transaction. - pub logs: Vec, - - /// Addresses of contracts created during execution of transaction. - /// Ordered from earliest creation. - /// - /// eg. sender creates contract A and A in constructor creates contract B - /// - /// B creation ends first, and it will be the first element of the vector. - pub contracts_created: Vec
, - /// Transaction output. - pub output: Bytes, - /// The trace of this transaction. - pub trace: Vec, - /// The VM trace of this transaction. - pub vm_trace: Option, - /// The state diff, if we traced it. - pub state_diff: Option, -} - -/// Transaction execution result. -pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs deleted file mode 100644 index ae48ac92fc3..00000000000 --- a/ethcore/src/executive.rs +++ /dev/null @@ -1,2260 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Transaction Execution environment. -use std::cmp; -use std::convert::TryFrom; -use std::sync::Arc; -use hash::keccak; -use ethereum_types::{H256, U256, U512, Address}; -use bytes::{Bytes, BytesRef}; -use account_state::{Backend as StateBackend, State, CleanupMode}; -use substate::Substate; -use machine::Machine; -use evm::{CallType, Finalize, FinalizationResult}; -use vm::{ - self, EnvInfo, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, - ActionValue, Schedule, TrapError, ResumeCall, ResumeCreate -}; -use trie_vm_factories::VmFactory; -use externalities::*; -use trace::{self, Tracer, VMTracer}; -use types::{ - errors::ExecutionError, - transaction::{Action, SignedTransaction}, -}; -use transaction_ext::Transaction; -use crossbeam_utils::thread; -pub use executed::{Executed, ExecutionResult}; - -#[cfg(debug_assertions)] -/// Roughly estimate what stack size each level of evm depth will use. (Debug build) -const STACK_SIZE_PER_DEPTH: usize = 128 * 1024; - -#[cfg(not(debug_assertions))] -/// Roughly estimate what stack size each level of evm depth will use. -const STACK_SIZE_PER_DEPTH: usize = 24 * 1024; - -#[cfg(debug_assertions)] -/// Entry stack overhead prior to execution. (Debug build) -const STACK_SIZE_ENTRY_OVERHEAD: usize = 100 * 1024; - -#[cfg(not(debug_assertions))] -/// Entry stack overhead prior to execution. -const STACK_SIZE_ENTRY_OVERHEAD: usize = 20 * 1024; - -/// Returns new address created from address, nonce, and code hash -pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address, nonce: &U256, code: &[u8]) -> (Address, Option) { - use rlp::RlpStream; - - match address_scheme { - CreateContractAddress::FromSenderAndNonce => { - let mut stream = RlpStream::new_list(2); - stream.append(sender); - stream.append(nonce); - (From::from(keccak(stream.as_raw())), None) - }, - CreateContractAddress::FromSenderSaltAndCodeHash(salt) => { - let code_hash = keccak(code); - let mut buffer = [0u8; 1 + 20 + 32 + 32]; - buffer[0] = 0xff; - &mut buffer[1..(1+20)].copy_from_slice(&sender[..]); - &mut buffer[(1+20)..(1+20+32)].copy_from_slice(&salt[..]); - &mut buffer[(1+20+32)..].copy_from_slice(&code_hash[..]); - (From::from(keccak(&buffer[..])), Some(code_hash)) - }, - CreateContractAddress::FromSenderAndCodeHash => { - let code_hash = keccak(code); - let mut buffer = [0u8; 20 + 32]; - &mut buffer[..20].copy_from_slice(&sender[..]); - &mut buffer[20..].copy_from_slice(&code_hash[..]); - (From::from(keccak(&buffer[..])), Some(code_hash)) - }, - } -} - -/// Convert a finalization result into a VM message call result. -pub fn into_message_call_result(result: vm::Result) -> vm::MessageCallResult { - match result { - Ok(FinalizationResult { gas_left, return_data, apply_state: true }) => vm::MessageCallResult::Success(gas_left, return_data), - Ok(FinalizationResult { gas_left, return_data, apply_state: false }) => vm::MessageCallResult::Reverted(gas_left, return_data), - _ => vm::MessageCallResult::Failed - } -} - -/// Convert a finalization result into a VM contract create result. -pub fn into_contract_create_result(result: vm::Result, address: &Address, substate: &mut Substate) -> vm::ContractCreateResult { - match result { - Ok(FinalizationResult { gas_left, apply_state: true, .. }) => { - substate.contracts_created.push(address.clone()); - vm::ContractCreateResult::Created(address.clone(), gas_left) - }, - Ok(FinalizationResult { gas_left, apply_state: false, return_data }) => { - vm::ContractCreateResult::Reverted(gas_left, return_data) - }, - _ => vm::ContractCreateResult::Failed, - } -} - -/// Get the cleanup mode object from this. -pub fn cleanup_mode<'a>(substate: &'a mut Substate, schedule: &Schedule) -> CleanupMode<'a> { - match (schedule.kill_dust != CleanDustMode::Off, schedule.no_empty, schedule.kill_empty) { - (false, false, _) => CleanupMode::ForceCreate, - (false, true, false) => CleanupMode::NoEmpty, - (false, true, true) | (true, _, _,) => CleanupMode::TrackTouched(&mut substate.touched), - } -} - -/// Transaction execution options. -#[derive(Copy, Clone, PartialEq)] -pub struct TransactOptions { - /// Enable call tracing. - pub tracer: T, - /// Enable VM tracing. - pub vm_tracer: V, - /// Check transaction nonce before execution. - pub check_nonce: bool, - /// Records the output from init contract calls. - pub output_from_init_contract: bool, -} - -impl TransactOptions { - /// Create new `TransactOptions` with given tracer and VM tracer. - pub fn new(tracer: T, vm_tracer: V) -> Self { - TransactOptions { - tracer, - vm_tracer, - check_nonce: true, - output_from_init_contract: false, - } - } - - /// Disables the nonce check - pub fn dont_check_nonce(mut self) -> Self { - self.check_nonce = false; - self - } - - /// Saves the output from contract creation. - pub fn save_output_from_contract(mut self) -> Self { - self.output_from_init_contract = true; - self - } -} - -impl TransactOptions { - /// Creates new `TransactOptions` with default tracing and VM tracing. - pub fn with_tracing_and_vm_tracing() -> Self { - TransactOptions { - tracer: trace::ExecutiveTracer::default(), - vm_tracer: trace::ExecutiveVMTracer::toplevel(), - check_nonce: true, - output_from_init_contract: false, - } - } -} - -impl TransactOptions { - /// Creates new `TransactOptions` with default tracing and no VM tracing. - pub fn with_tracing() -> Self { - TransactOptions { - tracer: trace::ExecutiveTracer::default(), - vm_tracer: trace::NoopVMTracer, - check_nonce: true, - output_from_init_contract: false, - } - } -} - -impl TransactOptions { - /// Creates new `TransactOptions` with no tracing and default VM tracing. - pub fn with_vm_tracing() -> Self { - TransactOptions { - tracer: trace::NoopTracer, - vm_tracer: trace::ExecutiveVMTracer::toplevel(), - check_nonce: true, - output_from_init_contract: false, - } - } -} - -impl TransactOptions { - /// Creates new `TransactOptions` without any tracing. - pub fn with_no_tracing() -> Self { - TransactOptions { - tracer: trace::NoopTracer, - vm_tracer: trace::NoopVMTracer, - check_nonce: true, - output_from_init_contract: false, - } - } -} - -/// Trap result returned by executive. -pub type ExecutiveTrapResult<'a, T> = vm::TrapResult, CallCreateExecutive<'a>>; -/// Trap error for executive. -pub type ExecutiveTrapError<'a> = vm::TrapError, CallCreateExecutive<'a>>; - -enum CallCreateExecutiveKind { - Transfer(ActionParams), - CallBuiltin(ActionParams), - ExecCall(ActionParams, Substate), - ExecCreate(ActionParams, Substate), - ResumeCall(OriginInfo, Box, Substate), - ResumeCreate(OriginInfo, Box, Substate), -} - -/// Executive for a raw call/create action. -pub struct CallCreateExecutive<'a> { - info: &'a EnvInfo, - machine: &'a Machine, - schedule: &'a Schedule, - factory: &'a VmFactory, - depth: usize, - stack_depth: usize, - static_flag: bool, - is_create: bool, - gas: U256, - kind: CallCreateExecutiveKind, -} - -impl<'a> CallCreateExecutive<'a> { - /// Create a new call executive using raw data. - pub fn new_call_raw(params: ActionParams, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule, factory: &'a VmFactory, depth: usize, stack_depth: usize, parent_static_flag: bool) -> Self { - trace!("Executive::call(params={:?}) self.env_info={:?}, parent_static={}", params, info, parent_static_flag); - - let gas = params.gas; - let static_flag = parent_static_flag || params.call_type == CallType::StaticCall; - - // if destination is builtin, try to execute it - let kind = if let Some(builtin) = machine.builtin(¶ms.code_address, info.number) { - // Engines aren't supposed to return builtins until activation, but - // prefer to fail rather than silently break consensus. - if !builtin.is_active(info.number) { - panic!("Consensus failure: engine implementation prematurely enabled built-in at {}", params.code_address); - } - - CallCreateExecutiveKind::CallBuiltin(params) - } else { - if params.code.is_some() { - CallCreateExecutiveKind::ExecCall(params, Substate::new()) - } else { - CallCreateExecutiveKind::Transfer(params) - } - }; - - Self { - info, machine, schedule, factory, depth, stack_depth, static_flag, kind, gas, - is_create: false, - } - } - - /// Create a new create executive using raw data. - pub fn new_create_raw(params: ActionParams, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule, factory: &'a VmFactory, depth: usize, stack_depth: usize, static_flag: bool) -> Self { - trace!("Executive::create(params={:?}) self.env_info={:?}, static={}", params, info, static_flag); - - let gas = params.gas; - - let kind = CallCreateExecutiveKind::ExecCreate(params, Substate::new()); - - Self { - info, machine, schedule, factory, depth, stack_depth, static_flag, kind, gas, - is_create: true, - } - } - - /// If this executive contains an unconfirmed substate, returns a mutable reference to it. - pub fn unconfirmed_substate(&mut self) -> Option<&mut Substate> { - match self.kind { - CallCreateExecutiveKind::ExecCall(_, ref mut unsub) => Some(unsub), - CallCreateExecutiveKind::ExecCreate(_, ref mut unsub) => Some(unsub), - CallCreateExecutiveKind::ResumeCreate(_, _, ref mut unsub) => Some(unsub), - CallCreateExecutiveKind::ResumeCall(_, _, ref mut unsub) => Some(unsub), - CallCreateExecutiveKind::Transfer(..) | CallCreateExecutiveKind::CallBuiltin(..) => None, - } - } - - fn check_static_flag(params: &ActionParams, static_flag: bool, is_create: bool) -> vm::Result<()> { - if is_create { - if static_flag { - return Err(vm::Error::MutableCallInStaticContext); - } - } else { - if (static_flag && - (params.call_type == CallType::StaticCall || params.call_type == CallType::Call)) && - params.value.value() > U256::zero() - { - return Err(vm::Error::MutableCallInStaticContext); - } - } - - Ok(()) - } - - fn check_eip684(params: &ActionParams, state: &State) -> vm::Result<()> { - if state.exists_and_has_code_or_nonce(¶ms.address)? { - return Err(vm::Error::OutOfGas); - } - - Ok(()) - } - - fn transfer_exec_balance(params: &ActionParams, schedule: &Schedule, state: &mut State, substate: &mut Substate) -> vm::Result<()> { - if let ActionValue::Transfer(val) = params.value { - state.transfer_balance(¶ms.sender, ¶ms.address, &val, cleanup_mode(substate, &schedule))?; - } - - Ok(()) - } - - fn transfer_exec_balance_and_init_contract(params: &ActionParams, schedule: &Schedule, state: &mut State, substate: &mut Substate) -> vm::Result<()> { - let nonce_offset = if schedule.no_empty { 1 } else { 0 }.into(); - let prev_bal = state.balance(¶ms.address)?; - if let ActionValue::Transfer(val) = params.value { - state.sub_balance(¶ms.sender, &val, &mut cleanup_mode(substate, &schedule))?; - state.new_contract(¶ms.address, val.saturating_add(prev_bal), nonce_offset, params.code_version)?; - } else { - state.new_contract(¶ms.address, prev_bal, nonce_offset, params.code_version)?; - } - - Ok(()) - } - - fn enact_result(result: &vm::Result, state: &mut State, substate: &mut Substate, un_substate: Substate) { - match *result { - Err(vm::Error::OutOfGas) - | Err(vm::Error::BadJumpDestination {..}) - | Err(vm::Error::BadInstruction {.. }) - | Err(vm::Error::StackUnderflow {..}) - | Err(vm::Error::BuiltIn {..}) - | Err(vm::Error::Wasm {..}) - | Err(vm::Error::OutOfStack {..}) - | Err(vm::Error::MutableCallInStaticContext) - | Err(vm::Error::OutOfBounds) - | Err(vm::Error::Reverted) - | Ok(FinalizationResult { apply_state: false, .. }) => { - state.revert_to_checkpoint(); - }, - Ok(_) | Err(vm::Error::Internal(_)) => { - state.discard_checkpoint(); - substate.accrue(un_substate); - } - } - } - - /// Creates `Externalities` from `Executive`. - fn as_externalities<'any, B: 'any + StateBackend, T, V>( - state: &'any mut State, - info: &'any EnvInfo, - machine: &'any Machine, - schedule: &'any Schedule, - depth: usize, - stack_depth: usize, - static_flag: bool, - origin_info: &'any OriginInfo, - substate: &'any mut Substate, - output: OutputPolicy, - tracer: &'any mut T, - vm_tracer: &'any mut V, - ) -> Externalities<'any, T, V, B> where T: Tracer, V: VMTracer { - Externalities::new(state, info, machine, schedule, depth, stack_depth, origin_info, substate, output, tracer, vm_tracer, static_flag) - } - - /// Execute the executive. If a sub-call/create action is required, a resume trap error is returned. The caller is - /// then expected to call `resume_call` or `resume_create` to continue the execution. - /// - /// Current-level tracing is expected to be handled by caller. - pub fn exec(mut self, state: &mut State, substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> ExecutiveTrapResult<'a, FinalizationResult> { - match self.kind { - CallCreateExecutiveKind::Transfer(ref params) => { - assert!(!self.is_create); - - let mut inner = || { - Self::check_static_flag(params, self.static_flag, self.is_create)?; - Self::transfer_exec_balance(params, self.schedule, state, substate)?; - - Ok(FinalizationResult { - gas_left: params.gas, - return_data: ReturnData::empty(), - apply_state: true, - }) - }; - - Ok(inner()) - }, - CallCreateExecutiveKind::CallBuiltin(ref params) => { - assert!(!self.is_create); - - let mut inner = || { - let builtin = self.machine.builtin(¶ms.code_address, self.info.number).expect("Builtin is_some is checked when creating this kind in new_call_raw; qed"); - - Self::check_static_flag(¶ms, self.static_flag, self.is_create)?; - state.checkpoint(); - Self::transfer_exec_balance(¶ms, self.schedule, state, substate)?; - - let default = []; - let data = if let Some(ref d) = params.data { d as &[u8] } else { &default as &[u8] }; - - let cost = builtin.cost(data); - if cost <= params.gas { - let mut builtin_out_buffer = Vec::new(); - let result = { - let mut builtin_output = BytesRef::Flexible(&mut builtin_out_buffer); - builtin.execute(data, &mut builtin_output) - }; - if let Err(e) = result { - state.revert_to_checkpoint(); - - Err(vm::Error::BuiltIn(e)) - } else { - state.discard_checkpoint(); - - let out_len = builtin_out_buffer.len(); - Ok(FinalizationResult { - gas_left: params.gas - cost, - return_data: ReturnData::new(builtin_out_buffer, 0, out_len), - apply_state: true, - }) - } - } else { - // just drain the whole gas - state.revert_to_checkpoint(); - - Err(vm::Error::OutOfGas) - } - }; - - Ok(inner()) - }, - CallCreateExecutiveKind::ExecCall(params, mut unconfirmed_substate) => { - assert!(!self.is_create); - - { - let static_flag = self.static_flag; - let is_create = self.is_create; - let schedule = self.schedule; - - let mut pre_inner = || { - Self::check_static_flag(¶ms, static_flag, is_create)?; - state.checkpoint(); - Self::transfer_exec_balance(¶ms, schedule, state, substate)?; - Ok(()) - }; - - match pre_inner() { - Ok(()) => (), - Err(err) => return Ok(Err(err)), - } - } - - let origin_info = OriginInfo::from(¶ms); - let exec = self.factory.create(params, self.schedule, self.depth); - - let out = match exec { - Some(exec) => { - let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, OutputPolicy::Return, tracer, vm_tracer); - match exec.exec(&mut ext) { - Ok(val) => Ok(val.finalize(ext)), - Err(err) => Err(err), - } - }, - None => Ok(Err(vm::Error::OutOfGas)), - }; - - let res = match out { - Ok(val) => val, - Err(TrapError::Call(subparams, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Call(subparams, self)); - }, - Err(TrapError::Create(subparams, address, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Create(subparams, address, self)); - }, - }; - - Self::enact_result(&res, state, substate, unconfirmed_substate); - Ok(res) - }, - CallCreateExecutiveKind::ExecCreate(params, mut unconfirmed_substate) => { - assert!(self.is_create); - - { - let static_flag = self.static_flag; - let is_create = self.is_create; - let schedule = self.schedule; - - let mut pre_inner = || { - Self::check_eip684(¶ms, state)?; - Self::check_static_flag(¶ms, static_flag, is_create)?; - state.checkpoint(); - Self::transfer_exec_balance_and_init_contract(¶ms, schedule, state, substate)?; - Ok(()) - }; - - match pre_inner() { - Ok(()) => (), - Err(err) => return Ok(Err(err)), - } - } - - let origin_info = OriginInfo::from(¶ms); - let exec = self.factory.create(params, self.schedule, self.depth); - - let out = match exec { - Some(exec) => { - let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, OutputPolicy::InitContract, tracer, vm_tracer); - match exec.exec(&mut ext) { - Ok(val) => Ok(val.finalize(ext)), - Err(err) => Err(err), - } - }, - None => Ok(Err(vm::Error::OutOfGas)), - }; - - let res = match out { - Ok(val) => val, - Err(TrapError::Call(subparams, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Call(subparams, self)); - }, - Err(TrapError::Create(subparams, address, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Create(subparams, address, self)); - }, - }; - - Self::enact_result(&res, state, substate, unconfirmed_substate); - Ok(res) - }, - CallCreateExecutiveKind::ResumeCall(..) | CallCreateExecutiveKind::ResumeCreate(..) => panic!("This executive has already been executed once."), - } - } - - /// Resume execution from a call trap previsouly trapped by `exec`. - /// - /// Current-level tracing is expected to be handled by caller. - pub fn resume_call(mut self, result: vm::MessageCallResult, state: &mut State, substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> ExecutiveTrapResult<'a, FinalizationResult> { - match self.kind { - CallCreateExecutiveKind::ResumeCall(origin_info, resume, mut unconfirmed_substate) => { - let out = { - let exec = resume.resume_call(result); - - let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, if self.is_create { OutputPolicy::InitContract } else { OutputPolicy::Return }, tracer, vm_tracer); - match exec.exec(&mut ext) { - Ok(val) => Ok(val.finalize(ext)), - Err(err) => Err(err), - } - }; - - let res = match out { - Ok(val) => val, - Err(TrapError::Call(subparams, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Call(subparams, self)); - }, - Err(TrapError::Create(subparams, address, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Create(subparams, address, self)); - }, - }; - - Self::enact_result(&res, state, substate, unconfirmed_substate); - Ok(res) - }, - CallCreateExecutiveKind::ResumeCreate(..) => - panic!("Resumable as create, but called resume_call"), - CallCreateExecutiveKind::Transfer(..) | CallCreateExecutiveKind::CallBuiltin(..) | - CallCreateExecutiveKind::ExecCall(..) | CallCreateExecutiveKind::ExecCreate(..) => - panic!("Not resumable"), - } - } - - /// Resume execution from a create trap previsouly trapped by `exec`. - /// - /// Current-level tracing is expected to be handled by caller. - pub fn resume_create(mut self, result: vm::ContractCreateResult, state: &mut State, substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> ExecutiveTrapResult<'a, FinalizationResult> { - match self.kind { - CallCreateExecutiveKind::ResumeCreate(origin_info, resume, mut unconfirmed_substate) => { - let out = { - let exec = resume.resume_create(result); - - let mut ext = Self::as_externalities(state, self.info, self.machine, self.schedule, self.depth, self.stack_depth, self.static_flag, &origin_info, &mut unconfirmed_substate, if self.is_create { OutputPolicy::InitContract } else { OutputPolicy::Return }, tracer, vm_tracer); - match exec.exec(&mut ext) { - Ok(val) => Ok(val.finalize(ext)), - Err(err) => Err(err), - } - }; - - let res = match out { - Ok(val) => val, - Err(TrapError::Call(subparams, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCall(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Call(subparams, self)); - }, - Err(TrapError::Create(subparams, address, resume)) => { - self.kind = CallCreateExecutiveKind::ResumeCreate(origin_info, resume, unconfirmed_substate); - return Err(TrapError::Create(subparams, address, self)); - }, - }; - - Self::enact_result(&res, state, substate, unconfirmed_substate); - Ok(res) - }, - CallCreateExecutiveKind::ResumeCall(..) => - panic!("Resumable as call, but called resume_create"), - CallCreateExecutiveKind::Transfer(..) | CallCreateExecutiveKind::CallBuiltin(..) | - CallCreateExecutiveKind::ExecCall(..) | CallCreateExecutiveKind::ExecCreate(..) => - panic!("Not resumable"), - } - } - - /// Execute and consume the current executive. This function handles resume traps and sub-level tracing. The caller is expected to handle current-level tracing. - pub fn consume(self, state: &mut State, top_substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V) -> vm::Result { - let mut last_res = Some((false, self.gas, self.exec(state, top_substate, tracer, vm_tracer))); - - let mut callstack: Vec<(Option
, CallCreateExecutive<'a>)> = Vec::new(); - loop { - match last_res { - None => { - match callstack.pop() { - Some((_, exec)) => { - let second_last = callstack.last_mut(); - let parent_substate = match second_last { - Some((_, ref mut second_last)) => second_last.unconfirmed_substate().expect("Current stack value is created from second last item; second last item must be call or create; qed"), - None => top_substate, - }; - - last_res = Some((exec.is_create, exec.gas, exec.exec(state, parent_substate, tracer, vm_tracer))); - }, - None => panic!("When callstack only had one item and it was executed, this function would return; callstack never reaches zero item; qed"), - } - }, - Some((is_create, gas, Ok(val))) => { - let current = callstack.pop(); - - match current { - Some((address, mut exec)) => { - if is_create { - let address = address.expect("If the last executed status was from a create executive, then the destination address was pushed to the callstack; address is_some if it is_create; qed"); - - match val { - Ok(ref val) if val.apply_state => { - tracer.done_trace_create( - gas - val.gas_left, - &val.return_data, - address - ); - }, - Ok(_) => { - tracer.done_trace_failed(&vm::Error::Reverted); - }, - Err(ref err) => { - tracer.done_trace_failed(err); - }, - } - - vm_tracer.done_subtrace(); - - let second_last = callstack.last_mut(); - let parent_substate = match second_last { - Some((_, ref mut second_last)) => second_last.unconfirmed_substate().expect("Current stack value is created from second last item; second last item must be call or create; qed"), - None => top_substate, - }; - - let contract_create_result = into_contract_create_result(val, &address, exec.unconfirmed_substate().expect("Executive is resumed from a create; it has an unconfirmed substate; qed")); - last_res = Some((exec.is_create, exec.gas, exec.resume_create( - contract_create_result, - state, - parent_substate, - tracer, - vm_tracer - ))); - } else { - match val { - Ok(ref val) if val.apply_state => { - tracer.done_trace_call( - gas - val.gas_left, - &val.return_data, - ); - }, - Ok(_) => { - tracer.done_trace_failed(&vm::Error::Reverted); - }, - Err(ref err) => { - tracer.done_trace_failed(err); - }, - } - - vm_tracer.done_subtrace(); - - let second_last = callstack.last_mut(); - let parent_substate = match second_last { - Some((_, ref mut second_last)) => second_last.unconfirmed_substate().expect("Current stack value is created from second last item; second last item must be call or create; qed"), - None => top_substate, - }; - - last_res = Some((exec.is_create, exec.gas, exec.resume_call( - into_message_call_result(val), - state, - parent_substate, - tracer, - vm_tracer - ))); - } - }, - None => return val, - } - }, - Some((_, _, Err(TrapError::Call(subparams, resume)))) => { - tracer.prepare_trace_call(&subparams, resume.depth + 1, resume.machine.builtin(&subparams.address, resume.info.number).is_some()); - vm_tracer.prepare_subtrace(subparams.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); - - let sub_exec = CallCreateExecutive::new_call_raw( - subparams, - resume.info, - resume.machine, - resume.schedule, - resume.factory, - resume.depth + 1, - resume.stack_depth, - resume.static_flag, - ); - - callstack.push((None, resume)); - callstack.push((None, sub_exec)); - last_res = None; - }, - Some((_, _, Err(TrapError::Create(subparams, address, resume)))) => { - tracer.prepare_trace_create(&subparams); - vm_tracer.prepare_subtrace(subparams.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); - - let sub_exec = CallCreateExecutive::new_create_raw( - subparams, - resume.info, - resume.machine, - resume.schedule, - resume.factory, - resume.depth + 1, - resume.stack_depth, - resume.static_flag - ); - - callstack.push((Some(address), resume)); - callstack.push((None, sub_exec)); - last_res = None; - }, - } - } - } -} - -/// Transaction executor. -pub struct Executive<'a, B: 'a> { - state: &'a mut State, - info: &'a EnvInfo, - machine: &'a Machine, - schedule: &'a Schedule, - depth: usize, - static_flag: bool, -} - -impl<'a, B: 'a + StateBackend> Executive<'a, B> { - /// Basic constructor. - pub fn new(state: &'a mut State, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule) -> Self { - Executive { - state: state, - info: info, - machine: machine, - schedule: schedule, - depth: 0, - static_flag: false, - } - } - - /// Populates executive from parent properties. Increments executive depth. - pub fn from_parent(state: &'a mut State, info: &'a EnvInfo, machine: &'a Machine, schedule: &'a Schedule, parent_depth: usize, static_flag: bool) -> Self { - Executive { - state: state, - info: info, - machine: machine, - schedule: schedule, - depth: parent_depth + 1, - static_flag: static_flag, - } - } - - /// This function should be used to execute transaction. - pub fn transact(&'a mut self, t: &SignedTransaction, options: TransactOptions) - -> Result, ExecutionError> where T: Tracer, V: VMTracer, - { - self.transact_with_tracer(t, options.check_nonce, options.output_from_init_contract, options.tracer, options.vm_tracer) - } - - /// Execute a transaction in a "virtual" context. - /// This will ensure the caller has enough balance to execute the desired transaction. - /// Used for extra-block executions for things like consensus contracts and RPCs - pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) - -> Result, ExecutionError> where T: Tracer, V: VMTracer, - { - let sender = t.sender(); - let balance = self.state.balance(&sender)?; - let needed_balance = t.value.saturating_add(t.gas.saturating_mul(t.gas_price)); - if balance < needed_balance { - // give the sender a sufficient balance - self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?; - } - - self.transact(t, options) - } - - /// Execute transaction/call with tracing enabled - fn transact_with_tracer( - &'a mut self, - t: &SignedTransaction, - check_nonce: bool, - output_from_create: bool, - mut tracer: T, - mut vm_tracer: V - ) -> Result, ExecutionError> where T: Tracer, V: VMTracer { - let sender = t.sender(); - let nonce = self.state.nonce(&sender)?; - - let schedule = self.schedule; - let base_gas_required = U256::from(t.gas_required(&schedule)); - - if t.gas < base_gas_required { - return Err(ExecutionError::NotEnoughBaseGas { required: base_gas_required, got: t.gas }); - } - - if !t.is_unsigned() && check_nonce && schedule.kill_dust != CleanDustMode::Off && !self.state.exists(&sender)? { - return Err(ExecutionError::SenderMustExist); - } - - let init_gas = t.gas - base_gas_required; - - // validate transaction nonce - if check_nonce && t.nonce != nonce { - return Err(ExecutionError::InvalidNonce { expected: nonce, got: t.nonce }); - } - - // validate if transaction fits into given block - if self.info.gas_used + t.gas > self.info.gas_limit { - return Err(ExecutionError::BlockGasLimitReached { - gas_limit: self.info.gas_limit, - gas_used: self.info.gas_used, - gas: t.gas - }); - } - - // TODO: we might need bigints here, or at least check overflows. - let balance = self.state.balance(&sender)?; - let gas_cost = t.gas.full_mul(t.gas_price); - let total_cost = U512::from(t.value) + gas_cost; - - // avoid unaffordable transactions - let balance512 = U512::from(balance); - if balance512 < total_cost { - return Err(ExecutionError::NotEnoughCash { required: total_cost, got: balance512 }); - } - - let mut substate = Substate::new(); - - // NOTE: there can be no invalid transactions from this point. - if !schedule.keep_unsigned_nonce || !t.is_unsigned() { - self.state.inc_nonce(&sender)?; - } - self.state.sub_balance( - &sender, - &U256::try_from(gas_cost).expect("Total cost (value + gas_cost) is lower than max allowed balance (U256); gas_cost has to fit U256; qed"), - &mut cleanup_mode(&mut substate, &schedule) - )?; - - let (result, output) = match t.action { - Action::Create => { - let (new_address, code_hash) = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &nonce, &t.data); - let params = ActionParams { - code_address: new_address.clone(), - code_hash: code_hash, - address: new_address, - sender: sender.clone(), - origin: sender.clone(), - gas: init_gas, - gas_price: t.gas_price, - value: ActionValue::Transfer(t.value), - code: Some(Arc::new(t.data.clone())), - code_version: schedule.latest_version, - data: None, - call_type: CallType::None, - params_type: vm::ParamsType::Embedded, - }; - let res = self.create(params, &mut substate, &mut tracer, &mut vm_tracer); - let out = match &res { - Ok(res) if output_from_create => res.return_data.to_vec(), - _ => Vec::new(), - }; - (res, out) - }, - Action::Call(ref address) => { - let params = ActionParams { - code_address: address.clone(), - address: address.clone(), - sender: sender.clone(), - origin: sender.clone(), - gas: init_gas, - gas_price: t.gas_price, - value: ActionValue::Transfer(t.value), - code: self.state.code(address)?, - code_hash: self.state.code_hash(address)?, - code_version: self.state.code_version(address)?, - data: Some(t.data.clone()), - call_type: CallType::Call, - params_type: vm::ParamsType::Separate, - }; - let res = self.call(params, &mut substate, &mut tracer, &mut vm_tracer); - let out = match &res { - Ok(res) => res.return_data.to_vec(), - _ => Vec::new(), - }; - (res, out) - } - }; - - // finalize here! - Ok(self.finalize(t, substate, result, output, tracer.drain(), vm_tracer.drain())?) - } - - /// Calls contract function with given contract params and stack depth. - /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). - /// Modifies the substate and the output. - /// Returns either gas_left or `vm::Error`. - pub fn call_with_stack_depth( - &mut self, - params: ActionParams, - substate: &mut Substate, - stack_depth: usize, - tracer: &mut T, - vm_tracer: &mut V - ) -> vm::Result where T: Tracer, V: VMTracer { - tracer.prepare_trace_call(¶ms, self.depth, self.machine.builtin(¶ms.address, self.info.number).is_some()); - vm_tracer.prepare_subtrace(params.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); - - let gas = params.gas; - - let vm_factory = self.state.vm_factory(); - let result = CallCreateExecutive::new_call_raw( - params, - self.info, - self.machine, - self.schedule, - &vm_factory, - self.depth, - stack_depth, - self.static_flag - ).consume(self.state, substate, tracer, vm_tracer); - - match result { - Ok(ref val) if val.apply_state => { - tracer.done_trace_call( - gas - val.gas_left, - &val.return_data, - ); - }, - Ok(_) => { - tracer.done_trace_failed(&vm::Error::Reverted); - }, - Err(ref err) => { - tracer.done_trace_failed(err); - }, - } - vm_tracer.done_subtrace(); - - result - } - - /// Calls contract function with given contract params, if the stack depth is above a threshold, create a new thread - /// to execute it. - pub fn call_with_crossbeam( - &mut self, - params: ActionParams, - substate: &mut Substate, - stack_depth: usize, - tracer: &mut T, - vm_tracer: &mut V - ) -> vm::Result where T: Tracer, V: VMTracer { - let local_stack_size = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get()); - let depth_threshold = local_stack_size.saturating_sub(STACK_SIZE_ENTRY_OVERHEAD) / STACK_SIZE_PER_DEPTH; - - if stack_depth != depth_threshold { - self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) - } else { - thread::scope(|scope| { - let stack_size = cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size); - scope.builder() - .stack_size(stack_size) - .spawn(|_| { - self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) - }) - .expect("Sub-thread creation cannot fail; the host might run out of resources; qed") - .join() - }) - .expect("Sub-thread never panics; qed") - .expect("Sub-thread never panics; qed") - } - } - - /// Calls contract function with given contract params. - pub fn call( - &mut self, - params: ActionParams, - substate: &mut Substate, - tracer: &mut T, - vm_tracer: &mut V - ) -> vm::Result where T: Tracer, V: VMTracer { - self.call_with_stack_depth(params, substate, 0, tracer, vm_tracer) - } - - /// Creates contract with given contract params and stack depth. - /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). - /// Modifies the substate. - pub fn create_with_stack_depth( - &mut self, - params: ActionParams, - substate: &mut Substate, - stack_depth: usize, - tracer: &mut T, - vm_tracer: &mut V, - ) -> vm::Result where T: Tracer, V: VMTracer { - tracer.prepare_trace_create(¶ms); - vm_tracer.prepare_subtrace(params.code.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); - - let address = params.address; - let gas = params.gas; - - let vm_factory = self.state.vm_factory(); - let result = CallCreateExecutive::new_create_raw( - params, - self.info, - self.machine, - self.schedule, - &vm_factory, - self.depth, - stack_depth, - self.static_flag - ).consume(self.state, substate, tracer, vm_tracer); - - match result { - Ok(ref val) if val.apply_state => { - tracer.done_trace_create( - gas - val.gas_left, - &val.return_data, - address, - ); - }, - Ok(_) => { - tracer.done_trace_failed(&vm::Error::Reverted); - }, - Err(ref err) => { - tracer.done_trace_failed(err); - }, - } - vm_tracer.done_subtrace(); - - result - } - - /// Creates contract with given contract params, if the stack depth is above a threshold, create a new thread to - /// execute it. - pub fn create_with_crossbeam( - &mut self, - params: ActionParams, - substate: &mut Substate, - stack_depth: usize, - tracer: &mut T, - vm_tracer: &mut V, - ) -> vm::Result where T: Tracer, V: VMTracer { - let local_stack_size = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get()); - let depth_threshold = local_stack_size.saturating_sub(STACK_SIZE_ENTRY_OVERHEAD) / STACK_SIZE_PER_DEPTH; - - if stack_depth != depth_threshold { - self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) - } else { - thread::scope(|scope| { - let stack_size = cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size); - scope.builder() - .stack_size(stack_size) - .spawn(|_| { - self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) - }) - .expect("Sub-thread creation cannot fail; the host might run out of resources; qed") - .join() - }) - .expect("Sub-thread never panics; qed") - .expect("Sub-thread never panics; qed") - } - } - - /// Creates contract with given contract params. - pub fn create( - &mut self, - params: ActionParams, - substate: &mut Substate, - tracer: &mut T, - vm_tracer: &mut V, - ) -> vm::Result where T: Tracer, V: VMTracer { - self.create_with_stack_depth(params, substate, 0, tracer, vm_tracer) - } - - /// Finalizes the transaction (does refunds and suicides). - fn finalize( - &mut self, - t: &SignedTransaction, - mut substate: Substate, - result: vm::Result, - output: Bytes, - trace: Vec, - vm_trace: Option - ) -> Result, ExecutionError> { - let schedule = self.schedule; - - // refunds from SSTORE nonzero -> zero - assert!(substate.sstore_clears_refund >= 0, "On transaction level, sstore clears refund cannot go below zero."); - let sstore_refunds = U256::from(substate.sstore_clears_refund as u64); - // refunds from contract suicides - let suicide_refunds = U256::from(schedule.suicide_refund_gas) * U256::from(substate.suicides.len()); - let refunds_bound = sstore_refunds + suicide_refunds; - - // real ammount to refund - let gas_left_prerefund = match result { Ok(FinalizationResult{ gas_left, .. }) => gas_left, _ => 0.into() }; - let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) >> 1); - let gas_left = gas_left_prerefund + refunded; - - let gas_used = t.gas.saturating_sub(gas_left); - let (refund_value, overflow_1) = gas_left.overflowing_mul(t.gas_price); - let (fees_value, overflow_2) = gas_used.overflowing_mul(t.gas_price); - if overflow_1 || overflow_2 { - return Err(ExecutionError::TransactionMalformed("U256 Overflow".to_string())); - } - - - trace!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n", - t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value); - - let sender = t.sender(); - trace!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, sender); - // Below: NoEmpty is safe since the sender must already be non-null to have sent this transaction - self.state.add_balance(&sender, &refund_value, CleanupMode::NoEmpty)?; - trace!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author); - self.state.add_balance(&self.info.author, &fees_value, cleanup_mode(&mut substate, &schedule))?; - - // perform suicides - for address in &substate.suicides { - self.state.kill_account(address); - } - - // perform garbage-collection - let min_balance = if schedule.kill_dust != CleanDustMode::Off { Some(U256::from(schedule.tx_gas).overflowing_mul(t.gas_price).0) } else { None }; - self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?; - - match result { - Err(vm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), - Err(exception) => { - Ok(Executed { - exception: Some(exception), - gas: t.gas, - gas_used: t.gas, - refunded: U256::zero(), - cumulative_gas_used: self.info.gas_used + t.gas, - logs: vec![], - contracts_created: vec![], - output: output, - trace: trace, - vm_trace: vm_trace, - state_diff: None, - }) - }, - Ok(r) => { - Ok(Executed { - exception: if r.apply_state { None } else { Some(vm::Error::Reverted) }, - gas: t.gas, - gas_used: gas_used, - refunded: refunded, - cumulative_gas_used: self.info.gas_used + gas_used, - logs: substate.logs, - contracts_created: substate.contracts_created, - output: output, - trace: trace, - vm_trace: vm_trace, - state_diff: None, - }) - }, - } - } -} - -#[cfg(test)] -#[allow(dead_code)] -mod tests { - use std::sync::Arc; - use std::str::FromStr; - use std::collections::HashSet; - use rustc_hex::FromHex; - use ethkey::{Generator, Random}; - use super::*; - use ethereum_types::{H256, U256, U512, Address, BigEndianHash}; - use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; - use evm::{Factory, VMType}; - use machine::Machine; - use account_state::CleanupMode; - use substate::Substate; - use test_helpers::{get_temp_state_with_factory, get_temp_state}; - use trace::trace; - use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer}; - use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; - use types::{ - errors::ExecutionError, - transaction::{Action, Transaction}, - }; - - fn make_frontier_machine(max_depth: usize) -> Machine { - let mut machine = ::ethereum::new_frontier_test_machine(); - machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth)); - machine - } - - fn make_byzantium_machine(max_depth: usize) -> Machine { - let mut machine = ::ethereum::new_byzantium_test_machine(); - machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth)); - machine - } - - #[test] - fn test_cleanup_mode() { - let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut touched = HashSet::new(); - touched.insert(address); - - let mut substate = Substate::default(); - substate.touched = touched.clone(); - - assert_eq!(CleanupMode::ForceCreate, cleanup_mode(&mut substate, &Schedule::new_frontier())); - assert_eq!(CleanupMode::ForceCreate, cleanup_mode(&mut substate, &Schedule::new_homestead())); - assert_eq!(CleanupMode::TrackTouched(&mut touched), cleanup_mode(&mut substate, &Schedule::new_byzantium())); - assert_eq!(CleanupMode::TrackTouched(&mut touched), cleanup_mode(&mut substate, &Schedule::new_constantinople())); - - assert_eq!(CleanupMode::TrackTouched(&mut touched), cleanup_mode(&mut substate, &{ - let mut schedule = Schedule::new_homestead(); - schedule.kill_dust = CleanDustMode::BasicOnly; - schedule - })); - - assert_eq!(CleanupMode::NoEmpty, cleanup_mode(&mut substate, &{ - let mut schedule = Schedule::new_homestead(); - schedule.no_empty = true; - schedule - })); - } - - #[test] - fn test_contract_address() { - let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let expected_address = Address::from_str("3f09c73a5ed19289fb9bdc72f1742566df146f56").unwrap(); - assert_eq!(expected_address, contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::from(88), &[]).0); - } - - // TODO: replace params with transactions! - evm_test!{test_sender_balance: test_sender_balance_int} - fn test_sender_balance(factory: Factory) { - let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - let mut params = ActionParams::default(); - params.address = address.clone(); - params.sender = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new("3331600055".from_hex().unwrap())); - params.value = ActionValue::Transfer(U256::from(0x7)); - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(0x100u64), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(79_975)); - assert_eq!(state.storage_at(&address, &H256::zero()).unwrap(), BigEndianHash::from_uint(&U256::from(0xf9u64))); - assert_eq!(state.balance(&sender).unwrap(), U256::from(0xf9)); - assert_eq!(state.balance(&address).unwrap(), U256::from(0x7)); - assert_eq!(substate.contracts_created.len(), 0); - - // TODO: just test state root. - } - - evm_test!{test_create_contract_out_of_depth: test_create_contract_out_of_depth_int} - fn test_create_contract_out_of_depth(factory: Factory) { - // code: - // - // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? - // 60 00 - push 0 - // 52 - // 60 1d - push 29 - // 60 03 - push 3 - // 60 17 - push 17 - // f0 - create - // 60 00 - push 0 - // 55 sstore - // - // other code: - // - // 60 10 - push 16 - // 80 - duplicate first stack item - // 60 0c - push 12 - // 60 00 - push 0 - // 39 - copy current code to memory - // 60 00 - push 0 - // f3 - return - - let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); - - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - // TODO: add tests for 'callcreate' - //let next_address = contract_address(&address, &U256::zero()); - let mut params = ActionParams::default(); - params.address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::from(100)); - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(62_976)); - // ended with max depth - assert_eq!(substate.contracts_created.len(), 0); - } - - #[test] - fn test_call_to_precompiled_tracing() { - // code: - // - // 60 00 - push 00 out size - // 60 00 - push 00 out offset - // 60 00 - push 00 in size - // 60 00 - push 00 in offset - // 60 01 - push 01 value - // 60 03 - push 03 to - // 61 ffff - push fff gas - // f1 - CALL - - let code = "60006000600060006001600361fffff1".from_hex().unwrap(); - let sender = Address::from_str("4444444444444444444444444444444444444444").unwrap(); - let address = Address::from_str("5555555555555555555555555555555555555555").unwrap(); - - let mut params = ActionParams::default(); - params.address = address.clone(); - params.code_address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::from(100)); - params.call_type = CallType::Call; - let mut state = get_temp_state(); - state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_byzantium_machine(5); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - let mut tracer = ExecutiveTracer::default(); - let mut vm_tracer = ExecutiveVMTracer::toplevel(); - - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params, &mut substate, &mut tracer, &mut vm_tracer).unwrap(); - - assert_eq!(tracer.drain(), vec![FlatTrace { - action: trace::Action::Call(trace::Call { - from: Address::from_str("4444444444444444444444444444444444444444").unwrap(), - to: Address::from_str("5555555555555555555555555555555555555555").unwrap(), - value: 100.into(), - gas: 100_000.into(), - input: vec![], - call_type: CallType::Call - }), - result: trace::Res::Call(trace::CallResult { - gas_used: 33021.into(), - output: vec![] - }), - subtraces: 1, - trace_address: Default::default() - }, FlatTrace { - action: trace::Action::Call(trace::Call { - from: Address::from_str("5555555555555555555555555555555555555555").unwrap(), - to: Address::from_str("0000000000000000000000000000000000000003").unwrap(), - value: 1.into(), - gas: 66560.into(), - input: vec![], - call_type: CallType::Call - }), result: trace::Res::Call(trace::CallResult { - gas_used: 600.into(), - output: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 17, 133, 165, 197, 233, 252, 84, 97, 40, 8, 151, 126, 232, 245, 72, 178, 37, 141, 49] - }), - subtraces: 0, - trace_address: vec![0].into_iter().collect(), - }]); - } - - #[test] - // Tracing is not suported in JIT - fn test_call_to_create() { - // code: - // - // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? - // 60 00 - push 0 - // 52 - // 60 1d - push 29 - // 60 03 - push 3 - // 60 17 - push 23 - // f0 - create - // 60 00 - push 0 - // 55 sstore - // - // other code: - // - // 60 10 - push 16 - // 80 - duplicate first stack item - // 60 0c - push 12 - // 60 00 - push 0 - // 39 - copy current code to memory - // 60 00 - push 0 - // f3 - return - - let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); - - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - // TODO: add tests for 'callcreate' - //let next_address = contract_address(&address, &U256::zero()); - let mut params = ActionParams::default(); - params.address = address.clone(); - params.code_address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::from(100)); - params.call_type = CallType::Call; - let mut state = get_temp_state(); - state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(5); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - let mut tracer = ExecutiveTracer::default(); - let mut vm_tracer = ExecutiveVMTracer::toplevel(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params, &mut substate, &mut tracer, &mut vm_tracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(44_752)); - - let expected_trace = vec![FlatTrace { - trace_address: Default::default(), - subtraces: 1, - action: trace::Action::Call(trace::Call { - from: Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(), - to: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), - value: 100.into(), - gas: 100000.into(), - input: vec![], - call_type: CallType::Call, - }), - result: trace::Res::Call(trace::CallResult { - gas_used: U256::from(55_248), - output: vec![], - }), - }, FlatTrace { - trace_address: vec![0].into_iter().collect(), - subtraces: 0, - action: trace::Action::Create(trace::Create { - from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), - value: 23.into(), - gas: 67979.into(), - init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85] - }), - result: trace::Res::Create(trace::CreateResult { - gas_used: U256::from(3224), - address: Address::from_str("c6d80f262ae5e0f164e5fde365044d7ada2bfa34").unwrap(), - code: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] - }), - }]; - - assert_eq!(tracer.drain(), expected_trace); - - let expected_vm_trace = VMTrace { - parent_step: 0, - code: vec![124, 96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85, 96, 0, 82, 96, 29, 96, 3, 96, 23, 240, 96, 0, 85], - operations: vec![ - VMOperation { pc: 0, instruction: 124, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99997.into(), stack_push: vec_into![U256::from_dec_str("2589892687202724018173567190521546555304938078595079151649957320078677").unwrap()], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 30, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99994.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 32, instruction: 82, gas_cost: 6.into(), executed: Some(VMExecutedOperation { gas_used: 99988.into(), stack_push: vec_into![], mem_diff: Some(MemoryDiff { offset: 0, data: vec![0, 0, 0, 96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85] }), store_diff: None }) }, - VMOperation { pc: 33, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99985.into(), stack_push: vec_into![29], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 35, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99982.into(), stack_push: vec_into![3], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 37, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99979.into(), stack_push: vec_into![23], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 39, instruction: 240, gas_cost: 99979.into(), executed: Some(VMExecutedOperation { gas_used: 64755.into(), stack_push: vec_into![U256::from_dec_str("1135198453258042933984631383966629874710669425204").unwrap()], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 40, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 64752.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 42, instruction: 85, gas_cost: 20000.into(), executed: Some(VMExecutedOperation { gas_used: 44752.into(), stack_push: vec_into![], mem_diff: None, store_diff: Some(StorageDiff { location: 0.into(), value: U256::from_dec_str("1135198453258042933984631383966629874710669425204").unwrap() }) }) } - ], - subs: vec![ - VMTrace { - parent_step: 6, - code: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], - operations: vec![ - VMOperation { pc: 0, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67976.into(), stack_push: vec_into![16], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 2, instruction: 128, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67973.into(), stack_push: vec_into![16, 16], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 3, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67970.into(), stack_push: vec_into![12], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 5, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67967.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 7, instruction: 57, gas_cost: 9.into(), executed: Some(VMExecutedOperation { gas_used: 67958.into(), stack_push: vec_into![], mem_diff: Some(MemoryDiff { offset: 0, data: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] }), store_diff: None }) }, - VMOperation { pc: 8, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67955.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 10, instruction: 243, gas_cost: 0.into(), executed: Some(VMExecutedOperation { gas_used: 67955.into(), stack_push: vec_into![], mem_diff: None, store_diff: None }) } - ], - subs: vec![] - } - ] - }; - assert_eq!(vm_tracer.drain().unwrap(), expected_vm_trace); - } - - #[test] - fn test_trace_reverted_create() { - // code: - // - // 65 60016000fd - push 5 bytes - // 60 00 - push 0 - // 52 mstore - // 60 05 - push 5 - // 60 1b - push 27 - // 60 17 - push 23 - // f0 - create - // 60 00 - push 0 - // 55 sstore - // - // other code: - // - // 60 01 - // 60 00 - // fd - revert - - let code = "6460016000fd6000526005601b6017f0600055".from_hex().unwrap(); - - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - let mut params = ActionParams::default(); - params.address = address.clone(); - params.code_address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::from(100)); - params.call_type = CallType::Call; - let mut state = get_temp_state(); - state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = ::ethereum::new_byzantium_test_machine(); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - let mut tracer = ExecutiveTracer::default(); - let mut vm_tracer = ExecutiveVMTracer::toplevel(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params, &mut substate, &mut tracer, &mut vm_tracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(62967)); - - let expected_trace = vec![FlatTrace { - trace_address: Default::default(), - subtraces: 1, - action: trace::Action::Call(trace::Call { - from: Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(), - to: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), - value: 100.into(), - gas: 100_000.into(), - input: vec![], - call_type: CallType::Call, - }), - result: trace::Res::Call(trace::CallResult { - gas_used: U256::from(37_033), - output: vec![], - }), - }, FlatTrace { - trace_address: vec![0].into_iter().collect(), - subtraces: 0, - action: trace::Action::Create(trace::Create { - from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), - value: 23.into(), - gas: 66_917.into(), - init: vec![0x60, 0x01, 0x60, 0x00, 0xfd] - }), - result: trace::Res::FailedCreate(vm::Error::Reverted.into()), - }]; - - assert_eq!(tracer.drain(), expected_trace); - } - - #[test] - fn test_create_contract() { - // Tracing is not supported in JIT - // code: - // - // 60 10 - push 16 - // 80 - duplicate first stack item - // 60 0c - push 12 - // 60 00 - push 0 - // 39 - copy current code to memory - // 60 00 - push 0 - // f3 - return - - let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(); - - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - // TODO: add tests for 'callcreate' - //let next_address = contract_address(&address, &U256::zero()); - let mut params = ActionParams::default(); - params.address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(100.into()); - let mut state = get_temp_state(); - state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(5); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - let mut tracer = ExecutiveTracer::default(); - let mut vm_tracer = ExecutiveVMTracer::toplevel(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.create(params.clone(), &mut substate, &mut tracer, &mut vm_tracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(96_776)); - - let expected_trace = vec![FlatTrace { - trace_address: Default::default(), - subtraces: 0, - action: trace::Action::Create(trace::Create { - from: params.sender, - value: 100.into(), - gas: params.gas, - init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], - }), - result: trace::Res::Create(trace::CreateResult { - gas_used: U256::from(3224), - address: params.address, - code: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] - }), - }]; - - assert_eq!(tracer.drain(), expected_trace); - - let expected_vm_trace = VMTrace { - parent_step: 0, - code: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], - operations: vec![ - VMOperation { pc: 0, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99997.into(), stack_push: vec_into![16], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 2, instruction: 128, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99994.into(), stack_push: vec_into![16, 16], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 3, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99991.into(), stack_push: vec_into![12], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 5, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99988.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 7, instruction: 57, gas_cost: 9.into(), executed: Some(VMExecutedOperation { gas_used: 99979.into(), stack_push: vec_into![], mem_diff: Some(MemoryDiff { offset: 0, data: vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53] }), store_diff: None }) }, - VMOperation { pc: 8, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 99976.into(), stack_push: vec_into![0], mem_diff: None, store_diff: None }) }, - VMOperation { pc: 10, instruction: 243, gas_cost: 0.into(), executed: Some(VMExecutedOperation { gas_used: 99976.into(), stack_push: vec_into![], mem_diff: None, store_diff: None }) } - ], - subs: vec![] - }; - assert_eq!(vm_tracer.drain().unwrap(), expected_vm_trace); - } - - evm_test!{test_create_contract_value_too_high: test_create_contract_value_too_high_int} - fn test_create_contract_value_too_high(factory: Factory) { - // code: - // - // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? - // 60 00 - push 0 - // 52 - // 60 1d - push 29 - // 60 03 - push 3 - // 60 e6 - push 230 - // f0 - create a contract trying to send 230. - // 60 00 - push 0 - // 55 sstore - // - // other code: - // - // 60 10 - push 16 - // 80 - duplicate first stack item - // 60 0c - push 12 - // 60 00 - push 0 - // 39 - copy current code to memory - // 60 00 - push 0 - // f3 - return - - let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().unwrap(); - - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - // TODO: add tests for 'callcreate' - //let next_address = contract_address(&address, &U256::zero()); - let mut params = ActionParams::default(); - params.address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::from(100)); - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(62_976)); - assert_eq!(substate.contracts_created.len(), 0); - } - - evm_test!{test_create_contract_without_max_depth: test_create_contract_without_max_depth_int} - fn test_create_contract_without_max_depth(factory: Factory) { - // code: - // - // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? - // 60 00 - push 0 - // 52 - // 60 1d - push 29 - // 60 03 - push 3 - // 60 17 - push 17 - // f0 - create - // 60 00 - push 0 - // 55 sstore - // - // other code: - // - // 60 10 - push 16 - // 80 - duplicate first stack item - // 60 0c - push 12 - // 60 00 - push 0 - // 39 - copy current code to memory - // 60 00 - push 0 - // f3 - return - - let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap(); - - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &[]).0; - let mut params = ActionParams::default(); - params.address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::from(100)); - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(1024); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap(); - } - - assert_eq!(substate.contracts_created.len(), 1); - assert_eq!(substate.contracts_created[0], next_address); - } - - // test is incorrect, mk - // TODO: fix (preferred) or remove - evm_test_ignore!{test_aba_calls: test_aba_calls_int} - fn test_aba_calls(factory: Factory) { - // 60 00 - push 0 - // 60 00 - push 0 - // 60 00 - push 0 - // 60 00 - push 0 - // 60 18 - push 18 - // 73 945304eb96065b2a98b57a48a06ae28d285a71b5 - push this address - // 61 03e8 - push 1000 - // f1 - message call - // 58 - get PC - // 55 - sstore - - let code_a = "6000600060006000601873945304eb96065b2a98b57a48a06ae28d285a71b56103e8f15855".from_hex().unwrap(); - - // 60 00 - push 0 - // 60 00 - push 0 - // 60 00 - push 0 - // 60 00 - push 0 - // 60 17 - push 17 - // 73 0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 - push this address - // 61 0x01f4 - push 500 - // f1 - message call - // 60 01 - push 1 - // 01 - add - // 58 - get PC - // 55 - sstore - let code_b = "60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66101f4f16001015855".from_hex().unwrap(); - - let address_a = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let address_b = Address::from_str("945304eb96065b2a98b57a48a06ae28d285a71b5" ).unwrap(); - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - - let mut params = ActionParams::default(); - params.address = address_a.clone(); - params.sender = sender.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code_a.clone())); - params.value = ActionValue::Transfer(U256::from(100_000)); - - let mut state = get_temp_state_with_factory(factory); - state.init_code(&address_a, code_a.clone()).unwrap(); - state.init_code(&address_b, code_b.clone()).unwrap(); - state.add_balance(&sender, &U256::from(100_000), CleanupMode::NoEmpty).unwrap(); - - let info = EnvInfo::default(); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(73_237)); - assert_eq!( - state.storage_at( - &address_a, - &BigEndianHash::from_uint(&U256::from(0x23)), - ).unwrap(), - BigEndianHash::from_uint(&U256::from(1)), - ); - } - - // test is incorrect, mk - // TODO: fix (preferred) or remove - evm_test_ignore!{test_recursive_bomb1: test_recursive_bomb1_int} - fn test_recursive_bomb1(factory: Factory) { - // 60 01 - push 1 - // 60 00 - push 0 - // 54 - sload - // 01 - add - // 60 00 - push 0 - // 55 - sstore - // 60 00 - push 0 - // 60 00 - push 0 - // 60 00 - push 0 - // 60 00 - push 0 - // 60 00 - push 0 - // 30 - load address - // 60 e0 - push e0 - // 5a - get gas - // 03 - sub - // f1 - message call (self in this case) - // 60 01 - push 1 - // 55 - sstore - let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - let mut params = ActionParams::default(); - params.address = address.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code.clone())); - let mut state = get_temp_state_with_factory(factory); - state.init_code(&address, code).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - let FinalizationResult { gas_left, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - - assert_eq!(gas_left, U256::from(59_870)); - assert_eq!(state.storage_at(&address, &BigEndianHash::from_uint(&U256::zero())).unwrap(), BigEndianHash::from_uint(&U256::from(1))); - assert_eq!(state.storage_at(&address, &BigEndianHash::from_uint(&U256::one())).unwrap(), BigEndianHash::from_uint(&U256::from(1))); - } - - // test is incorrect, mk - // TODO: fix (preferred) or remove - evm_test_ignore!{test_transact_simple: test_transact_simple_int} - fn test_transact_simple(factory: Factory) { - let keypair = Random.generate().unwrap(); - let t = Transaction { - action: Action::Create, - value: U256::from(17), - data: "3331600055".from_hex().unwrap(), - gas: U256::from(100_000), - gas_price: U256::zero(), - nonce: U256::zero() - }.sign(keypair.secret(), None); - let sender = t.sender(); - let contract = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap(); - let mut info = EnvInfo::default(); - info.gas_limit = U256::from(100_000); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - - let executed = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - let opts = TransactOptions::with_no_tracing(); - ex.transact(&t, opts).unwrap() - }; - - assert_eq!(executed.gas, U256::from(100_000)); - assert_eq!(executed.gas_used, U256::from(41_301)); - assert_eq!(executed.refunded, U256::from(58_699)); - assert_eq!(executed.cumulative_gas_used, U256::from(41_301)); - assert_eq!(executed.logs.len(), 0); - assert_eq!(executed.contracts_created.len(), 0); - assert_eq!(state.balance(&sender).unwrap(), U256::from(1)); - assert_eq!(state.balance(&contract).unwrap(), U256::from(17)); - assert_eq!(state.nonce(&sender).unwrap(), U256::from(1)); - assert_eq!(state.storage_at(&contract, &H256::zero()).unwrap(), BigEndianHash::from_uint(&U256::from(1))); - } - - evm_test!{test_transact_invalid_nonce: test_transact_invalid_nonce_int} - fn test_transact_invalid_nonce(factory: Factory) { - let keypair = Random.generate().unwrap(); - let t = Transaction { - action: Action::Create, - value: U256::from(17), - data: "3331600055".from_hex().unwrap(), - gas: U256::from(100_000), - gas_price: U256::zero(), - nonce: U256::one() - }.sign(keypair.secret(), None); - let sender = t.sender(); - - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); - let mut info = EnvInfo::default(); - info.gas_limit = U256::from(100_000); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - - let res = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - let opts = TransactOptions::with_no_tracing(); - ex.transact(&t, opts) - }; - - match res { - Err(ExecutionError::InvalidNonce { expected, got }) - if expected == U256::zero() && got == U256::one() => (), - _ => assert!(false, "Expected invalid nonce error.") - } - } - - evm_test!{test_transact_gas_limit_reached: test_transact_gas_limit_reached_int} - fn test_transact_gas_limit_reached(factory: Factory) { - let keypair = Random.generate().unwrap(); - let t = Transaction { - action: Action::Create, - value: U256::from(17), - data: "3331600055".from_hex().unwrap(), - gas: U256::from(80_001), - gas_price: U256::zero(), - nonce: U256::zero() - }.sign(keypair.secret(), None); - let sender = t.sender(); - - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); - let mut info = EnvInfo::default(); - info.gas_used = U256::from(20_000); - info.gas_limit = U256::from(100_000); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - - let res = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - let opts = TransactOptions::with_no_tracing(); - ex.transact(&t, opts) - }; - - match res { - Err(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, gas }) - if gas_limit == U256::from(100_000) && gas_used == U256::from(20_000) && gas == U256::from(80_001) => (), - _ => assert!(false, "Expected block gas limit error.") - } - } - - evm_test!{test_not_enough_cash: test_not_enough_cash_int} - fn test_not_enough_cash(factory: Factory) { - - let keypair = Random.generate().unwrap(); - let t = Transaction { - action: Action::Create, - value: U256::from(18), - data: "3331600055".from_hex().unwrap(), - gas: U256::from(100_000), - gas_price: U256::one(), - nonce: U256::zero() - }.sign(keypair.secret(), None); - let sender = t.sender(); - - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from(100_017), CleanupMode::NoEmpty).unwrap(); - let mut info = EnvInfo::default(); - info.gas_limit = U256::from(100_000); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - - let res = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - let opts = TransactOptions::with_no_tracing(); - ex.transact(&t, opts) - }; - - match res { - Err(ExecutionError::NotEnoughCash { required , got }) - if required == U512::from(100_018) && got == U512::from(100_017) => (), - _ => assert!(false, "Expected not enough cash error. {:?}", res) - } - } - - evm_test!{test_keccak: test_keccak_int} - fn test_keccak(factory: Factory) { - let code = "6064640fffffffff20600055".from_hex().unwrap(); - - let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0; - // TODO: add tests for 'callcreate' - //let next_address = contract_address(&address, &U256::zero()); - let mut params = ActionParams::default(); - params.address = address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(0x0186a0); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::from_str("0de0b6b3a7640000").unwrap()); - let mut state = get_temp_state_with_factory(factory); - state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap(), CleanupMode::NoEmpty).unwrap(); - let info = EnvInfo::default(); - let machine = make_frontier_machine(0); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - let result = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) - }; - - match result { - Err(_) => {}, - _ => panic!("Expected OutOfGas"), - } - } - - evm_test!{test_revert: test_revert_int} - fn test_revert(factory: Factory) { - let contract_address = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - // EIP-140 test case - let code = "6c726576657274656420646174616000557f726576657274206d657373616765000000000000000000000000000000000000600052600e6000fd".from_hex().unwrap(); - let returns = "726576657274206d657373616765".from_hex().unwrap(); - let mut state = get_temp_state_with_factory(factory.clone()); - state.add_balance(&sender, &U256::from_str("152d02c7e14af68000000").unwrap(), CleanupMode::NoEmpty).unwrap(); - state.commit().unwrap(); - - let mut params = ActionParams::default(); - params.address = contract_address.clone(); - params.sender = sender.clone(); - params.origin = sender.clone(); - params.gas = U256::from(20025); - params.code = Some(Arc::new(code)); - params.value = ActionValue::Transfer(U256::zero()); - let info = EnvInfo::default(); - let machine = ::ethereum::new_byzantium_test_machine(); - let schedule = machine.schedule(info.number); - let mut substate = Substate::new(); - - let mut output = [0u8; 14]; - let FinalizationResult { gas_left: result, return_data, .. } = { - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - (&mut output).copy_from_slice(&return_data[..(cmp::min(14, return_data.len()))]); - - assert_eq!(result, U256::from(1)); - assert_eq!(output[..], returns[..]); - assert_eq!(state.storage_at(&contract_address, &H256::zero()).unwrap(), H256::zero()); - } - - evm_test!{test_eip1283: test_eip1283_int} - fn test_eip1283(factory: Factory) { - let x1 = Address::from_low_u64_be(0x1000); - let x2 = Address::from_low_u64_be(0x1001); - let y1 = Address::from_low_u64_be(0x2001); - let y2 = Address::from_low_u64_be(0x2002); - let operating_address = Address::zero(); - let k = H256::zero(); - - let mut state = get_temp_state_with_factory(factory.clone()); - state.new_contract(&x1, U256::zero(), U256::from(1), U256::zero()).unwrap(); - state.init_code(&x1, "600160005560006000556001600055".from_hex().unwrap()).unwrap(); - state.new_contract(&x2, U256::zero(), U256::from(1), U256::zero()).unwrap(); - state.init_code(&x2, "600060005560016000556000600055".from_hex().unwrap()).unwrap(); - state.new_contract(&y1, U256::zero(), U256::from(1), U256::zero()).unwrap(); - state.init_code(&y1, "600060006000600061100062fffffff4".from_hex().unwrap()).unwrap(); - state.new_contract(&y2, U256::zero(), U256::from(1), U256::zero()).unwrap(); - state.init_code(&y2, "600060006000600061100162fffffff4".from_hex().unwrap()).unwrap(); - - let info = EnvInfo::default(); - let machine = ::ethereum::new_constantinople_test_machine(); - let schedule = machine.schedule(info.number); - - assert_eq!(state.storage_at(&operating_address, &k).unwrap(), BigEndianHash::from_uint(&U256::from(0))); - // Test a call via top-level -> y1 -> x1 - let (FinalizationResult { gas_left, .. }, refund, gas) = { - let gas = U256::from(0xffffffffffu64); - let mut params = ActionParams::default(); - params.code = Some(Arc::new("6001600055600060006000600061200163fffffffff4".from_hex().unwrap())); - params.gas = gas; - let mut substate = Substate::new(); - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - let res = ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap(); - - (res, substate.sstore_clears_refund, gas) - }; - let gas_used = gas - gas_left; - // sstore: 0 -> (1) -> () -> (1 -> 0 -> 1) - assert_eq!(gas_used, U256::from(41860)); - assert_eq!(refund, 19800); - - assert_eq!(state.storage_at(&operating_address, &k).unwrap(), BigEndianHash::from_uint(&U256::from(1))); - // Test a call via top-level -> y2 -> x2 - let (FinalizationResult { gas_left, .. }, refund, gas) = { - let gas = U256::from(0xffffffffffu64); - let mut params = ActionParams::default(); - params.code = Some(Arc::new("6001600055600060006000600061200263fffffffff4".from_hex().unwrap())); - params.gas = gas; - let mut substate = Substate::new(); - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - let res = ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).unwrap(); - - (res, substate.sstore_clears_refund, gas) - }; - let gas_used = gas - gas_left; - // sstore: 1 -> (1) -> () -> (0 -> 1 -> 0) - assert_eq!(gas_used, U256::from(11860)); - assert_eq!(refund, 19800); - } - - fn wasm_sample_code() -> Arc> { - Arc::new( - "0061736d01000000010d0360027f7f0060017f0060000002270303656e7603726574000003656e760673656e646572000103656e76066d656d6f727902010110030201020404017000000501000708010463616c6c00020901000ac10101be0102057f017e4100410028020441c0006b22043602042004412c6a41106a220041003602002004412c6a41086a22014200370200200441186a41106a22024100360200200441186a41086a220342003703002004420037022c2004410036021c20044100360218200441186a1001200020022802002202360200200120032903002205370200200441106a2002360200200441086a200537030020042004290318220537022c200420053703002004411410004100200441c0006a3602040b0b0a010041040b0410c00000" - .from_hex() - .unwrap() - ) - } - - #[test] - fn wasm_activated_test() { - let contract_address = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - - let mut state = get_temp_state(); - state.add_balance(&sender, &U256::from(10000000000u64), CleanupMode::NoEmpty).unwrap(); - state.commit().unwrap(); - - let mut params = ActionParams::default(); - params.origin = sender.clone(); - params.sender = sender.clone(); - params.address = contract_address.clone(); - params.gas = U256::from(20025); - params.code = Some(wasm_sample_code()); - - let mut info = EnvInfo::default(); - - // 100 > 10 - info.number = 100; - - // Network with wasm activated at block 10 - let machine = ::ethereum::new_kovan_wasm_test_machine(); - - let mut output = [0u8; 20]; - let FinalizationResult { gas_left: result, return_data, .. } = { - let schedule = machine.schedule(info.number); - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params.clone(), &mut Substate::new(), &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - (&mut output).copy_from_slice(&return_data[..(cmp::min(20, return_data.len()))]); - - assert_eq!(result, U256::from(18433)); - // Transaction successfully returned sender - assert_eq!(output[..], sender[..]); - - // 1 < 10 - info.number = 1; - - let mut output = [0u8; 20]; - let FinalizationResult { gas_left: result, return_data, .. } = { - let schedule = machine.schedule(info.number); - let mut ex = Executive::new(&mut state, &info, &machine, &schedule); - ex.call(params, &mut Substate::new(), &mut NoopTracer, &mut NoopVMTracer).unwrap() - }; - (&mut output[..((cmp::min(20, return_data.len())))]).copy_from_slice(&return_data[..(cmp::min(20, return_data.len()))]); - - assert_eq!(result, U256::from(20025)); - // Since transaction errored due to wasm was not activated, result is just empty - assert_eq!(output[..], [0u8; 20][..]); - } -} diff --git a/ethcore/src/executive_state.rs b/ethcore/src/executive_state.rs index 0931c45811b..94abcba47f6 100644 --- a/ethcore/src/executive_state.rs +++ b/ethcore/src/executive_state.rs @@ -18,10 +18,12 @@ //! `account-state` crates and contains everything that requires `Machine` or `Executive` (or types //! thereof). -use machine::Machine; +use machine::{ + machine::Machine, + executive::{Executive, TransactOptions}, + executed::Executed, +}; use vm::EnvInfo; -use executive::{Executive, TransactOptions}; -use executed::Executed; use types::{ errors::{ExecutionError, EthcoreError as Error}, transaction::SignedTransaction, @@ -266,7 +268,10 @@ mod tests { use ethkey::Secret; use ethereum_types::{H256, U256, Address, BigEndianHash}; use test_helpers::{get_temp_state, get_temp_state_db}; - use machine::Machine; + use machine::{ + Machine, + test_helpers::new_frontier_test_machine, + }; use vm::EnvInfo; use spec::*; use types::transaction::*; @@ -282,7 +287,7 @@ mod tests { } fn make_frontier_machine(max_depth: usize) -> Machine { - let mut machine = ::ethereum::new_frontier_test_machine(); + let mut machine = new_frontier_test_machine(); machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth)); machine } diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs deleted file mode 100644 index 272e642bd97..00000000000 --- a/ethcore/src/externalities.rs +++ /dev/null @@ -1,652 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Transaction Execution environment. -use std::cmp; -use std::sync::Arc; -use ethereum_types::{H256, U256, Address, BigEndianHash}; -use bytes::Bytes; -use account_state::{Backend as StateBackend, State, CleanupMode}; -use substate::Substate; -use machine::Machine; -use executive::*; -use vm::{ - self, ActionParams, ActionValue, EnvInfo, CallType, Schedule, - Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, - ReturnData, TrapKind -}; -use types::transaction::UNSIGNED_SENDER; -use trace::{Tracer, VMTracer}; - -/// Policy for handling output data on `RETURN` opcode. -pub enum OutputPolicy { - /// Return reference to fixed sized output. - /// Used for message calls. - Return, - /// Init new contract as soon as `RETURN` is called. - InitContract, -} - -/// Transaction properties that externalities need to know about. -pub struct OriginInfo { - address: Address, - origin: Address, - gas_price: U256, - value: U256, -} - -impl OriginInfo { - /// Populates origin info from action params. - pub fn from(params: &ActionParams) -> Self { - OriginInfo { - address: params.address.clone(), - origin: params.origin.clone(), - gas_price: params.gas_price, - value: match params.value { - ActionValue::Transfer(val) | ActionValue::Apparent(val) => val - }, - } - } -} - -/// Implementation of evm Externalities. -pub struct Externalities<'a, T: 'a, V: 'a, B: 'a> { - state: &'a mut State, - env_info: &'a EnvInfo, - depth: usize, - stack_depth: usize, - origin_info: &'a OriginInfo, - substate: &'a mut Substate, - machine: &'a Machine, - schedule: &'a Schedule, - output: OutputPolicy, - tracer: &'a mut T, - vm_tracer: &'a mut V, - static_flag: bool, -} - -impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B> - where T: Tracer, V: VMTracer, B: StateBackend -{ - /// Basic `Externalities` constructor. - pub fn new( - state: &'a mut State, - env_info: &'a EnvInfo, - machine: &'a Machine, - schedule: &'a Schedule, - depth: usize, - stack_depth: usize, - origin_info: &'a OriginInfo, - substate: &'a mut Substate, - output: OutputPolicy, - tracer: &'a mut T, - vm_tracer: &'a mut V, - static_flag: bool, - ) -> Self { - Externalities { - state: state, - env_info: env_info, - depth: depth, - stack_depth: stack_depth, - origin_info: origin_info, - substate: substate, - machine: machine, - schedule: schedule, - output: output, - tracer: tracer, - vm_tracer: vm_tracer, - static_flag: static_flag, - } - } -} - -impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> - where T: Tracer, V: VMTracer, B: StateBackend -{ - fn initial_storage_at(&self, key: &H256) -> vm::Result { - if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? { - self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or_default()).map_err(Into::into) - } else { - warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address); - Ok(H256::zero()) - } - } - - fn storage_at(&self, key: &H256) -> vm::Result { - self.state.storage_at(&self.origin_info.address, key).map_err(Into::into) - } - - fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { - if self.static_flag { - Err(vm::Error::MutableCallInStaticContext) - } else { - self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into) - } - } - - fn is_static(&self) -> bool { - return self.static_flag - } - - fn exists(&self, address: &Address) -> vm::Result { - self.state.exists(address).map_err(Into::into) - } - - fn exists_and_not_null(&self, address: &Address) -> vm::Result { - self.state.exists_and_not_null(address).map_err(Into::into) - } - - fn origin_balance(&self) -> vm::Result { - self.balance(&self.origin_info.address).map_err(Into::into) - } - - fn balance(&self, address: &Address) -> vm::Result { - self.state.balance(address).map_err(Into::into) - } - - fn blockhash(&mut self, number: &U256) -> H256 { - if self.env_info.number + 256 >= self.machine.params().eip210_transition { - let blockhash_contract_address = self.machine.params().eip210_contract_address; - let code_res = self.state.code(&blockhash_contract_address) - .and_then(|code| self.state.code_hash(&blockhash_contract_address).map(|hash| (code, hash))) - .and_then(|(code, hash)| self.state.code_version(&blockhash_contract_address).map(|version| (code, hash, version))); - - let (code, code_hash, code_version) = match code_res { - Ok((code, hash, version)) => (code, hash, version), - Err(_) => return H256::zero(), - }; - let data: H256 = BigEndianHash::from_uint(number); - - let params = ActionParams { - sender: self.origin_info.address.clone(), - address: blockhash_contract_address.clone(), - value: ActionValue::Apparent(self.origin_info.value), - code_address: blockhash_contract_address.clone(), - origin: self.origin_info.origin.clone(), - gas: self.machine.params().eip210_contract_gas, - gas_price: 0.into(), - code: code, - code_hash: code_hash, - code_version: code_version, - data: Some(data.as_bytes().to_vec()), - call_type: CallType::Call, - params_type: vm::ParamsType::Separate, - }; - - let mut ex = Executive::new(self.state, self.env_info, self.machine, self.schedule); - let r = ex.call_with_crossbeam(params, self.substate, self.stack_depth + 1, self.tracer, self.vm_tracer); - let output = match &r { - Ok(ref r) => H256::from_slice(&r.return_data[..32]), - _ => H256::zero(), - }; - trace!("ext: blockhash contract({}) -> {:?}({}) self.env_info.number={}\n", number, r, output, self.env_info.number); - output - } else { - // TODO: comment out what this function expects from env_info, since it will produce panics if the latter is inconsistent - match *number < U256::from(self.env_info.number) && number.low_u64() >= cmp::max(256, self.env_info.number) - 256 { - true => { - let index = self.env_info.number - number.low_u64() - 1; - assert!(index < self.env_info.last_hashes.len() as u64, format!("Inconsistent env_info, should contain at least {:?} last hashes", index+1)); - let r = self.env_info.last_hashes[index as usize].clone(); - trace!("ext: blockhash({}) -> {} self.env_info.number={}\n", number, r, self.env_info.number); - r - }, - false => { - trace!("ext: blockhash({}) -> null self.env_info.number={}\n", number, self.env_info.number); - H256::zero() - }, - } - } - } - - fn create( - &mut self, - gas: &U256, - value: &U256, - code: &[u8], - parent_version: &U256, - address_scheme: CreateContractAddress, - trap: bool, - ) -> ::std::result::Result { - // create new contract address - let (address, code_hash) = match self.state.nonce(&self.origin_info.address) { - Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code), - Err(e) => { - debug!(target: "ext", "Database corruption encountered: {:?}", e); - return Ok(ContractCreateResult::Failed) - } - }; - - // prepare the params - let params = ActionParams { - code_address: address.clone(), - address: address.clone(), - sender: self.origin_info.address.clone(), - origin: self.origin_info.origin.clone(), - gas: *gas, - gas_price: self.origin_info.gas_price, - value: ActionValue::Transfer(*value), - code: Some(Arc::new(code.to_vec())), - code_hash: code_hash, - code_version: *parent_version, - data: None, - call_type: CallType::None, - params_type: vm::ParamsType::Embedded, - }; - - if !self.static_flag { - if !self.schedule.keep_unsigned_nonce || params.sender != UNSIGNED_SENDER { - if let Err(e) = self.state.inc_nonce(&self.origin_info.address) { - debug!(target: "ext", "Database corruption encountered: {:?}", e); - return Ok(ContractCreateResult::Failed) - } - } - } - - if trap { - return Err(TrapKind::Create(params, address)); - } - - // TODO: handle internal error separately - let mut ex = Executive::from_parent(self.state, self.env_info, self.machine, self.schedule, self.depth, self.static_flag); - let out = ex.create_with_crossbeam(params, self.substate, self.stack_depth + 1, self.tracer, self.vm_tracer); - Ok(into_contract_create_result(out, &address, self.substate)) - } - - fn call( - &mut self, - gas: &U256, - sender_address: &Address, - receive_address: &Address, - value: Option, - data: &[u8], - code_address: &Address, - call_type: CallType, - trap: bool, - ) -> ::std::result::Result { - trace!(target: "externalities", "call"); - - let code_res = self.state.code(code_address) - .and_then(|code| self.state.code_hash(code_address).map(|hash| (code, hash))) - .and_then(|(code, hash)| self.state.code_version(code_address).map(|version| (code, hash, version))); - - let (code, code_hash, code_version) = match code_res { - Ok((code, hash, version)) => (code, hash, version), - Err(_) => return Ok(MessageCallResult::Failed), - }; - - let mut params = ActionParams { - sender: sender_address.clone(), - address: receive_address.clone(), - value: ActionValue::Apparent(self.origin_info.value), - code_address: code_address.clone(), - origin: self.origin_info.origin.clone(), - gas: *gas, - gas_price: self.origin_info.gas_price, - code: code, - code_hash: code_hash, - code_version: code_version, - data: Some(data.to_vec()), - call_type: call_type, - params_type: vm::ParamsType::Separate, - }; - - if let Some(value) = value { - params.value = ActionValue::Transfer(value); - } - - if trap { - return Err(TrapKind::Call(params)); - } - - let mut ex = Executive::from_parent(self.state, self.env_info, self.machine, self.schedule, self.depth, self.static_flag); - let out = ex.call_with_crossbeam(params, self.substate, self.stack_depth + 1, self.tracer, self.vm_tracer); - Ok(into_message_call_result(out)) - } - - fn extcode(&self, address: &Address) -> vm::Result>> { - Ok(self.state.code(address)?) - } - - fn extcodehash(&self, address: &Address) -> vm::Result> { - if self.state.exists_and_not_null(address)? { - Ok(self.state.code_hash(address)?) - } else { - Ok(None) - } - } - - fn extcodesize(&self, address: &Address) -> vm::Result> { - Ok(self.state.code_size(address)?) - } - - fn ret(self, gas: &U256, data: &ReturnData, apply_state: bool) -> vm::Result - where Self: Sized { - match self.output { - OutputPolicy::Return => { - Ok(*gas) - }, - OutputPolicy::InitContract if apply_state => { - let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); - if return_cost > *gas || data.len() > self.schedule.create_data_limit { - return match self.schedule.exceptional_failed_code_deposit { - true => Err(vm::Error::OutOfGas), - false => Ok(*gas) - } - } - self.state.init_code(&self.origin_info.address, data.to_vec())?; - Ok(*gas - return_cost) - }, - OutputPolicy::InitContract => { - Ok(*gas) - }, - } - } - - fn log(&mut self, topics: Vec, data: &[u8]) -> vm::Result<()> { - use types::log_entry::LogEntry; - - if self.static_flag { - return Err(vm::Error::MutableCallInStaticContext); - } - - let address = self.origin_info.address.clone(); - self.substate.logs.push(LogEntry { - address: address, - topics: topics, - data: data.to_vec() - }); - - Ok(()) - } - - fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { - if self.static_flag { - return Err(vm::Error::MutableCallInStaticContext); - } - - let address = self.origin_info.address.clone(); - let balance = self.balance(&address)?; - if &address == refund_address { - // TODO [todr] To be consistent with CPP client we set balance to 0 in that case. - self.state.sub_balance(&address, &balance, &mut CleanupMode::NoEmpty)?; - } else { - trace!(target: "ext", "Suiciding {} -> {} (xfer: {})", address, refund_address, balance); - self.state.transfer_balance( - &address, - refund_address, - &balance, - cleanup_mode(&mut self.substate, &self.schedule) - )?; - } - - self.tracer.trace_suicide(address, balance, refund_address.clone()); - self.substate.suicides.insert(address); - - Ok(()) - } - - fn schedule(&self) -> &Schedule { - &self.schedule - } - - fn env_info(&self) -> &EnvInfo { - self.env_info - } - - fn depth(&self) -> usize { - self.depth - } - - fn add_sstore_refund(&mut self, value: usize) { - self.substate.sstore_clears_refund += value as i128; - } - - fn sub_sstore_refund(&mut self, value: usize) { - self.substate.sstore_clears_refund -= value as i128; - } - - fn trace_next_instruction(&mut self, pc: usize, instruction: u8, current_gas: U256) -> bool { - self.vm_tracer.trace_next_instruction(pc, instruction, current_gas) - } - - fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: U256, mem_written: Option<(usize, usize)>, store_written: Option<(U256, U256)>) { - self.vm_tracer.trace_prepare_execute(pc, instruction, gas_cost, mem_written, store_written) - } - - fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) { - self.vm_tracer.trace_executed(gas_used, stack_push, mem) - } -} - -#[cfg(test)] -mod tests { - use ethereum_types::{U256, Address}; - use evm::{EnvInfo, Ext, CallType}; - use account_state::State; - use substate::Substate; - use test_helpers::get_temp_state; - use super::*; - use trace::{NoopTracer, NoopVMTracer}; - use std::str::FromStr; - - fn get_test_origin() -> OriginInfo { - OriginInfo { - address: Address::zero(), - origin: Address::zero(), - gas_price: U256::zero(), - value: U256::zero() - } - } - - fn get_test_env_info() -> EnvInfo { - EnvInfo { - number: 100, - author: Address::from_low_u64_be(0), - timestamp: 0, - difficulty: 0.into(), - last_hashes: Arc::new(vec![]), - gas_used: 0.into(), - gas_limit: 0.into(), - } - } - - struct TestSetup { - state: State<::state_db::StateDB>, - machine: ::machine::Machine, - schedule: Schedule, - sub_state: Substate, - env_info: EnvInfo - } - - impl Default for TestSetup { - fn default() -> Self { - TestSetup::new() - } - } - - impl TestSetup { - fn new() -> Self { - let machine = ::spec::Spec::new_test_machine(); - let env_info = get_test_env_info(); - let schedule = machine.schedule(env_info.number); - TestSetup { - state: get_temp_state(), - schedule: schedule, - machine: machine, - sub_state: Substate::new(), - env_info: env_info, - } - } - } - - #[test] - fn can_be_created() { - let mut setup = TestSetup::new(); - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - let ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - - assert_eq!(ext.env_info().number, 100); - } - - #[test] - fn can_return_block_hash_no_env() { - let mut setup = TestSetup::new(); - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - - let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); - - assert_eq!(hash, H256::zero()); - } - - #[test] - fn can_return_block_hash() { - let test_hash = H256::from_str("afafafafafafafafafafafbcbcbcbcbcbcbcbcbcbeeeeeeeeeeeeedddddddddd").unwrap(); - let test_env_number = 0x120001; - - let mut setup = TestSetup::new(); - { - let env_info = &mut setup.env_info; - env_info.number = test_env_number; - let mut last_hashes = (*env_info.last_hashes).clone(); - last_hashes.push(test_hash.clone()); - env_info.last_hashes = Arc::new(last_hashes); - } - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - - let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); - - assert_eq!(test_hash, hash); - } - - #[test] - #[should_panic] - fn can_call_fail_empty() { - let mut setup = TestSetup::new(); - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - - // this should panic because we have no balance on any account - ext.call( - &"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap(), - &Address::zero(), - &Address::zero(), - Some("0000000000000000000000000000000000000000000000000000000000150000".parse::().unwrap()), - &[], - &Address::zero(), - CallType::Call, - false, - ).ok().unwrap(); - } - - #[test] - fn can_log() { - let log_data = vec![120u8, 110u8]; - let log_topics = vec![H256::from_str("af0fa234a6af46afa23faf23bcbc1c1cb4bcb7bcbe7e7e7ee3ee2edddddddddd").unwrap()]; - - let mut setup = TestSetup::new(); - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - { - let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - ext.log(log_topics, &log_data).unwrap(); - } - - assert_eq!(setup.sub_state.logs.len(), 1); - } - - #[test] - fn can_suicide() { - let refund_account = &Address::zero(); - - let mut setup = TestSetup::new(); - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - { - let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - ext.suicide(refund_account).unwrap(); - } - - assert_eq!(setup.sub_state.suicides.len(), 1); - } - - #[test] - fn can_create() { - use std::str::FromStr; - - let mut setup = TestSetup::new(); - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - let address = { - let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - match ext.create(&U256::max_value(), &U256::zero(), &[], &U256::zero(), CreateContractAddress::FromSenderAndNonce, false) { - Ok(ContractCreateResult::Created(address, _)) => address, - _ => panic!("Test create failed; expected Created, got Failed/Reverted."), - } - }; - - assert_eq!(address, Address::from_str("bd770416a3345f91e4b34576cb804a576fa48eb1").unwrap()); - } - - #[test] - fn can_create2() { - use std::str::FromStr; - - let mut setup = TestSetup::new(); - let state = &mut setup.state; - let mut tracer = NoopTracer; - let mut vm_tracer = NoopVMTracer; - let origin_info = get_test_origin(); - - let address = { - let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, &setup.schedule, 0, 0, &origin_info, &mut setup.sub_state, OutputPolicy::InitContract, &mut tracer, &mut vm_tracer, false); - - match ext.create(&U256::max_value(), &U256::zero(), &[], &U256::zero(), CreateContractAddress::FromSenderSaltAndCodeHash(H256::zero()), false) { - Ok(ContractCreateResult::Created(address, _)) => address, - _ => panic!("Test create failed; expected Created, got Failed/Reverted."), - } - }; - - assert_eq!(address, Address::from_str("e33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0").unwrap()); - } -} diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 22a38f38797..9a0f3a2a1ae 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -18,24 +18,26 @@ use std::path::Path; use std::sync::Arc; use super::test_common::*; use account_state::{Backend as StateBackend, State}; -use substate::Substate; -use executive::*; use evm::{VMType, Finalize}; use vm::{ self, ActionParams, CallType, Schedule, Ext, ContractCreateResult, EnvInfo, MessageCallResult, CreateContractAddress, ReturnData, }; -use externalities::*; +use machine::{ + Machine, + externalities::{OutputPolicy, OriginInfo, Externalities}, + substate::Substate, + executive::*, // todo[dvdplm] make explicit +}; + use test_helpers::get_temp_state; use ethjson; -use trace::{Tracer, NoopTracer}; -use trace::{VMTracer, NoopVMTracer}; +use trace::{Tracer, NoopTracer, VMTracer, NoopVMTracer}; use bytes::Bytes; use ethtrie; use rlp::RlpStream; use hash::keccak; -use machine::Machine; use ethereum_types::BigEndianHash; use super::HookType; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index e7aa7385647..95c827d8184 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -56,6 +56,7 @@ extern crate account_db; extern crate account_state; extern crate ansi_term; +extern crate client_traits; extern crate common_types as types; extern crate crossbeam_utils; extern crate ethabi; @@ -83,6 +84,7 @@ extern crate kvdb_memorydb; extern crate len_caching_lock; extern crate lru_cache; +extern crate machine; extern crate memory_cache; extern crate num_cpus; extern crate parity_bytes as bytes; @@ -152,19 +154,19 @@ pub mod block; pub mod client; pub mod engines; pub mod ethereum; -pub mod executed; -pub mod executive; +//pub mod executed; +//pub mod executive; pub mod executive_state; -pub mod machine; +//pub mod machine; pub mod miner; pub mod snapshot; pub mod spec; pub mod verification; -mod externalities; -mod substate; -mod transaction_ext; -mod tx_filter; +//mod externalities; +//mod substate; +//mod transaction_ext; +//mod tx_filter; #[cfg(test)] mod tests; @@ -173,6 +175,6 @@ pub mod json_tests; #[cfg(any(test, feature = "test-helpers"))] pub mod test_helpers; -pub use executive::contract_address; +//pub use executive::contract_address; pub use evm::CreateContractAddress; pub use trie::TrieSpec; diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs deleted file mode 100644 index 1e7acb649c6..00000000000 --- a/ethcore/src/machine.rs +++ /dev/null @@ -1,485 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Ethereum-like state machine definition. - -use std::collections::BTreeMap; -use std::cmp; -use std::sync::Arc; - -use ethereum_types::{U256, H256, Address}; -use rlp::Rlp; -use types::{ - BlockNumber, - header::Header, - engines::{ - EthashExtensions, - params::CommonParams, - }, - errors::{EngineError, EthcoreError as Error}, - transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction}, -}; -use vm::{CallType, ActionParams, ActionValue, ParamsType}; -use vm::{EnvInfo, Schedule}; - -use block::ExecutedBlock; -use builtin::Builtin; -use call_contract::CallContract; -use client::BlockInfo; -use executive::Executive; -use account_state::CleanupMode; -use substate::Substate; -use trace::{NoopTracer, NoopVMTracer}; -use tx_filter::TransactionFilter; - -/// Parity tries to round block.gas_limit to multiple of this constant -pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); - -/// Special rules to be applied to the schedule. -pub type ScheduleCreationRules = dyn Fn(&mut Schedule, BlockNumber) + Sync + Send; - -/// An ethereum-like state machine. -pub struct Machine { - params: CommonParams, - builtins: Arc>, - tx_filter: Option>, - ethash_extensions: Option, - schedule_rules: Option>, -} - -impl Machine { - /// Regular ethereum machine. - pub fn regular(params: CommonParams, builtins: BTreeMap) -> Machine { - let tx_filter = TransactionFilter::from_params(¶ms).map(Arc::new); - Machine { - params, - builtins: Arc::new(builtins), - tx_filter, - ethash_extensions: None, - schedule_rules: None, - } - } - - /// Ethereum machine with ethash extensions. - // TODO: either unify or specify to mainnet specifically and include other specific-chain HFs? - pub fn with_ethash_extensions(params: CommonParams, builtins: BTreeMap, extensions: EthashExtensions) -> Machine { - let mut machine = Machine::regular(params, builtins); - machine.ethash_extensions = Some(extensions); - machine - } - - /// Attach special rules to the creation of schedule. - pub fn set_schedule_creation_rules(&mut self, rules: Box) { - self.schedule_rules = Some(rules); - } - - /// Get a reference to the ethash-specific extensions. - pub fn ethash_extensions(&self) -> Option<&EthashExtensions> { - self.ethash_extensions.as_ref() - } - - /// Execute a call as the system address. Block environment information passed to the - /// VM is modified to have its gas limit bounded at the upper limit of possible used - /// gases including this system call, capped at the maximum value able to be - /// represented by U256. This system call modifies the block state, but discards other - /// information. If suicides, logs or refunds happen within the system call, they - /// will not be executed or recorded. Gas used by this system call will not be counted - /// on the block. - pub fn execute_as_system( - &self, - block: &mut ExecutedBlock, - contract_address: Address, - gas: U256, - data: Option>, - ) -> Result, Error> { - let (code, code_hash) = { - let state = &block.state; - - (state.code(&contract_address)?, - state.code_hash(&contract_address)?) - }; - - self.execute_code_as_system( - block, - Some(contract_address), - code, - code_hash, - None, - gas, - data, - None, - ) - } - - /// Same as execute_as_system, but execute code directly. If contract address is None, use the null sender - /// address. If code is None, then this function has no effect. The call is executed without finalization, and does - /// not form a transaction. - pub fn execute_code_as_system( - &self, - block: &mut ExecutedBlock, - contract_address: Option
, - code: Option>>, - code_hash: Option, - value: Option, - gas: U256, - data: Option>, - call_type: Option, - ) -> Result, Error> { - let env_info = { - let mut env_info = block.env_info(); - env_info.gas_limit = env_info.gas_used.saturating_add(gas); - env_info - }; - - let mut state = block.state_mut(); - - let params = ActionParams { - code_address: contract_address.unwrap_or(UNSIGNED_SENDER), - address: contract_address.unwrap_or(UNSIGNED_SENDER), - sender: SYSTEM_ADDRESS, - origin: SYSTEM_ADDRESS, - gas, - gas_price: 0.into(), - value: value.unwrap_or_else(|| ActionValue::Transfer(0.into())), - code, - code_hash, - code_version: 0.into(), - data, - call_type: call_type.unwrap_or(CallType::Call), - params_type: ParamsType::Separate, - }; - let schedule = self.schedule(env_info.number); - let mut ex = Executive::new(&mut state, &env_info, self, &schedule); - let mut substate = Substate::new(); - - let res = ex.call(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer).map_err(|e| EngineError::FailedSystemCall(format!("{}", e)))?; - let output = res.return_data.to_vec(); - - Ok(output) - } - - /// Push last known block hash to the state. - fn push_last_hash(&self, block: &mut ExecutedBlock) -> Result<(), Error> { - let params = self.params(); - if block.header.number() == params.eip210_transition { - let state = block.state_mut(); - state.init_code(¶ms.eip210_contract_address, params.eip210_contract_code.clone())?; - } - if block.header.number() >= params.eip210_transition { - let parent_hash = *block.header.parent_hash(); - let _ = self.execute_as_system( - block, - params.eip210_contract_address, - params.eip210_contract_gas, - Some(parent_hash.as_bytes().to_vec()), - )?; - } - Ok(()) - } - - /// Logic to perform on a new block: updating last hashes and the DAO - /// fork, for ethash. - pub fn on_new_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { - self.push_last_hash(block)?; - - if let Some(ref ethash_params) = self.ethash_extensions { - if block.header.number() == ethash_params.dao_hardfork_transition { - let state = block.state_mut(); - for child in ðash_params.dao_hardfork_accounts { - let beneficiary = ðash_params.dao_hardfork_beneficiary; - state.balance(child) - .and_then(|b| state.transfer_balance(child, beneficiary, &b, CleanupMode::NoEmpty))?; - } - } - } - - Ok(()) - } - - /// Populate a header's fields based on its parent's header. - /// Usually implements the chain scoring rule based on weight. - /// The gas floor target must not be lower than the engine's minimum gas limit. - pub fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, gas_ceil_target: U256) { - header.set_difficulty(parent.difficulty().clone()); - let gas_limit = parent.gas_limit().clone(); - assert!(!gas_limit.is_zero(), "Gas limit should be > 0"); - - if let Some(ref ethash_params) = self.ethash_extensions { - let gas_limit = { - let bound_divisor = self.params().gas_limit_bound_divisor; - let lower_limit = gas_limit - gas_limit / bound_divisor + 1; - let upper_limit = gas_limit + gas_limit / bound_divisor - 1; - let gas_limit = if gas_limit < gas_floor_target { - let gas_limit = cmp::min(gas_floor_target, upper_limit); - round_block_gas_limit(gas_limit, lower_limit, upper_limit) - } else if gas_limit > gas_ceil_target { - let gas_limit = cmp::max(gas_ceil_target, lower_limit); - round_block_gas_limit(gas_limit, lower_limit, upper_limit) - } else { - let total_lower_limit = cmp::max(lower_limit, gas_floor_target); - let total_upper_limit = cmp::min(upper_limit, gas_ceil_target); - let gas_limit = cmp::max(gas_floor_target, cmp::min(total_upper_limit, - lower_limit + (header.gas_used().clone() * 6u32 / 5) / bound_divisor)); - round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit) - }; - // ensure that we are not violating protocol limits - debug_assert!(gas_limit >= lower_limit); - debug_assert!(gas_limit <= upper_limit); - gas_limit - }; - - header.set_gas_limit(gas_limit); - if header.number() >= ethash_params.dao_hardfork_transition && - header.number() <= ethash_params.dao_hardfork_transition + 9 { - header.set_extra_data(b"dao-hard-fork"[..].to_owned()); - } - return - } - - header.set_gas_limit({ - let bound_divisor = self.params().gas_limit_bound_divisor; - if gas_limit < gas_floor_target { - cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1) - } else { - cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1) - } - }); - } - - /// Get the general parameters of the chain. - pub fn params(&self) -> &CommonParams { - &self.params - } - - /// Get the EVM schedule for the given block number. - pub fn schedule(&self, block_number: BlockNumber) -> Schedule { - let mut schedule = match self.ethash_extensions { - None => self.params.schedule(block_number), - Some(ref ext) => { - if block_number < ext.homestead_transition { - Schedule::new_frontier() - } else { - self.params.schedule(block_number) - } - } - }; - - if let Some(ref rules) = self.schedule_rules { - (rules)(&mut schedule, block_number) - } - - schedule - } - - /// Builtin-contracts for the chain.. - pub fn builtins(&self) -> &BTreeMap { - &*self.builtins - } - - /// Attempt to get a handle to a built-in contract. - /// Only returns references to activated built-ins. - // TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic - // from Spec into here and removing the Spec::builtins field. - pub fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> { - self.builtins() - .get(a) - .and_then(|b| if b.is_active(block_number) { Some(b) } else { None }) - } - - /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. - pub fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size } - - /// The nonce with which accounts begin at given block. - pub fn account_start_nonce(&self, block: u64) -> U256 { - let params = self.params(); - - if block >= params.dust_protection_transition { - U256::from(params.nonce_cap_increment) * U256::from(block) - } else { - params.account_start_nonce - } - } - - /// The network ID that transactions should be signed with. - pub fn signing_chain_id(&self, env_info: &EnvInfo) -> Option { - let params = self.params(); - - if env_info.number >= params.eip155_transition { - Some(params.chain_id) - } else { - None - } - } - - /// Does basic verification of the transaction. - pub fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> { - let check_low_s = match self.ethash_extensions { - Some(ref ext) => header.number() >= ext.homestead_transition, - None => true, - }; - - let chain_id = if header.number() < self.params().validate_chain_id_transition { - t.chain_id() - } else if header.number() >= self.params().eip155_transition { - Some(self.params().chain_id) - } else { - None - }; - t.verify_basic(check_low_s, chain_id, false)?; - - Ok(()) - } - - /// Does verification of the transaction against the parent state. - pub fn verify_transaction( - &self, - t: &SignedTransaction, - parent: &Header, - client: &C - ) -> Result<(), transaction::Error> { - if let Some(ref filter) = self.tx_filter.as_ref() { - if !filter.transaction_allowed(&parent.hash(), parent.number() + 1, t, client) { - return Err(transaction::Error::NotAllowed.into()) - } - } - - Ok(()) - } - - /// Performs pre-validation of RLP decoded transaction before other processing - pub fn decode_transaction(&self, transaction: &[u8]) -> Result { - let rlp = Rlp::new(&transaction); - if rlp.as_raw().len() > self.params().max_transaction_size { - debug!("Rejected oversized transaction of {} bytes", rlp.as_raw().len()); - return Err(transaction::Error::TooBig) - } - rlp.as_val().map_err(|e| transaction::Error::InvalidRlp(e.to_string())) - } - - /// Get the balance, in base units, associated with an account. - /// Extracts data from the live block. - pub fn balance(&self, live: &ExecutedBlock, address: &Address) -> Result { - live.state.balance(address).map_err(Into::into) - } - - /// Increment the balance of an account in the state of the live block. - pub fn add_balance(&self, live: &mut ExecutedBlock, address: &Address, amount: &U256) -> Result<(), Error> { - live.state_mut().add_balance(address, amount, CleanupMode::NoEmpty).map_err(Into::into) - } -} - -// Try to round gas_limit a bit so that: -// 1) it will still be in desired range -// 2) it will be a nearest (with tendency to increase) multiple of PARITY_GAS_LIMIT_DETERMINANT -fn round_block_gas_limit(gas_limit: U256, lower_limit: U256, upper_limit: U256) -> U256 { - let increased_gas_limit = gas_limit + (PARITY_GAS_LIMIT_DETERMINANT - gas_limit % PARITY_GAS_LIMIT_DETERMINANT); - if increased_gas_limit > upper_limit { - let decreased_gas_limit = increased_gas_limit - PARITY_GAS_LIMIT_DETERMINANT; - if decreased_gas_limit < lower_limit { - gas_limit - } else { - decreased_gas_limit - } - } else { - increased_gas_limit - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::str::FromStr; - - fn get_default_ethash_extensions() -> EthashExtensions { - EthashExtensions { - homestead_transition: 1150000, - dao_hardfork_transition: u64::max_value(), - dao_hardfork_beneficiary: Address::from_str("0000000000000000000000000000000000000001").unwrap(), - dao_hardfork_accounts: Vec::new(), - } - } - - #[test] - fn should_disallow_unsigned_transactions() { - let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080"; - let transaction: UnverifiedTransaction = ::rlp::decode(&::rustc_hex::FromHex::from_hex(rlp).unwrap()).unwrap(); - let spec = ::ethereum::new_ropsten_test(); - let ethparams = get_default_ethash_extensions(); - - let machine = Machine::with_ethash_extensions( - spec.params().clone(), - Default::default(), - ethparams, - ); - let mut header = ::types::header::Header::new(); - header.set_number(15); - - let res = machine.verify_transaction_basic(&transaction, &header); - assert_eq!(res, Err(transaction::Error::InvalidSignature("Crypto error (Invalid EC signature)".into()))); - } - - #[test] - fn ethash_gas_limit_is_multiple_of_determinant() { - use ethereum_types::U256; - - let spec = ::ethereum::new_homestead_test(); - let ethparams = get_default_ethash_extensions(); - - let machine = Machine::with_ethash_extensions( - spec.params().clone(), - Default::default(), - ethparams, - ); - - let mut parent = ::types::header::Header::new(); - let mut header = ::types::header::Header::new(); - header.set_number(1); - - // this test will work for this constant only - assert_eq!(PARITY_GAS_LIMIT_DETERMINANT, U256::from(37)); - - // when parent.gas_limit < gas_floor_target: - parent.set_gas_limit(U256::from(50_000)); - machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000)); - assert_eq!(*header.gas_limit(), U256::from(50_024)); - - // when parent.gas_limit > gas_ceil_target: - parent.set_gas_limit(U256::from(250_000)); - machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000)); - assert_eq!(*header.gas_limit(), U256::from(249_787)); - - // when parent.gas_limit is in miner's range - header.set_gas_used(U256::from(150_000)); - parent.set_gas_limit(U256::from(150_000)); - machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000)); - assert_eq!(*header.gas_limit(), U256::from(150_035)); - - // when parent.gas_limit is in miner's range - // && we can NOT increase it to be multiple of constant - header.set_gas_used(U256::from(150_000)); - parent.set_gas_limit(U256::from(150_000)); - machine.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(150_002)); - assert_eq!(*header.gas_limit(), U256::from(149_998)); - - // when parent.gas_limit is in miner's range - // && we can NOT increase it to be multiple of constant - // && we can NOT decrease it to be multiple of constant - header.set_gas_used(U256::from(150_000)); - parent.set_gas_limit(U256::from(150_000)); - machine.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002)); - assert_eq!(*header.gas_limit(), U256::from(150_002)); - } -} diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index ad6ecaae8c2..04a3ce4a2c3 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -47,6 +47,7 @@ use types::{ BlockNumber, block::Block, header::Header, + ids::BlockId, engines::{SealingState}, errors::{EthcoreError as Error, ExecutionError}, receipt::RichReceipt, @@ -57,9 +58,8 @@ use block::{ClosedBlock, SealedBlock}; use client::{ BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId, ClientIoMessage, }; -use client::BlockId; use engines::{Engine, Seal, EngineSigner}; -use executive::contract_address; +use machine::executive::contract_address; use spec::Spec; use account_state::State; use vm::CreateContractAddress; diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index c87e307f024..669076c1849 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -32,15 +32,18 @@ use types::transaction::{ UnverifiedTransaction, SignedTransaction, }; -use types::header::Header; +use types::{ + header::Header, + ids::TransactionId, +}; use parking_lot::RwLock; use call_contract::CallContract; -use client::{TransactionId, Nonce}; -use client::BlockInfo; +use client::Nonce; +use client_traits::BlockInfo; use engines::Engine; +use machine::transaction_ext::Transaction; use miner; -use transaction_ext::Transaction; /// Cache for state nonces. #[derive(Debug, Clone)] diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index d3e2f1ce76c..684f1ea1eb9 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -28,7 +28,8 @@ use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, Snapshot use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter}; use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler}; -use client::{BlockChainClient, Client, ChainInfo, BlockInfo, ClientIoMessage}; +use client::{BlockChainClient, Client, ChainInfo, ClientIoMessage}; +use client_traits::BlockInfo; use engines::Engine; use hash::keccak; use types::{ diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 08e716d269a..dd1e905dbb8 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -22,7 +22,7 @@ use std::sync::Arc; use tempdir::TempDir; use blockchain::BlockProvider; use client::{Client, ClientConfig, ImportBlock}; -use client::BlockInfo; +use client_traits::BlockInfo; use types::ids::BlockId; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use snapshot::service::{Service, ServiceParams}; diff --git a/ethcore/src/snapshot/watcher.rs b/ethcore/src/snapshot/watcher.rs index 06df0c9cc42..4fc9d881f63 100644 --- a/ethcore/src/snapshot/watcher.rs +++ b/ethcore/src/snapshot/watcher.rs @@ -17,7 +17,8 @@ //! Watcher for snapshot-related chain events. use parking_lot::Mutex; -use client::{BlockInfo, Client, ChainNotify, NewBlocks, ClientIoMessage}; +use client::{Client, ChainNotify, NewBlocks, ClientIoMessage}; +use client_traits::BlockInfo; use types::ids::BlockId; use io::IoChannel; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 1d732f8f03f..ec5df98b149 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -43,14 +43,16 @@ use engines::{ Engine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority, Clique, AuthorityRound, Ethash, }; -use executive::Executive; +use machine::{ + executive::Executive, + machine::Machine, + substate::Substate, +}; use trie_vm_factories::Factories; -use machine::Machine; use pod::PodState; use spec::Genesis; use spec::seal::Generic as GenericSeal; use account_state::{Backend, State, backend::Basic as BasicBackend}; -use substate::Substate; use trace::{NoopTracer, NoopVMTracer}; pub use ethash::OptimizeFor; @@ -102,7 +104,7 @@ impl<'a, T: AsRef> From<&'a T> for SpecParams<'a> { fn run_constructors( genesis_state: &PodState, constructors: &[(Address, Bytes)], - engine: &Engine, + engine: &dyn Engine, author: Address, timestamp: u64, difficulty: U256, diff --git a/ethcore/src/substate.rs b/ethcore/src/substate.rs deleted file mode 100644 index 967e4bc7736..00000000000 --- a/ethcore/src/substate.rs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Execution environment substate. -use std::collections::HashSet; -use ethereum_types::Address; -use types::log_entry::LogEntry; - -/// State changes which should be applied in finalize, -/// after transaction is fully executed. -#[derive(Debug, Default)] -pub struct Substate { - /// Any accounts that have suicided. - pub suicides: HashSet
, - - /// Any accounts that are touched. - pub touched: HashSet
, - - /// Any logs. - pub logs: Vec, - - /// Refund counter of SSTORE. - pub sstore_clears_refund: i128, - - /// Created contracts. - pub contracts_created: Vec
, -} - -impl Substate { - /// Creates new substate. - pub fn new() -> Self { - Substate::default() - } - - /// Merge secondary substate `s` into self, accruing each element correspondingly. - pub fn accrue(&mut self, s: Substate) { - self.suicides.extend(s.suicides); - self.touched.extend(s.touched); - self.logs.extend(s.logs); - self.sstore_clears_refund += s.sstore_clears_refund; - self.contracts_created.extend(s.contracts_created); - } -} - -#[cfg(test)] -mod tests { - use ethereum_types::Address; - use types::log_entry::LogEntry; - use super::Substate; - - #[test] - fn created() { - let sub_state = Substate::new(); - assert_eq!(sub_state.suicides.len(), 0); - } - - #[test] - fn accrue() { - let mut sub_state = Substate::new(); - sub_state.contracts_created.push(Address::from_low_u64_be(1)); - sub_state.logs.push(LogEntry { - address: Address::from_low_u64_be(1), - topics: vec![], - data: vec![] - }); - sub_state.sstore_clears_refund = (15000 * 5).into(); - sub_state.suicides.insert(Address::from_low_u64_be(10)); - - let mut sub_state_2 = Substate::new(); - sub_state_2.contracts_created.push(Address::from_low_u64_be(2u64)); - sub_state_2.logs.push(LogEntry { - address: Address::from_low_u64_be(1), - topics: vec![], - data: vec![] - }); - sub_state_2.sstore_clears_refund = (15000 * 7).into(); - - sub_state.accrue(sub_state_2); - assert_eq!(sub_state.contracts_created.len(), 2); - assert_eq!(sub_state.sstore_clears_refund, (15000 * 12).into()); - assert_eq!(sub_state.suicides.len(), 1); - } -} diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index b319a85a13a..95f42897539 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -28,9 +28,9 @@ use types::view; use types::views::BlockView; use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, BlockId, ChainInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; -use client::BlockInfo; +use client_traits::BlockInfo; use ethereum; -use executive::{Executive, TransactOptions}; +use machine::executive::{Executive, TransactOptions}; use miner::{Miner, PendingOrdering, MinerService}; use spec::Spec; use account_state::{State, CleanupMode, backend}; diff --git a/ethcore/src/tests/evm.rs b/ethcore/src/tests/evm.rs index d0b9c821db2..184fa5801e9 100644 --- a/ethcore/src/tests/evm.rs +++ b/ethcore/src/tests/evm.rs @@ -20,8 +20,11 @@ use std::sync::Arc; use hash::keccak; use vm::{EnvInfo, ActionParams, ActionValue, CallType, ParamsType}; use evm::{Factory, VMType}; -use executive::Executive; -use substate::Substate; +use machine::{ + executive::Executive, + substate::Substate, + test_helpers::new_eip210_test_machine, +}; use test_helpers::get_temp_state_with_factory; use trace::{NoopVMTracer, NoopTracer}; use types::transaction::SYSTEM_ADDRESS; @@ -38,7 +41,7 @@ fn test_blockhash_eip210(factory: Factory) { let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b"; let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap()); let blockhash_contract_code_hash = keccak(blockhash_contract_code.as_ref()); - let machine = ::ethereum::new_eip210_test_machine(); + let machine = new_eip210_test_machine(); let mut env_info = EnvInfo::default(); // populate state with 256 last hashes diff --git a/ethcore/src/transaction_ext.rs b/ethcore/src/transaction_ext.rs deleted file mode 100644 index fefcd91a341..00000000000 --- a/ethcore/src/transaction_ext.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Ethereum transaction - -use evm::Schedule; -use types::transaction::{self, Action}; - -/// Extends transaction with gas verification method. -pub trait Transaction { - /// Get the transaction cost in gas for this transaction. - fn gas_required(&self, schedule: &Schedule) -> u64; -} - -impl Transaction for transaction::Transaction { - fn gas_required(&self, schedule: &Schedule) -> u64 { - gas_required_for(match self.action { - Action::Create => true, - Action::Call(_) => false - }, &self.data, schedule) - } -} - -/// Get the transaction cost in gas for the given params. -fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule) -> u64 { - data.iter().fold( - (if is_create {schedule.tx_create_gas} else {schedule.tx_gas}) as u64, - |g, b| g + (match *b { 0 => schedule.tx_data_zero_gas, _ => schedule.tx_data_non_zero_gas }) as u64 - ) -} diff --git a/ethcore/src/tx_filter.rs b/ethcore/src/tx_filter.rs deleted file mode 100644 index bbb6ce139f1..00000000000 --- a/ethcore/src/tx_filter.rs +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Smart contract based transaction filter. - -use ethereum_types::{H256, U256, Address}; -use lru_cache::LruCache; -use ethabi::FunctionOutputDecoder; - -use call_contract::CallContract; -use client::{BlockId, BlockInfo}; -use parking_lot::Mutex; -use types::{ - BlockNumber, - engines::params::CommonParams, - transaction::{Action, SignedTransaction} -}; -use hash::KECCAK_EMPTY; - -use_contract!(transact_acl_deprecated, "res/contracts/tx_acl_deprecated.json"); -use_contract!(transact_acl, "res/contracts/tx_acl.json"); - -const MAX_CACHE_SIZE: usize = 4096; - -mod tx_permissions { - pub const _ALL: u32 = 0xffffffff; - pub const NONE: u32 = 0x0; - pub const BASIC: u32 = 0b00000001; - pub const CALL: u32 = 0b00000010; - pub const CREATE: u32 = 0b00000100; - pub const _PRIVATE: u32 = 0b00001000; -} - -/// Connection filter that uses a contract to manage permissions. -pub struct TransactionFilter { - contract_address: Address, - transition_block: BlockNumber, - permission_cache: Mutex>, - contract_version_cache: Mutex>> -} - -impl TransactionFilter { - /// Create a new instance if address is specified in params. - pub fn from_params(params: &CommonParams) -> Option { - params.transaction_permission_contract.map(|address| - TransactionFilter { - contract_address: address, - transition_block: params.transaction_permission_contract_transition, - permission_cache: Mutex::new(LruCache::new(MAX_CACHE_SIZE)), - contract_version_cache: Mutex::new(LruCache::new(MAX_CACHE_SIZE)), - } - ) - } - - /// Check if transaction is allowed at given block. - pub fn transaction_allowed(&self, parent_hash: &H256, block_number: BlockNumber, transaction: &SignedTransaction, client: &C) -> bool { - if block_number < self.transition_block { return true; } - - let mut permission_cache = self.permission_cache.lock(); - let mut contract_version_cache = self.contract_version_cache.lock(); - - let (tx_type, to) = match transaction.action { - Action::Create => (tx_permissions::CREATE, Address::zero()), - Action::Call(address) => if client.code_hash(&address, BlockId::Hash(*parent_hash)).map_or(false, |c| c != KECCAK_EMPTY) { - (tx_permissions::CALL, address) - } else { - (tx_permissions::BASIC, address) - } - }; - - let sender = transaction.sender(); - let value = transaction.value; - let key = (*parent_hash, sender); - - if let Some(permissions) = permission_cache.get_mut(&key) { - return *permissions & tx_type != 0; - } - - let contract_address = self.contract_address; - let contract_version = contract_version_cache.get_mut(parent_hash).and_then(|v| *v).or_else(|| { - let (data, decoder) = transact_acl::functions::contract_version::call(); - decoder.decode(&client.call_contract(BlockId::Hash(*parent_hash), contract_address, data).ok()?).ok() - }); - contract_version_cache.insert(*parent_hash, contract_version); - - // Check permissions in smart contract based on its version - let (permissions, filter_only_sender) = match contract_version { - Some(version) => { - let version_u64 = version.low_u64(); - trace!(target: "tx_filter", "Version of tx permission contract: {}", version); - match version_u64 { - 2 => { - let (data, decoder) = transact_acl::functions::allowed_tx_types::call(sender, to, value); - client.call_contract(BlockId::Hash(*parent_hash), contract_address, data) - .and_then(|value| decoder.decode(&value).map_err(|e| e.to_string())) - .map(|(p, f)| (p.low_u32(), f)) - .unwrap_or_else(|e| { - error!(target: "tx_filter", "Error calling tx permissions contract: {:?}", e); - (tx_permissions::NONE, true) - }) - }, - _ => { - error!(target: "tx_filter", "Unknown version of tx permissions contract is used"); - (tx_permissions::NONE, true) - } - } - }, - None => { - trace!(target: "tx_filter", "Fallback to the deprecated version of tx permission contract"); - let (data, decoder) = transact_acl_deprecated::functions::allowed_tx_types::call(sender); - (client.call_contract(BlockId::Hash(*parent_hash), contract_address, data) - .and_then(|value| decoder.decode(&value).map_err(|e| e.to_string())) - .map(|p| p.low_u32()) - .unwrap_or_else(|e| { - error!(target: "tx_filter", "Error calling tx permissions contract: {:?}", e); - tx_permissions::NONE - }), true) - } - }; - - if filter_only_sender { - permission_cache.insert((*parent_hash, sender), permissions); - } - trace!(target: "tx_filter", - "Given transaction data: sender: {:?} to: {:?} value: {}. Permissions required: {:X}, got: {:X}", - sender, to, value, tx_type, permissions - ); - permissions & tx_type != 0 - } -} - -#[cfg(test)] -mod test { - use std::sync::Arc; - use std::str::FromStr; - use spec::Spec; - use client::{BlockChainClient, Client, ClientConfig, BlockId}; - use miner::Miner; - use ethereum_types::{U256, Address}; - use io::IoChannel; - use ethkey::{Secret, KeyPair}; - use super::TransactionFilter; - use types::transaction::{Transaction, Action}; - use tempdir::TempDir; - use test_helpers; - - /// Contract code: https://gist.github.com/VladLupashevskyi/84f18eabb1e4afadf572cf92af3e7e7f - #[test] - fn transaction_filter() { - let spec_data = include_str!("../res/tx_permission_tests/contract_ver_2_genesis.json"); - - let db = test_helpers::new_db(); - let tempdir = TempDir::new("").unwrap(); - let spec = Spec::load(&tempdir.path(), spec_data.as_bytes()).unwrap(); - - let client = Client::new( - ClientConfig::default(), - &spec, - db, - Arc::new(Miner::new_for_tests(&spec, None)), - IoChannel::disconnected(), - ).unwrap(); - let key1 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000001")).unwrap(); - let key2 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000002")).unwrap(); - let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000003")).unwrap(); - let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000004")).unwrap(); - let key5 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000005")).unwrap(); - let key6 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000006")).unwrap(); - let key7 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000007")).unwrap(); - - let filter = TransactionFilter::from_params(spec.params()).unwrap(); - let mut basic_tx = Transaction::default(); - basic_tx.action = Action::Call(Address::from_str("d41c057fd1c78805aac12b0a94a405c0461a6fbb").unwrap()); - let create_tx = Transaction::default(); - let mut call_tx = Transaction::default(); - call_tx.action = Action::Call(Address::from_str("0000000000000000000000000000000000000005").unwrap()); - - let mut basic_tx_with_ether_and_to_key7 = Transaction::default(); - basic_tx_with_ether_and_to_key7.action = Action::Call(Address::from_str("d41c057fd1c78805aac12b0a94a405c0461a6fbb").unwrap()); - basic_tx_with_ether_and_to_key7.value = U256::from(123123); - let mut call_tx_with_ether = Transaction::default(); - call_tx_with_ether.action = Action::Call(Address::from_str("0000000000000000000000000000000000000005").unwrap()); - call_tx_with_ether.value = U256::from(123123); - - let mut basic_tx_to_key6 = Transaction::default(); - basic_tx_to_key6.action = Action::Call(Address::from_str("e57bfe9f44b819898f47bf37e5af72a0783e1141").unwrap()); - let mut basic_tx_with_ether_and_to_key6 = Transaction::default(); - basic_tx_with_ether_and_to_key6.action = Action::Call(Address::from_str("e57bfe9f44b819898f47bf37e5af72a0783e1141").unwrap()); - basic_tx_with_ether_and_to_key6.value = U256::from(123123); - - let genesis = client.block_hash(BlockId::Latest).unwrap(); - let block_number = 1; - - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); - // same tx but request is allowed because the contract only enables at block #1 - assert!(filter.transaction_allowed(&genesis, 0, &create_tx.clone().sign(key2.secret(), None), &*client)); - - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key1.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key1.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key1.secret(), None), &*client)); - - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key2.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key2.secret(), None), &*client)); - - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key3.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key3.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key3.secret(), None), &*client)); - - assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key4.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key4.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key4.secret(), None), &*client)); - - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key1.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key1.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key1.secret(), None), &*client)); - - assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx_with_ether_and_to_key7.clone().sign(key5.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx_with_ether.clone().sign(key5.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key6.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx_with_ether_and_to_key7.clone().sign(key6.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx_to_key6.clone().sign(key7.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx_with_ether_and_to_key6.clone().sign(key7.secret(), None), &*client)); - } - - /// Contract code: https://gist.github.com/arkpar/38a87cb50165b7e683585eec71acb05a - #[test] - fn transaction_filter_deprecated() { - let spec_data = include_str!("../res/tx_permission_tests/deprecated_contract_genesis.json"); - - let db = test_helpers::new_db(); - let tempdir = TempDir::new("").unwrap(); - let spec = Spec::load(&tempdir.path(), spec_data.as_bytes()).unwrap(); - - let client = Client::new( - ClientConfig::default(), - &spec, - db, - Arc::new(Miner::new_for_tests(&spec, None)), - IoChannel::disconnected(), - ).unwrap(); - let key1 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000001")).unwrap(); - let key2 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000002")).unwrap(); - let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000003")).unwrap(); - let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000004")).unwrap(); - - let filter = TransactionFilter::from_params(spec.params()).unwrap(); - let mut basic_tx = Transaction::default(); - basic_tx.action = Action::Call(Address::from_str("0000000000000000000000000000000000000032").unwrap()); - let create_tx = Transaction::default(); - let mut call_tx = Transaction::default(); - call_tx.action = Action::Call(Address::from_str("0000000000000000000000000000000000000005").unwrap()); - - let genesis = client.block_hash(BlockId::Latest).unwrap(); - let block_number = 1; - - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); - // same tx but request is allowed because the contract only enables at block #1 - assert!(filter.transaction_allowed(&genesis, 0, &create_tx.clone().sign(key2.secret(), None), &*client)); - - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key1.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key1.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key1.secret(), None), &*client)); - - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key2.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key2.secret(), None), &*client)); - assert!(filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key2.secret(), None), &*client)); - - assert!(filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key3.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key3.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key3.secret(), None), &*client)); - - assert!(!filter.transaction_allowed(&genesis, block_number, &basic_tx.clone().sign(key4.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &create_tx.clone().sign(key4.secret(), None), &*client)); - assert!(!filter.transaction_allowed(&genesis, block_number, &call_tx.clone().sign(key4.secret(), None), &*client)); - } -} diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index eeb1b2afecd..acf42b4510a 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -17,7 +17,7 @@ //! Canonical verifier. use call_contract::CallContract; -use client::BlockInfo; +use client_traits::BlockInfo; use engines::Engine; use types::{ header::Header, diff --git a/ethcore/src/verification/mod.rs b/ethcore/src/verification/mod.rs index d80b7867bfa..46cfd4b9e2e 100644 --- a/ethcore/src/verification/mod.rs +++ b/ethcore/src/verification/mod.rs @@ -29,7 +29,7 @@ pub use self::noop_verifier::NoopVerifier; pub use self::queue::{BlockQueue, Config as QueueConfig, VerificationQueue, QueueInfo}; use call_contract::CallContract; -use client::BlockInfo; +use client_traits::BlockInfo; /// Verifier type. #[derive(Debug, PartialEq, Clone)] diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index 9875524fa94..8bcbe1532d0 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -17,7 +17,7 @@ //! No-op verifier. use call_contract::CallContract; -use client::BlockInfo; +use client_traits::BlockInfo; use engines::Engine; use types::{ header::Header, diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 270a817bc3b..106759ca3af 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -21,9 +21,7 @@ use engines::Engine; use parity_util_mem::MallocSizeOf; use ethereum_types::{H256, U256}; -use types::{ - errors::EthcoreError as Error, -}; +use types::errors::EthcoreError as Error; pub use self::blocks::Blocks; pub use self::headers::Headers; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 0bde0e2859c..f1d099fc02a 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -31,7 +31,7 @@ use unexpected::{Mismatch, OutOfBounds}; use blockchain::*; use call_contract::CallContract; -use client::BlockInfo; +use client_traits::BlockInfo; use engines::Engine; use types::{ BlockNumber, diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index 2ca855fe442..17bb96a2cab 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -17,7 +17,7 @@ //! A generic verifier trait. use call_contract::CallContract; -use client::BlockInfo; +use client_traits::BlockInfo; use engines::Engine; use types::{ header::Header, From 50ca45a120e0c00c90817514dc51e492fd308116 Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 6 Aug 2019 18:41:31 +0200 Subject: [PATCH 04/43] Use new crates machine and client-traits instead of ethcore where appropriate --- Cargo.lock | 251 ++++++++++++++++++------------ Cargo.toml | 1 + parity/blockchain.rs | 3 +- parity/informant.rs | 3 +- parity/lib.rs | 2 + parity/run.rs | 3 +- rpc/Cargo.toml | 1 + rpc/src/lib.rs | 1 + rpc/src/v1/helpers/light_fetch.rs | 3 +- rpc/src/v1/types/trace.rs | 2 +- rpc/src/v1/types/transaction.rs | 3 +- 11 files changed, 166 insertions(+), 107 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7f8e4dc250..9ea26eb3154 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,7 +9,7 @@ dependencies = [ "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -25,7 +25,7 @@ dependencies = [ "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -33,7 +33,7 @@ dependencies = [ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "pod 0.1.0", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_compress 0.1.0", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "trace 0.1.0", @@ -147,7 +147,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -422,6 +422,14 @@ dependencies = [ "rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "client-traits" +version = "0.1.0" +dependencies = [ + "common-types 0.1.0", + "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -465,7 +473,7 @@ dependencies = [ "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unexpected 0.1.0", @@ -492,7 +500,7 @@ dependencies = [ "handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "itertools-num 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -763,7 +771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -827,7 +835,7 @@ dependencies = [ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -857,6 +865,7 @@ dependencies = [ "account-state 0.1.0", "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "blooms-db 0.1.0", + "client-traits 0.1.0", "common-types 0.1.0", "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -890,8 +899,9 @@ dependencies = [ "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "len-caching-lock 0.1.1", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "machine 0.1.0", "macros 0.1.0", "memory-cache 0.1.0", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -905,7 +915,7 @@ dependencies = [ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_compress 0.1.0", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -934,7 +944,7 @@ dependencies = [ "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ethstore 0.2.1", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -957,13 +967,13 @@ dependencies = [ "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_compress 0.1.0", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -987,7 +997,7 @@ dependencies = [ "ethjson 0.1.0", "ethkey 0.3.0", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1012,7 +1022,7 @@ dependencies = [ "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", ] @@ -1023,7 +1033,7 @@ dependencies = [ "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1038,6 +1048,7 @@ name = "ethcore-light" version = "1.12.0" dependencies = [ "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "client-traits 0.1.0", "common-types 0.1.0", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1058,7 +1069,8 @@ dependencies = [ "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "machine 0.1.0", "memory-cache 0.1.0", "memory-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1066,7 +1078,7 @@ dependencies = [ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1087,7 +1099,7 @@ dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1113,12 +1125,12 @@ dependencies = [ "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "price-info 1.12.0", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1142,7 +1154,7 @@ dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1165,7 +1177,7 @@ dependencies = [ "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1174,7 +1186,7 @@ dependencies = [ "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1188,6 +1200,7 @@ name = "ethcore-private-tx" version = "1.0.0" dependencies = [ "account-state 0.1.0", + "client-traits 0.1.0", "common-types 0.1.0", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1204,14 +1217,15 @@ dependencies = [ "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "machine 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1250,7 +1264,7 @@ dependencies = [ "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", @@ -1282,7 +1296,7 @@ dependencies = [ "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1296,7 +1310,7 @@ dependencies = [ "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-tcp-server 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1325,7 +1339,7 @@ dependencies = [ "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", @@ -1333,7 +1347,7 @@ dependencies = [ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "triehash-ethereum 0.2.0", @@ -1371,7 +1385,7 @@ dependencies = [ "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1407,7 +1421,7 @@ dependencies = [ "ethkey 0.3.0", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1449,7 +1463,7 @@ dependencies = [ "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1552,7 +1566,7 @@ dependencies = [ "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1668,7 +1682,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1684,7 +1698,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1701,7 +1715,7 @@ version = "0.32.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1798,7 +1812,7 @@ dependencies = [ "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1852,7 +1866,7 @@ dependencies = [ "attohttpc 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "xmltree 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1871,7 +1885,7 @@ name = "impl-rlp" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1976,7 +1990,7 @@ dependencies = [ "combine 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1997,12 +2011,12 @@ dependencies = [ "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2011,7 +2025,7 @@ version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2036,7 +2050,7 @@ dependencies = [ "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2049,7 +2063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-tokio-ipc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2061,7 +2075,7 @@ version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2075,7 +2089,7 @@ dependencies = [ "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2089,7 +2103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2101,7 +2115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2247,12 +2261,12 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2274,6 +2288,40 @@ dependencies = [ "toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "machine" +version = "0.1.0" +dependencies = [ + "account-state 0.1.0", + "client-traits 0.1.0", + "common-types 0.1.0", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore 1.12.0", + "ethcore-builtin 0.1.0", + "ethcore-call-contract 0.1.0", + "ethcore-io 1.12.0", + "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethjson 0.1.0", + "ethkey 0.3.0", + "evm 0.1.0", + "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "macros 0.1.0", + "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "state-db 0.1.0", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "trace 0.1.0", + "trie-vm-factories 0.1.0", + "vm 0.1.0", +] + [[package]] name = "macros" version = "0.1.0" @@ -2354,7 +2402,7 @@ version = "0.1.0" dependencies = [ "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2389,7 +2437,7 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2402,7 +2450,7 @@ version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2412,7 +2460,7 @@ name = "mio-named-pipes" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2494,7 +2542,7 @@ dependencies = [ "ethcore-network-devp2p 1.12.0", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2665,7 +2713,7 @@ dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2678,6 +2726,7 @@ dependencies = [ "blooms-db 0.1.0", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "cli-signer 1.4.0", + "client-traits 0.1.0", "common-types 0.1.0", "ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)", "dir 0.1.2", @@ -2708,7 +2757,7 @@ dependencies = [ "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "migration-rocksdb 0.1.0", "node-filter 1.12.0", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2729,7 +2778,7 @@ dependencies = [ "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "registrar 0.0.1", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2756,7 +2805,7 @@ dependencies = [ "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2778,7 +2827,7 @@ dependencies = [ "jsonrpc-http-server 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2791,8 +2840,8 @@ dependencies = [ "ethkey 0.3.0", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2859,7 +2908,8 @@ dependencies = [ "jsonrpc-pubsub 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "machine 0.1.0", "macros 0.1.0", "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2872,7 +2922,7 @@ dependencies = [ "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2897,7 +2947,7 @@ dependencies = [ "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rpc 1.12.0", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2939,7 +2989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2962,7 +3012,7 @@ dependencies = [ "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", @@ -2995,7 +3045,7 @@ name = "parity-version" version = "2.7.0" dependencies = [ "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3080,7 +3130,7 @@ dependencies = [ "keccak-hasher 0.1.1", "memory-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3182,11 +3232,11 @@ dependencies = [ "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3208,7 +3258,7 @@ dependencies = [ "fake-fetch 0.0.1", "fetch 0.1.0", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3313,7 +3363,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3596,10 +3646,9 @@ dependencies = [ [[package]] name = "rlp" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3609,7 +3658,7 @@ version = "0.1.0" dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3618,7 +3667,7 @@ version = "0.1.0" dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3672,7 +3721,7 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3828,7 +3877,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3908,7 +3957,7 @@ dependencies = [ "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3928,7 +3977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "stats" version = "0.1.0" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4192,7 +4241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4215,7 +4264,7 @@ dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4264,7 +4313,7 @@ dependencies = [ "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4297,7 +4346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4313,7 +4362,7 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4354,11 +4403,11 @@ dependencies = [ "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "evm 0.1.0", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", "vm 0.1.0", ] @@ -4368,7 +4417,7 @@ name = "trace-time" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4376,7 +4425,7 @@ name = "transaction-pool" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4394,7 +4443,7 @@ dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4426,7 +4475,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hash-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4605,7 +4654,7 @@ dependencies = [ "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", - "rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4629,7 +4678,7 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4641,7 +4690,7 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", @@ -4731,7 +4780,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4951,7 +5000,7 @@ dependencies = [ "checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum lunarity-lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a1670671f305792567116d4660e6e5bd785d6fa973e817c3445c0a7a54cecb6" "checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3" @@ -5055,7 +5104,7 @@ dependencies = [ "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a" -"checksum rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b0d56c1450bfbef1181fdeb78b902dc1d23178de77c23d705317508e03d1b7c" +"checksum rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa2f7f9c612d133da9101ef7bcd3e603ca7098901eca852e71f87a83dd3e6b59" "checksum rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b273c91bd242ca03ad6d71c143b6f17a48790e61f21a6c78568fa2b6774a24a4" "checksum rprompt 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1601f32bc5858aae3cbfa1c645c96c4d820cc5c16be0194f089560c00b6eb625" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" diff --git a/Cargo.toml b/Cargo.toml index 5adec802871..ea85995a556 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ fdlimit = "0.1" ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" } jsonrpc-core = "12.0.0" parity-bytes = "0.1" +client-traits = { path = "ethcore/client-traits" } common-types = { path = "ethcore/types" } ethcore = { path = "ethcore", features = ["parity"] } ethcore-accounts = { path = "accounts", optional = true } diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 40b3bbf31e0..76c338e9902 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -27,8 +27,9 @@ use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; use ethcore::client::{ - Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock, BlockChainReset + Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, BlockId, ImportBlock, BlockChainReset }; +use client_traits::BlockInfo; use ethcore::miner::Miner; use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::kind::blocks::Unverified; diff --git a/parity/informant.rs b/parity/informant.rs index 14400d58f08..3c2b1e94d15 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -24,9 +24,10 @@ use std::time::{Instant, Duration}; use atty; use ethcore::client::{ - BlockId, ChainInfo, BlockInfo, BlockChainInfo, BlockChainClient, + BlockId, ChainInfo, BlockChainInfo, BlockChainClient, BlockQueueInfo, ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage }; +use client_traits::BlockInfo; use types::BlockNumber; use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::service::Service as SnapshotService; diff --git a/parity/lib.rs b/parity/lib.rs index 1092ff061fc..2e5e5c1b838 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -41,6 +41,8 @@ extern crate toml; extern crate blooms_db; extern crate cli_signer; + +extern crate client_traits; extern crate common_types as types; extern crate ethcore; extern crate ethcore_call_contract as call_contract; diff --git a/parity/run.rs b/parity/run.rs index 4e74f0d2529..f6b47576ce0 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -22,7 +22,8 @@ use std::thread; use ansi_term::Colour; use bytes::Bytes; use call_contract::CallContract; -use ethcore::client::{BlockId, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo}; +use ethcore::client::{BlockId, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient}; +use client_traits::BlockInfo; use ethcore::miner::{self, stratum, Miner, MinerService, MinerOptions}; use ethcore::snapshot::{self, SnapshotConfiguration}; use ethcore::spec::{SpecParams, OptimizeFor}; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 318276ceea4..73cfa4909fe 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -47,6 +47,7 @@ ethcore-private-tx = { path = "../ethcore/private-tx" } ethcore-sync = { path = "../ethcore/sync" } ethereum-types = "0.6.0" fastmap = { path = "../util/fastmap" } +machine = { path = "../ethcore/machine" } parity-bytes = "0.1" parity-crypto = "0.4.0" diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 49db563f526..7f4f7f04ec7 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -43,6 +43,7 @@ extern crate futures; extern crate ansi_term; extern crate cid; extern crate itertools; +extern crate machine; extern crate multihash; extern crate order_stat; extern crate parking_lot; diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 0f5d2fbbbb6..b7362a418b4 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -39,11 +39,12 @@ use light::client::LightChainClient; use light::{cht, MAX_HEADERS_PER_REQUEST}; use light::on_demand::{ request, OnDemandRequester, HeaderRef, Request as OnDemandRequest, - Response as OnDemandResponse, ExecutionResult, + Response as OnDemandResponse, }; use light::on_demand::error::Error as OnDemandError; use light::request::Field; use light::TransactionQueue; +use machine::executed::ExecutionResult; use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider}; diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index ca6c89e9ef6..519e8571429 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -16,7 +16,7 @@ use std::collections::BTreeMap; -use ethcore::client::Executed; +use machine::executed::Executed; use trace as et; use trace::{FlatTrace, LocalizedTrace as EthLocalizedTrace, trace, TraceError}; use ethereum_types::{H160, H256, U256}; diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 9d75aca3cb7..2a6b2f45d09 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -18,7 +18,8 @@ use std::sync::Arc; use serde::{Serialize, Serializer}; use serde::ser::SerializeStruct; -use ethcore::{contract_address, CreateContractAddress}; +use machine::executive::{contract_address}; +use vm::CreateContractAddress; use ethereum_types::{H160, H256, H512, U64, U256}; use miner; use types::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction}; From 29d4095e3f56287627e0fb5b809712448593b769 Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 6 Aug 2019 23:31:25 +0200 Subject: [PATCH 05/43] Fix tests --- Cargo.lock | 3 ++ ethcore/light/src/on_demand/request.rs | 31 ++++++++++---------- ethcore/machine/src/executive.rs | 1 - ethcore/machine/src/externalities.rs | 5 +--- ethcore/private-tx/tests/private_contract.rs | 13 ++++---- ethcore/src/json_tests/executive.rs | 3 +- ethcore/src/json_tests/transaction.rs | 2 +- ethcore/sync/Cargo.toml | 2 ++ ethcore/sync/src/chain/mod.rs | 3 +- ethcore/sync/src/chain/propagator.rs | 13 ++++---- ethcore/sync/src/lib.rs | 2 ++ ethcore/sync/src/light_sync/tests/mod.rs | 4 ++- ethcore/sync/src/tests/chain.rs | 5 ++-- ethcore/sync/src/tests/private.rs | 16 +++++----- rpc/Cargo.toml | 1 + rpc/src/lib.rs | 2 ++ rpc/src/v1/tests/mocked/eth.rs | 12 +++++--- rpc/src/v1/tests/mocked/eth_pubsub.rs | 10 ++++--- rpc/src/v1/tests/mocked/parity.rs | 8 +++-- rpc/src/v1/tests/mocked/traces.rs | 2 +- 20 files changed, 84 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ea26eb3154..c5e2d67e499 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1320,6 +1320,7 @@ dependencies = [ name = "ethcore-sync" version = "1.12.0" dependencies = [ + "client-traits 0.1.0", "common-types 0.1.0", "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1340,6 +1341,7 @@ dependencies = [ "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "machine 0.1.0", "macros 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", @@ -2880,6 +2882,7 @@ dependencies = [ "account-state 0.1.0", "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "client-traits 0.1.0", "common-types 0.1.0", "eip-712 0.1.0", "ethash 1.12.0", diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index 15b04ca6355..f74d2e492e1 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -1099,7 +1099,8 @@ mod tests { use trie::Recorder; use hash::keccak; - use ethcore::client::{BlockChainClient, BlockInfo, TestBlockChainClient, EachBlockWith}; + use ethcore::client::{BlockChainClient, TestBlockChainClient, EachBlockWith}; + use client_traits::BlockInfo; use common_types::header::Header; use common_types::encoded; use common_types::receipt::{Receipt, TransactionOutcome}; @@ -1202,32 +1203,32 @@ mod tests { // Incorrect responses assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 0) - .check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]), - Err(Error::WrongHash(invalid_successor.hash(), headers[0].hash()))); + .check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]), + Err(Error::WrongHash(invalid_successor.hash(), headers[0].hash()))); assert_eq!(header_with_ancestors(headers[0].hash().into(), 0) - .check_response(&cache, &headers[0].hash().into(), &[]), - Err(Error::Empty)); + .check_response(&cache, &headers[0].hash().into(), &[]), + Err(Error::Empty)); assert_eq!(header_with_ancestors(headers[0].hash().into(), 10) - .check_response(&cache, &headers[0].hash().into(), &raw_headers[0..10]), - Err(Error::TooFewResults(11, 10))); + .check_response(&cache, &headers[0].hash().into(), &raw_headers[0..10]), + Err(Error::TooFewResults(11, 10))); assert_eq!(header_with_ancestors(headers[0].hash().into(), 9) - .check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]), - Err(Error::TooManyResults(10, 11))); + .check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]), + Err(Error::TooManyResults(10, 11))); let response = &[raw_headers[0].clone(), raw_headers[2].clone()]; assert_eq!(header_with_ancestors(headers[0].hash().into(), 1) - .check_response(&cache, &headers[0].hash().into(), response), - Err(Error::WrongHeaderSequence)); + .check_response(&cache, &headers[0].hash().into(), response), + Err(Error::WrongHeaderSequence)); let response = &[raw_invalid_successor.clone(), raw_headers[0].clone()]; assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1) - .check_response(&cache, &invalid_successor.hash().into(), response), - Err(Error::WrongHeaderSequence)); + .check_response(&cache, &invalid_successor.hash().into(), response), + Err(Error::WrongHeaderSequence)); let response = &[raw_invalid_successor.clone(), raw_headers[1].clone()]; assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1) - .check_response(&cache, &invalid_successor.hash().into(), response), - Err(Error::WrongHeaderSequence)); + .check_response(&cache, &invalid_successor.hash().into(), response), + Err(Error::WrongHeaderSequence)); } #[test] diff --git a/ethcore/machine/src/executive.rs b/ethcore/machine/src/executive.rs index 4c81c517ebc..c49562dce3a 100644 --- a/ethcore/machine/src/executive.rs +++ b/ethcore/machine/src/executive.rs @@ -1226,7 +1226,6 @@ mod tests { errors::ExecutionError, transaction::{Action, Transaction}, }; -// use ethcore::ethereum; use ethkey::{Generator, Random}; use evm::{Factory, VMType, evm_test, evm_test_ignore}; use macros::vec_into; diff --git a/ethcore/machine/src/externalities.rs b/ethcore/machine/src/externalities.rs index edd7af489f4..19e77d72d49 100644 --- a/ethcore/machine/src/externalities.rs +++ b/ethcore/machine/src/externalities.rs @@ -450,10 +450,7 @@ mod tests { use ethereum_types::{U256, Address}; use evm::{EnvInfo, Ext, CallType}; use account_state::State; - use ethcore::{ -// spec, - test_helpers::get_temp_state - }; + use ethcore::test_helpers::get_temp_state; use trace::{NoopTracer, NoopVMTracer}; use crate::{ diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs index 75d73dda4b4..7b1fe4d6882 100644 --- a/ethcore/private-tx/tests/private_contract.rs +++ b/ethcore/private-tx/tests/private_contract.rs @@ -24,6 +24,7 @@ extern crate ethcore_private_tx; extern crate ethkey; extern crate keccak_hash as hash; extern crate rustc_hex; +extern crate machine; #[macro_use] extern crate log; @@ -33,12 +34,14 @@ use rustc_hex::{FromHex, ToHex}; use types::ids::BlockId; use types::transaction::{Transaction, Action}; -use ethcore::CreateContractAddress; -use ethcore::client::BlockChainClient; -use ethcore::executive::contract_address; -use ethcore::miner::Miner; -use ethcore::test_helpers::{generate_dummy_client, push_block_with_transactions}; +use ethcore::{ + CreateContractAddress, + client::BlockChainClient, + test_helpers::{generate_dummy_client, push_block_with_transactions}, + miner::Miner, +}; use ethkey::{Secret, KeyPair, Signature}; +use machine::executive::contract_address; use hash::keccak; use ethcore_private_tx::{NoopEncryptor, Provider, ProviderConfig, StoringKeyProvider}; diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 9a0f3a2a1ae..98f28431e94 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -29,6 +29,7 @@ use machine::{ externalities::{OutputPolicy, OriginInfo, Externalities}, substate::Substate, executive::*, // todo[dvdplm] make explicit + test_helpers::new_frontier_test_machine, }; use test_helpers::get_temp_state; @@ -273,7 +274,7 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8] state.populate_from(From::from(vm.pre_state.clone())); let info: EnvInfo = From::from(vm.env); let machine = { - let mut machine = ::ethereum::new_frontier_test_machine(); + let mut machine = new_frontier_test_machine(); machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = 1)); machine }; diff --git a/ethcore/src/json_tests/transaction.rs b/ethcore/src/json_tests/transaction.rs index d71ef3283cc..3a6ced3fddd 100644 --- a/ethcore/src/json_tests/transaction.rs +++ b/ethcore/src/json_tests/transaction.rs @@ -24,7 +24,7 @@ use types::{ errors::EthcoreError as Error, transaction::UnverifiedTransaction }; -use transaction_ext::Transaction; +use machine::transaction_ext::Transaction; /// Run transaction jsontests on a given folder. pub fn run_test_path(p: &Path, skip: &[&'static str], h: &mut H) { diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index a8eaa643d99..3f60b0b0df9 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Parity Technologies "] [lib] [dependencies] +client-traits = { path = "../client-traits" } common-types = { path = "../types" } enum_primitive = "0.1.1" ethcore = { path = ".." } @@ -24,6 +25,7 @@ keccak-hash = "0.2.0" keccak-hasher = { path = "../../util/keccak-hasher" } kvdb = "0.1" log = "0.4" +machine = { path = "../machine" } macros = { path = "../../util/macros" } parity-bytes = "0.1" parking_lot = "0.8" diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index ed7b058c402..e9b432b9f20 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -1370,7 +1370,8 @@ pub mod tests { use super::*; use ::SyncConfig; use super::{PeerInfo, PeerAsking}; - use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo, BlockInfo}; + use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo}; + use client_traits::BlockInfo; use ethcore::miner::{MinerService, PendingOrdering}; use types::header::Header; diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs index 4899d7491a6..eb554cd5de7 100644 --- a/ethcore/sync/src/chain/propagator.rs +++ b/ethcore/sync/src/chain/propagator.rs @@ -335,12 +335,15 @@ impl SyncPropagator { #[cfg(test)] mod tests { - use ethcore::client::{BlockInfo, ChainInfo, EachBlockWith, TestBlockChainClient}; + use ethcore::client::{ChainInfo, EachBlockWith, TestBlockChainClient}; + use client_traits::BlockInfo; use parking_lot::RwLock; - use rlp::{Rlp}; - use std::collections::{VecDeque}; - use tests::helpers::{TestIo}; - use tests::snapshot::TestSnapshotService; + use rlp::Rlp; + use std::collections::VecDeque; + use tests::{ + helpers::TestIo, + snapshot::TestSnapshotService, + }; use super::{*, super::{*, tests::*}}; diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index 805e9f0c15f..4f71170bce4 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -46,6 +46,8 @@ extern crate ethcore_light as light; #[cfg(test)] extern crate kvdb_memorydb; #[cfg(test)] extern crate rustc_hex; #[cfg(test)] extern crate rand_xorshift; +#[cfg(test)] extern crate client_traits; +#[cfg(test)] extern crate machine; #[macro_use] extern crate enum_primitive; diff --git a/ethcore/sync/src/light_sync/tests/mod.rs b/ethcore/sync/src/light_sync/tests/mod.rs index 9bfb99ed0d9..22f7756952e 100644 --- a/ethcore/sync/src/light_sync/tests/mod.rs +++ b/ethcore/sync/src/light_sync/tests/mod.rs @@ -16,7 +16,9 @@ use tests::helpers::TestNet; -use ethcore::client::{BlockInfo, BlockId, EachBlockWith}; +use ethcore::client::EachBlockWith; +use client_traits::BlockInfo; +use types::ids::BlockId; mod test_net; diff --git a/ethcore/sync/src/tests/chain.rs b/ethcore/sync/src/tests/chain.rs index d81a876d7a8..51610bca8b0 100644 --- a/ethcore/sync/src/tests/chain.rs +++ b/ethcore/sync/src/tests/chain.rs @@ -15,8 +15,9 @@ // along with Parity Ethereum. If not, see . use std::sync::Arc; -use ethcore::client::{TestBlockChainClient, BlockChainClient, BlockId, EachBlockWith, ChainInfo, BlockInfo}; -use chain::{SyncState}; +use ethcore::client::{TestBlockChainClient, BlockChainClient, BlockId, EachBlockWith, ChainInfo}; +use client_traits::BlockInfo; +use chain::SyncState; use super::helpers::*; use {SyncConfig, WarpSync}; diff --git a/ethcore/sync/src/tests/private.rs b/ethcore/sync/src/tests/private.rs index d6dfa5c81bb..c62a4ae35a0 100644 --- a/ethcore/sync/src/tests/private.rs +++ b/ethcore/sync/src/tests/private.rs @@ -19,15 +19,17 @@ use hash::keccak; use io::{IoHandler, IoChannel}; use types::transaction::{Transaction, Action}; use types::ids::BlockId; -use ethcore::CreateContractAddress; -use ethcore::client::{ClientIoMessage, BlockChainClient}; -use ethcore::executive::contract_address; -use ethcore::engines; -use ethcore::miner::{self, MinerService}; -use ethcore::spec::Spec; -use ethcore::test_helpers::{push_block_with_transactions}; +use ethcore::{ + CreateContractAddress, + client::{ClientIoMessage, BlockChainClient}, + engines, + miner::{self, MinerService}, + spec::Spec, + test_helpers::push_block_with_transactions, +}; use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor, Importer, SignedPrivateTransaction, StoringKeyProvider}; use ethkey::KeyPair; +use machine::executive::contract_address; use tests::helpers::{TestNet, TestIoHandler}; use rustc_hex::FromHex; use rlp::Rlp; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 73cfa4909fe..fc5baa868be 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -67,6 +67,7 @@ trace = { path = "../ethcore/trace" } vm = { path = "../ethcore/vm" } [dev-dependencies] +client-traits = { path = "../ethcore/client-traits" } ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-accounts = { path = "../accounts" } ethcore-io = { path = "../util/io" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 7f4f7f04ec7..37749cf43d7 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -121,6 +121,8 @@ extern crate fake_fetch; #[cfg(test)] extern crate ethcore_io as io; +#[cfg(test)] +extern crate client_traits; pub extern crate jsonrpc_ws_server as ws; diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 39da9aa2abc..34925ddce13 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -20,18 +20,22 @@ use std::sync::Arc; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; use accounts::AccountProvider; -use ethcore::client::{BlockChainClient, BlockId, EachBlockWith, Executed, TestBlockChainClient, TransactionId}; +use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient}; use ethcore::miner::{self, MinerService}; use ethereum_types::{H160, H256, U256, Address, Bloom}; +use machine::executed::Executed; use miner::external::ExternalMiner; use parity_runtime::Runtime; use parking_lot::Mutex; use rlp; use rustc_hex::{FromHex, ToHex}; use sync::SyncState; -use types::transaction::{Transaction, Action}; -use types::log_entry::{LocalizedLogEntry, LogEntry}; -use types::receipt::{LocalizedReceipt, TransactionOutcome}; +use types::{ + ids::{BlockId, TransactionId}, + transaction::{Transaction, Action}, + log_entry::{LocalizedLogEntry, LogEntry}, + receipt::{LocalizedReceipt, TransactionOutcome}, +}; use jsonrpc_core::IoHandler; use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient}; diff --git a/rpc/src/v1/tests/mocked/eth_pubsub.rs b/rpc/src/v1/tests/mocked/eth_pubsub.rs index 1336f4e154e..a2bfa118de2 100644 --- a/rpc/src/v1/tests/mocked/eth_pubsub.rs +++ b/rpc/src/v1/tests/mocked/eth_pubsub.rs @@ -26,6 +26,12 @@ use v1::{EthPubSub, EthPubSubClient, Metadata}; use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify, NewBlocks, ChainRoute, ChainRouteType}; use parity_runtime::Runtime; use ethereum_types::{Address, H256}; +use client_traits::BlockInfo; +use types::{ + log_entry::{LocalizedLogEntry, LogEntry}, + ids::BlockId, +}; + const DURATION_ZERO: Duration = Duration::from_millis(0); @@ -86,10 +92,6 @@ fn should_subscribe_to_new_heads() { #[test] fn should_subscribe_to_logs() { - use ethcore::client::BlockInfo; - use types::log_entry::{LocalizedLogEntry, LogEntry}; - use types::ids::BlockId; - // given let el = Runtime::with_thread_count(1); let mut client = TestBlockChainClient::new(); diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index 913e181e400..e8a83bb355d 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -15,13 +15,17 @@ // along with Parity Ethereum. If not, see . use std::sync::Arc; -use ethcore::client::{TestBlockChainClient, Executed, TransactionId}; +use ethcore::client::TestBlockChainClient; use ethcore_logger::RotatingLogger; use ethereum_types::{Address, U256, H256, BigEndianHash, Bloom}; use ethstore::ethkey::{Generator, Random}; +use machine::executed::Executed; use miner::pool::local_transactions::Status as LocalTransactionStatus; use sync::ManageNetwork; -use types::receipt::{LocalizedReceipt, TransactionOutcome}; +use types::{ + ids::TransactionId, + receipt::{LocalizedReceipt, TransactionOutcome}, +}; use jsonrpc_core::IoHandler; use v1::{Parity, ParityClient}; diff --git a/rpc/src/v1/tests/mocked/traces.rs b/rpc/src/v1/tests/mocked/traces.rs index 0f3cfd820d2..84c8b6a0b08 100644 --- a/rpc/src/v1/tests/mocked/traces.rs +++ b/rpc/src/v1/tests/mocked/traces.rs @@ -16,7 +16,7 @@ use std::sync::Arc; -use ethcore::executed::Executed; +use machine::executed::Executed; use trace::trace::{Action, Res, Call}; use trace::LocalizedTrace; use ethcore::client::TestBlockChainClient; From cd6e0e2d11632dfc97ff3b9253f9a5b7a33bcf23 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 00:28:12 +0200 Subject: [PATCH 06/43] Don't re-export so many types from ethcore::client --- Cargo.lock | 2 ++ ethcore/node-filter/Cargo.toml | 1 + ethcore/node-filter/src/lib.rs | 7 ++++--- ethcore/private-tx/src/key_server_keys.rs | 2 +- ethcore/private-tx/src/lib.rs | 8 +++++--- ethcore/src/client/mod.rs | 11 ++++++----- ethcore/src/engines/clique/mod.rs | 3 ++- ethcore/src/miner/miner.rs | 3 ++- ethcore/sync/src/block_sync.rs | 3 ++- ethcore/sync/src/chain/mod.rs | 9 ++++++--- ipfs/Cargo.toml | 1 + ipfs/src/lib.rs | 1 + ipfs/src/route.rs | 2 +- parity/blockchain.rs | 9 ++++++--- parity/helpers.rs | 3 ++- parity/informant.rs | 7 +++++-- parity/run.rs | 3 ++- rpc/src/v1/helpers/errors.rs | 2 +- rpc/src/v1/impls/eth.rs | 13 ++++++++----- rpc/src/v1/impls/eth_filter.rs | 7 +++++-- rpc/src/v1/impls/eth_pubsub.rs | 9 ++++++--- rpc/src/v1/impls/traces.rs | 8 ++++++-- rpc/src/v1/types/block_number.rs | 2 +- rpc/src/v1/types/trace_filter.rs | 11 +++++++---- updater/src/updater.rs | 9 ++++++--- 25 files changed, 89 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5e2d67e499..ca7024c0a97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2535,6 +2535,7 @@ dependencies = [ name = "node-filter" version = "1.12.0" dependencies = [ + "common-types 0.1.0", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2823,6 +2824,7 @@ name = "parity-ipfs-api" version = "1.12.0" dependencies = [ "cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "common-types 0.1.0", "ethcore 1.12.0", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/node-filter/Cargo.toml b/ethcore/node-filter/Cargo.toml index e48f4f56027..e174e6189c7 100644 --- a/ethcore/node-filter/Cargo.toml +++ b/ethcore/node-filter/Cargo.toml @@ -7,6 +7,7 @@ version = "1.12.0" authors = ["Parity Technologies "] [dependencies] +common-types = { path = "../types" } ethcore = { path = ".."} ethcore-network = { path = "../../util/network" } ethcore-network-devp2p = { path = "../../util/network-devp2p" } diff --git a/ethcore/node-filter/src/lib.rs b/ethcore/node-filter/src/lib.rs index 17b46c6a5f3..2886a58e3f3 100644 --- a/ethcore/node-filter/src/lib.rs +++ b/ethcore/node-filter/src/lib.rs @@ -16,6 +16,7 @@ //! Smart contract based node filter. +extern crate common_types; extern crate ethabi; extern crate ethcore; extern crate ethcore_network as network; @@ -40,8 +41,8 @@ extern crate log; use std::collections::{HashMap, VecDeque}; use std::sync::Weak; -use ethcore::client::{BlockChainClient, BlockId, ChainNotify, NewBlocks}; - +use common_types::ids::BlockId; +use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks}; use ethereum_types::{H256, Address}; use ethabi::FunctionOutputDecoder; use network::{ConnectionFilter, ConnectionDirection}; @@ -68,7 +69,7 @@ pub const CACHE_SIZE: usize = MAX_NODES_IN_TABLE + 1024; impl NodeFilter { /// Create a new instance. Accepts a contract address. - pub fn new(client: Weak, contract_address: Address) -> NodeFilter { + pub fn new(client: Weak, contract_address: Address) -> NodeFilter { NodeFilter { client, contract_address, diff --git a/ethcore/private-tx/src/key_server_keys.rs b/ethcore/private-tx/src/key_server_keys.rs index 50bdb6662f2..639c083978d 100644 --- a/ethcore/private-tx/src/key_server_keys.rs +++ b/ethcore/private-tx/src/key_server_keys.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use parking_lot::RwLock; use ethereum_types::{H256, Address}; use call_contract::{CallContract, RegistryInfo}; -use ethcore::client::BlockId; +use types::ids::BlockId; use ethabi::FunctionOutputDecoder; const ACL_CHECKER_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_acl_checker"; diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 30878f8784e..ebbfb191875 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -93,10 +93,12 @@ use machine::{ executive::{Executive, TransactOptions, contract_address as ethcore_contract_address}, executed::Executed, }; -use types::transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}; +use types::{ + ids::BlockId, + transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction} +}; use ethcore::client::{ - Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId, - Call + Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, Call }; use client_traits::BlockInfo; use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache}; diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 05051aec04b..57c21230c68 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -41,12 +41,13 @@ pub use self::traits::{ }; pub use account_state::state::StateInfo; -pub use types::ids::*; // todo[dvdplm] Why these re-exports? -pub use types::trace_filter::Filter as TraceFilter; -pub use types::pruning_info::PruningInfo; -pub use types::call_analytics::CallAnalytics; +use types::{ + ids::*, + trace_filter::Filter as TraceFilter, + pruning_info::PruningInfo, + call_analytics::CallAnalytics, +}; -//pub use executive::{Executed, Executive, TransactOptions}; // todo[dvdplm] Why these re-exports? pub use vm::{LastHashes, EnvInfo}; pub use verification::VerifierType; diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index 2e3259e3f77..c704717bd94 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -65,7 +65,7 @@ use std::thread; use std::time; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; -use client::{BlockId, EngineClient}; +use client::EngineClient; use engines::clique::util::{extract_signers, recover_creator}; use engines::{Engine, Seal, SealingState, EthashSeal}; use ethereum_types::{Address, H64, H160, H256, U256}; @@ -84,6 +84,7 @@ use unexpected::{Mismatch, OutOfBounds}; use time_utils::CheckedSystemTime; use types::{ BlockNumber, + ids::BlockId, header::Header, engines::{ params::CommonParams, diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 04a3ce4a2c3..573d815546b 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -45,6 +45,7 @@ use types::transaction::{ }; use types::{ BlockNumber, + ids::TransactionId, block::Block, header::Header, ids::BlockId, @@ -56,7 +57,7 @@ use using_queue::{UsingQueue, GetAction}; use block::{ClosedBlock, SealedBlock}; use client::{ - BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId, ClientIoMessage, + BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, ClientIoMessage, }; use engines::{Engine, Seal, EngineSigner}; use machine::executive::contract_address; diff --git a/ethcore/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs index 1d04c1c6df6..27d5c103d2a 100644 --- a/ethcore/sync/src/block_sync.rs +++ b/ethcore/sync/src/block_sync.rs @@ -25,9 +25,10 @@ use ethereum_types::H256; use rlp::{self, Rlp}; use types::{ BlockNumber, + block_status::BlockStatus, + ids::BlockId, errors::{EthcoreError, BlockError, ImportError}, }; -use ethcore::client::{BlockStatus, BlockId}; use sync_io::SyncIo; use blocks::{BlockCollection, SyncBody, SyncHeader}; use chain::BlockSet; diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index e9b432b9f20..1ca7fe0a744 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -108,7 +108,7 @@ use bytes::Bytes; use rlp::{RlpStream, DecoderError}; use network::{self, PeerId, PacketId}; use network::client_version::ClientVersion; -use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockQueueInfo}; +use ethcore::client::{BlockChainClient, BlockStatus, BlockChainInfo, BlockQueueInfo}; use ethcore::snapshot::RestorationStatus; use sync_io::SyncIo; use super::{WarpSync, SyncConfig}; @@ -118,8 +118,11 @@ use snapshot::{Snapshot}; use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID, PriorityTask}; use private_tx::PrivateTxHandler; use transactions_stats::{TransactionsStats, Stats as TransactionStats}; -use types::transaction::UnverifiedTransaction; -use types::BlockNumber; +use types::{ + BlockNumber, + ids::BlockId, + transaction::UnverifiedTransaction +}; use self::handler::SyncHandler; use self::sync_packet::{PacketInfo, SyncPacket}; diff --git a/ipfs/Cargo.toml b/ipfs/Cargo.toml index a34195ce38f..3df59d012f0 100644 --- a/ipfs/Cargo.toml +++ b/ipfs/Cargo.toml @@ -6,6 +6,7 @@ license = "GPL-3.0" authors = ["Parity Technologies "] [dependencies] +common-types = { path = "../ethcore/types" } ethcore = { path = "../ethcore" } parity-bytes = "0.1" ethereum-types = "0.6.0" diff --git a/ipfs/src/lib.rs b/ipfs/src/lib.rs index 0ba6a86d029..635fd4c76ea 100644 --- a/ipfs/src/lib.rs +++ b/ipfs/src/lib.rs @@ -19,6 +19,7 @@ extern crate cid; extern crate unicase; extern crate rlp; +extern crate common_types; extern crate ethcore; extern crate parity_bytes as bytes; extern crate ethereum_types; diff --git a/ipfs/src/route.rs b/ipfs/src/route.rs index 1a4b5128f1e..7d5fb926ff3 100644 --- a/ipfs/src/route.rs +++ b/ipfs/src/route.rs @@ -18,10 +18,10 @@ use {rlp, multihash, IpfsHandler}; use error::{Error, Result}; use cid::{ToCid, Codec}; +use common_types::ids::{BlockId, TransactionId}; use multihash::Hash; use ethereum_types::H256; use bytes::Bytes; -use ethcore::client::{BlockId, TransactionId}; type Reason = &'static str; diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 76c338e9902..7d19333be0b 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -26,10 +26,10 @@ use hash::{keccak, KECCAK_NULL_RLP}; use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; +use client_traits::BlockInfo; use ethcore::client::{ - Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, BlockId, ImportBlock, BlockChainReset + Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, ImportBlock, BlockChainReset }; -use client_traits::BlockInfo; use ethcore::miner::Miner; use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::kind::blocks::Unverified; @@ -43,7 +43,10 @@ use user_defaults::UserDefaults; use ethcore_private_tx; use db; use ansi_term::Colour; -use types::errors::{ImportError, EthcoreError}; +use types::{ + ids::BlockId, + errors::{ImportError, EthcoreError} +}; #[derive(Debug, PartialEq)] pub enum DataFormat { diff --git a/parity/helpers.rs b/parity/helpers.rs index 61947d6bf53..cdd0050928e 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -21,7 +21,7 @@ use std::fs::File; use std::collections::HashSet; use ethereum_types::{U256, Address}; use journaldb::Algorithm; -use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; +use ethcore::client::{Mode, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; use ethcore::miner::{PendingSet, Penalization}; use miner::pool::PrioritizationStrategy; use cache::CacheConfig; @@ -32,6 +32,7 @@ use sync::{validate_node_url, self}; use db::migrate; use path; use ethkey::Password; +use types::ids::BlockId; pub fn to_duration(s: &str) -> Result { to_seconds(s).map(Duration::from_secs) diff --git a/parity/informant.rs b/parity/informant.rs index 3c2b1e94d15..cd2690b23bb 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -24,11 +24,14 @@ use std::time::{Instant, Duration}; use atty; use ethcore::client::{ - BlockId, ChainInfo, BlockChainInfo, BlockChainClient, + ChainInfo, BlockChainInfo, BlockChainClient, BlockQueueInfo, ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage }; use client_traits::BlockInfo; -use types::BlockNumber; +use types::{ + BlockNumber, + ids::BlockId, +}; use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::service::Service as SnapshotService; use sync::{LightSyncProvider, LightSync, SyncProvider, ManageNetwork}; diff --git a/parity/run.rs b/parity/run.rs index f6b47576ce0..6f1c441f18e 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -22,8 +22,8 @@ use std::thread; use ansi_term::Colour; use bytes::Bytes; use call_contract::CallContract; -use ethcore::client::{BlockId, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient}; use client_traits::BlockInfo; +use ethcore::client::{Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient}; use ethcore::miner::{self, stratum, Miner, MinerService, MinerOptions}; use ethcore::snapshot::{self, SnapshotConfiguration}; use ethcore::spec::{SpecParams, OptimizeFor}; @@ -41,6 +41,7 @@ use miner::work_notify::WorkPoster; use node_filter::NodeFilter; use parity_runtime::Runtime; use sync::{self, SyncConfig, PrivateTxHandler}; +use types::ids::BlockId; use parity_rpc::{ Origin, Metadata, NetworkSettings, informant, PubSubSession, FutureResult, FutureResponse, FutureOutput }; diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 491f61d2ce1..e016c9cf815 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -18,7 +18,6 @@ use std::fmt; -use ethcore::client::BlockId; use jsonrpc_core::{futures, Result as RpcResult, Error, ErrorCode, Value}; use rlp::DecoderError; use types::transaction::Error as TransactionError; @@ -27,6 +26,7 @@ use vm::Error as VMError; use light::on_demand::error::{Error as OnDemandError}; use ethcore::client::BlockChainClient; use types::{ + ids::BlockId, blockchain_info::BlockChainInfo, errors::{EthcoreError}, transaction::CallError, diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index f630a8fc4cf..495b5449c4c 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -25,16 +25,19 @@ use ethereum_types::{Address, H64, H160, H256, U64, U256, BigEndianHash}; use parking_lot::Mutex; use ethash::{self, SeedHashCompute}; -use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo, ProvingBlockChainClient}; +use ethcore::client::{BlockChainClient, StateOrBlock, StateClient, StateInfo, Call, EngineInfo, ProvingBlockChainClient}; use ethcore::miner::{self, MinerService}; use ethcore::snapshot::SnapshotService; use hash::keccak; use miner::external::ExternalMinerService; use sync::SyncProvider; -use types::transaction::{SignedTransaction, LocalizedTransaction}; -use types::BlockNumber as EthBlockNumber; -use types::encoded; -use types::filter::Filter as EthcoreFilter; +use types::{ + BlockNumber as EthBlockNumber, + encoded, + ids::{BlockId, TransactionId, UncleId}, + filter::Filter as EthcoreFilter, + transaction::{SignedTransaction, LocalizedTransaction} +}; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::future; diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index c51c85fb629..b205dde572c 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -19,11 +19,14 @@ use std::sync::Arc; use std::collections::{BTreeSet, VecDeque}; -use ethcore::client::{BlockChainClient, BlockId}; +use ethcore::client::BlockChainClient; use ethcore::miner::{self, MinerService}; use ethereum_types::{H256, U256}; use parking_lot::Mutex; -use types::filter::Filter as EthcoreFilter; +use types::{ + ids::BlockId, + filter::Filter as EthcoreFilter +}; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::futures::{future, Future}; diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index acb0d5f0e25..fd557b09615 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -31,7 +31,7 @@ use v1::traits::EthPubSub; use v1::types::{pubsub, RichHeader, Log}; use sync::{SyncState, Notification}; -use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainRouteType, BlockId}; +use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainRouteType}; use ethereum_types::H256; use light::cache::Cache; use light::client::{LightChainClient, LightChainNotify}; @@ -41,8 +41,11 @@ use parking_lot::{RwLock, Mutex}; use sync::{LightSyncProvider, LightNetworkDispatcher, ManageNetwork}; -use types::encoded; -use types::filter::Filter as EthFilter; +use types::{ + ids::BlockId, + encoded, + filter::Filter as EthFilter, +}; type Client = Sink; diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index a6301eda539..752bd8ae711 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -18,10 +18,14 @@ use std::sync::Arc; -use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId}; +use ethcore::client::{BlockChainClient, StateClient, StateInfo, Call}; use ethereum_types::H256; use rlp::Rlp; -use types::transaction::SignedTransaction; +use types::{ + call_analytics::CallAnalytics, + ids::{BlockId, TransactionId, TraceId}, + transaction::SignedTransaction, +}; use jsonrpc_core::Result; use v1::Metadata; diff --git a/rpc/src/v1/types/block_number.rs b/rpc/src/v1/types/block_number.rs index 7e19f2d3d9a..a0105e4e1a2 100644 --- a/rpc/src/v1/types/block_number.rs +++ b/rpc/src/v1/types/block_number.rs @@ -17,7 +17,7 @@ use std::fmt; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::de::{Error, Visitor}; -use ethcore::client::BlockId; +use types::ids::BlockId; /// Represents rpc api block number param. #[derive(Debug, PartialEq, Clone, Hash, Eq)] diff --git a/rpc/src/v1/types/trace_filter.rs b/rpc/src/v1/types/trace_filter.rs index 60c7701953d..b8a6827b6ad 100644 --- a/rpc/src/v1/types/trace_filter.rs +++ b/rpc/src/v1/types/trace_filter.rs @@ -16,9 +16,12 @@ //! Trace filter deserialization. -use ethcore::client::BlockId; use ethcore::client; use ethereum_types::H160; +use types::{ + ids::BlockId, + trace_filter::Filter, +}; use v1::types::BlockNumber; /// Trace filter @@ -40,8 +43,8 @@ pub struct TraceFilter { pub count: Option, } -impl Into for TraceFilter { - fn into(self) -> client::TraceFilter { +impl Into for TraceFilter { + fn into(self) -> Filter { let num_to_id = |num| match num { BlockNumber::Num(n) => BlockId::Number(n), BlockNumber::Earliest => BlockId::Earliest, @@ -53,7 +56,7 @@ impl Into for TraceFilter { }; let start = self.from_block.map_or(BlockId::Latest, &num_to_id); let end = self.to_block.map_or(BlockId::Latest, &num_to_id); - client::TraceFilter { + Filter { range: start..end, from_address: self.from_address.map_or_else(Vec::new, |x| x.into_iter().map(Into::into).collect()), to_address: self.to_address.map_or_else(Vec::new, |x| x.into_iter().map(Into::into).collect()), diff --git a/updater/src/updater.rs b/updater/src/updater.rs index 6e84f8281e9..f9558876d93 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -25,9 +25,12 @@ use parking_lot::{Mutex, MutexGuard}; use rand::{self, Rng}; use target_info::Target; -use common_types::BlockNumber; -use common_types::filter::Filter; -use ethcore::client::{BlockId, BlockChainClient, ChainNotify, NewBlocks}; +use common_types::{ + BlockNumber, + ids::BlockId, + filter::Filter, +}; +use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks}; use ethereum_types::{H256, H160}; use hash_fetch::{self as fetch, HashFetch}; use parity_path::restrict_permissions_owner; From 2477cbd074577ed2aa586a7b4b64ede8d304701a Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 01:16:43 +0200 Subject: [PATCH 07/43] Fixing more fallout from removing re-export --- ethcore/src/client/client.rs | 39 +++++++++++++---------------- ethcore/src/client/mod.rs | 1 - ethcore/src/client/test_client.rs | 38 +++++++++++++++------------- ethcore/src/json_tests/executive.rs | 4 +-- ethcore/src/tests/client.rs | 13 ++++++---- ethcore/src/tests/trace.rs | 12 ++++++--- parity/configuration.rs | 3 ++- parity/helpers.rs | 3 ++- 8 files changed, 61 insertions(+), 52 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 0b2eaf4367c..1cd8ecba1a1 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -2653,20 +2653,27 @@ impl IoChannelQueue { #[cfg(test)] mod tests { use ethereum_types::{H256, Address}; + use client::{BlockChainClient, ChainInfo}; + use types::{ + encoded, + ids::{BlockId, TransactionId}, + log_entry::{LogEntry, LocalizedLogEntry}, + receipt::{Receipt, LocalizedReceipt, TransactionOutcome}, + transaction::{Transaction, LocalizedTransaction, Action}, + }; + use test_helpers::{generate_dummy_client, get_good_dummy_block_hash, generate_dummy_client_with_data}; + use std::thread; + use std::time::Duration; + use std::sync::Arc; + use std::sync::atomic::{AtomicBool, Ordering}; + use kvdb::DBTransaction; + use blockchain::ExtrasInsert; + use hash::keccak; + use super::transaction_receipt; + use ethkey::KeyPair; #[test] fn should_not_cache_details_before_commit() { - use client::{BlockChainClient, ChainInfo}; - use test_helpers::{generate_dummy_client, get_good_dummy_block_hash}; - - use std::thread; - use std::time::Duration; - use std::sync::Arc; - use std::sync::atomic::{AtomicBool, Ordering}; - use kvdb::DBTransaction; - use blockchain::ExtrasInsert; - use types::encoded; - let client = generate_dummy_client(0); let genesis = client.chain_info().best_block_hash; let (new_hash, new_block) = get_good_dummy_block_hash(); @@ -2694,9 +2701,6 @@ mod tests { #[test] fn should_return_block_receipts() { - use client::{BlockChainClient, BlockId, TransactionId}; - use test_helpers::{generate_dummy_client_with_data}; - let client = generate_dummy_client_with_data(2, 2, &[1.into(), 1.into()]); let receipts = client.localized_block_receipts(BlockId::Latest).unwrap(); @@ -2720,13 +2724,6 @@ mod tests { #[test] fn should_return_correct_log_index() { - use hash::keccak; - use super::transaction_receipt; - use ethkey::KeyPair; - use types::log_entry::{LogEntry, LocalizedLogEntry}; - use types::receipt::{Receipt, LocalizedReceipt, TransactionOutcome}; - use types::transaction::{Transaction, LocalizedTransaction, Action}; - // given let key = KeyPair::from_secret_slice(keccak("test").as_bytes()).unwrap(); let secret = key.secret(); diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 57c21230c68..8ac833f0da4 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -42,7 +42,6 @@ pub use self::traits::{ pub use account_state::state::StateInfo; use types::{ - ids::*, trace_filter::Filter as TraceFilter, pruning_info::PruningInfo, call_analytics::CallAnalytics, diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index baea824d33a..d3cec3059e0 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -36,29 +36,33 @@ use kvdb_memorydb; use parking_lot::RwLock; use rlp::{Rlp, RlpStream}; use rustc_hex::FromHex; -use types::transaction::{self, Transaction, LocalizedTransaction, SignedTransaction, Action, CallError}; -use types::BlockNumber; -use types::basic_account::BasicAccount; -use types::encoded; -use types::errors::{EthcoreError as Error, EthcoreResult}; -use types::filter::Filter; -use types::header::Header; -use types::log_entry::LocalizedLogEntry; -use types::pruning_info::PruningInfo; -use types::receipt::{Receipt, LocalizedReceipt, TransactionOutcome}; -use types::view; -use types::views::BlockView; +use types::{ + BlockNumber, + encoded, + ids::{BlockId, TransactionId, UncleId, TraceId}, + basic_account::BasicAccount, + errors::{EthcoreError as Error, EthcoreResult}, + transaction::{self, Transaction, LocalizedTransaction, SignedTransaction, Action, CallError}, + filter::Filter, + trace_filter::Filter as TraceFilter, + call_analytics::CallAnalytics, + header::Header, + log_entry::LocalizedLogEntry, + pruning_info::PruningInfo, + receipt::{Receipt, LocalizedReceipt, TransactionOutcome}, + view, + views::BlockView, +}; use vm::Schedule; use block::{OpenBlock, SealedBlock, ClosedBlock}; use call_contract::{CallContract, RegistryInfo}; use client::{ Nonce, Balance, ChainInfo, ReopenBlock, TransactionInfo, - PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode, - TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics, - ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, - Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, IoClient, - BadBlocks + PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, Mode, + LastHashes, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, + ImportBlock, StateOrBlock, Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, + SealedBlockImporter, IoClient, BadBlocks }; use client_traits::BlockInfo; use engines::Engine; diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 98f28431e94..78f2f71d26e 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -28,7 +28,7 @@ use machine::{ Machine, externalities::{OutputPolicy, OriginInfo, Externalities}, substate::Substate, - executive::*, // todo[dvdplm] make explicit + executive::contract_address, test_helpers::new_frontier_test_machine, }; @@ -303,7 +303,7 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8] &mut tracer, &mut vm_tracer, )); - let mut evm = vm_factory.create(params, &schedule, 0).expect("Current tests are all of version 0; factory always return Some; qed"); + let evm = vm_factory.create(params, &schedule, 0).expect("Current tests are all of version 0; factory always return Some; qed"); let res = evm.exec(&mut ex).ok().expect("TestExt never trap; resume error never happens; qed"); // a return in finalize will not alter callcreates let callcreates = ex.callcreates.clone(); diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 95f42897539..cf40c246c15 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -22,12 +22,15 @@ use ethkey::KeyPair; use hash::keccak; use io::IoChannel; use tempdir::TempDir; -use types::transaction::{PendingTransaction, Transaction, Action, Condition}; -use types::filter::Filter; -use types::view; -use types::views::BlockView; +use types::{ + ids::BlockId, + transaction::{PendingTransaction, Transaction, Action, Condition}, + filter::Filter, + view, + views::BlockView, +}; -use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, BlockId, ChainInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; +use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, ChainInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; use client_traits::BlockInfo; use ethereum; use machine::executive::{Executive, TransactOptions}; diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index b80c7485128..da70665a4b0 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -28,14 +28,18 @@ use client::{BlockChainClient, Client, ClientConfig}; use std::sync::Arc; use std::str::FromStr; use miner::Miner; -use types::transaction::{Action, Transaction}; use trace::{RewardType, LocalizedTrace}; use trace::trace::Action::Reward; use test_helpers; use verification::queue::kind::blocks::Unverified; -use types::header::Header; -use types::view; -use types::views::BlockView; +use types::{ + ids::BlockId, + transaction::{Action, Transaction}, + trace_filter::Filter as TraceFilter, + header::Header, + view, + views::BlockView, +}; #[test] fn can_trace_block_and_uncle_reward() { diff --git a/parity/configuration.rs b/parity/configuration.rs index b4e2d175bea..b9a8d37d27e 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -1194,11 +1194,12 @@ mod tests { use std::str::FromStr; use tempdir::TempDir; - use ethcore::client::{VMType, BlockId}; + use ethcore::client::VMType; use ethcore::miner::MinerOptions; use miner::pool::PrioritizationStrategy; use parity_rpc::NetworkSettings; use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack}; + use types::ids::BlockId; use account::{AccountCmd, NewAccount, ImportAccounts, ListAccounts}; use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat, ExportState}; diff --git a/parity/helpers.rs b/parity/helpers.rs index cdd0050928e..1c9494e3ddf 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -348,9 +348,10 @@ mod tests { use std::collections::HashSet; use tempdir::TempDir; use ethereum_types::U256; - use ethcore::client::{Mode, BlockId}; + use ethcore::client::Mode; use ethcore::miner::PendingSet; use ethkey::Password; + use types::ids::BlockId; use super::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_address, to_addresses, to_price, geth_ipc_path, to_bootnodes, join_set, password_from_file}; #[test] From c84a01f523d8276f0c4ac31d9595a072ae8c2a60 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 02:01:22 +0200 Subject: [PATCH 08/43] fix test --- ethcore/machine/src/tx_filter.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ethcore/machine/src/tx_filter.rs b/ethcore/machine/src/tx_filter.rs index 83d5c9a709b..eb4045a7ac5 100644 --- a/ethcore/machine/src/tx_filter.rs +++ b/ethcore/machine/src/tx_filter.rs @@ -152,9 +152,12 @@ mod test { use tempdir::TempDir; use ethereum_types::{U256, Address}; - use common_types::transaction::{Transaction, Action}; + use common_types::{ + ids::BlockId, + transaction::{Transaction, Action} + }; use ethcore::{ - client::{BlockChainClient, Client, ClientConfig, BlockId}, + client::{BlockChainClient, Client, ClientConfig}, spec::Spec, miner::Miner, test_helpers, From f2497f4f8aa3b07144d0c05d5e8bcab5b0d7a4e3 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 08:13:49 +0200 Subject: [PATCH 09/43] More fallout from not re-exporting types --- ethcore/sync/src/blocks.rs | 7 +++++-- ethcore/sync/src/tests/chain.rs | 3 ++- rpc/src/v1/types/block_number.rs | 2 +- secret-store/src/acl_storage.rs | 3 ++- secret-store/src/helpers.rs | 3 ++- secret-store/src/key_server_set.rs | 3 ++- secret-store/src/listener/service_contract.rs | 3 ++- secret-store/src/trusted_client.rs | 7 +++++-- 8 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ethcore/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs index 4ae2093ee3a..e5b89253668 100644 --- a/ethcore/sync/src/blocks.rs +++ b/ethcore/sync/src/blocks.rs @@ -541,8 +541,11 @@ impl BlockCollection { #[cfg(test)] mod test { use super::{BlockCollection, SyncHeader}; - use ethcore::client::{TestBlockChainClient, EachBlockWith, BlockId, BlockChainClient}; - use types::BlockNumber; + use ethcore::client::{TestBlockChainClient, EachBlockWith, BlockChainClient}; + use types::{ + ids::BlockId, + BlockNumber + }; use ethcore::verification::queue::kind::blocks::Unverified; use rlp::*; diff --git a/ethcore/sync/src/tests/chain.rs b/ethcore/sync/src/tests/chain.rs index 51610bca8b0..1da287a6463 100644 --- a/ethcore/sync/src/tests/chain.rs +++ b/ethcore/sync/src/tests/chain.rs @@ -15,7 +15,8 @@ // along with Parity Ethereum. If not, see . use std::sync::Arc; -use ethcore::client::{TestBlockChainClient, BlockChainClient, BlockId, EachBlockWith, ChainInfo}; +use types::ids::BlockId; +use ethcore::client::{TestBlockChainClient, BlockChainClient, EachBlockWith, ChainInfo}; use client_traits::BlockInfo; use chain::SyncState; use super::helpers::*; diff --git a/rpc/src/v1/types/block_number.rs b/rpc/src/v1/types/block_number.rs index b211a13aebd..dec711f683e 100644 --- a/rpc/src/v1/types/block_number.rs +++ b/rpc/src/v1/types/block_number.rs @@ -191,7 +191,7 @@ pub fn block_number_to_id(number: BlockNumber) -> BlockId { #[cfg(test)] mod tests { - use ethcore::client::BlockId; + use types::ids::BlockId; use super::*; use std::str::FromStr; use serde_json; diff --git a/secret-store/src/acl_storage.rs b/secret-store/src/acl_storage.rs index 8c6656b1084..110ce3d5ce6 100644 --- a/secret-store/src/acl_storage.rs +++ b/secret-store/src/acl_storage.rs @@ -16,9 +16,10 @@ use std::sync::Arc; use std::collections::{HashMap, HashSet}; +use common_types::ids::BlockId; use parking_lot::{Mutex, RwLock}; use call_contract::CallContract; -use ethcore::client::{BlockId, ChainNotify, NewBlocks}; +use ethcore::client::{ChainNotify, NewBlocks}; use ethereum_types::Address; use ethabi::FunctionOutputDecoder; use trusted_client::TrustedClient; diff --git a/secret-store/src/helpers.rs b/secret-store/src/helpers.rs index 19b19d1ba10..3dfe7ae8b66 100644 --- a/secret-store/src/helpers.rs +++ b/secret-store/src/helpers.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use ethcore::client::{Client, BlockChainClient, BlockId}; +use ethcore::client::{Client, BlockChainClient}; +use common_types::ids::BlockId; use ethereum_types::H256; // TODO: Instead of a constant, make this based on consensus finality. diff --git a/secret-store/src/key_server_set.rs b/secret-store/src/key_server_set.rs index 3002a3c12be..b57df0a8ba4 100644 --- a/secret-store/src/key_server_set.rs +++ b/secret-store/src/key_server_set.rs @@ -20,7 +20,8 @@ use std::collections::{BTreeMap, HashSet}; use parking_lot::Mutex; use call_contract::CallContract; use ethabi::FunctionOutputDecoder; -use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, NewBlocks}; +use ethcore::client::{Client, BlockChainClient, ChainNotify, NewBlocks}; +use common_types::ids::BlockId; use ethereum_types::{H256, Address}; use ethkey::public_to_address; use bytes::Bytes; diff --git a/secret-store/src/listener/service_contract.rs b/secret-store/src/listener/service_contract.rs index 4fad7cf7e28..caac9065a51 100644 --- a/secret-store/src/listener/service_contract.rs +++ b/secret-store/src/listener/service_contract.rs @@ -20,7 +20,8 @@ use common_types::filter::Filter; use ethabi::RawLog; use ethabi::FunctionOutputDecoder; use call_contract::CallContract; -use ethcore::client::{Client, BlockChainClient, BlockId}; +use ethcore::client::{Client, BlockChainClient}; +use common_types::ids::BlockId; use ethkey::{Public, public_to_address}; use hash::keccak; use bytes::Bytes; diff --git a/secret-store/src/trusted_client.rs b/secret-store/src/trusted_client.rs index 6fb9626f6e4..70ca6f420cb 100644 --- a/secret-store/src/trusted_client.rs +++ b/secret-store/src/trusted_client.rs @@ -17,9 +17,12 @@ use std::sync::{Arc, Weak}; use bytes::Bytes; use call_contract::RegistryInfo; -use common_types::transaction::{Transaction, SignedTransaction, Action}; +use common_types::{ + ids::BlockId, + transaction::{Transaction, SignedTransaction, Action}, +}; use ethereum_types::Address; -use ethcore::client::{Client, ChainInfo, Nonce, BlockId}; +use ethcore::client::{Client, ChainInfo, Nonce}; use ethcore::miner::{Miner, MinerService}; use sync::SyncProvider; use helpers::{get_confirmed_block_hash, REQUEST_CONFIRMATIONS_REQUIRED}; From 1e435346b8410d60a3c5d3d2043b4f072ef670cb Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 15:19:12 +0200 Subject: [PATCH 10/43] Add some docs --- ethcore/light/src/on_demand/mod.rs | 3 +-- ethcore/machine/src/executed_block.rs | 6 +++--- ethcore/machine/src/externalities.rs | 1 + ethcore/machine/src/lib.rs | 4 +++- ethcore/machine/src/machine.rs | 2 +- ethcore/machine/src/substate.rs | 1 + ethcore/machine/src/test_helpers.rs | 2 +- ethcore/src/block.rs | 4 ++-- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index cdac4fdc184..7f5b712dd7a 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -39,8 +39,7 @@ use net::{ use cache::Cache; use request::{self as basic_request, Request as NetworkRequest}; use self::request::CheckedRequest; - -use machine::executed::ExecutionResult; // todo[dvdplm] why was this re-exported? +use machine::executed::ExecutionResult; pub use self::request::{Request, Response, HeaderRef, Error as ValidityError}; pub use self::request_guard::{RequestGuard, Error as RequestError}; diff --git a/ethcore/machine/src/executed_block.rs b/ethcore/machine/src/executed_block.rs index ebe6de1fa2c..c1691cf6a97 100644 --- a/ethcore/machine/src/executed_block.rs +++ b/ethcore/machine/src/executed_block.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -// todo[dvdplm] improve docs -//! `ExecutedBlock` is an underlying data structure used by other block types to store block -//! related info. +//! `ExecutedBlock` is the underlying data structure used by other block types to store block +//! related info. As a block goes through processing we use different types to signal its state: +//! "open", "closed", "locked", "sealed". They all embed an `ExecutedBlock`. use std::{ collections::HashSet, diff --git a/ethcore/machine/src/externalities.rs b/ethcore/machine/src/externalities.rs index 19e77d72d49..d002f07bea1 100644 --- a/ethcore/machine/src/externalities.rs +++ b/ethcore/machine/src/externalities.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . //! Transaction Execution environment. + use std::{cmp, sync::Arc}; use ethereum_types::{H256, U256, Address, BigEndianHash}; diff --git a/ethcore/machine/src/lib.rs b/ethcore/machine/src/lib.rs index c89e6514e02..fae5a40a80d 100644 --- a/ethcore/machine/src/lib.rs +++ b/ethcore/machine/src/lib.rs @@ -14,7 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -// todo[dvdplm]: document all modules +//! This crate provides a state machine and the facilities needed to execute transactions and the +//! code contained therein, as well as contract based transaction permissions. All ethereum +//! engines embed a `Machine`. // todo[dvdplm]: fix ethabi for use with edition 2018 #[macro_use] diff --git a/ethcore/machine/src/machine.rs b/ethcore/machine/src/machine.rs index dfd4c724e88..0accc9f3b81 100644 --- a/ethcore/machine/src/machine.rs +++ b/ethcore/machine/src/machine.rs @@ -98,7 +98,7 @@ impl Machine { /// Execute a call as the system address. Block environment information passed to the /// VM is modified to have its gas limit bounded at the upper limit of possible used - /// gases including this system call, capped at the maximum value able to be + /// gas, including this system call, capped at the maximum value able to be /// represented by U256. This system call modifies the block state, but discards other /// information. If suicides, logs or refunds happen within the system call, they /// will not be executed or recorded. Gas used by this system call will not be counted diff --git a/ethcore/machine/src/substate.rs b/ethcore/machine/src/substate.rs index 48bf675207c..6875d10e7ba 100644 --- a/ethcore/machine/src/substate.rs +++ b/ethcore/machine/src/substate.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . //! Execution environment substate. + use std::collections::HashSet; use ethereum_types::Address; use common_types::log_entry::LogEntry; diff --git a/ethcore/machine/src/test_helpers.rs b/ethcore/machine/src/test_helpers.rs index 616b60e50a5..49394d727bf 100644 --- a/ethcore/machine/src/test_helpers.rs +++ b/ethcore/machine/src/test_helpers.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -// Creating test Machines +//! Provide facilities to create `Machine` instances for testing various networks. use common_types::engines::params::CommonParams; use ethjson; diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 3bc6f4373c6..afc996956b3 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -28,8 +28,8 @@ //! `LockedBlock` is a version of a `ClosedBlock` that cannot be reopened. It can be sealed //! using an engine. //! -//! `ExecutedBlock` is an underlying data structure used by all structs above to store block -//! related info. +//! `ExecutedBlock` from the `machine` crate is the underlying data structure used by all structs +//! above to store block related info. use std::{cmp, ops}; use std::sync::Arc; From 6d83cf2471323a402dc6913fa7d2db1816dd30d3 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 15:28:38 +0200 Subject: [PATCH 11/43] cleanup --- ethcore/{res/contracts => machine/res}/tx_acl.json | 0 .../{res/contracts => machine/res}/tx_acl_deprecated.json | 0 ethcore/machine/src/tx_filter.rs | 4 ++-- ethcore/src/lib.rs | 8 -------- 4 files changed, 2 insertions(+), 10 deletions(-) rename ethcore/{res/contracts => machine/res}/tx_acl.json (100%) rename ethcore/{res/contracts => machine/res}/tx_acl_deprecated.json (100%) diff --git a/ethcore/res/contracts/tx_acl.json b/ethcore/machine/res/tx_acl.json similarity index 100% rename from ethcore/res/contracts/tx_acl.json rename to ethcore/machine/res/tx_acl.json diff --git a/ethcore/res/contracts/tx_acl_deprecated.json b/ethcore/machine/res/tx_acl_deprecated.json similarity index 100% rename from ethcore/res/contracts/tx_acl_deprecated.json rename to ethcore/machine/res/tx_acl_deprecated.json diff --git a/ethcore/machine/src/tx_filter.rs b/ethcore/machine/src/tx_filter.rs index eb4045a7ac5..c77a5d3035d 100644 --- a/ethcore/machine/src/tx_filter.rs +++ b/ethcore/machine/src/tx_filter.rs @@ -32,8 +32,8 @@ use common_types::{ }; use keccak_hash::KECCAK_EMPTY; -use_contract!(transact_acl_deprecated, "../res/contracts/tx_acl_deprecated.json"); -use_contract!(transact_acl, "../res/contracts/tx_acl.json"); +use_contract!(transact_acl_deprecated, "res/tx_acl_deprecated.json"); +use_contract!(transact_acl, "res/tx_acl.json"); const MAX_CACHE_SIZE: usize = 4096; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 623fb28f579..b9c1979a55d 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -155,20 +155,12 @@ pub mod block; pub mod client; pub mod engines; pub mod ethereum; -//pub mod executed; -//pub mod executive; pub mod executive_state; -//pub mod machine; pub mod miner; pub mod snapshot; pub mod spec; pub mod verification; -//mod externalities; -//mod substate; -//mod transaction_ext; -//mod tx_filter; - #[cfg(test)] mod tests; #[cfg(feature = "json-tests")] From e04d188fd3b2e50e873ab2a0bb03878c87ccf599 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 16:08:33 +0200 Subject: [PATCH 12/43] import the macro edition style --- ethcore/machine/src/lib.rs | 2 -- ethcore/machine/src/tx_filter.rs | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ethcore/machine/src/lib.rs b/ethcore/machine/src/lib.rs index fae5a40a80d..d4059a01132 100644 --- a/ethcore/machine/src/lib.rs +++ b/ethcore/machine/src/lib.rs @@ -21,8 +21,6 @@ // todo[dvdplm]: fix ethabi for use with edition 2018 #[macro_use] extern crate ethabi_derive; -#[macro_use] -extern crate ethabi_contract; pub mod executed; pub mod executed_block; diff --git a/ethcore/machine/src/tx_filter.rs b/ethcore/machine/src/tx_filter.rs index c77a5d3035d..41c8ffd1047 100644 --- a/ethcore/machine/src/tx_filter.rs +++ b/ethcore/machine/src/tx_filter.rs @@ -21,6 +21,7 @@ use ethereum_types::{H256, U256, Address}; use log::{trace, error}; use lru_cache::LruCache; +use ethabi_contract::use_contract; use ethcore_call_contract::CallContract; use client_traits::BlockInfo; use parking_lot::Mutex; From bac72681ffc477cf0f1c4188ff2aca41d323833e Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 17:24:51 +0200 Subject: [PATCH 13/43] Tweak docs --- ethcore/src/spec/chain.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ethcore/src/spec/chain.rs b/ethcore/src/spec/chain.rs index 7d742d47354..49d19c65e96 100644 --- a/ethcore/src/spec/chain.rs +++ b/ethcore/src/spec/chain.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//! Ethereum protocol module. -//! -//! Loads all protocols supported by parity-ethereum client. +//! Load chain specifications for all chains supported by the parity-ethereum client. macro_rules! bundle_release_spec { ($($path: expr => $name: ident), *) => { From 978eb888c42a6f982ea7e76734eda63112141d5a Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 7 Aug 2019 17:41:46 +0200 Subject: [PATCH 14/43] Add missing import --- ethcore/private-tx/tests/private_contract.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs index 6149a80e7a3..5d144e787a4 100644 --- a/ethcore/private-tx/tests/private_contract.rs +++ b/ethcore/private-tx/tests/private_contract.rs @@ -39,6 +39,7 @@ use ethcore::{ client::BlockChainClient, test_helpers::{generate_dummy_client, push_block_with_transactions}, miner::Miner, + spec, }; use ethkey::{Secret, KeyPair, Signature}; use machine::executive::contract_address; From 18d6a9465cc6be80a2798ab8f54e0197b8e0492d Mon Sep 17 00:00:00 2001 From: David Palm Date: Thu, 8 Aug 2019 14:16:15 +0200 Subject: [PATCH 15/43] remove unused ethabi_derive imports --- ethcore/machine/src/lib.rs | 4 ---- ethcore/machine/src/tx_filter.rs | 2 +- ethcore/src/lib.rs | 2 -- miner/src/lib.rs | 2 -- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/ethcore/machine/src/lib.rs b/ethcore/machine/src/lib.rs index d4059a01132..70df17860e7 100644 --- a/ethcore/machine/src/lib.rs +++ b/ethcore/machine/src/lib.rs @@ -18,10 +18,6 @@ //! code contained therein, as well as contract based transaction permissions. All ethereum //! engines embed a `Machine`. -// todo[dvdplm]: fix ethabi for use with edition 2018 -#[macro_use] -extern crate ethabi_derive; - pub mod executed; pub mod executed_block; pub mod executive; diff --git a/ethcore/machine/src/tx_filter.rs b/ethcore/machine/src/tx_filter.rs index 41c8ffd1047..b688668d408 100644 --- a/ethcore/machine/src/tx_filter.rs +++ b/ethcore/machine/src/tx_filter.rs @@ -17,11 +17,11 @@ //! Smart contract based transaction filter. use ethabi::FunctionOutputDecoder; +use ethabi_contract::use_contract; use ethereum_types::{H256, U256, Address}; use log::{trace, error}; use lru_cache::LruCache; -use ethabi_contract::use_contract; use ethcore_call_contract::CallContract; use client_traits::BlockInfo; use parking_lot::Mutex; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index fde751af5a7..7802dc4dad5 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -127,8 +127,6 @@ extern crate env_logger; #[cfg(test)] extern crate serde_json; -#[macro_use] -extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; #[macro_use] diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 2880a645c36..5204580ef22 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -40,8 +40,6 @@ extern crate serde; #[macro_use] extern crate ethabi_contract; #[macro_use] -extern crate ethabi_derive; -#[macro_use] extern crate log; #[macro_use] extern crate serde_derive; From d5700d990d53d37c6a7f85ab59bbb87e55d651bb Mon Sep 17 00:00:00 2001 From: David Palm Date: Thu, 8 Aug 2019 14:18:21 +0200 Subject: [PATCH 16/43] Use latest ethabi-contract --- Cargo.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f287dfb7dd4..6e4981535a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -811,7 +811,7 @@ dependencies = [ [[package]] name = "ethabi-contract" -version = "8.0.0" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -871,7 +871,7 @@ dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.12.0", "ethcore-accounts 0.1.0", @@ -1114,7 +1114,7 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.12.0", "ethcore-call-contract 0.1.0", @@ -1205,7 +1205,7 @@ dependencies = [ "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-call-contract 0.1.0", @@ -1249,7 +1249,7 @@ dependencies = [ "common-types 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-accounts 0.1.0", @@ -2299,7 +2299,7 @@ dependencies = [ "common-types 0.1.0", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-builtin 0.1.0", @@ -2536,7 +2536,7 @@ version = "1.12.0" dependencies = [ "common-types 0.1.0", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-io 1.12.0", @@ -2800,7 +2800,7 @@ name = "parity-hash-fetch" version = "1.12.0" dependencies = [ "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "fake-fetch 0.0.1", @@ -3009,7 +3009,7 @@ version = "1.12.0" dependencies = [ "common-types 0.1.0", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-sync 1.12.0", @@ -3611,7 +3611,7 @@ name = "registrar" version = "0.0.1" dependencies = [ "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4922,7 +4922,7 @@ dependencies = [ "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "" "checksum ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b312e5740d6e0369491ebe81a8752f7797b70e495530f28bbb7cc967ded3d77c" -"checksum ethabi-contract 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "272b7fcfada8d9b2631d75693385b505efc826752dbc7ae1815e56b35d5a3f9f" +"checksum ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e0d6314f57a5451692753696f40903bacf870adf65d452911ab6b15bf6be41f8" "checksum ethabi-derive 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "65cdef3199bf5d1821dc53b5ab992f853a13b2e28d7a63983095d9d61fae58d3" "checksum ethbloom 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3932e82d64d347a045208924002930dc105a138995ccdc1479d0f05f0359f17c" "checksum ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62d1bc682337e2c5ec98930853674dd2b4bd5d0d246933a9e98e5280f7c76c5f" From 83bb140a2517f900fce73361107adee8f8aaadae Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 9 Aug 2019 12:23:11 +0200 Subject: [PATCH 17/43] Move many traits from ethcore/client/traits to client-traits crate Initial version of extracted Engine trait --- ethcore/client-traits/Cargo.toml | 10 + ethcore/client-traits/src/lib.rs | 361 +++++++++++++++- ethcore/engine/Cargo.toml | 19 + ethcore/engine/src/engine.rs | 420 +++++++++++++++++++ ethcore/engine/src/lib.rs | 22 + ethcore/engine/src/signer.rs | 79 ++++ ethcore/machine/src/executed.rs | 106 ++--- ethcore/machine/src/executive.rs | 2 +- ethcore/src/client/client.rs | 3 +- ethcore/src/client/config.rs | 2 + ethcore/src/client/traits.rs | 15 +- ethcore/src/engines/mod.rs | 6 + ethcore/src/executive_state.rs | 3 +- ethcore/src/snapshot/consensus/mod.rs | 2 +- ethcore/src/verification/queue/kind.rs | 3 +- ethcore/types/src/engines/machine.rs | 59 ++- ethcore/types/src/engines/mod.rs | 10 + ethcore/types/src/lib.rs | 1 + ethcore/types/src/verification_queue_info.rs | 43 ++ 19 files changed, 1098 insertions(+), 68 deletions(-) create mode 100644 ethcore/engine/Cargo.toml create mode 100644 ethcore/engine/src/engine.rs create mode 100644 ethcore/engine/src/lib.rs create mode 100644 ethcore/engine/src/signer.rs diff --git a/ethcore/client-traits/Cargo.toml b/ethcore/client-traits/Cargo.toml index cbc5b1934f1..c7a8aa48a67 100644 --- a/ethcore/client-traits/Cargo.toml +++ b/ethcore/client-traits/Cargo.toml @@ -7,6 +7,16 @@ edition = "2018" license = "GPL-3.0" [dependencies] +account-state = { path = "../account-state" } +blockchain = { package = "ethcore-blockchain", path = "../blockchain" } +call-contract = { package = "ethcore-call-contract", path = "../call-contract" } ethereum-types = "0.6.0" +ethcore-db = { path = "../db" } common-types = { path = "../types" } +bytes = { package = "parity-bytes", version = "0.1.0" } +stats = { path = "../../util/stats" } +vm = { path = "../vm" } +trace = { path = "../trace" } +itertools = "0.5" # todo[dvdplm] get rid of this +ethcore-miner = { path = "../../miner" } diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs index 84b418e3bda..fbb57c11021 100644 --- a/ethcore/client-traits/src/lib.rs +++ b/ethcore/client-traits/src/lib.rs @@ -14,24 +14,361 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use ethereum_types::{Address, H256}; +use std::{ + collections::BTreeMap, + sync::Arc, +}; + +use ethereum_types::{Address, H256, U256}; +use account_state::state::StateInfo; +use blockchain::BlockProvider; +use call_contract::{CallContract, RegistryInfo}; use common_types::{ - header::Header, - encoded, - ids::BlockId, + BlockNumber, + header::Header, + encoded, + errors::EthcoreResult, + ids::{BlockId, TransactionId, TraceId, UncleId}, + engines::{ + epoch::Transition as EpochTransition, + machine::Executed, + }, + blockchain_info::BlockChainInfo, + block_status::BlockStatus, + verification_queue_info::{VerificationQueueInfo, Unverified}, //todo[dvdplm] better module name + transaction::{self, LocalizedTransaction, CallError}, + receipt::LocalizedReceipt, + tree_route::TreeRoute, + filter::Filter, + log_entry::LocalizedLogEntry, + call_analytics::CallAnalytics, + pruning_info::PruningInfo, + client_types::Mode, + trace_filter::Filter as TraceFilter, +}; +use bytes::Bytes; +use ethcore_db::keys::BlockReceipts; +use ethcore_miner::pool::VerifiedTransaction; +use stats; +use trace::{ + FlatTrace, + VMTrace, + localized::LocalizedTrace, }; +use vm::LastHashes; +use itertools::Itertools; // todo[dvdplm] get rid of this + +/// State information to be used during client query +pub enum StateOrBlock { + /// State to be used, may be pending + State(Box), + + /// Id of an existing block from a chain to get state from + Block(BlockId) +} + +impl From> for StateOrBlock { + fn from(info: Box) -> StateOrBlock { + StateOrBlock::State(info) + } +} + +impl From for StateOrBlock { + fn from(id: BlockId) -> StateOrBlock { + StateOrBlock::Block(id) + } +} + +/// Provides `nonce` and `latest_nonce` methods +pub trait Nonce { + /// Attempt to get address nonce at given block. + /// May not fail on BlockId::Latest. + fn nonce(&self, address: &Address, id: BlockId) -> Option; + + /// Get address nonce at the latest block's state. + fn latest_nonce(&self, address: &Address) -> U256 { + self.nonce(address, BlockId::Latest) + .expect("nonce will return Some when given BlockId::Latest. nonce was given BlockId::Latest. \ + Therefore nonce has returned Some; qed") + } +} + +/// Provides `balance` and `latest_balance` methods +pub trait Balance { + /// Get address balance at the given block's state. + /// + /// May not return None if given BlockId::Latest. + /// Returns None if and only if the block's root hash has been pruned from the DB. + fn balance(&self, address: &Address, state: StateOrBlock) -> Option; + + /// Get address balance at the latest block's state. + fn latest_balance(&self, address: &Address) -> U256 { + self.balance(address, BlockId::Latest.into()) + .expect("balance will return Some if given BlockId::Latest. balance was given BlockId::Latest \ + Therefore balance has returned Some; qed") + } +} + +/// Provides methods to access account info +pub trait AccountData: Nonce + Balance {} + +/// Provides `chain_info` method +pub trait ChainInfo { + /// Get blockchain information. + fn chain_info(&self) -> BlockChainInfo; +} /// Provides various information on a block by it's ID pub trait BlockInfo { - /// Get raw block header data by block id. - fn block_header(&self, id: BlockId) -> Option; + /// Get raw block header data by block id. + fn block_header(&self, id: BlockId) -> Option; + + /// Get the best block header. + fn best_block_header(&self) -> Header; + + /// Get raw block data by block header hash. + fn block(&self, id: BlockId) -> Option; + + /// Get address code hash at given block's state. + fn code_hash(&self, address: &Address, id: BlockId) -> Option; +} + +/// Provides various information on a transaction by it's ID +pub trait TransactionInfo { + /// Get the hash of block that contains the transaction, if any. + fn transaction_block(&self, id: TransactionId) -> Option; +} + +/// Provides various blockchain information, like block header, chain state etc. +pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {} + +/// Client facilities used by internally sealing Engines. +pub trait EngineClient: Sync + Send + ChainInfo { + /// Make a new block and seal it. + fn update_sealing(&self); + + /// Submit a seal for a block in the mining queue. + fn submit_seal(&self, block_hash: H256, seal: Vec); + + /// Broadcast a consensus message to the network. + fn broadcast_consensus_message(&self, message: Bytes); + + /// Get the transition to the epoch the given parent hash is part of + /// or transitions to. + /// This will give the epoch that any children of this parent belong to. + /// + /// The block corresponding the the parent hash must be stored already. + fn epoch_transition_for(&self, parent_hash: H256) -> Option; + + /// Attempt to cast the engine client to a full client. + fn as_full_client(&self) -> Option<&dyn BlockChainClient>; + + /// Get a block number by ID. + fn block_number(&self, id: BlockId) -> Option; + + /// Get raw block header data by block id. + fn block_header(&self, id: BlockId) -> Option; +} + +// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient? +/// Provides methods to import block into blockchain +pub trait ImportBlock { + /// Import a block into the blockchain. + fn import_block(&self, block: Unverified) -> EthcoreResult; +} + +/// IO operations that should off-load heavy work to another thread. +pub trait IoClient: Sync + Send { + /// Queue transactions for importing. + fn queue_transactions(&self, transactions: Vec, peer_id: usize); + + /// Queue block import with transaction receipts. Does no sealing and transaction validation. + fn queue_ancient_block(&self, block_bytes: Unverified, receipts_bytes: Bytes) -> EthcoreResult; + + /// Queue consensus engine message. + fn queue_consensus_message(&self, message: Bytes); +} + +/// Provides recently seen bad blocks. +pub trait BadBlocks { + /// Returns a list of blocks that were recently not imported because they were invalid. + fn bad_blocks(&self) -> Vec<(Unverified, String)>; +} + + +/// Blockchain database client. Owns and manages a blockchain and a block queue. +pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContract + RegistryInfo + ImportBlock ++ IoClient + BadBlocks { + /// Look up the block number for the given block ID. + fn block_number(&self, id: BlockId) -> Option; + + /// Get raw block body data by block id. + /// Block body is an RLP list of two items: uncles and transactions. + fn block_body(&self, id: BlockId) -> Option; + + /// Get block status by block header hash. + fn block_status(&self, id: BlockId) -> BlockStatus; + + /// Get block total difficulty. + fn block_total_difficulty(&self, id: BlockId) -> Option; + + /// Attempt to get address storage root at given block. + /// May not fail on BlockId::Latest. + fn storage_root(&self, address: &Address, id: BlockId) -> Option; + + /// Get block hash. + fn block_hash(&self, id: BlockId) -> Option; + + /// Get address code at given block's state. + fn code(&self, address: &Address, state: StateOrBlock) -> Option>; + + /// Get address code at the latest block's state. + fn latest_code(&self, address: &Address) -> Option { + self.code(address, BlockId::Latest.into()) + .expect("code will return Some if given BlockId::Latest; qed") + } + + /// Get a reference to the `BlockProvider`. + fn chain(&self) -> Arc; + + /// Get block queue information. + fn queue_info(&self) -> VerificationQueueInfo; + + /// Get address code hash at given block's state. + + /// Get value of the storage at given position at the given block's state. + /// + /// May not return None if given BlockId::Latest. + /// Returns None if and only if the block's root hash has been pruned from the DB. + fn storage_at(&self, address: &Address, position: &H256, state: StateOrBlock) -> Option; + + /// Get value of the storage at given position at the latest block's state. + fn latest_storage_at(&self, address: &Address, position: &H256) -> H256 { + self.storage_at(address, position, BlockId::Latest.into()) + .expect("storage_at will return Some if given BlockId::Latest. storage_at was given BlockId::Latest. \ + Therefore storage_at has returned Some; qed") + } + + /// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`. + /// If `after` is set the list starts with the following item. + fn list_accounts(&self, id: BlockId, after: Option<&Address>, count: u64) -> Option>; + + /// Get a list of all storage keys in the block `id`, if fat DB is in operation, otherwise `None`. + /// If `after` is set the list starts with the following item. + fn list_storage(&self, id: BlockId, account: &Address, after: Option<&H256>, count: u64) -> Option>; + + /// Get transaction with given hash. + fn transaction(&self, id: TransactionId) -> Option; + + /// Get uncle with given id. + fn uncle(&self, id: UncleId) -> Option; + + /// Get transaction receipt with given hash. + fn transaction_receipt(&self, id: TransactionId) -> Option; + + /// Get localized receipts for all transaction in given block. + fn localized_block_receipts(&self, id: BlockId) -> Option>; + + /// Get a tree route between `from` and `to`. + /// See `BlockChain::tree_route`. + fn tree_route(&self, from: &H256, to: &H256) -> Option; + + /// Get all possible uncle hashes for a block. + fn find_uncles(&self, hash: &H256) -> Option>; + + /// Get latest state node + fn state_data(&self, hash: &H256) -> Option; + + /// Get block receipts data by block header hash. + fn block_receipts(&self, hash: &H256) -> Option; + + /// Returns true if block queue is empty. + fn is_queue_empty(&self) -> bool { + self.queue_info().is_empty() + } + + /// Clear block queue and abort all import activity. + fn clear_queue(&self); + + /// Returns logs matching given filter. If one of the filtering block cannot be found, returns the block id that caused the error. + fn logs(&self, filter: Filter) -> Result, BlockId>; + + /// Replays a given transaction for inspection. + fn replay(&self, t: TransactionId, analytics: CallAnalytics) -> Result, CallError>; + + /// Replays all the transactions in a given block for inspection. + fn replay_block_transactions(&self, block: BlockId, analytics: CallAnalytics) -> Result)>>, CallError>; + + /// Returns traces matching given filter. + fn filter_traces(&self, filter: TraceFilter) -> Option>; + + /// Returns trace with given id. + fn trace(&self, trace: TraceId) -> Option; + + /// Returns traces created by transaction. + fn transaction_traces(&self, trace: TransactionId) -> Option>; + + /// Returns traces created by transaction from block. + fn block_traces(&self, trace: BlockId) -> Option>; + + /// Get last hashes starting from best block. + fn last_hashes(&self) -> LastHashes; + + /// List all ready transactions that should be propagated to other peers. + fn transactions_to_propagate(&self) -> Vec>; + + /// Sorted list of transaction gas prices from at least last sample_size blocks. + fn gas_price_corpus(&self, sample_size: usize) -> stats::Corpus { + let mut h = self.chain_info().best_block_hash; + let mut corpus = Vec::new(); + while corpus.is_empty() { + for _ in 0..sample_size { + let block = match self.block(BlockId::Hash(h)) { + Some(block) => block, + None => return corpus.into(), + }; + + if block.number() == 0 { + return corpus.into(); + } + block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price())); + h = block.parent_hash().clone(); + } + } + corpus.into() + } + + /// Get the preferred chain ID to sign on + fn signing_chain_id(&self) -> Option; + + /// Get the mode. + fn mode(&self) -> Mode; + + /// Set the mode. + fn set_mode(&self, mode: Mode); + + /// Get the chain spec name. + fn spec_name(&self) -> String; + + /// Set the chain via a spec name. + fn set_spec_name(&self, spec_name: String) -> Result<(), ()>; + + /// Disable the client from importing blocks. This cannot be undone in this session and indicates + /// that a subsystem has reason to believe this executable incapable of syncing the chain. + fn disable(&self); + + /// Returns engine-related extra info for `BlockId`. + fn block_extra_info(&self, id: BlockId) -> Option>; + + /// Returns engine-related extra info for `UncleId`. + fn uncle_extra_info(&self, id: UncleId) -> Option>; - /// Get the best block header. - fn best_block_header(&self) -> Header; + /// Returns information about pruning/data availability. + fn pruning_info(&self) -> PruningInfo; - /// Get raw block data by block header hash. - fn block(&self, id: BlockId) -> Option; + /// Schedule state-altering transaction to be executed on the next pending block. + fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error>; - /// Get address code hash at given block's state. - fn code_hash(&self, address: &Address, id: BlockId) -> Option; + /// Get the address of the registry itself. + fn registrar_address(&self) -> Option
; } diff --git a/ethcore/engine/Cargo.toml b/ethcore/engine/Cargo.toml new file mode 100644 index 00000000000..cee2c811bbf --- /dev/null +++ b/ethcore/engine/Cargo.toml @@ -0,0 +1,19 @@ +[package] +description = "Ethereum engine trai definition" +name = "engine" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" + +[dependencies] +client-traits = { path = "../client-traits" } +common-types = { path = "../types" } +builtin = { path = "../builtin", package = "ethcore-builtin" } +ethereum-types = "0.6.0" +ethkey = { path = "../../accounts/ethkey" } +machine = { path = "../machine" } +bytes = { package = "parity-bytes", version = "0.1.0" } +vm = { path = "../vm" } + + diff --git a/ethcore/engine/src/engine.rs b/ethcore/engine/src/engine.rs new file mode 100644 index 00000000000..5ed665ee123 --- /dev/null +++ b/ethcore/engine/src/engine.rs @@ -0,0 +1,420 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Consensus engine specification and basic implementations. + +use std::sync::{Weak, Arc}; +use std::collections::BTreeMap; + +use builtin::Builtin; +use common_types::{ + BlockNumber, + ancestry_action::AncestryAction, + header::{Header, ExtendedHeader}, + engines::{ + Seal, SealingState, Headers, PendingTransitionStore, + params::CommonParams, + machine as machine_types, + machine::{AuxiliaryData, AuxiliaryRequest}, + }, + errors::{EthcoreError as Error, EngineError}, + transaction::{self, UnverifiedTransaction}, +}; +//use snapshot::SnapshotComponents; //todo +use client_traits::EngineClient; + +use ethereum_types::{H256, U256, Address}; +use ethkey::Signature; +use machine::{ + Machine, + executed_block::ExecutedBlock, +}; +use vm::{EnvInfo, Schedule, CallType, ActionValue}; + +use crate::signer::EngineSigner; + +/// A system-calling closure. Enacts calls on a block's state from the system address. +pub type SystemCall<'a> = dyn FnMut(Address, Vec) -> Result, String> + 'a; + +/// A system-calling closure. Enacts calls on a block's state with code either from an on-chain contract, or hard-coded EVM or WASM (if enabled on-chain) codes. +pub type SystemOrCodeCall<'a> = dyn FnMut(SystemOrCodeCallKind, Vec) -> Result, String> + 'a; + +/// Kind of SystemOrCodeCall, this is either an on-chain address, or code. +#[derive(PartialEq, Debug, Clone)] +pub enum SystemOrCodeCallKind { + /// On-chain address. + Address(Address), + /// Hard-coded code. + Code(Arc>, H256), +} + +/// Default SystemOrCodeCall implementation. +pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut ExecutedBlock) -> impl FnMut(SystemOrCodeCallKind, Vec) -> Result, String> + 'a { + move |to, data| { + let result = match to { + SystemOrCodeCallKind::Address(address) => { + machine.execute_as_system( + block, + address, + U256::max_value(), + Some(data), + ) + }, + SystemOrCodeCallKind::Code(code, code_hash) => { + machine.execute_code_as_system( + block, + None, + Some(code), + Some(code_hash), + Some(ActionValue::Apparent(U256::zero())), + U256::max_value(), + Some(data), + Some(CallType::StaticCall), + ) + }, + }; + + result.map_err(|e| format!("{}", e)) + } +} + +/// Proof dependent on state. +pub trait StateDependentProof: Send + Sync { + /// Generate a proof, given the state. + fn generate_proof<'a>(&self, state: &machine_types::Call) -> Result, String>; + /// Check a proof generated elsewhere (potentially by a peer). + // `engine` needed to check state proofs, while really this should + // just be state machine params. + fn check_proof(&self, machine: &Machine, proof: &[u8]) -> Result<(), String>; +} + +/// Proof generated on epoch change. +pub enum Proof { + /// Known proof (extracted from signal) + Known(Vec), + /// State dependent proof. + WithState(Arc), +} + +/// Generated epoch verifier. +pub enum ConstructedVerifier<'a> { + /// Fully trusted verifier. + Trusted(Box), + /// Verifier unconfirmed. Check whether given finality proof finalizes given hash + /// under previous epoch. + Unconfirmed(Box, &'a [u8], H256), + /// Error constructing verifier. + Err(Error), +} + +impl<'a> ConstructedVerifier<'a> { + /// Convert to a result, indicating that any necessary confirmation has been done + /// already. + pub fn known_confirmed(self) -> Result, Error> { + match self { + ConstructedVerifier::Trusted(v) | ConstructedVerifier::Unconfirmed(v, _, _) => Ok(v), + ConstructedVerifier::Err(e) => Err(e), + } + } +} + +/// Results of a query of whether an epoch change occurred at the given block. +pub enum EpochChange { + /// Cannot determine until more data is passed. + Unsure(AuxiliaryRequest), + /// No epoch change. + No, + /// The epoch will change, with proof. + Yes(Proof), +} + +/// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. +/// Provides hooks into each of the major parts of block import. +pub trait Engine: Sync + Send { + /// The name of this engine. + fn name(&self) -> &str; + + /// Get access to the underlying state machine. + // TODO: decouple. + fn machine(&self) -> &Machine; + + /// The number of additional header fields required for this engine. + fn seal_fields(&self, _header: &Header) -> usize { 0 } + + /// Additional engine-specific information for the user/developer concerning `header`. + fn extra_info(&self, _header: &Header) -> BTreeMap { BTreeMap::new() } + + /// Maximum number of uncles a block is allowed to declare. + fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 } + + /// Optional maximum gas limit. + fn maximum_gas_limit(&self) -> Option { None } + + /// Block transformation functions, before the transactions. + /// `epoch_begin` set to true if this block kicks off an epoch. + fn on_new_block( + &self, + _block: &mut ExecutedBlock, + _epoch_begin: bool, + ) -> Result<(), Error> { + Ok(()) + } + + /// Block transformation functions, after the transactions. + fn on_close_block( + &self, + _block: &mut ExecutedBlock, + _parent_header: &Header, + ) -> Result<(), Error> { + Ok(()) + } + + /// Allow mutating the header during seal generation. Currently only used by Clique. + fn on_seal_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { Ok(()) } + + /// Returns the engine's current sealing state. + fn sealing_state(&self) -> SealingState { SealingState::External } + + /// Attempt to seal the block internally. + /// + /// If `Some` is returned, then you get a valid seal. + /// + /// This operation is synchronous and may (quite reasonably) not be available, in which None will + /// be returned. + /// + /// It is fine to require access to state or a full client for this function, since + /// light clients do not generate seals. + fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None } + + /// Verify a locally-generated seal of a header. + /// + /// If this engine seals internally, + /// no checks have to be done here, since all internally generated seals + /// should be valid. + /// + /// Externally-generated seals (e.g. PoW) will need to be checked for validity. + /// + /// It is fine to require access to state or a full client for this function, since + /// light clients do not generate seals. + fn verify_local_seal(&self, header: &Header) -> Result<(), Error>; + + /// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import. + /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. + fn verify_block_basic(&self, _header: &Header) -> Result<(), Error> { Ok(()) } + + /// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import. + /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. + fn verify_block_unordered(&self, _header: &Header) -> Result<(), Error> { Ok(()) } + + /// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import. + fn verify_block_family(&self, _header: &Header, _parent: &Header) -> Result<(), Error> { Ok(()) } + + /// Phase 4 verification. Verify block header against potentially external data. + /// Should only be called when `register_client` has been called previously. + fn verify_block_external(&self, _header: &Header) -> Result<(), Error> { Ok(()) } + + /// Genesis epoch data. + fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine_types::Call) -> Result, String> { Ok(Vec::new()) } + + /// Whether an epoch change is signalled at the given header but will require finality. + /// If a change can be enacted immediately then return `No` from this function but + /// `Yes` from `is_epoch_end`. + /// + /// If auxiliary data of the block is required, return an auxiliary request and the function will be + /// called again with them. + /// Return `Yes` or `No` when the answer is definitively known. + /// + /// Should not interact with state. + fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange { + EpochChange::No + } + + /// Whether a block is the end of an epoch. + /// + /// This either means that an immediate transition occurs or a block signalling transition + /// has reached finality. The `Headers` given are not guaranteed to return any blocks + /// from any epoch other than the current. The client must keep track of finality and provide + /// the latest finalized headers to check against the transition store. + /// + /// Return optional transition proof. + fn is_epoch_end( + &self, + _chain_head: &Header, + _finalized: &[H256], + _chain: &Headers
, + _transition_store: &PendingTransitionStore, + ) -> Option> { + None + } + + /// Whether a block is the end of an epoch. + /// + /// This either means that an immediate transition occurs or a block signalling transition + /// has reached finality. The `Headers` given are not guaranteed to return any blocks + /// from any epoch other than the current. This is a specialized method to use for light + /// clients since the light client doesn't track finality of all blocks, and therefore finality + /// for blocks in the current epoch is built inside this method by the engine. + /// + /// Return optional transition proof. + fn is_epoch_end_light( + &self, + _chain_head: &Header, + _chain: &Headers
, + _transition_store: &PendingTransitionStore, + ) -> Option> { + None + } + + /// Create an epoch verifier from validation proof and a flag indicating + /// whether finality is required. + fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> ConstructedVerifier<'a> { + ConstructedVerifier::Trusted(Box::new(NoOp)) + } + + /// Populate a header's fields based on its parent's header. + /// Usually implements the chain scoring rule based on weight. + fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) { } + + /// Handle any potential consensus messages; + /// updating consensus state and potentially issuing a new one. + fn handle_message(&self, _message: &[u8]) -> Result<(), EngineError> { Err(EngineError::UnexpectedMessage) } + + /// Register a component which signs consensus messages. + fn set_signer(&self, _signer: Box) {} + + /// Sign using the EngineSigner, to be used for consensus tx signing. + fn sign(&self, _hash: H256) -> Result { unimplemented!() } + + /// Add Client which can be used for sealing, potentially querying the state and sending messages. + fn register_client(&self, _client: Weak) {} + + /// Trigger next step of the consensus engine. + fn step(&self) {} + + // todo[dvdplm] sort out this mess: SnapshotComponents depends on Rebuilder and that depends on Engine + /// Create a factory for building snapshot chunks and restoring from them. + /// Returning `None` indicates that this engine doesn't support snapshot creation. +// fn snapshot_components(&self) -> Option> { +// None +// } + fn snapshot_components(&self) -> Option { None } + + /// Whether this engine supports warp sync. + fn supports_warp(&self) -> bool { + self.snapshot_components().is_some() + } + + /// Return a new open block header timestamp based on the parent timestamp. + fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 { + use std::{time, cmp}; + + let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default(); + cmp::max(now.as_secs() as u64, parent_timestamp + 1) + } + + /// Check whether the parent timestamp is valid. + fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { + header_timestamp > parent_timestamp + } + + /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that + /// the ancestry exists. + fn ancestry_actions(&self, _header: &Header, _ancestry: &mut dyn Iterator) -> Vec { + Vec::new() + } + + /// Returns author should used when executing tx's for this block. + fn executive_author(&self, header: &Header) -> Result { + Ok(*header.author()) + } + + /// Get the general parameters of the chain. + fn params(&self) -> &CommonParams; + + /// Get the EVM schedule for the given block number. + fn schedule(&self, block_number: BlockNumber) -> Schedule { + self.machine().schedule(block_number) + } + + /// Builtin-contracts for the chain.. + fn builtins(&self) -> &BTreeMap { + self.machine().builtins() + } + + /// Attempt to get a handle to a built-in contract. + /// Only returns references to activated built-ins. + fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> { + self.machine().builtin(a, block_number) + } + + /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. + fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size } + + /// The nonce with which accounts begin at given block. + fn account_start_nonce(&self, block: BlockNumber) -> U256 { + self.machine().account_start_nonce(block) + } + + /// The network ID that transactions should be signed with. + fn signing_chain_id(&self, env_info: &EnvInfo) -> Option { + self.machine().signing_chain_id(env_info) + } + + /// Perform basic/cheap transaction verification. + /// + /// This should include all cheap checks that can be done before + /// actually checking the signature, like chain-replay protection. + /// + /// NOTE This is done before the signature is recovered so avoid + /// doing any state-touching checks that might be expensive. + /// + /// TODO: Add flags for which bits of the transaction to check. + /// TODO: consider including State in the params. + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> { + self.machine().verify_transaction_basic(t, header) + } + + /// Performs pre-validation of RLP decoded transaction before other processing + fn decode_transaction(&self, transaction: &[u8]) -> Result { + self.machine().decode_transaction(transaction) + } +} + +/// Verifier for all blocks within an epoch with self-contained state. +pub trait EpochVerifier: Send + Sync { + /// Lightly verify the next block header. + /// This may not be a header belonging to a different epoch. + fn verify_light(&self, header: &Header) -> Result<(), Error>; + + /// Perform potentially heavier checks on the next block header. + fn verify_heavy(&self, header: &Header) -> Result<(), Error> { + self.verify_light(header) + } + + /// Check a finality proof against this epoch verifier. + /// Returns `Some(hashes)` if the proof proves finality of these hashes. + /// Returns `None` if the proof doesn't prove anything. + fn check_finality_proof(&self, _proof: &[u8]) -> Option> { + None + } +} + +/// Special "no-op" verifier for stateless, epoch-less engines. +pub struct NoOp; + +impl EpochVerifier for NoOp { + fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } +} diff --git a/ethcore/engine/src/lib.rs b/ethcore/engine/src/lib.rs new file mode 100644 index 00000000000..904f81231ec --- /dev/null +++ b/ethcore/engine/src/lib.rs @@ -0,0 +1,22 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +// todo[dvdplm]: docs +//! This crate + +// todo[dvdplm] do we need all of this exported? +pub mod engine; +pub mod signer; diff --git a/ethcore/engine/src/signer.rs b/ethcore/engine/src/signer.rs new file mode 100644 index 00000000000..196c535fe76 --- /dev/null +++ b/ethcore/engine/src/signer.rs @@ -0,0 +1,79 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! A signer used by Engines which need to sign messages. + +use ethereum_types::{H256, Address}; +use ethkey::{self, Signature}; + +/// Everything that an Engine needs to sign messages. +pub trait EngineSigner: Send + Sync { + /// Sign a consensus message hash. + fn sign(&self, hash: H256) -> Result; + + /// Signing address + fn address(&self) -> Address; +} + +/// Creates a new `EngineSigner` from given key pair. +pub fn from_keypair(keypair: ethkey::KeyPair) -> Box { + Box::new(Signer(keypair)) +} + +struct Signer(ethkey::KeyPair); + +impl EngineSigner for Signer { + fn sign(&self, hash: H256) -> Result { + ethkey::sign(self.0.secret(), &hash) + } + + fn address(&self) -> Address { + self.0.address() + } +} + +#[cfg(test)] +mod test_signer { + use std::sync::Arc; + + use ethkey::Password; + use accounts::{self, AccountProvider, SignError}; + + use super::*; + + impl EngineSigner for (Arc, Address, Password) { + fn sign(&self, hash: H256) -> Result { + match self.0.sign(self.1, Some(self.2.clone()), hash) { + Err(SignError::NotUnlocked) => unreachable!(), + Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress), + Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err), + Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => { + warn!("Low level crypto error: {:?}", err); + Err(ethkey::Error::InvalidSecret) + }, + Err(SignError::SStore(err)) => { + warn!("Error signing for engine: {:?}", err); + Err(ethkey::Error::InvalidSignature) + }, + Ok(ok) => Ok(ok), + } + } + + fn address(&self) -> Address { + self.1 + } + } +} diff --git a/ethcore/machine/src/executed.rs b/ethcore/machine/src/executed.rs index 42c165bcb96..a7aede7abd3 100644 --- a/ethcore/machine/src/executed.rs +++ b/ethcore/machine/src/executed.rs @@ -16,58 +16,68 @@ //! Transaction execution format module. -use ethereum_types::{U256, Address}; -use parity_bytes::Bytes; -use vm; use trace::{VMTrace, FlatTrace}; use common_types::{ - state_diff::StateDiff, - log_entry::LogEntry, + engines::machine, errors::ExecutionError, }; - -/// Transaction execution receipt. -#[derive(Debug, PartialEq, Clone)] -pub struct Executed { - /// True if the outer call/create resulted in an exceptional exit. - pub exception: Option, - - /// Gas paid up front for execution of transaction. - pub gas: U256, - - /// Gas used during execution of transaction. - pub gas_used: U256, - - /// Gas refunded after the execution of transaction. - /// To get gas that was required up front, add `refunded` and `gas_used`. - pub refunded: U256, - - /// Cumulative gas used in current block so far. - /// - /// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)` - /// - /// where `tn` is current transaction. - pub cumulative_gas_used: U256, - - /// Vector of logs generated by transaction. - pub logs: Vec, - - /// Addresses of contracts created during execution of transaction. - /// Ordered from earliest creation. - /// - /// eg. sender creates contract A and A in constructor creates contract B - /// - /// B creation ends first, and it will be the first element of the vector. - pub contracts_created: Vec
, - /// Transaction output. - pub output: Bytes, - /// The trace of this transaction. - pub trace: Vec, - /// The VM trace of this transaction. - pub vm_trace: Option, - /// The state diff, if we traced it. - pub state_diff: Option, -} +pub type Executed = machine::Executed; /// Transaction execution result. pub type ExecutionResult = Result, ExecutionError>; + +//use ethereum_types::{U256, Address}; +//use parity_bytes::Bytes; +//use vm; +//use trace::{VMTrace, FlatTrace}; +//use common_types::{ +// state_diff::StateDiff, +// log_entry::LogEntry, +// errors::ExecutionError, +//}; +// +///// Transaction execution receipt. +//#[derive(Debug, PartialEq, Clone)] +//pub struct Executed { +// /// True if the outer call/create resulted in an exceptional exit. +// pub exception: Option, +// +// /// Gas paid up front for execution of transaction. +// pub gas: U256, +// +// /// Gas used during execution of transaction. +// pub gas_used: U256, +// +// /// Gas refunded after the execution of transaction. +// /// To get gas that was required up front, add `refunded` and `gas_used`. +// pub refunded: U256, +// +// /// Cumulative gas used in current block so far. +// /// +// /// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)` +// /// +// /// where `tn` is current transaction. +// pub cumulative_gas_used: U256, +// +// /// Vector of logs generated by transaction. +// pub logs: Vec, +// +// /// Addresses of contracts created during execution of transaction. +// /// Ordered from earliest creation. +// /// +// /// eg. sender creates contract A and A in constructor creates contract B +// /// +// /// B creation ends first, and it will be the first element of the vector. +// pub contracts_created: Vec
, +// /// Transaction output. +// pub output: Bytes, +// /// The trace of this transaction. +// pub trace: Vec, +// /// The VM trace of this transaction. +// pub vm_trace: Option, +// /// The state diff, if we traced it. +// pub state_diff: Option, +//} +// +///// Transaction execution result. +//pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/machine/src/executive.rs b/ethcore/machine/src/executive.rs index c49562dce3a..7e9de19f28c 100644 --- a/ethcore/machine/src/executive.rs +++ b/ethcore/machine/src/executive.rs @@ -36,6 +36,7 @@ use trace::{self, Tracer, VMTracer}; use common_types::{ errors::ExecutionError, transaction::{Action, SignedTransaction}, + engines::machine::Executed, }; use crate::{ @@ -43,7 +44,6 @@ use crate::{ substate::Substate, externalities::{Externalities, OutputPolicy, OriginInfo}, // todo: make explicit transaction_ext::Transaction, - executed::Executed, }; #[cfg(debug_assertions)] diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 207a92da03b..55f51e04321 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1275,6 +1275,7 @@ impl Client { t: &SignedTransaction, analytics: CallAnalytics, ) -> Result { + use types::engines::machine::Executed as RawExecuted; //todo[dvdplm] better name fn call( state: &mut State, env_info: &EnvInfo, @@ -1282,7 +1283,7 @@ impl Client { state_diff: bool, transaction: &SignedTransaction, options: TransactOptions, - ) -> Result, CallError> where + ) -> Result, CallError> where T: trace::Tracer, V: trace::VMTracer, { diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index 59fc4f8135e..a821ebf607e 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -56,6 +56,7 @@ impl FromStr for DatabaseCompactionProfile { } } +//todo[dvdplm] moved /// Operating mode for the client. #[derive(Debug, Eq, PartialEq, Clone)] pub enum Mode { @@ -71,6 +72,7 @@ pub enum Mode { Off, } +//todo[dvdplm] moved impl Display for Mode { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { match *self { diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index ccb7d38a716..dfc54e23061 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -53,8 +53,9 @@ use engines::Engine; use machine::executed::Executed; use account_state::state::StateInfo; use trace::LocalizedTrace; -use verification::queue::kind::blocks::Unverified; // todo this is reexported from common_types +use verification::queue::kind::blocks::Unverified; +//todo[dvdplm] moved /// State information to be used during client query pub enum StateOrBlock { /// State to be used, may be pending @@ -64,18 +65,21 @@ pub enum StateOrBlock { Block(BlockId) } +//todo[dvdplm] moved impl From> for StateOrBlock { fn from(info: Box) -> StateOrBlock { StateOrBlock::State(info) } } +//todo[dvdplm] moved impl From for StateOrBlock { fn from(id: BlockId) -> StateOrBlock { StateOrBlock::Block(id) } } +//todo[dvdplm] moved /// Provides `nonce` and `latest_nonce` methods pub trait Nonce { /// Attempt to get address nonce at given block. @@ -90,6 +94,7 @@ pub trait Nonce { } } +//todo[dvdplm] moved /// Provides `balance` and `latest_balance` methods pub trait Balance { /// Get address balance at the given block's state. @@ -106,15 +111,18 @@ pub trait Balance { } } +//todo[dvdplm] moved /// Provides methods to access account info pub trait AccountData: Nonce + Balance {} +//todo[dvdplm] moved /// Provides `chain_info` method pub trait ChainInfo { /// Get blockchain information. fn chain_info(&self) -> BlockChainInfo; } +//todo[dvdplm] moved /// Provides various information on a transaction by it's ID pub trait TransactionInfo { /// Get the hash of block that contains the transaction, if any. @@ -137,9 +145,11 @@ pub trait StateClient { fn state_at(&self, id: BlockId) -> Option; } +//todo[dvdplm] moved /// Provides various blockchain information, like block header, chain state etc. pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {} +// todo[dvdplm]: moved // FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient? /// Provides methods to import block into blockchain pub trait ImportBlock { @@ -169,6 +179,7 @@ pub trait EngineInfo { fn engine(&self) -> &dyn Engine; } +// todo[dvdplm]: moved /// IO operations that should off-load heavy work to another thread. pub trait IoClient: Sync + Send { /// Queue transactions for importing. @@ -181,6 +192,7 @@ pub trait IoClient: Sync + Send { fn queue_consensus_message(&self, message: Bytes); } +// todo[dvdplm]: moved /// Provides recently seen bad blocks. pub trait BadBlocks { /// Returns a list of blocks that were recently not imported because they were invalid. @@ -404,6 +416,7 @@ pub trait BroadcastProposalBlock { /// Provides methods to import sealed block and broadcast a block proposal pub trait SealedBlockImporter: ImportSealedBlock + BroadcastProposalBlock {} +// todo[dvdplm] moved /// Client facilities used by internally sealing Engines. pub trait EngineClient: Sync + Send + ChainInfo { /// Make a new block and seal it. diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index b5391c0b226..65976dd89c9 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -68,6 +68,7 @@ use machine::{ use ethereum_types::{H256, U256, Address}; use bytes::Bytes; +// todo[dvdplm] remove /// Seal type. #[derive(Debug, PartialEq, Eq)] pub enum Seal { @@ -122,6 +123,7 @@ pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut Exec } } +// todo[dvdplm] moved /// Proof dependent on state. pub trait StateDependentProof: Send + Sync { /// Generate a proof, given the state. @@ -132,6 +134,7 @@ pub trait StateDependentProof: Send + Sync { fn check_proof(&self, machine: &Machine, proof: &[u8]) -> Result<(), String>; } +// todo[dvdplm] moved /// Proof generated on epoch change. pub enum Proof { /// Known proof (extracted from signal) @@ -140,6 +143,7 @@ pub enum Proof { WithState(Arc), } +// todo[dvdplm] moved /// Generated epoch verifier. pub enum ConstructedVerifier<'a> { /// Fully trusted verifier. @@ -151,6 +155,7 @@ pub enum ConstructedVerifier<'a> { Err(Error), } +// todo[dvdplm] moved impl<'a> ConstructedVerifier<'a> { /// Convert to a result, indicating that any necessary confirmation has been done /// already. @@ -162,6 +167,7 @@ impl<'a> ConstructedVerifier<'a> { } } +// todo[dvdplm] moved /// Results of a query of whether an epoch change occurred at the given block. pub enum EpochChange { /// Cannot determine until more data is passed. diff --git a/ethcore/src/executive_state.rs b/ethcore/src/executive_state.rs index 02f6ffa8cd0..0ab16bf5239 100644 --- a/ethcore/src/executive_state.rs +++ b/ethcore/src/executive_state.rs @@ -25,6 +25,7 @@ use machine::{ }; use vm::EnvInfo; use types::{ + engines::machine::Executed as RawExecuted, errors::{ExecutionError, EthcoreError as Error}, transaction::SignedTransaction, receipt::{TransactionOutcome, Receipt}, @@ -242,7 +243,7 @@ fn execute( t: &SignedTransaction, options: TransactOptions, virt: bool -) -> Result, ExecutionError> +) -> Result, ExecutionError> where B: Backend, T: trace::Tracer, diff --git a/ethcore/src/snapshot/consensus/mod.rs b/ethcore/src/snapshot/consensus/mod.rs index 102acdeca2a..d9c9cc8017d 100644 --- a/ethcore/src/snapshot/consensus/mod.rs +++ b/ethcore/src/snapshot/consensus/mod.rs @@ -54,7 +54,7 @@ pub trait SnapshotComponents: Send { preferred_size: usize, ) -> Result<(), SnapshotError>; - /// Create a rebuilder, which will have chunks fed into it in aribtrary + /// Create a rebuilder, which will have chunks fed into it in arbitrary /// order and then be finalized. /// /// The manifest, a database, and fresh `BlockChain` are supplied. diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 106759ca3af..562290c2475 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -116,6 +116,7 @@ pub mod blocks { } } + // todo[dvdplm] moved to common-types /// An unverified block. #[derive(PartialEq, Debug, MallocSizeOf)] pub struct Unverified { @@ -128,7 +129,7 @@ pub mod blocks { /// Raw block bytes. pub bytes: Bytes, } - + // todo[dvdplm] moved to common-types impl Unverified { /// Create an `Unverified` from raw bytes. pub fn from_rlp(bytes: Bytes) -> Result { diff --git a/ethcore/types/src/engines/machine.rs b/ethcore/types/src/engines/machine.rs index be0a5ef9c01..6a238c0c486 100644 --- a/ethcore/types/src/engines/machine.rs +++ b/ethcore/types/src/engines/machine.rs @@ -16,9 +16,16 @@ //! State machine types -use ethereum_types::Address; +use ethereum_types::{Address, U256}; +use bytes::Bytes; +//use trace::{VMTrace, FlatTrace}; -use crate::receipt; +use crate::{ + log_entry::LogEntry, + receipt, + state_diff::StateDiff, + errors::ExecutionError, +}; /// Type alias for a function we can make calls through synchronously. /// Returns the call result and state proof for each call. @@ -44,3 +51,51 @@ pub struct AuxiliaryData<'a> { /// The block receipts. pub receipts: Option<&'a [receipt::Receipt]>, } + + +/// Transaction execution receipt. +#[derive(Debug, PartialEq, Clone)] +//pub struct Executed { +pub struct Executed { + /// True if the outer call/create resulted in an exceptional exit. + pub exception: Option, + + /// Gas paid up front for execution of transaction. + pub gas: U256, + + /// Gas used during execution of transaction. + pub gas_used: U256, + + /// Gas refunded after the execution of transaction. + /// To get gas that was required up front, add `refunded` and `gas_used`. + pub refunded: U256, + + /// Cumulative gas used in current block so far. + /// + /// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)` + /// + /// where `tn` is current transaction. + pub cumulative_gas_used: U256, + + /// Vector of logs generated by transaction. + pub logs: Vec, + + /// Addresses of contracts created during execution of transaction. + /// Ordered from earliest creation. + /// + /// eg. sender creates contract A and A in constructor creates contract B + /// + /// B creation ends first, and it will be the first element of the vector. + pub contracts_created: Vec
, + /// Transaction output. + pub output: Bytes, + /// The trace of this transaction. + pub trace: Vec, + /// The VM trace of this transaction. + pub vm_trace: Option, + /// The state diff, if we traced it. + pub state_diff: Option, +} + +///// Transaction execution result. +//pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/types/src/engines/mod.rs b/ethcore/types/src/engines/mod.rs index ac8a20d290d..3a1564b9ab1 100644 --- a/ethcore/types/src/engines/mod.rs +++ b/ethcore/types/src/engines/mod.rs @@ -17,6 +17,7 @@ //! Engine-specific types. use ethereum_types::{Address, H256}; +use bytes::Bytes; use ethjson; use crate::BlockNumber; @@ -25,6 +26,15 @@ pub mod epoch; pub mod params; pub mod machine; +/// Seal type. +#[derive(Debug, PartialEq, Eq)] +pub enum Seal { + /// Regular block seal; should be part of the blockchain. + Regular(Vec), + /// Engine does not generate seal for this block right now. + None, +} + /// The type of sealing the engine is currently able to perform. #[derive(Debug, PartialEq, Eq)] pub enum SealingState { diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index d209b3d25a4..b817cbf1134 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -64,6 +64,7 @@ pub mod block; pub mod block_status; pub mod blockchain_info; pub mod call_analytics; +pub mod client_types; pub mod encoded; pub mod engines; pub mod errors; diff --git a/ethcore/types/src/verification_queue_info.rs b/ethcore/types/src/verification_queue_info.rs index b89cfe20c0d..7cd763644d3 100644 --- a/ethcore/types/src/verification_queue_info.rs +++ b/ethcore/types/src/verification_queue_info.rs @@ -48,3 +48,46 @@ impl VerificationQueueInfo { self.unverified_queue_size + self.verified_queue_size + self.verifying_queue_size == 0 } } + +//todo[dvdplm] move verification types into own module +use crate::{ + header::Header, + transaction::UnverifiedTransaction, +}; +use bytes::Bytes; +use parity_util_mem::MallocSizeOf; + +/// An unverified block. +#[derive(PartialEq, Debug, MallocSizeOf)] +pub struct Unverified { + /// Unverified block header. + pub header: Header, + /// Unverified block transactions. + pub transactions: Vec, + /// Unverified block uncles. + pub uncles: Vec
, + /// Raw block bytes. + pub bytes: Bytes, +} + +impl Unverified { + /// Create an `Unverified` from raw bytes. + pub fn from_rlp(bytes: Bytes) -> Result { + use rlp::Rlp; + let (header, transactions, uncles) = { + let rlp = Rlp::new(&bytes); + let header = rlp.val_at(0)?; + let transactions = rlp.list_at(1)?; + let uncles = rlp.list_at(2)?; + (header, transactions, uncles) + }; + + Ok(Unverified { + header, + transactions, + uncles, + bytes, + }) + } +} + From d96fff31182d4a44957cc8bc0da7383c28abc99b Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 9 Aug 2019 13:13:22 +0200 Subject: [PATCH 18/43] Move snapshot related traits to the engine crate (eew) --- ethcore/engine/Cargo.toml | 1 + ethcore/engine/src/engine.rs | 76 +++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/ethcore/engine/Cargo.toml b/ethcore/engine/Cargo.toml index cee2c811bbf..fe11797caf7 100644 --- a/ethcore/engine/Cargo.toml +++ b/ethcore/engine/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" license = "GPL-3.0" [dependencies] +blockchain = { package = "ethcore-blockchain", path = "../blockchain" } client-traits = { path = "../client-traits" } common-types = { path = "../types" } builtin = { path = "../builtin", package = "ethcore-builtin" } diff --git a/ethcore/engine/src/engine.rs b/ethcore/engine/src/engine.rs index 5ed665ee123..69a26dd8d03 100644 --- a/ethcore/engine/src/engine.rs +++ b/ethcore/engine/src/engine.rs @@ -16,9 +16,10 @@ //! Consensus engine specification and basic implementations. -use std::sync::{Weak, Arc}; +use std::sync::{Weak, Arc, atomic::AtomicBool}; use std::collections::BTreeMap; +use blockchain::{BlockChain, BlockChainDB}; use builtin::Builtin; use common_types::{ BlockNumber, @@ -30,8 +31,9 @@ use common_types::{ machine as machine_types, machine::{AuxiliaryData, AuxiliaryRequest}, }, - errors::{EthcoreError as Error, EngineError}, + errors::{EthcoreError as Error, EngineError, SnapshotError}, transaction::{self, UnverifiedTransaction}, + snapshot::{ManifestData, ChunkSink, Progress}, }; //use snapshot::SnapshotComponents; //todo use client_traits::EngineClient; @@ -307,10 +309,9 @@ pub trait Engine: Sync + Send { // todo[dvdplm] sort out this mess: SnapshotComponents depends on Rebuilder and that depends on Engine /// Create a factory for building snapshot chunks and restoring from them. /// Returning `None` indicates that this engine doesn't support snapshot creation. -// fn snapshot_components(&self) -> Option> { -// None -// } - fn snapshot_components(&self) -> Option { None } + fn snapshot_components(&self) -> Option> { + None + } /// Whether this engine supports warp sync. fn supports_warp(&self) -> bool { @@ -418,3 +419,66 @@ pub struct NoOp; impl EpochVerifier for NoOp { fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } } + + +// todo[dvdplm] it's pretty weird to have this here +/// Restore from secondary snapshot chunks. +pub trait Rebuilder: Send { + /// Feed a chunk, potentially out of order. + /// + /// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with + /// `Error::RestorationAborted`. + fn feed( + &mut self, + chunk: &[u8], + engine: &dyn Engine, + abort_flag: &AtomicBool, + ) -> Result<(), Error>; + + /// Finalize the restoration. Will be done after all chunks have been + /// fed successfully. + /// + /// This should apply the necessary "glue" between chunks, + /// and verify against the restored state. + fn finalize(&mut self) -> Result<(), Error>; +} + +// todo[dvdplm] it's pretty weird to have this here – perhaps own crate? +/// Components necessary for snapshot creation and restoration. +pub trait SnapshotComponents: Send { + /// Create secondary snapshot chunks; these corroborate the state data + /// in the state chunks. + /// + /// Chunks shouldn't exceed the given preferred size, and should be fed + /// uncompressed into the sink. + /// + /// This will vary by consensus engine, so it's exposed as a trait. + fn chunk_all( + &mut self, + chain: &BlockChain, + block_at: H256, + chunk_sink: &mut ChunkSink, + progress: &Progress, + preferred_size: usize, + ) -> Result<(), SnapshotError>; + + /// Create a rebuilder, which will have chunks fed into it in arbitrary + /// order and then be finalized. + /// + /// The manifest, a database, and fresh `BlockChain` are supplied. + /// + /// The engine passed to the `Rebuilder` methods will be the same instance + /// that created the `SnapshotComponents`. + fn rebuilder( + &self, + chain: BlockChain, + db: Arc, + manifest: &ManifestData, + ) -> Result, Error>; + + /// Minimum supported snapshot version number. + fn min_supported_version(&self) -> u64; + + /// Current version number + fn current_version(&self) -> u64; +} From 33aa152d65ff251e8c8dc1bbdf1028a42addc8fe Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 9 Aug 2019 13:15:08 +0200 Subject: [PATCH 19/43] Move a few snapshot related types to common_types Cleanup Executed as exported from machine crate --- ethcore/machine/src/executed.rs | 58 +------------------ ethcore/src/snapshot/consensus/mod.rs | 1 + ethcore/src/snapshot/consensus/work.rs | 7 ++- ethcore/src/snapshot/mod.rs | 6 +- ethcore/types/src/engines/machine.rs | 6 -- ethcore/types/src/lib.rs | 2 +- .../src/{snapshot_manifest.rs => snapshot.rs} | 55 +++++++++++++++--- 7 files changed, 62 insertions(+), 73 deletions(-) rename ethcore/types/src/{snapshot_manifest.rs => snapshot.rs} (62%) diff --git a/ethcore/machine/src/executed.rs b/ethcore/machine/src/executed.rs index a7aede7abd3..b34f264ce93 100644 --- a/ethcore/machine/src/executed.rs +++ b/ethcore/machine/src/executed.rs @@ -21,63 +21,9 @@ use common_types::{ engines::machine, errors::ExecutionError, }; + +/// /// Transaction execution receipt, parametrised with convenient defaults. pub type Executed = machine::Executed; /// Transaction execution result. pub type ExecutionResult = Result, ExecutionError>; - -//use ethereum_types::{U256, Address}; -//use parity_bytes::Bytes; -//use vm; -//use trace::{VMTrace, FlatTrace}; -//use common_types::{ -// state_diff::StateDiff, -// log_entry::LogEntry, -// errors::ExecutionError, -//}; -// -///// Transaction execution receipt. -//#[derive(Debug, PartialEq, Clone)] -//pub struct Executed { -// /// True if the outer call/create resulted in an exceptional exit. -// pub exception: Option, -// -// /// Gas paid up front for execution of transaction. -// pub gas: U256, -// -// /// Gas used during execution of transaction. -// pub gas_used: U256, -// -// /// Gas refunded after the execution of transaction. -// /// To get gas that was required up front, add `refunded` and `gas_used`. -// pub refunded: U256, -// -// /// Cumulative gas used in current block so far. -// /// -// /// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)` -// /// -// /// where `tn` is current transaction. -// pub cumulative_gas_used: U256, -// -// /// Vector of logs generated by transaction. -// pub logs: Vec, -// -// /// Addresses of contracts created during execution of transaction. -// /// Ordered from earliest creation. -// /// -// /// eg. sender creates contract A and A in constructor creates contract B -// /// -// /// B creation ends first, and it will be the first element of the vector. -// pub contracts_created: Vec
, -// /// Transaction output. -// pub output: Bytes, -// /// The trace of this transaction. -// pub trace: Vec, -// /// The VM trace of this transaction. -// pub vm_trace: Option, -// /// The state diff, if we traced it. -// pub state_diff: Option, -//} -// -///// Transaction execution result. -//pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/src/snapshot/consensus/mod.rs b/ethcore/src/snapshot/consensus/mod.rs index d9c9cc8017d..1cff0179d21 100644 --- a/ethcore/src/snapshot/consensus/mod.rs +++ b/ethcore/src/snapshot/consensus/mod.rs @@ -75,6 +75,7 @@ pub trait SnapshotComponents: Send { fn current_version(&self) -> u64; } +// todo[dvdplm] moved /// Restore from secondary snapshot chunks. pub trait Rebuilder: Send { /// Feed a chunk, potentially out of order. diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index f286006a921..fd19e89178d 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -84,7 +84,12 @@ impl SnapshotComponents for PowSnapshot { db: Arc, manifest: &ManifestData, ) -> Result, EthcoreError> { - PowRebuilder::new(chain, db.key_value().clone(), manifest, self.max_restore_blocks).map(|r| Box::new(r) as Box<_>) + PowRebuilder::new( + chain, + db.key_value().clone(), + manifest, + self.max_restore_blocks + ).map(|r| Box::new(r) as Box<_>) } fn min_supported_version(&self) -> u64 { ::snapshot::MIN_SUPPORTED_STATE_CHUNK_VERSION } diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 256db1d94ec..b8d9cd94155 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -59,7 +59,7 @@ pub use self::consensus::*; pub use self::service::{SnapshotClient, Service, DatabaseRestore}; pub use self::traits::SnapshotService; pub use self::watcher::Watcher; -pub use types::snapshot_manifest::ManifestData; +pub use types::snapshot::ManifestData; pub use types::restoration_status::RestorationStatus; pub use types::basic_account::BasicAccount; @@ -111,6 +111,7 @@ impl Default for SnapshotConfiguration { } } +// todo[dvdplm] moved /// A progress indicator for snapshots. #[derive(Debug, Default)] pub struct Progress { @@ -121,6 +122,7 @@ pub struct Progress { abort: AtomicBool, } +// todo[dvdplm] moved impl Progress { /// Reset the progress. pub fn reset(&self) { @@ -145,8 +147,8 @@ impl Progress { /// Whether the snapshot is complete. pub fn done(&self) -> bool { self.done.load(Ordering::Acquire) } - } + /// Take a snapshot using the given blockchain, starting block hash, and database, writing into the given writer. pub fn take_snapshot( chunker: Box, diff --git a/ethcore/types/src/engines/machine.rs b/ethcore/types/src/engines/machine.rs index 6a238c0c486..db952aebc0a 100644 --- a/ethcore/types/src/engines/machine.rs +++ b/ethcore/types/src/engines/machine.rs @@ -18,13 +18,11 @@ use ethereum_types::{Address, U256}; use bytes::Bytes; -//use trace::{VMTrace, FlatTrace}; use crate::{ log_entry::LogEntry, receipt, state_diff::StateDiff, - errors::ExecutionError, }; /// Type alias for a function we can make calls through synchronously. @@ -55,7 +53,6 @@ pub struct AuxiliaryData<'a> { /// Transaction execution receipt. #[derive(Debug, PartialEq, Clone)] -//pub struct Executed { pub struct Executed { /// True if the outer call/create resulted in an exceptional exit. pub exception: Option, @@ -96,6 +93,3 @@ pub struct Executed { /// The state diff, if we traced it. pub state_diff: Option, } - -///// Transaction execution result. -//pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index b817cbf1134..e19194cc622 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -76,7 +76,7 @@ pub mod pruning_info; pub mod receipt; pub mod restoration_status; pub mod security_level; -pub mod snapshot_manifest; +pub mod snapshot; pub mod state_diff; pub mod trace_filter; pub mod transaction; diff --git a/ethcore/types/src/snapshot_manifest.rs b/ethcore/types/src/snapshot.rs similarity index 62% rename from ethcore/types/src/snapshot_manifest.rs rename to ethcore/types/src/snapshot.rs index 8ed19fcfc20..aa1647227cd 100644 --- a/ethcore/types/src/snapshot_manifest.rs +++ b/ethcore/types/src/snapshot.rs @@ -14,12 +14,50 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//! Snapshot manifest type definition +//! Snapshot type definitions + +use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU64, Ordering}; use ethereum_types::H256; use rlp::{Rlp, RlpStream, DecoderError}; use bytes::Bytes; +/// A progress indicator for snapshots. +#[derive(Debug, Default)] +pub struct Progress { + accounts: AtomicUsize, + blocks: AtomicUsize, + size: AtomicU64, + done: AtomicBool, + abort: AtomicBool, +} + +impl Progress { + /// Reset the progress. + pub fn reset(&self) { + self.accounts.store(0, Ordering::Release); + self.blocks.store(0, Ordering::Release); + self.size.store(0, Ordering::Release); + self.abort.store(false, Ordering::Release); + + // atomic fence here to ensure the others are written first? + // logs might very rarely get polluted if not. + self.done.store(false, Ordering::Release); + } + + /// Get the number of accounts snapshotted thus far. + pub fn accounts(&self) -> usize { self.accounts.load(Ordering::Acquire) } + + /// Get the number of blocks snapshotted thus far. + pub fn blocks(&self) -> usize { self.blocks.load(Ordering::Acquire) } + + /// Get the written size of the snapshot in bytes. + pub fn size(&self) -> u64 { self.size.load(Ordering::Acquire) } + + /// Whether the snapshot is complete. + pub fn done(&self) -> bool { self.done.load(Ordering::Acquire) } +} + /// Manifest data. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ManifestData { @@ -67,12 +105,15 @@ impl ManifestData { let block_hash: H256 = decoder.val_at(start + 4)?; Ok(ManifestData { - version: version, - state_hashes: state_hashes, - block_hashes: block_hashes, - state_root: state_root, - block_number: block_number, - block_hash: block_hash, + version, + state_hashes, + block_hashes, + state_root, + block_number, + block_hash, }) } } + +/// A sink for produced chunks. +pub type ChunkSink<'a> = dyn FnMut(&[u8]) -> std::io::Result<()> + 'a; From 9b70856c948283ee07986388ecaacf04ff773f71 Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 9 Aug 2019 13:16:15 +0200 Subject: [PATCH 20/43] fix warning --- miner/src/pool/local_transactions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/src/pool/local_transactions.rs b/miner/src/pool/local_transactions.rs index 346877d0301..a83af5b72e4 100644 --- a/miner/src/pool/local_transactions.rs +++ b/miner/src/pool/local_transactions.rs @@ -66,7 +66,7 @@ pub struct LocalTransactionsList { max_old: usize, transactions: LinkedHashMap, pending: usize, - in_chain: Option bool + Send + Sync>>, + in_chain: Option bool + Send + Sync>>, } impl fmt::Debug for LocalTransactionsList { From f76e5edf9f95faeea186dec5f2e7508f39e6d67b Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 9 Aug 2019 13:52:33 +0200 Subject: [PATCH 21/43] Gradually introduce new engine crate: snapshot --- ethcore/Cargo.toml | 1 + ethcore/engine/src/engine.rs | 75 ++--------------- ethcore/engine/src/lib.rs | 1 + ethcore/engine/src/snapshot.rs | 91 +++++++++++++++++++++ ethcore/src/client/client.rs | 3 +- ethcore/src/engines/authority_round/mod.rs | 3 +- ethcore/src/engines/basic_authority.rs | 3 +- ethcore/src/engines/ethash.rs | 3 +- ethcore/src/engines/mod.rs | 2 +- ethcore/src/engines/null_engine.rs | 3 +- ethcore/src/lib.rs | 1 + ethcore/src/snapshot/account.rs | 7 +- ethcore/src/snapshot/consensus/authority.rs | 6 +- ethcore/src/snapshot/consensus/mod.rs | 74 ----------------- ethcore/src/snapshot/consensus/work.rs | 5 +- ethcore/src/snapshot/mod.rs | 42 +--------- ethcore/src/snapshot/service.rs | 6 +- ethcore/types/src/client_types.rs | 49 +++++++++++ ethcore/types/src/snapshot.rs | 10 +-- 19 files changed, 181 insertions(+), 204 deletions(-) create mode 100644 ethcore/engine/src/snapshot.rs create mode 100644 ethcore/types/src/client_types.rs diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index b61932b0ceb..aafbc358bc9 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -13,6 +13,7 @@ blooms-db = { path = "../util/blooms-db", optional = true } client-traits = { path = "./client-traits" } common-types = { path = "types" } crossbeam-utils = "0.6" +engine = { path = "./engine" } env_logger = { version = "0.5", optional = true } ethabi = "8.0" ethabi-contract = "8.0" diff --git a/ethcore/engine/src/engine.rs b/ethcore/engine/src/engine.rs index 69a26dd8d03..4b509c084bb 100644 --- a/ethcore/engine/src/engine.rs +++ b/ethcore/engine/src/engine.rs @@ -16,10 +16,9 @@ //! Consensus engine specification and basic implementations. -use std::sync::{Weak, Arc, atomic::AtomicBool}; +use std::sync::{Weak, Arc}; use std::collections::BTreeMap; -use blockchain::{BlockChain, BlockChainDB}; use builtin::Builtin; use common_types::{ BlockNumber, @@ -31,11 +30,9 @@ use common_types::{ machine as machine_types, machine::{AuxiliaryData, AuxiliaryRequest}, }, - errors::{EthcoreError as Error, EngineError, SnapshotError}, + errors::{EthcoreError as Error, EngineError}, transaction::{self, UnverifiedTransaction}, - snapshot::{ManifestData, ChunkSink, Progress}, }; -//use snapshot::SnapshotComponents; //todo use client_traits::EngineClient; use ethereum_types::{H256, U256, Address}; @@ -46,7 +43,10 @@ use machine::{ }; use vm::{EnvInfo, Schedule, CallType, ActionValue}; -use crate::signer::EngineSigner; +use crate::{ + signer::EngineSigner, + snapshot::SnapshotComponents, +}; /// A system-calling closure. Enacts calls on a block's state from the system address. pub type SystemCall<'a> = dyn FnMut(Address, Vec) -> Result, String> + 'a; @@ -419,66 +419,3 @@ pub struct NoOp; impl EpochVerifier for NoOp { fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } } - - -// todo[dvdplm] it's pretty weird to have this here -/// Restore from secondary snapshot chunks. -pub trait Rebuilder: Send { - /// Feed a chunk, potentially out of order. - /// - /// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with - /// `Error::RestorationAborted`. - fn feed( - &mut self, - chunk: &[u8], - engine: &dyn Engine, - abort_flag: &AtomicBool, - ) -> Result<(), Error>; - - /// Finalize the restoration. Will be done after all chunks have been - /// fed successfully. - /// - /// This should apply the necessary "glue" between chunks, - /// and verify against the restored state. - fn finalize(&mut self) -> Result<(), Error>; -} - -// todo[dvdplm] it's pretty weird to have this here – perhaps own crate? -/// Components necessary for snapshot creation and restoration. -pub trait SnapshotComponents: Send { - /// Create secondary snapshot chunks; these corroborate the state data - /// in the state chunks. - /// - /// Chunks shouldn't exceed the given preferred size, and should be fed - /// uncompressed into the sink. - /// - /// This will vary by consensus engine, so it's exposed as a trait. - fn chunk_all( - &mut self, - chain: &BlockChain, - block_at: H256, - chunk_sink: &mut ChunkSink, - progress: &Progress, - preferred_size: usize, - ) -> Result<(), SnapshotError>; - - /// Create a rebuilder, which will have chunks fed into it in arbitrary - /// order and then be finalized. - /// - /// The manifest, a database, and fresh `BlockChain` are supplied. - /// - /// The engine passed to the `Rebuilder` methods will be the same instance - /// that created the `SnapshotComponents`. - fn rebuilder( - &self, - chain: BlockChain, - db: Arc, - manifest: &ManifestData, - ) -> Result, Error>; - - /// Minimum supported snapshot version number. - fn min_supported_version(&self) -> u64; - - /// Current version number - fn current_version(&self) -> u64; -} diff --git a/ethcore/engine/src/lib.rs b/ethcore/engine/src/lib.rs index 904f81231ec..b9de84d0f8e 100644 --- a/ethcore/engine/src/lib.rs +++ b/ethcore/engine/src/lib.rs @@ -20,3 +20,4 @@ // todo[dvdplm] do we need all of this exported? pub mod engine; pub mod signer; +pub mod snapshot; diff --git a/ethcore/engine/src/snapshot.rs b/ethcore/engine/src/snapshot.rs new file mode 100644 index 00000000000..e4dd680dca7 --- /dev/null +++ b/ethcore/engine/src/snapshot.rs @@ -0,0 +1,91 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//todo[dvdplm: document module + +use std::sync::{Arc, atomic::AtomicBool}; + +use ethereum_types::H256; + +use blockchain::{BlockChain, BlockChainDB}; +use common_types::{ + errors::{EthcoreError as Error, SnapshotError}, + snapshot::{ManifestData, ChunkSink, Progress}, +}; + +use crate::engine::Engine; + +// todo[dvdplm] it's pretty weird to have this here +/// Restore from secondary snapshot chunks. +pub trait Rebuilder: Send { + /// Feed a chunk, potentially out of order. + /// + /// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with + /// `Error::RestorationAborted`. + fn feed( + &mut self, + chunk: &[u8], + engine: &dyn Engine, + abort_flag: &AtomicBool, + ) -> Result<(), Error>; + + /// Finalize the restoration. Will be done after all chunks have been + /// fed successfully. + /// + /// This should apply the necessary "glue" between chunks, + /// and verify against the restored state. + fn finalize(&mut self) -> Result<(), Error>; +} + +// todo[dvdplm] it's pretty weird to have this here – perhaps own crate? +/// Components necessary for snapshot creation and restoration. +pub trait SnapshotComponents: Send { + /// Create secondary snapshot chunks; these corroborate the state data + /// in the state chunks. + /// + /// Chunks shouldn't exceed the given preferred size, and should be fed + /// uncompressed into the sink. + /// + /// This will vary by consensus engine, so it's exposed as a trait. + fn chunk_all( + &mut self, + chain: &BlockChain, + block_at: H256, + chunk_sink: &mut ChunkSink, + progress: &Progress, + preferred_size: usize, + ) -> Result<(), SnapshotError>; + + /// Create a rebuilder, which will have chunks fed into it in arbitrary + /// order and then be finalized. + /// + /// The manifest, a database, and fresh `BlockChain` are supplied. + /// + /// The engine passed to the `Rebuilder` methods will be the same instance + /// that created the `SnapshotComponents`. + fn rebuilder( + &self, + chain: BlockChain, + db: Arc, + manifest: &ManifestData, + ) -> Result, Error>; + + /// Minimum supported snapshot version number. + fn min_supported_version(&self) -> u64; + + /// Current version number + fn current_version(&self) -> u64; +} diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 55f51e04321..bf55819e6ed 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -84,6 +84,7 @@ use types::{ log_entry::LocalizedLogEntry, receipt::{Receipt, LocalizedReceipt}, header::Header, + snapshot::Progress, }; use verification::queue::kind::BlockLike; @@ -1163,7 +1164,7 @@ impl Client { &self, writer: W, at: BlockId, - p: &snapshot::Progress, + p: &Progress, ) -> Result<(), EthcoreError> { let db = self.state_db.read().journal_db().boxed_clone(); let best_block_number = self.chain_info().best_block_number; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index d4523ffbffe..9e7b77254b3 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -28,6 +28,7 @@ use client::EngineClient; use engines::{Engine, Seal, ConstructedVerifier}; use engines::block_reward; use engines::block_reward::{BlockRewardContract, RewardKind}; +use engine::snapshot::SnapshotComponents; use ethjson; use machine::{ ExecutedBlock, @@ -1591,7 +1592,7 @@ impl Engine for AuthorityRound { ) } - fn snapshot_components(&self) -> Option> { + fn snapshot_components(&self) -> Option> { if self.immediate_transitions { None } else { diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 632e2a0e8c9..d8518439cca 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -22,6 +22,7 @@ use parking_lot::RwLock; use ethkey::{self, Signature}; use engines::{Engine, Seal, ConstructedVerifier}; use engines::signer::EngineSigner; +use engine::snapshot::SnapshotComponents; use ethjson; use client::EngineClient; use machine::{ @@ -211,7 +212,7 @@ impl Engine for BasicAuthority { ) } - fn snapshot_components(&self) -> Option> { + fn snapshot_components(&self) -> Option> { None } diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index 22f81804f67..5afb36a5e39 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -19,6 +19,7 @@ use std::collections::BTreeMap; use std::path::Path; use std::sync::Arc; +use engine::snapshot::SnapshotComponents; use ethereum_types::{H256, H64, U256}; use ethjson; use hash::{KECCAK_EMPTY_LIST_RLP}; @@ -386,7 +387,7 @@ impl Engine for Arc { engines::ConstructedVerifier::Trusted(Box::new(self.clone())) } - fn snapshot_components(&self) -> Option> { + fn snapshot_components(&self) -> Option> { Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS))) } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 65976dd89c9..a8d7e37685b 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -57,7 +57,7 @@ use types::{ errors::{EthcoreError as Error, EngineError}, transaction::{self, UnverifiedTransaction}, }; -use snapshot::SnapshotComponents; +use engine::snapshot::SnapshotComponents; use client::EngineClient; use ethkey::Signature; diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index 549bf22e053..dddf64cba94 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . +use engine::snapshot::SnapshotComponents; use engines::Engine; use engines::block_reward::{self, RewardKind}; use ethereum_types::U256; @@ -103,7 +104,7 @@ impl Engine for NullEngine { Ok(()) } - fn snapshot_components(&self) -> Option> { + fn snapshot_components(&self) -> Option> { Some(Box::new(::snapshot::PowSnapshot::new(10000, 10000))) } diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 7802dc4dad5..78cafd6945e 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -59,6 +59,7 @@ extern crate ansi_term; extern crate client_traits; extern crate common_types as types; extern crate crossbeam_utils; +extern crate engine; extern crate ethabi; extern crate ethash; extern crate ethcore_blockchain as blockchain; diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index 7bf2f4829c4..62d9ac71d0d 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -17,14 +17,17 @@ //! Account state encoding and decoding use account_db::{AccountDB, AccountDBMut}; -use types::basic_account::BasicAccount; +use types::{ + basic_account::BasicAccount, + snapshot::Progress, + errors::SnapshotError as Error, +}; use bytes::Bytes; use ethereum_types::{H256, U256}; use ethtrie::{TrieDB, TrieDBMut}; use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP}; use hash_db::HashDB; use rlp::{RlpStream, Rlp}; -use snapshot::{Error, Progress}; use std::collections::HashSet; use trie::{Trie, TrieMut}; use std::sync::atomic::Ordering; diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index 341c70d34c5..0d4b3cd7b0e 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -19,13 +19,10 @@ //! //! The chunks here contain state proofs of transitions, along with validator proofs. -use super::{SnapshotComponents, Rebuilder, ChunkSink}; - use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use engines::{Engine, EpochVerifier, EpochTransition}; -use snapshot::{ManifestData, Progress}; use blockchain::{BlockChain, BlockChainDB, BlockProvider}; use bytes::Bytes; @@ -39,8 +36,9 @@ use types::{ ids::BlockId, errors::{SnapshotError, EthcoreError}, receipt::Receipt, + snapshot::{ChunkSink, Progress, ManifestData} }; - +use engine::snapshot::{SnapshotComponents, Rebuilder}; /// Snapshot creation and restoration for PoA chains. /// Chunk format: /// diff --git a/ethcore/src/snapshot/consensus/mod.rs b/ethcore/src/snapshot/consensus/mod.rs index 1cff0179d21..3623d008d30 100644 --- a/ethcore/src/snapshot/consensus/mod.rs +++ b/ethcore/src/snapshot/consensus/mod.rs @@ -17,82 +17,8 @@ //! Secondary chunk creation and restoration, implementations for different consensus //! engines. -use std::sync::atomic::AtomicBool; -use std::sync::Arc; - -use blockchain::{BlockChain, BlockChainDB}; -use engines::Engine; -use snapshot::{ManifestData, Progress}; -use types::errors::{SnapshotError, EthcoreError}; - -use ethereum_types::H256; - mod authority; mod work; pub use self::authority::*; pub use self::work::*; - -/// A sink for produced chunks. -pub type ChunkSink<'a> = dyn FnMut(&[u8]) -> ::std::io::Result<()> + 'a; - -/// Components necessary for snapshot creation and restoration. -pub trait SnapshotComponents: Send { - /// Create secondary snapshot chunks; these corroborate the state data - /// in the state chunks. - /// - /// Chunks shouldn't exceed the given preferred size, and should be fed - /// uncompressed into the sink. - /// - /// This will vary by consensus engine, so it's exposed as a trait. - fn chunk_all( - &mut self, - chain: &BlockChain, - block_at: H256, - chunk_sink: &mut ChunkSink, - progress: &Progress, - preferred_size: usize, - ) -> Result<(), SnapshotError>; - - /// Create a rebuilder, which will have chunks fed into it in arbitrary - /// order and then be finalized. - /// - /// The manifest, a database, and fresh `BlockChain` are supplied. - /// - /// The engine passed to the `Rebuilder` methods will be the same instance - /// that created the `SnapshotComponents`. - fn rebuilder( - &self, - chain: BlockChain, - db: Arc, - manifest: &ManifestData, - ) -> Result, EthcoreError>; - - /// Minimum supported snapshot version number. - fn min_supported_version(&self) -> u64; - - /// Current version number - fn current_version(&self) -> u64; -} - -// todo[dvdplm] moved -/// Restore from secondary snapshot chunks. -pub trait Rebuilder: Send { - /// Feed a chunk, potentially out of order. - /// - /// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with - /// `Error::RestorationAborted`. - fn feed( - &mut self, - chunk: &[u8], - engine: &dyn Engine, - abort_flag: &AtomicBool, - ) -> Result<(), EthcoreError>; - - /// Finalize the restoration. Will be done after all chunks have been - /// fed successfully. - /// - /// This should apply the necessary "glue" between chunks, - /// and verify against the restored state. - fn finalize(&mut self) -> Result<(), EthcoreError>; -} diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index fd19e89178d..7a949c383d0 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -20,15 +20,13 @@ //! The secondary chunks in this instance are 30,000 "abridged blocks" from the head //! of the chain, which serve as an indication of valid chain. -use super::{SnapshotComponents, Rebuilder, ChunkSink}; - use std::collections::VecDeque; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use blockchain::{BlockChain, BlockChainDB, BlockProvider}; use engines::Engine; -use snapshot::{ManifestData, Progress}; +use engine::snapshot::{SnapshotComponents, Rebuilder}; use snapshot::block::AbridgedBlock; use ethereum_types::H256; use kvdb::KeyValueDB; @@ -38,6 +36,7 @@ use rand::rngs::OsRng; use types::{ encoded, errors::{SnapshotError, EthcoreError}, + snapshot::{ChunkSink, ManifestData, Progress}, }; /// Snapshot creation and restoration for PoW chains. diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index b8d9cd94155..466dddde325 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -22,7 +22,7 @@ use std::collections::{HashMap, HashSet}; use std::cmp; use std::sync::Arc; -use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicBool, Ordering}; use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY}; use account_db::{AccountDB, AccountDBMut}; @@ -32,6 +32,7 @@ use types::{ ids::BlockId, header::Header, errors::{SnapshotError as Error, EthcoreError}, + snapshot::Progress, }; use ethereum_types::{H256, U256}; use hash_db::HashDB; @@ -51,6 +52,7 @@ use self::io::SnapshotWriter; use super::state_db::StateDB; use account_state::Account as StateAccount; +use engine::snapshot::SnapshotComponents; use crossbeam_utils::thread; use rand::{Rng, rngs::OsRng}; @@ -111,44 +113,6 @@ impl Default for SnapshotConfiguration { } } -// todo[dvdplm] moved -/// A progress indicator for snapshots. -#[derive(Debug, Default)] -pub struct Progress { - accounts: AtomicUsize, - blocks: AtomicUsize, - size: AtomicU64, - done: AtomicBool, - abort: AtomicBool, -} - -// todo[dvdplm] moved -impl Progress { - /// Reset the progress. - pub fn reset(&self) { - self.accounts.store(0, Ordering::Release); - self.blocks.store(0, Ordering::Release); - self.size.store(0, Ordering::Release); - self.abort.store(false, Ordering::Release); - - // atomic fence here to ensure the others are written first? - // logs might very rarely get polluted if not. - self.done.store(false, Ordering::Release); - } - - /// Get the number of accounts snapshotted thus far. - pub fn accounts(&self) -> usize { self.accounts.load(Ordering::Acquire) } - - /// Get the number of blocks snapshotted thus far. - pub fn blocks(&self) -> usize { self.blocks.load(Ordering::Acquire) } - - /// Get the written size of the snapshot in bytes. - pub fn size(&self) -> u64 { self.size.load(Ordering::Acquire) } - - /// Whether the snapshot is complete. - pub fn done(&self) -> bool { self.done.load(Ordering::Acquire) } -} - /// Take a snapshot using the given blockchain, starting block hash, and database, writing into the given writer. pub fn take_snapshot( chunker: Box, diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 79bdb902cd2..8c7b428faca 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -24,17 +24,19 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::cmp; -use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE}; +use super::{StateRebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE}; use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter}; use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler}; use client::{BlockChainClient, Client, ChainInfo, ClientIoMessage}; use client_traits::BlockInfo; use engines::Engine; +use engine::snapshot::Rebuilder; use hash::keccak; use types::{ errors::{EthcoreError as Error, SnapshotError, SnapshotError::UnlinkedAncientBlockChain}, ids::BlockId, + snapshot::{ManifestData, Progress}, }; use io::IoChannel; @@ -245,7 +247,7 @@ pub struct Service { state_chunks: AtomicUsize, block_chunks: AtomicUsize, client: Arc, - progress: super::Progress, + progress: Progress, taking_snapshot: AtomicBool, restoring_snapshot: AtomicBool, } diff --git a/ethcore/types/src/client_types.rs b/ethcore/types/src/client_types.rs new file mode 100644 index 00000000000..ad90e0db0d6 --- /dev/null +++ b/ethcore/types/src/client_types.rs @@ -0,0 +1,49 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Client related types. + +use std::{ + fmt::{Display, Formatter, Error as FmtError}, + time::Duration, +}; + +/// Operating mode for the client. +#[derive(Debug, Eq, PartialEq, Clone)] +pub enum Mode { + /// Always on. + Active, + /// Goes offline after client is inactive for some (given) time, but + /// comes back online after a while of inactivity. + Passive(Duration, Duration), + /// Goes offline after client is inactive for some (given) time and + /// stays inactive. + Dark(Duration), + /// Always off. + Off, +} + +impl Display for Mode { + fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + match *self { + Mode::Active => write!(f, "active"), + Mode::Passive(..) => write!(f, "passive"), + Mode::Dark(..) => write!(f, "dark"), + Mode::Off => write!(f, "offline"), + } + } +} + diff --git a/ethcore/types/src/snapshot.rs b/ethcore/types/src/snapshot.rs index aa1647227cd..e59bbf8cea8 100644 --- a/ethcore/types/src/snapshot.rs +++ b/ethcore/types/src/snapshot.rs @@ -25,11 +25,11 @@ use bytes::Bytes; /// A progress indicator for snapshots. #[derive(Debug, Default)] pub struct Progress { - accounts: AtomicUsize, - blocks: AtomicUsize, - size: AtomicU64, - done: AtomicBool, - abort: AtomicBool, + pub accounts: AtomicUsize, + pub blocks: AtomicUsize, + pub size: AtomicU64, + pub done: AtomicBool, + pub abort: AtomicBool, } impl Progress { From 5b3a8cadc448f2720078e84b21bdedb56883e390 Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 9 Aug 2019 17:06:59 +0200 Subject: [PATCH 22/43] ethcore typechecks with new engine crate --- Cargo.lock | 26 + ethcore/engine/src/lib.rs | 9 + ethcore/src/block.rs | 4 +- ethcore/src/client/ancient_import.rs | 2 +- ethcore/src/client/bad_blocks.rs | 2 +- ethcore/src/client/client.rs | 37 +- ethcore/src/client/config.rs | 30 +- ethcore/src/client/mod.rs | 20 +- ethcore/src/client/test_client.rs | 4 +- ethcore/src/client/traits.rs | 338 +-------- ethcore/src/engines/authority_round/mod.rs | 13 +- ethcore/src/engines/basic_authority.rs | 22 +- ethcore/src/engines/clique/mod.rs | 15 +- ethcore/src/engines/clique/tests.rs | 2 +- ethcore/src/engines/ethash.rs | 28 +- ethcore/src/engines/instant_seal.rs | 3 +- ethcore/src/engines/mod.rs | 703 +++++++++--------- ethcore/src/engines/null_engine.rs | 2 +- ethcore/src/engines/validator_set/contract.rs | 4 +- ethcore/src/engines/validator_set/mod.rs | 4 +- ethcore/src/engines/validator_set/multi.rs | 4 +- .../engines/validator_set/safe_contract.rs | 16 +- .../src/engines/validator_set/simple_list.rs | 4 +- ethcore/src/engines/validator_set/test.rs | 4 +- ethcore/src/lib.rs | 1 - ethcore/src/miner/miner.rs | 12 +- ethcore/src/miner/mod.rs | 7 +- ethcore/src/miner/pool_client.rs | 5 +- ethcore/src/snapshot/consensus/authority.rs | 11 +- ethcore/src/snapshot/consensus/work.rs | 2 +- ethcore/src/snapshot/mod.rs | 6 +- ethcore/src/snapshot/service.rs | 8 +- ethcore/src/snapshot/tests/helpers.rs | 2 +- ethcore/src/spec/spec.rs | 3 +- ethcore/src/verification/canon_verifier.rs | 2 +- ethcore/src/verification/noop_verifier.rs | 2 +- ethcore/src/verification/queue/kind.rs | 79 +- ethcore/src/verification/queue/mod.rs | 2 +- ethcore/src/verification/verification.rs | 6 +- ethcore/src/verification/verifier.rs | 2 +- 40 files changed, 576 insertions(+), 870 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e4981535a0..415e6036761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -426,8 +426,18 @@ dependencies = [ name = "client-traits" version = "0.1.0" dependencies = [ + "account-state 0.1.0", "common-types 0.1.0", + "ethcore-blockchain 0.1.0", + "ethcore-call-contract 0.1.0", + "ethcore-db 0.1.0", + "ethcore-miner 1.12.0", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stats 0.1.0", + "trace 0.1.0", + "vm 0.1.0", ] [[package]] @@ -756,6 +766,21 @@ dependencies = [ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "engine" +version = "0.1.0" +dependencies = [ + "client-traits 0.1.0", + "common-types 0.1.0", + "ethcore-blockchain 0.1.0", + "ethcore-builtin 0.1.0", + "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethkey 0.3.0", + "machine 0.1.0", + "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", +] + [[package]] name = "enum_primitive" version = "0.1.1" @@ -869,6 +894,7 @@ dependencies = [ "common-types 0.1.0", "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "engine 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/engine/src/lib.rs b/ethcore/engine/src/lib.rs index b9de84d0f8e..d3eb9405946 100644 --- a/ethcore/engine/src/lib.rs +++ b/ethcore/engine/src/lib.rs @@ -21,3 +21,12 @@ pub mod engine; pub mod signer; pub mod snapshot; + +pub use engine::{ + Engine, + EpochVerifier, + StateDependentProof, + ConstructedVerifier, + EpochChange, + Proof, +}; diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 2e4d050f632..be50257d915 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -37,7 +37,7 @@ use std::sync::Arc; use bytes::Bytes; use ethereum_types::{H256, U256, Address, Bloom}; -use engines::Engine; +use engine::Engine; use trie_vm_factories::Factories; use state_db::StateDB; use account_state::State; @@ -485,7 +485,7 @@ pub fn enact_verified( mod tests { use test_helpers::get_temp_state_db; use super::*; - use engines::Engine; + use engine::Engine; use vm::LastHashes; use trie_vm_factories::Factories; use state_db::StateDB; diff --git a/ethcore/src/client/ancient_import.rs b/ethcore/src/client/ancient_import.rs index 22f13ff5388..c25c5a599a4 100644 --- a/ethcore/src/client/ancient_import.rs +++ b/ethcore/src/client/ancient_import.rs @@ -18,7 +18,7 @@ use std::sync::Arc; -use engines::{Engine, EpochVerifier}; +use engine::{Engine, EpochVerifier}; use blockchain::BlockChain; use parking_lot::RwLock; diff --git a/ethcore/src/client/bad_blocks.rs b/ethcore/src/client/bad_blocks.rs index 6af24cc4093..dac71458989 100644 --- a/ethcore/src/client/bad_blocks.rs +++ b/ethcore/src/client/bad_blocks.rs @@ -21,7 +21,7 @@ use ethereum_types::H256; use itertools::Itertools; use memory_cache::MemoryLruCache; use parking_lot::RwLock; -use verification::queue::kind::blocks::Unverified; +use types::verification_queue_info::Unverified; /// Recently seen bad blocks. pub struct BadBlocks { diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index bf55819e6ed..3d03c3f0a73 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -39,20 +39,23 @@ use hash_db::EMPTY_PREFIX; use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; use client::ancient_import::AncientVerifier; use client::{ - Nonce, Balance, ChainInfo, TransactionInfo, ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock, - BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call, - AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter, - BlockChainReset + BroadcastProposalBlock, StateInfo, StateClient, Call, + BlockProducer, SealedBlockImporter, + BlockChainReset, + ClientConfig, + ChainNotify, NewBlocks, ChainRoute, ProvingBlockChainClient, EngineInfo, ChainMessageType, + bad_blocks, ClientIoMessage, }; -use client::{ - ClientConfig, BlockChainClient, - TraceFilter, CallAnalytics, Mode, - ChainNotify, NewBlocks, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType, - IoClient, BadBlocks, bad_blocks, ClientIoMessage, +use client_traits::{ + BlockInfo, + Nonce, Balance, ChainInfo, TransactionInfo, ImportBlock, + AccountData, BlockChain as BlockChainTrait, BlockChainClient, + IoClient, BadBlocks, + StateOrBlock }; -use client_traits::BlockInfo; -use engines::{Engine, EpochTransition, ForkChoice}; +use engines::{EpochTransition, ForkChoice}; +use engine::Engine; use machine::{ executed::Executed, executive::{Executive, TransactOptions, contract_address}, @@ -85,10 +88,14 @@ use types::{ receipt::{Receipt, LocalizedReceipt}, header::Header, snapshot::Progress, + trace_filter::Filter as TraceFilter, + pruning_info::PruningInfo, + call_analytics::CallAnalytics, + client_types::Mode, + verification_queue_info::Unverified, // todo[dvdplm] rename the module }; use verification::queue::kind::BlockLike; -use verification::queue::kind::blocks::Unverified; use verification::{Verifier, BlockQueue}; use verification; use ansi_term::Colour; @@ -605,7 +612,7 @@ impl Importer { state_db: &StateDB, client: &Client, ) -> EthcoreResult> { - use engines::EpochChange; + use engine::EpochChange; let hash = header.hash(); let auxiliary = AuxiliaryData { @@ -615,7 +622,7 @@ impl Importer { match self.engine.signals_epoch_end(header, auxiliary) { EpochChange::Yes(proof) => { - use engines::Proof; + use engine::Proof; let proof = match proof { Proof::Known(proof) => proof, @@ -2509,7 +2516,7 @@ impl SealedBlockImporter for Client {} impl ::miner::TransactionVerifierClient for Client {} impl ::miner::BlockChainClient for Client {} -impl super::traits::EngineClient for Client { +impl client_traits::EngineClient for Client { fn update_sealing(&self) { self.importer.miner.update_sealing(self) } diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index a821ebf607e..8397344a214 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -15,11 +15,11 @@ // along with Parity Ethereum. If not, see . use std::str::FromStr; -use std::fmt::{Display, Formatter, Error as FmtError}; use verification::{VerifierType, QueueConfig}; use journaldb; use snapshot::SnapshotConfiguration; +use types::client_types::Mode; pub use std::time::Duration; pub use blockchain::Config as BlockChainConfig; @@ -56,34 +56,6 @@ impl FromStr for DatabaseCompactionProfile { } } -//todo[dvdplm] moved -/// Operating mode for the client. -#[derive(Debug, Eq, PartialEq, Clone)] -pub enum Mode { - /// Always on. - Active, - /// Goes offline after client is inactive for some (given) time, but - /// comes back online after a while of inactivity. - Passive(Duration, Duration), - /// Goes offline after client is inactive for some (given) time and - /// stays inactive. - Dark(Duration), - /// Always off. - Off, -} - -//todo[dvdplm] moved -impl Display for Mode { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - match *self { - Mode::Active => write!(f, "active"), - Mode::Passive(..) => write!(f, "passive"), - Mode::Dark(..) => write!(f, "dark"), - Mode::Off => write!(f, "offline"), - } - } -} - /// Client configuration. Includes configs for all sub-systems. #[derive(Debug, PartialEq, Clone)] pub struct ClientConfig { diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 8ac833f0da4..c639205cf45 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -26,8 +26,10 @@ mod io_message; #[cfg(any(test, feature = "test-helpers"))] mod test_client; +// todo[dvdplm]: really? re-export everything? pub use self::client::*; -pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; +// todo[dvdplm]: Mode was rexported here +pub use self::config::{ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; #[cfg(any(test, feature = "test-helpers"))] pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess}; pub use self::io_message::ClientIoMessage; @@ -35,17 +37,17 @@ pub use self::io_message::ClientIoMessage; pub use self::test_client::{TestBlockChainClient, EachBlockWith, TestState}; pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ - Nonce, Balance, ChainInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, - StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks, - BlockChainReset, BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient + ReopenBlock, PrepareOpenBlock,ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, + Call, EngineInfo, BlockProducer, SealedBlockImporter, BlockChainReset, ProvingBlockChainClient, StateClient, }; +// todo[dvdplm]: how many of these need to be exported? +//pub use self::traits::{ +// Nonce, Balance, ChainInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, +// StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks, +// BlockChainReset, BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient +//}; pub use account_state::state::StateInfo; -use types::{ - trace_filter::Filter as TraceFilter, - pruning_info::PruningInfo, - call_analytics::CallAnalytics, -}; pub use vm::{LastHashes, EnvInfo}; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 801215cb2e7..5e7c17c9cbe 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -66,7 +66,7 @@ use client::{ SealedBlockImporter, IoClient, BadBlocks }; use client_traits::BlockInfo; -use engines::Engine; +use engine::Engine; use machine::executed::Executed; use journaldb; use miner::{self, Miner, MinerService}; @@ -945,7 +945,7 @@ impl ProvingBlockChainClient for TestBlockChainClient { } } -impl super::traits::EngineClient for TestBlockChainClient { +impl client_traits::EngineClient for TestBlockChainClient { fn update_sealing(&self) { self.miner.update_sealing(self) } diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index dfc54e23061..38438a5af78 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -14,120 +14,25 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use std::collections::BTreeMap; -use std::sync::Arc; - -use blockchain::{BlockReceipts, TreeRoute, BlockProvider}; use bytes::Bytes; -use call_contract::{CallContract, RegistryInfo}; -use client_traits::BlockInfo; -use ethcore_miner::pool::VerifiedTransaction; +use client_traits::BlockChainClient; use ethereum_types::{H256, U256, Address}; use evm::Schedule; -use itertools::Itertools; use kvdb::DBValue; use types::{ - transaction::{self, LocalizedTransaction, SignedTransaction, CallError}, - BlockNumber, + transaction::{SignedTransaction, CallError}, basic_account::BasicAccount, - block_status::BlockStatus, - blockchain_info::BlockChainInfo, call_analytics::CallAnalytics, - encoded, errors::EthcoreError as Error, errors::EthcoreResult, - filter::Filter, header::Header, ids::*, - log_entry::LocalizedLogEntry, - pruning_info::PruningInfo, - receipt::LocalizedReceipt, - trace_filter::Filter as TraceFilter, - verification_queue_info::VerificationQueueInfo as BlockQueueInfo, }; -use vm::LastHashes; use block::{OpenBlock, SealedBlock, ClosedBlock}; -use client::Mode; -use engines::Engine; +use engine::Engine; use machine::executed::Executed; use account_state::state::StateInfo; -use trace::LocalizedTrace; -use verification::queue::kind::blocks::Unverified; - -//todo[dvdplm] moved -/// State information to be used during client query -pub enum StateOrBlock { - /// State to be used, may be pending - State(Box), - - /// Id of an existing block from a chain to get state from - Block(BlockId) -} - -//todo[dvdplm] moved -impl From> for StateOrBlock { - fn from(info: Box) -> StateOrBlock { - StateOrBlock::State(info) - } -} - -//todo[dvdplm] moved -impl From for StateOrBlock { - fn from(id: BlockId) -> StateOrBlock { - StateOrBlock::Block(id) - } -} - -//todo[dvdplm] moved -/// Provides `nonce` and `latest_nonce` methods -pub trait Nonce { - /// Attempt to get address nonce at given block. - /// May not fail on BlockId::Latest. - fn nonce(&self, address: &Address, id: BlockId) -> Option; - - /// Get address nonce at the latest block's state. - fn latest_nonce(&self, address: &Address) -> U256 { - self.nonce(address, BlockId::Latest) - .expect("nonce will return Some when given BlockId::Latest. nonce was given BlockId::Latest. \ - Therefore nonce has returned Some; qed") - } -} - -//todo[dvdplm] moved -/// Provides `balance` and `latest_balance` methods -pub trait Balance { - /// Get address balance at the given block's state. - /// - /// May not return None if given BlockId::Latest. - /// Returns None if and only if the block's root hash has been pruned from the DB. - fn balance(&self, address: &Address, state: StateOrBlock) -> Option; - - /// Get address balance at the latest block's state. - fn latest_balance(&self, address: &Address) -> U256 { - self.balance(address, BlockId::Latest.into()) - .expect("balance will return Some if given BlockId::Latest. balance was given BlockId::Latest \ - Therefore balance has returned Some; qed") - } -} - -//todo[dvdplm] moved -/// Provides methods to access account info -pub trait AccountData: Nonce + Balance {} - -//todo[dvdplm] moved -/// Provides `chain_info` method -pub trait ChainInfo { - /// Get blockchain information. - fn chain_info(&self) -> BlockChainInfo; -} - -//todo[dvdplm] moved -/// Provides various information on a transaction by it's ID -pub trait TransactionInfo { - /// Get the hash of block that contains the transaction, if any. - fn transaction_block(&self, id: TransactionId) -> Option; -} /// Provides methods to access chain state pub trait StateClient { @@ -145,18 +50,6 @@ pub trait StateClient { fn state_at(&self, id: BlockId) -> Option; } -//todo[dvdplm] moved -/// Provides various blockchain information, like block header, chain state etc. -pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {} - -// todo[dvdplm]: moved -// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient? -/// Provides methods to import block into blockchain -pub trait ImportBlock { - /// Import a block into the blockchain. - fn import_block(&self, block: Unverified) -> EthcoreResult; -} - /// Provides `call` and `call_many` methods pub trait Call { /// Type representing chain state @@ -179,202 +72,6 @@ pub trait EngineInfo { fn engine(&self) -> &dyn Engine; } -// todo[dvdplm]: moved -/// IO operations that should off-load heavy work to another thread. -pub trait IoClient: Sync + Send { - /// Queue transactions for importing. - fn queue_transactions(&self, transactions: Vec, peer_id: usize); - - /// Queue block import with transaction receipts. Does no sealing and transaction validation. - fn queue_ancient_block(&self, block_bytes: Unverified, receipts_bytes: Bytes) -> EthcoreResult; - - /// Queue consensus engine message. - fn queue_consensus_message(&self, message: Bytes); -} - -// todo[dvdplm]: moved -/// Provides recently seen bad blocks. -pub trait BadBlocks { - /// Returns a list of blocks that were recently not imported because they were invalid. - fn bad_blocks(&self) -> Vec<(Unverified, String)>; -} - -/// Blockchain database client. Owns and manages a blockchain and a block queue. -pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContract + RegistryInfo + ImportBlock -+ IoClient + BadBlocks { - /// Look up the block number for the given block ID. - fn block_number(&self, id: BlockId) -> Option; - - /// Get raw block body data by block id. - /// Block body is an RLP list of two items: uncles and transactions. - fn block_body(&self, id: BlockId) -> Option; - - /// Get block status by block header hash. - fn block_status(&self, id: BlockId) -> BlockStatus; - - /// Get block total difficulty. - fn block_total_difficulty(&self, id: BlockId) -> Option; - - /// Attempt to get address storage root at given block. - /// May not fail on BlockId::Latest. - fn storage_root(&self, address: &Address, id: BlockId) -> Option; - - /// Get block hash. - fn block_hash(&self, id: BlockId) -> Option; - - /// Get address code at given block's state. - fn code(&self, address: &Address, state: StateOrBlock) -> Option>; - - /// Get address code at the latest block's state. - fn latest_code(&self, address: &Address) -> Option { - self.code(address, BlockId::Latest.into()) - .expect("code will return Some if given BlockId::Latest; qed") - } - - /// Get a reference to the `BlockProvider`. - fn chain(&self) -> Arc; - - /// Get block queue information. - fn queue_info(&self) -> BlockQueueInfo; - - /// Get address code hash at given block's state. - - /// Get value of the storage at given position at the given block's state. - /// - /// May not return None if given BlockId::Latest. - /// Returns None if and only if the block's root hash has been pruned from the DB. - fn storage_at(&self, address: &Address, position: &H256, state: StateOrBlock) -> Option; - - /// Get value of the storage at given position at the latest block's state. - fn latest_storage_at(&self, address: &Address, position: &H256) -> H256 { - self.storage_at(address, position, BlockId::Latest.into()) - .expect("storage_at will return Some if given BlockId::Latest. storage_at was given BlockId::Latest. \ - Therefore storage_at has returned Some; qed") - } - - /// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`. - /// If `after` is set the list starts with the following item. - fn list_accounts(&self, id: BlockId, after: Option<&Address>, count: u64) -> Option>; - - /// Get a list of all storage keys in the block `id`, if fat DB is in operation, otherwise `None`. - /// If `after` is set the list starts with the following item. - fn list_storage(&self, id: BlockId, account: &Address, after: Option<&H256>, count: u64) -> Option>; - - /// Get transaction with given hash. - fn transaction(&self, id: TransactionId) -> Option; - - /// Get uncle with given id. - fn uncle(&self, id: UncleId) -> Option; - - /// Get transaction receipt with given hash. - fn transaction_receipt(&self, id: TransactionId) -> Option; - - /// Get localized receipts for all transaction in given block. - fn localized_block_receipts(&self, id: BlockId) -> Option>; - - /// Get a tree route between `from` and `to`. - /// See `BlockChain::tree_route`. - fn tree_route(&self, from: &H256, to: &H256) -> Option; - - /// Get all possible uncle hashes for a block. - fn find_uncles(&self, hash: &H256) -> Option>; - - /// Get latest state node - fn state_data(&self, hash: &H256) -> Option; - - /// Get block receipts data by block header hash. - fn block_receipts(&self, hash: &H256) -> Option; - - /// Returns true if block queue is empty. - fn is_queue_empty(&self) -> bool { - self.queue_info().is_empty() - } - - /// Clear block queue and abort all import activity. - fn clear_queue(&self); - - /// Returns logs matching given filter. If one of the filtering block cannot be found, returns the block id that caused the error. - fn logs(&self, filter: Filter) -> Result, BlockId>; - - /// Replays a given transaction for inspection. - fn replay(&self, t: TransactionId, analytics: CallAnalytics) -> Result; - - /// Replays all the transactions in a given block for inspection. - fn replay_block_transactions(&self, block: BlockId, analytics: CallAnalytics) -> Result>, CallError>; - - /// Returns traces matching given filter. - fn filter_traces(&self, filter: TraceFilter) -> Option>; - - /// Returns trace with given id. - fn trace(&self, trace: TraceId) -> Option; - - /// Returns traces created by transaction. - fn transaction_traces(&self, trace: TransactionId) -> Option>; - - /// Returns traces created by transaction from block. - fn block_traces(&self, trace: BlockId) -> Option>; - - /// Get last hashes starting from best block. - fn last_hashes(&self) -> LastHashes; - - /// List all ready transactions that should be propagated to other peers. - fn transactions_to_propagate(&self) -> Vec>; - - /// Sorted list of transaction gas prices from at least last sample_size blocks. - fn gas_price_corpus(&self, sample_size: usize) -> ::stats::Corpus { - let mut h = self.chain_info().best_block_hash; - let mut corpus = Vec::new(); - while corpus.is_empty() { - for _ in 0..sample_size { - let block = match self.block(BlockId::Hash(h)) { - Some(block) => block, - None => return corpus.into(), - }; - - if block.number() == 0 { - return corpus.into(); - } - block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price())); - h = block.parent_hash().clone(); - } - } - corpus.into() - } - - /// Get the preferred chain ID to sign on - fn signing_chain_id(&self) -> Option; - - /// Get the mode. - fn mode(&self) -> Mode; - - /// Set the mode. - fn set_mode(&self, mode: Mode); - - /// Get the chain spec name. - fn spec_name(&self) -> String; - - /// Set the chain via a spec name. - fn set_spec_name(&self, spec_name: String) -> Result<(), ()>; - - /// Disable the client from importing blocks. This cannot be undone in this session and indicates - /// that a subsystem has reason to believe this executable incapable of syncing the chain. - fn disable(&self); - - /// Returns engine-related extra info for `BlockId`. - fn block_extra_info(&self, id: BlockId) -> Option>; - - /// Returns engine-related extra info for `UncleId`. - fn uncle_extra_info(&self, id: UncleId) -> Option>; - - /// Returns information about pruning/data availability. - fn pruning_info(&self) -> PruningInfo; - - /// Schedule state-altering transaction to be executed on the next pending block. - fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error>; - - /// Get the address of the registry itself. - fn registrar_address(&self) -> Option
; -} /// Provides `reopen_block` method pub trait ReopenBlock { @@ -416,35 +113,6 @@ pub trait BroadcastProposalBlock { /// Provides methods to import sealed block and broadcast a block proposal pub trait SealedBlockImporter: ImportSealedBlock + BroadcastProposalBlock {} -// todo[dvdplm] moved -/// Client facilities used by internally sealing Engines. -pub trait EngineClient: Sync + Send + ChainInfo { - /// Make a new block and seal it. - fn update_sealing(&self); - - /// Submit a seal for a block in the mining queue. - fn submit_seal(&self, block_hash: H256, seal: Vec); - - /// Broadcast a consensus message to the network. - fn broadcast_consensus_message(&self, message: Bytes); - - /// Get the transition to the epoch the given parent hash is part of - /// or transitions to. - /// This will give the epoch that any children of this parent belong to. - /// - /// The block corresponding the the parent hash must be stored already. - fn epoch_transition_for(&self, parent_hash: H256) -> Option<::engines::EpochTransition>; - - /// Attempt to cast the engine client to a full client. - fn as_full_client(&self) -> Option<&dyn BlockChainClient>; - - /// Get a block number by ID. - fn block_number(&self, id: BlockId) -> Option; - - /// Get raw block header data by block id. - fn block_header(&self, id: BlockId) -> Option; -} - /// Extended client interface for providing proofs of the state. pub trait ProvingBlockChainClient: BlockChainClient { /// Prove account storage at a specific block id. diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 9e7b77254b3..f3d17ee15eb 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -24,8 +24,8 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Weak, Arc}; use std::time::{UNIX_EPOCH, Duration}; -use client::EngineClient; -use engines::{Engine, Seal, ConstructedVerifier}; +use client_traits::EngineClient; +use engine::{Engine,ConstructedVerifier}; use engines::block_reward; use engines::block_reward::{BlockRewardContract, RewardKind}; use engine::snapshot::SnapshotComponents; @@ -35,7 +35,7 @@ use machine::{ Machine, }; use hash::keccak; -use super::signer::EngineSigner; +use engine::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; use self::finality::RollingFinality; use ethkey::{self, Signature}; @@ -51,6 +51,7 @@ use types::{ header::{Header, ExtendedHeader}, engines::{ params::CommonParams, + Seal, SealingState, machine::{Call, AuxiliaryData}, }, @@ -460,7 +461,7 @@ struct EpochVerifier { empty_steps_transition: u64, } -impl super::EpochVerifier for EpochVerifier { +impl engine::EpochVerifier for EpochVerifier { fn verify_light(&self, header: &Header) -> Result<(), Error> { // Validate the timestamp verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?)?; @@ -1430,8 +1431,8 @@ impl Engine for AuthorityRound { .map(|set_proof| combine_proofs(0, &set_proof, &[])) } - fn signals_epoch_end(&self, header: &Header, aux: AuxiliaryData) -> super::EpochChange { - if self.immediate_transitions { return super::EpochChange::No } + fn signals_epoch_end(&self, header: &Header, aux: AuxiliaryData) -> engine::EpochChange { + if self.immediate_transitions { return engine::EpochChange::No } let first = header.number() == 0; self.validators.signals_epoch_end(first, header, aux) diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index d8518439cca..eadbf8897f5 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -20,11 +20,14 @@ use std::sync::Weak; use ethereum_types::{H256, H520}; use parking_lot::RwLock; use ethkey::{self, Signature}; -use engines::{Engine, Seal, ConstructedVerifier}; -use engines::signer::EngineSigner; -use engine::snapshot::SnapshotComponents; +use engine::{ + Engine, + ConstructedVerifier, + snapshot::SnapshotComponents, + signer::EngineSigner, +}; use ethjson; -use client::EngineClient; +use client_traits::EngineClient; use machine::{ Machine, executed_block::ExecutedBlock, @@ -33,6 +36,7 @@ use types::{ header::Header, engines::{ SealingState, + Seal, params::CommonParams, machine::{AuxiliaryData, Call}, }, @@ -60,7 +64,7 @@ struct EpochVerifier { list: SimpleList, } -impl super::EpochVerifier for EpochVerifier { +impl engine::EpochVerifier for EpochVerifier { fn verify_light(&self, header: &Header) -> Result<(), Error> { verify_external(header, &self.list) } @@ -145,13 +149,13 @@ impl Engine for BasicAuthority { } #[cfg(not(test))] - fn signals_epoch_end(&self, _header: &Header, _auxiliary: AuxiliaryData) -> super::EpochChange { + fn signals_epoch_end(&self, _header: &Header, _auxiliary: AuxiliaryData) -> engine::EpochChange { // don't bother signalling even though a contract might try. - super::EpochChange::No + engine::EpochChange::No } #[cfg(test)] - fn signals_epoch_end(&self, header: &Header, auxiliary: AuxiliaryData) -> super::EpochChange { + fn signals_epoch_end(&self, header: &Header, auxiliary: AuxiliaryData) -> engine::EpochChange { // in test mode, always signal even though they don't be finalized. let first = header.number() == 0; self.validators.signals_epoch_end(first, header, auxiliary) @@ -184,7 +188,7 @@ impl Engine for BasicAuthority { match self.validators.epoch_set(first, &self.machine, header.number(), proof) { Ok((list, finalize)) => { - let verifier = Box::new(EpochVerifier { list: list }); + let verifier = Box::new(EpochVerifier { list }); // our epoch verifier will ensure no unverified verifier is ever verified. match finalize { diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index 8dea9d9979c..3f249f42a5e 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -65,9 +65,15 @@ use std::thread; use std::time; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; -use client::EngineClient; -use engines::clique::util::{extract_signers, recover_creator}; -use engines::{Engine, Seal, SealingState, EthashSeal}; +use client_traits::EngineClient; +use engines::{ + clique::util::{extract_signers, recover_creator}, + EthashSeal, +}; +use engine::{ + Engine, + signer::EngineSigner, +}; use ethereum_types::{Address, H64, H160, H256, U256}; use ethkey::Signature; use hash::KECCAK_EMPTY_LIST_RLP; @@ -79,7 +85,6 @@ use machine::{ }; use parking_lot::RwLock; use rand::Rng; -use super::signer::EngineSigner; use unexpected::{Mismatch, OutOfBounds}; use time_utils::CheckedSystemTime; use types::{ @@ -87,6 +92,8 @@ use types::{ ids::BlockId, header::Header, engines::{ + Seal, + SealingState, params::CommonParams, machine::Call, }, diff --git a/ethcore/src/engines/clique/tests.rs b/ethcore/src/engines/clique/tests.rs index 46e9506f1e4..e1954a13faf 100644 --- a/ethcore/src/engines/clique/tests.rs +++ b/ethcore/src/engines/clique/tests.rs @@ -17,7 +17,7 @@ //! Consensus tests for `PoA Clique Engine`, see http://eips.ethereum.org/EIPS/eip-225 for more information use block::*; -use engines::Engine; +use engine::Engine; use ethereum_types::{Address, H256}; use ethkey::{Secret, KeyPair}; use state_db::StateDB; diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index 5afb36a5e39..717ab1d1d82 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -34,7 +34,8 @@ use types::{ use unexpected::{OutOfBounds, Mismatch}; use engines::block_reward::{self, BlockRewardContract, RewardKind}; -use engines::{self, Engine}; +use engines; +use engine::Engine; use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor}; use machine::{ ExecutedBlock, @@ -191,14 +192,14 @@ impl Ethash { ethash_params: EthashParams, machine: Machine, optimize_for: T, - ) -> Arc { + ) -> Self { let progpow_transition = ethash_params.progpow_transition; - Arc::new(Ethash { + Ethash { ethash_params, machine, pow: EthashManager::new(cache_dir.as_ref(), optimize_for.into(), progpow_transition), - }) + } } } @@ -213,14 +214,18 @@ impl Ethash { // NOTE[dvdplm]: the reason we impl this for Arc and not plain Ethash is the // way `epoch_verifier()` works. This means `new()` returns an `Arc` which is // then re-wrapped in an Arc in `spec::engine()`. -impl engines::EpochVerifier for Arc { + +//pub struct ArcEthash<'a>(Arc<&'a Ethash>); +//impl engine::EpochVerifier for Arc { +impl engine::EpochVerifier for Ethash { fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } fn verify_heavy(&self, header: &Header) -> Result<(), Error> { self.verify_block_unordered(header).into() } } -impl Engine for Arc { +//impl Engine for Arc { +impl Engine for Ethash { fn name(&self) -> &str { "Ethash" } fn machine(&self) -> &Machine { &self.machine } @@ -383,8 +388,13 @@ impl Engine for Arc { Ok(()) } - fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> engines::ConstructedVerifier<'a> { - engines::ConstructedVerifier::Trusted(Box::new(self.clone())) + fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> engine::ConstructedVerifier<'a> { + // todo[dvdplm]: this one's tricky, not sure how to solve this. + engine::ConstructedVerifier::Trusted(Box::new(engine::engine::NoOp)) +// engine::ConstructedVerifier::Trusted(Box::new(ArcEthash(Arc::new(self)))) +// engine::ConstructedVerifier::Trusted(Box::new(self.clone())) +// engine::ConstructedVerifier::Trusted(Box::new(*self)) +// engine::ConstructedVerifier::Trusted(Box::new(self)) } fn snapshot_components(&self) -> Option> { @@ -503,7 +513,7 @@ mod tests { errors::{BlockError, EthcoreError as Error}, }; use spec::Spec; - use engines::Engine; + use engine::Engine; use crate::spec::{new_morden, new_mcip3_test, new_homestead_test_machine}; use super::{Ethash, EthashParams, ecip1017_eras_block_reward}; use rlp; diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 8b2be486575..bd855921f6e 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use engines::{Engine, Seal}; +use engine::Engine; use machine::{ ExecutedBlock, Machine @@ -22,6 +22,7 @@ use machine::{ use types::{ header::Header, engines::{ + Seal, SealingState, params::CommonParams, }, diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index a8d7e37685b..41be6a95dff 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -25,13 +25,11 @@ mod null_engine; mod validator_set; pub mod block_reward; -pub mod signer; pub use self::authority_round::AuthorityRound; pub use self::basic_authority::BasicAuthority; pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::null_engine::NullEngine; -pub use self::signer::EngineSigner; pub use self::clique::Clique; pub use self::ethash::{Ethash, Seal as EthashSeal}; @@ -39,44 +37,30 @@ pub use self::ethash::{Ethash, Seal as EthashSeal}; pub use types::engines::ForkChoice; pub use types::engines::epoch::{self, Transition as EpochTransition}; -use std::sync::{Weak, Arc}; -use std::collections::BTreeMap; +use std::sync::Arc; -use builtin::Builtin; -use vm::{EnvInfo, Schedule, CallType, ActionValue}; +use vm::{CallType, ActionValue}; use types::{ - BlockNumber, - ancestry_action::AncestryAction, - header::{Header, ExtendedHeader}, engines::{ - SealingState, Headers, PendingTransitionStore, - params::CommonParams, - machine as machine_types, - machine::{AuxiliaryData, AuxiliaryRequest}, + Headers, PendingTransitionStore, }, - errors::{EthcoreError as Error, EngineError}, - transaction::{self, UnverifiedTransaction}, }; -use engine::snapshot::SnapshotComponents; -use client::EngineClient; -use ethkey::Signature; use machine::{ Machine, executed_block::ExecutedBlock, }; use ethereum_types::{H256, U256, Address}; -use bytes::Bytes; -// todo[dvdplm] remove -/// Seal type. -#[derive(Debug, PartialEq, Eq)] -pub enum Seal { - /// Regular block seal; should be part of the blockchain. - Regular(Vec), - /// Engine does not generate seal for this block right now. - None, -} +//// todo[dvdplm] remove +///// Seal type. +//#[derive(Debug, PartialEq, Eq)] +//pub enum Seal { +// /// Regular block seal; should be part of the blockchain. +// Regular(Vec), +// /// Engine does not generate seal for this block right now. +// None, +//} /// A system-calling closure. Enacts calls on a block's state from the system address. pub type SystemCall<'a> = dyn FnMut(Address, Vec) -> Result, String> + 'a; @@ -123,333 +107,336 @@ pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut Exec } } -// todo[dvdplm] moved -/// Proof dependent on state. -pub trait StateDependentProof: Send + Sync { - /// Generate a proof, given the state. - fn generate_proof<'a>(&self, state: &machine_types::Call) -> Result, String>; - /// Check a proof generated elsewhere (potentially by a peer). - // `engine` needed to check state proofs, while really this should - // just be state machine params. - fn check_proof(&self, machine: &Machine, proof: &[u8]) -> Result<(), String>; -} - -// todo[dvdplm] moved -/// Proof generated on epoch change. -pub enum Proof { - /// Known proof (extracted from signal) - Known(Vec), - /// State dependent proof. - WithState(Arc), -} - -// todo[dvdplm] moved -/// Generated epoch verifier. -pub enum ConstructedVerifier<'a> { - /// Fully trusted verifier. - Trusted(Box), - /// Verifier unconfirmed. Check whether given finality proof finalizes given hash - /// under previous epoch. - Unconfirmed(Box, &'a [u8], H256), - /// Error constructing verifier. - Err(Error), -} - -// todo[dvdplm] moved -impl<'a> ConstructedVerifier<'a> { - /// Convert to a result, indicating that any necessary confirmation has been done - /// already. - pub fn known_confirmed(self) -> Result, Error> { - match self { - ConstructedVerifier::Trusted(v) | ConstructedVerifier::Unconfirmed(v, _, _) => Ok(v), - ConstructedVerifier::Err(e) => Err(e), - } - } -} - -// todo[dvdplm] moved -/// Results of a query of whether an epoch change occurred at the given block. -pub enum EpochChange { - /// Cannot determine until more data is passed. - Unsure(AuxiliaryRequest), - /// No epoch change. - No, - /// The epoch will change, with proof. - Yes(Proof), -} - -/// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. -/// Provides hooks into each of the major parts of block import. -pub trait Engine: Sync + Send { - /// The name of this engine. - fn name(&self) -> &str; - - /// Get access to the underlying state machine. - // TODO: decouple. - fn machine(&self) -> &Machine; - - /// The number of additional header fields required for this engine. - fn seal_fields(&self, _header: &Header) -> usize { 0 } - - /// Additional engine-specific information for the user/developer concerning `header`. - fn extra_info(&self, _header: &Header) -> BTreeMap { BTreeMap::new() } - - /// Maximum number of uncles a block is allowed to declare. - fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 } - - /// Optional maximum gas limit. - fn maximum_gas_limit(&self) -> Option { None } - - /// Block transformation functions, before the transactions. - /// `epoch_begin` set to true if this block kicks off an epoch. - fn on_new_block( - &self, - _block: &mut ExecutedBlock, - _epoch_begin: bool, - ) -> Result<(), Error> { - Ok(()) - } - - /// Block transformation functions, after the transactions. - fn on_close_block( - &self, - _block: &mut ExecutedBlock, - _parent_header: &Header, - ) -> Result<(), Error> { - Ok(()) - } - - /// Allow mutating the header during seal generation. Currently only used by Clique. - fn on_seal_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { Ok(()) } - - /// Returns the engine's current sealing state. - fn sealing_state(&self) -> SealingState { SealingState::External } - - /// Attempt to seal the block internally. - /// - /// If `Some` is returned, then you get a valid seal. - /// - /// This operation is synchronous and may (quite reasonably) not be available, in which None will - /// be returned. - /// - /// It is fine to require access to state or a full client for this function, since - /// light clients do not generate seals. - fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None } - - /// Verify a locally-generated seal of a header. - /// - /// If this engine seals internally, - /// no checks have to be done here, since all internally generated seals - /// should be valid. - /// - /// Externally-generated seals (e.g. PoW) will need to be checked for validity. - /// - /// It is fine to require access to state or a full client for this function, since - /// light clients do not generate seals. - fn verify_local_seal(&self, header: &Header) -> Result<(), Error>; - - /// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import. - /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. - fn verify_block_basic(&self, _header: &Header) -> Result<(), Error> { Ok(()) } - - /// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import. - /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. - fn verify_block_unordered(&self, _header: &Header) -> Result<(), Error> { Ok(()) } - - /// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import. - fn verify_block_family(&self, _header: &Header, _parent: &Header) -> Result<(), Error> { Ok(()) } - - /// Phase 4 verification. Verify block header against potentially external data. - /// Should only be called when `register_client` has been called previously. - fn verify_block_external(&self, _header: &Header) -> Result<(), Error> { Ok(()) } - - /// Genesis epoch data. - fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine_types::Call) -> Result, String> { Ok(Vec::new()) } - - /// Whether an epoch change is signalled at the given header but will require finality. - /// If a change can be enacted immediately then return `No` from this function but - /// `Yes` from `is_epoch_end`. - /// - /// If auxiliary data of the block is required, return an auxiliary request and the function will be - /// called again with them. - /// Return `Yes` or `No` when the answer is definitively known. - /// - /// Should not interact with state. - fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange { - EpochChange::No - } - - /// Whether a block is the end of an epoch. - /// - /// This either means that an immediate transition occurs or a block signalling transition - /// has reached finality. The `Headers` given are not guaranteed to return any blocks - /// from any epoch other than the current. The client must keep track of finality and provide - /// the latest finalized headers to check against the transition store. - /// - /// Return optional transition proof. - fn is_epoch_end( - &self, - _chain_head: &Header, - _finalized: &[H256], - _chain: &Headers
, - _transition_store: &PendingTransitionStore, - ) -> Option> { - None - } - - /// Whether a block is the end of an epoch. - /// - /// This either means that an immediate transition occurs or a block signalling transition - /// has reached finality. The `Headers` given are not guaranteed to return any blocks - /// from any epoch other than the current. This is a specialized method to use for light - /// clients since the light client doesn't track finality of all blocks, and therefore finality - /// for blocks in the current epoch is built inside this method by the engine. - /// - /// Return optional transition proof. - fn is_epoch_end_light( - &self, - _chain_head: &Header, - _chain: &Headers
, - _transition_store: &PendingTransitionStore, - ) -> Option> { - None - } - - /// Create an epoch verifier from validation proof and a flag indicating - /// whether finality is required. - fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> ConstructedVerifier<'a> { - ConstructedVerifier::Trusted(Box::new(NoOp)) - } - - /// Populate a header's fields based on its parent's header. - /// Usually implements the chain scoring rule based on weight. - fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) { } - - /// Handle any potential consensus messages; - /// updating consensus state and potentially issuing a new one. - fn handle_message(&self, _message: &[u8]) -> Result<(), EngineError> { Err(EngineError::UnexpectedMessage) } - - /// Register a component which signs consensus messages. - fn set_signer(&self, _signer: Box) {} - - /// Sign using the EngineSigner, to be used for consensus tx signing. - fn sign(&self, _hash: H256) -> Result { unimplemented!() } - - /// Add Client which can be used for sealing, potentially querying the state and sending messages. - fn register_client(&self, _client: Weak) {} - - /// Trigger next step of the consensus engine. - fn step(&self) {} - - /// Create a factory for building snapshot chunks and restoring from them. - /// Returning `None` indicates that this engine doesn't support snapshot creation. - fn snapshot_components(&self) -> Option> { - None - } - - /// Whether this engine supports warp sync. - fn supports_warp(&self) -> bool { - self.snapshot_components().is_some() - } - - /// Return a new open block header timestamp based on the parent timestamp. - fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 { - use std::{time, cmp}; - - let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default(); - cmp::max(now.as_secs() as u64, parent_timestamp + 1) - } - - /// Check whether the parent timestamp is valid. - fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { - header_timestamp > parent_timestamp - } - - /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that - /// the ancestry exists. - fn ancestry_actions(&self, _header: &Header, _ancestry: &mut dyn Iterator) -> Vec { - Vec::new() - } - - /// Returns author should used when executing tx's for this block. - fn executive_author(&self, header: &Header) -> Result { - Ok(*header.author()) - } - - /// Get the general parameters of the chain. - fn params(&self) -> &CommonParams; - - /// Get the EVM schedule for the given block number. - fn schedule(&self, block_number: BlockNumber) -> Schedule { - self.machine().schedule(block_number) - } - - /// Builtin-contracts for the chain.. - fn builtins(&self) -> &BTreeMap { - self.machine().builtins() - } - - /// Attempt to get a handle to a built-in contract. - /// Only returns references to activated built-ins. - fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> { - self.machine().builtin(a, block_number) - } - - /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. - fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size } - - /// The nonce with which accounts begin at given block. - fn account_start_nonce(&self, block: BlockNumber) -> U256 { - self.machine().account_start_nonce(block) - } - - /// The network ID that transactions should be signed with. - fn signing_chain_id(&self, env_info: &EnvInfo) -> Option { - self.machine().signing_chain_id(env_info) - } - - /// Perform basic/cheap transaction verification. - /// - /// This should include all cheap checks that can be done before - /// actually checking the signature, like chain-replay protection. - /// - /// NOTE This is done before the signature is recovered so avoid - /// doing any state-touching checks that might be expensive. - /// - /// TODO: Add flags for which bits of the transaction to check. - /// TODO: consider including State in the params. - fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> { - self.machine().verify_transaction_basic(t, header) - } - - /// Performs pre-validation of RLP decoded transaction before other processing - fn decode_transaction(&self, transaction: &[u8]) -> Result { - self.machine().decode_transaction(transaction) - } -} - -/// Verifier for all blocks within an epoch with self-contained state. -pub trait EpochVerifier: Send + Sync { - /// Lightly verify the next block header. - /// This may not be a header belonging to a different epoch. - fn verify_light(&self, header: &Header) -> Result<(), Error>; - - /// Perform potentially heavier checks on the next block header. - fn verify_heavy(&self, header: &Header) -> Result<(), Error> { - self.verify_light(header) - } - - /// Check a finality proof against this epoch verifier. - /// Returns `Some(hashes)` if the proof proves finality of these hashes. - /// Returns `None` if the proof doesn't prove anything. - fn check_finality_proof(&self, _proof: &[u8]) -> Option> { - None - } -} - -/// Special "no-op" verifier for stateless, epoch-less engines. -pub struct NoOp; - -impl EpochVerifier for NoOp { - fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -} +//// todo[dvdplm] moved +///// Proof dependent on state. +//pub trait StateDependentProof: Send + Sync { +// /// Generate a proof, given the state. +// fn generate_proof<'a>(&self, state: &machine_types::Call) -> Result, String>; +// /// Check a proof generated elsewhere (potentially by a peer). +// // `engine` needed to check state proofs, while really this should +// // just be state machine params. +// fn check_proof(&self, machine: &Machine, proof: &[u8]) -> Result<(), String>; +//} +// +//// todo[dvdplm] moved +///// Proof generated on epoch change. +//pub enum Proof { +// /// Known proof (extracted from signal) +// Known(Vec), +// /// State dependent proof. +// WithState(Arc), +//} +// +//// todo[dvdplm] moved +///// Generated epoch verifier. +//pub enum ConstructedVerifier<'a> { +// /// Fully trusted verifier. +// Trusted(Box), +// /// Verifier unconfirmed. Check whether given finality proof finalizes given hash +// /// under previous epoch. +// Unconfirmed(Box, &'a [u8], H256), +// /// Error constructing verifier. +// Err(Error), +//} +// +//// todo[dvdplm] moved +//impl<'a> ConstructedVerifier<'a> { +// /// Convert to a result, indicating that any necessary confirmation has been done +// /// already. +// pub fn known_confirmed(self) -> Result, Error> { +// match self { +// ConstructedVerifier::Trusted(v) | ConstructedVerifier::Unconfirmed(v, _, _) => Ok(v), +// ConstructedVerifier::Err(e) => Err(e), +// } +// } +//} +// +//// todo[dvdplm] moved +///// Results of a query of whether an epoch change occurred at the given block. +//pub enum EpochChange { +// /// Cannot determine until more data is passed. +// Unsure(AuxiliaryRequest), +// /// No epoch change. +// No, +// /// The epoch will change, with proof. +// Yes(Proof), +//} +// +//// todo[dvdplm] moved +///// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. +///// Provides hooks into each of the major parts of block import. +//pub trait Engine: Sync + Send { +// /// The name of this engine. +// fn name(&self) -> &str; +// +// /// Get access to the underlying state machine. +// // TODO: decouple. +// fn machine(&self) -> &Machine; +// +// /// The number of additional header fields required for this engine. +// fn seal_fields(&self, _header: &Header) -> usize { 0 } +// +// /// Additional engine-specific information for the user/developer concerning `header`. +// fn extra_info(&self, _header: &Header) -> BTreeMap { BTreeMap::new() } +// +// /// Maximum number of uncles a block is allowed to declare. +// fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 } +// +// /// Optional maximum gas limit. +// fn maximum_gas_limit(&self) -> Option { None } +// +// /// Block transformation functions, before the transactions. +// /// `epoch_begin` set to true if this block kicks off an epoch. +// fn on_new_block( +// &self, +// _block: &mut ExecutedBlock, +// _epoch_begin: bool, +// ) -> Result<(), Error> { +// Ok(()) +// } +// +// /// Block transformation functions, after the transactions. +// fn on_close_block( +// &self, +// _block: &mut ExecutedBlock, +// _parent_header: &Header, +// ) -> Result<(), Error> { +// Ok(()) +// } +// +// /// Allow mutating the header during seal generation. Currently only used by Clique. +// fn on_seal_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { Ok(()) } +// +// /// Returns the engine's current sealing state. +// fn sealing_state(&self) -> SealingState { SealingState::External } +// +// /// Attempt to seal the block internally. +// /// +// /// If `Some` is returned, then you get a valid seal. +// /// +// /// This operation is synchronous and may (quite reasonably) not be available, in which None will +// /// be returned. +// /// +// /// It is fine to require access to state or a full client for this function, since +// /// light clients do not generate seals. +// fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None } +// +// /// Verify a locally-generated seal of a header. +// /// +// /// If this engine seals internally, +// /// no checks have to be done here, since all internally generated seals +// /// should be valid. +// /// +// /// Externally-generated seals (e.g. PoW) will need to be checked for validity. +// /// +// /// It is fine to require access to state or a full client for this function, since +// /// light clients do not generate seals. +// fn verify_local_seal(&self, header: &Header) -> Result<(), Error>; +// +// /// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import. +// /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. +// fn verify_block_basic(&self, _header: &Header) -> Result<(), Error> { Ok(()) } +// +// /// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import. +// /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. +// fn verify_block_unordered(&self, _header: &Header) -> Result<(), Error> { Ok(()) } +// +// /// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import. +// fn verify_block_family(&self, _header: &Header, _parent: &Header) -> Result<(), Error> { Ok(()) } +// +// /// Phase 4 verification. Verify block header against potentially external data. +// /// Should only be called when `register_client` has been called previously. +// fn verify_block_external(&self, _header: &Header) -> Result<(), Error> { Ok(()) } +// +// /// Genesis epoch data. +// fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine_types::Call) -> Result, String> { Ok(Vec::new()) } +// +// /// Whether an epoch change is signalled at the given header but will require finality. +// /// If a change can be enacted immediately then return `No` from this function but +// /// `Yes` from `is_epoch_end`. +// /// +// /// If auxiliary data of the block is required, return an auxiliary request and the function will be +// /// called again with them. +// /// Return `Yes` or `No` when the answer is definitively known. +// /// +// /// Should not interact with state. +// fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange { +// EpochChange::No +// } +// +// /// Whether a block is the end of an epoch. +// /// +// /// This either means that an immediate transition occurs or a block signalling transition +// /// has reached finality. The `Headers` given are not guaranteed to return any blocks +// /// from any epoch other than the current. The client must keep track of finality and provide +// /// the latest finalized headers to check against the transition store. +// /// +// /// Return optional transition proof. +// fn is_epoch_end( +// &self, +// _chain_head: &Header, +// _finalized: &[H256], +// _chain: &Headers
, +// _transition_store: &PendingTransitionStore, +// ) -> Option> { +// None +// } +// +// /// Whether a block is the end of an epoch. +// /// +// /// This either means that an immediate transition occurs or a block signalling transition +// /// has reached finality. The `Headers` given are not guaranteed to return any blocks +// /// from any epoch other than the current. This is a specialized method to use for light +// /// clients since the light client doesn't track finality of all blocks, and therefore finality +// /// for blocks in the current epoch is built inside this method by the engine. +// /// +// /// Return optional transition proof. +// fn is_epoch_end_light( +// &self, +// _chain_head: &Header, +// _chain: &Headers
, +// _transition_store: &PendingTransitionStore, +// ) -> Option> { +// None +// } +// +// /// Create an epoch verifier from validation proof and a flag indicating +// /// whether finality is required. +// fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> ConstructedVerifier<'a> { +// ConstructedVerifier::Trusted(Box::new(NoOp)) +// } +// +// /// Populate a header's fields based on its parent's header. +// /// Usually implements the chain scoring rule based on weight. +// fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) { } +// +// /// Handle any potential consensus messages; +// /// updating consensus state and potentially issuing a new one. +// fn handle_message(&self, _message: &[u8]) -> Result<(), EngineError> { Err(EngineError::UnexpectedMessage) } +// +// /// Register a component which signs consensus messages. +// fn set_signer(&self, _signer: Box) {} +// +// /// Sign using the EngineSigner, to be used for consensus tx signing. +// fn sign(&self, _hash: H256) -> Result { unimplemented!() } +// +// /// Add Client which can be used for sealing, potentially querying the state and sending messages. +// fn register_client(&self, _client: Weak) {} +// +// /// Trigger next step of the consensus engine. +// fn step(&self) {} +// +// /// Create a factory for building snapshot chunks and restoring from them. +// /// Returning `None` indicates that this engine doesn't support snapshot creation. +// fn snapshot_components(&self) -> Option> { +// None +// } +// +// /// Whether this engine supports warp sync. +// fn supports_warp(&self) -> bool { +// self.snapshot_components().is_some() +// } +// +// /// Return a new open block header timestamp based on the parent timestamp. +// fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 { +// use std::{time, cmp}; +// +// let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default(); +// cmp::max(now.as_secs() as u64, parent_timestamp + 1) +// } +// +// /// Check whether the parent timestamp is valid. +// fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { +// header_timestamp > parent_timestamp +// } +// +// /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that +// /// the ancestry exists. +// fn ancestry_actions(&self, _header: &Header, _ancestry: &mut dyn Iterator) -> Vec { +// Vec::new() +// } +// +// /// Returns author should used when executing tx's for this block. +// fn executive_author(&self, header: &Header) -> Result { +// Ok(*header.author()) +// } +// +// /// Get the general parameters of the chain. +// fn params(&self) -> &CommonParams; +// +// /// Get the EVM schedule for the given block number. +// fn schedule(&self, block_number: BlockNumber) -> Schedule { +// self.machine().schedule(block_number) +// } +// +// /// Builtin-contracts for the chain.. +// fn builtins(&self) -> &BTreeMap { +// self.machine().builtins() +// } +// +// /// Attempt to get a handle to a built-in contract. +// /// Only returns references to activated built-ins. +// fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> { +// self.machine().builtin(a, block_number) +// } +// +// /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. +// fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size } +// +// /// The nonce with which accounts begin at given block. +// fn account_start_nonce(&self, block: BlockNumber) -> U256 { +// self.machine().account_start_nonce(block) +// } +// +// /// The network ID that transactions should be signed with. +// fn signing_chain_id(&self, env_info: &EnvInfo) -> Option { +// self.machine().signing_chain_id(env_info) +// } +// +// /// Perform basic/cheap transaction verification. +// /// +// /// This should include all cheap checks that can be done before +// /// actually checking the signature, like chain-replay protection. +// /// +// /// NOTE This is done before the signature is recovered so avoid +// /// doing any state-touching checks that might be expensive. +// /// +// /// TODO: Add flags for which bits of the transaction to check. +// /// TODO: consider including State in the params. +// fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> { +// self.machine().verify_transaction_basic(t, header) +// } +// +// /// Performs pre-validation of RLP decoded transaction before other processing +// fn decode_transaction(&self, transaction: &[u8]) -> Result { +// self.machine().decode_transaction(transaction) +// } +//} +//// todo[dvdplm] moved +///// Verifier for all blocks within an epoch with self-contained state. +//pub trait EpochVerifier: Send + Sync { +// /// Lightly verify the next block header. +// /// This may not be a header belonging to a different epoch. +// fn verify_light(&self, header: &Header) -> Result<(), Error>; +// +// /// Perform potentially heavier checks on the next block header. +// fn verify_heavy(&self, header: &Header) -> Result<(), Error> { +// self.verify_light(header) +// } +// +// /// Check a finality proof against this epoch verifier. +// /// Returns `Some(hashes)` if the proof proves finality of these hashes. +// /// Returns `None` if the proof doesn't prove anything. +// fn check_finality_proof(&self, _proof: &[u8]) -> Option> { +// None +// } +//} +// +//// todo[dvdplm] moved +///// Special "no-op" verifier for stateless, epoch-less engines. +//pub struct NoOp; +// +//// todo[dvdplm] moved +//impl EpochVerifier for NoOp { +// fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } +//} diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index dddf64cba94..37e4e2ce608 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -15,7 +15,7 @@ // along with Parity Ethereum. If not, see . use engine::snapshot::SnapshotComponents; -use engines::Engine; +use engine::Engine; use engines::block_reward::{self, RewardKind}; use ethereum_types::U256; use machine::{ diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index b680bdeeba8..ca05967b1b4 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -30,7 +30,7 @@ use types::{ engines::machine::{Call, AuxiliaryData}, }; -use client::EngineClient; +use client_traits::EngineClient; use super::{ValidatorSet, SimpleList, SystemCall}; use super::safe_contract::ValidatorSafeContract; @@ -93,7 +93,7 @@ impl ValidatorSet for ValidatorContract { first: bool, header: &Header, aux: AuxiliaryData, - ) -> ::engines::EpochChange { + ) -> engine::EpochChange { self.validators.signals_epoch_end(first, header, aux) } diff --git a/ethcore/src/engines/validator_set/mod.rs b/ethcore/src/engines/validator_set/mod.rs index 3a72554271a..b5a51de8bd8 100644 --- a/ethcore/src/engines/validator_set/mod.rs +++ b/ethcore/src/engines/validator_set/mod.rs @@ -37,7 +37,7 @@ use types::{ engines::machine::{Call, AuxiliaryData}, }; -use client::EngineClient; +use client_traits::EngineClient; #[cfg(test)] pub use self::test::TestSet; @@ -117,7 +117,7 @@ pub trait ValidatorSet: Send + Sync + 'static { first: bool, header: &Header, aux: AuxiliaryData, - ) -> ::engines::EpochChange; + ) -> engine::EpochChange; /// Recover the validator set from the given proof, the block number, and /// whether this header is first in its set. diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 48b00b9cf7a..a94ead2b52d 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -30,7 +30,7 @@ use types::{ engines::machine::{Call, AuxiliaryData}, }; -use client::EngineClient; +use client_traits::EngineClient; use machine::Machine; use super::{SystemCall, ValidatorSet}; @@ -100,7 +100,7 @@ impl ValidatorSet for Multi { } fn signals_epoch_end(&self, _first: bool, header: &Header, aux: AuxiliaryData) - -> ::engines::EpochChange + -> engine::EpochChange { let (set_block, set) = self.correct_set_by_number(header.number()); let first = set_block == header.number(); diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 68c9575c6ee..116ecd797c2 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -36,7 +36,7 @@ use types::{ }; use unexpected::Mismatch; -use client::EngineClient; +use client_traits::EngineClient; use machine::Machine; use super::{SystemCall, ValidatorSet}; use super::simple_list::SimpleList; @@ -59,7 +59,7 @@ struct StateProof { header: Header, } -impl ::engines::StateDependentProof for StateProof { +impl engine::StateDependentProof for StateProof { fn generate_proof(&self, caller: &Call) -> Result, String> { prove_initial(self.contract_address, &self.header, caller) } @@ -314,7 +314,7 @@ impl ValidatorSet for ValidatorSafeContract { } fn signals_epoch_end(&self, first: bool, header: &Header, aux: AuxiliaryData) - -> ::engines::EpochChange + -> engine::EpochChange { let receipts = aux.receipts; @@ -325,27 +325,27 @@ impl ValidatorSet for ValidatorSafeContract { contract_address: self.contract_address, header: header.clone(), }); - return ::engines::EpochChange::Yes(::engines::Proof::WithState(state_proof as Arc<_>)); + return engine::EpochChange::Yes(engine::Proof::WithState(state_proof as Arc<_>)); } // otherwise, we're checking for logs. let bloom = self.expected_bloom(header); let header_bloom = header.log_bloom(); - if &bloom & header_bloom != bloom { return ::engines::EpochChange::No } + if &bloom & header_bloom != bloom { return engine::EpochChange::No } trace!(target: "engine", "detected epoch change event bloom"); match receipts { - None => ::engines::EpochChange::Unsure(AuxiliaryRequest::Receipts), + None => engine::EpochChange::Unsure(AuxiliaryRequest::Receipts), Some(receipts) => match self.extract_from_event(bloom, header, receipts) { - None => ::engines::EpochChange::No, + None => engine::EpochChange::No, Some(list) => { info!(target: "engine", "Signal for transition within contract. New validator list: {:?}", &*list); let proof = encode_proof(&header, receipts); - ::engines::EpochChange::Yes(::engines::Proof::Known(proof)) + engine::EpochChange::Yes(engine::Proof::Known(proof)) } }, } diff --git a/ethcore/src/engines/validator_set/simple_list.rs b/ethcore/src/engines/validator_set/simple_list.rs index 5ec08b28684..d3d14f009f6 100644 --- a/ethcore/src/engines/validator_set/simple_list.rs +++ b/ethcore/src/engines/validator_set/simple_list.rs @@ -77,9 +77,9 @@ impl ValidatorSet for SimpleList { } fn signals_epoch_end(&self, _: bool, _: &Header, _: AuxiliaryData) - -> ::engines::EpochChange + -> engine::EpochChange { - ::engines::EpochChange::No + engine::EpochChange::No } fn epoch_set(&self, _first: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option), EthcoreError> { diff --git a/ethcore/src/engines/validator_set/test.rs b/ethcore/src/engines/validator_set/test.rs index 7abb294bc23..c4572a75cd4 100644 --- a/ethcore/src/engines/validator_set/test.rs +++ b/ethcore/src/engines/validator_set/test.rs @@ -71,9 +71,9 @@ impl ValidatorSet for TestSet { fn is_epoch_end(&self, _first: bool, _chain_head: &Header) -> Option> { None } fn signals_epoch_end(&self, _: bool, _: &Header, _: AuxiliaryData) - -> ::engines::EpochChange + -> engine::EpochChange { - ::engines::EpochChange::No + engine::EpochChange::No } fn epoch_set(&self, _: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option), EthcoreError> { diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 78cafd6945e..d1936aa9d1a 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -103,7 +103,6 @@ extern crate parity_util_mem as malloc_size_of; extern crate rustc_hex; extern crate serde; extern crate state_db; -extern crate stats; extern crate time_utils; extern crate trace; extern crate triehash_ethereum as triehash; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index aeb664b57ad..2dfdad3ff05 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -49,7 +49,7 @@ use types::{ block::Block, header::Header, ids::BlockId, - engines::{SealingState}, + engines::{Seal, SealingState}, errors::{EthcoreError as Error, ExecutionError}, receipt::RichReceipt, }; @@ -57,9 +57,15 @@ use using_queue::{UsingQueue, GetAction}; use block::{ClosedBlock, SealedBlock}; use client::{ - BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, ClientIoMessage, + BlockProducer, SealedBlockImporter, ClientIoMessage, +}; +use client_traits::{ + BlockChain, ChainInfo, Nonce, TransactionInfo, +}; +use engine::{ + Engine, + signer::EngineSigner }; -use engines::{Engine, Seal, EngineSigner}; use machine::executive::contract_address; use spec::Spec; use account_state::State; diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index c9f4c0d1f04..bfdb1b7d849 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -48,9 +48,10 @@ use types::{ use block::SealedBlock; use call_contract::{CallContract, RegistryInfo}; use client::{ - ScheduleInfo, - BlockChain, BlockProducer, SealedBlockImporter, ChainInfo, - AccountData, Nonce, + ScheduleInfo, BlockProducer, SealedBlockImporter, +}; +use client_traits::{ + BlockChain, ChainInfo, AccountData, Nonce, }; use account_state::state::StateInfo; diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index 669076c1849..e63f66e7678 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -39,9 +39,8 @@ use types::{ use parking_lot::RwLock; use call_contract::CallContract; -use client::Nonce; -use client_traits::BlockInfo; -use engines::Engine; +use client_traits::{BlockInfo, Nonce}; +use engine::Engine; use machine::transaction_ext::Transaction; use miner; diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index 0d4b3cd7b0e..d24c890db06 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -22,7 +22,12 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -use engines::{Engine, EpochVerifier, EpochTransition}; +use engine::{ + Engine, + EpochVerifier, + snapshot::{SnapshotComponents, Rebuilder} +}; +use engines::EpochTransition; use blockchain::{BlockChain, BlockChainDB, BlockProvider}; use bytes::Bytes; @@ -38,7 +43,7 @@ use types::{ receipt::Receipt, snapshot::{ChunkSink, Progress, ManifestData} }; -use engine::snapshot::{SnapshotComponents, Rebuilder}; + /// Snapshot creation and restoration for PoA chains. /// Chunk format: /// @@ -187,7 +192,7 @@ impl ChunkRebuilder { transition_rlp: Rlp, engine: &dyn Engine, ) -> Result { - use engines::ConstructedVerifier; + use engine::ConstructedVerifier; // decode. let header: Header = transition_rlp.val_at(0)?; diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index 7a949c383d0..5ffc8c53f40 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -25,7 +25,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use blockchain::{BlockChain, BlockChainDB, BlockProvider}; -use engines::Engine; +use engine::Engine; use engine::snapshot::{SnapshotComponents, Rebuilder}; use snapshot::block::AbridgedBlock; use ethereum_types::H256; diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 466dddde325..3dab15d4f13 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -27,7 +27,6 @@ use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY}; use account_db::{AccountDB, AccountDBMut}; use blockchain::{BlockChain, BlockProvider}; -use engines::Engine; use types::{ ids::BlockId, header::Header, @@ -52,7 +51,10 @@ use self::io::SnapshotWriter; use super::state_db::StateDB; use account_state::Account as StateAccount; -use engine::snapshot::SnapshotComponents; +use engine::{ + Engine, + snapshot::SnapshotComponents +}; use crossbeam_utils::thread; use rand::{Rng, rngs::OsRng}; diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 8c7b428faca..3c1a3afea3b 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -28,9 +28,11 @@ use super::{StateRebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE}; use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter}; use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler}; -use client::{BlockChainClient, Client, ChainInfo, ClientIoMessage}; -use client_traits::BlockInfo; -use engines::Engine; +use client::{Client, ClientIoMessage}; +use client_traits::{ + BlockInfo, BlockChainClient, ChainInfo +}; +use engine::Engine; use engine::snapshot::Rebuilder; use hash::keccak; use types::{ diff --git a/ethcore/src/snapshot/tests/helpers.rs b/ethcore/src/snapshot/tests/helpers.rs index 053e8813f33..5b3df97492e 100644 --- a/ethcore/src/snapshot/tests/helpers.rs +++ b/ethcore/src/snapshot/tests/helpers.rs @@ -26,7 +26,7 @@ use account_db::AccountDBMut; use types::basic_account::BasicAccount; use blockchain::{BlockChain, BlockChainDB}; use client::{Client, ChainInfo}; -use engines::Engine; +use engine::Engine; use snapshot::{StateRebuilder}; use snapshot::io::{SnapshotReader, PackedWriter, PackedReader}; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index db9dd7c7f25..613d467086e 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -39,8 +39,9 @@ use types::{ use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType}; use builtin::Builtin; +use engine::Engine; use engines::{ - Engine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority, Clique, + NullEngine, InstantSeal, InstantSealParams, BasicAuthority, Clique, AuthorityRound, Ethash, }; use machine::{ diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index acf42b4510a..c0c60709700 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -18,7 +18,7 @@ use call_contract::CallContract; use client_traits::BlockInfo; -use engines::Engine; +use engine::Engine; use types::{ header::Header, errors::EthcoreError as Error, diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index 8bcbe1532d0..3f9a6210f40 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -18,7 +18,7 @@ use call_contract::CallContract; use client_traits::BlockInfo; -use engines::Engine; +use engine::Engine; use types::{ header::Header, errors::EthcoreError as Error diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 562290c2475..b4e297f88a0 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -16,7 +16,7 @@ //! Definition of valid items for the verification queue. -use engines::Engine; +use engine::Engine; use parity_util_mem::MallocSizeOf; use ethereum_types::{H256, U256}; @@ -69,18 +69,15 @@ pub trait Kind: 'static + Sized + Send + Sync { pub mod blocks { use super::{Kind, BlockLike}; - use engines::Engine; + use engine::Engine; use types::{ block::PreverifiedBlock, - header::Header, errors::{EthcoreError as Error, BlockError}, - transaction::UnverifiedTransaction + verification_queue_info::Unverified, }; use verification::{verify_block_basic, verify_block_unordered}; - use parity_util_mem::MallocSizeOf; use ethereum_types::{H256, U256}; - use bytes::Bytes; /// A mode for verifying blocks. pub struct Blocks; @@ -116,40 +113,40 @@ pub mod blocks { } } - // todo[dvdplm] moved to common-types - /// An unverified block. - #[derive(PartialEq, Debug, MallocSizeOf)] - pub struct Unverified { - /// Unverified block header. - pub header: Header, - /// Unverified block transactions. - pub transactions: Vec, - /// Unverified block uncles. - pub uncles: Vec
, - /// Raw block bytes. - pub bytes: Bytes, - } - // todo[dvdplm] moved to common-types - impl Unverified { - /// Create an `Unverified` from raw bytes. - pub fn from_rlp(bytes: Bytes) -> Result { - use rlp::Rlp; - let (header, transactions, uncles) = { - let rlp = Rlp::new(&bytes); - let header = rlp.val_at(0)?; - let transactions = rlp.list_at(1)?; - let uncles = rlp.list_at(2)?; - (header, transactions, uncles) - }; - - Ok(Unverified { - header, - transactions, - uncles, - bytes, - }) - } - } +// // todo[dvdplm] moved to common-types +// /// An unverified block. +// #[derive(PartialEq, Debug, MallocSizeOf)] +// pub struct Unverified { +// /// Unverified block header. +// pub header: Header, +// /// Unverified block transactions. +// pub transactions: Vec, +// /// Unverified block uncles. +// pub uncles: Vec
, +// /// Raw block bytes. +// pub bytes: Bytes, +// } +// // todo[dvdplm] moved to common-types +// impl Unverified { +// /// Create an `Unverified` from raw bytes. +// pub fn from_rlp(bytes: Bytes) -> Result { +// use rlp::Rlp; +// let (header, transactions, uncles) = { +// let rlp = Rlp::new(&bytes); +// let header = rlp.val_at(0)?; +// let transactions = rlp.list_at(1)?; +// let uncles = rlp.list_at(2)?; +// (header, transactions, uncles) +// }; +// +// Ok(Unverified { +// header, +// transactions, +// uncles, +// bytes, +// }) +// } +// } impl BlockLike for Unverified { fn hash(&self) -> H256 { @@ -184,7 +181,7 @@ pub mod blocks { pub mod headers { use super::{Kind, BlockLike}; - use engines::Engine; + use engine::Engine; use types::{ header::Header, errors::EthcoreError as Error, diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 9b736807d09..465f9b4501e 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -26,7 +26,7 @@ use parity_util_mem::{MallocSizeOf, MallocSizeOfExt}; use ethereum_types::{H256, U256}; use parking_lot::{Condvar, Mutex, RwLock}; use io::*; -use engines::Engine; +use engine::Engine; use client::ClientIoMessage; use len_caching_lock::LenCachingMutex; use types::errors::{BlockError, EthcoreError as Error, ImportError}; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 2042e70afc5..31b81981bc0 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -32,15 +32,15 @@ use unexpected::{Mismatch, OutOfBounds}; use blockchain::*; use call_contract::CallContract; use client_traits::BlockInfo; -use engines::Engine; +use engine::Engine; use types::{ BlockNumber, header::Header, errors::{EthcoreError as Error, BlockError}, engines::MAX_UNCLE_AGE, block::PreverifiedBlock, + verification_queue_info::Unverified, }; -use verification::queue::kind::blocks::Unverified; use time_utils::CheckedSystemTime; @@ -370,7 +370,7 @@ mod tests { use blockchain::{BlockDetails, TransactionAddress, BlockReceipts}; use bytes::Bytes; use hash::keccak; - use engines::Engine; + use engine::Engine; use ethkey::{Random, Generator}; use crate::spec; use test_helpers::{create_test_block_with_data, create_test_block}; diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index 17bb96a2cab..ced7f564967 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -18,7 +18,7 @@ use call_contract::CallContract; use client_traits::BlockInfo; -use engines::Engine; +use engine::Engine; use types::{ header::Header, errors::EthcoreError as Error, From cecd69cc20ad9a771612e056294426be96dbaf0f Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 10:32:56 +0200 Subject: [PATCH 23/43] Sort out types outside ethcore --- Cargo.lock | 6 ++++++ Cargo.toml | 1 + ethcore/light/Cargo.toml | 1 + ethcore/light/src/client/fetch.rs | 10 ++++++---- ethcore/light/src/client/mod.rs | 9 +++++---- ethcore/light/src/lib.rs | 1 + ethcore/light/src/on_demand/request.rs | 2 +- ethcore/light/src/provider.rs | 8 ++++++-- ethcore/node-filter/Cargo.toml | 1 + ethcore/node-filter/src/lib.rs | 8 ++++---- ethcore/private-tx/src/encryptor.rs | 4 ++-- ethcore/private-tx/src/lib.rs | 11 ++++++----- ethcore/src/client/test_client.rs | 17 ++++++++++------- ethcore/src/test_helpers.rs | 17 ++++++++++------- ethcore/sync/src/api.rs | 3 ++- ethcore/sync/src/blocks.rs | 8 +++++--- ethcore/sync/src/chain/handler.rs | 2 +- ethcore/sync/src/chain/mod.rs | 3 ++- ethcore/sync/src/lib.rs | 1 + ethcore/sync/src/sync_io.rs | 2 +- ipfs/Cargo.toml | 1 + ipfs/src/lib.rs | 3 ++- parity/account_utils.rs | 2 +- parity/blockchain.rs | 15 ++++++++------- parity/helpers.rs | 7 +++++-- parity/informant.rs | 6 +++--- parity/ipfs.rs | 2 +- parity/lib.rs | 1 + parity/light_helpers/epoch_fetch.rs | 10 ++++++---- parity/modules.rs | 2 +- parity/params.rs | 2 +- parity/rpc_apis.rs | 2 +- parity/run.rs | 9 ++++++--- parity/snapshot.rs | 10 +++++++--- parity/user_defaults.rs | 2 +- rpc/Cargo.toml | 2 ++ rpc/src/lib.rs | 2 ++ rpc/src/v1/helpers/dispatch/full.rs | 2 +- rpc/src/v1/helpers/dispatch/mod.rs | 2 +- rpc/src/v1/helpers/engine_signer.rs | 2 +- rpc/src/v1/helpers/errors.rs | 2 +- rpc/src/v1/helpers/light_fetch.rs | 2 +- rpc/src/v1/impls/debug.rs | 2 +- rpc/src/v1/impls/eth.rs | 3 ++- rpc/src/v1/impls/eth_filter.rs | 2 +- rpc/src/v1/impls/eth_pubsub.rs | 3 ++- rpc/src/v1/impls/parity.rs | 9 ++++++--- rpc/src/v1/impls/parity_set.rs | 5 +++-- rpc/src/v1/impls/traces.rs | 3 ++- updater/Cargo.toml | 1 + updater/src/lib.rs | 1 + updater/src/updater.rs | 3 ++- 52 files changed, 147 insertions(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 415e6036761..5b34a89475f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1077,6 +1077,7 @@ dependencies = [ "client-traits 0.1.0", "common-types 0.1.0", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "engine 0.1.0", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", "ethcore-blockchain 0.1.0", @@ -2560,6 +2561,7 @@ dependencies = [ name = "node-filter" version = "1.12.0" dependencies = [ + "client-traits 0.1.0", "common-types 0.1.0", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2759,6 +2761,7 @@ dependencies = [ "ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)", "dir 0.1.2", "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "engine 0.1.0", "ethcore 1.12.0", "ethcore-accounts 0.1.0", "ethcore-blockchain 0.1.0", @@ -2849,6 +2852,7 @@ name = "parity-ipfs-api" version = "1.12.0" dependencies = [ "cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "client-traits 0.1.0", "common-types 0.1.0", "ethcore 1.12.0", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2912,6 +2916,7 @@ dependencies = [ "client-traits 0.1.0", "common-types 0.1.0", "eip-712 0.1.0", + "engine 0.1.0", "ethash 1.12.0", "ethcore 1.12.0", "ethcore-accounts 0.1.0", @@ -3033,6 +3038,7 @@ dependencies = [ name = "parity-updater" version = "1.12.0" dependencies = [ + "client-traits 0.1.0", "common-types 0.1.0", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index ea85995a556..4e14b305274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ jsonrpc-core = "12.0.0" parity-bytes = "0.1" client-traits = { path = "ethcore/client-traits" } common-types = { path = "ethcore/types" } +engine = { path = "ethcore/engine" } ethcore = { path = "ethcore", features = ["parity"] } ethcore-accounts = { path = "accounts", optional = true } ethcore-blockchain = { path = "ethcore/blockchain" } diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 998d82b6229..0e59eb585cb 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -12,6 +12,7 @@ parity-bytes = "0.1" client-traits = { path = "../client-traits" } common-types = { path = "../types" } derive_more = "0.14.0" +engine = { path = "../engine" } ethcore = { path = ".."} ethcore-db = { path = "../db" } ethcore-blockchain = { path = "../blockchain" } diff --git a/ethcore/light/src/client/fetch.rs b/ethcore/light/src/client/fetch.rs index 602be8fc3a6..cbb5d3e2279 100644 --- a/ethcore/light/src/client/fetch.rs +++ b/ethcore/light/src/client/fetch.rs @@ -18,10 +18,12 @@ use std::sync::Arc; -use common_types::encoded; -use common_types::header::Header; -use common_types::receipt::Receipt; -use ethcore::engines::{Engine, StateDependentProof}; +use common_types::{ + header::Header, + encoded, + receipt::Receipt, +}; +use engine::{Engine, StateDependentProof}; use ethereum_types::H256; use futures::future::IntoFuture; diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index 6d4dd5a0b09..140d128f0e5 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -18,8 +18,9 @@ use std::sync::{Weak, Arc}; +use engine::{Engine, EpochChange, Proof}; use ethcore::client::{ClientReport, EnvInfo, ClientIoMessage}; -use ethcore::engines::{epoch, Engine, EpochChange, EpochTransition, Proof}; +use ethcore::engines::{epoch, EpochTransition}; use ethcore::verification::queue::{self, HeaderQueue}; use ethcore::spec::{Spec, SpecHardcodedSync}; use io::IoChannel; @@ -616,13 +617,13 @@ impl LightChainClient for Client { } } -impl ::ethcore::client::ChainInfo for Client { +impl client_traits::ChainInfo for Client { fn chain_info(&self) -> BlockChainInfo { Client::chain_info(self) } } -impl ::ethcore::client::EngineClient for Client { +impl client_traits::EngineClient for Client { fn update_sealing(&self) { } fn submit_seal(&self, _block_hash: H256, _seal: Vec>) { } fn broadcast_consensus_message(&self, _message: Vec) { } @@ -635,7 +636,7 @@ impl ::ethcore::client::EngineClient for Client { }) } - fn as_full_client(&self) -> Option<&dyn (::ethcore::client::BlockChainClient)> { + fn as_full_client(&self) -> Option<&dyn (client_traits::BlockChainClient)> { None } diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index 64b7f7d69dc..9b9c4053315 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -56,6 +56,7 @@ extern crate log; extern crate bincode; extern crate client_traits; extern crate common_types; +extern crate engine; extern crate ethcore_blockchain; extern crate ethcore_db; extern crate ethcore_io as io; diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index f74d2e492e1..704155ae8b9 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -24,7 +24,7 @@ use common_types::basic_account::BasicAccount; use common_types::encoded; use common_types::receipt::Receipt; use common_types::transaction::SignedTransaction; -use ethcore::engines::{Engine, StateDependentProof}; +use engine::{Engine, StateDependentProof}; use ethcore::executive_state::{ProvedExecution, self}; use ethereum_types::{H256, U256, Address}; use ethtrie::{TrieError, TrieDB}; diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index 5e9533d5bc5..b50d01face6 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -25,8 +25,12 @@ use common_types::{ ids::BlockId, transaction::PendingTransaction, }; -use ethcore::client::{BlockChainClient, ProvingBlockChainClient, ChainInfo}; -use client_traits::BlockInfo as ClientBlockInfo; +use ethcore::client::ProvingBlockChainClient; +use client_traits::{ + BlockChainClient, + BlockInfo as ClientBlockInfo, + ChainInfo, +}; use ethereum_types::H256; use parking_lot::RwLock; diff --git a/ethcore/node-filter/Cargo.toml b/ethcore/node-filter/Cargo.toml index e174e6189c7..73a8612523d 100644 --- a/ethcore/node-filter/Cargo.toml +++ b/ethcore/node-filter/Cargo.toml @@ -7,6 +7,7 @@ version = "1.12.0" authors = ["Parity Technologies "] [dependencies] +client-traits = { path = "../client-traits" } common-types = { path = "../types" } ethcore = { path = ".."} ethcore-network = { path = "../../util/network" } diff --git a/ethcore/node-filter/src/lib.rs b/ethcore/node-filter/src/lib.rs index 2886a58e3f3..3fffc718163 100644 --- a/ethcore/node-filter/src/lib.rs +++ b/ethcore/node-filter/src/lib.rs @@ -16,6 +16,7 @@ //! Smart contract based node filter. +extern crate client_traits; extern crate common_types; extern crate ethabi; extern crate ethcore; @@ -25,8 +26,6 @@ extern crate ethereum_types; extern crate lru_cache; extern crate parking_lot; -#[macro_use] -extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; #[cfg(test)] @@ -42,7 +41,8 @@ use std::collections::{HashMap, VecDeque}; use std::sync::Weak; use common_types::ids::BlockId; -use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks}; +use ethcore::client::{ChainNotify, NewBlocks}; +use client_traits::BlockChainClient; use ethereum_types::{H256, Address}; use ethabi::FunctionOutputDecoder; use network::{ConnectionFilter, ConnectionDirection}; @@ -54,7 +54,7 @@ use_contract!(peer_set, "res/peer_set.json"); /// Connection filter that uses a contract to manage permissions. pub struct NodeFilter { - client: Weak, + client: Weak, contract_address: Address, cache: RwLock } diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs index 323f44a692e..d62ba546b6a 100644 --- a/ethcore/private-tx/src/encryptor.rs +++ b/ethcore/private-tx/src/encryptor.rs @@ -81,7 +81,7 @@ pub struct SecretStoreEncryptor { config: EncryptorConfig, client: FetchClient, sessions: Mutex>, - signer: Arc, + signer: Arc, } impl SecretStoreEncryptor { @@ -89,7 +89,7 @@ impl SecretStoreEncryptor { pub fn new( config: EncryptorConfig, client: FetchClient, - signer: Arc, + signer: Arc, ) -> Result { Ok(SecretStoreEncryptor { config, diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index ebbfb191875..283df9b7a8e 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -91,11 +91,12 @@ use ethkey::{Signature, recover, public_to_address}; use io::IoChannel; use machine::{ executive::{Executive, TransactOptions, contract_address as ethcore_contract_address}, - executed::Executed, + executed::Executed as FlatExecuted, }; use types::{ ids::BlockId, - transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction} + transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}, + engines::machine::Executed, }; use ethcore::client::{ Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, Call @@ -307,7 +308,7 @@ impl Provider { nonce_cache, engine, local_accounts, - None, // refuse_service_transactions = true + None, // refuse_service_transactions = true ) } @@ -456,7 +457,7 @@ impl Provider { } } - fn last_required_signature(&self, desc: &PrivateTransactionSigningDesc, sign: Signature) -> Result<(bool, Address), Error> { + fn last_required_signature(&self, desc: &PrivateTransactionSigningDesc, sign: Signature) -> Result<(bool, Address), Error> { let state_hash = self.calculate_state_hash(&desc.state, desc.contract_nonce); match recover(&sign, &state_hash) { Ok(public) => { @@ -702,7 +703,7 @@ impl Provider { } /// Call into private contract. - pub fn private_call(&self, block: BlockId, transaction: &SignedTransaction) -> Result { + pub fn private_call(&self, block: BlockId, transaction: &SignedTransaction) -> Result { let result = self.execute_private(transaction, TransactOptions::with_no_tracing(), block)?; Ok(result.result) } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 5e7c17c9cbe..f7e5003d82b 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -53,19 +53,23 @@ use types::{ receipt::{Receipt, LocalizedReceipt, TransactionOutcome}, view, views::BlockView, + verification_queue_info::Unverified, + client_types::Mode, }; use vm::Schedule; use block::{OpenBlock, SealedBlock, ClosedBlock}; use call_contract::{CallContract, RegistryInfo}; use client::{ - Nonce, Balance, ChainInfo, ReopenBlock, TransactionInfo, - PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, Mode, - LastHashes, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, - ImportBlock, StateOrBlock, Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, - SealedBlockImporter, IoClient, BadBlocks + ReopenBlock, PrepareOpenBlock, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, + BroadcastProposalBlock, Call, StateClient, EngineInfo, BlockProducer, SealedBlockImporter, + BlockChainInfo, BlockStatus, LastHashes, +}; +use client_traits::{ + BlockInfo, Nonce, Balance, ChainInfo, TransactionInfo, BlockChainClient, ImportBlock, + AccountData, BlockChain, IoClient, BadBlocks, + StateOrBlock }; -use client_traits::BlockInfo; use engine::Engine; use machine::executed::Executed; use journaldb; @@ -75,7 +79,6 @@ use account_state::state::StateInfo; use state_db::StateDB; use trace::LocalizedTrace; use verification::queue::QueueInfo as BlockQueueInfo; -use verification::queue::kind::blocks::Unverified; /// Test client. pub struct TestBlockChainClient { diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 2349b781cc6..d5c861b8979 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -33,20 +33,23 @@ use kvdb_rocksdb::{self, Database, DatabaseConfig}; use parking_lot::RwLock; use rlp::{self, RlpStream}; use tempdir::TempDir; -use types::transaction::{Action, Transaction, SignedTransaction}; -use types::encoded; -use types::header::Header; -use types::view; -use types::views::BlockView; +use types::{ + transaction::{Action, Transaction, SignedTransaction}, + encoded, + header::Header, + view, + views::BlockView, + verification_queue_info::Unverified, +}; use block::{OpenBlock, Drain}; -use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify, ChainMessageType, PrepareOpenBlock}; +use client::{Client, ClientConfig, ChainNotify, ChainMessageType, PrepareOpenBlock}; +use client_traits::{ChainInfo, ImportBlock}; use trie_vm_factories::Factories; use miner::Miner; use spec::{Spec, self}; use account_state::*; use state_db::StateDB; -use verification::queue::kind::blocks::Unverified; /// Creates test block with corresponding header pub fn create_test_block(header: &Header) -> Bytes { diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index 9a8c6a8bf3a..3a662f8cb6a 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -32,7 +32,8 @@ use futures::sync::mpsc as futures_mpsc; use futures::Stream; use io::{TimerToken}; use ethkey::Secret; -use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainMessageType}; +use ethcore::client::{ChainNotify, NewBlocks, ChainMessageType}; +use client_traits::BlockChainClient; use ethcore::snapshot::SnapshotService; use types::BlockNumber; use sync_io::NetSyncIo; diff --git a/ethcore/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs index e5b89253668..0b8ca55122e 100644 --- a/ethcore/sync/src/blocks.rs +++ b/ethcore/sync/src/blocks.rs @@ -22,9 +22,11 @@ use triehash_ethereum::ordered_trie_root; use bytes::Bytes; use rlp::{Rlp, RlpStream, DecoderError}; use network; -use ethcore::verification::queue::kind::blocks::Unverified; -use types::transaction::UnverifiedTransaction; -use types::header::Header as BlockHeader; +use types::{ + transaction::UnverifiedTransaction, + header::Header as BlockHeader, + verification_queue_info::Unverified, +}; malloc_size_of_is_0!(HeaderId); diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index 15fd65e0f1a..20fea88d761 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -19,7 +19,6 @@ use block_sync::{BlockDownloaderImportError as DownloaderImportError, DownloadAc use bytes::Bytes; use enum_primitive::FromPrimitive; use ethcore::snapshot::{ManifestData, RestorationStatus}; -use ethcore::verification::queue::kind::blocks::Unverified; use ethereum_types::{H256, U256}; use hash::keccak; use network::PeerId; @@ -34,6 +33,7 @@ use types::{ block_status::BlockStatus, ids::BlockId, errors::{EthcoreError, ImportError, BlockError}, + verification_queue_info::Unverified, }; use super::sync_packet::{PacketInfo, SyncPacket}; diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 1ca7fe0a744..15bd4c8b924 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -108,7 +108,8 @@ use bytes::Bytes; use rlp::{RlpStream, DecoderError}; use network::{self, PeerId, PacketId}; use network::client_version::ClientVersion; -use ethcore::client::{BlockChainClient, BlockStatus, BlockChainInfo, BlockQueueInfo}; +use ethcore::client::{BlockStatus, BlockChainInfo, BlockQueueInfo}; +use client_traits::BlockChainClient; use ethcore::snapshot::RestorationStatus; use sync_io::SyncIo; use super::{WarpSync, SyncConfig}; diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index 4f71170bce4..a2825687abf 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -21,6 +21,7 @@ //! https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol //! +extern crate client_traits; extern crate common_types as types; extern crate ethcore; extern crate ethcore_io as io; diff --git a/ethcore/sync/src/sync_io.rs b/ethcore/sync/src/sync_io.rs index 73f95caf9f5..b7a25bafda8 100644 --- a/ethcore/sync/src/sync_io.rs +++ b/ethcore/sync/src/sync_io.rs @@ -19,7 +19,7 @@ use chain::sync_packet::{PacketInfo, SyncPacket}; use network::{NetworkContext, PeerId, PacketId, Error, SessionInfo, ProtocolId}; use network::client_version::ClientVersion; use bytes::Bytes; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use types::BlockNumber; use ethcore::snapshot::SnapshotService; use parking_lot::RwLock; diff --git a/ipfs/Cargo.toml b/ipfs/Cargo.toml index 3df59d012f0..44902200e9d 100644 --- a/ipfs/Cargo.toml +++ b/ipfs/Cargo.toml @@ -6,6 +6,7 @@ license = "GPL-3.0" authors = ["Parity Technologies "] [dependencies] +client-traits = { path = "../ethcore/client-traits" } common-types = { path = "../ethcore/types" } ethcore = { path = "../ethcore" } parity-bytes = "0.1" diff --git a/ipfs/src/lib.rs b/ipfs/src/lib.rs index 635fd4c76ea..40ff2bd1891 100644 --- a/ipfs/src/lib.rs +++ b/ipfs/src/lib.rs @@ -19,6 +19,7 @@ extern crate cid; extern crate unicase; extern crate rlp; +extern crate client_traits; extern crate common_types; extern crate ethcore; extern crate parity_bytes as bytes; @@ -35,7 +36,7 @@ use std::net::{SocketAddr, IpAddr}; use core::futures::future::{self, FutureResult}; use core::futures::{self, Future}; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use http::hyper::{self, server, Method, StatusCode, Body, header::{self, HeaderValue}, }; diff --git a/parity/account_utils.rs b/parity/account_utils.rs index 88a8dcfd484..9c380c2f56e 100644 --- a/parity/account_utils.rs +++ b/parity/account_utils.rs @@ -133,7 +133,7 @@ mod accounts { } pub fn miner_author(spec: &SpecType, dirs: &Directories, account_provider: &Arc, engine_signer: Address, passwords: &[Password]) -> Result, String> { - use ethcore::engines::EngineSigner; + use engine::signer::EngineSigner; // Check if engine signer exists if !account_provider.has_account(engine_signer) { diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 7d19333be0b..1c077c03b9b 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -26,13 +26,12 @@ use hash::{keccak, KECCAK_NULL_RLP}; use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; -use client_traits::BlockInfo; -use ethcore::client::{ - Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, ImportBlock, BlockChainReset +use client_traits::{BlockInfo, Nonce, Balance, BlockChainClient, ImportBlock}; +use ethcore::{ + client::{DatabaseCompactionProfile, VMType, BlockChainReset}, + miner::Miner, + verification::queue::VerifierSettings, }; -use ethcore::miner::Miner; -use ethcore::verification::queue::VerifierSettings; -use ethcore::verification::queue::kind::blocks::Unverified; use ethcore_service::ClientService; use cache::CacheConfig; use informant::{Informant, FullNodeInformantData, MillisecondDuration}; @@ -45,7 +44,9 @@ use db; use ansi_term::Colour; use types::{ ids::BlockId, - errors::{ImportError, EthcoreError} + errors::{ImportError, EthcoreError}, + client_types::Mode, + verification_queue_info::Unverified, }; #[derive(Debug, PartialEq)] diff --git a/parity/helpers.rs b/parity/helpers.rs index 1c9494e3ddf..f22cbd795ad 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -21,7 +21,7 @@ use std::fs::File; use std::collections::HashSet; use ethereum_types::{U256, Address}; use journaldb::Algorithm; -use ethcore::client::{Mode, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; +use ethcore::client::{VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; use ethcore::miner::{PendingSet, Penalization}; use miner::pool::PrioritizationStrategy; use cache::CacheConfig; @@ -32,7 +32,10 @@ use sync::{validate_node_url, self}; use db::migrate; use path; use ethkey::Password; -use types::ids::BlockId; +use types::{ + ids::BlockId, + client_types::Mode, +}; pub fn to_duration(s: &str) -> Result { to_seconds(s).map(Duration::from_secs) diff --git a/parity/informant.rs b/parity/informant.rs index cd2690b23bb..da7887c2348 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -24,10 +24,10 @@ use std::time::{Instant, Duration}; use atty; use ethcore::client::{ - ChainInfo, BlockChainInfo, BlockChainClient, - BlockQueueInfo, ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage + BlockChainInfo, BlockQueueInfo, ChainNotify, NewBlocks, + ClientReport, Client, ClientIoMessage }; -use client_traits::BlockInfo; +use client_traits::{BlockInfo, ChainInfo, BlockChainClient}; use types::{ BlockNumber, ids::BlockId, diff --git a/parity/ipfs.rs b/parity/ipfs.rs index 0923a1e7d40..f8062f52a1c 100644 --- a/parity/ipfs.rs +++ b/parity/ipfs.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use parity_ipfs_api::{self, AccessControlAllowOrigin, Host, Listening}; use parity_ipfs_api::error::ServerError; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; #[derive(Debug, PartialEq, Clone)] pub struct Configuration { diff --git a/parity/lib.rs b/parity/lib.rs index 2e5e5c1b838..86abde9da24 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -44,6 +44,7 @@ extern crate cli_signer; extern crate client_traits; extern crate common_types as types; +extern crate engine; extern crate ethcore; extern crate ethcore_call_contract as call_contract; extern crate ethcore_db; diff --git a/parity/light_helpers/epoch_fetch.rs b/parity/light_helpers/epoch_fetch.rs index 95eea58586d..f73aec57dcf 100644 --- a/parity/light_helpers/epoch_fetch.rs +++ b/parity/light_helpers/epoch_fetch.rs @@ -16,11 +16,13 @@ use std::sync::{Arc, Weak}; -use ethcore::engines::{Engine, StateDependentProof}; +use engine::{Engine, StateDependentProof}; use sync::{LightSync, LightNetworkDispatcher}; -use types::encoded; -use types::header::Header; -use types::receipt::Receipt; +use types::{ + header::Header, + encoded, + receipt::Receipt, +}; use futures::{future, Future}; use futures::future::Either; diff --git a/parity/modules.rs b/parity/modules.rs index 8c86cda9b95..f8607b827ff 100644 --- a/parity/modules.rs +++ b/parity/modules.rs @@ -16,7 +16,7 @@ use std::sync::{Arc, mpsc}; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use sync::{self, SyncConfig, NetworkConfiguration, Params, ConnectionFilter}; use ethcore::snapshot::SnapshotService; use light::Provider; diff --git a/parity/params.rs b/parity/params.rs index bee919290fe..7560a6c2b20 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -18,7 +18,6 @@ use std::collections::HashSet; use std::time::Duration; use std::{str, fs, fmt}; -use ethcore::client::Mode; use ethcore::spec::{Spec, SpecParams, self}; use ethereum_types::{U256, Address}; use parity_runtime::Executor; @@ -28,6 +27,7 @@ use miner::gas_pricer::GasPricer; use miner::gas_price_calibrator::{GasPriceCalibratorOptions, GasPriceCalibrator}; use parity_version::version_data; use user_defaults::UserDefaults; +use types::client_types::Mode; #[derive(Debug, PartialEq)] pub enum SpecType { diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index b3aec40dcc2..0b9d4d9f58b 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -25,7 +25,7 @@ use account_utils::{self, AccountProvider}; use ethcore::client::Client; use ethcore::miner::Miner; use ethcore::snapshot::SnapshotService; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use sync::SyncState; use ethcore_logger::RotatingLogger; use ethcore_private_tx::Provider as PrivateTransactionManager; diff --git a/parity/run.rs b/parity/run.rs index 6f1c441f18e..82ae9694f73 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -22,8 +22,8 @@ use std::thread; use ansi_term::Colour; use bytes::Bytes; use call_contract::CallContract; -use client_traits::BlockInfo; -use ethcore::client::{Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient}; +use client_traits::{BlockInfo, BlockChainClient}; +use ethcore::client::{Client, DatabaseCompactionProfile, VMType}; use ethcore::miner::{self, stratum, Miner, MinerService, MinerOptions}; use ethcore::snapshot::{self, SnapshotConfiguration}; use ethcore::spec::{SpecParams, OptimizeFor}; @@ -41,7 +41,10 @@ use miner::work_notify::WorkPoster; use node_filter::NodeFilter; use parity_runtime::Runtime; use sync::{self, SyncConfig, PrivateTxHandler}; -use types::ids::BlockId; +use types::{ + client_types::Mode, + ids::BlockId, +}; use parity_rpc::{ Origin, Metadata, NetworkSettings, informant, PubSubSession, FutureResult, FutureResponse, FutureOutput }; diff --git a/parity/snapshot.rs b/parity/snapshot.rs index c1d2a77e3fd..19cfb489718 100644 --- a/parity/snapshot.rs +++ b/parity/snapshot.rs @@ -21,13 +21,17 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use hash::keccak; -use ethcore::snapshot::{Progress, RestorationStatus, SnapshotConfiguration, SnapshotService as SS}; +use ethcore::snapshot::{RestorationStatus, SnapshotConfiguration, SnapshotService as SS}; use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter}; use ethcore::snapshot::service::Service as SnapshotService; -use ethcore::client::{Mode, DatabaseCompactionProfile, VMType}; +use ethcore::client::{DatabaseCompactionProfile, VMType}; use ethcore::miner::Miner; use ethcore_service::ClientService; -use types::ids::BlockId; +use types::{ + ids::BlockId, + snapshot::Progress, + client_types::Mode, +}; use cache::CacheConfig; use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_bool}; diff --git a/parity/user_defaults.rs b/parity/user_defaults.rs index bdd5d9efb33..34e68dd824d 100644 --- a/parity/user_defaults.rs +++ b/parity/user_defaults.rs @@ -22,7 +22,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::de::from_reader; use serde_json::ser::to_string; use journaldb::Algorithm; -use ethcore::client::{Mode as ClientMode}; +use types::client_types::Mode as ClientMode; #[derive(Clone)] pub struct Seconds(Duration); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index fc5baa868be..507b821ef24 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -35,7 +35,9 @@ jsonrpc-ws-server = "12.0.0" jsonrpc-ipc-server = "12.0.0" jsonrpc-pubsub = "12.0.0" +client-traits = { path = "../ethcore/client-traits" } common-types = { path = "../ethcore/types" } +engine = { path = "../ethcore/engine" } ethash = { path = "../ethash" } ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-accounts = { path = "../accounts", optional = true } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 37749cf43d7..1ae66453ba9 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -61,7 +61,9 @@ extern crate jsonrpc_http_server as http; extern crate jsonrpc_ipc_server as ipc; extern crate jsonrpc_pubsub; +extern crate client_traits; extern crate common_types as types; +extern crate engine; extern crate ethash; extern crate ethcore; extern crate fastmap; diff --git a/rpc/src/v1/helpers/dispatch/full.rs b/rpc/src/v1/helpers/dispatch/full.rs index d958416cbf2..8c23f720822 100644 --- a/rpc/src/v1/helpers/dispatch/full.rs +++ b/rpc/src/v1/helpers/dispatch/full.rs @@ -16,7 +16,7 @@ use std::sync::Arc; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use ethcore::miner::{self, MinerService}; use ethereum_types::{H256, U256, Address}; use types::transaction::{SignedTransaction, PendingTransaction}; diff --git a/rpc/src/v1/helpers/dispatch/mod.rs b/rpc/src/v1/helpers/dispatch/mod.rs index 3f247f0c6c0..fa82385087b 100644 --- a/rpc/src/v1/helpers/dispatch/mod.rs +++ b/rpc/src/v1/helpers/dispatch/mod.rs @@ -75,7 +75,7 @@ use std::ops::Deref; use std::sync::Arc; use bytes::Bytes; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use ethcore::miner::MinerService; use ethereum_types::{H520, H256, U256, Address}; use ethkey::{Password, Signature}; diff --git a/rpc/src/v1/helpers/engine_signer.rs b/rpc/src/v1/helpers/engine_signer.rs index 4cc3608cb96..fd40dc95e24 100644 --- a/rpc/src/v1/helpers/engine_signer.rs +++ b/rpc/src/v1/helpers/engine_signer.rs @@ -33,7 +33,7 @@ impl EngineSigner { } } -impl ethcore::engines::EngineSigner for EngineSigner { +impl engine::signer::EngineSigner for EngineSigner { fn sign(&self, message: ethkey::Message) -> Result { match self.accounts.sign(self.address, Some(self.password.clone()), message) { Ok(ok) => Ok(ok), diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 9e0d6de3c87..ef4a9daa8b2 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -24,7 +24,7 @@ use types::transaction::Error as TransactionError; use ethcore_private_tx::Error as PrivateTransactionError; use vm::Error as VMError; use light::on_demand::error::{Error as OnDemandError}; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use types::{ ids::BlockId, blockchain_info::BlockChainInfo, diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 2a78f46f4d3..f2e67f86c9d 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -741,7 +741,7 @@ where tx: EthTransaction, hdr: encoded::Header, env_info: ::vm::EnvInfo, - engine: Arc<::ethcore::engines::Engine>, + engine: Arc, on_demand: Arc, sync: Arc, } diff --git a/rpc/src/v1/impls/debug.rs b/rpc/src/v1/impls/debug.rs index e46dd628d1e..64e2acac6c2 100644 --- a/rpc/src/v1/impls/debug.rs +++ b/rpc/src/v1/impls/debug.rs @@ -18,7 +18,7 @@ use std::sync::Arc; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use types::header::Header; use types::transaction::LocalizedTransaction; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 0511c52410f..de11de63754 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -24,8 +24,9 @@ use rlp::Rlp; use ethereum_types::{Address, H64, H160, H256, U64, U256, BigEndianHash}; use parking_lot::Mutex; +use client_traits::{BlockChainClient, StateOrBlock}; use ethash::{self, SeedHashCompute}; -use ethcore::client::{BlockChainClient, StateOrBlock, StateClient, StateInfo, Call, EngineInfo, ProvingBlockChainClient}; +use ethcore::client::{StateClient, StateInfo, Call, EngineInfo, ProvingBlockChainClient}; use ethcore::miner::{self, MinerService}; use ethcore::snapshot::SnapshotService; use hash::keccak; diff --git a/rpc/src/v1/impls/eth_filter.rs b/rpc/src/v1/impls/eth_filter.rs index b205dde572c..8bab9005883 100644 --- a/rpc/src/v1/impls/eth_filter.rs +++ b/rpc/src/v1/impls/eth_filter.rs @@ -19,7 +19,7 @@ use std::sync::Arc; use std::collections::{BTreeSet, VecDeque}; -use ethcore::client::BlockChainClient; +use client_traits::BlockChainClient; use ethcore::miner::{self, MinerService}; use ethereum_types::{H256, U256}; use parking_lot::Mutex; diff --git a/rpc/src/v1/impls/eth_pubsub.rs b/rpc/src/v1/impls/eth_pubsub.rs index fd557b09615..d9fe2329e91 100644 --- a/rpc/src/v1/impls/eth_pubsub.rs +++ b/rpc/src/v1/impls/eth_pubsub.rs @@ -31,7 +31,8 @@ use v1::traits::EthPubSub; use v1::types::{pubsub, RichHeader, Log}; use sync::{SyncState, Notification}; -use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainRouteType}; +use ethcore::client::{ChainNotify, NewBlocks, ChainRouteType}; +use client_traits::BlockChainClient; use ethereum_types::H256; use light::cache::Cache; use light::client::{LightChainClient, LightChainNotify}; diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 305205644b4..4994c4db55c 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -20,7 +20,8 @@ use std::collections::BTreeMap; use crypto::DEFAULT_MAC; use ethereum_types::{H64, H160, H256, H512, U64, U256}; -use ethcore::client::{BlockChainClient, StateClient, Call}; +use ethcore::client::{StateClient, Call}; +use client_traits::BlockChainClient; use ethcore::miner::{self, MinerService, FilterOptions}; use ethcore::snapshot::{SnapshotService, RestorationStatus}; use account_state::state::StateInfo; @@ -30,7 +31,10 @@ use ethstore::random_phrase; use jsonrpc_core::futures::future; use jsonrpc_core::{BoxFuture, Result}; use sync::{SyncProvider, ManageNetwork}; -use types::ids::BlockId; +use types::{ + ids::BlockId, + verification_queue_info::Unverified, +}; use updater::{Service as UpdateService}; use version::version_data; @@ -48,7 +52,6 @@ use v1::types::{ block_number_to_id }; use Host; -use ethcore::verification::queue::kind::blocks::Unverified; /// Parity implementation. pub struct ParityClient { diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index b7cef6c6b8c..25d06ed8514 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -19,7 +19,8 @@ use std::io; use std::sync::Arc; use std::time::Duration; -use ethcore::client::{BlockChainClient, Mode}; +use client_traits::BlockChainClient; +use types::client_types::Mode; use ethcore::miner::{self, MinerService}; use ethereum_types::{H160, H256, U256}; use ethkey; @@ -161,7 +162,7 @@ impl ParitySet for ParitySetClient where fn set_engine_signer_secret(&self, secret: H256) -> Result { let keypair = ethkey::KeyPair::from_secret(secret.into()).map_err(|e| errors::account("Invalid secret", e))?; - self.miner.set_author(miner::Author::Sealer(ethcore::engines::signer::from_keypair(keypair))); + self.miner.set_author(miner::Author::Sealer(engine::signer::from_keypair(keypair))); Ok(true) } diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index b279c127dc7..f0c779654a5 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -18,7 +18,8 @@ use std::sync::Arc; -use ethcore::client::{BlockChainClient, StateClient, StateInfo, Call}; +use ethcore::client::{StateClient, StateInfo, Call}; +use client_traits::BlockChainClient; use ethereum_types::H256; use rlp::Rlp; use types::{ diff --git a/updater/Cargo.toml b/updater/Cargo.toml index 2229f376ebd..3ea95d5987f 100644 --- a/updater/Cargo.toml +++ b/updater/Cargo.toml @@ -6,6 +6,7 @@ license = "GPL-3.0" authors = ["Parity Technologies "] [dependencies] +client-traits = { path = "../ethcore/client-traits" } common-types = { path = "../ethcore/types" } ethabi = "8.0" ethabi-contract = "8.0" diff --git a/updater/src/lib.rs b/updater/src/lib.rs index f6fad17199a..7bc4eab7df9 100644 --- a/updater/src/lib.rs +++ b/updater/src/lib.rs @@ -18,6 +18,7 @@ #![warn(missing_docs)] +extern crate client_traits; extern crate common_types; extern crate ethabi; extern crate ethcore; diff --git a/updater/src/updater.rs b/updater/src/updater.rs index f9558876d93..ec51ffd9aa0 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -30,7 +30,8 @@ use common_types::{ ids::BlockId, filter::Filter, }; -use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks}; +use ethcore::client::{ChainNotify, NewBlocks}; +use client_traits::BlockChainClient; use ethereum_types::{H256, H160}; use hash_fetch::{self as fetch, HashFetch}; use parity_path::restrict_permissions_owner; From c5ab53477bf218bd794fbf76b2298b733edc4fa3 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 13:02:55 +0200 Subject: [PATCH 24/43] Add an EpochVerifier to ethash and use that in Engine.epoch_verifier() Cleanup --- ethash/src/lib.rs | 2 +- ethcore/engine/src/engine.rs | 1 - ethcore/src/engines/authority_round/mod.rs | 2 +- ethcore/src/engines/ethash.rs | 133 ++++++-- ethcore/src/engines/mod.rs | 344 --------------------- 5 files changed, 105 insertions(+), 377 deletions(-) diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs index 47dd0688d54..3225ceb9f58 100644 --- a/ethash/src/lib.rs +++ b/ethash/src/lib.rs @@ -85,7 +85,7 @@ impl EthashManager { EthashManager { cache_dir: cache_dir.to_path_buf(), nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default(), progpow_transition), - progpow_transition: progpow_transition, + progpow_transition, cache: Mutex::new(LightCache { recent_epoch: None, recent: None, diff --git a/ethcore/engine/src/engine.rs b/ethcore/engine/src/engine.rs index 4b509c084bb..ef6adad8f0d 100644 --- a/ethcore/engine/src/engine.rs +++ b/ethcore/engine/src/engine.rs @@ -306,7 +306,6 @@ pub trait Engine: Sync + Send { /// Trigger next step of the consensus engine. fn step(&self) {} - // todo[dvdplm] sort out this mess: SnapshotComponents depends on Rebuilder and that depends on Engine /// Create a factory for building snapshot chunks and restoring from them. /// Returning `None` indicates that this engine doesn't support snapshot creation. fn snapshot_components(&self) -> Option> { diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index f3d17ee15eb..2bc161b5208 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -461,7 +461,7 @@ struct EpochVerifier { empty_steps_transition: u64, } -impl engine::EpochVerifier for EpochVerifier { +impl engine::EpochVerifier for EpochVerifier { fn verify_light(&self, header: &Header) -> Result<(), Error> { // Validate the timestamp verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?)?; diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index 717ab1d1d82..8f773267aa2 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -181,7 +181,7 @@ impl From for EthashParams { /// mainnet chains in the Olympic, Frontier and Homestead eras. pub struct Ethash { ethash_params: EthashParams, - pow: EthashManager, + pow: Arc, machine: Machine, } @@ -198,11 +198,42 @@ impl Ethash { Ethash { ethash_params, machine, - pow: EthashManager::new(cache_dir.as_ref(), optimize_for.into(), progpow_transition), + pow: Arc::new(EthashManager::new( + cache_dir.as_ref(), + optimize_for.into(), + progpow_transition + )), } } } +fn verify_block_unordered(pow: &Arc, header: &Header) -> Result<(), Error> { + let seal = Seal::parse_seal(header.seal())?; + + let result = pow.compute_light( + header.number() as u64, + &header.bare_hash().0, + seal.nonce.to_low_u64_be() + ); + let mix = H256(result.mix_hash); + let difficulty = ethash::boundary_to_difficulty(&H256(result.value)); + trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}", + num = header.number() as u64, + seed = H256(slow_hash_block_number(header.number() as u64)), + h = header.bare_hash(), + non = seal.nonce.to_low_u64_be(), + mix = H256(result.mix_hash), + res = H256(result.value)); + if mix != seal.mix_hash { + return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash }))); + } + if &difficulty < header.difficulty() { + return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty }))); + } + Ok(()) +} + + // TODO [rphmeier] // // for now, this is different than Ethash's own epochs, and signal @@ -217,11 +248,46 @@ impl Ethash { //pub struct ArcEthash<'a>(Arc<&'a Ethash>); //impl engine::EpochVerifier for Arc { -impl engine::EpochVerifier for Ethash { +//impl<'a> engine::EpochVerifier for &'a Ethash { +// fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } +// fn verify_heavy(&self, header: &Header) -> Result<(), Error> { +// self.verify_block_unordered(header).into() +// } +//} + +struct EpochVerifier { + pow: Arc +} + +impl engine::EpochVerifier for EpochVerifier { fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } fn verify_heavy(&self, header: &Header) -> Result<(), Error> { - self.verify_block_unordered(header).into() + verify_block_unordered(&self.pow, header) } +// let seal = Seal::parse_seal(header.seal())?; +// +// let result = self.pow.compute_light( +// header.number() as u64, +// &header.bare_hash().0, +// seal.nonce.to_low_u64_be() +// ); +// let mix = H256(result.mix_hash); +// let difficulty = ethash::boundary_to_difficulty(&H256(result.value)); +// trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}", +// num = header.number() as u64, +// seed = H256(slow_hash_block_number(header.number() as u64)), +// h = header.bare_hash(), +// non = seal.nonce.to_low_u64_be(), +// mix = H256(result.mix_hash), +// res = H256(result.value)); +// if mix != seal.mix_hash { +// return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash }))); +// } +// if &difficulty < header.difficulty() { +// return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty }))); +// } +// Ok(()) +// } } //impl Engine for Arc { @@ -247,11 +313,6 @@ impl Engine for Ethash { fn maximum_gas_limit(&self) -> Option { Some(0x7fff_ffff_ffff_ffffu64.into()) } - fn populate_from_parent(&self, header: &mut Header, parent: &Header) { - let difficulty = self.calculate_difficulty(header, parent); - header.set_difficulty(difficulty); - } - /// Apply the block reward on finalisation of the block. /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). fn on_close_block(&self, block: &mut ExecutedBlock, _parent_header: &Header) -> Result<(), Error> { @@ -352,25 +413,30 @@ impl Engine for Ethash { } fn verify_block_unordered(&self, header: &Header) -> Result<(), Error> { - let seal = Seal::parse_seal(header.seal())?; - - let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, seal.nonce.to_low_u64_be()); - let mix = H256(result.mix_hash); - let difficulty = ethash::boundary_to_difficulty(&H256(result.value)); - trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}", - num = header.number() as u64, - seed = H256(slow_hash_block_number(header.number() as u64)), - h = header.bare_hash(), - non = seal.nonce.to_low_u64_be(), - mix = H256(result.mix_hash), - res = H256(result.value)); - if mix != seal.mix_hash { - return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash }))); - } - if &difficulty < header.difficulty() { - return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty }))); - } - Ok(()) + verify_block_unordered(&self.pow, header) +// let seal = Seal::parse_seal(header.seal())?; +// +// let result = self.pow.compute_light( +// header.number() as u64, +// &header.bare_hash().0, +// seal.nonce.to_low_u64_be() +// ); +// let mix = H256(result.mix_hash); +// let difficulty = ethash::boundary_to_difficulty(&H256(result.value)); +// trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}", +// num = header.number() as u64, +// seed = H256(slow_hash_block_number(header.number() as u64)), +// h = header.bare_hash(), +// non = seal.nonce.to_low_u64_be(), +// mix = H256(result.mix_hash), +// res = H256(result.value)); +// if mix != seal.mix_hash { +// return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash }))); +// } +// if &difficulty < header.difficulty() { +// return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty }))); +// } +// Ok(()) } fn verify_block_family(&self, header: &Header, parent: &Header) -> Result<(), Error> { @@ -390,13 +456,20 @@ impl Engine for Ethash { fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> engine::ConstructedVerifier<'a> { // todo[dvdplm]: this one's tricky, not sure how to solve this. - engine::ConstructedVerifier::Trusted(Box::new(engine::engine::NoOp)) + let v = EpochVerifier{pow: self.pow.clone()}; + engine::ConstructedVerifier::Trusted(Box::new(v)) +// engine::ConstructedVerifier::Trusted(Box::new(engine::engine::NoOp)) // engine::ConstructedVerifier::Trusted(Box::new(ArcEthash(Arc::new(self)))) -// engine::ConstructedVerifier::Trusted(Box::new(self.clone())) +// engine::ConstructedVerifier::Trusted(Box::new(self.clone())) // original // engine::ConstructedVerifier::Trusted(Box::new(*self)) // engine::ConstructedVerifier::Trusted(Box::new(self)) } + fn populate_from_parent(&self, header: &mut Header, parent: &Header) { + let difficulty = self.calculate_difficulty(header, parent); + header.set_difficulty(difficulty); + } + fn snapshot_components(&self) -> Option> { Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS))) } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 41be6a95dff..6391ed824ee 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -52,16 +52,6 @@ use machine::{ }; use ethereum_types::{H256, U256, Address}; -//// todo[dvdplm] remove -///// Seal type. -//#[derive(Debug, PartialEq, Eq)] -//pub enum Seal { -// /// Regular block seal; should be part of the blockchain. -// Regular(Vec), -// /// Engine does not generate seal for this block right now. -// None, -//} - /// A system-calling closure. Enacts calls on a block's state from the system address. pub type SystemCall<'a> = dyn FnMut(Address, Vec) -> Result, String> + 'a; @@ -106,337 +96,3 @@ pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut Exec result.map_err(|e| format!("{}", e)) } } - -//// todo[dvdplm] moved -///// Proof dependent on state. -//pub trait StateDependentProof: Send + Sync { -// /// Generate a proof, given the state. -// fn generate_proof<'a>(&self, state: &machine_types::Call) -> Result, String>; -// /// Check a proof generated elsewhere (potentially by a peer). -// // `engine` needed to check state proofs, while really this should -// // just be state machine params. -// fn check_proof(&self, machine: &Machine, proof: &[u8]) -> Result<(), String>; -//} -// -//// todo[dvdplm] moved -///// Proof generated on epoch change. -//pub enum Proof { -// /// Known proof (extracted from signal) -// Known(Vec), -// /// State dependent proof. -// WithState(Arc), -//} -// -//// todo[dvdplm] moved -///// Generated epoch verifier. -//pub enum ConstructedVerifier<'a> { -// /// Fully trusted verifier. -// Trusted(Box), -// /// Verifier unconfirmed. Check whether given finality proof finalizes given hash -// /// under previous epoch. -// Unconfirmed(Box, &'a [u8], H256), -// /// Error constructing verifier. -// Err(Error), -//} -// -//// todo[dvdplm] moved -//impl<'a> ConstructedVerifier<'a> { -// /// Convert to a result, indicating that any necessary confirmation has been done -// /// already. -// pub fn known_confirmed(self) -> Result, Error> { -// match self { -// ConstructedVerifier::Trusted(v) | ConstructedVerifier::Unconfirmed(v, _, _) => Ok(v), -// ConstructedVerifier::Err(e) => Err(e), -// } -// } -//} -// -//// todo[dvdplm] moved -///// Results of a query of whether an epoch change occurred at the given block. -//pub enum EpochChange { -// /// Cannot determine until more data is passed. -// Unsure(AuxiliaryRequest), -// /// No epoch change. -// No, -// /// The epoch will change, with proof. -// Yes(Proof), -//} -// -//// todo[dvdplm] moved -///// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. -///// Provides hooks into each of the major parts of block import. -//pub trait Engine: Sync + Send { -// /// The name of this engine. -// fn name(&self) -> &str; -// -// /// Get access to the underlying state machine. -// // TODO: decouple. -// fn machine(&self) -> &Machine; -// -// /// The number of additional header fields required for this engine. -// fn seal_fields(&self, _header: &Header) -> usize { 0 } -// -// /// Additional engine-specific information for the user/developer concerning `header`. -// fn extra_info(&self, _header: &Header) -> BTreeMap { BTreeMap::new() } -// -// /// Maximum number of uncles a block is allowed to declare. -// fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 } -// -// /// Optional maximum gas limit. -// fn maximum_gas_limit(&self) -> Option { None } -// -// /// Block transformation functions, before the transactions. -// /// `epoch_begin` set to true if this block kicks off an epoch. -// fn on_new_block( -// &self, -// _block: &mut ExecutedBlock, -// _epoch_begin: bool, -// ) -> Result<(), Error> { -// Ok(()) -// } -// -// /// Block transformation functions, after the transactions. -// fn on_close_block( -// &self, -// _block: &mut ExecutedBlock, -// _parent_header: &Header, -// ) -> Result<(), Error> { -// Ok(()) -// } -// -// /// Allow mutating the header during seal generation. Currently only used by Clique. -// fn on_seal_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { Ok(()) } -// -// /// Returns the engine's current sealing state. -// fn sealing_state(&self) -> SealingState { SealingState::External } -// -// /// Attempt to seal the block internally. -// /// -// /// If `Some` is returned, then you get a valid seal. -// /// -// /// This operation is synchronous and may (quite reasonably) not be available, in which None will -// /// be returned. -// /// -// /// It is fine to require access to state or a full client for this function, since -// /// light clients do not generate seals. -// fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None } -// -// /// Verify a locally-generated seal of a header. -// /// -// /// If this engine seals internally, -// /// no checks have to be done here, since all internally generated seals -// /// should be valid. -// /// -// /// Externally-generated seals (e.g. PoW) will need to be checked for validity. -// /// -// /// It is fine to require access to state or a full client for this function, since -// /// light clients do not generate seals. -// fn verify_local_seal(&self, header: &Header) -> Result<(), Error>; -// -// /// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import. -// /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. -// fn verify_block_basic(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -// -// /// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import. -// /// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called. -// fn verify_block_unordered(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -// -// /// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import. -// fn verify_block_family(&self, _header: &Header, _parent: &Header) -> Result<(), Error> { Ok(()) } -// -// /// Phase 4 verification. Verify block header against potentially external data. -// /// Should only be called when `register_client` has been called previously. -// fn verify_block_external(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -// -// /// Genesis epoch data. -// fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine_types::Call) -> Result, String> { Ok(Vec::new()) } -// -// /// Whether an epoch change is signalled at the given header but will require finality. -// /// If a change can be enacted immediately then return `No` from this function but -// /// `Yes` from `is_epoch_end`. -// /// -// /// If auxiliary data of the block is required, return an auxiliary request and the function will be -// /// called again with them. -// /// Return `Yes` or `No` when the answer is definitively known. -// /// -// /// Should not interact with state. -// fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange { -// EpochChange::No -// } -// -// /// Whether a block is the end of an epoch. -// /// -// /// This either means that an immediate transition occurs or a block signalling transition -// /// has reached finality. The `Headers` given are not guaranteed to return any blocks -// /// from any epoch other than the current. The client must keep track of finality and provide -// /// the latest finalized headers to check against the transition store. -// /// -// /// Return optional transition proof. -// fn is_epoch_end( -// &self, -// _chain_head: &Header, -// _finalized: &[H256], -// _chain: &Headers
, -// _transition_store: &PendingTransitionStore, -// ) -> Option> { -// None -// } -// -// /// Whether a block is the end of an epoch. -// /// -// /// This either means that an immediate transition occurs or a block signalling transition -// /// has reached finality. The `Headers` given are not guaranteed to return any blocks -// /// from any epoch other than the current. This is a specialized method to use for light -// /// clients since the light client doesn't track finality of all blocks, and therefore finality -// /// for blocks in the current epoch is built inside this method by the engine. -// /// -// /// Return optional transition proof. -// fn is_epoch_end_light( -// &self, -// _chain_head: &Header, -// _chain: &Headers
, -// _transition_store: &PendingTransitionStore, -// ) -> Option> { -// None -// } -// -// /// Create an epoch verifier from validation proof and a flag indicating -// /// whether finality is required. -// fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> ConstructedVerifier<'a> { -// ConstructedVerifier::Trusted(Box::new(NoOp)) -// } -// -// /// Populate a header's fields based on its parent's header. -// /// Usually implements the chain scoring rule based on weight. -// fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) { } -// -// /// Handle any potential consensus messages; -// /// updating consensus state and potentially issuing a new one. -// fn handle_message(&self, _message: &[u8]) -> Result<(), EngineError> { Err(EngineError::UnexpectedMessage) } -// -// /// Register a component which signs consensus messages. -// fn set_signer(&self, _signer: Box) {} -// -// /// Sign using the EngineSigner, to be used for consensus tx signing. -// fn sign(&self, _hash: H256) -> Result { unimplemented!() } -// -// /// Add Client which can be used for sealing, potentially querying the state and sending messages. -// fn register_client(&self, _client: Weak) {} -// -// /// Trigger next step of the consensus engine. -// fn step(&self) {} -// -// /// Create a factory for building snapshot chunks and restoring from them. -// /// Returning `None` indicates that this engine doesn't support snapshot creation. -// fn snapshot_components(&self) -> Option> { -// None -// } -// -// /// Whether this engine supports warp sync. -// fn supports_warp(&self) -> bool { -// self.snapshot_components().is_some() -// } -// -// /// Return a new open block header timestamp based on the parent timestamp. -// fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 { -// use std::{time, cmp}; -// -// let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default(); -// cmp::max(now.as_secs() as u64, parent_timestamp + 1) -// } -// -// /// Check whether the parent timestamp is valid. -// fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { -// header_timestamp > parent_timestamp -// } -// -// /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that -// /// the ancestry exists. -// fn ancestry_actions(&self, _header: &Header, _ancestry: &mut dyn Iterator) -> Vec { -// Vec::new() -// } -// -// /// Returns author should used when executing tx's for this block. -// fn executive_author(&self, header: &Header) -> Result { -// Ok(*header.author()) -// } -// -// /// Get the general parameters of the chain. -// fn params(&self) -> &CommonParams; -// -// /// Get the EVM schedule for the given block number. -// fn schedule(&self, block_number: BlockNumber) -> Schedule { -// self.machine().schedule(block_number) -// } -// -// /// Builtin-contracts for the chain.. -// fn builtins(&self) -> &BTreeMap { -// self.machine().builtins() -// } -// -// /// Attempt to get a handle to a built-in contract. -// /// Only returns references to activated built-ins. -// fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> { -// self.machine().builtin(a, block_number) -// } -// -// /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. -// fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size } -// -// /// The nonce with which accounts begin at given block. -// fn account_start_nonce(&self, block: BlockNumber) -> U256 { -// self.machine().account_start_nonce(block) -// } -// -// /// The network ID that transactions should be signed with. -// fn signing_chain_id(&self, env_info: &EnvInfo) -> Option { -// self.machine().signing_chain_id(env_info) -// } -// -// /// Perform basic/cheap transaction verification. -// /// -// /// This should include all cheap checks that can be done before -// /// actually checking the signature, like chain-replay protection. -// /// -// /// NOTE This is done before the signature is recovered so avoid -// /// doing any state-touching checks that might be expensive. -// /// -// /// TODO: Add flags for which bits of the transaction to check. -// /// TODO: consider including State in the params. -// fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> { -// self.machine().verify_transaction_basic(t, header) -// } -// -// /// Performs pre-validation of RLP decoded transaction before other processing -// fn decode_transaction(&self, transaction: &[u8]) -> Result { -// self.machine().decode_transaction(transaction) -// } -//} -//// todo[dvdplm] moved -///// Verifier for all blocks within an epoch with self-contained state. -//pub trait EpochVerifier: Send + Sync { -// /// Lightly verify the next block header. -// /// This may not be a header belonging to a different epoch. -// fn verify_light(&self, header: &Header) -> Result<(), Error>; -// -// /// Perform potentially heavier checks on the next block header. -// fn verify_heavy(&self, header: &Header) -> Result<(), Error> { -// self.verify_light(header) -// } -// -// /// Check a finality proof against this epoch verifier. -// /// Returns `Some(hashes)` if the proof proves finality of these hashes. -// /// Returns `None` if the proof doesn't prove anything. -// fn check_finality_proof(&self, _proof: &[u8]) -> Option> { -// None -// } -//} -// -//// todo[dvdplm] moved -///// Special "no-op" verifier for stateless, epoch-less engines. -//pub struct NoOp; -// -//// todo[dvdplm] moved -//impl EpochVerifier for NoOp { -// fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -//} From 45c04970b9b43c26896c30f197dcb7f83a271c95 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 13:48:38 +0200 Subject: [PATCH 25/43] Document pub members --- ethcore/types/src/snapshot.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ethcore/types/src/snapshot.rs b/ethcore/types/src/snapshot.rs index e59bbf8cea8..dd58279e267 100644 --- a/ethcore/types/src/snapshot.rs +++ b/ethcore/types/src/snapshot.rs @@ -25,10 +25,15 @@ use bytes::Bytes; /// A progress indicator for snapshots. #[derive(Debug, Default)] pub struct Progress { + /// Number of accounts processed so far pub accounts: AtomicUsize, + /// Number of blocks processed so far pub blocks: AtomicUsize, + /// Size in bytes of a all compressed chunks processed so far pub size: AtomicU64, + /// Signals that the snapshotting process is completed pub done: AtomicBool, + /// Signal snapshotting process to abort pub abort: AtomicBool, } From b11a21f0c399c7536206ddc17b92a9b69758d36d Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 13:48:51 +0200 Subject: [PATCH 26/43] Sort out tests Sort out default impls for EpochVerifier --- ethcore/engine/Cargo.toml | 4 +++- ethcore/engine/src/engine.rs | 6 ++---- ethcore/engine/src/signer.rs | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ethcore/engine/Cargo.toml b/ethcore/engine/Cargo.toml index fe11797caf7..def6250c2eb 100644 --- a/ethcore/engine/Cargo.toml +++ b/ethcore/engine/Cargo.toml @@ -17,4 +17,6 @@ machine = { path = "../machine" } bytes = { package = "parity-bytes", version = "0.1.0" } vm = { path = "../vm" } - +[dev-dependencies] +accounts = { package = "ethcore-accounts", path = "../../accounts" } +log = "0.4.8" diff --git a/ethcore/engine/src/engine.rs b/ethcore/engine/src/engine.rs index ef6adad8f0d..33c25335792 100644 --- a/ethcore/engine/src/engine.rs +++ b/ethcore/engine/src/engine.rs @@ -397,7 +397,7 @@ pub trait Engine: Sync + Send { pub trait EpochVerifier: Send + Sync { /// Lightly verify the next block header. /// This may not be a header belonging to a different epoch. - fn verify_light(&self, header: &Header) -> Result<(), Error>; + fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } /// Perform potentially heavier checks on the next block header. fn verify_heavy(&self, header: &Header) -> Result<(), Error> { @@ -415,6 +415,4 @@ pub trait EpochVerifier: Send + Sync { /// Special "no-op" verifier for stateless, epoch-less engines. pub struct NoOp; -impl EpochVerifier for NoOp { - fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -} +impl EpochVerifier for NoOp {} diff --git a/ethcore/engine/src/signer.rs b/ethcore/engine/src/signer.rs index 196c535fe76..032a989b618 100644 --- a/ethcore/engine/src/signer.rs +++ b/ethcore/engine/src/signer.rs @@ -50,6 +50,7 @@ mod test_signer { use std::sync::Arc; use ethkey::Password; + use log::warn; use accounts::{self, AccountProvider, SignError}; use super::*; From af485ccb443936e2912c1a5cc91a597906dbbe3e Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 14:55:49 +0200 Subject: [PATCH 27/43] Add test-helpers feature and move EngineSigner impl to the right place --- ethcore/engine/Cargo.toml | 7 +++++ ethcore/engine/src/lib.rs | 5 ++- ethcore/engine/src/signer.rs | 34 --------------------- ethcore/engine/src/test_helpers.rs | 49 ++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 35 deletions(-) create mode 100644 ethcore/engine/src/test_helpers.rs diff --git a/ethcore/engine/Cargo.toml b/ethcore/engine/Cargo.toml index def6250c2eb..48e386d9b79 100644 --- a/ethcore/engine/Cargo.toml +++ b/ethcore/engine/Cargo.toml @@ -17,6 +17,13 @@ machine = { path = "../machine" } bytes = { package = "parity-bytes", version = "0.1.0" } vm = { path = "../vm" } +# used from test-helpers +accounts = { package = "ethcore-accounts", path = "../../accounts", optional = true } +log = { version = "0.4.8", optional = true } + [dev-dependencies] accounts = { package = "ethcore-accounts", path = "../../accounts" } log = "0.4.8" + +[features] +test-helpers = ["accounts", "log"] diff --git a/ethcore/engine/src/lib.rs b/ethcore/engine/src/lib.rs index d3eb9405946..8341e7f6721 100644 --- a/ethcore/engine/src/lib.rs +++ b/ethcore/engine/src/lib.rs @@ -22,7 +22,7 @@ pub mod engine; pub mod signer; pub mod snapshot; -pub use engine::{ +pub use crate::engine::{ Engine, EpochVerifier, StateDependentProof, @@ -30,3 +30,6 @@ pub use engine::{ EpochChange, Proof, }; + +#[cfg(any(test, feature = "test-helpers"))] +pub mod test_helpers; diff --git a/ethcore/engine/src/signer.rs b/ethcore/engine/src/signer.rs index 032a989b618..1e932feefc3 100644 --- a/ethcore/engine/src/signer.rs +++ b/ethcore/engine/src/signer.rs @@ -44,37 +44,3 @@ impl EngineSigner for Signer { self.0.address() } } - -#[cfg(test)] -mod test_signer { - use std::sync::Arc; - - use ethkey::Password; - use log::warn; - use accounts::{self, AccountProvider, SignError}; - - use super::*; - - impl EngineSigner for (Arc, Address, Password) { - fn sign(&self, hash: H256) -> Result { - match self.0.sign(self.1, Some(self.2.clone()), hash) { - Err(SignError::NotUnlocked) => unreachable!(), - Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress), - Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err), - Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => { - warn!("Low level crypto error: {:?}", err); - Err(ethkey::Error::InvalidSecret) - }, - Err(SignError::SStore(err)) => { - warn!("Error signing for engine: {:?}", err); - Err(ethkey::Error::InvalidSignature) - }, - Ok(ok) => Ok(ok), - } - } - - fn address(&self) -> Address { - self.1 - } - } -} diff --git a/ethcore/engine/src/test_helpers.rs b/ethcore/engine/src/test_helpers.rs new file mode 100644 index 00000000000..92ba66ff480 --- /dev/null +++ b/ethcore/engine/src/test_helpers.rs @@ -0,0 +1,49 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Test helpers for engine related tests + +use std::sync::Arc; + +use ethereum_types::{Address, H256}; +use ethkey::{Password, Signature}; +use log::warn; +use accounts::{self, AccountProvider, SignError}; + +use crate::signer::EngineSigner; + +impl EngineSigner for (Arc, Address, Password) { + fn sign(&self, hash: H256) -> Result { + match self.0.sign(self.1, Some(self.2.clone()), hash) { + Err(SignError::NotUnlocked) => unreachable!(), + Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress), + Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err), + Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => { + warn!("Low level crypto error: {:?}", err); + Err(ethkey::Error::InvalidSecret) + }, + Err(SignError::SStore(err)) => { + warn!("Error signing for engine: {:?}", err); + Err(ethkey::Error::InvalidSignature) + }, + Ok(ok) => Ok(ok), + } + } + + fn address(&self) -> Address { + self.1 + } +} From f617bcbf656638ef89bb8aadc4a77347b515f44e Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 14:57:09 +0200 Subject: [PATCH 28/43] Sort out tests --- ethcore/Cargo.toml | 1 + ethcore/client-traits/src/lib.rs | 2 +- ethcore/light/src/client/mod.rs | 2 +- ethcore/machine/src/test_helpers.rs | 1 - ethcore/machine/src/tx_filter.rs | 3 +- ethcore/src/block.rs | 8 +++-- ethcore/src/client/bad_blocks.rs | 2 +- ethcore/src/client/client.rs | 6 ++-- ethcore/src/client/test_client.rs | 2 +- ethcore/src/engines/authority_round/mod.rs | 4 +-- ethcore/src/engines/basic_authority.rs | 2 +- ethcore/src/engines/ethash.rs | 25 -------------- ethcore/src/engines/instant_seal.rs | 6 ++-- ethcore/src/engines/validator_set/contract.rs | 9 ++--- ethcore/src/engines/validator_set/multi.rs | 21 ++++++------ .../engines/validator_set/safe_contract.rs | 33 ++++++++----------- ethcore/src/json_tests/chain.rs | 5 +-- ethcore/src/miner/miner.rs | 9 +++-- ethcore/src/snapshot/tests/helpers.rs | 3 +- .../src/snapshot/tests/proof_of_authority.rs | 3 +- ethcore/src/snapshot/tests/service.rs | 13 +++++--- ethcore/src/test_helpers.rs | 2 +- ethcore/src/tests/client.rs | 8 ++--- ethcore/src/tests/trace.rs | 6 ++-- ethcore/src/verification/queue/kind.rs | 2 +- ethcore/src/verification/queue/mod.rs | 6 ++-- ethcore/src/verification/verification.rs | 2 +- ethcore/sync/src/blocks.rs | 2 +- ethcore/sync/src/chain/handler.rs | 2 +- ethcore/types/src/lib.rs | 2 +- ...fication_queue_info.rs => verification.rs} | 17 +++++----- 31 files changed, 97 insertions(+), 112 deletions(-) rename ethcore/types/src/{verification_queue_info.rs => verification.rs} (96%) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index aafbc358bc9..56bb163f096 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -88,6 +88,7 @@ rlp_compress = { path = "../util/rlp-compress" } serde_json = "1.0" tempdir = "0.3" trie-standardmap = "0.12.4" +engine = { path = "./engine", features = ["test-helpers"] } machine = { path = "./machine", features = ["test-helpers"] } [features] diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs index fbb57c11021..b0d2163f71c 100644 --- a/ethcore/client-traits/src/lib.rs +++ b/ethcore/client-traits/src/lib.rs @@ -35,7 +35,7 @@ use common_types::{ }, blockchain_info::BlockChainInfo, block_status::BlockStatus, - verification_queue_info::{VerificationQueueInfo, Unverified}, //todo[dvdplm] better module name + verification::{VerificationQueueInfo, Unverified}, //todo[dvdplm] better module name transaction::{self, LocalizedTransaction, CallError}, receipt::LocalizedReceipt, tree_route::TreeRoute, diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index 140d128f0e5..8a1100cf649 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -36,7 +36,7 @@ use common_types::{ errors::EthcoreResult, header::Header, ids::BlockId, - verification_queue_info::VerificationQueueInfo as BlockQueueInfo, + verification::VerificationQueueInfo as BlockQueueInfo, }; use kvdb::KeyValueDB; diff --git a/ethcore/machine/src/test_helpers.rs b/ethcore/machine/src/test_helpers.rs index 49394d727bf..2182212b6c8 100644 --- a/ethcore/machine/src/test_helpers.rs +++ b/ethcore/machine/src/test_helpers.rs @@ -20,7 +20,6 @@ use common_types::engines::params::CommonParams; use ethjson; use crate::Machine; - pub fn load_machine(reader: &[u8]) -> Machine { let spec = ethjson::spec::Spec::load(reader).expect("chain spec is invalid"); diff --git a/ethcore/machine/src/tx_filter.rs b/ethcore/machine/src/tx_filter.rs index b688668d408..76a5d571a1b 100644 --- a/ethcore/machine/src/tx_filter.rs +++ b/ethcore/machine/src/tx_filter.rs @@ -153,12 +153,13 @@ mod test { use tempdir::TempDir; use ethereum_types::{U256, Address}; + use client_traits::BlockChainClient; use common_types::{ ids::BlockId, transaction::{Transaction, Action} }; use ethcore::{ - client::{BlockChainClient, Client, ClientConfig}, + client::{Client, ClientConfig}, spec::Spec, miner::Miner, test_helpers, diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index be50257d915..2ed86bb66bf 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -491,11 +491,13 @@ mod tests { use state_db::StateDB; use ethereum_types::Address; use std::sync::Arc; - use verification::queue::kind::blocks::Unverified; - use types::transaction::SignedTransaction; use types::{ - header::Header, view, views::BlockView, errors::EthcoreError as Error, + header::Header, + transaction::SignedTransaction, + view, + views::BlockView, + verification::Unverified, }; use hash_db::EMPTY_PREFIX; use crate::spec; diff --git a/ethcore/src/client/bad_blocks.rs b/ethcore/src/client/bad_blocks.rs index dac71458989..5df225c5b66 100644 --- a/ethcore/src/client/bad_blocks.rs +++ b/ethcore/src/client/bad_blocks.rs @@ -21,7 +21,7 @@ use ethereum_types::H256; use itertools::Itertools; use memory_cache::MemoryLruCache; use parking_lot::RwLock; -use types::verification_queue_info::Unverified; +use types::verification::Unverified; /// Recently seen bad blocks. pub struct BadBlocks { diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 3d03c3f0a73..cbb7532a58f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -92,7 +92,7 @@ use types::{ pruning_info::PruningInfo, call_analytics::CallAnalytics, client_types::Mode, - verification_queue_info::Unverified, // todo[dvdplm] rename the module + verification::Unverified, // todo[dvdplm] rename the module }; use verification::queue::kind::BlockLike; @@ -105,7 +105,7 @@ pub use blockchain::CacheSize as BlockChainCacheSize; use db::{Writable, Readable, keys::BlockDetails}; pub use types::blockchain_info::BlockChainInfo; pub use types::block_status::BlockStatus; -pub use types::verification_queue_info::VerificationQueueInfo as BlockQueueInfo; +pub use types::verification::VerificationQueueInfo as BlockQueueInfo; use_contract!(registry, "res/contracts/registrar.json"); @@ -2666,7 +2666,7 @@ impl IoChannelQueue { #[cfg(test)] mod tests { use ethereum_types::{H256, Address}; - use client::{BlockChainClient, ChainInfo}; + use client_traits::{BlockChainClient, ChainInfo}; use types::{ encoded, ids::{BlockId, TransactionId}, diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index f7e5003d82b..ca71ca4b391 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -53,7 +53,7 @@ use types::{ receipt::{Receipt, LocalizedReceipt, TransactionOutcome}, view, views::BlockView, - verification_queue_info::Unverified, + verification::Unverified, client_types::Mode, }; use vm::Schedule; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 2bc161b5208..a93afa30aff 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1630,7 +1630,7 @@ mod tests { use ethkey::Signature; use types::{ header::Header, - engines::params::CommonParams, + engines::{Seal, params::CommonParams}, errors::{EthcoreError as Error, EngineError}, transaction::{Action, Transaction}, }; @@ -1641,7 +1641,7 @@ mod tests { TestNotify }; use crate::spec::{Spec, self}; - use engines::{Seal, Engine}; + use engine::Engine; use engines::validator_set::{TestSet, SimpleList}; use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score}; use machine::Machine; diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index eadbf8897f5..59a4c5fefa5 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -235,7 +235,7 @@ mod tests { use accounts::AccountProvider; use types::header::Header; use spec::Spec; - use engines::{Seal, SealingState}; + use types::engines::{Seal, SealingState}; use tempdir::TempDir; /// Create a new test chain spec with `BasicAuthority` consensus engine. diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index 8f773267aa2..e56183e5644 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -260,34 +260,9 @@ struct EpochVerifier { } impl engine::EpochVerifier for EpochVerifier { - fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } fn verify_heavy(&self, header: &Header) -> Result<(), Error> { verify_block_unordered(&self.pow, header) } -// let seal = Seal::parse_seal(header.seal())?; -// -// let result = self.pow.compute_light( -// header.number() as u64, -// &header.bare_hash().0, -// seal.nonce.to_low_u64_be() -// ); -// let mix = H256(result.mix_hash); -// let difficulty = ethash::boundary_to_difficulty(&H256(result.value)); -// trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}", -// num = header.number() as u64, -// seed = H256(slow_hash_block_number(header.number() as u64)), -// h = header.bare_hash(), -// non = seal.nonce.to_low_u64_be(), -// mix = H256(result.mix_hash), -// res = H256(result.value)); -// if mix != seal.mix_hash { -// return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash }))); -// } -// if &difficulty < header.difficulty() { -// return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty }))); -// } -// Ok(()) -// } } //impl Engine for Arc { diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index bd855921f6e..d786176bdd7 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -111,9 +111,11 @@ mod tests { use ethereum_types::{H520, Address}; use test_helpers::get_temp_state_db; use crate::spec; - use types::header::Header; + use types::{ + header::Header, + engines::Seal, + }; use block::*; - use engines::Seal; #[test] fn instant_can_seal() { diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index ca05967b1b4..e6240463249 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -145,14 +145,15 @@ mod tests { use bytes::ToPretty; use rlp::encode; use crate::spec; - use types::header::Header; + use types::{ + header::Header, + ids::BlockId, + }; use accounts::AccountProvider; use miner::{self, MinerService}; - use types::ids::BlockId; use test_helpers::generate_dummy_client_with_spec; use call_contract::CallContract; - use client::{BlockChainClient, ChainInfo}; - use client_traits::BlockInfo; + use client_traits::{BlockChainClient, ChainInfo, BlockInfo}; use super::super::ValidatorSet; use super::ValidatorContract; diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index a94ead2b52d..9e44430f4a1 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -155,18 +155,19 @@ mod tests { use std::collections::BTreeMap; use hash::keccak; use accounts::AccountProvider; - use client::{BlockChainClient, ChainInfo, ImportBlock}; - use client_traits::BlockInfo; - use engines::EpochChange; + use client_traits::{BlockChainClient, BlockInfo, ChainInfo, ImportBlock, EngineClient}; + use engine::EpochChange; use engines::validator_set::ValidatorSet; use ethkey::Secret; use types::header::Header; use miner::{self, MinerService}; use crate::spec; use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data}; - use types::ids::BlockId; + use types::{ + ids::BlockId, + verification::Unverified, + }; use ethereum_types::Address; - use verification::queue::kind::blocks::Unverified; use super::Multi; @@ -186,24 +187,24 @@ mod tests { let signer = Box::new((tap.clone(), v1, "".into())); client.miner().set_author(miner::Author::Sealer(signer)); client.transact_contract(Default::default(), Default::default()).unwrap(); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 0); // Right signer for the first block. let signer = Box::new((tap.clone(), v0, "".into())); client.miner().set_author(miner::Author::Sealer(signer)); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 1); // This time v0 is wrong. client.transact_contract(Default::default(), Default::default()).unwrap(); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 1); let signer = Box::new((tap.clone(), v1, "".into())); client.miner().set_author(miner::Author::Sealer(signer)); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 2); // v1 is still good. client.transact_contract(Default::default(), Default::default()).unwrap(); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 3); // Check syncing. diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 116ecd797c2..08f03c7a4f8 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -452,19 +452,24 @@ mod tests { use std::sync::Arc; use rustc_hex::FromHex; use hash::keccak; + use engine::{EpochChange, Proof}; use ethereum_types::Address; - use types::ids::BlockId; use crate::spec; use accounts::AccountProvider; - use types::transaction::{Transaction, Action}; - use client::{ChainInfo, ImportBlock}; - use client_traits::BlockInfo; + use types::{ + ids::BlockId, + engines::machine::AuxiliaryRequest, + header::Header, + log_entry::LogEntry, + transaction::{Transaction, Action}, + verification::Unverified, + }; + use client_traits::{BlockInfo, ChainInfo, ImportBlock, EngineClient}; use ethkey::Secret; use miner::{self, MinerService}; use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data}; use super::super::ValidatorSet; use super::{ValidatorSafeContract, EVENT_NAME_HASH}; - use verification::queue::kind::blocks::Unverified; #[test] fn fetches_validators() { @@ -500,7 +505,7 @@ mod tests { data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), }.sign(&s0, Some(chain_id)); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 1); // Add "1" validator back in. let tx = Transaction { @@ -512,14 +517,14 @@ mod tests { data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), }.sign(&s0, Some(chain_id)); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); // The transaction is not yet included so still unable to seal. assert_eq!(client.chain_info().best_block_number, 1); // Switch to the validator that is still there. let signer = Box::new((tap.clone(), v0, "".into())); client.miner().set_author(miner::Author::Sealer(signer)); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); assert_eq!(client.chain_info().best_block_number, 2); // Switch back to the added validator, since the state is updated. let signer = Box::new((tap.clone(), v1, "".into())); @@ -533,7 +538,7 @@ mod tests { data: Vec::new(), }.sign(&s0, Some(chain_id)); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); - ::client::EngineClient::update_sealing(&*client); + EngineClient::update_sealing(&*client); // Able to seal again. assert_eq!(client.chain_info().best_block_number, 3); @@ -549,13 +554,6 @@ mod tests { #[test] fn detects_bloom() { - use engines::EpochChange; - use types::{ - header::Header, - log_entry::LogEntry, - engines::machine::AuxiliaryRequest, - }; - let client = generate_dummy_client_with_spec(spec::new_validator_safe_contract); let engine = client.engine().clone(); let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); @@ -590,9 +588,6 @@ mod tests { #[test] fn initial_contract_is_signal() { - use types::header::Header; - use engines::{EpochChange, Proof}; - let client = generate_dummy_client_with_spec(spec::new_validator_safe_contract); let engine = client.engine().clone(); diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 1e9861f61e5..4bfe3c7c962 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -16,13 +16,14 @@ use std::path::Path; use std::sync::Arc; -use client::{EvmTestClient, Client, ClientConfig, ChainInfo, ImportBlock}; +use client::{EvmTestClient, Client, ClientConfig}; +use client_traits::{ImportBlock, ChainInfo}; use spec::Genesis; use ethjson; use miner::Miner; use io::IoChannel; use test_helpers; -use verification::queue::kind::blocks::Unverified; +use types::verification::Unverified; use verification::VerifierType; use super::SKIP_TEST_STATE; use super::HookType; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 2dfdad3ff05..1332ab35f50 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1489,12 +1489,15 @@ mod tests { use ethkey::{Generator, Random}; use hash::keccak; use rustc_hex::FromHex; - use types::BlockNumber; - use client::{TestBlockChainClient, EachBlockWith, ChainInfo, ImportSealedBlock}; + use client::{TestBlockChainClient, EachBlockWith, ImportSealedBlock}; + use client_traits::ChainInfo; use miner::{MinerService, PendingOrdering}; use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec}; - use types::transaction::{Transaction}; + use types::{ + BlockNumber, + transaction::Transaction + }; use crate::spec; #[test] diff --git a/ethcore/src/snapshot/tests/helpers.rs b/ethcore/src/snapshot/tests/helpers.rs index 5b3df97492e..d1931d911da 100644 --- a/ethcore/src/snapshot/tests/helpers.rs +++ b/ethcore/src/snapshot/tests/helpers.rs @@ -25,7 +25,8 @@ use hash::{KECCAK_NULL_RLP}; use account_db::AccountDBMut; use types::basic_account::BasicAccount; use blockchain::{BlockChain, BlockChainDB}; -use client::{Client, ChainInfo}; +use client::Client; +use client_traits::ChainInfo; use engine::Engine; use snapshot::{StateRebuilder}; use snapshot::io::{SnapshotReader, PackedWriter, PackedReader}; diff --git a/ethcore/src/snapshot/tests/proof_of_authority.rs b/ethcore/src/snapshot/tests/proof_of_authority.rs index f16357b0f37..a0161acdf98 100644 --- a/ethcore/src/snapshot/tests/proof_of_authority.rs +++ b/ethcore/src/snapshot/tests/proof_of_authority.rs @@ -21,7 +21,8 @@ use std::sync::Arc; use std::str::FromStr; use accounts::AccountProvider; -use client::{Client, BlockChainClient, ChainInfo}; +use client::Client; +use client_traits::{BlockChainClient, ChainInfo}; use ethkey::Secret; use snapshot::tests::helpers as snapshot_helpers; use spec::Spec; diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 13ab94214ad..e9bc3b92bb7 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -21,19 +21,22 @@ use std::sync::Arc; use tempdir::TempDir; use blockchain::BlockProvider; -use client::{Client, ClientConfig, ImportBlock}; -use client_traits::BlockInfo; -use types::ids::BlockId; +use client::{Client, ClientConfig}; +use client_traits::{BlockInfo, ImportBlock}; +use types::{ + ids::BlockId, + snapshot::Progress, + verification::Unverified, +}; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use snapshot::service::{Service, ServiceParams}; -use snapshot::{chunk_state, chunk_secondary, ManifestData, Progress, SnapshotService, RestorationStatus}; +use snapshot::{chunk_state, chunk_secondary, ManifestData, SnapshotService, RestorationStatus}; use crate::spec; use test_helpers::{new_db, new_temp_db, generate_dummy_client_with_spec_and_data, restoration_db_handler}; use parking_lot::Mutex; use io::IoChannel; use kvdb_rocksdb::DatabaseConfig; -use verification::queue::kind::blocks::Unverified; #[test] fn restored_is_equivalent() { diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index d5c861b8979..145eee4041a 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -39,7 +39,7 @@ use types::{ header::Header, view, views::BlockView, - verification_queue_info::Unverified, + verification::Unverified, }; use block::{OpenBlock, Drain}; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 7c7b4c1d340..2de42b4ce9b 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -26,12 +26,13 @@ use types::{ ids::BlockId, transaction::{PendingTransaction, Transaction, Action, Condition}, filter::Filter, + verification::Unverified, view, views::BlockView, }; -use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, ChainInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; -use client_traits::BlockInfo; +use client::{BlockChainReset, Client, ClientConfig, PrepareOpenBlock, ImportSealedBlock}; +use client_traits::{BlockInfo, BlockChainClient, ChainInfo, ImportBlock}; use crate::spec; use machine::executive::{Executive, TransactOptions}; use miner::{Miner, PendingOrdering, MinerService}; @@ -41,7 +42,6 @@ use test_helpers::{ generate_dummy_client, push_blocks_to_client, get_test_client_with_blocks, get_good_dummy_block_seq, generate_dummy_client_with_data, get_good_dummy_block, get_bad_state_dummy_block }; -use verification::queue::kind::blocks::Unverified; #[test] fn imports_from_empty() { @@ -210,7 +210,7 @@ fn can_generate_gas_price_histogram() { let client = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]); let hist = client.gas_price_corpus(20).histogram(5).unwrap(); - let correct_hist = ::stats::Histogram { bucket_bounds: vec_into![643, 2294, 3945, 5596, 7247, 8898], counts: vec![4,2,4,6,4] }; + let correct_hist = stats::Histogram { bucket_bounds: vec_into![643, 2294, 3945, 5596, 7247, 8898], counts: vec![4,2,4,6,4] }; assert_eq!(hist, correct_hist); } diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index 9f1326b4999..dd6fb8464d5 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -22,21 +22,21 @@ use block::*; use ethereum_types::{U256, Address}; use io::*; use crate::spec; -use client::*; use test_helpers::get_temp_state_db; -use client::{BlockChainClient, Client, ClientConfig}; +use client::{Client, ClientConfig}; +use client_traits::{BlockChainClient, ImportBlock}; use std::sync::Arc; use std::str::FromStr; use miner::Miner; use trace::{RewardType, LocalizedTrace}; use trace::trace::Action::Reward; use test_helpers; -use verification::queue::kind::blocks::Unverified; use types::{ ids::BlockId, transaction::{Action, Transaction}, trace_filter::Filter as TraceFilter, header::Header, + verification::Unverified, view, views::BlockView, }; diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index b4e297f88a0..32b159cb48c 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -73,7 +73,7 @@ pub mod blocks { use types::{ block::PreverifiedBlock, errors::{EthcoreError as Error, BlockError}, - verification_queue_info::Unverified, + verification::Unverified, }; use verification::{verify_block_basic, verify_block_unordered}; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 465f9b4501e..5bd96442aed 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -33,7 +33,7 @@ use types::errors::{BlockError, EthcoreError as Error, ImportError}; use self::kind::{BlockLike, Kind}; -pub use types::verification_queue_info::VerificationQueueInfo as QueueInfo; +pub use types::verification::VerificationQueueInfo as QueueInfo; pub mod kind; @@ -735,13 +735,13 @@ impl Drop for VerificationQueue { mod tests { use io::*; use super::{BlockQueue, Config, State}; - use super::kind::blocks::Unverified; use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block}; use bytes::Bytes; use types::{ + errors::{EthcoreError, ImportError}, + verification::Unverified, view, views::BlockView, - errors::{EthcoreError, ImportError}, }; use crate::spec; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 31b81981bc0..28cc87e5e6d 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -39,7 +39,7 @@ use types::{ errors::{EthcoreError as Error, BlockError}, engines::MAX_UNCLE_AGE, block::PreverifiedBlock, - verification_queue_info::Unverified, + verification::Unverified, }; use time_utils::CheckedSystemTime; diff --git a/ethcore/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs index 0b8ca55122e..ced44974d30 100644 --- a/ethcore/sync/src/blocks.rs +++ b/ethcore/sync/src/blocks.rs @@ -25,7 +25,7 @@ use network; use types::{ transaction::UnverifiedTransaction, header::Header as BlockHeader, - verification_queue_info::Unverified, + verification::Unverified, }; malloc_size_of_is_0!(HeaderId); diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index 20fea88d761..bf84e9fff46 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -33,7 +33,7 @@ use types::{ block_status::BlockStatus, ids::BlockId, errors::{EthcoreError, ImportError, BlockError}, - verification_queue_info::Unverified, + verification::Unverified, }; use super::sync_packet::{PacketInfo, SyncPacket}; diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index e19194cc622..99153a205b0 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -81,7 +81,7 @@ pub mod state_diff; pub mod trace_filter; pub mod transaction; pub mod tree_route; -pub mod verification_queue_info; +pub mod verification; /// Type for block number. pub type BlockNumber = u64; diff --git a/ethcore/types/src/verification_queue_info.rs b/ethcore/types/src/verification.rs similarity index 96% rename from ethcore/types/src/verification_queue_info.rs rename to ethcore/types/src/verification.rs index 7cd763644d3..dedf4549298 100644 --- a/ethcore/types/src/verification_queue_info.rs +++ b/ethcore/types/src/verification.rs @@ -14,7 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//! Verification queue info types +//! Verification types + +use crate::{ + header::Header, + transaction::UnverifiedTransaction, +}; +use bytes::Bytes; +use parity_util_mem::MallocSizeOf; /// Verification queue status #[derive(Debug, Clone)] @@ -49,14 +56,6 @@ impl VerificationQueueInfo { } } -//todo[dvdplm] move verification types into own module -use crate::{ - header::Header, - transaction::UnverifiedTransaction, -}; -use bytes::Bytes; -use parity_util_mem::MallocSizeOf; - /// An unverified block. #[derive(PartialEq, Debug, MallocSizeOf)] pub struct Unverified { From 64b5c6080936cddd01692ef58610269dfbd2374c Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 14:57:21 +0200 Subject: [PATCH 29/43] Sort out tests and refactor verification types --- Cargo.lock | 2 ++ parity/blockchain.rs | 2 +- rpc/src/v1/impls/parity.rs | 2 +- rpc/src/v1/types/histogram.rs | 7 ++++--- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b34a89475f..07a86007537 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -772,10 +772,12 @@ version = "0.1.0" dependencies = [ "client-traits 0.1.0", "common-types 0.1.0", + "ethcore-accounts 0.1.0", "ethcore-blockchain 0.1.0", "ethcore-builtin 0.1.0", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "machine 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 1c077c03b9b..731d258ab8a 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -46,7 +46,7 @@ use types::{ ids::BlockId, errors::{ImportError, EthcoreError}, client_types::Mode, - verification_queue_info::Unverified, + verification::Unverified, }; #[derive(Debug, PartialEq)] diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 4994c4db55c..0866d2a5857 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -33,7 +33,7 @@ use jsonrpc_core::{BoxFuture, Result}; use sync::{SyncProvider, ManageNetwork}; use types::{ ids::BlockId, - verification_queue_info::Unverified, + verification::Unverified, }; use updater::{Service as UpdateService}; use version::version_data; diff --git a/rpc/src/v1/types/histogram.rs b/rpc/src/v1/types/histogram.rs index d7f14c514e6..c3088048450 100644 --- a/rpc/src/v1/types/histogram.rs +++ b/rpc/src/v1/types/histogram.rs @@ -17,6 +17,7 @@ //! Gas prices histogram. use ethereum_types::U256; +use stats::Histogram; /// Values of RPC settings. #[derive(Serialize, Deserialize)] @@ -25,12 +26,12 @@ use ethereum_types::U256; pub struct Histogram { /// Gas prices for bucket edges. pub bucket_bounds: Vec, - /// Transacion counts for each bucket. + /// Transaction counts for each bucket. pub counts: Vec, } -impl From<::stats::Histogram<::ethereum_types::U256>> for Histogram { - fn from(h: ::stats::Histogram<::ethereum_types::U256>) -> Self { +impl From> for Histogram { + fn from(h: Histogram) -> Self { Histogram { bucket_bounds: h.bucket_bounds.into_iter().map(Into::into).collect(), counts: h.counts From b1b6b468caf3237eb1faf6097f0583c26ebc468e Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 15:20:33 +0200 Subject: [PATCH 30/43] Fix missing traits --- secret-store/Cargo.toml | 1 + secret-store/src/helpers.rs | 3 ++- secret-store/src/key_server_set.rs | 3 ++- secret-store/src/lib.rs | 1 + secret-store/src/listener/service_contract.rs | 3 ++- secret-store/src/trusted_client.rs | 7 ++++--- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/secret-store/Cargo.toml b/secret-store/Cargo.toml index 06f13663fc1..76a0df44a2d 100644 --- a/secret-store/Cargo.toml +++ b/secret-store/Cargo.toml @@ -7,6 +7,7 @@ authors = ["Parity Technologies "] [dependencies] byteorder = "1.0" +client-traits = { path = "../ethcore/client-traits" } common-types = { path = "../ethcore/types" } ethabi = "8.0" ethabi-contract = "8.0" diff --git a/secret-store/src/helpers.rs b/secret-store/src/helpers.rs index 3dfe7ae8b66..cdb235ac91c 100644 --- a/secret-store/src/helpers.rs +++ b/secret-store/src/helpers.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use ethcore::client::{Client, BlockChainClient}; +use ethcore::client::Client; +use client_traits::BlockChainClient; use common_types::ids::BlockId; use ethereum_types::H256; diff --git a/secret-store/src/key_server_set.rs b/secret-store/src/key_server_set.rs index b57df0a8ba4..5ffaa7fb767 100644 --- a/secret-store/src/key_server_set.rs +++ b/secret-store/src/key_server_set.rs @@ -20,7 +20,8 @@ use std::collections::{BTreeMap, HashSet}; use parking_lot::Mutex; use call_contract::CallContract; use ethabi::FunctionOutputDecoder; -use ethcore::client::{Client, BlockChainClient, ChainNotify, NewBlocks}; +use ethcore::client::{Client, ChainNotify, NewBlocks}; +use client_traits::BlockChainClient; use common_types::ids::BlockId; use ethereum_types::{H256, Address}; use ethkey::public_to_address; diff --git a/secret-store/src/lib.rs b/secret-store/src/lib.rs index 02571670460..2999b4ebd85 100644 --- a/secret-store/src/lib.rs +++ b/secret-store/src/lib.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . extern crate byteorder; +extern crate client_traits; extern crate common_types; extern crate ethabi; extern crate ethcore; diff --git a/secret-store/src/listener/service_contract.rs b/secret-store/src/listener/service_contract.rs index caac9065a51..3d24ff79839 100644 --- a/secret-store/src/listener/service_contract.rs +++ b/secret-store/src/listener/service_contract.rs @@ -20,7 +20,8 @@ use common_types::filter::Filter; use ethabi::RawLog; use ethabi::FunctionOutputDecoder; use call_contract::CallContract; -use ethcore::client::{Client, BlockChainClient}; +use ethcore::client::Client; +use client_traits::BlockChainClient; use common_types::ids::BlockId; use ethkey::{Public, public_to_address}; use hash::keccak; diff --git a/secret-store/src/trusted_client.rs b/secret-store/src/trusted_client.rs index 70ca6f420cb..a058f056420 100644 --- a/secret-store/src/trusted_client.rs +++ b/secret-store/src/trusted_client.rs @@ -22,7 +22,8 @@ use common_types::{ transaction::{Transaction, SignedTransaction, Action}, }; use ethereum_types::Address; -use ethcore::client::{Client, ChainInfo, Nonce}; +use ethcore::client::Client; +use client_traits::{ChainInfo, Nonce}; use ethcore::miner::{Miner, MinerService}; use sync::SyncProvider; use helpers::{get_confirmed_block_hash, REQUEST_CONFIRMATIONS_REQUIRED}; @@ -43,9 +44,9 @@ pub struct TrustedClient { impl TrustedClient { /// Create new trusted client. - pub fn new(self_key_pair: Arc, client: Arc, sync: Arc, miner: Arc) -> Self { + pub fn new(self_key_pair: Arc, client: Arc, sync: Arc, miner: Arc) -> Self { TrustedClient { - self_key_pair: self_key_pair, + self_key_pair, client: Arc::downgrade(&client), sync: Arc::downgrade(&sync), miner: Arc::downgrade(&miner), From 881b71f58f2a7669db1d8f72755b73b574cb337d Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 15:20:55 +0200 Subject: [PATCH 31/43] More missing traits Fix Histogram --- Cargo.lock | 1 + ethcore/light/src/on_demand/request.rs | 4 ++-- rpc/src/v1/types/histogram.rs | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07a86007537..cb2206eb606 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1275,6 +1275,7 @@ name = "ethcore-secretstore" version = "1.0.0" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "client-traits 0.1.0", "common-types 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index 704155ae8b9..cff0b63fc26 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -1099,8 +1099,8 @@ mod tests { use trie::Recorder; use hash::keccak; - use ethcore::client::{BlockChainClient, TestBlockChainClient, EachBlockWith}; - use client_traits::BlockInfo; + use ethcore::client::{TestBlockChainClient, EachBlockWith}; + use client_traits::{BlockInfo, BlockChainClient}; use common_types::header::Header; use common_types::encoded; use common_types::receipt::{Receipt, TransactionOutcome}; diff --git a/rpc/src/v1/types/histogram.rs b/rpc/src/v1/types/histogram.rs index c3088048450..41ac8730190 100644 --- a/rpc/src/v1/types/histogram.rs +++ b/rpc/src/v1/types/histogram.rs @@ -17,7 +17,7 @@ //! Gas prices histogram. use ethereum_types::U256; -use stats::Histogram; +use stats; /// Values of RPC settings. #[derive(Serialize, Deserialize)] @@ -30,8 +30,8 @@ pub struct Histogram { pub counts: Vec, } -impl From> for Histogram { - fn from(h: Histogram) -> Self { +impl From> for Histogram { + fn from(h: stats::Histogram) -> Self { Histogram { bucket_bounds: h.bucket_bounds.into_iter().map(Into::into).collect(), counts: h.counts From ddca9ee4da1238d8fc82dfbf94d1bd620da52486 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 16:02:06 +0200 Subject: [PATCH 32/43] Fix tests and cleanup --- Cargo.lock | 1 + ethcore/client-traits/src/lib.rs | 2 +- ethcore/engine/src/lib.rs | 3 +- ethcore/engine/src/snapshot.rs | 5 ++- ethcore/node-filter/src/lib.rs | 4 ++- ethcore/private-tx/src/lib.rs | 2 -- ethcore/private-tx/tests/private_contract.rs | 3 +- ethcore/src/client/client.rs | 2 +- ethcore/src/client/mod.rs | 6 ---- ethcore/src/verification/queue/kind.rs | 35 -------------------- ethcore/sync/Cargo.toml | 1 + ethcore/sync/src/blocks.rs | 7 ++-- ethcore/sync/src/chain/handler.rs | 5 +-- ethcore/sync/src/chain/mod.rs | 4 +-- ethcore/sync/src/chain/propagator.rs | 4 +-- ethcore/sync/src/chain/supplier.rs | 3 +- ethcore/sync/src/lib.rs | 2 +- ethcore/sync/src/tests/chain.rs | 3 +- ethcore/sync/src/tests/consensus.rs | 9 ++--- ethcore/sync/src/tests/helpers.rs | 3 +- ethcore/sync/src/tests/private.rs | 9 ++--- parity/helpers.rs | 6 ++-- rpc/src/lib.rs | 2 -- rpc/src/v1/tests/eth.rs | 16 +++++---- rpc/src/v1/tests/helpers/miner_service.rs | 7 ++-- rpc/src/v1/tests/mocked/eth.rs | 3 +- rpc/src/v1/types/trace_filter.rs | 1 - 27 files changed, 59 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb2206eb606..81f72faa4ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1352,6 +1352,7 @@ version = "1.12.0" dependencies = [ "client-traits 0.1.0", "common-types 0.1.0", + "engine 0.1.0", "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.12.0", diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs index b0d2163f71c..a8c6d91d664 100644 --- a/ethcore/client-traits/src/lib.rs +++ b/ethcore/client-traits/src/lib.rs @@ -35,7 +35,7 @@ use common_types::{ }, blockchain_info::BlockChainInfo, block_status::BlockStatus, - verification::{VerificationQueueInfo, Unverified}, //todo[dvdplm] better module name + verification::{VerificationQueueInfo, Unverified}, transaction::{self, LocalizedTransaction, CallError}, receipt::LocalizedReceipt, tree_route::TreeRoute, diff --git a/ethcore/engine/src/lib.rs b/ethcore/engine/src/lib.rs index 8341e7f6721..d492d0ea318 100644 --- a/ethcore/engine/src/lib.rs +++ b/ethcore/engine/src/lib.rs @@ -14,8 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -// todo[dvdplm]: docs -//! This crate +//! This crate defines the Engine trait and related types. // todo[dvdplm] do we need all of this exported? pub mod engine; diff --git a/ethcore/engine/src/snapshot.rs b/ethcore/engine/src/snapshot.rs index e4dd680dca7..8499b97bf2d 100644 --- a/ethcore/engine/src/snapshot.rs +++ b/ethcore/engine/src/snapshot.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//todo[dvdplm: document module +//! This module contains traits used while creating/restoring snapshots. They +//! are here because they use and are used by the Engine trait itself. use std::sync::{Arc, atomic::AtomicBool}; @@ -28,7 +29,6 @@ use common_types::{ use crate::engine::Engine; -// todo[dvdplm] it's pretty weird to have this here /// Restore from secondary snapshot chunks. pub trait Rebuilder: Send { /// Feed a chunk, potentially out of order. @@ -50,7 +50,6 @@ pub trait Rebuilder: Send { fn finalize(&mut self) -> Result<(), Error>; } -// todo[dvdplm] it's pretty weird to have this here – perhaps own crate? /// Components necessary for snapshot creation and restoration. pub trait SnapshotComponents: Send { /// Create secondary snapshot chunks; these corroborate the state data diff --git a/ethcore/node-filter/src/lib.rs b/ethcore/node-filter/src/lib.rs index 3fffc718163..2c4313c37f0 100644 --- a/ethcore/node-filter/src/lib.rs +++ b/ethcore/node-filter/src/lib.rs @@ -128,8 +128,10 @@ impl ChainNotify for NodeFilter { #[cfg(test)] mod test { use std::sync::{Arc, Weak}; + + use client_traits::BlockChainClient; use ethcore::spec::Spec; - use ethcore::client::{BlockChainClient, Client, ClientConfig}; + use ethcore::client::{Client, ClientConfig}; use ethcore::miner::Miner; use ethcore::test_helpers; use network::{ConnectionDirection, ConnectionFilter, NodeId}; diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 283df9b7a8e..6db9a0fc71d 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -55,8 +55,6 @@ extern crate trace; extern crate transaction_pool as txpool; extern crate url; #[macro_use] -extern crate log as ethlog; -#[macro_use] extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs index 5d144e787a4..e4ee445df11 100644 --- a/ethcore/private-tx/tests/private_contract.rs +++ b/ethcore/private-tx/tests/private_contract.rs @@ -16,6 +16,7 @@ //! Contract for private transactions tests. +extern crate client_traits; extern crate common_types as types; extern crate env_logger; extern crate ethcore; @@ -36,11 +37,11 @@ use types::ids::BlockId; use types::transaction::{Transaction, Action}; use ethcore::{ CreateContractAddress, - client::BlockChainClient, test_helpers::{generate_dummy_client, push_block_with_transactions}, miner::Miner, spec, }; +use client_traits::BlockChainClient; use ethkey::{Secret, KeyPair, Signature}; use machine::executive::contract_address; use hash::keccak; diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index cbb7532a58f..4743482c943 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -92,7 +92,7 @@ use types::{ pruning_info::PruningInfo, call_analytics::CallAnalytics, client_types::Mode, - verification::Unverified, // todo[dvdplm] rename the module + verification::Unverified, }; use verification::queue::kind::BlockLike; diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index c639205cf45..c878bf9c347 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -40,12 +40,6 @@ pub use self::traits::{ ReopenBlock, PrepareOpenBlock,ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, Call, EngineInfo, BlockProducer, SealedBlockImporter, BlockChainReset, ProvingBlockChainClient, StateClient, }; -// todo[dvdplm]: how many of these need to be exported? -//pub use self::traits::{ -// Nonce, Balance, ChainInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, -// StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks, -// BlockChainReset, BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient -//}; pub use account_state::state::StateInfo; diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 32b159cb48c..937d05abd18 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -113,41 +113,6 @@ pub mod blocks { } } -// // todo[dvdplm] moved to common-types -// /// An unverified block. -// #[derive(PartialEq, Debug, MallocSizeOf)] -// pub struct Unverified { -// /// Unverified block header. -// pub header: Header, -// /// Unverified block transactions. -// pub transactions: Vec, -// /// Unverified block uncles. -// pub uncles: Vec
, -// /// Raw block bytes. -// pub bytes: Bytes, -// } -// // todo[dvdplm] moved to common-types -// impl Unverified { -// /// Create an `Unverified` from raw bytes. -// pub fn from_rlp(bytes: Bytes) -> Result { -// use rlp::Rlp; -// let (header, transactions, uncles) = { -// let rlp = Rlp::new(&bytes); -// let header = rlp.val_at(0)?; -// let transactions = rlp.list_at(1)?; -// let uncles = rlp.list_at(2)?; -// (header, transactions, uncles) -// }; -// -// Ok(Unverified { -// header, -// transactions, -// uncles, -// bytes, -// }) -// } -// } - impl BlockLike for Unverified { fn hash(&self) -> H256 { self.header.hash() diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index 3f60b0b0df9..2b6eb4e6923 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -10,6 +10,7 @@ authors = ["Parity Technologies "] [dependencies] client-traits = { path = "../client-traits" } common-types = { path = "../types" } +engine = { path = "../engine" } enum_primitive = "0.1.1" ethcore = { path = ".." } ethcore-io = { path = "../../util/io" } diff --git a/ethcore/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs index ced44974d30..0dd672786dc 100644 --- a/ethcore/sync/src/blocks.rs +++ b/ethcore/sync/src/blocks.rs @@ -543,12 +543,13 @@ impl BlockCollection { #[cfg(test)] mod test { use super::{BlockCollection, SyncHeader}; - use ethcore::client::{TestBlockChainClient, EachBlockWith, BlockChainClient}; + use client_traits::BlockChainClient; + use ethcore::client::{TestBlockChainClient, EachBlockWith}; use types::{ ids::BlockId, - BlockNumber + BlockNumber, + verification::Unverified, }; - use ethcore::verification::queue::kind::blocks::Unverified; use rlp::*; fn is_empty(bc: &BlockCollection) -> bool { diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index bf84e9fff46..659720e3f6d 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -742,9 +742,10 @@ impl SyncHandler { #[cfg(test)] mod tests { - use ethcore::client::{ChainInfo, EachBlockWith, TestBlockChainClient}; + use client_traits::ChainInfo; + use ethcore::client::{EachBlockWith, TestBlockChainClient}; use parking_lot::RwLock; - use rlp::{Rlp}; + use rlp::Rlp; use std::collections::{VecDeque}; use tests::helpers::{TestIo}; use tests::snapshot::TestSnapshotService; diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 15bd4c8b924..bf790239934 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -1374,8 +1374,8 @@ pub mod tests { use super::*; use ::SyncConfig; use super::{PeerInfo, PeerAsking}; - use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo}; - use client_traits::BlockInfo; + use ethcore::client::{EachBlockWith, TestBlockChainClient}; + use client_traits::{BlockInfo, BlockChainClient, ChainInfo}; use ethcore::miner::{MinerService, PendingOrdering}; use types::header::Header; diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs index eb554cd5de7..e347d81c8d9 100644 --- a/ethcore/sync/src/chain/propagator.rs +++ b/ethcore/sync/src/chain/propagator.rs @@ -335,8 +335,8 @@ impl SyncPropagator { #[cfg(test)] mod tests { - use ethcore::client::{ChainInfo, EachBlockWith, TestBlockChainClient}; - use client_traits::BlockInfo; + use client_traits::{BlockInfo, ChainInfo}; + use ethcore::client::{EachBlockWith, TestBlockChainClient}; use parking_lot::RwLock; use rlp::Rlp; use std::collections::VecDeque; diff --git a/ethcore/sync/src/chain/supplier.rs b/ethcore/sync/src/chain/supplier.rs index 34cb7161798..e802cb0e0a5 100644 --- a/ethcore/sync/src/chain/supplier.rs +++ b/ethcore/sync/src/chain/supplier.rs @@ -376,7 +376,8 @@ mod test { use rlp::{Rlp, RlpStream}; use super::{*, super::tests::*}; use blocks::SyncHeader; - use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient}; + use client_traits::BlockChainClient; + use ethcore::client::{EachBlockWith, TestBlockChainClient}; use std::str::FromStr; #[test] diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index a2825687abf..674f0db4443 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -47,8 +47,8 @@ extern crate ethcore_light as light; #[cfg(test)] extern crate kvdb_memorydb; #[cfg(test)] extern crate rustc_hex; #[cfg(test)] extern crate rand_xorshift; -#[cfg(test)] extern crate client_traits; #[cfg(test)] extern crate machine; +#[cfg(test)] extern crate engine; #[macro_use] extern crate enum_primitive; diff --git a/ethcore/sync/src/tests/chain.rs b/ethcore/sync/src/tests/chain.rs index 1ae9922a5be..0f67321df68 100644 --- a/ethcore/sync/src/tests/chain.rs +++ b/ethcore/sync/src/tests/chain.rs @@ -16,7 +16,8 @@ use std::sync::Arc; use types::ids::BlockId; -use ethcore::client::{TestBlockChainClient, BlockChainClient, EachBlockWith, ChainInfo}; +use client_traits::{BlockChainClient, ChainInfo}; +use ethcore::client::{TestBlockChainClient, EachBlockWith}; use client_traits::BlockInfo; use chain::SyncState; use super::helpers::*; diff --git a/ethcore/sync/src/tests/consensus.rs b/ethcore/sync/src/tests/consensus.rs index 8f17ecb156b..f991d4692e4 100644 --- a/ethcore/sync/src/tests/consensus.rs +++ b/ethcore/sync/src/tests/consensus.rs @@ -18,8 +18,9 @@ use std::sync::Arc; use hash::keccak; use ethereum_types::{U256, Address}; use io::{IoHandler, IoChannel}; -use ethcore::client::{ChainInfo, ClientIoMessage}; -use ethcore::engines; +use client_traits::ChainInfo; +use engine::signer; +use ethcore::client::{ClientIoMessage}; use ethcore::spec; use ethcore::miner::{self, MinerService}; use ethkey::{KeyPair, Secret}; @@ -49,8 +50,8 @@ fn authority_round() { let io_handler0: Arc> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone())); let io_handler1: Arc> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone())); // Push transaction to both clients. Only one of them gets lucky to produce a block. - net.peer(0).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s0.clone()))); - net.peer(1).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s1.clone()))); + net.peer(0).miner.set_author(miner::Author::Sealer(signer::from_keypair(s0.clone()))); + net.peer(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone()))); net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _); net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _); net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler1))); diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index 135161a381a..017e8b3ee24 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -22,7 +22,8 @@ use bytes::Bytes; use network::{self, PeerId, ProtocolId, PacketId, SessionInfo}; use network::client_version::ClientVersion; use tests::snapshot::*; -use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient, +use client_traits::BlockChainClient; +use ethcore::client::{TestBlockChainClient, Client as EthcoreClient, ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage}; use ethcore::snapshot::SnapshotService; use ethcore::spec::{self, Spec}; diff --git a/ethcore/sync/src/tests/private.rs b/ethcore/sync/src/tests/private.rs index c62a4ae35a0..1d91e212403 100644 --- a/ethcore/sync/src/tests/private.rs +++ b/ethcore/sync/src/tests/private.rs @@ -19,10 +19,11 @@ use hash::keccak; use io::{IoHandler, IoChannel}; use types::transaction::{Transaction, Action}; use types::ids::BlockId; +use client_traits::BlockChainClient; +use engine::signer; use ethcore::{ CreateContractAddress, - client::{ClientIoMessage, BlockChainClient}, - engines, + client::ClientIoMessage, miner::{self, MinerService}, spec::Spec, test_helpers::push_block_with_transactions, @@ -54,8 +55,8 @@ fn send_private_transaction() { let io_handler0: Arc> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone())); let io_handler1: Arc> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone())); - net.peer(0).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s0.clone()))); - net.peer(1).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s1.clone()))); + net.peer(0).miner.set_author(miner::Author::Sealer(signer::from_keypair(s0.clone()))); + net.peer(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone()))); net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _); net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _); net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler0))); diff --git a/parity/helpers.rs b/parity/helpers.rs index f22cbd795ad..ebcdf87bcd4 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -351,10 +351,12 @@ mod tests { use std::collections::HashSet; use tempdir::TempDir; use ethereum_types::U256; - use ethcore::client::Mode; use ethcore::miner::PendingSet; use ethkey::Password; - use types::ids::BlockId; + use types::{ + ids::BlockId, + client_types::Mode, + }; use super::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_address, to_addresses, to_price, geth_ipc_path, to_bootnodes, join_set, password_from_file}; #[test] diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 1ae66453ba9..897df8d96c1 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -123,8 +123,6 @@ extern crate fake_fetch; #[cfg(test)] extern crate ethcore_io as io; -#[cfg(test)] -extern crate client_traits; pub extern crate jsonrpc_ws_server as ws; diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index c1981ce0101..23aedbe50ec 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -19,12 +19,12 @@ use std::env; use std::sync::Arc; use accounts::AccountProvider; -use ethcore::client::{BlockChainClient, Client, ClientConfig, ChainInfo, ImportBlock}; +use client_traits::{BlockChainClient, ChainInfo, ImportBlock}; +use ethcore::client::{Client, ClientConfig}; use ethcore::miner::Miner; use ethcore::spec::{Genesis, Spec, self}; use ethcore::test_helpers; use ethcore::verification::VerifierType; -use ethcore::verification::queue::kind::blocks::Unverified; use ethereum_types::{Address, H256, U256}; use ethjson::blockchain::BlockChain; use ethjson::spec::ForkSpec; @@ -32,7 +32,10 @@ use io::IoChannel; use miner::external::ExternalMiner; use parity_runtime::Runtime; use parking_lot::Mutex; -use types::ids::BlockId; +use types::{ + ids::BlockId, + verification::Unverified, +}; use jsonrpc_core::IoHandler; use v1::helpers::dispatch::{self, FullDispatcher}; @@ -114,7 +117,7 @@ impl EthTester { let runtime = Runtime::with_thread_count(1); let account_provider = account_provider(); let ap = account_provider.clone(); - let accounts = Arc::new(move || ap.accounts().unwrap_or_default()) as _; + let accounts = Arc::new(move || ap.accounts().unwrap_or_default()) as _; let miner_service = miner_service(&spec); let snapshot_service = snapshot_service(); @@ -215,8 +218,7 @@ fn eth_get_proof() { }"#; let res_latest = r#","address":"0xaaaf5374fce5edbc8e2a8697c15331677e6ebaaa","balance":"0x9","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","nonce":"0x0","storageHash":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","storageProof":[]},"id":1}"#.to_owned(); - assert!(tester.handler.handle_request_sync(req_latest).unwrap().to_string().ends_with(res_latest.as_str())); - + assert!(tester.handler.handle_request_sync(req_latest).unwrap().to_string().ends_with(res_latest.as_str())); // non-existant account let req_new_acc = r#"{ "jsonrpc": "2.0", @@ -226,7 +228,7 @@ fn eth_get_proof() { }"#; let res_new_acc = r#","address":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","balance":"0x0","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","nonce":"0x0","storageHash":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","storageProof":[]},"id":3}"#.to_owned(); - assert!(tester.handler.handle_request_sync(req_new_acc).unwrap().to_string().ends_with(res_new_acc.as_str())); + assert!(tester.handler.handle_request_sync(req_new_acc).unwrap().to_string().ends_with(res_new_acc.as_str())); } #[test] diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 5f7d3eed4b5..2dc3761b061 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -20,15 +20,15 @@ use std::sync::Arc; use std::collections::{BTreeMap, BTreeSet, HashMap}; use bytes::Bytes; +use client_traits::Nonce; +use engine::{Engine, signer::EngineSigner}; use ethcore::block::SealedBlock; -use ethcore::client::{Nonce, PrepareOpenBlock, StateClient, EngineInfo, TestState}; -use ethcore::engines::{Engine, signer::EngineSigner}; +use ethcore::client::{PrepareOpenBlock, StateClient, EngineInfo, TestState}; use ethcore::miner::{self, MinerService, AuthoringParams, FilterOptions}; use ethereum_types::{H256, U256, Address}; use miner::pool::local_transactions::Status as LocalTransactionStatus; use miner::pool::{verifier, VerifiedTransaction, QueueStatus}; use parking_lot::{RwLock, Mutex}; -use types::transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction}; use txpool; use types::{ BlockNumber, @@ -37,6 +37,7 @@ use types::{ errors::EthcoreError as Error, ids::BlockId, receipt::RichReceipt, + transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction}, }; /// Test miner service. diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 34925ddce13..7477eec696e 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -20,7 +20,8 @@ use std::sync::Arc; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; use accounts::AccountProvider; -use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient}; +use client_traits::BlockChainClient; +use ethcore::client::{EachBlockWith, TestBlockChainClient}; use ethcore::miner::{self, MinerService}; use ethereum_types::{H160, H256, U256, Address, Bloom}; use machine::executed::Executed; diff --git a/rpc/src/v1/types/trace_filter.rs b/rpc/src/v1/types/trace_filter.rs index 42bad70e88c..4f11308c51c 100644 --- a/rpc/src/v1/types/trace_filter.rs +++ b/rpc/src/v1/types/trace_filter.rs @@ -16,7 +16,6 @@ //! Trace filter deserialization. -use ethcore::client; use ethereum_types::H160; use types::{ ids::BlockId, From d7d3f4b087d58bee353ea535bec6f034bef5a4ad Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 16:13:34 +0200 Subject: [PATCH 33/43] cleanup --- ethcore/src/engines/ethash.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index e56183e5644..ad9f093f39b 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -242,19 +242,6 @@ fn verify_block_unordered(pow: &Arc, header: &Header) -> Result<( // for any block in the chain. // in the future, we might move the Ethash epoch // caching onto this mechanism as well. -// NOTE[dvdplm]: the reason we impl this for Arc and not plain Ethash is the -// way `epoch_verifier()` works. This means `new()` returns an `Arc` which is -// then re-wrapped in an Arc in `spec::engine()`. - -//pub struct ArcEthash<'a>(Arc<&'a Ethash>); -//impl engine::EpochVerifier for Arc { -//impl<'a> engine::EpochVerifier for &'a Ethash { -// fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } -// fn verify_heavy(&self, header: &Header) -> Result<(), Error> { -// self.verify_block_unordered(header).into() -// } -//} - struct EpochVerifier { pow: Arc } From b2f8be6aec093cb6f659a6a051cfb099e4187470 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 16:18:17 +0200 Subject: [PATCH 34/43] Put back needed logger import --- ethcore/private-tx/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 6db9a0fc71d..283df9b7a8e 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -55,6 +55,8 @@ extern crate trace; extern crate transaction_pool as txpool; extern crate url; #[macro_use] +extern crate log as ethlog; +#[macro_use] extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; From 8ab2a02ee46f3fd03156df2a529a570121518594 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 16:45:32 +0200 Subject: [PATCH 35/43] Don't rexport common_types from ethcore/src/client Don't export ethcore::client::* --- ethcore/src/client/client.rs | 7 +++---- ethcore/src/client/mod.rs | 3 +-- ethcore/src/client/test_client.rs | 4 +++- ethcore/sync/src/chain/mod.rs | 6 ++++-- parity/informant.rs | 5 +++-- rpc/src/v1/helpers/block_import.rs | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 4743482c943..920382f8290 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -73,6 +73,8 @@ use types::{ ancestry_action::AncestryAction, BlockNumber, block::PreverifiedBlock, + block_status::BlockStatus, + blockchain_info::BlockChainInfo, encoded, engines::{ SealingState, @@ -92,7 +94,7 @@ use types::{ pruning_info::PruningInfo, call_analytics::CallAnalytics, client_types::Mode, - verification::Unverified, + verification::{Unverified, VerificationQueueInfo as BlockQueueInfo}, }; use verification::queue::kind::BlockLike; @@ -103,9 +105,6 @@ use ansi_term::Colour; // re-export pub use blockchain::CacheSize as BlockChainCacheSize; use db::{Writable, Readable, keys::BlockDetails}; -pub use types::blockchain_info::BlockChainInfo; -pub use types::block_status::BlockStatus; -pub use types::verification::VerificationQueueInfo as BlockQueueInfo; use_contract!(registry, "res/contracts/registrar.json"); diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index c878bf9c347..5d639d659e9 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -27,8 +27,7 @@ mod io_message; mod test_client; // todo[dvdplm]: really? re-export everything? -pub use self::client::*; -// todo[dvdplm]: Mode was rexported here +pub use self::client::{Client, ClientReport}; pub use self::config::{ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; #[cfg(any(test, feature = "test-helpers"))] pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess}; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index ca71ca4b391..3b01275ebe4 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -55,6 +55,8 @@ use types::{ views::BlockView, verification::Unverified, client_types::Mode, + blockchain_info::BlockChainInfo, + block_status::BlockStatus, }; use vm::Schedule; @@ -63,7 +65,7 @@ use call_contract::{CallContract, RegistryInfo}; use client::{ ReopenBlock, PrepareOpenBlock, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, Call, StateClient, EngineInfo, BlockProducer, SealedBlockImporter, - BlockChainInfo, BlockStatus, LastHashes, + LastHashes, }; use client_traits::{ BlockInfo, Nonce, Balance, ChainInfo, TransactionInfo, BlockChainClient, ImportBlock, diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index bf790239934..1b40649ecb5 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -108,7 +108,6 @@ use bytes::Bytes; use rlp::{RlpStream, DecoderError}; use network::{self, PeerId, PacketId}; use network::client_version::ClientVersion; -use ethcore::client::{BlockStatus, BlockChainInfo, BlockQueueInfo}; use client_traits::BlockChainClient; use ethcore::snapshot::RestorationStatus; use sync_io::SyncIo; @@ -122,7 +121,10 @@ use transactions_stats::{TransactionsStats, Stats as TransactionStats}; use types::{ BlockNumber, ids::BlockId, - transaction::UnverifiedTransaction + transaction::UnverifiedTransaction, + verification::VerificationQueueInfo as BlockQueueInfo, + blockchain_info::BlockChainInfo, + block_status::BlockStatus, }; use self::handler::SyncHandler; diff --git a/parity/informant.rs b/parity/informant.rs index da7887c2348..683c67c4bd1 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -24,13 +24,14 @@ use std::time::{Instant, Duration}; use atty; use ethcore::client::{ - BlockChainInfo, BlockQueueInfo, ChainNotify, NewBlocks, - ClientReport, Client, ClientIoMessage + ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage }; use client_traits::{BlockInfo, ChainInfo, BlockChainClient}; use types::{ BlockNumber, ids::BlockId, + blockchain_info::BlockChainInfo, + verification::VerificationQueueInfo as BlockQueueInfo, }; use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::service::Service as SnapshotService; diff --git a/rpc/src/v1/helpers/block_import.rs b/rpc/src/v1/helpers/block_import.rs index 8e8dba28f7b..a062e11786f 100644 --- a/rpc/src/v1/helpers/block_import.rs +++ b/rpc/src/v1/helpers/block_import.rs @@ -16,7 +16,7 @@ //! Block import analysis functions. -use ethcore::client::BlockQueueInfo; +use types::verification::VerificationQueueInfo as BlockQueueInfo; use sync::SyncState; /// Check if client is during major sync or during block import and allows defining whether 'waiting for peers' should From 4aef5f24cbb106017c417c3180cc72aa6c24fc08 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 17:13:12 +0200 Subject: [PATCH 36/43] Remove files no longer used Use types from the engine crate Explicit exports from engine::engine --- ethcore/engine/src/lib.rs | 6 +- ethcore/src/client/mod.rs | 1 - ethcore/src/engines/authority_round/mod.rs | 12 +-- ethcore/src/engines/basic_authority.rs | 10 ++- ethcore/src/engines/block_reward.rs | 2 +- ethcore/src/engines/ethash.rs | 9 +-- ethcore/src/engines/mod.rs | 60 -------------- ethcore/src/engines/signer.rs | 79 ------------------- ethcore/src/engines/validator_set/contract.rs | 3 +- ethcore/src/engines/validator_set/mod.rs | 6 +- 10 files changed, 25 insertions(+), 163 deletions(-) delete mode 100644 ethcore/src/engines/signer.rs diff --git a/ethcore/engine/src/lib.rs b/ethcore/engine/src/lib.rs index d492d0ea318..05a07dc4053 100644 --- a/ethcore/engine/src/lib.rs +++ b/ethcore/engine/src/lib.rs @@ -17,7 +17,7 @@ //! This crate defines the Engine trait and related types. // todo[dvdplm] do we need all of this exported? -pub mod engine; +mod engine; pub mod signer; pub mod snapshot; @@ -28,6 +28,10 @@ pub use crate::engine::{ ConstructedVerifier, EpochChange, Proof, + SystemCall, + SystemOrCodeCall, + SystemOrCodeCallKind, + default_system_or_code_call, }; #[cfg(any(test, feature = "test-helpers"))] diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 5d639d659e9..3f4c46eab6c 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -26,7 +26,6 @@ mod io_message; #[cfg(any(test, feature = "test-helpers"))] mod test_client; -// todo[dvdplm]: really? re-export everything? pub use self::client::{Client, ClientReport}; pub use self::config::{ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; #[cfg(any(test, feature = "test-helpers"))] diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index a93afa30aff..dae24e9ef55 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -50,7 +50,9 @@ use types::{ BlockNumber, header::{Header, ExtendedHeader}, engines::{ + Headers, params::CommonParams, + PendingTransitionStore, Seal, SealingState, machine::{Call, AuxiliaryData}, @@ -1275,7 +1277,7 @@ impl Engine for AuthorityRound { let rewards: Vec<_> = match self.block_reward_contract { Some(ref c) if block.header.number() >= self.block_reward_contract_transition => { - let mut call = super::default_system_or_code_call(&self.machine, block); + let mut call = engine::default_system_or_code_call(&self.machine, block); let rewards = c.reward(beneficiaries, &mut call)?; rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect() @@ -1441,8 +1443,8 @@ impl Engine for AuthorityRound { fn is_epoch_end_light( &self, chain_head: &Header, - chain: &super::Headers
, - transition_store: &super::PendingTransitionStore, + chain: &Headers
, + transition_store: &PendingTransitionStore, ) -> Option> { // epochs only matter if we want to support light clients. if self.immediate_transitions { return None } @@ -1485,8 +1487,8 @@ impl Engine for AuthorityRound { &self, chain_head: &Header, finalized: &[H256], - chain: &super::Headers
, - transition_store: &super::PendingTransitionStore, + chain: &Headers
, + transition_store: &PendingTransitionStore, ) -> Option> { // epochs only matter if we want to support light clients. if self.immediate_transitions { return None } diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 59a4c5fefa5..55c8ab5e7aa 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -35,6 +35,8 @@ use machine::{ use types::{ header::Header, engines::{ + Headers, + PendingTransitionStore, SealingState, Seal, params::CommonParams, @@ -165,8 +167,8 @@ impl Engine for BasicAuthority { &self, chain_head: &Header, _finalized: &[H256], - _chain: &super::Headers
, - _transition_store: &super::PendingTransitionStore, + _chain: &Headers
, + _transition_store: &PendingTransitionStore, ) -> Option> { let first = chain_head.number() == 0; @@ -177,8 +179,8 @@ impl Engine for BasicAuthority { fn is_epoch_end_light( &self, chain_head: &Header, - chain: &super::Headers
, - transition_store: &super::PendingTransitionStore, + chain: &Headers
, + transition_store: &PendingTransitionStore, ) -> Option> { self.is_epoch_end(chain_head, &[], chain, transition_store) } diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index 3429a28cef0..bd38f3e8c8f 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -28,7 +28,7 @@ use types::{ BlockNumber, errors::{EngineError, EthcoreError as Error}, }; -use super::{SystemOrCodeCall, SystemOrCodeCallKind}; +use engine::{SystemOrCodeCall, SystemOrCodeCallKind}; use trace::{Tracer, ExecutiveTracer, Tracing}; use_contract!(block_reward_contract, "res/contracts/block_reward.json"); diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index ad9f093f39b..70549b6bdef 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -34,7 +34,6 @@ use types::{ use unexpected::{OutOfBounds, Mismatch}; use engines::block_reward::{self, BlockRewardContract, RewardKind}; -use engines; use engine::Engine; use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor}; use machine::{ @@ -293,7 +292,7 @@ impl Engine for Ethash { beneficiaries.push((*uncle_author, RewardKind::uncle(number, u.number()))); } - let mut call = engines::default_system_or_code_call(&self.machine, block); + let mut call = engine::default_system_or_code_call(&self.machine, block); let rewards = c.reward(beneficiaries, &mut call)?; rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect() @@ -417,14 +416,8 @@ impl Engine for Ethash { } fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> engine::ConstructedVerifier<'a> { - // todo[dvdplm]: this one's tricky, not sure how to solve this. let v = EpochVerifier{pow: self.pow.clone()}; engine::ConstructedVerifier::Trusted(Box::new(v)) -// engine::ConstructedVerifier::Trusted(Box::new(engine::engine::NoOp)) -// engine::ConstructedVerifier::Trusted(Box::new(ArcEthash(Arc::new(self)))) -// engine::ConstructedVerifier::Trusted(Box::new(self.clone())) // original -// engine::ConstructedVerifier::Trusted(Box::new(*self)) -// engine::ConstructedVerifier::Trusted(Box::new(self)) } fn populate_from_parent(&self, header: &mut Header, parent: &Header) { diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 6391ed824ee..f5d8c4bdd27 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -36,63 +36,3 @@ pub use self::ethash::{Ethash, Seal as EthashSeal}; // TODO [ToDr] Remove re-export (#10130) pub use types::engines::ForkChoice; pub use types::engines::epoch::{self, Transition as EpochTransition}; - -use std::sync::Arc; - -use vm::{CallType, ActionValue}; -use types::{ - engines::{ - Headers, PendingTransitionStore, - }, -}; - -use machine::{ - Machine, - executed_block::ExecutedBlock, -}; -use ethereum_types::{H256, U256, Address}; - -/// A system-calling closure. Enacts calls on a block's state from the system address. -pub type SystemCall<'a> = dyn FnMut(Address, Vec) -> Result, String> + 'a; - -/// A system-calling closure. Enacts calls on a block's state with code either from an on-chain contract, or hard-coded EVM or WASM (if enabled on-chain) codes. -pub type SystemOrCodeCall<'a> = dyn FnMut(SystemOrCodeCallKind, Vec) -> Result, String> + 'a; - -/// Kind of SystemOrCodeCall, this is either an on-chain address, or code. -#[derive(PartialEq, Debug, Clone)] -pub enum SystemOrCodeCallKind { - /// On-chain address. - Address(Address), - /// Hard-coded code. - Code(Arc>, H256), -} - -/// Default SystemOrCodeCall implementation. -pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut ExecutedBlock) -> impl FnMut(SystemOrCodeCallKind, Vec) -> Result, String> + 'a { - move |to, data| { - let result = match to { - SystemOrCodeCallKind::Address(address) => { - machine.execute_as_system( - block, - address, - U256::max_value(), - Some(data), - ) - }, - SystemOrCodeCallKind::Code(code, code_hash) => { - machine.execute_code_as_system( - block, - None, - Some(code), - Some(code_hash), - Some(ActionValue::Apparent(U256::zero())), - U256::max_value(), - Some(data), - Some(CallType::StaticCall), - ) - }, - }; - - result.map_err(|e| format!("{}", e)) - } -} diff --git a/ethcore/src/engines/signer.rs b/ethcore/src/engines/signer.rs deleted file mode 100644 index 196c535fe76..00000000000 --- a/ethcore/src/engines/signer.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! A signer used by Engines which need to sign messages. - -use ethereum_types::{H256, Address}; -use ethkey::{self, Signature}; - -/// Everything that an Engine needs to sign messages. -pub trait EngineSigner: Send + Sync { - /// Sign a consensus message hash. - fn sign(&self, hash: H256) -> Result; - - /// Signing address - fn address(&self) -> Address; -} - -/// Creates a new `EngineSigner` from given key pair. -pub fn from_keypair(keypair: ethkey::KeyPair) -> Box { - Box::new(Signer(keypair)) -} - -struct Signer(ethkey::KeyPair); - -impl EngineSigner for Signer { - fn sign(&self, hash: H256) -> Result { - ethkey::sign(self.0.secret(), &hash) - } - - fn address(&self) -> Address { - self.0.address() - } -} - -#[cfg(test)] -mod test_signer { - use std::sync::Arc; - - use ethkey::Password; - use accounts::{self, AccountProvider, SignError}; - - use super::*; - - impl EngineSigner for (Arc, Address, Password) { - fn sign(&self, hash: H256) -> Result { - match self.0.sign(self.1, Some(self.2.clone()), hash) { - Err(SignError::NotUnlocked) => unreachable!(), - Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress), - Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err), - Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => { - warn!("Low level crypto error: {:?}", err); - Err(ethkey::Error::InvalidSecret) - }, - Err(SignError::SStore(err)) => { - warn!("Error signing for engine: {:?}", err); - Err(ethkey::Error::InvalidSignature) - }, - Ok(ok) => Ok(ok), - } - } - - fn address(&self) -> Address { - self.1 - } - } -} diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index e6240463249..bf97695563d 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -31,8 +31,9 @@ use types::{ }; use client_traits::EngineClient; +use engine::SystemCall; -use super::{ValidatorSet, SimpleList, SystemCall}; +use super::{ValidatorSet, SimpleList}; use super::safe_contract::ValidatorSafeContract; use_contract!(validator_report, "res/contracts/validator_report.json"); diff --git a/ethcore/src/engines/validator_set/mod.rs b/ethcore/src/engines/validator_set/mod.rs index b5a51de8bd8..27f11f4e2cb 100644 --- a/ethcore/src/engines/validator_set/mod.rs +++ b/ethcore/src/engines/validator_set/mod.rs @@ -26,6 +26,8 @@ mod multi; use std::sync::Weak; use bytes::Bytes; +use client_traits::EngineClient; +use engine::SystemCall; use ethereum_types::{H256, Address}; use ethjson::spec::ValidatorSet as ValidatorSpec; use machine::Machine; @@ -37,15 +39,13 @@ use types::{ engines::machine::{Call, AuxiliaryData}, }; -use client_traits::EngineClient; - #[cfg(test)] pub use self::test::TestSet; pub use self::simple_list::SimpleList; + use self::contract::ValidatorContract; use self::safe_contract::ValidatorSafeContract; use self::multi::Multi; -use super::SystemCall; /// Creates a validator set from spec. pub fn new_validator_set(spec: ValidatorSpec) -> Box { From 951f63e73df24637678ba27b50ad13d161a85883 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 17:20:37 +0200 Subject: [PATCH 37/43] Get rid of itertools --- Cargo.lock | 1 - ethcore/client-traits/Cargo.toml | 1 - ethcore/client-traits/src/lib.rs | 5 +++-- ethcore/engine/src/lib.rs | 1 - ethcore/src/client/client.rs | 2 +- ethcore/src/engines/block_reward.rs | 2 +- 6 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81f72faa4ae..de0ac5a6ee9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,7 +433,6 @@ dependencies = [ "ethcore-db 0.1.0", "ethcore-miner 1.12.0", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "trace 0.1.0", diff --git a/ethcore/client-traits/Cargo.toml b/ethcore/client-traits/Cargo.toml index c7a8aa48a67..a65df8db1bf 100644 --- a/ethcore/client-traits/Cargo.toml +++ b/ethcore/client-traits/Cargo.toml @@ -17,6 +17,5 @@ bytes = { package = "parity-bytes", version = "0.1.0" } stats = { path = "../../util/stats" } vm = { path = "../vm" } trace = { path = "../trace" } -itertools = "0.5" # todo[dvdplm] get rid of this ethcore-miner = { path = "../../miner" } diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs index a8c6d91d664..08e164c3efe 100644 --- a/ethcore/client-traits/src/lib.rs +++ b/ethcore/client-traits/src/lib.rs @@ -56,7 +56,6 @@ use trace::{ localized::LocalizedTrace, }; use vm::LastHashes; -use itertools::Itertools; // todo[dvdplm] get rid of this /// State information to be used during client query pub enum StateOrBlock { @@ -331,7 +330,9 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra if block.number() == 0 { return corpus.into(); } - block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price())); + for t in block.transaction_views().iter() { + corpus.push( t.gas_price() ) + } h = block.parent_hash().clone(); } } diff --git a/ethcore/engine/src/lib.rs b/ethcore/engine/src/lib.rs index 05a07dc4053..5b3c93bf649 100644 --- a/ethcore/engine/src/lib.rs +++ b/ethcore/engine/src/lib.rs @@ -16,7 +16,6 @@ //! This crate defines the Engine trait and related types. -// todo[dvdplm] do we need all of this exported? mod engine; pub mod signer; pub mod snapshot; diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 920382f8290..10903e6472a 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1282,7 +1282,7 @@ impl Client { t: &SignedTransaction, analytics: CallAnalytics, ) -> Result { - use types::engines::machine::Executed as RawExecuted; //todo[dvdplm] better name + use types::engines::machine::Executed as RawExecuted; fn call( state: &mut State, env_info: &EnvInfo, diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index bd38f3e8c8f..c2f66c13e78 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -166,7 +166,7 @@ mod test { use crate::spec; use test_helpers::generate_dummy_client_with_spec; - use engines::SystemOrCodeCallKind; + use engine::SystemOrCodeCallKind; use super::{BlockRewardContract, RewardKind}; #[test] From 1c42cc1c422b04284b5f721f55c46236e1070ec4 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 17:51:52 +0200 Subject: [PATCH 38/43] Move a few more traits from ethcore to client-traits: BlockChainReset, ScheduleInfo, StateClient --- ethcore/client-traits/src/lib.rs | 62 ++++++++++++++++------- ethcore/src/client/client.rs | 12 ++--- ethcore/src/client/mod.rs | 4 +- ethcore/src/client/test_client.rs | 6 +-- ethcore/src/client/traits.rs | 30 ----------- ethcore/src/json_tests/executive.rs | 1 - ethcore/src/miner/mod.rs | 8 +-- ethcore/src/tests/client.rs | 4 +- parity/blockchain.rs | 4 +- rpc/src/v1/impls/eth.rs | 4 +- rpc/src/v1/impls/parity.rs | 4 +- rpc/src/v1/impls/traces.rs | 4 +- rpc/src/v1/tests/helpers/miner_service.rs | 4 +- 13 files changed, 67 insertions(+), 80 deletions(-) diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs index 08e164c3efe..d733f56a565 100644 --- a/ethcore/client-traits/src/lib.rs +++ b/ethcore/client-traits/src/lib.rs @@ -19,43 +19,40 @@ use std::{ sync::Arc, }; -use ethereum_types::{Address, H256, U256}; use account_state::state::StateInfo; use blockchain::BlockProvider; +use bytes::Bytes; use call_contract::{CallContract, RegistryInfo}; use common_types::{ + block_status::BlockStatus, + blockchain_info::BlockChainInfo, BlockNumber, - header::Header, + call_analytics::CallAnalytics, + client_types::Mode, encoded, + engines::{epoch::Transition as EpochTransition, machine::Executed}, errors::EthcoreResult, - ids::{BlockId, TransactionId, TraceId, UncleId}, - engines::{ - epoch::Transition as EpochTransition, - machine::Executed, - }, - blockchain_info::BlockChainInfo, - block_status::BlockStatus, - verification::{VerificationQueueInfo, Unverified}, - transaction::{self, LocalizedTransaction, CallError}, - receipt::LocalizedReceipt, - tree_route::TreeRoute, filter::Filter, + header::Header, + ids::{BlockId, TransactionId, TraceId, UncleId}, log_entry::LocalizedLogEntry, - call_analytics::CallAnalytics, pruning_info::PruningInfo, - client_types::Mode, + receipt::LocalizedReceipt, trace_filter::Filter as TraceFilter, + transaction::{self, LocalizedTransaction, CallError}, + tree_route::TreeRoute, + verification::{VerificationQueueInfo, Unverified}, }; -use bytes::Bytes; +use ethereum_types::{Address, H256, U256}; use ethcore_db::keys::BlockReceipts; use ethcore_miner::pool::VerifiedTransaction; use stats; use trace::{ FlatTrace, - VMTrace, localized::LocalizedTrace, + VMTrace, }; -use vm::LastHashes; +use vm::{LastHashes, Schedule}; /// State information to be used during client query pub enum StateOrBlock { @@ -373,3 +370,32 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra /// Get the address of the registry itself. fn registrar_address(&self) -> Option
; } + +/// resets the blockchain +pub trait BlockChainReset { + /// reset to best_block - n + fn reset(&self, num: u32) -> Result<(), String>; +} + + +/// Provides `latest_schedule` method +pub trait ScheduleInfo { + /// Returns latest schedule. + fn latest_schedule(&self) -> Schedule; +} + +/// Provides methods to access chain state +pub trait StateClient { + /// Type representing chain state + type State: StateInfo; + + /// Get a copy of the best block's state. + fn latest_state(&self) -> Self::State; + + /// Attempt to get a copy of a specific block's final state. + /// + /// This will not fail if given BlockId::Latest. + /// Otherwise, this can fail (but may not) if the DB prunes state or the block + /// is unknown. + fn state_at(&self, id: BlockId) -> Option; +} diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 10903e6472a..b5d24dccbd6 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -39,16 +39,12 @@ use hash_db::EMPTY_PREFIX; use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; use client::ancient_import::AncientVerifier; use client::{ - ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock, - BroadcastProposalBlock, StateInfo, StateClient, Call, - BlockProducer, SealedBlockImporter, - BlockChainReset, - ClientConfig, - ChainNotify, NewBlocks, ChainRoute, ProvingBlockChainClient, EngineInfo, ChainMessageType, - bad_blocks, ClientIoMessage, + ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, StateInfo, Call, + BlockProducer, SealedBlockImporter, ChainNotify, ProvingBlockChainClient, EngineInfo, + ClientConfig, NewBlocks, ChainRoute, ChainMessageType, bad_blocks, ClientIoMessage, }; use client_traits::{ - BlockInfo, + BlockInfo, ScheduleInfo, StateClient, BlockChainReset, Nonce, Balance, ChainInfo, TransactionInfo, ImportBlock, AccountData, BlockChain as BlockChainTrait, BlockChainClient, IoClient, BadBlocks, diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 3f4c46eab6c..b770b59ccbb 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -35,8 +35,8 @@ pub use self::io_message::ClientIoMessage; pub use self::test_client::{TestBlockChainClient, EachBlockWith, TestState}; pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ - ReopenBlock, PrepareOpenBlock,ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, - Call, EngineInfo, BlockProducer, SealedBlockImporter, BlockChainReset, ProvingBlockChainClient, StateClient, + ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, + Call, EngineInfo, BlockProducer, SealedBlockImporter, ProvingBlockChainClient, }; pub use account_state::state::StateInfo; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 3b01275ebe4..0559e1692c7 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -63,13 +63,13 @@ use vm::Schedule; use block::{OpenBlock, SealedBlock, ClosedBlock}; use call_contract::{CallContract, RegistryInfo}; use client::{ - ReopenBlock, PrepareOpenBlock, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, - BroadcastProposalBlock, Call, StateClient, EngineInfo, BlockProducer, SealedBlockImporter, + ReopenBlock, PrepareOpenBlock, ProvingBlockChainClient, ImportSealedBlock, + BroadcastProposalBlock, Call, EngineInfo, BlockProducer, SealedBlockImporter, LastHashes, }; use client_traits::{ BlockInfo, Nonce, Balance, ChainInfo, TransactionInfo, BlockChainClient, ImportBlock, - AccountData, BlockChain, IoClient, BadBlocks, + AccountData, BlockChain, IoClient, BadBlocks, ScheduleInfo, StateClient, StateOrBlock }; use engine::Engine; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 38438a5af78..a30b3b62f66 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -17,7 +17,6 @@ use bytes::Bytes; use client_traits::BlockChainClient; use ethereum_types::{H256, U256, Address}; -use evm::Schedule; use kvdb::DBValue; use types::{ transaction::{SignedTransaction, CallError}, @@ -34,22 +33,6 @@ use engine::Engine; use machine::executed::Executed; use account_state::state::StateInfo; -/// Provides methods to access chain state -pub trait StateClient { - /// Type representing chain state - type State: StateInfo; - - /// Get a copy of the best block's state. - fn latest_state(&self) -> Self::State; - - /// Attempt to get a copy of a specific block's final state. - /// - /// This will not fail if given BlockId::Latest. - /// Otherwise, this can fail (but may not) if the DB prunes state or the block - /// is unknown. - fn state_at(&self, id: BlockId) -> Option; -} - /// Provides `call` and `call_many` methods pub trait Call { /// Type representing chain state @@ -72,7 +55,6 @@ pub trait EngineInfo { fn engine(&self) -> &dyn Engine; } - /// Provides `reopen_block` method pub trait ReopenBlock { /// Reopens an OpenBlock and updates uncles. @@ -92,12 +74,6 @@ pub trait PrepareOpenBlock { /// Provides methods used for sealing new state pub trait BlockProducer: PrepareOpenBlock + ReopenBlock {} -/// Provides `latest_schedule` method -pub trait ScheduleInfo { - /// Returns latest schedule. - fn latest_schedule(&self) -> Schedule; -} - ///Provides `import_sealed_block` method pub trait ImportSealedBlock { /// Import sealed block. Skips all verifications. @@ -134,9 +110,3 @@ pub trait ProvingBlockChainClient: BlockChainClient { /// Get an epoch change signal by block hash. fn epoch_signal(&self, hash: H256) -> Option>; } - -/// resets the blockchain -pub trait BlockChainReset { - /// reset to best_block - n - fn reset(&self, num: u32) -> Result<(), String>; -} diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index aaac509c488..234cd557d54 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -29,7 +29,6 @@ use machine::{ externalities::{OutputPolicy, OriginInfo, Externalities}, substate::Substate, executive::contract_address, - test_helpers::new_frontier_test_machine, }; use test_helpers::get_temp_state; diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index bfdb1b7d849..0de9390259d 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -47,12 +47,8 @@ use types::{ use block::SealedBlock; use call_contract::{CallContract, RegistryInfo}; -use client::{ - ScheduleInfo, BlockProducer, SealedBlockImporter, -}; -use client_traits::{ - BlockChain, ChainInfo, AccountData, Nonce, -}; +use client::{BlockProducer, SealedBlockImporter}; +use client_traits::{BlockChain, ChainInfo, AccountData, Nonce, ScheduleInfo}; use account_state::state::StateInfo; /// Provides methods to verify incoming external transactions diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 2de42b4ce9b..a111640be96 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -31,8 +31,8 @@ use types::{ views::BlockView, }; -use client::{BlockChainReset, Client, ClientConfig, PrepareOpenBlock, ImportSealedBlock}; -use client_traits::{BlockInfo, BlockChainClient, ChainInfo, ImportBlock}; +use client::{Client, ClientConfig, PrepareOpenBlock, ImportSealedBlock}; +use client_traits::{BlockInfo, BlockChainClient, BlockChainReset, ChainInfo, ImportBlock}; use crate::spec; use machine::executive::{Executive, TransactOptions}; use miner::{Miner, PendingOrdering, MinerService}; diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 731d258ab8a..d5e66676803 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -26,9 +26,9 @@ use hash::{keccak, KECCAK_NULL_RLP}; use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; -use client_traits::{BlockInfo, Nonce, Balance, BlockChainClient, ImportBlock}; +use client_traits::{BlockInfo, BlockChainReset, Nonce, Balance, BlockChainClient, ImportBlock}; use ethcore::{ - client::{DatabaseCompactionProfile, VMType, BlockChainReset}, + client::{DatabaseCompactionProfile, VMType}, miner::Miner, verification::queue::VerifierSettings, }; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index de11de63754..09ac505ef75 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -24,9 +24,9 @@ use rlp::Rlp; use ethereum_types::{Address, H64, H160, H256, U64, U256, BigEndianHash}; use parking_lot::Mutex; -use client_traits::{BlockChainClient, StateOrBlock}; +use client_traits::{BlockChainClient, StateClient, StateOrBlock}; use ethash::{self, SeedHashCompute}; -use ethcore::client::{StateClient, StateInfo, Call, EngineInfo, ProvingBlockChainClient}; +use ethcore::client::{StateInfo, Call, EngineInfo, ProvingBlockChainClient}; use ethcore::miner::{self, MinerService}; use ethcore::snapshot::SnapshotService; use hash::keccak; diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 0866d2a5857..75e69dcbfb0 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -20,8 +20,8 @@ use std::collections::BTreeMap; use crypto::DEFAULT_MAC; use ethereum_types::{H64, H160, H256, H512, U64, U256}; -use ethcore::client::{StateClient, Call}; -use client_traits::BlockChainClient; +use ethcore::client::Call; +use client_traits::{BlockChainClient, StateClient}; use ethcore::miner::{self, MinerService, FilterOptions}; use ethcore::snapshot::{SnapshotService, RestorationStatus}; use account_state::state::StateInfo; diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index f0c779654a5..4d0ccc1a90c 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -18,8 +18,8 @@ use std::sync::Arc; -use ethcore::client::{StateClient, StateInfo, Call}; -use client_traits::BlockChainClient; +use ethcore::client::{StateInfo, Call}; +use client_traits::{BlockChainClient, StateClient}; use ethereum_types::H256; use rlp::Rlp; use types::{ diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 2dc3761b061..8bff84dc3b2 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -20,10 +20,10 @@ use std::sync::Arc; use std::collections::{BTreeMap, BTreeSet, HashMap}; use bytes::Bytes; -use client_traits::Nonce; +use client_traits::{Nonce, StateClient}; use engine::{Engine, signer::EngineSigner}; use ethcore::block::SealedBlock; -use ethcore::client::{PrepareOpenBlock, StateClient, EngineInfo, TestState}; +use ethcore::client::{PrepareOpenBlock, EngineInfo, TestState}; use ethcore::miner::{self, MinerService, AuthoringParams, FilterOptions}; use ethereum_types::{H256, U256, Address}; use miner::pool::local_transactions::Status as LocalTransactionStatus; From 07b1c2ddd27c03ba6c202aa731a6fff673b78fc9 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 18:56:15 +0200 Subject: [PATCH 39/43] Move ProvingBlockChainClient to client-traits --- Cargo.lock | 1 + ethcore/client-traits/Cargo.toml | 2 +- ethcore/client-traits/src/lib.rs | 26 +++++++++++++++++++++++++- ethcore/engine/Cargo.toml | 2 +- ethcore/light/src/provider.rs | 2 +- ethcore/machine/src/executive.rs | 2 +- ethcore/src/client/client.rs | 6 +++--- ethcore/src/client/mod.rs | 2 +- ethcore/src/client/test_client.rs | 6 +++--- ethcore/src/client/traits.rs | 26 -------------------------- ethcore/src/tests/client.rs | 2 +- rpc/src/v1/impls/eth.rs | 4 ++-- 12 files changed, 40 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de0ac5a6ee9..a4b9664b190 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,6 +433,7 @@ dependencies = [ "ethcore-db 0.1.0", "ethcore-miner 1.12.0", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "trace 0.1.0", diff --git a/ethcore/client-traits/Cargo.toml b/ethcore/client-traits/Cargo.toml index a65df8db1bf..b00bdd6d7bc 100644 --- a/ethcore/client-traits/Cargo.toml +++ b/ethcore/client-traits/Cargo.toml @@ -18,4 +18,4 @@ stats = { path = "../../util/stats" } vm = { path = "../vm" } trace = { path = "../trace" } ethcore-miner = { path = "../../miner" } - +kvdb = "0.1.0" diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs index d733f56a565..af68b9b3f6c 100644 --- a/ethcore/client-traits/src/lib.rs +++ b/ethcore/client-traits/src/lib.rs @@ -24,6 +24,7 @@ use blockchain::BlockProvider; use bytes::Bytes; use call_contract::{CallContract, RegistryInfo}; use common_types::{ + basic_account::BasicAccount, block_status::BlockStatus, blockchain_info::BlockChainInfo, BlockNumber, @@ -39,13 +40,14 @@ use common_types::{ pruning_info::PruningInfo, receipt::LocalizedReceipt, trace_filter::Filter as TraceFilter, - transaction::{self, LocalizedTransaction, CallError}, + transaction::{self, LocalizedTransaction, CallError, SignedTransaction}, tree_route::TreeRoute, verification::{VerificationQueueInfo, Unverified}, }; use ethereum_types::{Address, H256, U256}; use ethcore_db::keys::BlockReceipts; use ethcore_miner::pool::VerifiedTransaction; +use kvdb::DBValue; use stats; use trace::{ FlatTrace, @@ -399,3 +401,25 @@ pub trait StateClient { /// is unknown. fn state_at(&self, id: BlockId) -> Option; } + +/// Extended client interface for providing proofs of the state. +pub trait ProvingBlockChainClient: BlockChainClient { + /// Prove account storage at a specific block id. + /// + /// Both provided keys assume a secure trie. + /// Returns a vector of raw trie nodes (in order from the root) proving the storage query. + fn prove_storage(&self, key1: H256, key2: H256, id: BlockId) -> Option<(Vec, H256)>; + + /// Prove account existence at a specific block id. + /// The key is the keccak hash of the account's address. + /// Returns a vector of raw trie nodes (in order from the root) proving the query. + fn prove_account(&self, key1: H256, id: BlockId) -> Option<(Vec, BasicAccount)>; + + /// Prove execution of a transaction at the given block. + /// Returns the output of the call and a vector of database items necessary + /// to reproduce it. + fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec)>; + + /// Get an epoch change signal by block hash. + fn epoch_signal(&self, hash: H256) -> Option>; +} diff --git a/ethcore/engine/Cargo.toml b/ethcore/engine/Cargo.toml index 48e386d9b79..dfc67e3995d 100644 --- a/ethcore/engine/Cargo.toml +++ b/ethcore/engine/Cargo.toml @@ -1,5 +1,5 @@ [package] -description = "Ethereum engine trai definition" +description = "Ethereum engine trait definition" name = "engine" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index b50d01face6..c44bf59b398 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -25,11 +25,11 @@ use common_types::{ ids::BlockId, transaction::PendingTransaction, }; -use ethcore::client::ProvingBlockChainClient; use client_traits::{ BlockChainClient, BlockInfo as ClientBlockInfo, ChainInfo, + ProvingBlockChainClient, }; use ethereum_types::H256; use parking_lot::RwLock; diff --git a/ethcore/machine/src/executive.rs b/ethcore/machine/src/executive.rs index 7e9de19f28c..81b92599ca9 100644 --- a/ethcore/machine/src/executive.rs +++ b/ethcore/machine/src/executive.rs @@ -42,7 +42,7 @@ use common_types::{ use crate::{ Machine, substate::Substate, - externalities::{Externalities, OutputPolicy, OriginInfo}, // todo: make explicit + externalities::{Externalities, OutputPolicy, OriginInfo}, transaction_ext::Transaction, }; diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index b5d24dccbd6..2730f0d26d9 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -39,15 +39,15 @@ use hash_db::EMPTY_PREFIX; use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; use client::ancient_import::AncientVerifier; use client::{ - ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, StateInfo, Call, - BlockProducer, SealedBlockImporter, ChainNotify, ProvingBlockChainClient, EngineInfo, + ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, StateInfo, + Call, BlockProducer, SealedBlockImporter, ChainNotify, EngineInfo, ClientConfig, NewBlocks, ChainRoute, ChainMessageType, bad_blocks, ClientIoMessage, }; use client_traits::{ BlockInfo, ScheduleInfo, StateClient, BlockChainReset, Nonce, Balance, ChainInfo, TransactionInfo, ImportBlock, AccountData, BlockChain as BlockChainTrait, BlockChainClient, - IoClient, BadBlocks, + IoClient, BadBlocks, ProvingBlockChainClient, StateOrBlock }; use engines::{EpochTransition, ForkChoice}; diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index b770b59ccbb..cd5dd473598 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -36,7 +36,7 @@ pub use self::test_client::{TestBlockChainClient, EachBlockWith, TestState}; pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::traits::{ ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, - Call, EngineInfo, BlockProducer, SealedBlockImporter, ProvingBlockChainClient, + Call, EngineInfo, BlockProducer, SealedBlockImporter, }; pub use account_state::state::StateInfo; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 0559e1692c7..ad9fc0ad780 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -63,13 +63,13 @@ use vm::Schedule; use block::{OpenBlock, SealedBlock, ClosedBlock}; use call_contract::{CallContract, RegistryInfo}; use client::{ - ReopenBlock, PrepareOpenBlock, ProvingBlockChainClient, ImportSealedBlock, - BroadcastProposalBlock, Call, EngineInfo, BlockProducer, SealedBlockImporter, + ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, Call, + EngineInfo, BlockProducer, SealedBlockImporter, LastHashes, }; use client_traits::{ BlockInfo, Nonce, Balance, ChainInfo, TransactionInfo, BlockChainClient, ImportBlock, - AccountData, BlockChain, IoClient, BadBlocks, ScheduleInfo, StateClient, + AccountData, BlockChain, IoClient, BadBlocks, ScheduleInfo, StateClient, ProvingBlockChainClient, StateOrBlock }; use engine::Engine; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index a30b3b62f66..36ce4144497 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -15,17 +15,13 @@ // along with Parity Ethereum. If not, see . use bytes::Bytes; -use client_traits::BlockChainClient; use ethereum_types::{H256, U256, Address}; -use kvdb::DBValue; use types::{ transaction::{SignedTransaction, CallError}, - basic_account::BasicAccount, call_analytics::CallAnalytics, errors::EthcoreError as Error, errors::EthcoreResult, header::Header, - ids::*, }; use block::{OpenBlock, SealedBlock, ClosedBlock}; @@ -88,25 +84,3 @@ pub trait BroadcastProposalBlock { /// Provides methods to import sealed block and broadcast a block proposal pub trait SealedBlockImporter: ImportSealedBlock + BroadcastProposalBlock {} - -/// Extended client interface for providing proofs of the state. -pub trait ProvingBlockChainClient: BlockChainClient { - /// Prove account storage at a specific block id. - /// - /// Both provided keys assume a secure trie. - /// Returns a vector of raw trie nodes (in order from the root) proving the storage query. - fn prove_storage(&self, key1: H256, key2: H256, id: BlockId) -> Option<(Vec, H256)>; - - /// Prove account existence at a specific block id. - /// The key is the keccak hash of the account's address. - /// Returns a vector of raw trie nodes (in order from the root) proving the query. - fn prove_account(&self, key1: H256, id: BlockId) -> Option<(Vec, BasicAccount)>; - - /// Prove execution of a transaction at the given block. - /// Returns the output of the call and a vector of database items necessary - /// to reproduce it. - fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec)>; - - /// Get an epoch change signal by block hash. - fn epoch_signal(&self, hash: H256) -> Option>; -} diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index a111640be96..ea2aff7ae64 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -327,7 +327,7 @@ fn does_not_propagate_delayed_transactions() { #[test] fn transaction_proof() { - use ::client::ProvingBlockChainClient; + use client_traits::ProvingBlockChainClient; let client = generate_dummy_client(0); let address = Address::random(); diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 09ac505ef75..f50d79b5a54 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -24,9 +24,9 @@ use rlp::Rlp; use ethereum_types::{Address, H64, H160, H256, U64, U256, BigEndianHash}; use parking_lot::Mutex; -use client_traits::{BlockChainClient, StateClient, StateOrBlock}; +use client_traits::{BlockChainClient, StateClient, ProvingBlockChainClient, StateOrBlock}; use ethash::{self, SeedHashCompute}; -use ethcore::client::{StateInfo, Call, EngineInfo, ProvingBlockChainClient}; +use ethcore::client::{StateInfo, Call, EngineInfo}; use ethcore::miner::{self, MinerService}; use ethcore::snapshot::SnapshotService; use hash::keccak; From 7e5e4bcba68252dedea02d819bb680259d5a0ced Mon Sep 17 00:00:00 2001 From: David Palm Date: Sat, 10 Aug 2019 19:13:53 +0200 Subject: [PATCH 40/43] Don't re-export ForkChoice and Transition from ethcore --- ethcore/light/src/client/header_chain.rs | 5 ++++- ethcore/light/src/client/mod.rs | 4 ++-- ethcore/src/client/client.rs | 9 +++++---- ethcore/src/client/test_client.rs | 3 ++- ethcore/src/engines/mod.rs | 4 ---- ethcore/src/snapshot/consensus/authority.rs | 3 +-- ethcore/src/snapshot/consensus/work.rs | 3 ++- ethcore/src/snapshot/tests/proof_of_work.rs | 7 +++++-- ethcore/src/test_helpers.rs | 5 +++-- 9 files changed, 24 insertions(+), 19 deletions(-) diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index 3b9d2beec4b..92207139a0e 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -33,11 +33,14 @@ use cht; use common_types::{ block_status::BlockStatus, encoded, + engines::epoch::{ + Transition as EpochTransition, + PendingTransition as PendingEpochTransition, + }, errors::{EthcoreError as Error, BlockError, EthcoreResult}, header::Header, ids::BlockId, }; -use ethcore::engines::epoch::{Transition as EpochTransition, PendingTransition as PendingEpochTransition}; use ethcore::spec::{Spec, SpecHardcodedSync}; use ethereum_types::{H256, H264, U256}; use parity_util_mem::{MallocSizeOf, MallocSizeOfOps}; diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index 8a1100cf649..73e512b10b2 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -20,7 +20,6 @@ use std::sync::{Weak, Arc}; use engine::{Engine, EpochChange, Proof}; use ethcore::client::{ClientReport, EnvInfo, ClientIoMessage}; -use ethcore::engines::{epoch, EpochTransition}; use ethcore::verification::queue::{self, HeaderQueue}; use ethcore::spec::{Spec, SpecHardcodedSync}; use io::IoChannel; @@ -32,6 +31,7 @@ use common_types::{ block_status::BlockStatus, blockchain_info::BlockChainInfo, encoded, + engines::epoch::{Transition as EpochTransition, PendingTransition}, errors::EthcoreError as Error, errors::EthcoreResult, header::Header, @@ -529,7 +529,7 @@ impl Client { }; let mut batch = self.db.transaction(); - self.chain.insert_pending_transition(&mut batch, header.hash(), &epoch::PendingTransition { + self.chain.insert_pending_transition(&mut batch, header.hash(), &PendingTransition { proof, }); self.db.write_buffered(batch); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 2730f0d26d9..31fe29f9835 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -50,7 +50,6 @@ use client_traits::{ IoClient, BadBlocks, ProvingBlockChainClient, StateOrBlock }; -use engines::{EpochTransition, ForkChoice}; use engine::Engine; use machine::{ executed::Executed, @@ -73,9 +72,10 @@ use types::{ blockchain_info::BlockChainInfo, encoded, engines::{ + ForkChoice, SealingState, MAX_UNCLE_AGE, - epoch::PendingTransition, + epoch::{PendingTransition, Transition as EpochTransition}, machine::{AuxiliaryData, Call as MachineCall}, }, errors::{EngineError, ExecutionError, BlockError, EthcoreError, SnapshotError, ImportError, EthcoreResult}, @@ -2527,7 +2527,7 @@ impl client_traits::EngineClient for Client { self.notify(|notify| notify.broadcast(ChainMessageType::Consensus(message.clone()))); } - fn epoch_transition_for(&self, parent_hash: H256) -> Option<::engines::EpochTransition> { + fn epoch_transition_for(&self, parent_hash: H256) -> Option { self.chain.read().epoch_transition_for(parent_hash) } @@ -2664,6 +2664,7 @@ mod tests { use client_traits::{BlockChainClient, ChainInfo}; use types::{ encoded, + engines::ForkChoice, ids::{BlockId, TransactionId}, log_entry::{LogEntry, LocalizedLogEntry}, receipt::{Receipt, LocalizedReceipt, TransactionOutcome}, @@ -2694,7 +2695,7 @@ mod tests { thread::spawn(move || { let mut batch = DBTransaction::new(); another_client.chain.read().insert_block(&mut batch, encoded::Block::new(new_block), Vec::new(), ExtrasInsert { - fork_choice: ::engines::ForkChoice::New, + fork_choice: ForkChoice::New, is_finalized: false, }); go_thread.store(true, Ordering::SeqCst); diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index ad9fc0ad780..42d30bbc22c 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -40,6 +40,7 @@ use rustc_hex::FromHex; use types::{ BlockNumber, encoded, + engines::epoch::Transition as EpochTransition, ids::{BlockId, TransactionId, UncleId, TraceId}, basic_account::BasicAccount, errors::{EthcoreError as Error, EthcoreResult}, @@ -964,7 +965,7 @@ impl client_traits::EngineClient for TestBlockChainClient { fn broadcast_consensus_message(&self, _message: Bytes) {} - fn epoch_transition_for(&self, _block_hash: H256) -> Option<::engines::EpochTransition> { + fn epoch_transition_for(&self, _block_hash: H256) -> Option { None } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index f5d8c4bdd27..780a6a06328 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -32,7 +32,3 @@ pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::null_engine::NullEngine; pub use self::clique::Clique; pub use self::ethash::{Ethash, Seal as EthashSeal}; - -// TODO [ToDr] Remove re-export (#10130) -pub use types::engines::ForkChoice; -pub use types::engines::epoch::{self, Transition as EpochTransition}; diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index d24c890db06..19f46bb144c 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -27,8 +27,6 @@ use engine::{ EpochVerifier, snapshot::{SnapshotComponents, Rebuilder} }; -use engines::EpochTransition; - use blockchain::{BlockChain, BlockChainDB, BlockProvider}; use bytes::Bytes; use ethereum_types::{H256, U256}; @@ -37,6 +35,7 @@ use kvdb::KeyValueDB; use rlp::{RlpStream, Rlp}; use types::{ encoded, + engines::epoch::Transition as EpochTransition, header::Header, ids::BlockId, errors::{SnapshotError, EthcoreError}, diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index 5ffc8c53f40..f9c4faec343 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -35,6 +35,7 @@ use rlp::{RlpStream, Rlp}; use rand::rngs::OsRng; use types::{ encoded, + engines::epoch::Transition as EpochTransition, errors::{SnapshotError, EthcoreError}, snapshot::{ChunkSink, ManifestData, Progress}, }; @@ -318,7 +319,7 @@ impl Rebuilder for PowRebuilder { } let genesis_hash = self.chain.genesis_hash(); - self.chain.insert_epoch_transition(&mut batch, 0, ::engines::EpochTransition { + self.chain.insert_epoch_transition(&mut batch, 0, EpochTransition { block_number: 0, block_hash: genesis_hash, proof: vec![], diff --git a/ethcore/src/snapshot/tests/proof_of_work.rs b/ethcore/src/snapshot/tests/proof_of_work.rs index eee12a0c271..6e7726a6a0c 100644 --- a/ethcore/src/snapshot/tests/proof_of_work.rs +++ b/ethcore/src/snapshot/tests/proof_of_work.rs @@ -18,7 +18,10 @@ use std::sync::atomic::AtomicBool; use tempdir::TempDir; -use types::errors::EthcoreError as Error; +use types::{ + errors::EthcoreError as Error, + engines::ForkChoice, +}; use blockchain::generator::{BlockGenerator, BlockBuilder}; use blockchain::{BlockChain, ExtrasInsert}; @@ -50,7 +53,7 @@ fn chunk_and_restore(amount: u64) { let mut batch = DBTransaction::new(); for block in generator { bc.insert_block(&mut batch, block.encoded(), vec![], ExtrasInsert { - fork_choice: ::engines::ForkChoice::New, + fork_choice: ForkChoice::New, is_finalized: false, }); bc.commit(); diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 145eee4041a..32a5f7778da 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -36,6 +36,7 @@ use tempdir::TempDir; use types::{ transaction::{Action, Transaction, SignedTransaction}, encoded, + engines::ForkChoice, header::Header, view, views::BlockView, @@ -378,7 +379,7 @@ pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain { for block_order in 1..block_number { // Total difficulty is always 0 here. bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block(block_order, bc.best_block_hash())), vec![], ExtrasInsert { - fork_choice: ::engines::ForkChoice::New, + fork_choice: ForkChoice::New, is_finalized: false, }); bc.commit(); @@ -396,7 +397,7 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain { for block_order in 1..block_number { // Total difficulty is always 0 here. bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None)), vec![], ExtrasInsert { - fork_choice: ::engines::ForkChoice::New, + fork_choice: ForkChoice::New, is_finalized: false, }); bc.commit(); From b244bfbe44f1fcf2f5f36cbfa798ec4a7d2a1c8d Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 13 Aug 2019 12:34:53 +0200 Subject: [PATCH 41/43] Address grumbles: sort imports, remove commented out code --- ethcore/Cargo.toml | 18 +++++++++--------- ethcore/client-traits/Cargo.toml | 12 ++++++------ ethcore/engine/Cargo.toml | 4 ++-- ethcore/src/engines/ethash.rs | 24 ------------------------ 4 files changed, 17 insertions(+), 41 deletions(-) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 56bb163f096..9874215b42d 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Parity Technologies "] [dependencies] account-db = { path = "account-db" } +account-state = { path = "account-state" } ansi_term = "0.11" blooms-db = { path = "../util/blooms-db", optional = true } client-traits = { path = "./client-traits" } @@ -31,10 +32,8 @@ ethereum-types = "0.6.0" ethjson = { path = "../json" } ethkey = { path = "../accounts/ethkey" } evm = { path = "evm" } -trie-vm-factories = { path = "trie-vm-factories" } futures = "0.1" hash-db = "0.12.4" -parity-util-mem = "0.1" itertools = "0.5" journaldb = { path = "../util/journaldb" } keccak-hash = "0.2.0" @@ -52,44 +51,45 @@ memory-cache = { path = "../util/memory-cache" } num_cpus = "1.2" parity-bytes = "0.1" parity-snappy = "0.1" +parity-util-mem = "0.1" parking_lot = "0.8" -pod = { path = "pod" } -trie-db = "0.12.4" patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" } +pod = { path = "pod" } rand = "0.6" +rand_xorshift = "0.1.1" rayon = "1.1" rlp = "0.4.0" rlp_derive = { path = "../util/rlp-derive" } rustc-hex = "1.0" serde = "1.0" serde_derive = "1.0" -account-state = { path = "account-state" } -stats = { path = "../util/stats" } state-db = { path = "state-db" } +stats = { path = "../util/stats" } tempdir = { version = "0.3", optional = true } time-utils = { path = "../util/time-utils" } trace = { path = "trace" } trace-time = "0.1" +trie-db = "0.12.4" +trie-vm-factories = { path = "trie-vm-factories" } triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" } unexpected = { path = "../util/unexpected" } using_queue = { path = "../miner/using-queue" } vm = { path = "vm" } -rand_xorshift = "0.1.1" [dev-dependencies] blooms-db = { path = "../util/blooms-db" } criterion = "0.2" +engine = { path = "./engine", features = ["test-helpers"] } env_logger = "0.5" ethcore-accounts = { path = "../accounts" } fetch = { path = "../util/fetch" } kvdb-rocksdb = "0.1.3" +machine = { path = "./machine", features = ["test-helpers"] } parity-runtime = { path = "../util/runtime" } rlp_compress = { path = "../util/rlp-compress" } serde_json = "1.0" tempdir = "0.3" trie-standardmap = "0.12.4" -engine = { path = "./engine", features = ["test-helpers"] } -machine = { path = "./machine", features = ["test-helpers"] } [features] parity = ["work-notify", "price-info", "stratum"] diff --git a/ethcore/client-traits/Cargo.toml b/ethcore/client-traits/Cargo.toml index b00bdd6d7bc..bc8b06f0fe2 100644 --- a/ethcore/client-traits/Cargo.toml +++ b/ethcore/client-traits/Cargo.toml @@ -9,13 +9,13 @@ license = "GPL-3.0" [dependencies] account-state = { path = "../account-state" } blockchain = { package = "ethcore-blockchain", path = "../blockchain" } +bytes = { package = "parity-bytes", version = "0.1.0" } call-contract = { package = "ethcore-call-contract", path = "../call-contract" } -ethereum-types = "0.6.0" -ethcore-db = { path = "../db" } common-types = { path = "../types" } -bytes = { package = "parity-bytes", version = "0.1.0" } -stats = { path = "../../util/stats" } -vm = { path = "../vm" } -trace = { path = "../trace" } +ethcore-db = { path = "../db" } ethcore-miner = { path = "../../miner" } +ethereum-types = "0.6.0" kvdb = "0.1.0" +stats = { path = "../../util/stats" } +trace = { path = "../trace" } +vm = { path = "../vm" } diff --git a/ethcore/engine/Cargo.toml b/ethcore/engine/Cargo.toml index dfc67e3995d..28b2e5527fd 100644 --- a/ethcore/engine/Cargo.toml +++ b/ethcore/engine/Cargo.toml @@ -8,13 +8,13 @@ license = "GPL-3.0" [dependencies] blockchain = { package = "ethcore-blockchain", path = "../blockchain" } +builtin = { path = "../builtin", package = "ethcore-builtin" } +bytes = { package = "parity-bytes", version = "0.1.0" } client-traits = { path = "../client-traits" } common-types = { path = "../types" } -builtin = { path = "../builtin", package = "ethcore-builtin" } ethereum-types = "0.6.0" ethkey = { path = "../../accounts/ethkey" } machine = { path = "../machine" } -bytes = { package = "parity-bytes", version = "0.1.0" } vm = { path = "../vm" } # used from test-helpers diff --git a/ethcore/src/engines/ethash.rs b/ethcore/src/engines/ethash.rs index 70549b6bdef..df75ae816b5 100644 --- a/ethcore/src/engines/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -251,7 +251,6 @@ impl engine::EpochVerifier for EpochVerifier { } } -//impl Engine for Arc { impl Engine for Ethash { fn name(&self) -> &str { "Ethash" } fn machine(&self) -> &Machine { &self.machine } @@ -375,29 +374,6 @@ impl Engine for Ethash { fn verify_block_unordered(&self, header: &Header) -> Result<(), Error> { verify_block_unordered(&self.pow, header) -// let seal = Seal::parse_seal(header.seal())?; -// -// let result = self.pow.compute_light( -// header.number() as u64, -// &header.bare_hash().0, -// seal.nonce.to_low_u64_be() -// ); -// let mix = H256(result.mix_hash); -// let difficulty = ethash::boundary_to_difficulty(&H256(result.value)); -// trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}", -// num = header.number() as u64, -// seed = H256(slow_hash_block_number(header.number() as u64)), -// h = header.bare_hash(), -// non = seal.nonce.to_low_u64_be(), -// mix = H256(result.mix_hash), -// res = H256(result.value)); -// if mix != seal.mix_hash { -// return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash }))); -// } -// if &difficulty < header.difficulty() { -// return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty }))); -// } -// Ok(()) } fn verify_block_family(&self, header: &Header, parent: &Header) -> Result<(), Error> { From 88cfa7fc7f9b59a56166b46dfa06f4a6765f4ec9 Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 13 Aug 2019 13:26:20 +0200 Subject: [PATCH 42/43] Fix merge resolution error --- rpc/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 1ae66453ba9..897df8d96c1 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -123,8 +123,6 @@ extern crate fake_fetch; #[cfg(test)] extern crate ethcore_io as io; -#[cfg(test)] -extern crate client_traits; pub extern crate jsonrpc_ws_server as ws; From 60a03b20ee068db1c8c80e14ff454b002102132c Mon Sep 17 00:00:00 2001 From: David Palm Date: Thu, 15 Aug 2019 16:41:19 +0200 Subject: [PATCH 43/43] merge failure --- ethcore/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index cbeef080922..f896042aa88 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -52,7 +52,6 @@ memory-cache = { path = "../util/memory-cache" } num_cpus = "1.2" parity-bytes = "0.1" parity-snappy = "0.1" -parity-util-mem = "0.1" parking_lot = "0.8" trie-db = "0.15.0" patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" } @@ -71,7 +70,6 @@ tempdir = { version = "0.3", optional = true } time-utils = { path = "../util/time-utils" } trace = { path = "trace" } trace-time = "0.1" -trie-db = "0.12.4" trie-vm-factories = { path = "trie-vm-factories" } triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" } unexpected = { path = "../util/unexpected" }