diff --git a/Cargo.lock b/Cargo.lock index 396caa4d0..d2b8d2353 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -454,16 +454,22 @@ dependencies = [ name = "common-types" version = "0.1.0" dependencies = [ + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethbloom 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "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", "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)", + "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_derive 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unexpected 0.1.0", + "vm 0.1.0", ] [[package]] @@ -513,7 +519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (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.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -854,7 +860,6 @@ 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)", - "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)", @@ -889,7 +894,7 @@ dependencies = [ "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "memory-cache 0.1.0", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-runtime 0.1.0", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1020,7 +1025,7 @@ 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)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (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)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1032,7 +1037,6 @@ dependencies = [ name = "ethcore-light" version = "1.12.0" dependencies = [ - "account-state 0.1.0", "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1268,6 +1272,7 @@ name = "ethcore-service" version = "0.1.0" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "common-types 0.1.0", "ethcore 1.12.0", "ethcore-blockchain 0.1.0", "ethcore-db 0.1.0", @@ -1426,7 +1431,7 @@ dependencies = [ "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethstore 0.2.1", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1621,7 +1626,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2071,7 +2076,7 @@ dependencies = [ "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)", - "num_cpus 1.10.0 (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)", "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2168,7 +2173,7 @@ dependencies = [ "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rocksdb 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2551,7 +2556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2703,7 +2708,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "migration-rocksdb 0.1.0", "node-filter 1.12.0", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3469,7 +3474,7 @@ dependencies = [ "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4086,7 +4091,7 @@ name = "threadpool" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4209,7 +4214,7 @@ 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)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (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)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4257,7 +4262,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)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (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)", ] @@ -4973,7 +4978,7 @@ dependencies = [ "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" +"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index bfe330bca..90a33c7fd 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -12,7 +12,6 @@ ansi_term = "0.11" blooms-db = { path = "../util/blooms-db", optional = true } common-types = { path = "types" } crossbeam-utils = "0.6" -derive_more = "0.14.0" env_logger = { version = "0.5", optional = true } ethabi = "8.0" ethabi-contract = "8.0" diff --git a/ethcore/account-db/Cargo.toml b/ethcore/account-db/Cargo.toml index e3d0dea21..850b55905 100644 --- a/ethcore/account-db/Cargo.toml +++ b/ethcore/account-db/Cargo.toml @@ -1,8 +1,9 @@ [package] -description = "DB backend wrapper for Account trie" name = "account-db" -version = "0.1.0" +description = "DB backend wrapper for Account trie" authors = ["Parity Technologies "] +license = "GPL-3.0" +version = "0.1.0" edition = "2018" [dependencies] diff --git a/ethcore/account-state/Cargo.toml b/ethcore/account-state/Cargo.toml index 71d206f3e..e7ff784e4 100644 --- a/ethcore/account-state/Cargo.toml +++ b/ethcore/account-state/Cargo.toml @@ -1,8 +1,9 @@ [package] -description = "Ethereum accounts, keeps track of changes to the code and storage" name = "account-state" -version = "0.1.0" +description = "Ethereum accounts, keeps track of changes to the code and storage" authors = ["Parity Technologies "] +license = "GPL-3.0" +version = "0.1.0" edition = "2018" [dependencies] diff --git a/ethcore/account-state/src/account.rs b/ethcore/account-state/src/account.rs index c0bab08be..48d528014 100644 --- a/ethcore/account-state/src/account.rs +++ b/ethcore/account-state/src/account.rs @@ -29,7 +29,6 @@ use lru_cache::LruCache; use parity_bytes::{Bytes, ToPretty}; use rlp::{DecoderError, encode}; use trie_db::{Recorder, Trie}; - use common_types::basic_account::BasicAccount; use ethtrie::{Result as TrieResult, SecTrieDB, TrieDB, TrieFactory}; use keccak_hasher::KeccakHasher; diff --git a/ethcore/account-state/src/backend.rs b/ethcore/account-state/src/backend.rs index 563aa1023..5aa675ff9 100644 --- a/ethcore/account-state/src/backend.rs +++ b/ethcore/account-state/src/backend.rs @@ -29,7 +29,6 @@ use hash_db::{AsHashDB, EMPTY_PREFIX, HashDB, Prefix}; use kvdb::DBValue; use memory_db::{HashKey, MemoryDB}; use parking_lot::Mutex; - use journaldb::AsKeyedHashDB; use keccak_hasher::KeccakHasher; @@ -222,7 +221,7 @@ impl> Proving { /// This will store all values ever fetched from that base. pub fn new(base: H) -> Self { Proving { - base: base, + base, changed: journaldb::new_memory_db(), proof: Mutex::new(HashSet::new()), } diff --git a/ethcore/account-state/src/lib.rs b/ethcore/account-state/src/lib.rs index 83313e8b8..953912d40 100644 --- a/ethcore/account-state/src/lib.rs +++ b/ethcore/account-state/src/lib.rs @@ -25,11 +25,9 @@ pub mod account; pub mod backend; pub mod state; -pub mod error; pub use { account::Account, backend::Backend, - error::Error, state::{State, CleanupMode}, }; diff --git a/ethcore/account-state/src/state.rs b/ethcore/account-state/src/state.rs index 72889ab8f..abcdf6866 100644 --- a/ethcore/account-state/src/state.rs +++ b/ethcore/account-state/src/state.rs @@ -32,6 +32,7 @@ use std::{ use common_types::{ state_diff::StateDiff, basic_account::BasicAccount, + errors::EthcoreError as Error, }; use ethereum_types::{Address, H256, U256}; use ethtrie::{TrieDB, Result as TrieResult}; @@ -46,7 +47,6 @@ use pod::{self, PodAccount, PodState}; use trie_db::{Trie, TrieError, Recorder}; use crate::{ - Error, account::Account, backend::Backend, }; diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 90507a515..be6f1b164 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -35,7 +35,6 @@ itertools = "0.5" bincode = "1.1" serde = "1.0" serde_derive = "1.0" -account-state = { path = "../account-state" } parking_lot = "0.8" stats = { path = "../../util/stats" } keccak-hash = "0.2.0" diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index 905a7bd1e..172240388 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -30,12 +30,14 @@ use std::sync::Arc; use cache::Cache; use cht; -use common_types::block_status::BlockStatus; -use common_types::encoded; -use common_types::header::Header; -use common_types::ids::BlockId; +use common_types::{ + block_status::BlockStatus, + encoded, + errors::{EthcoreError as Error, BlockError, EthcoreResult}, + header::Header, + ids::BlockId, +}; use ethcore::engines::epoch::{Transition as EpochTransition, PendingTransition as PendingEpochTransition}; -use ethcore::error::{Error, EthcoreResult, BlockError}; 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 ee0a09b1a..6d4dd5a0b 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -20,21 +20,23 @@ use std::sync::{Weak, Arc}; use ethcore::client::{ClientReport, EnvInfo, ClientIoMessage}; use ethcore::engines::{epoch, Engine, EpochChange, EpochTransition, Proof}; -use ethcore::error::{Error, EthcoreResult}; use ethcore::verification::queue::{self, HeaderQueue}; use ethcore::spec::{Spec, SpecHardcodedSync}; use io::IoChannel; use parking_lot::{Mutex, RwLock}; use ethereum_types::{H256, U256}; use futures::{IntoFuture, Future}; -use common_types::BlockNumber; -use common_types::block_status::BlockStatus; -use common_types::blockchain_info::BlockChainInfo; -use common_types::encoded; -use common_types::header::Header; -use common_types::ids::BlockId; -use common_types::verification_queue_info::VerificationQueueInfo as BlockQueueInfo; - +use common_types::{ + BlockNumber, + block_status::BlockStatus, + blockchain_info::BlockChainInfo, + encoded, + errors::EthcoreError as Error, + errors::EthcoreResult, + header::Header, + ids::BlockId, + verification_queue_info::VerificationQueueInfo as BlockQueueInfo, +}; use kvdb::KeyValueDB; use self::fetch::ChainDataFetcher; @@ -468,7 +470,7 @@ impl Client { } fn check_epoch_signal(&self, verified_header: &Header) -> Result, T::Error> { - use ethcore::machine::{AuxiliaryRequest, AuxiliaryData}; + use common_types::engines::machine::{AuxiliaryRequest, AuxiliaryData}; let mut block: Option> = None; let mut receipts: Option> = None; diff --git a/ethcore/light/src/client/service.rs b/ethcore/light/src/client/service.rs index 61e65357f..f08f05975 100644 --- a/ethcore/light/src/client/service.rs +++ b/ethcore/light/src/client/service.rs @@ -20,10 +20,10 @@ use std::fmt; use std::sync::Arc; +use common_types::errors::EthcoreError as CoreError; use ethcore_db as db; use ethcore_blockchain::BlockChainDB; use ethcore::client::ClientIoMessage; -use ethcore::error::Error as CoreError; use ethcore::spec::Spec; use io::{IoContext, IoError, IoHandler, IoService}; diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index dadb90c66..d169c6925 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -89,7 +89,6 @@ extern crate triehash_ethereum as triehash; extern crate kvdb; extern crate memory_cache; extern crate derive_more; -extern crate account_state; #[cfg(test)] extern crate kvdb_memorydb; diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index d57699a79..15b04ca63 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -26,7 +26,6 @@ use common_types::receipt::Receipt; use common_types::transaction::SignedTransaction; use ethcore::engines::{Engine, StateDependentProof}; use ethcore::executive_state::{ProvedExecution, self}; -use account_state; use ethereum_types::{H256, U256, Address}; use ethtrie::{TrieError, TrieDB}; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak}; diff --git a/ethcore/pod/Cargo.toml b/ethcore/pod/Cargo.toml index cef7d8542..f9bc2b3ad 100644 --- a/ethcore/pod/Cargo.toml +++ b/ethcore/pod/Cargo.toml @@ -1,8 +1,9 @@ [package] -description = "State/Account system expressed in Plain Old Data." name = "pod" -version = "0.1.0" +description = "State/Account system expressed in Plain Old Data." authors = ["Parity Technologies "] +license = "GPL-3.0" +version = "0.1.0" edition = "2018" [dependencies] diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs index b4fc4a3fa..4d26599a5 100644 --- a/ethcore/private-tx/src/error.rs +++ b/ethcore/private-tx/src/error.rs @@ -19,8 +19,10 @@ use derive_more::Display; use ethereum_types::Address; use rlp::DecoderError; use ethtrie::TrieError; -use ethcore::error::{Error as EthcoreError, ExecutionError}; -use types::transaction::Error as TransactionError; +use types::{ + errors::{EthcoreError, ExecutionError}, + transaction::Error as TransactionError, +}; use ethkey::Error as KeyError; use ethkey::crypto::Error as CryptoError; use txpool::VerifiedTransaction; diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index ab62cb1ba..7d68a7719 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Parity Technologies "] [dependencies] ansi_term = "0.11" +common-types = { path = "../types" } ethcore = { path = ".." } ethcore-blockchain = { path = "../blockchain" } ethcore-io = { path = "../../util/io" } diff --git a/ethcore/service/src/lib.rs b/ethcore/service/src/lib.rs index f9a4da5e4..fabb4a9b0 100644 --- a/ethcore/service/src/lib.rs +++ b/ethcore/service/src/lib.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . extern crate ansi_term; +extern crate common_types; extern crate ethcore; extern crate ethcore_blockchain as blockchain; extern crate ethcore_io as io; diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index a227de06b..8496f5a0d 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -29,9 +29,9 @@ use blockchain::{BlockChainDB, BlockChainDBHandler}; use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; -use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus, Error as SnapshotError}; +use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus}; use ethcore::spec::Spec; -use ethcore::error::Error as EthcoreError; +use common_types::errors::{EthcoreError, SnapshotError}; use ethcore_private_tx::{self, Importer, Signer}; diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index ef8e27db1..19a4a70b6 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -39,21 +39,23 @@ use bytes::Bytes; use ethereum_types::{H256, U256, Address, Bloom}; use engines::Engine; -use error::{Error, BlockError}; use trie_vm_factories::Factories; use state_db::StateDB; use account_state::State; use trace::Tracing; use triehash::ordered_trie_root; use unexpected::{Mismatch, OutOfBounds}; -use verification::PreverifiedBlock; use vm::{EnvInfo, LastHashes}; use hash::keccak; use rlp::{RlpStream, Encodable, encode_list}; -use types::transaction::{SignedTransaction, Error as TransactionError}; -use types::header::Header; -use types::receipt::{Receipt, TransactionOutcome}; +use types::{ + block::PreverifiedBlock, + errors::{EthcoreError as Error, BlockError}, + transaction::{SignedTransaction, Error as TransactionError}, + header::Header, + receipt::{Receipt, TransactionOutcome}, +}; use executive_state::ExecutiveState; /// Block that is ready for transactions to be added. @@ -550,16 +552,16 @@ mod tests { use super::*; use engines::Engine; use vm::LastHashes; - use error::Error; use trie_vm_factories::Factories; 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; - use types::view; - use types::views::BlockView; + use types::{ + header::Header, view, views::BlockView, + errors::EthcoreError as Error, + }; use hash_db::EMPTY_PREFIX; /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header diff --git a/ethcore/src/client/ancient_import.rs b/ethcore/src/client/ancient_import.rs index f89afa13a..22f13ff53 100644 --- a/ethcore/src/client/ancient_import.rs +++ b/ethcore/src/client/ancient_import.rs @@ -23,7 +23,10 @@ use engines::{Engine, EpochVerifier}; use blockchain::BlockChain; use parking_lot::RwLock; use rand::Rng; -use types::header::Header; +use types::{ + header::Header, + errors::EthcoreError, +}; // do "heavy" verification on ~1/50 blocks, randomly sampled. const HEAVY_VERIFY_RATE: f32 = 0.02; @@ -51,7 +54,7 @@ impl AncientVerifier { rng: &mut R, header: &Header, chain: &BlockChain, - ) -> Result<(), ::error::Error> { + ) -> Result<(), EthcoreError> { // perform verification let verified = if let Some(ref cur_verifier) = *self.cur_verifier.read() { match rng.gen::() <= HEAVY_VERIFY_RATE { @@ -86,7 +89,7 @@ impl AncientVerifier { } fn initial_verifier(&self, header: &Header, chain: &BlockChain) - -> Result, ::error::Error> + -> Result, EthcoreError> { trace!(target: "client", "Initializing ancient block restoration."); let current_epoch_data = chain.epoch_transitions() diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index ac6205e6f..e0633f5cb 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -33,38 +33,25 @@ use journaldb; use kvdb::{DBValue, KeyValueDB, DBTransaction}; use parking_lot::{Mutex, RwLock}; use rand::rngs::OsRng; -use types::transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Action}; use trie::{TrieSpec, TrieFactory, Trie}; -use types::ancestry_action::AncestryAction; -use types::encoded; -use types::filter::Filter; -use types::log_entry::LocalizedLogEntry; -use types::receipt::{Receipt, LocalizedReceipt}; -use types::{BlockNumber, header::Header}; use vm::{EnvInfo, LastHashes, CreateContractAddress}; use hash_db::EMPTY_PREFIX; use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; use client::ancient_import::AncientVerifier; use client::{ - Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo, + Nonce, Balance, ChainInfo, TransactionInfo, ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call, AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter, - ClientIoMessage, BlockChainReset + BlockChainReset }; use client::{ BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, TraceFilter, CallAnalytics, Mode, ChainNotify, NewBlocks, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType, - IoClient, BadBlocks, -}; -use client::bad_blocks; -use engines::{MAX_UNCLE_AGE, Engine, EpochTransition, ForkChoice, EngineError, SealingState}; -use engines::epoch::PendingTransition; -use error::{ - ImportError, ExecutionError, CallError, BlockError, - Error as EthcoreError, EthcoreResult, + IoClient, BadBlocks, bad_blocks, BlockInfo, ClientIoMessage, }; +use engines::{Engine, EpochTransition, ForkChoice}; use executive::{Executive, Executed, TransactOptions, contract_address}; use trie_vm_factories::{Factories, VmFactory}; use miner::{Miner, MinerService}; @@ -75,18 +62,37 @@ 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, + block::PreverifiedBlock, + encoded, + engines::{ + SealingState, + MAX_UNCLE_AGE, + epoch::PendingTransition, + machine::{AuxiliaryData, Call as MachineCall}, + }, + errors::{EngineError, ExecutionError, BlockError, EthcoreError, SnapshotError, ImportError, EthcoreResult}, + transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Action, CallError}, + filter::Filter, + log_entry::LocalizedLogEntry, + receipt::{Receipt, LocalizedReceipt}, + header::Header, +}; + use verification::queue::kind::BlockLike; use verification::queue::kind::blocks::Unverified; -use verification::{PreverifiedBlock, Verifier, BlockQueue}; +use verification::{Verifier, BlockQueue}; use verification; 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 blockchain::CacheSize as BlockChainCacheSize; -pub use verification::QueueInfo as BlockQueueInfo; -use db::{Writable, Readable, keys::BlockDetails}; +pub use types::verification_queue_info::VerificationQueueInfo as BlockQueueInfo; use_contract!(registry, "res/contracts/registrar.json"); @@ -249,7 +255,12 @@ impl Importer { message_channel: IoChannel, miner: Arc, ) -> Result { - let block_queue = BlockQueue::new(config.queue.clone(), engine.clone(), message_channel.clone(), config.verifier_type.verifying_seal()); + let block_queue = BlockQueue::new( + config.queue.clone(), + engine.clone(), + message_channel.clone(), + config.verifier_type.verifying_seal() + ); Ok(Importer { import_lock: Mutex::new(()), @@ -384,7 +395,7 @@ impl Importer { if let Err(e) = verify_family_result { warn!(target: "client", "Stage 3 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); - return Err(e.into()); + return Err(e); }; let verify_external_result = self.verifier.verify_block_external(&header, engine); @@ -591,7 +602,7 @@ impl Importer { use engines::EpochChange; let hash = header.hash(); - let auxiliary = ::machine::AuxiliaryData { + let auxiliary = AuxiliaryData { bytes: Some(block_bytes), receipts: Some(&receipts), }; @@ -935,7 +946,7 @@ impl Client { // use a state-proving closure for the given block. fn with_proving_caller(&self, id: BlockId, with_call: F) -> T - where F: FnOnce(&::machine::Call) -> T + where F: FnOnce(&MachineCall) -> T { let call = |a, d| { let tx = self.contract_call_tx(id, a, d); @@ -1151,10 +1162,10 @@ impl Client { ) -> Result<(), EthcoreError> { let db = self.state_db.read().journal_db().boxed_clone(); let best_block_number = self.chain_info().best_block_number; - let block_number = self.block_number(at).ok_or_else(|| snapshot::Error::InvalidStartingBlock(at))?; + let block_number = self.block_number(at).ok_or_else(|| SnapshotError::InvalidStartingBlock(at))?; if db.is_prunable() && self.pruning_info().earliest_state > block_number { - return Err(snapshot::Error::OldBlockPrunedDB.into()); + return Err(SnapshotError::OldBlockPrunedDB.into()); } let history = cmp::min(self.history, 1000); @@ -1168,17 +1179,17 @@ impl Client { match self.block_hash(BlockId::Number(start_num)) { Some(h) => h, - None => return Err(snapshot::Error::InvalidStartingBlock(at).into()), + None => return Err(SnapshotError::InvalidStartingBlock(at).into()), } } _ => match self.block_hash(at) { Some(hash) => hash, - None => return Err(snapshot::Error::InvalidStartingBlock(at).into()), + None => return Err(SnapshotError::InvalidStartingBlock(at).into()), }, }; let processing_threads = self.config.snapshot.processing_threads; - let chunker = self.engine.snapshot_components().ok_or_else(|| snapshot::Error::SnapshotsUnsupported)?; + let chunker = self.engine.snapshot_components().ok_or_else(|| SnapshotError::SnapshotsUnsupported)?; snapshot::take_snapshot( chunker, &self.chain.read(), diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index 1e2ee1e45..8d0419e2e 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -23,7 +23,12 @@ use {trie_vm_factories, journaldb, trie, kvdb_memorydb}; use kvdb::{self, KeyValueDB}; use {state_db, client, executive, trace, db, spec}; use pod::PodState; -use types::{log_entry, receipt, transaction}; +use types::{ + errors::EthcoreError, + log_entry, + receipt, + transaction +}; use trie_vm_factories::Factories; use evm::{VMType, FinalizationResult}; use vm::{self, ActionParams, CreateContractAddress}; @@ -41,12 +46,12 @@ pub enum EvmTestError { /// EVM error. Evm(vm::Error), /// Initialization error. - ClientError(::error::Error), + ClientError(EthcoreError), /// Post-condition failure, PostCondition(String), } -impl> From for EvmTestError { +impl> From for EvmTestError { fn from(err: E) -> Self { EvmTestError::ClientError(err.into()) } @@ -345,7 +350,7 @@ pub struct TransactErr { /// State root pub state_root: H256, /// Execution error - pub error: ::error::Error, + pub error: EthcoreError, /// end state if needed pub end_state: Option, } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 693fdad01..6b0ae3c81 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -36,10 +36,11 @@ use kvdb_memorydb; use parking_lot::RwLock; use rlp::{Rlp, RlpStream}; use rustc_hex::FromHex; -use types::transaction::{self, Transaction, LocalizedTransaction, SignedTransaction, Action}; +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; @@ -52,16 +53,15 @@ use vm::Schedule; use block::{OpenBlock, SealedBlock, ClosedBlock}; use call_contract::{CallContract, RegistryInfo}; use client::{ - Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, TransactionInfo, + 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 }; +use client::BlockInfo; use engines::Engine; -use error::{Error, EthcoreResult}; -use executed::CallError; use executive::Executed; use journaldb; use miner::{self, Miner, MinerService}; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 50fe75a69..69787efa9 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -25,32 +25,34 @@ use ethereum_types::{H256, U256, Address}; use evm::Schedule; use itertools::Itertools; use kvdb::DBValue; -use types::transaction::{self, LocalizedTransaction, SignedTransaction}; -use types::BlockNumber; -use types::basic_account::BasicAccount; -use types::block_status::BlockStatus; -use types::blockchain_info::BlockChainInfo; -use types::call_analytics::CallAnalytics; -use types::encoded; -use types::filter::Filter; -use types::header::Header; -use types::ids::*; -use types::log_entry::LocalizedLogEntry; -use types::pruning_info::PruningInfo; -use types::receipt::LocalizedReceipt; -use types::trace_filter::Filter as TraceFilter; +use types::{ + transaction::{self, LocalizedTransaction, SignedTransaction, CallError}, + BlockNumber, + 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 error::{Error, EthcoreResult}; -use executed::CallError; use executive::Executed; use account_state::state::StateInfo; use trace::LocalizedTrace; -use verification::queue::QueueInfo as BlockQueueInfo; -use verification::queue::kind::blocks::Unverified; +use verification::queue::kind::blocks::Unverified; // todo this is reexported from common_types /// State information to be used during client query pub enum StateOrBlock { diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 360ec0443..30df44eb4 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -26,12 +26,11 @@ use std::time::{UNIX_EPOCH, Duration}; use block::*; use client::EngineClient; -use engines::{Engine, Seal, SealingState, EngineError, ConstructedVerifier}; +use engines::{Engine, Seal, ConstructedVerifier}; use engines::block_reward; use engines::block_reward::{BlockRewardContract, RewardKind}; -use error::{Error, BlockError}; use ethjson; -use machine::{AuxiliaryData, Call, Machine}; +use machine::Machine; use hash::keccak; use super::signer::EngineSigner; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; @@ -43,9 +42,17 @@ use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp}; use ethereum_types::{H256, H520, Address, U128, U256}; use parking_lot::{Mutex, RwLock}; use time_utils::CheckedSystemTime; -use types::BlockNumber; -use types::header::{Header, ExtendedHeader}; -use types::ancestry_action::AncestryAction; +use types::{ + ancestry_action::AncestryAction, + BlockNumber, + header::{Header, ExtendedHeader}, + engines::{ + params::CommonParams, + SealingState, + machine::{Call, AuxiliaryData}, + }, + errors::{BlockError, EthcoreError as Error, EngineError}, +}; use unexpected::{Mismatch, OutOfBounds}; mod finality; @@ -270,7 +277,7 @@ impl EpochManager { .ok() .map(|(list, _)| { trace!(target: "engine", "Updating finality checker with new validator set extracted from epoch ({}, {}): {:?}", - last_transition.block_number, last_transition.block_hash, &list); + last_transition.block_number, last_transition.block_hash, &list); list.into_inner() }) @@ -536,7 +543,7 @@ fn header_step(header: &Header, empty_steps_transition: u64) -> Result Result { Rlp::new(&header.seal().get(1).unwrap_or_else(|| panic!("was checked with verify_block_basic; has {} fields; qed", - header_expected_seal_fields(header, empty_steps_transition)) + header_expected_seal_fields(header, empty_steps_transition)) )) .as_val::().map(Into::into) } @@ -815,7 +822,7 @@ impl AuthorityRound { if let (true, Some(me)) = (current_step > parent_step + 1, self.address()) { debug!(target: "engine", "Author {} built block with step gap. current step: {}, parent step: {}", - header.author(), current_step, parent_step); + header.author(), current_step, parent_step); let mut reported = HashSet::new(); for step in parent_step + 1..current_step { let skipped_primary = step_proposer(validators, header.parent_hash(), step); @@ -853,7 +860,7 @@ impl AuthorityRound { if epoch_manager.finality_checker.subchain_head() != Some(*chain_head.parent_hash()) { // build new finality checker from unfinalized ancestry of chain head, not including chain head itself yet. trace!(target: "finality", "Building finality up to parent of {} ({})", - chain_head.hash(), chain_head.parent_hash()); + chain_head.hash(), chain_head.parent_hash()); // the empty steps messages in a header signal approval of the // parent header. @@ -984,9 +991,9 @@ impl Engine for AuthorityRound { let empty_steps = if let Ok(empty_steps) = header_empty_steps(header).as_ref() { format!("[{}]", - empty_steps.iter().fold( - "".to_string(), - |acc, e| if acc.len() > 0 { acc + ","} else { acc } + &e.to_string())) + empty_steps.iter().fold( + "".to_string(), + |acc, e| if acc.len() > 0 { acc + ","} else { acc } + &e.to_string())) } else { "".into() @@ -1061,7 +1068,7 @@ impl Engine for AuthorityRound { if !is_step_proposer(&*validators, &parent.hash(), step, &our_addr) { trace!(target: "engine", "Not preparing block: not a proposer for step {}. (Our address: {})", - step, our_addr); + step, our_addr); return SealingState::NotReady; } @@ -1119,7 +1126,7 @@ impl Engine for AuthorityRound { if header.difficulty() != &expected_diff { debug!(target: "engine", "Aborting seal generation. The step or empty_steps have changed in the meantime. {:?} != {:?}", - header.difficulty(), expected_diff); + header.difficulty(), expected_diff); return Seal::None; } @@ -1297,7 +1304,7 @@ impl Engine for AuthorityRound { // likely ignore old reports // - This specific check is only relevant if you're importing (since it checks // against wall clock) - if let Ok((_, set_number)) = self.epoch_set(header) { + if let Ok((_, set_number)) = self.epoch_set(header) { trace!(target: "engine", "Reporting benign misbehaviour (cause: InvalidSeal) at block #{}, epoch set number {}. Own address: {}", header.number(), set_number, self.address().unwrap_or_default()); self.validators.report_benign(header.author(), set_number, header.number()); @@ -1420,9 +1427,7 @@ impl Engine for AuthorityRound { .map(|set_proof| combine_proofs(0, &set_proof, &[])) } - fn signals_epoch_end(&self, header: &Header, aux: AuxiliaryData) - -> super::EpochChange - { + fn signals_epoch_end(&self, header: &Header, aux: AuxiliaryData) -> super::EpochChange { if self.immediate_transitions { return super::EpochChange::No } let first = header.number() == 0; @@ -1604,6 +1609,10 @@ impl Engine for AuthorityRound { finalized.into_iter().map(AncestryAction::MarkFinalized).collect() } + + fn params(&self) -> &CommonParams { + self.machine.params() + } } #[cfg(test)] @@ -1615,7 +1624,12 @@ mod tests { use accounts::AccountProvider; use ethereum_types::{Address, H520, H256, U256}; use ethkey::Signature; - use types::header::Header; + use types::{ + header::Header, + engines::params::CommonParams, + errors::{EthcoreError as Error, EngineError}, + transaction::{Action, Transaction}, + }; use rlp::encode; use block::*; use test_helpers::{ @@ -1623,10 +1637,8 @@ mod tests { TestNotify }; use spec::Spec; - use types::transaction::{Action, Transaction}; - use engines::{Seal, Engine, EngineError}; + use engines::{Seal, Engine}; use engines::validator_set::{TestSet, SimpleList}; - use error::Error; use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score}; use machine::Machine; @@ -1653,7 +1665,7 @@ mod tests { // mutate aura params f(&mut params); // create engine - let mut c_params = ::spec::CommonParams::default(); + let mut c_params = CommonParams::default(); c_params.gas_limit_bound_divisor = 5.into(); let machine = Machine::regular(c_params, Default::default()); AuthorityRound::new(params, machine).unwrap() diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 8232c0ff2..d5247da34 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -21,13 +21,21 @@ use ethereum_types::{H256, H520}; use parking_lot::RwLock; use ethkey::{self, Signature}; use block::*; -use engines::{Engine, Seal, SealingState, ConstructedVerifier, EngineError}; +use engines::{Engine, Seal, ConstructedVerifier}; use engines::signer::EngineSigner; -use error::{BlockError, Error}; use ethjson; use client::EngineClient; -use machine::{AuxiliaryData, Call, Machine}; -use types::header::Header; +use machine::Machine; +use types::{ + header::Header, + engines::{ + SealingState, + params::CommonParams, + machine::{AuxiliaryData, Call}, + }, + errors::{EngineError, BlockError, EthcoreError as Error}, +}; + use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; /// `BasicAuthority` params. @@ -134,17 +142,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) -> super::EpochChange { // don't bother signalling even though a contract might try. super::EpochChange::No } #[cfg(test)] - fn signals_epoch_end(&self, header: &Header, auxiliary: AuxiliaryData) - -> super::EpochChange - { + fn signals_epoch_end(&self, header: &Header, auxiliary: AuxiliaryData) -> super::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) @@ -208,6 +212,10 @@ impl Engine for BasicAuthority { fn snapshot_components(&self) -> Option> { None } + + fn params(&self) -> &CommonParams { + self.machine.params() + } } #[cfg(test)] diff --git a/ethcore/src/engines/block_reward.rs b/ethcore/src/engines/block_reward.rs index c7266368d..908fc9ceb 100644 --- a/ethcore/src/engines/block_reward.rs +++ b/ethcore/src/engines/block_reward.rs @@ -23,10 +23,12 @@ use ethereum_types::{H160, Address, U256}; use std::sync::Arc; use hash::keccak; -use error::Error; use machine::Machine; use trace; -use types::BlockNumber; +use types::{ + BlockNumber, + errors::{EngineError, EthcoreError as Error}, +}; use super::{SystemOrCodeCall, SystemOrCodeCallKind}; use trace::{Tracer, ExecutiveTracer, Tracing}; use block::ExecutedBlock; @@ -120,7 +122,7 @@ impl BlockRewardContract { let output = caller(self.kind.clone(), input) .map_err(Into::into) - .map_err(::engines::EngineError::FailedSystemCall)?; + .map_err(EngineError::FailedSystemCall)?; // since this is a non-constant call we can't use ethabi's function output // deserialization, sadness ensues. @@ -131,7 +133,7 @@ impl BlockRewardContract { let tokens = ethabi::decode(types, &output) .map_err(|err| err.to_string()) - .map_err(::engines::EngineError::FailedSystemCall)?; + .map_err(EngineError::FailedSystemCall)?; assert!(tokens.len() == 2); @@ -139,7 +141,7 @@ impl BlockRewardContract { let rewards = tokens[1].clone().to_array().expect("type checked by ethabi::decode; qed"); if addresses.len() != rewards.len() { - return Err(::engines::EngineError::FailedSystemCall( + return Err(EngineError::FailedSystemCall( "invalid data returned by reward contract: both arrays must have the same size".into() ).into()); } diff --git a/ethcore/src/engines/clique/block_state.rs b/ethcore/src/engines/clique/block_state.rs index 913053eaa..787dd53dc 100644 --- a/ethcore/src/engines/clique/block_state.rs +++ b/ethcore/src/engines/clique/block_state.rs @@ -18,15 +18,16 @@ use std::collections::{HashMap, BTreeSet, VecDeque}; use std::fmt; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use engines::EngineError; use engines::clique::util::{extract_signers, recover_creator}; use engines::clique::{VoteType, DIFF_INTURN, DIFF_NOTURN, NULL_AUTHOR, SIGNING_DELAY_NOTURN_MS}; -use error::{Error, BlockError}; use ethereum_types::{Address, H64}; use rand::Rng; use time_utils::CheckedSystemTime; -use types::BlockNumber; -use types::header::Header; +use types::{ + BlockNumber, + header::Header, + errors::{BlockError, EthcoreError as Error, EngineError}, +}; use unexpected::Mismatch; /// Type that keeps track of the state for a given vote @@ -90,7 +91,7 @@ pub struct CliqueBlockState { } impl fmt::Display for CliqueBlockState { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let signers: Vec = self.signers.iter() .map(|s| format!("{} {:?}", @@ -107,11 +108,11 @@ impl fmt::Display for CliqueBlockState { let rm_votes = self.votes_history.iter().filter(|v| v.kind == VoteType::Remove).count(); let reverted_votes = self.votes_history.iter().filter(|v| v.reverted).count(); - write!(f, + write!(f, "Votes {{ \n signers: {:?} \n recent_signers: {:?} \n number of votes: {} \n number of add votes {} \r number of remove votes {} \n number of reverted votes: {}}}", signers, recent_signers, num_votes, add_votes, rm_votes, reverted_votes) - } + } } impl CliqueBlockState { diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index 3674c5c8d..84d45a284 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -68,22 +68,27 @@ 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, EngineError, Seal, SealingState}; -use error::{BlockError, Error}; +use engines::{Engine, Seal, SealingState, EthashSeal}; use ethereum_types::{Address, H64, H160, H256, U256}; use ethkey::Signature; use hash::KECCAK_EMPTY_LIST_RLP; use itertools::Itertools; use lru_cache::LruCache; -use machine::{Call, Machine}; +use machine::Machine; use parking_lot::RwLock; use rand::Rng; use super::signer::EngineSigner; use unexpected::{Mismatch, OutOfBounds}; use time_utils::CheckedSystemTime; -use types::BlockNumber; -use types::header::Header; -use ethereum::ethash; +use types::{ + BlockNumber, + header::Header, + engines::{ + params::CommonParams, + machine::Call, + }, + errors::{BlockError, EthcoreError as Error, EngineError}, +}; use self::block_state::CliqueBlockState; use self::params::CliqueParams; @@ -255,8 +260,7 @@ impl Clique { fn new_checkpoint_state(&self, header: &Header) -> Result { debug_assert_eq!(header.number() % self.epoch_length, 0); - let mut state = CliqueBlockState::new( - extract_signers(header)?); + let mut state = CliqueBlockState::new(extract_signers(header)?); // TODO(niklasad1): refactor to perform this check in the `CliqueBlockState` constructor instead state.calc_next_timestamp(header.timestamp(), self.period)?; @@ -364,7 +368,7 @@ impl Engine for Clique { fn extra_info(&self, header: &Header) -> BTreeMap { // clique engine seal fields are the same as ethash seal fields - match ethash::Seal::parse_seal(header.seal()) { + match EthashSeal::parse_seal(header.seal()) { Ok(seal) => map![ "nonce".to_owned() => format!("{:#x}", seal.nonce), "mixHash".to_owned() => format!("{:#x}", seal.mix_hash) @@ -499,7 +503,7 @@ impl Engine for Clique { match self.state(&parent) { Err(e) => { warn!(target: "engine", "generate_seal: can't get parent state(number: {}, hash: {}): {} ", - parent.number(), parent.hash(), e); + parent.number(), parent.hash(), e); return Seal::None; } Ok(state) => { @@ -522,9 +526,8 @@ impl Engine for Clique { // Wait for the right moment. if now < limit { - trace!(target: "engine", - "generate_seal: sleeping to sign: inturn: {}, now: {:?}, to: {:?}.", - inturn, now, limit); + trace!(target: "engine", "generate_seal: sleeping to sign: inturn: {}, now: {:?}, to: {:?}.", + inturn, now, limit); match limit.duration_since(SystemTime::now()) { Ok(duration) => { thread::sleep(duration); @@ -537,7 +540,7 @@ impl Engine for Clique { } trace!(target: "engine", "generate_seal: seal ready for block {}, txs: {}.", - block.header.number(), block.transactions.len()); + block.header.number(), block.transactions.len()); return Seal::Regular(null_seal); } } @@ -560,7 +563,7 @@ impl Engine for Clique { let limit = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_secs(self.period)) .ok_or(BlockError::TimestampOverflow)?; - // This should succeed under the contraints that the system clock works + // This should succeed under the constraints that the system clock works let limit_as_dur = limit.duration_since(UNIX_EPOCH).map_err(|e| { Box::new(format!("Converting SystemTime to Duration failed: {}", e)) })?; @@ -721,7 +724,7 @@ impl Engine for Clique { // it's just to ignore setting a correct difficulty here, we will check authorization in next step in generate_seal anyway. if let Some(signer) = self.signer.read().as_ref() { let state = match self.state(&parent) { - Err(e) => { + Err(e) => { trace!(target: "engine", "populate_from_parent: Unable to find parent state: {}, ignored.", e); return; } @@ -782,4 +785,8 @@ impl Engine for Clique { fn executive_author(&self, header: &Header) -> Result { recover_creator(header) } + + fn params(&self) -> &CommonParams { + self.machine.params() + } } diff --git a/ethcore/src/engines/clique/tests.rs b/ethcore/src/engines/clique/tests.rs index 97e218a05..46e9506f1 100644 --- a/ethcore/src/engines/clique/tests.rs +++ b/ethcore/src/engines/clique/tests.rs @@ -18,12 +18,12 @@ use block::*; use engines::Engine; -use error::Error; use ethereum_types::{Address, H256}; use ethkey::{Secret, KeyPair}; use state_db::StateDB; use super::*; use test_helpers::get_temp_state_db; +use types::errors::{EthcoreError as Error, EngineError}; use std::sync::Arc; use std::collections::HashMap; diff --git a/ethcore/src/engines/clique/util.rs b/ethcore/src/engines/clique/util.rs index 79b74bb73..afa0a73bf 100644 --- a/ethcore/src/engines/clique/util.rs +++ b/ethcore/src/engines/clique/util.rs @@ -16,15 +16,16 @@ use std::collections::BTreeSet; -use engines::EngineError; use engines::clique::{ADDRESS_LENGTH, SIGNATURE_LENGTH, VANITY_LENGTH, NULL_NONCE, NULL_MIXHASH}; -use error::Error; use ethereum_types::{Address, H256}; use ethkey::{public_to_address, recover as ec_recover, Signature}; use lru_cache::LruCache; use parking_lot::RwLock; use rlp::encode; -use types::header::Header; +use types::{ + header::Header, + errors::{EthcoreError as Error, EngineError}, +}; /// How many recovered signature to cache in the memory. pub const CREATOR_CACHE_NUM: usize = 4096; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/engines/ethash.rs similarity index 97% rename from ethcore/src/ethereum/ethash.rs rename to ethcore/src/engines/ethash.rs index 91964a11e..d25bed59b 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/engines/ethash.rs @@ -23,19 +23,23 @@ use ethereum_types::{H256, H64, U256}; use ethjson; use hash::{KECCAK_EMPTY_LIST_RLP}; use rlp::Rlp; -use types::header::Header; -use types::BlockNumber; +use types::{ + BlockNumber, + header::Header, + engines::params::CommonParams, + errors::{BlockError, EthcoreError as Error}, +}; + use unexpected::{OutOfBounds, Mismatch}; use block::ExecutedBlock; use engines::block_reward::{self, BlockRewardContract, RewardKind}; use engines::{self, Engine}; -use error::{BlockError, Error}; use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor}; use machine::Machine; /// Number of blocks in an ethash snapshot. -// make dependent on difficulty incrment divisor? +// make dependent on difficulty increment divisor? const SNAPSHOT_BLOCKS: u64 = 5000; /// Maximum number of blocks allowed in an ethash snapshot. const MAX_SNAPSHOT_BLOCKS: u64 = 30000; @@ -203,10 +207,13 @@ impl Ethash { // 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()`. impl engines::EpochVerifier for Arc { fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } fn verify_heavy(&self, header: &Header) -> Result<(), Error> { - self.verify_block_unordered(header) + self.verify_block_unordered(header).into() } } @@ -343,12 +350,12 @@ impl Engine for Arc { 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)); + 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 }))); } @@ -380,6 +387,8 @@ impl Engine for Arc { fn snapshot_components(&self) -> Option> { Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS))) } + + fn params(&self) -> &CommonParams { self.machine.params() } } impl Ethash { @@ -486,11 +495,13 @@ mod tests { use ethereum_types::{H64, H256, U256, Address}; use block::*; use test_helpers::get_temp_state_db; - use error::{BlockError, Error}; - use types::header::Header; + use types::{ + header::Header, + errors::{BlockError, EthcoreError as Error}, + }; use spec::Spec; use engines::Engine; - use super::super::{new_morden, new_mcip3_test, new_homestead_test_machine}; + use ethereum::{new_morden, new_mcip3_test, 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 125a4edc2..51dd8ff3c 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -14,11 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use engines::{Engine, Seal, SealingState}; +use engines::{Engine, Seal}; use machine::Machine; -use types::header::Header; +use types::{ + header::Header, + engines::{ + SealingState, + params::CommonParams, + }, + errors::EthcoreError as Error, +}; + use block::ExecutedBlock; -use error::Error; /// `InstantSeal` params. #[derive(Default, Debug, PartialEq)] @@ -87,8 +94,14 @@ impl Engine for InstantSeal { fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { header_timestamp >= parent_timestamp } + + fn params(&self) -> &CommonParams { + self.machine.params() + } + } + #[cfg(test)] mod tests { use std::sync::Arc; diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 91aaed567..a3fc70465 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -19,6 +19,7 @@ mod authority_round; mod basic_authority; mod clique; +mod ethash; mod instant_seal; mod null_engine; mod validator_set; @@ -32,6 +33,7 @@ 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}; // TODO [ToDr] Remove re-export (#10130) pub use types::engines::ForkChoice; @@ -39,120 +41,31 @@ pub use types::engines::epoch::{self, Transition as EpochTransition}; use std::sync::{Weak, Arc}; use std::collections::BTreeMap; -use std::{fmt, error}; use builtin::Builtin; use vm::{EnvInfo, Schedule, CallType, ActionValue}; -use error::Error; -use types::BlockNumber; -use types::header::{Header, ExtendedHeader}; +use types::{ + BlockNumber, + ancestry_action::AncestryAction, + header::{Header, ExtendedHeader}, + engines::{ + SealingState, Headers, PendingTransitionStore, + params::CommonParams, + machine as machine_types, + machine::{AuxiliaryData, AuxiliaryRequest}, + }, + errors::{EthcoreError as Error, EngineError}, + transaction::{self, UnverifiedTransaction, SignedTransaction}, +}; use snapshot::SnapshotComponents; -use spec::CommonParams; -use types::transaction::{self, UnverifiedTransaction, SignedTransaction}; use client::EngineClient; use ethkey::{Signature}; -use machine::{self, Machine, AuxiliaryRequest, AuxiliaryData}; -use ethereum_types::{H64, H256, U256, Address}; -use unexpected::{Mismatch, OutOfBounds}; +use machine::Machine; +use ethereum_types::{H256, U256, Address}; use bytes::Bytes; -use types::ancestry_action::AncestryAction; use block::ExecutedBlock; -/// Default EIP-210 contract code. -/// As defined in https://github.com/ethereum/EIPs/pull/210 -pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b"; -/// The number of generations back that uncles can be. -pub const MAX_UNCLE_AGE: usize = 6; - -/// Voting errors. -#[derive(Debug)] -pub enum EngineError { - /// Signature or author field does not belong to an authority. - NotAuthorized(Address), - /// The same author issued different votes at the same step. - DoubleVote(Address), - /// The received block is from an incorrect proposer. - NotProposer(Mismatch
), - /// Message was not expected. - UnexpectedMessage, - /// Seal field has an unexpected size. - BadSealFieldSize(OutOfBounds), - /// Validation proof insufficient. - InsufficientProof(String), - /// Failed system call. - FailedSystemCall(String), - /// Malformed consensus message. - MalformedMessage(String), - /// Requires client ref, but none registered. - RequiresClient, - /// Invalid engine specification or implementation. - InvalidEngine, - /// Requires signer ref, but none registered. - RequiresSigner, - /// Missing Parent Epoch - MissingParent(H256), - /// Checkpoint is missing - CliqueMissingCheckpoint(H256), - /// Missing vanity data - CliqueMissingVanity, - /// Missing signature - CliqueMissingSignature, - /// Missing signers - CliqueCheckpointNoSigner, - /// List of signers is invalid - CliqueCheckpointInvalidSigners(usize), - /// Wrong author on a checkpoint - CliqueWrongAuthorCheckpoint(Mismatch
), - /// Wrong checkpoint authors recovered - CliqueFaultyRecoveredSigners(Vec), - /// Invalid nonce (should contain vote) - CliqueInvalidNonce(H64), - /// The signer signed a block to recently - CliqueTooRecentlySigned(Address), - /// Custom - Custom(String), -} - -impl fmt::Display for EngineError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::EngineError::*; - let msg = match *self { - CliqueMissingCheckpoint(ref hash) => format!("Missing checkpoint block: {}", hash), - CliqueMissingVanity => format!("Extra data is missing vanity data"), - CliqueMissingSignature => format!("Extra data is missing signature"), - CliqueCheckpointInvalidSigners(len) => format!("Checkpoint block list was of length: {} of checkpoint but - it needs to be bigger than zero and a divisible by 20", len), - CliqueCheckpointNoSigner => format!("Checkpoint block list of signers was empty"), - CliqueInvalidNonce(ref mis) => format!("Unexpected nonce {} expected {} or {}", mis, 0_u64, u64::max_value()), - CliqueWrongAuthorCheckpoint(ref oob) => format!("Unexpected checkpoint author: {}", oob), - CliqueFaultyRecoveredSigners(ref mis) => format!("Faulty recovered signers {:?}", mis), - CliqueTooRecentlySigned(ref address) => format!("The signer: {} has signed a block too recently", address), - Custom(ref s) => s.clone(), - DoubleVote(ref address) => format!("Author {} issued too many blocks.", address), - NotProposer(ref mis) => format!("Author is not a current proposer: {}", mis), - NotAuthorized(ref address) => format!("Signer {} is not authorized.", address), - UnexpectedMessage => "This Engine should not be fed messages.".into(), - BadSealFieldSize(ref oob) => format!("Seal field has an unexpected length: {}", oob), - InsufficientProof(ref msg) => format!("Insufficient validation proof: {}", msg), - FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg), - MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg), - RequiresClient => format!("Call requires client but none registered"), - RequiresSigner => format!("Call requires signer but none registered"), - InvalidEngine => format!("Invalid engine specification or implementation"), - MissingParent(ref hash) => format!("Parent Epoch is missing from database: {}", hash), - }; - - f.write_fmt(format_args!("Engine error ({})", msg)) - } -} - -impl error::Error for EngineError { - fn description(&self) -> &str { - "Engine error" - } -} - /// Seal type. #[derive(Debug, PartialEq, Eq)] pub enum Seal { @@ -162,17 +75,6 @@ pub enum Seal { None, } -/// The type of sealing the engine is currently able to perform. -#[derive(Debug, PartialEq, Eq)] -pub enum SealingState { - /// The engine is ready to seal a block. - Ready, - /// The engine can't seal at the moment, and no block should be prepared and queued. - NotReady, - /// The engine does not seal internally. - External, -} - /// 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; @@ -189,7 +91,7 @@ pub enum SystemOrCodeCallKind { } /// Default SystemOrCodeCall implementation. -pub fn default_system_or_code_call<'a>(machine: &'a ::machine::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 ::block::ExecutedBlock) -> impl FnMut(SystemOrCodeCallKind, Vec) -> Result, String> + 'a { move |to, data| { let result = match to { SystemOrCodeCallKind::Address(address) => { @@ -218,16 +120,10 @@ pub fn default_system_or_code_call<'a>(machine: &'a ::machine::Machine, block: & } } -/// Type alias for a function we can get headers by hash through. -pub type Headers<'a, H> = dyn Fn(H256) -> Option + 'a; - -/// Type alias for a function we can query pending transitions by block hash through. -pub type PendingTransitionStore<'a> = dyn Fn(H256) -> Option + 'a; - /// Proof dependent on state. pub trait StateDependentProof: Send + Sync { /// Generate a proof, given the state. - fn generate_proof<'a>(&self, state: &machine::Call) -> Result, String>; + 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. @@ -360,7 +256,7 @@ pub trait Engine: Sync + Send { fn verify_block_external(&self, _header: &Header) -> Result<(), Error> { Ok(()) } /// Genesis epoch data. - fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine::Call) -> Result, String> { Ok(Vec::new()) } + 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 @@ -371,9 +267,7 @@ pub trait Engine: Sync + Send { /// 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 - { + fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange { EpochChange::No } @@ -475,9 +369,7 @@ pub trait Engine: Sync + Send { } /// Get the general parameters of the chain. - fn params(&self) -> &CommonParams { - self.machine().params() - } + fn params(&self) -> &CommonParams; /// Get the EVM schedule for the given block number. fn schedule(&self, block_number: BlockNumber) -> Schedule { @@ -496,9 +388,7 @@ pub trait Engine: Sync + Send { } /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. - fn maximum_extra_data_size(&self) -> usize { - self.machine().maximum_extra_data_size() - } + 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 { diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index 2d81e4400..c62c64681 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -18,10 +18,13 @@ use engines::Engine; use engines::block_reward::{self, RewardKind}; use ethereum_types::U256; use machine::Machine; -use types::BlockNumber; -use types::header::Header; +use types::{ + BlockNumber, + header::Header, + engines::params::CommonParams, + errors::EthcoreError as Error, +}; use block::ExecutedBlock; -use error::Error; /// Params for a null engine. #[derive(Clone, Default)] @@ -61,6 +64,8 @@ impl Engine for NullEngine { fn machine(&self) -> &Machine { &self.machine } + fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 } + fn on_close_block( &self, block: &mut ExecutedBlock, @@ -92,8 +97,6 @@ impl Engine for NullEngine { block_reward::apply_block_rewards(&rewards, block, &self.machine) } - fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 } - fn verify_local_seal(&self, _header: &Header) -> Result<(), Error> { Ok(()) } @@ -101,4 +104,8 @@ impl Engine for NullEngine { fn snapshot_components(&self) -> Option> { Some(Box::new(::snapshot::PowSnapshot::new(10000, 10000))) } + + fn params(&self) -> &CommonParams { + self.machine.params() + } } diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 5b695525d..ca3f3cd3d 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -21,10 +21,14 @@ use std::sync::Weak; use bytes::Bytes; use ethereum_types::{H256, Address}; -use machine::{AuxiliaryData, Call, Machine}; +use machine::Machine; use parking_lot::RwLock; -use types::BlockNumber; -use types::header::Header; +use types::{ + BlockNumber, + header::Header, + errors::EthcoreError, + engines::machine::{Call, AuxiliaryData}, +}; use client::EngineClient; @@ -72,7 +76,7 @@ impl ValidatorSet for ValidatorContract { self.validators.default_caller(id) } - fn on_epoch_begin(&self, first: bool, header: &Header, call: &mut SystemCall) -> Result<(), ::error::Error> { + fn on_epoch_begin(&self, first: bool, header: &Header, call: &mut SystemCall) -> Result<(), EthcoreError> { self.validators.on_epoch_begin(first, header, call) } @@ -93,7 +97,7 @@ impl ValidatorSet for ValidatorContract { self.validators.signals_epoch_end(first, header, aux) } - fn epoch_set(&self, first: bool, machine: &Machine, number: BlockNumber, proof: &[u8]) -> Result<(SimpleList, Option), ::error::Error> { + fn epoch_set(&self, first: bool, machine: &Machine, number: BlockNumber, proof: &[u8]) -> Result<(SimpleList, Option), EthcoreError> { self.validators.epoch_set(first, machine, number, proof) } @@ -147,7 +151,8 @@ mod tests { use types::ids::BlockId; use test_helpers::generate_dummy_client_with_spec; use call_contract::CallContract; - use client::{BlockChainClient, ChainInfo, BlockInfo}; + use client::{BlockChainClient, ChainInfo}; + use client::BlockInfo; use super::super::ValidatorSet; use super::ValidatorContract; diff --git a/ethcore/src/engines/validator_set/mod.rs b/ethcore/src/engines/validator_set/mod.rs index 865c45484..3a7255427 100644 --- a/ethcore/src/engines/validator_set/mod.rs +++ b/ethcore/src/engines/validator_set/mod.rs @@ -28,10 +28,14 @@ use std::sync::Weak; use bytes::Bytes; use ethereum_types::{H256, Address}; use ethjson::spec::ValidatorSet as ValidatorSpec; -use machine::{AuxiliaryData, Call, Machine}; -use types::BlockNumber; -use types::header::Header; -use types::ids::BlockId; +use machine::Machine; +use types::{ + BlockNumber, + header::Header, + ids::BlockId, + errors::EthcoreError, + engines::machine::{Call, AuxiliaryData}, +}; use client::EngineClient; @@ -88,7 +92,7 @@ pub trait ValidatorSet: Send + Sync + 'static { /// The caller provided here may not generate proofs. /// /// `first` is true if this is the first block in the set. - fn on_epoch_begin(&self, _first: bool, _header: &Header, _call: &mut SystemCall) -> Result<(), ::error::Error> { + fn on_epoch_begin(&self, _first: bool, _header: &Header, _call: &mut SystemCall) -> Result<(), EthcoreError> { Ok(()) } @@ -124,7 +128,7 @@ pub trait ValidatorSet: Send + Sync + 'static { /// Returns the set, along with a flag indicating whether finality of a specific /// hash should be proven. fn epoch_set(&self, first: bool, machine: &Machine, number: BlockNumber, proof: &[u8]) - -> Result<(SimpleList, Option), ::error::Error>; + -> Result<(SimpleList, Option), EthcoreError>; /// Checks if a given address is a validator, with the given function /// for executing synchronous calls to contracts. diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 0f6dd41af..d43edf10f 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -22,12 +22,16 @@ use std::sync::Weak; use bytes::Bytes; use ethereum_types::{H256, Address}; use parking_lot::RwLock; -use types::BlockNumber; -use types::header::Header; -use types::ids::BlockId; +use types::{ + BlockNumber, + header::Header, + ids::BlockId, + errors::EthcoreError, + engines::machine::{Call, AuxiliaryData}, +}; use client::EngineClient; -use machine::{AuxiliaryData, Call, Machine}; +use machine::Machine; use super::{SystemCall, ValidatorSet}; type BlockNumberLookup = Box Result + Send + Sync + 'static>; @@ -77,7 +81,7 @@ impl ValidatorSet for Multi { .unwrap_or_else(|| Box::new(|_, _| Err("No validator set for given ID.".into()))) } - fn on_epoch_begin(&self, _first: bool, header: &Header, call: &mut SystemCall) -> Result<(), ::error::Error> { + fn on_epoch_begin(&self, _first: bool, header: &Header, call: &mut SystemCall) -> Result<(), EthcoreError> { let (set_block, set) = self.correct_set_by_number(header.number()); let first = set_block == header.number(); @@ -104,7 +108,7 @@ impl ValidatorSet for Multi { set.signals_epoch_end(first, header, aux) } - fn epoch_set(&self, _first: bool, machine: &Machine, number: BlockNumber, proof: &[u8]) -> Result<(super::SimpleList, Option), ::error::Error> { + fn epoch_set(&self, _first: bool, machine: &Machine, number: BlockNumber, proof: &[u8]) -> Result<(super::SimpleList, Option), EthcoreError> { let (set_block, set) = self.correct_set_by_number(number); let first = set_block == number; @@ -151,7 +155,8 @@ mod tests { use std::collections::BTreeMap; use hash::keccak; use accounts::AccountProvider; - use client::{BlockChainClient, ChainInfo, BlockInfo, ImportBlock}; + use client::{BlockChainClient, ChainInfo, ImportBlock}; + use client::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 50ee598dc..cc2aafc4c 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -26,14 +26,18 @@ use kvdb::DBValue; use memory_cache::MemoryLruCache; use parking_lot::RwLock; use rlp::{Rlp, RlpStream}; -use types::header::Header; -use types::ids::BlockId; -use types::log_entry::LogEntry; -use types::receipt::Receipt; +use types::{ + header::Header, + errors::{EngineError, EthcoreError, BlockError}, + ids::BlockId, + log_entry::LogEntry, + engines::machine::{Call, AuxiliaryData, AuxiliaryRequest}, + receipt::Receipt, +}; use unexpected::Mismatch; use client::EngineClient; -use machine::{AuxiliaryData, Call, Machine, AuxiliaryRequest}; +use machine::Machine; use super::{SystemCall, ValidatorSet}; use super::simple_list::SimpleList; @@ -144,13 +148,13 @@ fn check_first_proof(machine: &Machine, contract_address: Address, old_header: H } } -fn decode_first_proof(rlp: &Rlp) -> Result<(Header, Vec), ::error::Error> { +fn decode_first_proof(rlp: &Rlp) -> Result<(Header, Vec), EthcoreError> { let header = rlp.val_at(0)?; let state_items = rlp.at(1)?.iter().map(|x| { let mut val = DBValue::new(); val.append_slice(x.data()?); Ok(val) - }).collect::>()?; + }).collect::>()?; Ok((header, state_items)) } @@ -164,7 +168,7 @@ fn encode_proof(header: &Header, receipts: &[Receipt]) -> Bytes { stream.drain() } -fn decode_proof(rlp: &Rlp) -> Result<(Header, Vec), ::error::Error> { +fn decode_proof(rlp: &Rlp) -> Result<(Header, Vec), EthcoreError> { Ok((rlp.val_at(0)?, rlp.list_at(1)?)) } @@ -293,11 +297,11 @@ impl ValidatorSet for ValidatorSafeContract { .map(|out| (out, Vec::new()))) // generate no proofs in general } - fn on_epoch_begin(&self, _first: bool, _header: &Header, caller: &mut SystemCall) -> Result<(), ::error::Error> { + fn on_epoch_begin(&self, _first: bool, _header: &Header, caller: &mut SystemCall) -> Result<(), EthcoreError> { let data = validator_set::functions::finalize_change::encode_input(); caller(self.contract_address, data) .map(|_| ()) - .map_err(::engines::EngineError::FailedSystemCall) + .map_err(EngineError::FailedSystemCall) .map_err(Into::into) } @@ -348,7 +352,7 @@ impl ValidatorSet for ValidatorSafeContract { } fn epoch_set(&self, first: bool, machine: &Machine, _number: ::types::BlockNumber, proof: &[u8]) - -> Result<(SimpleList, Option), ::error::Error> + -> Result<(SimpleList, Option), EthcoreError> { let rlp = Rlp::new(proof); @@ -359,7 +363,7 @@ impl ValidatorSet for ValidatorSafeContract { let number = old_header.number(); let old_hash = old_header.hash(); let addresses = check_first_proof(machine, self.contract_address, old_header, &state_items) - .map_err(::engines::EngineError::InsufficientProof)?; + .map_err(EngineError::InsufficientProof)?; trace!(target: "engine", "Extracted epoch validator set at block #{}: {} addresses", number, addresses.len()); @@ -374,7 +378,7 @@ impl ValidatorSet for ValidatorSafeContract { receipts.iter().map(::rlp::encode) ); if found_root != *old_header.receipts_root() { - return Err(::error::BlockError::InvalidReceiptsRoot( + return Err(BlockError::InvalidReceiptsRoot( Mismatch { expected: *old_header.receipts_root(), found: found_root } ).into()); } @@ -387,7 +391,7 @@ impl ValidatorSet for ValidatorSafeContract { Ok((list, Some(old_header.hash()))) }, - None => Err(::engines::EngineError::InsufficientProof("No log event in proof.".into()).into()), + None => Err(EngineError::InsufficientProof("No log event in proof.".into()).into()), } } } @@ -453,7 +457,8 @@ mod tests { use spec::Spec; use accounts::AccountProvider; use types::transaction::{Transaction, Action}; - use client::{ChainInfo, BlockInfo, ImportBlock}; + use client::{ChainInfo, ImportBlock}; + use client::BlockInfo; use ethkey::Secret; use miner::{self, MinerService}; use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data}; @@ -545,9 +550,11 @@ mod tests { #[test] fn detects_bloom() { use engines::EpochChange; - use machine::AuxiliaryRequest; - use types::header::Header; - use types::log_entry::LogEntry; + 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(); diff --git a/ethcore/src/engines/validator_set/simple_list.rs b/ethcore/src/engines/validator_set/simple_list.rs index 613b10880..5ec08b286 100644 --- a/ethcore/src/engines/validator_set/simple_list.rs +++ b/ethcore/src/engines/validator_set/simple_list.rs @@ -19,9 +19,13 @@ use parity_util_mem::MallocSizeOf; use ethereum_types::{H256, Address}; -use machine::{AuxiliaryData, Call, Machine}; -use types::BlockNumber; -use types::header::Header; +use machine::Machine; +use types::{ + BlockNumber, + header::Header, + errors::EthcoreError, + engines::machine::{Call, AuxiliaryData}, +}; use super::ValidatorSet; /// Validator set containing a known set of addresses. @@ -78,7 +82,7 @@ impl ValidatorSet for SimpleList { ::engines::EpochChange::No } - fn epoch_set(&self, _first: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option), ::error::Error> { + fn epoch_set(&self, _first: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option), EthcoreError> { Ok((self.clone(), None)) } diff --git a/ethcore/src/engines/validator_set/test.rs b/ethcore/src/engines/validator_set/test.rs index 04e695ef4..7abb294bc 100644 --- a/ethcore/src/engines/validator_set/test.rs +++ b/ethcore/src/engines/validator_set/test.rs @@ -23,10 +23,14 @@ use parity_util_mem::MallocSizeOf; use bytes::Bytes; use ethereum_types::{H256, Address}; -use types::BlockNumber; -use types::header::Header; +use types::{ + BlockNumber, + header::Header, + errors::EthcoreError, + engines::machine::{Call, AuxiliaryData}, +}; -use machine::{AuxiliaryData, Call, Machine}; +use machine::Machine; use super::{ValidatorSet, SimpleList}; /// Set used for testing with a single validator. @@ -72,7 +76,7 @@ impl ValidatorSet for TestSet { ::engines::EpochChange::No } - fn epoch_set(&self, _: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option), ::error::Error> { + fn epoch_set(&self, _: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option), EthcoreError> { Ok((self.validator.clone(), None)) } diff --git a/ethcore/src/ethereum/denominations.rs b/ethcore/src/ethereum/denominations.rs deleted file mode 100644 index 3bf4878c7..000000000 --- a/ethcore/src/ethereum/denominations.rs +++ /dev/null @@ -1,37 +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 . - -use ethereum_types::U256; - -#[inline] -/// 1 Ether in Wei -pub fn ether() -> U256 { U256::exp10(18) } - -#[inline] -/// 1 Finney in Wei -pub fn finney() -> U256 { U256::exp10(15) } - -#[inline] -/// 1 Szabo in Wei -pub fn szabo() -> U256 { U256::exp10(12) } - -#[inline] -/// 1 Shannon in Wei -pub fn shannon() -> U256 { U256::exp10(9) } - -#[inline] -/// 1 Wei in Wei -pub fn wei() -> U256 { U256::exp10(0) } diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index af2114a1b..5b9806670 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -19,14 +19,6 @@ //! Contains all Ethereum network specific stuff, such as denominations and //! consensus specifications. -/// Export the ethash module. -pub mod ethash; -/// Export the denominations module. -pub mod denominations; - -pub use self::ethash::{Ethash}; -pub use self::denominations::*; - use machine::Machine; use super::spec::*; diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index 10e06fd05..6b503942c 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -16,15 +16,15 @@ //! Transaction execution format module. -use ethereum_types::{U256, U512, Address}; +use ethereum_types::{U256, Address}; use bytes::Bytes; -use ethtrie; use vm; use trace::{VMTrace, FlatTrace}; -use types::state_diff::StateDiff; -use types::log_entry::LogEntry; - -use std::{fmt, error}; +use types::{ + state_diff::StateDiff, + log_entry::LogEntry, + errors::ExecutionError, +}; /// Transaction execution receipt. #[derive(Debug, PartialEq, Clone)] @@ -69,132 +69,5 @@ pub struct Executed { pub state_diff: Option, } -/// Result of executing the transaction. -#[derive(PartialEq, Debug, Clone)] -pub enum ExecutionError { - /// Returned when there gas paid for transaction execution is - /// lower than base gas required. - NotEnoughBaseGas { - /// Absolute minimum gas required. - required: U256, - /// Gas provided. - got: U256 - }, - /// Returned when block (gas_used + gas) > gas_limit. - /// - /// If gas =< gas_limit, upstream may try to execute the transaction - /// in next block. - BlockGasLimitReached { - /// Gas limit of block for transaction. - gas_limit: U256, - /// Gas used in block prior to transaction. - gas_used: U256, - /// Amount of gas in block. - gas: U256 - }, - /// Returned when transaction nonce does not match state nonce. - InvalidNonce { - /// Nonce expected. - expected: U256, - /// Nonce found. - got: U256 - }, - /// Returned when cost of transaction (value + gas_price * gas) exceeds - /// current sender balance. - NotEnoughCash { - /// Minimum required balance. - required: U512, - /// Actual balance. - got: U512 - }, - /// When execution tries to modify the state in static context - MutableCallInStaticContext, - /// Returned when transacting from a non-existing account with dust protection enabled. - SenderMustExist, - /// Returned when internal evm error occurs. - Internal(String), - /// Returned when generic transaction occurs - TransactionMalformed(String), -} - -impl From> for ExecutionError { - fn from(err: Box) -> Self { - ExecutionError::Internal(format!("{:?}", err)) - } -} -impl From for ExecutionError { - fn from(err: ethtrie::TrieError) -> Self { - ExecutionError::Internal(format!("{:?}", err)) - } -} - -impl fmt::Display for ExecutionError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::ExecutionError::*; - - let msg = match *self { - NotEnoughBaseGas { ref required, ref got } => - format!("Not enough base gas. {} is required, but only {} paid", required, got), - BlockGasLimitReached { ref gas_limit, ref gas_used, ref gas } => - format!("Block gas limit reached. The limit is {}, {} has \ - already been used, and {} more is required", gas_limit, gas_used, gas), - InvalidNonce { ref expected, ref got } => - format!("Invalid transaction nonce: expected {}, found {}", expected, got), - NotEnoughCash { ref required, ref got } => - format!("Cost of transaction exceeds sender balance. {} is required \ - but the sender only has {}", required, got), - MutableCallInStaticContext => "Mutable Call in static context".to_owned(), - SenderMustExist => "Transacting from an empty account".to_owned(), - Internal(ref msg) => msg.clone(), - TransactionMalformed(ref err) => format!("Malformed transaction: {}", err), - }; - - f.write_fmt(format_args!("Transaction execution error ({}).", msg)) - } -} - -impl error::Error for ExecutionError { - fn description(&self) -> &str { - "Transaction execution error" - } -} - -/// Result of executing the transaction. -#[derive(PartialEq, Debug, Clone)] -pub enum CallError { - /// Couldn't find the transaction in the chain. - TransactionNotFound, - /// Couldn't find requested block's state in the chain. - StatePruned, - /// Couldn't find an amount of gas that didn't result in an exception. - Exceptional(vm::Error), - /// Corrupt state. - StateCorrupt, - /// Error executing. - Execution(ExecutionError), -} - -impl From for CallError { - fn from(error: ExecutionError) -> Self { - CallError::Execution(error) - } -} - -impl fmt::Display for CallError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::CallError::*; - - let msg = match *self { - TransactionNotFound => "Transaction couldn't be found in the chain".into(), - StatePruned => "Couldn't find the transaction block's state in the chain".into(), - Exceptional(ref e) => format!("An exception ({}) happened in the execution", e), - StateCorrupt => "Stored state found to be corrupted.".into(), - Execution(ref e) => format!("{}", e), - }; - - f.write_fmt(format_args!("Transaction execution error ({}).", msg)) - } -} - /// Transaction execution result. pub type ExecutionResult = Result, ExecutionError>; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 5acd6667f..ae48ac92f 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -23,7 +23,6 @@ use ethereum_types::{H256, U256, U512, Address}; use bytes::{Bytes, BytesRef}; use account_state::{Backend as StateBackend, State, CleanupMode}; use substate::Substate; -use executed::ExecutionError; use machine::Machine; use evm::{CallType, Finalize, FinalizationResult}; use vm::{ @@ -33,7 +32,10 @@ use vm::{ use trie_vm_factories::VmFactory; use externalities::*; use trace::{self, Tracer, VMTracer}; -use types::transaction::{Action, SignedTransaction}; +use types::{ + errors::ExecutionError, + transaction::{Action, SignedTransaction}, +}; use transaction_ext::Transaction; use crossbeam_utils::thread; pub use executed::{Executed, ExecutionResult}; @@ -1215,7 +1217,6 @@ mod tests { use ethereum_types::{H256, U256, U512, Address, BigEndianHash}; use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; use evm::{Factory, VMType}; - use error::ExecutionError; use machine::Machine; use account_state::CleanupMode; use substate::Substate; @@ -1223,7 +1224,10 @@ mod tests { use trace::trace; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer}; use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; - use types::transaction::{Action, Transaction}; + use types::{ + errors::ExecutionError, + transaction::{Action, Transaction}, + }; fn make_frontier_machine(max_depth: usize) -> Machine { let mut machine = ::ethereum::new_frontier_test_machine(); diff --git a/ethcore/src/executive_state.rs b/ethcore/src/executive_state.rs index f0f89f8bc..0931c4581 100644 --- a/ethcore/src/executive_state.rs +++ b/ethcore/src/executive_state.rs @@ -21,8 +21,9 @@ use machine::Machine; use vm::EnvInfo; use executive::{Executive, TransactOptions}; -use executed::{Executed, ExecutionError}; +use executed::Executed; use types::{ + errors::{ExecutionError, EthcoreError as Error}, transaction::SignedTransaction, receipt::{TransactionOutcome, Receipt}, }; @@ -38,8 +39,6 @@ use keccak_hasher::KeccakHasher; use kvdb::DBValue; use hash_db::AsHashDB; -use error::Error; - /// Return type of proof validity check. #[derive(Debug, Clone)] pub enum ProvedExecution { diff --git a/ethcore/src/json_tests/transaction.rs b/ethcore/src/json_tests/transaction.rs index febc61404..7a7c0b809 100644 --- a/ethcore/src/json_tests/transaction.rs +++ b/ethcore/src/json_tests/transaction.rs @@ -19,8 +19,11 @@ use super::test_common::*; use client::EvmTestClient; use ethjson; use rlp::Rlp; -use types::header::Header; -use types::transaction::UnverifiedTransaction; +use types::{ + header::Header, + errors::EthcoreError as Error, + transaction::UnverifiedTransaction +}; use transaction_ext::Transaction; /// Run transaction jsontests on a given folder. @@ -60,7 +63,7 @@ fn do_json_test(json_data: &[u8], start_stop_hook: &mu let rlp: Vec = test.rlp.clone().into(); let res = Rlp::new(&rlp) .as_val() - .map_err(::error::Error::from) + .map_err(Error::from) .and_then(|t: UnverifiedTransaction| { let mut header: Header = Default::default(); // Use high enough number to activate all required features. diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 118a33d43..e7aa73856 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -128,7 +128,6 @@ extern crate serde_json; extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; -extern crate derive_more; #[macro_use] extern crate log; #[macro_use] @@ -152,7 +151,6 @@ extern crate parity_runtime; pub mod block; pub mod client; pub mod engines; -pub mod error; pub mod ethereum; pub mod executed; pub mod executive; diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index 8cb5dab0d..0960b915c 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -22,17 +22,24 @@ use std::sync::Arc; use ethereum_types::{U256, H256, Address}; use rlp::Rlp; -use types::transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction}; -use types::BlockNumber; -use types::header::Header; -use vm::{CallType, ActionParams, ActionValue, ParamsType, EnvInfo, Schedule}; +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 error::Error; use executive::Executive; -use spec::CommonParams; use account_state::CleanupMode; use substate::Substate; use trace::{NoopTracer, NoopVMTracer}; @@ -41,30 +48,6 @@ 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]); -/// Ethash-specific extensions. -#[derive(Debug, Clone)] -pub struct EthashExtensions { - /// Homestead transition block number. - pub homestead_transition: BlockNumber, - /// DAO hard-fork transition block (X). - pub dao_hardfork_transition: u64, - /// DAO hard-fork refund contract address (C). - pub dao_hardfork_beneficiary: Address, - /// DAO hard-fork DAO accounts list (L) - pub dao_hardfork_accounts: Vec
, -} - -impl From<::ethjson::spec::EthashParams> for EthashExtensions { - fn from(p: ::ethjson::spec::EthashParams) -> Self { - EthashExtensions { - homestead_transition: p.homestead_transition.map_or(0, Into::into), - dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into), - dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::zero, Into::into), - dao_hardfork_accounts: p.dao_hardfork_accounts.unwrap_or_else(Vec::new).into_iter().map(Into::into).collect(), - } - } -} - /// Special rules to be applied to the schedule. pub type ScheduleCreationRules = dyn Fn(&mut Schedule, BlockNumber) + Sync + Send; @@ -182,7 +165,7 @@ impl Machine { 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| ::engines::EngineError::FailedSystemCall(format!("{}", e)))?; + 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) @@ -366,9 +349,12 @@ impl Machine { } /// Does verification of the transaction against the parent state. - pub fn verify_transaction(&self, t: &SignedTransaction, parent: &Header, client: &C) - -> Result<(), transaction::Error> - { + 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()) @@ -399,30 +385,6 @@ impl Machine { live.state_mut().add_balance(address, amount, CleanupMode::NoEmpty).map_err(Into::into) } } -/// Auxiliary data fetcher for an Ethereum machine. In Ethereum-like machines -/// there are two kinds of auxiliary data: bodies and receipts. -#[derive(Default, Clone)] -pub struct AuxiliaryData<'a> { - /// The full block bytes, including the header. - pub bytes: Option<&'a [u8]>, - /// The block receipts. - pub receipts: Option<&'a [::types::receipt::Receipt]>, -} - -/// Type alias for a function we can make calls through synchronously. -/// Returns the call result and state proof for each call. -pub type Call<'a> = dyn Fn(Address, Vec) -> Result<(Vec, Vec>), String> + 'a; - -/// Request for auxiliary data of a block. -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum AuxiliaryRequest { - /// Needs the body. - Body, - /// Needs the receipts. - Receipts, - /// Needs both body and receipts. - Both, -} // Try to round gas_limit a bit so that: // 1) it will still be in desired range diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 03e95c6c4..ad6ecaae8 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -43,20 +43,22 @@ use types::transaction::{ SignedTransaction, PendingTransaction, }; -use types::BlockNumber; -use types::block::Block; -use types::header::Header; -use types::receipt::RichReceipt; +use types::{ + BlockNumber, + block::Block, + header::Header, + engines::{SealingState}, + errors::{EthcoreError as Error, ExecutionError}, + receipt::RichReceipt, +}; use using_queue::{UsingQueue, GetAction}; use block::{ClosedBlock, SealedBlock}; use client::{ - BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId + BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId, ClientIoMessage, }; -use client::{BlockId, ClientIoMessage}; -use engines::{Engine, Seal, SealingState, EngineSigner}; -use error::Error; -use executed::ExecutionError; +use client::BlockId; +use engines::{Engine, Seal, EngineSigner}; use executive::contract_address; use spec::Spec; use account_state::State; @@ -245,7 +247,7 @@ pub struct Miner { sealing: Mutex, params: RwLock, #[cfg(feature = "work-notify")] - listeners: RwLock>>, + listeners: RwLock>>, nonce_cache: NonceCache, gas_pricer: Mutex, options: MinerOptions, @@ -260,7 +262,7 @@ pub struct Miner { impl Miner { /// Push listener that will handle new jobs #[cfg(feature = "work-notify")] - pub fn add_work_listener(&self, notifier: Box) { + pub fn add_work_listener(&self, notifier: Box) { self.listeners.write().push(notifier); self.sealing.lock().enabled = true; } diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 10a101ee5..c9f4c0d1f 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -37,10 +37,13 @@ use bytes::Bytes; use ethcore_miner::pool::{VerifiedTransaction, QueueStatus, local_transactions}; use ethereum_types::{H256, U256, Address}; use types::transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction}; -use types::BlockNumber; -use types::block::Block; -use types::header::Header; -use types::receipt::RichReceipt; +use types::{ + BlockNumber, + errors::EthcoreError as Error, + block::Block, + header::Header, + receipt::RichReceipt, +}; use block::SealedBlock; use call_contract::{CallContract, RegistryInfo}; @@ -49,7 +52,6 @@ use client::{ BlockChain, BlockProducer, SealedBlockImporter, ChainInfo, AccountData, Nonce, }; -use error::Error; use account_state::state::StateInfo; /// Provides methods to verify incoming external transactions diff --git a/ethcore/src/miner/pool_client.rs b/ethcore/src/miner/pool_client.rs index b197e56f6..f6ab115a1 100644 --- a/ethcore/src/miner/pool_client.rs +++ b/ethcore/src/miner/pool_client.rs @@ -36,7 +36,8 @@ use types::header::Header; use parking_lot::RwLock; use call_contract::CallContract; -use client::{TransactionId, BlockInfo, Nonce}; +use client::{TransactionId, Nonce}; +use client::BlockInfo; use engines::Engine; use miner; use transaction_ext::Transaction; diff --git a/ethcore/src/miner/stratum.rs b/ethcore/src/miner/stratum.rs index aad646753..49e8c9483 100644 --- a/ethcore/src/miner/stratum.rs +++ b/ethcore/src/miner/stratum.rs @@ -255,7 +255,7 @@ impl Stratum { #[cfg(feature = "work-notify")] pub fn register(cfg: &Options, miner: Arc, client: Weak) -> Result<(), Error> { let stratum = Stratum::start(cfg, Arc::downgrade(&miner.clone()), client)?; - miner.add_work_listener(Box::new(stratum) as Box); + miner.add_work_listener(Box::new(stratum) as Box); Ok(()) } } diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index 4f65d4290..341c70d34 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -25,7 +25,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use engines::{Engine, EpochVerifier, EpochTransition}; -use snapshot::{Error, ManifestData, Progress}; +use snapshot::{ManifestData, Progress}; use blockchain::{BlockChain, BlockChainDB, BlockProvider}; use bytes::Bytes; @@ -33,10 +33,13 @@ use ethereum_types::{H256, U256}; use itertools::{Position, Itertools}; use kvdb::KeyValueDB; use rlp::{RlpStream, Rlp}; -use types::encoded; -use types::header::Header; -use types::ids::BlockId; -use types::receipt::Receipt; +use types::{ + encoded, + header::Header, + ids::BlockId, + errors::{SnapshotError, EthcoreError}, + receipt::Receipt, +}; /// Snapshot creation and restoration for PoA chains. /// Chunk format: @@ -59,9 +62,9 @@ impl SnapshotComponents for PoaSnapshot { sink: &mut ChunkSink, _progress: &Progress, preferred_size: usize, - ) -> Result<(), Error> { + ) -> Result<(), SnapshotError> { let number = chain.block_number(&block_at) - .ok_or_else(|| Error::InvalidStartingBlock(BlockId::Hash(block_at)))?; + .ok_or_else(||SnapshotError::InvalidStartingBlock(BlockId::Hash(block_at)))?; let mut pending_size = 0; let mut rlps = Vec::new(); @@ -75,7 +78,7 @@ impl SnapshotComponents for PoaSnapshot { } let header = chain.block_header_data(&transition.block_hash) - .ok_or_else(|| Error::BlockNotFound(transition.block_hash))?; + .ok_or_else(||SnapshotError::BlockNotFound(transition.block_hash))?; let entry = { let mut entry_stream = RlpStream::new_list(2); @@ -100,12 +103,12 @@ impl SnapshotComponents for PoaSnapshot { let (block, receipts) = chain.block(&block_at) .and_then(|b| chain.block_receipts(&block_at).map(|r| (b, r))) - .ok_or_else(|| Error::BlockNotFound(block_at))?; + .ok_or_else(||SnapshotError::BlockNotFound(block_at))?; let block = block.decode()?; let parent_td = chain.block_details(block.header.parent_hash()) .map(|d| d.total_difficulty) - .ok_or_else(|| Error::BlockNotFound(block_at))?; + .ok_or_else(||SnapshotError::BlockNotFound(block_at))?; rlps.push({ let mut stream = RlpStream::new_list(5); @@ -128,11 +131,11 @@ impl SnapshotComponents for PoaSnapshot { chain: BlockChain, db: Arc, manifest: &ManifestData, - ) -> Result, ::error::Error> { + ) -> Result, EthcoreError> { Ok(Box::new(ChunkRebuilder { manifest: manifest.clone(), warp_target: None, - chain: chain, + chain, db: db.key_value().clone(), had_genesis: false, unverified_firsts: Vec::new(), @@ -146,7 +149,7 @@ impl SnapshotComponents for PoaSnapshot { // writes a chunk composed of the inner RLPs here. // flag indicates whether the chunk is the last chunk. -fn write_chunk(last: bool, chunk_data: &mut Vec, sink: &mut ChunkSink) -> Result<(), Error> { +fn write_chunk(last: bool, chunk_data: &mut Vec, sink: &mut ChunkSink) -> Result<(), SnapshotError> { let mut stream = RlpStream::new_list(1 + chunk_data.len()); stream.append(&last); @@ -185,7 +188,7 @@ impl ChunkRebuilder { last_verifier: &mut Option>, transition_rlp: Rlp, engine: &dyn Engine, - ) -> Result { + ) -> Result { use engines::ConstructedVerifier; // decode. @@ -202,7 +205,7 @@ impl ChunkRebuilder { Some(ref last) => if last.check_finality_proof(finality_proof).map_or(true, |hashes| !hashes.contains(&hash)) { - return Err(Error::BadEpochProof(header.number()).into()); + return Err(SnapshotError::BadEpochProof(header.number()).into()); }, None if header.number() != 0 => { // genesis never requires additional validation. @@ -231,7 +234,7 @@ impl ChunkRebuilder { block_number: header.number(), proof: epoch_data, }, - header: header, + header, }) } } @@ -242,7 +245,7 @@ impl Rebuilder for ChunkRebuilder { chunk: &[u8], engine: &dyn Engine, abort_flag: &AtomicBool, - ) -> Result<(), ::error::Error> { + ) -> Result<(), EthcoreError> { let rlp = Rlp::new(chunk); let is_last_chunk: bool = rlp.val_at(0)?; let num_items = rlp.item_count()?; @@ -255,13 +258,13 @@ impl Rebuilder for ChunkRebuilder { }; if num_transitions == 0 && !is_last_chunk { - return Err(Error::WrongChunkFormat("Found non-last chunk without any data.".into()).into()); + return Err(SnapshotError::WrongChunkFormat("Found non-last chunk without any data.".into()).into()); } let mut last_verifier = None; let mut last_number = None; for transition_rlp in rlp.iter().skip(1).take(num_transitions).with_position() { - if !abort_flag.load(Ordering::SeqCst) { return Err(Error::RestorationAborted.into()) } + if !abort_flag.load(Ordering::SeqCst) { return Err(SnapshotError::RestorationAborted.into()) } let (is_first, is_last) = match transition_rlp { Position::First(_) => (true, false), @@ -278,7 +281,7 @@ impl Rebuilder for ChunkRebuilder { )?; if last_number.map_or(false, |num| verified.header.number() <= num) { - return Err(Error::WrongChunkFormat("Later epoch transition in earlier or same block.".into()).into()); + return Err(SnapshotError::WrongChunkFormat("Later epoch transition in earlier or same block.".into()).into()); } last_number = Some(verified.header.number()); @@ -289,7 +292,7 @@ impl Rebuilder for ChunkRebuilder { // but it doesn't need verification later. if verified.header.number() == 0 { if verified.header.hash() != self.chain.genesis_hash() { - return Err(Error::WrongBlockHash(0, verified.header.hash(), self.chain.genesis_hash()).into()); + return Err(SnapshotError::WrongBlockHash(0, verified.header.hash(), self.chain.genesis_hash()).into()); } self.had_genesis = true; @@ -332,7 +335,7 @@ impl Rebuilder for ChunkRebuilder { let hash = block.header.hash(); let best_hash = self.manifest.block_hash; if hash != best_hash { - return Err(Error::WrongBlockHash(block.header.number(), best_hash, hash).into()) + return Err(SnapshotError::WrongBlockHash(block.header.number(), best_hash, hash).into()) } } @@ -348,14 +351,14 @@ impl Rebuilder for ChunkRebuilder { Ok(()) } - fn finalize(&mut self) -> Result<(), ::error::Error> { + fn finalize(&mut self) -> Result<(), EthcoreError> { if !self.had_genesis { - return Err(Error::WrongChunkFormat("No genesis transition included.".into()).into()); + return Err(SnapshotError::WrongChunkFormat("No genesis transition included.".into()).into()); } let target_header = match self.warp_target.take() { Some(x) => x, - None => return Err(Error::WrongChunkFormat("Warp target block not included.".into()).into()), + None => return Err(SnapshotError::WrongChunkFormat("Warp target block not included.".into()).into()), }; trace!(target: "snapshot", "rebuilder, finalize: verifying {} unverified first blocks", self.unverified_firsts.len()); @@ -368,7 +371,7 @@ impl Rebuilder for ChunkRebuilder { while let Some(&(ref last_header, ref last_verifier)) = lasts_reversed.next() { if last_header.number() < header.number() { if last_verifier.check_finality_proof(&finality_proof).map_or(true, |hashes| !hashes.contains(&hash)) { - return Err(Error::BadEpochProof(header.number()).into()); + return Err(SnapshotError::BadEpochProof(header.number()).into()); } found = true; break; @@ -376,7 +379,7 @@ impl Rebuilder for ChunkRebuilder { } if !found { - return Err(Error::WrongChunkFormat("Inconsistent chunk ordering.".into()).into()); + return Err(SnapshotError::WrongChunkFormat("Inconsistent chunk ordering.".into()).into()); } } diff --git a/ethcore/src/snapshot/consensus/mod.rs b/ethcore/src/snapshot/consensus/mod.rs index d6f317538..102acdeca 100644 --- a/ethcore/src/snapshot/consensus/mod.rs +++ b/ethcore/src/snapshot/consensus/mod.rs @@ -22,7 +22,8 @@ use std::sync::Arc; use blockchain::{BlockChain, BlockChainDB}; use engines::Engine; -use snapshot::{Error, ManifestData, Progress}; +use snapshot::{ManifestData, Progress}; +use types::errors::{SnapshotError, EthcoreError}; use ethereum_types::H256; @@ -51,7 +52,7 @@ pub trait SnapshotComponents: Send { chunk_sink: &mut ChunkSink, progress: &Progress, preferred_size: usize, - ) -> Result<(), Error>; + ) -> Result<(), SnapshotError>; /// Create a rebuilder, which will have chunks fed into it in aribtrary /// order and then be finalized. @@ -65,7 +66,7 @@ pub trait SnapshotComponents: Send { chain: BlockChain, db: Arc, manifest: &ManifestData, - ) -> Result, ::error::Error>; + ) -> Result, EthcoreError>; /// Minimum supported snapshot version number. fn min_supported_version(&self) -> u64; @@ -85,12 +86,12 @@ pub trait Rebuilder: Send { chunk: &[u8], engine: &dyn Engine, abort_flag: &AtomicBool, - ) -> Result<(), ::error::Error>; + ) -> 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<(), ::error::Error>; + fn finalize(&mut self) -> Result<(), EthcoreError>; } diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index eda200d66..f286006a9 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -28,14 +28,17 @@ use std::sync::Arc; use blockchain::{BlockChain, BlockChainDB, BlockProvider}; use engines::Engine; -use snapshot::{Error, ManifestData, Progress}; +use snapshot::{ManifestData, Progress}; use snapshot::block::AbridgedBlock; use ethereum_types::H256; use kvdb::KeyValueDB; use bytes::Bytes; use rlp::{RlpStream, Rlp}; use rand::rngs::OsRng; -use types::encoded; +use types::{ + encoded, + errors::{SnapshotError, EthcoreError}, +}; /// Snapshot creation and restoration for PoW chains. /// This includes blocks from the head of the chain as a @@ -52,10 +55,7 @@ pub struct PowSnapshot { impl PowSnapshot { /// Create a new instance. pub fn new(blocks: u64, max_restore_blocks: u64) -> PowSnapshot { - PowSnapshot { - blocks: blocks, - max_restore_blocks: max_restore_blocks, - } + PowSnapshot { blocks, max_restore_blocks } } } @@ -67,14 +67,14 @@ impl SnapshotComponents for PowSnapshot { chunk_sink: &mut ChunkSink, progress: &Progress, preferred_size: usize, - ) -> Result<(), Error> { + ) -> Result<(), SnapshotError> { PowWorker { - chain: chain, + chain, rlps: VecDeque::new(), current_hash: block_at, writer: chunk_sink, - progress: progress, - preferred_size: preferred_size, + progress, + preferred_size, }.chunk_all(self.blocks) } @@ -83,7 +83,7 @@ impl SnapshotComponents for PowSnapshot { chain: BlockChain, db: Arc, manifest: &ManifestData, - ) -> Result, ::error::Error> { + ) -> Result, EthcoreError> { PowRebuilder::new(chain, db.key_value().clone(), manifest, self.max_restore_blocks).map(|r| Box::new(r) as Box<_>) } @@ -105,7 +105,7 @@ struct PowWorker<'a> { impl<'a> PowWorker<'a> { // Repeatedly fill the buffers and writes out chunks, moving backwards from starting block hash. // Loops until we reach the first desired block, and writes out the remainder. - fn chunk_all(&mut self, snapshot_blocks: u64) -> Result<(), Error> { + fn chunk_all(&mut self, snapshot_blocks: u64) -> Result<(), SnapshotError> { let mut loaded_size = 0; let mut last = self.current_hash; @@ -116,7 +116,7 @@ impl<'a> PowWorker<'a> { let (block, receipts) = self.chain.block(&self.current_hash) .and_then(|b| self.chain.block_receipts(&self.current_hash).map(|r| (b, r))) - .ok_or_else(|| Error::BlockNotFound(self.current_hash))?; + .ok_or_else(||SnapshotError::BlockNotFound(self.current_hash))?; let abridged_rlp = AbridgedBlock::from_block_view(&block.view()).into_inner(); @@ -155,12 +155,12 @@ impl<'a> PowWorker<'a> { // // we preface each chunk with the parent of the first block's details, // obtained from the details of the last block written. - fn write_chunk(&mut self, last: H256) -> Result<(), Error> { + fn write_chunk(&mut self, last: H256) -> Result<(), SnapshotError> { trace!(target: "snapshot", "prepared block chunk with {} blocks", self.rlps.len()); let (last_header, last_details) = self.chain.block_header_data(&last) .and_then(|n| self.chain.block_details(&last).map(|d| (n, d))) - .ok_or_else(|| Error::BlockNotFound(last))?; + .ok_or_else(||SnapshotError::BlockNotFound(last))?; let parent_number = last_header.number() - 1; let parent_hash = last_header.parent_hash(); @@ -206,7 +206,7 @@ pub struct PowRebuilder { impl PowRebuilder { /// Create a new PowRebuilder. - fn new(chain: BlockChain, db: Arc, manifest: &ManifestData, snapshot_blocks: u64) -> Result { + fn new(chain: BlockChain, db: Arc, manifest: &ManifestData, snapshot_blocks: u64) -> Result { Ok(PowRebuilder { chain, db, @@ -224,7 +224,7 @@ impl PowRebuilder { impl Rebuilder for PowRebuilder { /// Feed the rebuilder an uncompressed block chunk. /// Returns the number of blocks fed or any errors. - fn feed(&mut self, chunk: &[u8], engine: &dyn Engine, abort_flag: &AtomicBool) -> Result<(), ::error::Error> { + fn feed(&mut self, chunk: &[u8], engine: &dyn Engine, abort_flag: &AtomicBool) -> Result<(), EthcoreError> { use snapshot::verify_old_block; use ethereum_types::U256; use triehash::ordered_trie_root; @@ -236,7 +236,7 @@ impl Rebuilder for PowRebuilder { trace!(target: "snapshot", "restoring block chunk with {} blocks.", num_blocks); if self.fed_blocks + num_blocks > self.snapshot_blocks { - return Err(Error::TooManyBlocks(self.snapshot_blocks, self.fed_blocks + num_blocks).into()) + return Err(SnapshotError::TooManyBlocks(self.snapshot_blocks, self.fed_blocks + num_blocks).into()) } // todo: assert here that these values are consistent with chunks being in order. @@ -245,7 +245,7 @@ impl Rebuilder for PowRebuilder { let parent_total_difficulty = rlp.val_at::(2)?; for idx in 3..item_count { - if !abort_flag.load(Ordering::SeqCst) { return Err(Error::RestorationAborted.into()) } + if !abort_flag.load(Ordering::SeqCst) { return Err(SnapshotError::RestorationAborted.into()) } let pair = rlp.at(idx)?; let abridged_rlp = pair.at(0)?.as_raw().to_owned(); @@ -259,11 +259,11 @@ impl Rebuilder for PowRebuilder { if is_best { if block.header.hash() != self.best_hash { - return Err(Error::WrongBlockHash(cur_number, self.best_hash, block.header.hash()).into()) + return Err(SnapshotError::WrongBlockHash(cur_number, self.best_hash, block.header.hash()).into()) } if block.header.state_root() != &self.best_root { - return Err(Error::WrongStateRoot(self.best_root, *block.header.state_root()).into()) + return Err(SnapshotError::WrongStateRoot(self.best_root, *block.header.state_root()).into()) } } @@ -298,7 +298,7 @@ impl Rebuilder for PowRebuilder { } /// Glue together any disconnected chunks and check that the chain is complete. - fn finalize(&mut self) -> Result<(), ::error::Error> { + fn finalize(&mut self) -> Result<(), EthcoreError> { let mut batch = self.db.transaction(); trace!(target: "snapshot", "rebuilder, finalize: inserting {} disconnected chunks", self.disconnected.len()); for (first_num, first_hash) in self.disconnected.drain(..) { diff --git a/ethcore/src/snapshot/io.rs b/ethcore/src/snapshot/io.rs index 536862e7b..cf1316827 100644 --- a/ethcore/src/snapshot/io.rs +++ b/ethcore/src/snapshot/io.rs @@ -28,6 +28,7 @@ use std::path::{Path, PathBuf}; use bytes::Bytes; use ethereum_types::H256; use rlp::{RlpStream, Rlp}; +use types::errors::{SnapshotError, EthcoreError}; use super::ManifestData; @@ -206,7 +207,7 @@ impl PackedReader { /// Create a new `PackedReader` for the file at the given path. /// This will fail if any io errors are encountered or the file /// is not a valid packed snapshot. - pub fn new(path: &Path) -> Result, ::snapshot::error::Error> { + pub fn new(path: &Path) -> Result, SnapshotError> { let mut file = File::open(path)?; let file_len = file.metadata()?.len(); if file_len < 8 { @@ -246,7 +247,7 @@ impl PackedReader { }; if version > SNAPSHOT_VERSION { - return Err(::snapshot::error::Error::VersionNotSupported(version)); + return Err(SnapshotError::VersionNotSupported(version)); } let state: Vec = rlp.list_at(0 + start)?; @@ -299,7 +300,7 @@ pub struct LooseReader { impl LooseReader { /// Create a new `LooseReader` which will read the manifest and chunk data from /// the given directory. - pub fn new(mut dir: PathBuf) -> Result { + pub fn new(mut dir: PathBuf) -> Result { let mut manifest_buf = Vec::new(); dir.push("MANIFEST"); diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 4ded83efe..256db1d94 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -28,9 +28,11 @@ use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY}; use account_db::{AccountDB, AccountDBMut}; use blockchain::{BlockChain, BlockProvider}; use engines::Engine; -use types::header::Header; -use types::ids::BlockId; - +use types::{ + ids::BlockId, + header::Header, + errors::{SnapshotError as Error, EthcoreError}, +}; use ethereum_types::{H256, U256}; use hash_db::HashDB; use keccak_hasher::KeccakHasher; @@ -53,8 +55,6 @@ use account_state::Account as StateAccount; use crossbeam_utils::thread; use rand::{Rng, rngs::OsRng}; -pub use self::error::Error; - pub use self::consensus::*; pub use self::service::{SnapshotClient, Service, DatabaseRestore}; pub use self::traits::SnapshotService; @@ -69,7 +69,6 @@ pub mod service; mod account; mod block; mod consensus; -mod error; mod watcher; #[cfg(test)] @@ -423,7 +422,7 @@ impl StateRebuilder { } /// Feed an uncompressed state chunk into the rebuilder. - pub fn feed(&mut self, chunk: &[u8], flag: &AtomicBool) -> Result<(), ::error::Error> { + pub fn feed(&mut self, chunk: &[u8], flag: &AtomicBool) -> Result<(), EthcoreError> { let rlp = Rlp::new(chunk); let empty_rlp = StateAccount::new_basic(U256::zero(), U256::zero()).rlp(); let mut pairs = Vec::with_capacity(rlp.item_count()?); @@ -486,7 +485,7 @@ impl StateRebuilder { /// Finalize the restoration. Check for accounts missing code and make a dummy /// journal entry. /// Once all chunks have been fed, there should be nothing missing. - pub fn finalize(mut self, era: u64, id: H256) -> Result, ::error::Error> { + pub fn finalize(mut self, era: u64, id: H256) -> Result, EthcoreError> { let missing = self.missing_code.keys().cloned().collect::>(); if !missing.is_empty() { return Err(Error::MissingCode(missing).into()) } @@ -517,7 +516,7 @@ fn rebuild_accounts( known_code: &HashMap, known_storage_roots: &mut HashMap, abort_flag: &AtomicBool, -) -> Result { +) -> Result { let mut status = RebuiltStatus::default(); for (account_rlp, out) in account_fat_rlps.into_iter().zip(out_chunk.iter_mut()) { if !abort_flag.load(Ordering::SeqCst) { return Err(Error::RestorationAborted.into()) } @@ -578,13 +577,13 @@ const POW_VERIFY_RATE: f32 = 0.02; /// Verify an old block with the given header, engine, blockchain, body. If `always` is set, it will perform /// the fullest verification possible. If not, it will take a random sample to determine whether it will /// do heavy or light verification. -pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &dyn Engine, chain: &BlockChain, always: bool) -> Result<(), ::error::Error> { +pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &dyn Engine, chain: &BlockChain, always: bool) -> Result<(), EthcoreError> { engine.verify_block_basic(header)?; if always || rng.gen::() <= POW_VERIFY_RATE { engine.verify_block_unordered(header)?; match chain.block_header_data(header.parent_hash()) { - Some(parent) => engine.verify_block_family(header, &parent.decode()?), + Some(parent) => engine.verify_block_family(header, &parent.decode()?).map_err(Into::into), None => Ok(()), } } else { diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 5e1efe138..d3e2f1ce7 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -28,12 +28,13 @@ use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, Snapshot use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter}; use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler}; -use client::{BlockInfo, BlockChainClient, Client, ChainInfo, ClientIoMessage}; +use client::{BlockChainClient, Client, ChainInfo, BlockInfo, ClientIoMessage}; use engines::Engine; -use error::Error; -use snapshot::{Error as SnapshotError}; use hash::keccak; -use types::ids::BlockId; +use types::{ + errors::{EthcoreError as Error, SnapshotError, SnapshotError::UnlinkedAncientBlockChain}, + ids::BlockId, +}; use io::IoChannel; @@ -43,7 +44,6 @@ use bytes::Bytes; use journaldb::Algorithm; use kvdb::DBTransaction; use snappy; -use snapshot::error::Error::UnlinkedAncientBlockChain; /// Helper for removing directories in case of error. struct Guard(bool, PathBuf); diff --git a/ethcore/src/snapshot/tests/helpers.rs b/ethcore/src/snapshot/tests/helpers.rs index 89e6f8730..053e8813f 100644 --- a/ethcore/src/snapshot/tests/helpers.rs +++ b/ethcore/src/snapshot/tests/helpers.rs @@ -41,6 +41,7 @@ use journaldb; use trie::{TrieMut, Trie}; use ethtrie::{SecTrieDBMut, TrieDB, TrieDBMut}; use self::trie_standardmap::{Alphabet, StandardMap, ValueMode}; +use types::errors::EthcoreError; // the proportion of accounts we will alter each tick. const ACCOUNT_CHURN: f32 = 0.01; @@ -155,7 +156,7 @@ pub fn restore( engine: &dyn Engine, reader: &dyn SnapshotReader, genesis: &[u8], -) -> Result<(), ::error::Error> { +) -> Result<(), EthcoreError> { use std::sync::atomic::AtomicBool; let flag = AtomicBool::new(true); diff --git a/ethcore/src/snapshot/tests/proof_of_work.rs b/ethcore/src/snapshot/tests/proof_of_work.rs index 4aa444229..9be48ab06 100644 --- a/ethcore/src/snapshot/tests/proof_of_work.rs +++ b/ethcore/src/snapshot/tests/proof_of_work.rs @@ -18,7 +18,7 @@ use std::sync::atomic::AtomicBool; use tempdir::TempDir; -use error::Error; +use types::errors::EthcoreError as Error; use blockchain::generator::{BlockGenerator, BlockBuilder}; use blockchain::{BlockChain, ExtrasInsert}; diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index 515e5992f..08e716d26 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -21,7 +21,8 @@ use std::sync::Arc; use tempdir::TempDir; use blockchain::BlockProvider; -use client::{Client, ClientConfig, ImportBlock, BlockInfo}; +use client::{Client, ClientConfig, ImportBlock}; +use client::BlockInfo; use types::ids::BlockId; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use snapshot::service::{Service, ServiceParams}; diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index b62775c54..d78f33d8d 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -20,14 +20,14 @@ use std::sync::Arc; use std::sync::atomic::AtomicBool; use hash::{KECCAK_NULL_RLP, keccak}; -use types::basic_account::BasicAccount; +use types::{ + basic_account::BasicAccount, + errors::EthcoreError as Error, +}; use snapshot::account; use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder, SNAPSHOT_SUBPARTS}; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use super::helpers::StateProducer; - -use error::Error; - use rand::SeedableRng; use rand_xorshift::XorShiftRng; use ethereum_types::H256; diff --git a/ethcore/src/spec/mod.rs b/ethcore/src/spec/mod.rs index 5d90b5fbf..b3710a91b 100644 --- a/ethcore/src/spec/mod.rs +++ b/ethcore/src/spec/mod.rs @@ -21,4 +21,4 @@ mod seal; mod spec; pub use self::genesis::Genesis; -pub use self::spec::{Spec, SpecHardcodedSync, SpecParams, CommonParams, OptimizeFor}; +pub use self::spec::{Spec, SpecHardcodedSync, SpecParams, OptimizeFor}; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 70ce86e1a..39971e7b9 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -28,17 +28,20 @@ use hash::{KECCAK_NULL_RLP, keccak}; use parking_lot::RwLock; use rlp::{Rlp, RlpStream}; use rustc_hex::{FromHex, ToHex}; -use types::BlockNumber; -use types::encoded; -use types::header::Header; -use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType, VersionedSchedule}; +use types::{ + BlockNumber, + header::Header, + encoded, + engines::params::CommonParams, + errors::EthcoreError as Error, +}; +use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType}; use builtin::Builtin; use engines::{ Engine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority, Clique, - AuthorityRound, DEFAULT_BLOCKHASH_CONTRACT + AuthorityRound, Ethash, }; -use error::Error; use executive::Executive; use trie_vm_factories::Factories; use machine::Machine; @@ -51,301 +54,11 @@ use trace::{NoopTracer, NoopVMTracer}; pub use ethash::OptimizeFor; -const MAX_TRANSACTION_SIZE: usize = 300 * 1024; - // helper for formatting errors. fn fmt_err(f: F) -> String { format!("Spec json is invalid: {}", f) } -/// Parameters common to ethereum-like blockchains. -/// NOTE: when adding bugfix hard-fork parameters, -/// add to `nonzero_bugfix_hard_fork` -/// -/// we define a "bugfix" hard fork as any hard fork which -/// you would put on-by-default in a new chain. -#[derive(Debug, PartialEq, Default)] -#[cfg_attr(test, derive(Clone))] -pub struct CommonParams { - /// Account start nonce. - pub account_start_nonce: U256, - /// Maximum size of extra data. - pub maximum_extra_data_size: usize, - /// Network id. - pub network_id: u64, - /// Chain id. - pub chain_id: u64, - /// Main subprotocol name. - pub subprotocol_name: String, - /// Minimum gas limit. - pub min_gas_limit: U256, - /// Fork block to check. - pub fork_block: Option<(BlockNumber, H256)>, - /// EIP150 transition block number. - pub eip150_transition: BlockNumber, - /// Number of first block where EIP-160 rules begin. - pub eip160_transition: BlockNumber, - /// Number of first block where EIP-161.abc begin. - pub eip161abc_transition: BlockNumber, - /// Number of first block where EIP-161.d begins. - pub eip161d_transition: BlockNumber, - /// Number of first block where EIP-98 rules begin. - pub eip98_transition: BlockNumber, - /// Number of first block where EIP-658 rules begin. - pub eip658_transition: BlockNumber, - /// Number of first block where EIP-155 rules begin. - pub eip155_transition: BlockNumber, - /// Validate block receipts root. - pub validate_receipts_transition: BlockNumber, - /// Validate transaction chain id. - pub validate_chain_id_transition: BlockNumber, - /// Number of first block where EIP-140 rules begin. - pub eip140_transition: BlockNumber, - /// Number of first block where EIP-210 rules begin. - pub eip210_transition: BlockNumber, - /// EIP-210 Blockhash contract address. - pub eip210_contract_address: Address, - /// EIP-210 Blockhash contract code. - pub eip210_contract_code: Bytes, - /// Gas allocated for EIP-210 blockhash update. - pub eip210_contract_gas: U256, - /// Number of first block where EIP-211 rules begin. - pub eip211_transition: BlockNumber, - /// Number of first block where EIP-214 rules begin. - pub eip214_transition: BlockNumber, - /// Number of first block where EIP-145 rules begin. - pub eip145_transition: BlockNumber, - /// Number of first block where EIP-1052 rules begin. - pub eip1052_transition: BlockNumber, - /// Number of first block where EIP-1283 rules begin. - pub eip1283_transition: BlockNumber, - /// Number of first block where EIP-1283 rules end. - pub eip1283_disable_transition: BlockNumber, - /// Number of first block where EIP-1014 rules begin. - pub eip1014_transition: BlockNumber, - /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. - pub dust_protection_transition: BlockNumber, - /// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled. - pub nonce_cap_increment: u64, - /// Enable dust cleanup for contracts. - pub remove_dust_contracts: bool, - /// Wasm activation blocknumber, if any disabled initially. - pub wasm_activation_transition: BlockNumber, - /// Wasm account version, activated after `wasm_activation_transition`. If this field is defined, do not use code - /// prefix to determine VM to execute. - pub wasm_version: Option, - /// Number of first block where KIP-4 rules begin. Only has effect if Wasm is activated. - pub kip4_transition: BlockNumber, - /// Number of first block where KIP-6 rules begin. Only has effect if Wasm is activated. - pub kip6_transition: BlockNumber, - /// Gas limit bound divisor (how much gas limit can change per block) - pub gas_limit_bound_divisor: U256, - /// Registrar contract address. - pub registrar: Option
, - /// Node permission managing contract address. - pub node_permission_contract: Option
, - /// Maximum contract code size that can be deployed. - pub max_code_size: u64, - /// Number of first block where max code size limit is active. - pub max_code_size_transition: BlockNumber, - /// Transaction permission managing contract address. - pub transaction_permission_contract: Option
, - /// Block at which the transaction permission contract should start being used. - pub transaction_permission_contract_transition: BlockNumber, - /// Maximum size of transaction's RLP payload - pub max_transaction_size: usize, -} - -impl CommonParams { - /// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net. - pub fn schedule(&self, block_number: u64) -> ::vm::Schedule { - if block_number < self.eip150_transition { - ::vm::Schedule::new_homestead() - } else { - let max_code_size = self.max_code_size(block_number); - let mut schedule = ::vm::Schedule::new_post_eip150( - max_code_size as _, - block_number >= self.eip160_transition, - block_number >= self.eip161abc_transition, - block_number >= self.eip161d_transition - ); - - self.update_schedule(block_number, &mut schedule); - schedule - } - } - - /// Returns max code size at given block. - pub fn max_code_size(&self, block_number: u64) -> u64 { - if block_number >= self.max_code_size_transition { - self.max_code_size - } else { - u64::max_value() - } - } - - /// Apply common spec config parameters to the schedule. - pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) { - schedule.have_create2 = block_number >= self.eip1014_transition; - schedule.have_revert = block_number >= self.eip140_transition; - schedule.have_static_call = block_number >= self.eip214_transition; - schedule.have_return_data = block_number >= self.eip211_transition; - schedule.have_bitwise_shifting = block_number >= self.eip145_transition; - schedule.have_extcodehash = block_number >= self.eip1052_transition; - schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition); - if block_number >= self.eip210_transition { - schedule.blockhash_gas = 800; - } - if block_number >= self.dust_protection_transition { - schedule.kill_dust = match self.remove_dust_contracts { - true => ::vm::CleanDustMode::WithCodeAndStorage, - false => ::vm::CleanDustMode::BasicOnly, - }; - } - if block_number >= self.wasm_activation_transition { - let mut wasm = ::vm::WasmCosts::default(); - if block_number >= self.kip4_transition { - wasm.have_create2 = true; - } - if block_number >= self.kip6_transition { - wasm.have_gasleft = true; - } - schedule.wasm = Some(wasm); - if let Some(version) = self.wasm_version { - schedule.versions.insert(version, VersionedSchedule::PWasm); - } - } - } - - /// Return Some if the current parameters contain a bugfix hard fork not on block 0. - pub fn nonzero_bugfix_hard_fork(&self) -> Option<&str> { - if self.eip155_transition != 0 { - return Some("eip155Transition"); - } - - if self.validate_receipts_transition != 0 { - return Some("validateReceiptsTransition"); - } - - if self.validate_chain_id_transition != 0 { - return Some("validateChainIdTransition"); - } - - None - } -} - -impl From for CommonParams { - fn from(p: ethjson::spec::Params) -> Self { - CommonParams { - account_start_nonce: p.account_start_nonce.map_or_else(U256::zero, Into::into), - maximum_extra_data_size: p.maximum_extra_data_size.into(), - network_id: p.network_id.into(), - chain_id: if let Some(n) = p.chain_id { - n.into() - } else { - p.network_id.into() - }, - subprotocol_name: p.subprotocol_name.unwrap_or_else(|| "eth".to_owned()), - min_gas_limit: p.min_gas_limit.into(), - fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { - Some((n.into(), h.into())) - } else { - None - }, - eip150_transition: p.eip150_transition.map_or(0, Into::into), - eip160_transition: p.eip160_transition.map_or(0, Into::into), - eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into), - eip161d_transition: p.eip161d_transition.map_or(0, Into::into), - eip98_transition: p.eip98_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip155_transition: p.eip155_transition.map_or(0, Into::into), - validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), - validate_chain_id_transition: p.validate_chain_id_transition.map_or(0, Into::into), - eip140_transition: p.eip140_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip210_transition: p.eip210_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip210_contract_address: p.eip210_contract_address.map_or(Address::from_low_u64_be(0xf0), Into::into), - eip210_contract_code: p.eip210_contract_code.map_or_else( - || { - DEFAULT_BLOCKHASH_CONTRACT.from_hex().expect( - "Default BLOCKHASH contract is valid", - ) - }, - Into::into, - ), - eip210_contract_gas: p.eip210_contract_gas.map_or(1000000.into(), Into::into), - eip211_transition: p.eip211_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip145_transition: p.eip145_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip214_transition: p.eip214_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip658_transition: p.eip658_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip1052_transition: p.eip1052_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip1283_transition: p.eip1283_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip1283_disable_transition: p.eip1283_disable_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - eip1014_transition: p.eip1014_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - dust_protection_transition: p.dust_protection_transition.map_or_else( - BlockNumber::max_value, - Into::into, - ), - nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), - remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false), - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), - registrar: p.registrar.map(Into::into), - node_permission_contract: p.node_permission_contract.map(Into::into), - max_code_size: p.max_code_size.map_or(u64::max_value(), Into::into), - max_transaction_size: p.max_transaction_size.map_or(MAX_TRANSACTION_SIZE, Into::into), - max_code_size_transition: p.max_code_size_transition.map_or(0, Into::into), - transaction_permission_contract: p.transaction_permission_contract.map(Into::into), - transaction_permission_contract_transition: - p.transaction_permission_contract_transition.map_or(0, Into::into), - wasm_activation_transition: p.wasm_activation_transition.map_or_else( - BlockNumber::max_value, - Into::into - ), - wasm_version: p.wasm_version.map(Into::into), - kip4_transition: p.kip4_transition.map_or_else( - BlockNumber::max_value, - Into::into - ), - kip6_transition: p.kip6_transition.map_or_else( - BlockNumber::max_value, - Into::into - ), - } - } -} - /// Runtime parameters for the spec that are related to how the software should run the chain, /// rather than integral properties of the chain itself. #[derive(Debug, Clone, Copy)] @@ -613,7 +326,7 @@ impl Spec { match engine_spec { ethjson::spec::Engine::Null(null) => Arc::new(NullEngine::new(null.params.into(), machine)), - ethjson::spec::Engine::Ethash(ethash) => Arc::new(::ethereum::Ethash::new(spec_params.cache_dir, ethash.params.into(), machine, spec_params.optimization_setting)), + ethjson::spec::Engine::Ethash(ethash) => Arc::new(Ethash::new(spec_params.cache_dir, ethash.params.into(), machine, spec_params.optimization_setting)), ethjson::spec::Engine::InstantSeal(Some(instant_seal)) => Arc::new(InstantSeal::new(instant_seal.params.into(), machine)), ethjson::spec::Engine::InstantSeal(None) => Arc::new(InstantSeal::new(InstantSealParams::default(), machine)), ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(basic_authority.params.into(), machine)), diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 9063df3ae..b319a85a1 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -27,7 +27,8 @@ use types::filter::Filter; use types::view; use types::views::BlockView; -use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; +use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, BlockId, ChainInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock}; +use client::BlockInfo; use ethereum; use executive::{Executive, TransactOptions}; use miner::{Miner, PendingOrdering, MinerService}; diff --git a/ethcore/src/tx_filter.rs b/ethcore/src/tx_filter.rs index 2b9a7c941..bbb6ce139 100644 --- a/ethcore/src/tx_filter.rs +++ b/ethcore/src/tx_filter.rs @@ -21,11 +21,13 @@ use lru_cache::LruCache; use ethabi::FunctionOutputDecoder; use call_contract::CallContract; -use client::{BlockInfo, BlockId}; +use client::{BlockId, BlockInfo}; use parking_lot::Mutex; -use spec::CommonParams; -use types::transaction::{Action, SignedTransaction}; -use types::BlockNumber; +use types::{ + BlockNumber, + engines::params::CommonParams, + transaction::{Action, SignedTransaction} +}; use hash::KECCAK_EMPTY; use_contract!(transact_acl_deprecated, "res/contracts/tx_acl_deprecated.json"); diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index 230521c30..eeb1b2afe 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -19,12 +19,14 @@ use call_contract::CallContract; use client::BlockInfo; use engines::Engine; -use error::Error; -use types::header::Header; +use types::{ + header::Header, + errors::EthcoreError as Error, +}; use super::Verifier; use super::verification; -/// A canonial verifier -- this does full verification. +/// A canonical verifier -- this does full verification. pub struct CanonVerifier; impl Verifier for CanonVerifier { diff --git a/ethcore/src/verification/mod.rs b/ethcore/src/verification/mod.rs index 37c721ab1..d80b7867b 100644 --- a/ethcore/src/verification/mod.rs +++ b/ethcore/src/verification/mod.rs @@ -36,7 +36,7 @@ use client::BlockInfo; pub enum VerifierType { /// Verifies block normally. Canon, - /// Verifies block normallly, but skips seal verification. + /// Verifies block normally, but skips seal verification. CanonNoSeal, /// Does not verify block at all. /// Used in tests. diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index f503caa2f..9875524fa 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -19,8 +19,10 @@ use call_contract::CallContract; use client::BlockInfo; use engines::Engine; -use error::Error; -use types::header::Header; +use types::{ + header::Header, + errors::EthcoreError as Error +}; use super::{verification, Verifier}; /// A no-op verifier -- this will verify everything it's given immediately. diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 0ac0b4f34..270a817bc 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -17,11 +17,14 @@ //! Definition of valid items for the verification queue. use engines::Engine; -use error::Error; use parity_util_mem::MallocSizeOf; use ethereum_types::{H256, U256}; +use types::{ + errors::EthcoreError as Error, +}; + pub use self::blocks::Blocks; pub use self::headers::Headers; @@ -69,10 +72,13 @@ pub mod blocks { use super::{Kind, BlockLike}; use engines::Engine; - use error::{Error, BlockError}; - use types::header::Header; - use verification::{PreverifiedBlock, verify_block_basic, verify_block_unordered}; - use types::transaction::UnverifiedTransaction; + use types::{ + block::PreverifiedBlock, + header::Header, + errors::{EthcoreError as Error, BlockError}, + transaction::UnverifiedTransaction + }; + use verification::{verify_block_basic, verify_block_unordered}; use parity_util_mem::MallocSizeOf; use ethereum_types::{H256, U256}; @@ -180,8 +186,10 @@ pub mod headers { use super::{Kind, BlockLike}; use engines::Engine; - use error::Error; - use types::header::Header; + use types::{ + header::Header, + errors::EthcoreError as Error, + }; use verification::verify_header_params; use ethereum_types::{H256, U256}; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 21e9f92ef..94bc49437 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -26,10 +26,10 @@ use parity_util_mem::{MallocSizeOf, MallocSizeOfExt}; use ethereum_types::{H256, U256}; use parking_lot::{Condvar, Mutex, RwLock}; use io::*; -use error::{BlockError, ImportError, Error}; use engines::Engine; use client::ClientIoMessage; use len_caching_lock::LenCachingMutex; +use types::errors::{BlockError, EthcoreError as Error, ImportError}; use self::kind::{BlockLike, Kind}; @@ -738,10 +738,12 @@ mod tests { use super::{BlockQueue, Config, State}; use super::kind::blocks::Unverified; use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block}; - use error::*; use bytes::Bytes; - use types::view; - use types::views::BlockView; + use types::{ + view, + views::BlockView, + errors::{EthcoreError, ImportError}, + }; // create a test block queue. // auto_scaling enables verifier adjustment. @@ -792,7 +794,7 @@ mod tests { match duplicate_import { Err((_, e)) => { match e { - Error::Import(ImportError::AlreadyQueued) => {}, + EthcoreError::Import(ImportError::AlreadyQueued) => {}, _ => { panic!("must return AlreadyQueued error"); } } } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 664926374..434f23982 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -24,9 +24,7 @@ use std::collections::HashSet; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use bytes::Bytes; use hash::keccak; -use parity_util_mem::MallocSizeOf; use rlp::Rlp; use triehash::ordered_trie_root; use unexpected::{Mismatch, OutOfBounds}; @@ -34,27 +32,18 @@ use unexpected::{Mismatch, OutOfBounds}; use blockchain::*; use call_contract::CallContract; use client::BlockInfo; -use engines::{Engine, MAX_UNCLE_AGE}; -use error::{BlockError, Error}; -use types::{BlockNumber, header::Header}; -use types::transaction::SignedTransaction; +use engines::Engine; +use types::{ + BlockNumber, + header::Header, + errors::{EthcoreError as Error, BlockError}, + engines::MAX_UNCLE_AGE, + block::PreverifiedBlock, +}; use verification::queue::kind::blocks::Unverified; use time_utils::CheckedSystemTime; -/// Preprocessed block data gathered in `verify_block_unordered` call -#[derive(MallocSizeOf)] -pub struct PreverifiedBlock { - /// Populated block header - pub header: Header, - /// Populated block transactions - pub transactions: Vec, - /// Populated block uncles - pub uncles: Vec
, - /// Block bytes - pub bytes: Bytes, -} - /// Phase 1 quick block verification. Only does checks that are cheap. Operates on a single block pub fn verify_block_basic(block: &Unverified, engine: &dyn Engine, check_seal: bool) -> Result<(), Error> { verify_header_params(&block.header, engine, true, check_seal)?; @@ -281,7 +270,7 @@ pub fn verify_header_params(header: &Header, engine: &dyn Engine, is_full: bool, } if let Some(limit) = engine.maximum_gas_limit() { if header.gas_limit() > &limit { - return Err(From::from(::error::BlockError::InvalidGasLimit(OutOfBounds { min: None, max: Some(limit), found: *header.gas_limit() }))); + return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: None, max: Some(limit), found: *header.gas_limit() }))); } } let maximum_extra_data_size = engine.maximum_extra_data_size(); @@ -379,15 +368,19 @@ mod tests { use std::time::{SystemTime, UNIX_EPOCH}; use ethereum_types::{H256, BloomRef, U256, Address}; use blockchain::{BlockDetails, TransactionAddress, BlockReceipts}; - use types::encoded; + use bytes::Bytes; use hash::keccak; use engines::Engine; - use error::BlockError::*; use ethkey::{Random, Generator}; - use spec::{CommonParams, Spec}; + use spec::Spec; use test_helpers::{create_test_block_with_data, create_test_block}; - use types::transaction::{SignedTransaction, Transaction, UnverifiedTransaction, Action}; - use types::log_entry::{LogEntry, LocalizedLogEntry}; + use types::{ + encoded, + engines::params::CommonParams, + errors::BlockError::*, + transaction::{SignedTransaction, Transaction, UnverifiedTransaction, Action}, + log_entry::{LogEntry, LocalizedLogEntry}, + }; use rlp; use triehash::ordered_trie_root; diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index b5c2782a6..2ca855fe4 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -19,8 +19,10 @@ use call_contract::CallContract; use client::BlockInfo; use engines::Engine; -use error::Error; -use types::header::Header; +use types::{ + header::Header, + errors::EthcoreError as Error, +}; use super::verification; /// Should be used to verify blocks. diff --git a/ethcore/state-db/Cargo.toml b/ethcore/state-db/Cargo.toml index 2742522db..547c398db 100644 --- a/ethcore/state-db/Cargo.toml +++ b/ethcore/state-db/Cargo.toml @@ -1,9 +1,9 @@ [package] -description = "State database" name = "state-db" -version = "0.1.0" +description = "State database" authors = ["Parity Technologies "] license = "GPL-3.0" +version = "0.1.0" edition = "2018" [dependencies] diff --git a/ethcore/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs index 074a25494..1d04c1c6d 100644 --- a/ethcore/sync/src/block_sync.rs +++ b/ethcore/sync/src/block_sync.rs @@ -23,9 +23,11 @@ use std::cmp; use parity_util_mem::MallocSizeOf; use ethereum_types::H256; use rlp::{self, Rlp}; -use types::BlockNumber; +use types::{ + BlockNumber, + errors::{EthcoreError, BlockError, ImportError}, +}; use ethcore::client::{BlockStatus, BlockId}; -use ethcore::error::{ImportError, BlockError, Error as EthcoreError}; use sync_io::SyncIo; use blocks::{BlockCollection, SyncBody, SyncHeader}; use chain::BlockSet; diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index 6c5f024a5..15fd65e0f 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -18,7 +18,6 @@ use api::WARP_SYNC_PROTOCOL_ID; use block_sync::{BlockDownloaderImportError as DownloaderImportError, DownloadAction}; use bytes::Bytes; use enum_primitive::FromPrimitive; -use ethcore::error::{Error as EthcoreError, ImportError, BlockError}; use ethcore::snapshot::{ManifestData, RestorationStatus}; use ethcore::verification::queue::kind::blocks::Unverified; use ethereum_types::{H256, U256}; @@ -30,9 +29,12 @@ use snapshot::ChunkType; use std::time::Instant; use std::{mem, cmp}; use sync_io::SyncIo; -use types::BlockNumber; -use types::block_status::BlockStatus; -use types::ids::BlockId; +use types::{ + BlockNumber, + block_status::BlockStatus, + ids::BlockId, + errors::{EthcoreError, ImportError, BlockError}, +}; use super::sync_packet::{PacketInfo, SyncPacket}; use super::sync_packet::SyncPacket::{ diff --git a/ethcore/sync/src/light_sync/mod.rs b/ethcore/sync/src/light_sync/mod.rs index c7057c1f0..20cfdd9f1 100644 --- a/ethcore/sync/src/light_sync/mod.rs +++ b/ethcore/sync/src/light_sync/mod.rs @@ -493,7 +493,7 @@ impl LightSync { // handles request dispatch, block import, state machine transitions, and timeouts. fn maintain_sync(&self, ctx: &dyn BasicContext) { - use ethcore::error::{Error as EthcoreError, ImportError}; + use types::errors::{EthcoreError, ImportError}; const DRAIN_AMOUNT: usize = 128; diff --git a/ethcore/trace/Cargo.toml b/ethcore/trace/Cargo.toml index d6575fb35..af0f9f21a 100644 --- a/ethcore/trace/Cargo.toml +++ b/ethcore/trace/Cargo.toml @@ -1,8 +1,9 @@ [package] -description = "Transaction tracing" name = "trace" +description = "Transaction tracing" version = "0.1.0" authors = ["Parity Technologies "] +license = "GPL-3.0" edition = "2018" [dependencies] diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index 083205d71..f80a9c414 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -5,15 +5,21 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] +derive_more = "0.15.0" +ethbloom = "0.6" +ethcore-io = { path = "../../util/io" } ethereum-types = "0.6.0" ethjson = { path = "../../json" } -parity-util-mem = "0.1" ethkey = { path = "../../accounts/ethkey" } keccak-hash = "0.2.0" parity-bytes = "0.1" +parity-util-mem = "0.1" +parity-snappy = "0.1" +patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } rlp = "0.4.0" rlp_derive = { path = "../../util/rlp-derive" } unexpected = { path = "../../util/unexpected" } +vm = { path = "../vm"} [dev-dependencies] -rustc-hex= "1.0" +rustc-hex= "1.0" # todo: only needed for CommonParams to do from_hex on a const. Remove? diff --git a/ethcore/types/src/block.rs b/ethcore/types/src/block.rs index a423fb1ed..e110fc7dc 100644 --- a/ethcore/types/src/block.rs +++ b/ethcore/types/src/block.rs @@ -18,24 +18,14 @@ //! //! Blocks can be produced by a local node or they may be received from the network. //! -//! To create a block locally, we start with an `OpenBlock`. This block is mutable -//! and can be appended to with transactions and uncles. -//! -//! When ready, `OpenBlock` can be closed and turned into a `ClosedBlock`. A `ClosedBlock` can -//! be reopend again by a miner under certain circumstances. On block close, state commit is -//! performed. -//! -//! `LockedBlock` is a version of a `ClosedBlock` that cannot be reopened. It can be sealed -//! using an engine. -//! -//! `ExecutedBlock` is an underlaying data structure used by all structs above to store block -//! related info. +//! Other block types are found in `ethcore` use bytes::Bytes; +use parity_util_mem::MallocSizeOf; use header::Header; use rlp::{Rlp, RlpStream, Decodable, DecoderError}; -use transaction::UnverifiedTransaction; +use transaction::{UnverifiedTransaction, SignedTransaction}; /// A block, encoded as it is on the block chain. #[derive(Default, Debug, Clone, PartialEq)] @@ -74,3 +64,16 @@ impl Decodable for Block { }) } } + +/// Preprocessed block data gathered in `verify_block_unordered` call +#[derive(MallocSizeOf)] +pub struct PreverifiedBlock { + /// Populated block header + pub header: Header, + /// Populated block transactions + pub transactions: Vec, + /// Populated block uncles + pub uncles: Vec
, + /// Block bytes + pub bytes: Bytes, +} diff --git a/ethcore/types/src/blockchain_info.rs b/ethcore/types/src/blockchain_info.rs index 42158638d..c303775b9 100644 --- a/ethcore/types/src/blockchain_info.rs +++ b/ethcore/types/src/blockchain_info.rs @@ -20,7 +20,7 @@ use std::fmt; use ethereum_types::{U256, H256}; use security_level::SecurityLevel; -use {BlockNumber}; +use BlockNumber; /// Information about the blockchain gathered together. #[derive(Clone, Debug)] diff --git a/ethcore/types/src/engines/epoch.rs b/ethcore/types/src/engines/epoch.rs index 2a43b4775..7b7c027c8 100644 --- a/ethcore/types/src/engines/epoch.rs +++ b/ethcore/types/src/engines/epoch.rs @@ -17,7 +17,6 @@ //! Epoch verifiers and transitions. use ethereum_types::H256; - use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; /// A full epoch transition. @@ -70,4 +69,3 @@ impl Decodable for PendingTransition { }) } } - diff --git a/ethcore/types/src/engines/machine.rs b/ethcore/types/src/engines/machine.rs new file mode 100644 index 000000000..be0a5ef9c --- /dev/null +++ b/ethcore/types/src/engines/machine.rs @@ -0,0 +1,46 @@ +// 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 . + +//! State machine types + +use ethereum_types::Address; + +use crate::receipt; + +/// Type alias for a function we can make calls through synchronously. +/// Returns the call result and state proof for each call. +pub type Call<'a> = dyn Fn(Address, Vec) -> Result<(Vec, Vec>), String> + 'a; + +/// Request for auxiliary data of a block. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum AuxiliaryRequest { + /// Needs the body. + Body, + /// Needs the receipts. + Receipts, + /// Needs both body and receipts. + Both, +} + +/// Auxiliary data fetcher for an Ethereum machine. In Ethereum-like machines +/// there are two kinds of auxiliary data: bodies and receipts. +#[derive(Default, Clone)] +pub struct AuxiliaryData<'a> { + /// The full block bytes, including the header. + pub bytes: Option<&'a [u8]>, + /// The block receipts. + pub receipts: Option<&'a [receipt::Receipt]>, +} diff --git a/ethcore/types/src/engines/mod.rs b/ethcore/types/src/engines/mod.rs index cc622bbe6..ac8a20d29 100644 --- a/ethcore/types/src/engines/mod.rs +++ b/ethcore/types/src/engines/mod.rs @@ -16,7 +16,52 @@ //! Engine-specific types. +use ethereum_types::{Address, H256}; +use ethjson; + +use crate::BlockNumber; + pub mod epoch; +pub mod params; +pub mod machine; + +/// The type of sealing the engine is currently able to perform. +#[derive(Debug, PartialEq, Eq)] +pub enum SealingState { + /// The engine is ready to seal a block. + Ready, + /// The engine can't seal at the moment, and no block should be prepared and queued. + NotReady, + /// The engine does not seal internally. + External, +} + +/// The number of generations back that uncles can be. +pub const MAX_UNCLE_AGE: usize = 6; + +/// Default EIP-210 contract code. +/// As defined in https://github.com/ethereum/EIPs/pull/210 +pub const DEFAULT_BLOCKHASH_CONTRACT: &'static [u8] = &[ + 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x33, 0x14, 0x15, 0x61, 0x00, 0x6a, 0x57, 0x60, 0x01, 0x43, 0x03, + 0x60, 0x00, 0x35, 0x61, 0x01, 0x00, 0x82, 0x07, 0x55, 0x61, 0x01, 0x00, 0x81, 0x07, 0x15, 0x15, + 0x61, 0x00, 0x45, 0x57, 0x60, 0x00, 0x35, 0x61, 0x01, 0x00, 0x61, 0x01, 0x00, 0x83, 0x05, 0x07, + 0x61, 0x01, 0x00, 0x01, 0x55, 0x5b, 0x62, 0x01, 0x00, 0x00, 0x81, 0x07, 0x15, 0x15, 0x61, 0x00, + 0x64, 0x57, 0x60, 0x00, 0x35, 0x61, 0x01, 0x00, 0x62, 0x01, 0x00, 0x00, 0x83, 0x05, 0x07, 0x61, + 0x02, 0x00, 0x01, 0x55, 0x5b, 0x50, 0x61, 0x01, 0x3e, 0x56, 0x5b, 0x43, 0x60, 0x00, 0x35, 0x12, + 0x15, 0x15, 0x61, 0x00, 0x84, 0x57, 0x60, 0x00, 0x60, 0x40, 0x52, 0x60, 0x20, 0x60, 0x40, 0xf3, + 0x61, 0x01, 0x3d, 0x56, 0x5b, 0x61, 0x01, 0x00, 0x60, 0x00, 0x35, 0x43, 0x03, 0x13, 0x15, 0x15, + 0x61, 0x00, 0xa8, 0x57, 0x61, 0x01, 0x00, 0x60, 0x00, 0x35, 0x07, 0x54, 0x60, 0x60, 0x52, 0x60, + 0x20, 0x60, 0x60, 0xf3, 0x61, 0x01, 0x3c, 0x56, 0x5b, 0x61, 0x01, 0x00, 0x60, 0x00, 0x35, 0x07, + 0x15, 0x15, 0x61, 0x00, 0xc5, 0x57, 0x62, 0x01, 0x00, 0x00, 0x60, 0x00, 0x35, 0x43, 0x03, 0x13, + 0x15, 0x61, 0x00, 0xc8, 0x56, 0x5b, 0x60, 0x00, 0x5b, 0x15, 0x61, 0x00, 0xea, 0x57, 0x61, 0x01, + 0x00, 0x61, 0x01, 0x00, 0x60, 0x00, 0x35, 0x05, 0x07, 0x61, 0x01, 0x00, 0x01, 0x54, 0x60, 0x80, + 0x52, 0x60, 0x20, 0x60, 0x80, 0xf3, 0x61, 0x01, 0x3b, 0x56, 0x5b, 0x62, 0x01, 0x00, 0x00, 0x60, + 0x00, 0x35, 0x07, 0x15, 0x15, 0x61, 0x01, 0x09, 0x57, 0x63, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, + 0x35, 0x43, 0x03, 0x13, 0x15, 0x61, 0x01, 0x0c, 0x56, 0x5b, 0x60, 0x00, 0x5b, 0x15, 0x61, 0x01, + 0x2f, 0x57, 0x61, 0x01, 0x00, 0x62, 0x01, 0x00, 0x00, 0x60, 0x00, 0x35, 0x05, 0x07, 0x61, 0x02, + 0x00, 0x01, 0x54, 0x60, 0xa0, 0x52, 0x60, 0x20, 0x60, 0xa0, 0xf3, 0x61, 0x01, 0x3a, 0x56, 0x5b, + 0x60, 0x00, 0x60, 0xc0, 0x52, 0x60, 0x20, 0x60, 0xc0, 0xf3, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b]; /// Fork choice. #[derive(Debug, PartialEq, Eq)] @@ -26,3 +71,33 @@ pub enum ForkChoice { /// Choose the current best block. Old, } + +/// Ethash-specific extensions. +#[derive(Debug, Clone)] +pub struct EthashExtensions { + /// Homestead transition block number. + pub homestead_transition: BlockNumber, + /// DAO hard-fork transition block (X). + pub dao_hardfork_transition: u64, + /// DAO hard-fork refund contract address (C). + pub dao_hardfork_beneficiary: Address, + /// DAO hard-fork DAO accounts list (L) + pub dao_hardfork_accounts: Vec
, +} + +impl From for EthashExtensions { + fn from(p: ::ethjson::spec::EthashParams) -> Self { + EthashExtensions { + homestead_transition: p.homestead_transition.map_or(0, Into::into), + dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into), + dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::zero, Into::into), + dao_hardfork_accounts: p.dao_hardfork_accounts.unwrap_or_else(Vec::new).into_iter().map(Into::into).collect(), + } + } +} + +/// Type alias for a function we can get headers by hash through. +pub type Headers<'a, H> = dyn Fn(H256) -> Option + 'a; + +/// Type alias for a function we can query pending transitions by block hash through. +pub type PendingTransitionStore<'a> = dyn Fn(H256) -> Option + 'a; diff --git a/ethcore/types/src/engines/params.rs b/ethcore/types/src/engines/params.rs new file mode 100644 index 000000000..f3995adaa --- /dev/null +++ b/ethcore/types/src/engines/params.rs @@ -0,0 +1,310 @@ +// 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 . + +//! Engine-specific parameter types. + +use ethereum_types::{Address, U256, H256}; +use bytes::Bytes; +use ethjson; + +use BlockNumber; +use engines::DEFAULT_BLOCKHASH_CONTRACT; + +const MAX_TRANSACTION_SIZE: usize = 300 * 1024; + +/// Parameters common to ethereum-like blockchains. +/// NOTE: when adding bugfix hard-fork parameters, +/// add to `nonzero_bugfix_hard_fork` +/// +/// we define a "bugfix" hard fork as any hard fork which +/// you would put on-by-default in a new chain. +// NOTE [dvdplm]: `Clone` is needed only for tests. +#[derive(Debug, PartialEq, Default, Clone)] +pub struct CommonParams { + /// Account start nonce. + pub account_start_nonce: U256, + /// Maximum size of extra data. + pub maximum_extra_data_size: usize, + /// Network id. + pub network_id: u64, + /// Chain id. + pub chain_id: u64, + /// Main subprotocol name. + pub subprotocol_name: String, + /// Minimum gas limit. + pub min_gas_limit: U256, + /// Fork block to check. + pub fork_block: Option<(BlockNumber, H256)>, + /// EIP150 transition block number. + pub eip150_transition: BlockNumber, + /// Number of first block where EIP-160 rules begin. + pub eip160_transition: BlockNumber, + /// Number of first block where EIP-161.abc begin. + pub eip161abc_transition: BlockNumber, + /// Number of first block where EIP-161.d begins. + pub eip161d_transition: BlockNumber, + /// Number of first block where EIP-98 rules begin. + pub eip98_transition: BlockNumber, + /// Number of first block where EIP-658 rules begin. + pub eip658_transition: BlockNumber, + /// Number of first block where EIP-155 rules begin. + pub eip155_transition: BlockNumber, + /// Validate block receipts root. + pub validate_receipts_transition: BlockNumber, + /// Validate transaction chain id. + pub validate_chain_id_transition: BlockNumber, + /// Number of first block where EIP-140 rules begin. + pub eip140_transition: BlockNumber, + /// Number of first block where EIP-210 rules begin. + pub eip210_transition: BlockNumber, + /// EIP-210 Blockhash contract address. + pub eip210_contract_address: Address, + /// EIP-210 Blockhash contract code. + pub eip210_contract_code: Bytes, + /// Gas allocated for EIP-210 blockhash update. + pub eip210_contract_gas: U256, + /// Number of first block where EIP-211 rules begin. + pub eip211_transition: BlockNumber, + /// Number of first block where EIP-214 rules begin. + pub eip214_transition: BlockNumber, + /// Number of first block where EIP-145 rules begin. + pub eip145_transition: BlockNumber, + /// Number of first block where EIP-1052 rules begin. + pub eip1052_transition: BlockNumber, + /// Number of first block where EIP-1283 rules begin. + pub eip1283_transition: BlockNumber, + /// Number of first block where EIP-1283 rules end. + pub eip1283_disable_transition: BlockNumber, + /// Number of first block where EIP-1014 rules begin. + pub eip1014_transition: BlockNumber, + /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. + pub dust_protection_transition: BlockNumber, + /// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled. + pub nonce_cap_increment: u64, + /// Enable dust cleanup for contracts. + pub remove_dust_contracts: bool, + /// Wasm activation blocknumber, if any disabled initially. + pub wasm_activation_transition: BlockNumber, + /// Wasm account version, activated after `wasm_activation_transition`. If this field is defined, do not use code + /// prefix to determine VM to execute. + pub wasm_version: Option, + /// Number of first block where KIP-4 rules begin. Only has effect if Wasm is activated. + pub kip4_transition: BlockNumber, + /// Number of first block where KIP-6 rules begin. Only has effect if Wasm is activated. + pub kip6_transition: BlockNumber, + /// Gas limit bound divisor (how much gas limit can change per block) + pub gas_limit_bound_divisor: U256, + /// Registrar contract address. + pub registrar: Option
, + /// Node permission managing contract address. + pub node_permission_contract: Option
, + /// Maximum contract code size that can be deployed. + pub max_code_size: u64, + /// Number of first block where max code size limit is active. + pub max_code_size_transition: BlockNumber, + /// Transaction permission managing contract address. + pub transaction_permission_contract: Option
, + /// Block at which the transaction permission contract should start being used. + pub transaction_permission_contract_transition: BlockNumber, + /// Maximum size of transaction's RLP payload + pub max_transaction_size: usize, +} + +impl CommonParams { + /// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net. + pub fn schedule(&self, block_number: u64) -> vm::Schedule { + if block_number < self.eip150_transition { + vm::Schedule::new_homestead() + } else { + let max_code_size = self.max_code_size(block_number); + let mut schedule = vm::Schedule::new_post_eip150( + max_code_size as _, + block_number >= self.eip160_transition, + block_number >= self.eip161abc_transition, + block_number >= self.eip161d_transition + ); + + self.update_schedule(block_number, &mut schedule); + schedule + } + } + + /// Returns max code size at given block. + pub fn max_code_size(&self, block_number: u64) -> u64 { + if block_number >= self.max_code_size_transition { + self.max_code_size + } else { + u64::max_value() + } + } + + /// Apply common spec config parameters to the schedule. + pub fn update_schedule(&self, block_number: u64, schedule: &mut vm::Schedule) { + schedule.have_create2 = block_number >= self.eip1014_transition; + schedule.have_revert = block_number >= self.eip140_transition; + schedule.have_static_call = block_number >= self.eip214_transition; + schedule.have_return_data = block_number >= self.eip211_transition; + schedule.have_bitwise_shifting = block_number >= self.eip145_transition; + schedule.have_extcodehash = block_number >= self.eip1052_transition; + schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition); + if block_number >= self.eip210_transition { + schedule.blockhash_gas = 800; + } + if block_number >= self.dust_protection_transition { + schedule.kill_dust = match self.remove_dust_contracts { + true => vm::CleanDustMode::WithCodeAndStorage, + false => vm::CleanDustMode::BasicOnly, + }; + } + if block_number >= self.wasm_activation_transition { + let mut wasm = vm::WasmCosts::default(); + if block_number >= self.kip4_transition { + wasm.have_create2 = true; + } + if block_number >= self.kip6_transition { + wasm.have_gasleft = true; + } + schedule.wasm = Some(wasm); + if let Some(version) = self.wasm_version { + schedule.versions.insert(version, vm::VersionedSchedule::PWasm); + } + } + } + + /// Return Some if the current parameters contain a bugfix hard fork not on block 0. + pub fn nonzero_bugfix_hard_fork(&self) -> Option<&str> { + if self.eip155_transition != 0 { + return Some("eip155Transition"); + } + + if self.validate_receipts_transition != 0 { + return Some("validateReceiptsTransition"); + } + + if self.validate_chain_id_transition != 0 { + return Some("validateChainIdTransition"); + } + + None + } +} + +impl From for CommonParams { + fn from(p: ethjson::spec::Params) -> Self { + CommonParams { + account_start_nonce: p.account_start_nonce.map_or_else(U256::zero, Into::into), + maximum_extra_data_size: p.maximum_extra_data_size.into(), + network_id: p.network_id.into(), + chain_id: if let Some(n) = p.chain_id { + n.into() + } else { + p.network_id.into() + }, + subprotocol_name: p.subprotocol_name.unwrap_or_else(|| "eth".to_owned()), + min_gas_limit: p.min_gas_limit.into(), + fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { + Some((n.into(), h.into())) + } else { + None + }, + eip150_transition: p.eip150_transition.map_or(0, Into::into), + eip160_transition: p.eip160_transition.map_or(0, Into::into), + eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into), + eip161d_transition: p.eip161d_transition.map_or(0, Into::into), + eip98_transition: p.eip98_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip155_transition: p.eip155_transition.map_or(0, Into::into), + validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), + validate_chain_id_transition: p.validate_chain_id_transition.map_or(0, Into::into), + eip140_transition: p.eip140_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip210_transition: p.eip210_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip210_contract_address: p.eip210_contract_address.map_or(Address::from_low_u64_be(0xf0), Into::into), + eip210_contract_code: p.eip210_contract_code.map_or_else( + || DEFAULT_BLOCKHASH_CONTRACT.to_vec(), + Into::into, + ), + eip210_contract_gas: p.eip210_contract_gas.map_or(1000000.into(), Into::into), + eip211_transition: p.eip211_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip145_transition: p.eip145_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip214_transition: p.eip214_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip658_transition: p.eip658_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip1052_transition: p.eip1052_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip1283_transition: p.eip1283_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip1283_disable_transition: p.eip1283_disable_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + eip1014_transition: p.eip1014_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + dust_protection_transition: p.dust_protection_transition.map_or_else( + BlockNumber::max_value, + Into::into, + ), + nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), + remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false), + gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), + registrar: p.registrar.map(Into::into), + node_permission_contract: p.node_permission_contract.map(Into::into), + max_code_size: p.max_code_size.map_or(u64::max_value(), Into::into), + max_transaction_size: p.max_transaction_size.map_or(MAX_TRANSACTION_SIZE, Into::into), + max_code_size_transition: p.max_code_size_transition.map_or(0, Into::into), + transaction_permission_contract: p.transaction_permission_contract.map(Into::into), + transaction_permission_contract_transition: + p.transaction_permission_contract_transition.map_or(0, Into::into), + wasm_activation_transition: p.wasm_activation_transition.map_or_else( + BlockNumber::max_value, + Into::into + ), + wasm_version: p.wasm_version.map(Into::into), + kip4_transition: p.kip4_transition.map_or_else( + BlockNumber::max_value, + Into::into + ), + kip6_transition: p.kip6_transition.map_or_else( + BlockNumber::max_value, + Into::into + ), + } + } +} diff --git a/ethcore/src/error.rs b/ethcore/types/src/errors/block_error.rs similarity index 64% rename from ethcore/src/error.rs rename to ethcore/types/src/errors/block_error.rs index 8affe6a97..31baceff3 100644 --- a/ethcore/src/error.rs +++ b/ethcore/types/src/errors/block_error.rs @@ -1,38 +1,30 @@ // Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. +// This file is part of Parity. -// Parity Ethereum is free software: you can redistribute it and/or modify +// Parity is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// Parity Ethereum is distributed in the hope that it will be useful, +// Parity is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . +// along with Parity. If not, see . -//! General error types for use in ethcore. +use std::{ + fmt, + error, + time::SystemTime +}; -use std::{fmt, error}; -use std::time::SystemTime; - -use derive_more::{Display, From}; -use ethereum_types::{H256, U256, Address, Bloom}; -use ethkey::Error as EthkeyError; -use ethtrie::TrieError; -use rlp; -use snappy::InvalidInput; -use snapshot::Error as SnapshotError; -use types::BlockNumber; -use types::transaction::Error as TransactionError; +use ethbloom::Bloom; +use ethereum_types::{H256, U256, Address}; use unexpected::{Mismatch, OutOfBounds}; -use engines::EngineError; - -pub use executed::{ExecutionError, CallError}; +use BlockNumber; /// Errors concerning block processing. #[derive(Debug, Display, PartialEq, Clone, Eq)] @@ -165,94 +157,3 @@ pub enum ImportError { } impl error::Error for ImportError {} - -/// Ethcore Result -pub type EthcoreResult = Result; - -/// Ethcore Error -#[derive(Debug, Display, From)] -pub enum Error { - /// Error concerning block import. - #[display(fmt = "Import error: {}", _0)] - Import(ImportError), - /// Io channel queue error - #[display(fmt = "Queue is full: {}", _0)] - FullQueue(usize), - /// Io create error - #[display(fmt = "Io error: {}", _0)] - Io(::io::IoError), - /// Error concerning the Rust standard library's IO subsystem. - #[display(fmt = "Std Io error: {}", _0)] - StdIo(::std::io::Error), - /// Error concerning TrieDBs. - #[display(fmt = "Trie error: {}", _0)] - Trie(TrieError), - /// Error concerning EVM code execution. - #[display(fmt = "Execution error: {}", _0)] - Execution(ExecutionError), - /// Error concerning block processing. - #[display(fmt = "Block error: {}", _0)] - Block(BlockError), - /// Error concerning transaction processing. - #[display(fmt = "Transaction error: {}", _0)] - Transaction(TransactionError), - /// Snappy error - #[display(fmt = "Snappy error: {}", _0)] - Snappy(InvalidInput), - /// Consensus vote error. - #[display(fmt = "Engine error: {}", _0)] - Engine(EngineError), - /// Ethkey error." - #[display(fmt = "Ethkey error: {}", _0)] - Ethkey(EthkeyError), - /// RLP decoding errors - #[display(fmt = "Decoder error: {}", _0)] - Decoder(rlp::DecoderError), - /// Snapshot error. - #[display(fmt = "Snapshot error {}", _0)] - Snapshot(SnapshotError), - /// PoW hash is invalid or out of date. - #[display(fmt = "PoW hash is invalid or out of date.")] - PowHashInvalid, - /// The value of the nonce or mishash is invalid. - #[display(fmt = "The value of the nonce or mishash is invalid.")] - PowInvalid, - /// A convenient variant for String. - #[display(fmt = "{}", _0)] - Msg(String), - /// State errors - #[display(fmt = "State error ({})", _0)] - State(account_state::Error), -} - -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match self { - Error::Io(e) => Some(e), - Error::StdIo(e) => Some(e), - Error::Trie(e) => Some(e), - Error::Execution(e) => Some(e), - Error::Block(e) => Some(e), - Error::Transaction(e) => Some(e), - Error::Snappy(e) => Some(e), - Error::Engine(e) => Some(e), - Error::Ethkey(e) => Some(e), - Error::Decoder(e) => Some(e), - Error::Snapshot(e) => Some(e), - Error::State(e) => Some(e), - _ => None, - } - } -} - -impl From<&str> for Error { - fn from(s: &str) -> Self { - Error::Msg(s.into()) - } -} - -impl From> for Error where Error: From { - fn from(err: Box) -> Error { - Error::from(*err) - } -} diff --git a/ethcore/types/src/errors/engine_error.rs b/ethcore/types/src/errors/engine_error.rs new file mode 100644 index 000000000..02cdd066b --- /dev/null +++ b/ethcore/types/src/errors/engine_error.rs @@ -0,0 +1,109 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::fmt; + +use derive_more::From; +use ethereum_types::{Address, H64, H256}; +use unexpected::{Mismatch, OutOfBounds}; + +/// Voting errors. +#[derive(Debug, From)] +pub enum EngineError { + /// Signature or author field does not belong to an authority. + NotAuthorized(Address), + /// The same author issued different votes at the same step. + DoubleVote(Address), + /// The received block is from an incorrect proposer. + NotProposer(Mismatch
), + /// Message was not expected. + UnexpectedMessage, + /// Seal field has an unexpected size. + BadSealFieldSize(OutOfBounds), + /// Validation proof insufficient. + InsufficientProof(String), + /// Failed system call. + FailedSystemCall(String), + /// Malformed consensus message. + MalformedMessage(String), + /// Requires client ref, but none registered. + RequiresClient, + /// Invalid engine specification or implementation. + InvalidEngine, + /// Requires signer ref, but none registered. + RequiresSigner, + /// Missing Parent Epoch + MissingParent(H256), + /// Checkpoint is missing + CliqueMissingCheckpoint(H256), + /// Missing vanity data + CliqueMissingVanity, + /// Missing signature + CliqueMissingSignature, + /// Missing signers + CliqueCheckpointNoSigner, + /// List of signers is invalid + CliqueCheckpointInvalidSigners(usize), + /// Wrong author on a checkpoint + CliqueWrongAuthorCheckpoint(Mismatch
), + /// Wrong checkpoint authors recovered + CliqueFaultyRecoveredSigners(Vec), + /// Invalid nonce (should contain vote) + CliqueInvalidNonce(H64), + /// The signer signed a block to recently + CliqueTooRecentlySigned(Address), + /// Custom + Custom(String), +} + +impl fmt::Display for EngineError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::EngineError::*; + let msg = match *self { + CliqueMissingCheckpoint(ref hash) => format!("Missing checkpoint block: {}", hash), + CliqueMissingVanity => format!("Extra data is missing vanity data"), + CliqueMissingSignature => format!("Extra data is missing signature"), + CliqueCheckpointInvalidSigners(len) => format!("Checkpoint block list was of length: {} of checkpoint but + it needs to be bigger than zero and a divisible by 20", len), + CliqueCheckpointNoSigner => format!("Checkpoint block list of signers was empty"), + CliqueInvalidNonce(ref mis) => format!("Unexpected nonce {} expected {} or {}", mis, 0_u64, u64::max_value()), + CliqueWrongAuthorCheckpoint(ref oob) => format!("Unexpected checkpoint author: {}", oob), + CliqueFaultyRecoveredSigners(ref mis) => format!("Faulty recovered signers {:?}", mis), + CliqueTooRecentlySigned(ref address) => format!("The signer: {} has signed a block too recently", address), + Custom(ref s) => s.clone(), + DoubleVote(ref address) => format!("Author {} issued too many blocks.", address), + NotProposer(ref mis) => format!("Author is not a current proposer: {}", mis), + NotAuthorized(ref address) => format!("Signer {} is not authorized.", address), + UnexpectedMessage => "This Engine should not be fed messages.".into(), + BadSealFieldSize(ref oob) => format!("Seal field has an unexpected length: {}", oob), + InsufficientProof(ref msg) => format!("Insufficient validation proof: {}", msg), + FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg), + MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg), + RequiresClient => format!("Call requires client but none registered"), + RequiresSigner => format!("Call requires signer but none registered"), + InvalidEngine => format!("Invalid engine specification or implementation"), + MissingParent(ref hash) => format!("Parent Epoch is missing from database: {}", hash), + }; + + f.write_fmt(format_args!("Engine error ({})", msg)) + } +} + +impl std::error::Error for EngineError { + fn description(&self) -> &str { + "Engine error" + } +} diff --git a/ethcore/types/src/errors/ethcore_error.rs b/ethcore/types/src/errors/ethcore_error.rs new file mode 100644 index 000000000..f7b5abc9e --- /dev/null +++ b/ethcore/types/src/errors/ethcore_error.rs @@ -0,0 +1,205 @@ +// 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 . + +//! General error types for use in ethcore. + +use std::{error, fmt}; +use derive_more::{Display, From}; +use ethereum_types::{U256, U512}; +use ethtrie::TrieError; +use parity_snappy::InvalidInput; +use ethkey::Error as EthkeyError; + +use errors::{BlockError, EngineError, ImportError, SnapshotError}; +use transaction::Error as TransactionError; + +/// Ethcore Result +pub type EthcoreResult = Result; + +/// Ethcore Error +#[derive(Debug, Display, From)] +pub enum EthcoreError { + /// Error concerning block import. + #[display(fmt = "Import error: {}", _0)] + Import(ImportError), + /// Io channel queue error + #[display(fmt = "Queue is full: {}", _0)] + FullQueue(usize), + /// Io create error + #[display(fmt = "Io error: {}", _0)] + Io(ethcore_io::IoError), + /// Error concerning the Rust standard library's IO subsystem. + #[display(fmt = "Std Io error: {}", _0)] + StdIo(::std::io::Error), + /// Error concerning TrieDBs. + #[display(fmt = "Trie error: {}", _0)] + Trie(TrieError), + /// Error concerning EVM code execution. + #[display(fmt = "Execution error: {}", _0)] + Execution(ExecutionError), + /// Error concerning block processing. + #[display(fmt = "Block error: {}", _0)] + Block(BlockError), + /// Error concerning transaction processing. + #[display(fmt = "Transaction error: {}", _0)] + Transaction(TransactionError), + /// Snappy error + #[display(fmt = "Snappy error: {}", _0)] + Snappy(InvalidInput), + /// Consensus vote error. + #[display(fmt = "Engine error: {}", _0)] + Engine(EngineError), + /// Ethkey error." + #[display(fmt = "Ethkey error: {}", _0)] + Ethkey(EthkeyError), + /// RLP decoding errors + #[display(fmt = "Decoder error: {}", _0)] + Decoder(rlp::DecoderError), + /// Snapshot error. + #[display(fmt = "Snapshot error {}", _0)] + Snapshot(SnapshotError), + /// PoW hash is invalid or out of date. + #[display(fmt = "PoW hash is invalid or out of date.")] + PowHashInvalid, + /// The value of the nonce or mishash is invalid. + #[display(fmt = "The value of the nonce or mishash is invalid.")] + PowInvalid, + /// A convenient variant for String. + #[display(fmt = "{}", _0)] + Msg(String), +} + +impl error::Error for EthcoreError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + use self::EthcoreError::*; + match self { + Io(e) => Some(e), + StdIo(e) => Some(e), + Trie(e) => Some(e), + Execution(e) => Some(e), + Block(e) => Some(e), + Transaction(e) => Some(e), + Snappy(e) => Some(e), + Engine(e) => Some(e), + Ethkey(e) => Some(e), + Decoder(e) => Some(e), + Snapshot(e) => Some(e), + _ => None, + } + } +} + +impl From<&str> for EthcoreError { + fn from(s: &str) -> Self { + EthcoreError::Msg(s.into()) + } +} + +impl From> for EthcoreError where EthcoreError: From { + fn from(err: Box) -> EthcoreError { + EthcoreError::from(*err) + } +} + +/// Error type for executing a transaction. +#[derive(PartialEq, Debug, Clone)] +pub enum ExecutionError { + /// Returned when there gas paid for transaction execution is + /// lower than base gas required. + NotEnoughBaseGas { + /// Absolute minimum gas required. + required: U256, + /// Gas provided. + got: U256 + }, + /// Returned when block (gas_used + gas) > gas_limit. + /// + /// If gas =< gas_limit, upstream may try to execute the transaction + /// in next block. + BlockGasLimitReached { + /// Gas limit of block for transaction. + gas_limit: U256, + /// Gas used in block prior to transaction. + gas_used: U256, + /// Amount of gas in block. + gas: U256 + }, + /// Returned when transaction nonce does not match state nonce. + InvalidNonce { + /// Nonce expected. + expected: U256, + /// Nonce found. + got: U256 + }, + /// Returned when cost of transaction (value + gas_price * gas) exceeds + /// current sender balance. + NotEnoughCash { + /// Minimum required balance. + required: U512, + /// Actual balance. + got: U512 + }, + /// When execution tries to modify the state in static context + MutableCallInStaticContext, + /// Returned when transacting from a non-existing account with dust protection enabled. + SenderMustExist, + /// Returned when internal evm error occurs. + Internal(String), + /// Returned when generic transaction occurs + TransactionMalformed(String), +} + +impl error::Error for ExecutionError { + fn description(&self) -> &str { + "Transaction execution error" + } +} + +impl From> for ExecutionError { + fn from(err: Box) -> Self { + ExecutionError::Internal(format!("{:?}", err)) + } +} +impl From for ExecutionError { + fn from(err: TrieError) -> Self { + ExecutionError::Internal(format!("{:?}", err)) + } +} + +impl fmt::Display for ExecutionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::ExecutionError::*; + + let msg = match *self { + NotEnoughBaseGas { ref required, ref got } => + format!("Not enough base gas. {} is required, but only {} paid", required, got), + BlockGasLimitReached { ref gas_limit, ref gas_used, ref gas } => + format!("Block gas limit reached. The limit is {}, {} has \ + already been used, and {} more is required", gas_limit, gas_used, gas), + InvalidNonce { ref expected, ref got } => + format!("Invalid transaction nonce: expected {}, found {}", expected, got), + NotEnoughCash { ref required, ref got } => + format!("Cost of transaction exceeds sender balance. {} is required \ + but the sender only has {}", required, got), + MutableCallInStaticContext => "Mutable Call in static context".to_owned(), + SenderMustExist => "Transacting from an empty account".to_owned(), + Internal(ref msg) => msg.clone(), + TransactionMalformed(ref err) => format!("Malformed transaction: {}", err), + }; + + f.write_fmt(format_args!("Transaction execution error ({}).", msg)) + } +} diff --git a/ethcore/account-state/src/error.rs b/ethcore/types/src/errors/mod.rs similarity index 68% rename from ethcore/account-state/src/error.rs rename to ethcore/types/src/errors/mod.rs index 0a2911f79..ad31f5543 100644 --- a/ethcore/account-state/src/error.rs +++ b/ethcore/types/src/errors/mod.rs @@ -14,22 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//! State related errors +//! General error types for use in parity-ethereum. -use derive_more::{Display, From}; +mod block_error; +mod engine_error; +mod ethcore_error; +mod snapshot_error; -#[derive(Debug, Display, From)] -pub enum Error { - /// Trie error. - Trie(ethtrie::TrieError), - /// Decoder error. - Decoder(rlp::DecoderError), -} - -impl std::error::Error for Error {} - -impl From> for Error where Error: From { - fn from(err: Box) -> Self { - Error::from(*err) - } -} +pub use self::{ + block_error::{BlockError, ImportError}, + engine_error::EngineError, + ethcore_error::{EthcoreError, ExecutionError, EthcoreResult}, + snapshot_error::SnapshotError, +}; diff --git a/ethcore/src/snapshot/error.rs b/ethcore/types/src/errors/snapshot_error.rs similarity index 54% rename from ethcore/src/snapshot/error.rs rename to ethcore/types/src/errors/snapshot_error.rs index 68742e2e1..ae4048fd2 100644 --- a/ethcore/src/snapshot/error.rs +++ b/ethcore/types/src/errors/snapshot_error.rs @@ -19,15 +19,15 @@ use std::error; use std::fmt; -use types::ids::BlockId; - use ethereum_types::H256; use ethtrie::TrieError; use rlp::DecoderError; +use ids::BlockId; + /// Snapshot-related errors. #[derive(Debug)] -pub enum Error { +pub enum SnapshotError { /// Invalid starting block for snapshot. InvalidStartingBlock(BlockId), /// Block not found. @@ -72,67 +72,69 @@ pub enum Error { UnlinkedAncientBlockChain(H256), } -impl error::Error for Error { +impl error::Error for SnapshotError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { + use self::SnapshotError::*; match self { - Error::Trie(e) => Some(e), - Error::Decoder(e) => Some(e), - Error::Io(e) => Some(e), + Trie(e) => Some(e), + Decoder(e) => Some(e), + Io(e) => Some(e), _ => None, } } } -impl fmt::Display for Error { +impl fmt::Display for SnapshotError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::SnapshotError::*; match *self { - Error::InvalidStartingBlock(ref id) => write!(f, "Invalid starting block: {:?}", id), - Error::BlockNotFound(ref hash) => write!(f, "Block not found in chain: {}", hash), - Error::IncompleteChain => write!(f, "Incomplete blockchain."), - Error::WrongStateRoot(ref expected, ref found) => write!(f, "Final block has wrong state root. Expected {:?}, got {:?}", expected, found), - Error::WrongBlockHash(ref num, ref expected, ref found) => + InvalidStartingBlock(ref id) => write!(f, "Invalid starting block: {:?}", id), + BlockNotFound(ref hash) => write!(f, "Block not found in chain: {}", hash), + IncompleteChain => write!(f, "Incomplete blockchain."), + WrongStateRoot(ref expected, ref found) => write!(f, "Final block has wrong state root. Expected {:?}, got {:?}", expected, found), + WrongBlockHash(ref num, ref expected, ref found) => write!(f, "Block {} had wrong hash. expected {:?}, got {:?}", num, expected, found), - Error::TooManyBlocks(ref expected, ref found) => write!(f, "Snapshot contained too many blocks. Expected {}, got {}", expected, found), - Error::OldBlockPrunedDB => write!(f, "Attempted to create a snapshot at an old block while using \ + TooManyBlocks(ref expected, ref found) => write!(f, "Snapshot contained too many blocks. Expected {}, got {}", expected, found), + OldBlockPrunedDB => write!(f, "Attempted to create a snapshot at an old block while using \ a pruned database. Please re-run with the --pruning archive flag."), - Error::MissingCode(ref missing) => write!(f, "Incomplete snapshot: {} contract codes not found.", missing.len()), - Error::UnrecognizedCodeState(state) => write!(f, "Unrecognized code encoding ({})", state), - Error::RestorationAborted => write!(f, "Snapshot restoration aborted."), - Error::Io(ref err) => err.fmt(f), - Error::Decoder(ref err) => err.fmt(f), - Error::Trie(ref err) => err.fmt(f), - Error::VersionNotSupported(ref ver) => write!(f, "Snapshot version {} is not supprted.", ver), - Error::ChunkTooSmall => write!(f, "Chunk size is too small."), - Error::ChunkTooLarge => write!(f, "Chunk size is too large."), - Error::SnapshotsUnsupported => write!(f, "Snapshots unsupported by consensus engine."), - Error::SnapshotAborted => write!(f, "Snapshot was aborted."), - Error::BadEpochProof(i) => write!(f, "Bad epoch proof for transition to epoch {}", i), - Error::WrongChunkFormat(ref msg) => write!(f, "Wrong chunk format: {}", msg), - Error::UnlinkedAncientBlockChain(parent_hash) => write!(f, "Unlinked ancient blocks chain at parent_hash={:#x}", parent_hash), + MissingCode(ref missing) => write!(f, "Incomplete snapshot: {} contract codes not found.", missing.len()), + UnrecognizedCodeState(state) => write!(f, "Unrecognized code encoding ({})", state), + RestorationAborted => write!(f, "Snapshot restoration aborted."), + Io(ref err) => err.fmt(f), + Decoder(ref err) => err.fmt(f), + Trie(ref err) => err.fmt(f), + VersionNotSupported(ref ver) => write!(f, "Snapshot version {} is not supprted.", ver), + ChunkTooSmall => write!(f, "Chunk size is too small."), + ChunkTooLarge => write!(f, "Chunk size is too large."), + SnapshotsUnsupported => write!(f, "Snapshots unsupported by consensus engine."), + SnapshotAborted => write!(f, "Snapshot was aborted."), + BadEpochProof(i) => write!(f, "Bad epoch proof for transition to epoch {}", i), + WrongChunkFormat(ref msg) => write!(f, "Wrong chunk format: {}", msg), + UnlinkedAncientBlockChain(parent_hash) => write!(f, "Unlinked ancient blocks chain at parent_hash={:#x}", parent_hash), } } } -impl From<::std::io::Error> for Error { +impl From<::std::io::Error> for SnapshotError { fn from(err: ::std::io::Error) -> Self { - Error::Io(err) + SnapshotError::Io(err) } } -impl From for Error { +impl From for SnapshotError { fn from(err: TrieError) -> Self { - Error::Trie(err) + SnapshotError::Trie(err) } } -impl From for Error { +impl From for SnapshotError { fn from(err: DecoderError) -> Self { - Error::Decoder(err) + SnapshotError::Decoder(err) } } -impl From> for Error where Error: From { +impl From> for SnapshotError where SnapshotError: From { fn from(err: Box) -> Self { - Error::from(*err) + SnapshotError::from(*err) } } diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index f8c5087bd..d209b3d25 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -33,26 +33,30 @@ #![warn(missing_docs, unused_extern_crates)] +extern crate ethbloom; extern crate ethereum_types; extern crate ethjson; extern crate ethkey; +#[macro_use] +extern crate derive_more; extern crate keccak_hash as hash; extern crate parity_bytes as bytes; +extern crate patricia_trie_ethereum as ethtrie; extern crate rlp; +extern crate parity_snappy; extern crate unexpected; #[macro_use] extern crate rlp_derive; extern crate parity_util_mem; - extern crate parity_util_mem as malloc_size_of; -#[cfg(test)] -extern crate rustc_hex; - #[macro_use] pub mod views; +#[cfg(test)] +extern crate rustc_hex; + pub mod account_diff; pub mod ancestry_action; pub mod basic_account; @@ -62,6 +66,7 @@ pub mod blockchain_info; pub mod call_analytics; pub mod encoded; pub mod engines; +pub mod errors; pub mod filter; pub mod header; pub mod ids; diff --git a/ethcore/types/src/transaction/error.rs b/ethcore/types/src/transaction/error.rs index 60da33eaf..a563347ce 100644 --- a/ethcore/types/src/transaction/error.rs +++ b/ethcore/types/src/transaction/error.rs @@ -21,6 +21,8 @@ use ethkey; use rlp; use unexpected::OutOfBounds; +use errors::ExecutionError; + #[derive(Debug, PartialEq, Clone)] /// Errors concerning transaction processing. pub enum Error { @@ -130,3 +132,40 @@ impl error::Error for Error { "Transaction error" } } + +/// Result of executing the transaction. +#[derive(PartialEq, Debug, Clone)] +pub enum CallError { + /// Couldn't find the transaction in the chain. + TransactionNotFound, + /// Couldn't find requested block's state in the chain. + StatePruned, + /// Couldn't find an amount of gas that didn't result in an exception. + Exceptional(vm::Error), + /// Corrupt state. + StateCorrupt, + /// Error executing. + Execution(ExecutionError), +} + +impl From for CallError { + fn from(error: ExecutionError) -> Self { + CallError::Execution(error) + } +} + +impl fmt::Display for CallError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::CallError::*; + let msg = match *self { + TransactionNotFound => "Transaction couldn't be found in the chain".into(), + StatePruned => "Couldn't find the transaction block's state in the chain".into(), + Exceptional(ref e) => format!("An exception ({}) happened in the execution", e), + StateCorrupt => "Stored state found to be corrupted.".into(), + Execution(ref e) => format!("{}", e), + }; + + f.write_fmt(format_args!("Transaction execution error ({}).", msg)) + } +} + diff --git a/ethcore/types/src/transaction/mod.rs b/ethcore/types/src/transaction/mod.rs index 4b26b7dc1..f27f1f0cf 100644 --- a/ethcore/types/src/transaction/mod.rs +++ b/ethcore/types/src/transaction/mod.rs @@ -19,5 +19,5 @@ mod error; mod transaction; -pub use self::error::Error; +pub use self::error::{Error, CallError}; pub use self::transaction::*; diff --git a/parity/blockchain.rs b/parity/blockchain.rs index e4b8752c5..40b3bbf31 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -20,6 +20,7 @@ use std::io::{BufReader, BufRead}; use std::time::{Instant, Duration}; use std::thread::sleep; use std::sync::Arc; + use rustc_hex::FromHex; use hash::{keccak, KECCAK_NULL_RLP}; use ethereum_types::{U256, H256, Address}; @@ -28,7 +29,6 @@ use rlp::PayloadInfo; use ethcore::client::{ Mode, DatabaseCompactionProfile, VMType, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock, BlockChainReset }; -use ethcore::error::{ImportError, Error as EthcoreError}; use ethcore::miner::Miner; use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::kind::blocks::Unverified; @@ -42,6 +42,7 @@ use user_defaults::UserDefaults; use ethcore_private_tx; use db; use ansi_term::Colour; +use types::errors::{ImportError, EthcoreError}; #[derive(Debug, PartialEq)] pub enum DataFormat { diff --git a/parity/db/rocksdb/blooms.rs b/parity/db/rocksdb/blooms.rs index eea913bea..679c4092d 100644 --- a/parity/db/rocksdb/blooms.rs +++ b/parity/db/rocksdb/blooms.rs @@ -18,7 +18,7 @@ use std::path::Path; use ethereum_types::Bloom; -use ethcore::error::Error; +use types::errors::EthcoreError as Error; use rlp; use super::kvdb_rocksdb::DatabaseConfig; use super::open_database; diff --git a/parity/db/rocksdb/migration.rs b/parity/db/rocksdb/migration.rs index eec43d233..a054f3689 100644 --- a/parity/db/rocksdb/migration.rs +++ b/parity/db/rocksdb/migration.rs @@ -21,7 +21,7 @@ use std::fmt::{Display, Formatter, Error as FmtError}; use super::migration_rocksdb::{Manager as MigrationManager, Config as MigrationConfig, ChangeColumns}; use super::kvdb_rocksdb::{CompactionProfile, DatabaseConfig}; use ethcore::client::DatabaseCompactionProfile; -use ethcore; +use types::errors::EthcoreError; use super::helpers; use super::blooms::migrate_blooms; @@ -63,7 +63,7 @@ pub enum Error { /// Migration is not possible. MigrationImpossible, /// Blooms-db migration error. - BloomsDB(ethcore::error::Error), + BloomsDB(EthcoreError), /// Migration was completed succesfully, /// but there was a problem with io. Io(IoError), diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 3365c5490..491f61d2c 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -18,7 +18,6 @@ use std::fmt; -use ethcore::error::{Error as EthcoreError, CallError}; use ethcore::client::BlockId; use jsonrpc_core::{futures, Result as RpcResult, Error, ErrorCode, Value}; use rlp::DecoderError; @@ -27,7 +26,11 @@ 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 types::blockchain_info::BlockChainInfo; +use types::{ + blockchain_info::BlockChainInfo, + errors::{EthcoreError}, + transaction::CallError, +}; use v1::types::BlockNumber; use v1::impls::EthClientOptions; diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 5c6696e43..0f5d2fbbb 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -21,12 +21,14 @@ use std::cmp; use std::collections::BTreeMap; use std::sync::Arc; -use types::basic_account::BasicAccount; -use types::encoded; -use types::filter::Filter as EthcoreFilter; -use types::ids::BlockId; -use types::receipt::Receipt; -use ethcore::executed::ExecutionError; +use types::{ + basic_account::BasicAccount, + encoded, + errors::ExecutionError, + filter::Filter as EthcoreFilter, + ids::BlockId, + receipt::Receipt, +}; use jsonrpc_core::{Result, Error}; use jsonrpc_core::futures::{future, Future}; diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index b85e3fbee..5f7d3eed4 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -23,7 +23,6 @@ use bytes::Bytes; use ethcore::block::SealedBlock; use ethcore::client::{Nonce, PrepareOpenBlock, StateClient, EngineInfo, TestState}; use ethcore::engines::{Engine, signer::EngineSigner}; -use ethcore::error::Error; use ethcore::miner::{self, MinerService, AuthoringParams, FilterOptions}; use ethereum_types::{H256, U256, Address}; use miner::pool::local_transactions::Status as LocalTransactionStatus; @@ -31,11 +30,14 @@ use miner::pool::{verifier, VerifiedTransaction, QueueStatus}; use parking_lot::{RwLock, Mutex}; use types::transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction}; use txpool; -use types::BlockNumber; -use types::block::Block; -use types::header::Header; -use types::ids::BlockId; -use types::receipt::RichReceipt; +use types::{ + BlockNumber, + block::Block, + header::Header, + errors::EthcoreError as Error, + ids::BlockId, + receipt::RichReceipt, +}; /// Test miner service. pub struct TestMinerService { diff --git a/rpc/src/v1/tests/mocked/traces.rs b/rpc/src/v1/tests/mocked/traces.rs index d6cb0399b..0f3cfd820 100644 --- a/rpc/src/v1/tests/mocked/traces.rs +++ b/rpc/src/v1/tests/mocked/traces.rs @@ -16,12 +16,13 @@ use std::sync::Arc; -use ethcore::executed::{Executed, CallError}; +use ethcore::executed::Executed; use trace::trace::{Action, Res, Call}; use trace::LocalizedTrace; use ethcore::client::TestBlockChainClient; use ethereum_types::{Address, H256}; +use types::transaction::CallError; use vm::CallType; use jsonrpc_core::IoHandler;