Extract the Engine trait (#10958)
* Add client-traits crate Move the BlockInfo trait to new crate * New crate `machine` Contains code extracted from ethcore that defines `Machine`, `Externalities` and other execution related code. * Use new machine and client-traits crates in ethcore * Use new crates machine and client-traits instead of ethcore where appropriate * Fix tests * Don't re-export so many types from ethcore::client * Fixing more fallout from removing re-export * fix test * More fallout from not re-exporting types * Add some docs * cleanup * import the macro edition style * Tweak docs * Add missing import * remove unused ethabi_derive imports * Use latest ethabi-contract * Move many traits from ethcore/client/traits to client-traits crate Initial version of extracted Engine trait * Move snapshot related traits to the engine crate (eew) * Move a few snapshot related types to common_types Cleanup Executed as exported from machine crate * fix warning * Gradually introduce new engine crate: snapshot * ethcore typechecks with new engine crate * Sort out types outside ethcore * Add an EpochVerifier to ethash and use that in Engine.epoch_verifier() Cleanup * Document pub members * Sort out tests Sort out default impls for EpochVerifier * Add test-helpers feature and move EngineSigner impl to the right place * Sort out tests * Sort out tests and refactor verification types * Fix missing traits * More missing traits Fix Histogram * Fix tests and cleanup * cleanup * Put back needed logger import * Don't rexport common_types from ethcore/src/client Don't export ethcore::client::* * Remove files no longer used Use types from the engine crate Explicit exports from engine::engine * Get rid of itertools * Move a few more traits from ethcore to client-traits: BlockChainReset, ScheduleInfo, StateClient * Move ProvingBlockChainClient to client-traits * Don't re-export ForkChoice and Transition from ethcore * Address grumbles: sort imports, remove commented out code * Fix merge resolution error * merge failure
This commit is contained in:
parent
1ba4df08f9
commit
6a9de9b11e
36
Cargo.lock
generated
36
Cargo.lock
generated
@ -418,8 +418,18 @@ dependencies = [
|
|||||||
name = "client-traits"
|
name = "client-traits"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"account-state 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
|
"ethcore-blockchain 0.1.0",
|
||||||
|
"ethcore-call-contract 0.1.0",
|
||||||
|
"ethcore-db 0.1.0",
|
||||||
|
"ethcore-miner 1.12.0",
|
||||||
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"stats 0.1.0",
|
||||||
|
"trace 0.1.0",
|
||||||
|
"vm 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -748,6 +758,23 @@ dependencies = [
|
|||||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "engine"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"client-traits 0.1.0",
|
||||||
|
"common-types 0.1.0",
|
||||||
|
"ethcore-accounts 0.1.0",
|
||||||
|
"ethcore-blockchain 0.1.0",
|
||||||
|
"ethcore-builtin 0.1.0",
|
||||||
|
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethkey 0.3.0",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"machine 0.1.0",
|
||||||
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"vm 0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum_primitive"
|
name = "enum_primitive"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -861,6 +888,7 @@ dependencies = [
|
|||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"engine 0.1.0",
|
||||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1043,6 +1071,7 @@ dependencies = [
|
|||||||
"client-traits 0.1.0",
|
"client-traits 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"engine 0.1.0",
|
||||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
@ -1238,6 +1267,7 @@ name = "ethcore-secretstore"
|
|||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"client-traits 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"env_logger 0.5.13 (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 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1314,6 +1344,7 @@ version = "1.12.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"client-traits 0.1.0",
|
"client-traits 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
|
"engine 0.1.0",
|
||||||
"enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
@ -2524,6 +2555,7 @@ dependencies = [
|
|||||||
name = "node-filter"
|
name = "node-filter"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"client-traits 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2723,6 +2755,7 @@ dependencies = [
|
|||||||
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
|
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
|
||||||
"dir 0.1.2",
|
"dir 0.1.2",
|
||||||
"docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"engine 0.1.0",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
"ethcore-accounts 0.1.0",
|
"ethcore-accounts 0.1.0",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
@ -2813,6 +2846,7 @@ name = "parity-ipfs-api"
|
|||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"client-traits 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2876,6 +2910,7 @@ dependencies = [
|
|||||||
"client-traits 0.1.0",
|
"client-traits 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"eip-712 0.1.0",
|
"eip-712 0.1.0",
|
||||||
|
"engine 0.1.0",
|
||||||
"ethash 1.12.0",
|
"ethash 1.12.0",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
"ethcore-accounts 0.1.0",
|
"ethcore-accounts 0.1.0",
|
||||||
@ -2997,6 +3032,7 @@ dependencies = [
|
|||||||
name = "parity-updater"
|
name = "parity-updater"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"client-traits 0.1.0",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi-contract 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -33,6 +33,7 @@ jsonrpc-core = "12.0.0"
|
|||||||
parity-bytes = "0.1"
|
parity-bytes = "0.1"
|
||||||
client-traits = { path = "ethcore/client-traits" }
|
client-traits = { path = "ethcore/client-traits" }
|
||||||
common-types = { path = "ethcore/types" }
|
common-types = { path = "ethcore/types" }
|
||||||
|
engine = { path = "ethcore/engine" }
|
||||||
ethcore = { path = "ethcore", features = ["parity"] }
|
ethcore = { path = "ethcore", features = ["parity"] }
|
||||||
ethcore-accounts = { path = "accounts", optional = true }
|
ethcore-accounts = { path = "accounts", optional = true }
|
||||||
ethcore-blockchain = { path = "ethcore/blockchain" }
|
ethcore-blockchain = { path = "ethcore/blockchain" }
|
||||||
|
@ -85,7 +85,7 @@ impl EthashManager {
|
|||||||
EthashManager {
|
EthashManager {
|
||||||
cache_dir: cache_dir.to_path_buf(),
|
cache_dir: cache_dir.to_path_buf(),
|
||||||
nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default(), progpow_transition),
|
nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default(), progpow_transition),
|
||||||
progpow_transition: progpow_transition,
|
progpow_transition,
|
||||||
cache: Mutex::new(LightCache {
|
cache: Mutex::new(LightCache {
|
||||||
recent_epoch: None,
|
recent_epoch: None,
|
||||||
recent: None,
|
recent: None,
|
||||||
|
@ -8,11 +8,13 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
account-db = { path = "account-db" }
|
account-db = { path = "account-db" }
|
||||||
|
account-state = { path = "account-state" }
|
||||||
ansi_term = "0.11"
|
ansi_term = "0.11"
|
||||||
blooms-db = { path = "../util/blooms-db", optional = true }
|
blooms-db = { path = "../util/blooms-db", optional = true }
|
||||||
client-traits = { path = "./client-traits" }
|
client-traits = { path = "./client-traits" }
|
||||||
common-types = { path = "types" }
|
common-types = { path = "types" }
|
||||||
crossbeam-utils = "0.6"
|
crossbeam-utils = "0.6"
|
||||||
|
engine = { path = "./engine" }
|
||||||
env_logger = { version = "0.5", optional = true }
|
env_logger = { version = "0.5", optional = true }
|
||||||
ethabi = "8.0"
|
ethabi = "8.0"
|
||||||
ethabi-contract = "8.0"
|
ethabi-contract = "8.0"
|
||||||
@ -30,7 +32,6 @@ ethereum-types = "0.6.0"
|
|||||||
ethjson = { path = "../json" }
|
ethjson = { path = "../json" }
|
||||||
ethkey = { path = "../accounts/ethkey" }
|
ethkey = { path = "../accounts/ethkey" }
|
||||||
evm = { path = "evm" }
|
evm = { path = "evm" }
|
||||||
trie-vm-factories = { path = "trie-vm-factories" }
|
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hash-db = "0.15.0"
|
hash-db = "0.15.0"
|
||||||
parity-util-mem = "0.2.0"
|
parity-util-mem = "0.2.0"
|
||||||
@ -52,42 +53,43 @@ num_cpus = "1.2"
|
|||||||
parity-bytes = "0.1"
|
parity-bytes = "0.1"
|
||||||
parity-snappy = "0.1"
|
parity-snappy = "0.1"
|
||||||
parking_lot = "0.8"
|
parking_lot = "0.8"
|
||||||
pod = { path = "pod" }
|
|
||||||
trie-db = "0.15.0"
|
trie-db = "0.15.0"
|
||||||
patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" }
|
patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" }
|
||||||
|
pod = { path = "pod" }
|
||||||
rand = "0.6"
|
rand = "0.6"
|
||||||
|
rand_xorshift = "0.1.1"
|
||||||
rayon = "1.1"
|
rayon = "1.1"
|
||||||
rlp = "0.4.0"
|
rlp = "0.4.0"
|
||||||
rlp_derive = { path = "../util/rlp-derive" }
|
rlp_derive = { path = "../util/rlp-derive" }
|
||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
account-state = { path = "account-state" }
|
|
||||||
stats = { path = "../util/stats" }
|
|
||||||
state-db = { path = "state-db" }
|
state-db = { path = "state-db" }
|
||||||
|
stats = { path = "../util/stats" }
|
||||||
tempdir = { version = "0.3", optional = true }
|
tempdir = { version = "0.3", optional = true }
|
||||||
time-utils = { path = "../util/time-utils" }
|
time-utils = { path = "../util/time-utils" }
|
||||||
trace = { path = "trace" }
|
trace = { path = "trace" }
|
||||||
trace-time = "0.1"
|
trace-time = "0.1"
|
||||||
|
trie-vm-factories = { path = "trie-vm-factories" }
|
||||||
triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" }
|
triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" }
|
||||||
unexpected = { path = "../util/unexpected" }
|
unexpected = { path = "../util/unexpected" }
|
||||||
using_queue = { path = "../miner/using-queue" }
|
using_queue = { path = "../miner/using-queue" }
|
||||||
vm = { path = "vm" }
|
vm = { path = "vm" }
|
||||||
rand_xorshift = "0.1.1"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
blooms-db = { path = "../util/blooms-db" }
|
blooms-db = { path = "../util/blooms-db" }
|
||||||
criterion = "0.2"
|
criterion = "0.2"
|
||||||
|
engine = { path = "./engine", features = ["test-helpers"] }
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
ethcore-accounts = { path = "../accounts" }
|
ethcore-accounts = { path = "../accounts" }
|
||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
kvdb-rocksdb = "0.1.3"
|
kvdb-rocksdb = "0.1.3"
|
||||||
|
machine = { path = "./machine", features = ["test-helpers"] }
|
||||||
parity-runtime = { path = "../util/runtime" }
|
parity-runtime = { path = "../util/runtime" }
|
||||||
rlp_compress = { path = "../util/rlp-compress" }
|
rlp_compress = { path = "../util/rlp-compress" }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tempdir = "0.3"
|
tempdir = "0.3"
|
||||||
trie-standardmap = "0.15.0"
|
trie-standardmap = "0.15.0"
|
||||||
machine = { path = "./machine", features = ["test-helpers"] }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
parity = ["work-notify", "price-info", "stratum"]
|
parity = ["work-notify", "price-info", "stratum"]
|
||||||
|
@ -7,6 +7,15 @@ edition = "2018"
|
|||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ethereum-types = "0.6.0"
|
account-state = { path = "../account-state" }
|
||||||
|
blockchain = { package = "ethcore-blockchain", path = "../blockchain" }
|
||||||
|
bytes = { package = "parity-bytes", version = "0.1.0" }
|
||||||
|
call-contract = { package = "ethcore-call-contract", path = "../call-contract" }
|
||||||
common-types = { path = "../types" }
|
common-types = { path = "../types" }
|
||||||
|
ethcore-db = { path = "../db" }
|
||||||
|
ethcore-miner = { path = "../../miner" }
|
||||||
|
ethereum-types = "0.6.0"
|
||||||
|
kvdb = "0.1.0"
|
||||||
|
stats = { path = "../../util/stats" }
|
||||||
|
trace = { path = "../trace" }
|
||||||
|
vm = { path = "../vm" }
|
||||||
|
@ -14,24 +14,412 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use ethereum_types::{Address, H256};
|
use std::{
|
||||||
use common_types::{
|
collections::BTreeMap,
|
||||||
header::Header,
|
sync::Arc,
|
||||||
encoded,
|
|
||||||
ids::BlockId,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use account_state::state::StateInfo;
|
||||||
|
use blockchain::BlockProvider;
|
||||||
|
use bytes::Bytes;
|
||||||
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
|
use common_types::{
|
||||||
|
basic_account::BasicAccount,
|
||||||
|
block_status::BlockStatus,
|
||||||
|
blockchain_info::BlockChainInfo,
|
||||||
|
BlockNumber,
|
||||||
|
call_analytics::CallAnalytics,
|
||||||
|
client_types::Mode,
|
||||||
|
encoded,
|
||||||
|
engines::{epoch::Transition as EpochTransition, machine::Executed},
|
||||||
|
errors::EthcoreResult,
|
||||||
|
filter::Filter,
|
||||||
|
header::Header,
|
||||||
|
ids::{BlockId, TransactionId, TraceId, UncleId},
|
||||||
|
log_entry::LocalizedLogEntry,
|
||||||
|
pruning_info::PruningInfo,
|
||||||
|
receipt::LocalizedReceipt,
|
||||||
|
trace_filter::Filter as TraceFilter,
|
||||||
|
transaction::{self, LocalizedTransaction, CallError, SignedTransaction},
|
||||||
|
tree_route::TreeRoute,
|
||||||
|
verification::{VerificationQueueInfo, Unverified},
|
||||||
|
};
|
||||||
|
use ethereum_types::{Address, H256, U256};
|
||||||
|
use ethcore_db::keys::BlockReceipts;
|
||||||
|
use ethcore_miner::pool::VerifiedTransaction;
|
||||||
|
use kvdb::DBValue;
|
||||||
|
use stats;
|
||||||
|
use trace::{
|
||||||
|
FlatTrace,
|
||||||
|
localized::LocalizedTrace,
|
||||||
|
VMTrace,
|
||||||
|
};
|
||||||
|
use vm::{LastHashes, Schedule};
|
||||||
|
|
||||||
|
/// State information to be used during client query
|
||||||
|
pub enum StateOrBlock {
|
||||||
|
/// State to be used, may be pending
|
||||||
|
State(Box<dyn StateInfo>),
|
||||||
|
|
||||||
|
/// Id of an existing block from a chain to get state from
|
||||||
|
Block(BlockId)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Box<dyn StateInfo>> for StateOrBlock {
|
||||||
|
fn from(info: Box<dyn StateInfo>) -> StateOrBlock {
|
||||||
|
StateOrBlock::State(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BlockId> for StateOrBlock {
|
||||||
|
fn from(id: BlockId) -> StateOrBlock {
|
||||||
|
StateOrBlock::Block(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides `nonce` and `latest_nonce` methods
|
||||||
|
pub trait Nonce {
|
||||||
|
/// Attempt to get address nonce at given block.
|
||||||
|
/// May not fail on BlockId::Latest.
|
||||||
|
fn nonce(&self, address: &Address, id: BlockId) -> Option<U256>;
|
||||||
|
|
||||||
|
/// Get address nonce at the latest block's state.
|
||||||
|
fn latest_nonce(&self, address: &Address) -> U256 {
|
||||||
|
self.nonce(address, BlockId::Latest)
|
||||||
|
.expect("nonce will return Some when given BlockId::Latest. nonce was given BlockId::Latest. \
|
||||||
|
Therefore nonce has returned Some; qed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides `balance` and `latest_balance` methods
|
||||||
|
pub trait Balance {
|
||||||
|
/// Get address balance at the given block's state.
|
||||||
|
///
|
||||||
|
/// May not return None if given BlockId::Latest.
|
||||||
|
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
||||||
|
fn balance(&self, address: &Address, state: StateOrBlock) -> Option<U256>;
|
||||||
|
|
||||||
|
/// Get address balance at the latest block's state.
|
||||||
|
fn latest_balance(&self, address: &Address) -> U256 {
|
||||||
|
self.balance(address, BlockId::Latest.into())
|
||||||
|
.expect("balance will return Some if given BlockId::Latest. balance was given BlockId::Latest \
|
||||||
|
Therefore balance has returned Some; qed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides methods to access account info
|
||||||
|
pub trait AccountData: Nonce + Balance {}
|
||||||
|
|
||||||
|
/// Provides `chain_info` method
|
||||||
|
pub trait ChainInfo {
|
||||||
|
/// Get blockchain information.
|
||||||
|
fn chain_info(&self) -> BlockChainInfo;
|
||||||
|
}
|
||||||
|
|
||||||
/// Provides various information on a block by it's ID
|
/// Provides various information on a block by it's ID
|
||||||
pub trait BlockInfo {
|
pub trait BlockInfo {
|
||||||
/// Get raw block header data by block id.
|
/// Get raw block header data by block id.
|
||||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
||||||
|
|
||||||
/// Get the best block header.
|
/// Get the best block header.
|
||||||
fn best_block_header(&self) -> Header;
|
fn best_block_header(&self) -> Header;
|
||||||
|
|
||||||
/// Get raw block data by block header hash.
|
/// Get raw block data by block header hash.
|
||||||
fn block(&self, id: BlockId) -> Option<encoded::Block>;
|
fn block(&self, id: BlockId) -> Option<encoded::Block>;
|
||||||
|
|
||||||
/// Get address code hash at given block's state.
|
/// Get address code hash at given block's state.
|
||||||
fn code_hash(&self, address: &Address, id: BlockId) -> Option<H256>;
|
fn code_hash(&self, address: &Address, id: BlockId) -> Option<H256>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides various information on a transaction by it's ID
|
||||||
|
pub trait TransactionInfo {
|
||||||
|
/// Get the hash of block that contains the transaction, if any.
|
||||||
|
fn transaction_block(&self, id: TransactionId) -> Option<H256>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides various blockchain information, like block header, chain state etc.
|
||||||
|
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
|
||||||
|
|
||||||
|
/// Client facilities used by internally sealing Engines.
|
||||||
|
pub trait EngineClient: Sync + Send + ChainInfo {
|
||||||
|
/// Make a new block and seal it.
|
||||||
|
fn update_sealing(&self);
|
||||||
|
|
||||||
|
/// Submit a seal for a block in the mining queue.
|
||||||
|
fn submit_seal(&self, block_hash: H256, seal: Vec<Bytes>);
|
||||||
|
|
||||||
|
/// Broadcast a consensus message to the network.
|
||||||
|
fn broadcast_consensus_message(&self, message: Bytes);
|
||||||
|
|
||||||
|
/// Get the transition to the epoch the given parent hash is part of
|
||||||
|
/// or transitions to.
|
||||||
|
/// This will give the epoch that any children of this parent belong to.
|
||||||
|
///
|
||||||
|
/// The block corresponding the the parent hash must be stored already.
|
||||||
|
fn epoch_transition_for(&self, parent_hash: H256) -> Option<EpochTransition>;
|
||||||
|
|
||||||
|
/// Attempt to cast the engine client to a full client.
|
||||||
|
fn as_full_client(&self) -> Option<&dyn BlockChainClient>;
|
||||||
|
|
||||||
|
/// Get a block number by ID.
|
||||||
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
||||||
|
|
||||||
|
/// Get raw block header data by block id.
|
||||||
|
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
|
||||||
|
/// Provides methods to import block into blockchain
|
||||||
|
pub trait ImportBlock {
|
||||||
|
/// Import a block into the blockchain.
|
||||||
|
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// IO operations that should off-load heavy work to another thread.
|
||||||
|
pub trait IoClient: Sync + Send {
|
||||||
|
/// Queue transactions for importing.
|
||||||
|
fn queue_transactions(&self, transactions: Vec<Bytes>, peer_id: usize);
|
||||||
|
|
||||||
|
/// Queue block import with transaction receipts. Does no sealing and transaction validation.
|
||||||
|
fn queue_ancient_block(&self, block_bytes: Unverified, receipts_bytes: Bytes) -> EthcoreResult<H256>;
|
||||||
|
|
||||||
|
/// Queue consensus engine message.
|
||||||
|
fn queue_consensus_message(&self, message: Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides recently seen bad blocks.
|
||||||
|
pub trait BadBlocks {
|
||||||
|
/// Returns a list of blocks that were recently not imported because they were invalid.
|
||||||
|
fn bad_blocks(&self) -> Vec<(Unverified, String)>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
||||||
|
pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContract + RegistryInfo + ImportBlock
|
||||||
|
+ IoClient + BadBlocks {
|
||||||
|
/// Look up the block number for the given block ID.
|
||||||
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
||||||
|
|
||||||
|
/// Get raw block body data by block id.
|
||||||
|
/// Block body is an RLP list of two items: uncles and transactions.
|
||||||
|
fn block_body(&self, id: BlockId) -> Option<encoded::Body>;
|
||||||
|
|
||||||
|
/// Get block status by block header hash.
|
||||||
|
fn block_status(&self, id: BlockId) -> BlockStatus;
|
||||||
|
|
||||||
|
/// Get block total difficulty.
|
||||||
|
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
|
||||||
|
|
||||||
|
/// Attempt to get address storage root at given block.
|
||||||
|
/// May not fail on BlockId::Latest.
|
||||||
|
fn storage_root(&self, address: &Address, id: BlockId) -> Option<H256>;
|
||||||
|
|
||||||
|
/// Get block hash.
|
||||||
|
fn block_hash(&self, id: BlockId) -> Option<H256>;
|
||||||
|
|
||||||
|
/// Get address code at given block's state.
|
||||||
|
fn code(&self, address: &Address, state: StateOrBlock) -> Option<Option<Bytes>>;
|
||||||
|
|
||||||
|
/// Get address code at the latest block's state.
|
||||||
|
fn latest_code(&self, address: &Address) -> Option<Bytes> {
|
||||||
|
self.code(address, BlockId::Latest.into())
|
||||||
|
.expect("code will return Some if given BlockId::Latest; qed")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference to the `BlockProvider`.
|
||||||
|
fn chain(&self) -> Arc<dyn BlockProvider>;
|
||||||
|
|
||||||
|
/// Get block queue information.
|
||||||
|
fn queue_info(&self) -> VerificationQueueInfo;
|
||||||
|
|
||||||
|
/// Get address code hash at given block's state.
|
||||||
|
|
||||||
|
/// Get value of the storage at given position at the given block's state.
|
||||||
|
///
|
||||||
|
/// May not return None if given BlockId::Latest.
|
||||||
|
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
||||||
|
fn storage_at(&self, address: &Address, position: &H256, state: StateOrBlock) -> Option<H256>;
|
||||||
|
|
||||||
|
/// Get value of the storage at given position at the latest block's state.
|
||||||
|
fn latest_storage_at(&self, address: &Address, position: &H256) -> H256 {
|
||||||
|
self.storage_at(address, position, BlockId::Latest.into())
|
||||||
|
.expect("storage_at will return Some if given BlockId::Latest. storage_at was given BlockId::Latest. \
|
||||||
|
Therefore storage_at has returned Some; qed")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`.
|
||||||
|
/// If `after` is set the list starts with the following item.
|
||||||
|
fn list_accounts(&self, id: BlockId, after: Option<&Address>, count: u64) -> Option<Vec<Address>>;
|
||||||
|
|
||||||
|
/// Get a list of all storage keys in the block `id`, if fat DB is in operation, otherwise `None`.
|
||||||
|
/// If `after` is set the list starts with the following item.
|
||||||
|
fn list_storage(&self, id: BlockId, account: &Address, after: Option<&H256>, count: u64) -> Option<Vec<H256>>;
|
||||||
|
|
||||||
|
/// Get transaction with given hash.
|
||||||
|
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction>;
|
||||||
|
|
||||||
|
/// Get uncle with given id.
|
||||||
|
fn uncle(&self, id: UncleId) -> Option<encoded::Header>;
|
||||||
|
|
||||||
|
/// Get transaction receipt with given hash.
|
||||||
|
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt>;
|
||||||
|
|
||||||
|
/// Get localized receipts for all transaction in given block.
|
||||||
|
fn localized_block_receipts(&self, id: BlockId) -> Option<Vec<LocalizedReceipt>>;
|
||||||
|
|
||||||
|
/// Get a tree route between `from` and `to`.
|
||||||
|
/// See `BlockChain::tree_route`.
|
||||||
|
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
|
||||||
|
|
||||||
|
/// Get all possible uncle hashes for a block.
|
||||||
|
fn find_uncles(&self, hash: &H256) -> Option<Vec<H256>>;
|
||||||
|
|
||||||
|
/// Get latest state node
|
||||||
|
fn state_data(&self, hash: &H256) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Get block receipts data by block header hash.
|
||||||
|
fn block_receipts(&self, hash: &H256) -> Option<BlockReceipts>;
|
||||||
|
|
||||||
|
/// Returns true if block queue is empty.
|
||||||
|
fn is_queue_empty(&self) -> bool {
|
||||||
|
self.queue_info().is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear block queue and abort all import activity.
|
||||||
|
fn clear_queue(&self);
|
||||||
|
|
||||||
|
/// Returns logs matching given filter. If one of the filtering block cannot be found, returns the block id that caused the error.
|
||||||
|
fn logs(&self, filter: Filter) -> Result<Vec<LocalizedLogEntry>, BlockId>;
|
||||||
|
|
||||||
|
/// Replays a given transaction for inspection.
|
||||||
|
fn replay(&self, t: TransactionId, analytics: CallAnalytics) -> Result<Executed<FlatTrace, VMTrace>, CallError>;
|
||||||
|
|
||||||
|
/// Replays all the transactions in a given block for inspection.
|
||||||
|
fn replay_block_transactions(&self, block: BlockId, analytics: CallAnalytics) -> Result<Box<dyn Iterator<Item = (H256, Executed<FlatTrace, VMTrace>)>>, CallError>;
|
||||||
|
|
||||||
|
/// Returns traces matching given filter.
|
||||||
|
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>>;
|
||||||
|
|
||||||
|
/// Returns trace with given id.
|
||||||
|
fn trace(&self, trace: TraceId) -> Option<LocalizedTrace>;
|
||||||
|
|
||||||
|
/// Returns traces created by transaction.
|
||||||
|
fn transaction_traces(&self, trace: TransactionId) -> Option<Vec<LocalizedTrace>>;
|
||||||
|
|
||||||
|
/// Returns traces created by transaction from block.
|
||||||
|
fn block_traces(&self, trace: BlockId) -> Option<Vec<LocalizedTrace>>;
|
||||||
|
|
||||||
|
/// Get last hashes starting from best block.
|
||||||
|
fn last_hashes(&self) -> LastHashes;
|
||||||
|
|
||||||
|
/// List all ready transactions that should be propagated to other peers.
|
||||||
|
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>>;
|
||||||
|
|
||||||
|
/// Sorted list of transaction gas prices from at least last sample_size blocks.
|
||||||
|
fn gas_price_corpus(&self, sample_size: usize) -> stats::Corpus<U256> {
|
||||||
|
let mut h = self.chain_info().best_block_hash;
|
||||||
|
let mut corpus = Vec::new();
|
||||||
|
while corpus.is_empty() {
|
||||||
|
for _ in 0..sample_size {
|
||||||
|
let block = match self.block(BlockId::Hash(h)) {
|
||||||
|
Some(block) => block,
|
||||||
|
None => return corpus.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if block.number() == 0 {
|
||||||
|
return corpus.into();
|
||||||
|
}
|
||||||
|
for t in block.transaction_views().iter() {
|
||||||
|
corpus.push( t.gas_price() )
|
||||||
|
}
|
||||||
|
h = block.parent_hash().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
corpus.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the preferred chain ID to sign on
|
||||||
|
fn signing_chain_id(&self) -> Option<u64>;
|
||||||
|
|
||||||
|
/// Get the mode.
|
||||||
|
fn mode(&self) -> Mode;
|
||||||
|
|
||||||
|
/// Set the mode.
|
||||||
|
fn set_mode(&self, mode: Mode);
|
||||||
|
|
||||||
|
/// Get the chain spec name.
|
||||||
|
fn spec_name(&self) -> String;
|
||||||
|
|
||||||
|
/// Set the chain via a spec name.
|
||||||
|
fn set_spec_name(&self, spec_name: String) -> Result<(), ()>;
|
||||||
|
|
||||||
|
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
||||||
|
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
||||||
|
fn disable(&self);
|
||||||
|
|
||||||
|
/// Returns engine-related extra info for `BlockId`.
|
||||||
|
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>>;
|
||||||
|
|
||||||
|
/// Returns engine-related extra info for `UncleId`.
|
||||||
|
fn uncle_extra_info(&self, id: UncleId) -> Option<BTreeMap<String, String>>;
|
||||||
|
|
||||||
|
/// Returns information about pruning/data availability.
|
||||||
|
fn pruning_info(&self) -> PruningInfo;
|
||||||
|
|
||||||
|
/// Schedule state-altering transaction to be executed on the next pending block.
|
||||||
|
fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error>;
|
||||||
|
|
||||||
|
/// Get the address of the registry itself.
|
||||||
|
fn registrar_address(&self) -> Option<Address>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// resets the blockchain
|
||||||
|
pub trait BlockChainReset {
|
||||||
|
/// reset to best_block - n
|
||||||
|
fn reset(&self, num: u32) -> Result<(), String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Provides `latest_schedule` method
|
||||||
|
pub trait ScheduleInfo {
|
||||||
|
/// Returns latest schedule.
|
||||||
|
fn latest_schedule(&self) -> Schedule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides methods to access chain state
|
||||||
|
pub trait StateClient {
|
||||||
|
/// Type representing chain state
|
||||||
|
type State: StateInfo;
|
||||||
|
|
||||||
|
/// Get a copy of the best block's state.
|
||||||
|
fn latest_state(&self) -> Self::State;
|
||||||
|
|
||||||
|
/// Attempt to get a copy of a specific block's final state.
|
||||||
|
///
|
||||||
|
/// This will not fail if given BlockId::Latest.
|
||||||
|
/// Otherwise, this can fail (but may not) if the DB prunes state or the block
|
||||||
|
/// is unknown.
|
||||||
|
fn state_at(&self, id: BlockId) -> Option<Self::State>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extended client interface for providing proofs of the state.
|
||||||
|
pub trait ProvingBlockChainClient: BlockChainClient {
|
||||||
|
/// Prove account storage at a specific block id.
|
||||||
|
///
|
||||||
|
/// Both provided keys assume a secure trie.
|
||||||
|
/// Returns a vector of raw trie nodes (in order from the root) proving the storage query.
|
||||||
|
fn prove_storage(&self, key1: H256, key2: H256, id: BlockId) -> Option<(Vec<Bytes>, H256)>;
|
||||||
|
|
||||||
|
/// Prove account existence at a specific block id.
|
||||||
|
/// The key is the keccak hash of the account's address.
|
||||||
|
/// Returns a vector of raw trie nodes (in order from the root) proving the query.
|
||||||
|
fn prove_account(&self, key1: H256, id: BlockId) -> Option<(Vec<Bytes>, BasicAccount)>;
|
||||||
|
|
||||||
|
/// Prove execution of a transaction at the given block.
|
||||||
|
/// Returns the output of the call and a vector of database items necessary
|
||||||
|
/// to reproduce it.
|
||||||
|
fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec<DBValue>)>;
|
||||||
|
|
||||||
|
/// Get an epoch change signal by block hash.
|
||||||
|
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>>;
|
||||||
}
|
}
|
||||||
|
29
ethcore/engine/Cargo.toml
Normal file
29
ethcore/engine/Cargo.toml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[package]
|
||||||
|
description = "Ethereum engine trait definition"
|
||||||
|
name = "engine"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
blockchain = { package = "ethcore-blockchain", path = "../blockchain" }
|
||||||
|
builtin = { path = "../builtin", package = "ethcore-builtin" }
|
||||||
|
bytes = { package = "parity-bytes", version = "0.1.0" }
|
||||||
|
client-traits = { path = "../client-traits" }
|
||||||
|
common-types = { path = "../types" }
|
||||||
|
ethereum-types = "0.6.0"
|
||||||
|
ethkey = { path = "../../accounts/ethkey" }
|
||||||
|
machine = { path = "../machine" }
|
||||||
|
vm = { path = "../vm" }
|
||||||
|
|
||||||
|
# used from test-helpers
|
||||||
|
accounts = { package = "ethcore-accounts", path = "../../accounts", optional = true }
|
||||||
|
log = { version = "0.4.8", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
accounts = { package = "ethcore-accounts", path = "../../accounts" }
|
||||||
|
log = "0.4.8"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
test-helpers = ["accounts", "log"]
|
418
ethcore/engine/src/engine.rs
Normal file
418
ethcore/engine/src/engine.rs
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Consensus engine specification and basic implementations.
|
||||||
|
|
||||||
|
use std::sync::{Weak, Arc};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use builtin::Builtin;
|
||||||
|
use common_types::{
|
||||||
|
BlockNumber,
|
||||||
|
ancestry_action::AncestryAction,
|
||||||
|
header::{Header, ExtendedHeader},
|
||||||
|
engines::{
|
||||||
|
Seal, SealingState, Headers, PendingTransitionStore,
|
||||||
|
params::CommonParams,
|
||||||
|
machine as machine_types,
|
||||||
|
machine::{AuxiliaryData, AuxiliaryRequest},
|
||||||
|
},
|
||||||
|
errors::{EthcoreError as Error, EngineError},
|
||||||
|
transaction::{self, UnverifiedTransaction},
|
||||||
|
};
|
||||||
|
use client_traits::EngineClient;
|
||||||
|
|
||||||
|
use ethereum_types::{H256, U256, Address};
|
||||||
|
use ethkey::Signature;
|
||||||
|
use machine::{
|
||||||
|
Machine,
|
||||||
|
executed_block::ExecutedBlock,
|
||||||
|
};
|
||||||
|
use vm::{EnvInfo, Schedule, CallType, ActionValue};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
signer::EngineSigner,
|
||||||
|
snapshot::SnapshotComponents,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A system-calling closure. Enacts calls on a block's state from the system address.
|
||||||
|
pub type SystemCall<'a> = dyn FnMut(Address, Vec<u8>) -> Result<Vec<u8>, String> + 'a;
|
||||||
|
|
||||||
|
/// A system-calling closure. Enacts calls on a block's state with code either from an on-chain contract, or hard-coded EVM or WASM (if enabled on-chain) codes.
|
||||||
|
pub type SystemOrCodeCall<'a> = dyn FnMut(SystemOrCodeCallKind, Vec<u8>) -> Result<Vec<u8>, String> + 'a;
|
||||||
|
|
||||||
|
/// Kind of SystemOrCodeCall, this is either an on-chain address, or code.
|
||||||
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
pub enum SystemOrCodeCallKind {
|
||||||
|
/// On-chain address.
|
||||||
|
Address(Address),
|
||||||
|
/// Hard-coded code.
|
||||||
|
Code(Arc<Vec<u8>>, H256),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default SystemOrCodeCall implementation.
|
||||||
|
pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut ExecutedBlock) -> impl FnMut(SystemOrCodeCallKind, Vec<u8>) -> Result<Vec<u8>, String> + 'a {
|
||||||
|
move |to, data| {
|
||||||
|
let result = match to {
|
||||||
|
SystemOrCodeCallKind::Address(address) => {
|
||||||
|
machine.execute_as_system(
|
||||||
|
block,
|
||||||
|
address,
|
||||||
|
U256::max_value(),
|
||||||
|
Some(data),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
SystemOrCodeCallKind::Code(code, code_hash) => {
|
||||||
|
machine.execute_code_as_system(
|
||||||
|
block,
|
||||||
|
None,
|
||||||
|
Some(code),
|
||||||
|
Some(code_hash),
|
||||||
|
Some(ActionValue::Apparent(U256::zero())),
|
||||||
|
U256::max_value(),
|
||||||
|
Some(data),
|
||||||
|
Some(CallType::StaticCall),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result.map_err(|e| format!("{}", e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Proof dependent on state.
|
||||||
|
pub trait StateDependentProof: Send + Sync {
|
||||||
|
/// Generate a proof, given the state.
|
||||||
|
fn generate_proof<'a>(&self, state: &machine_types::Call) -> Result<Vec<u8>, String>;
|
||||||
|
/// Check a proof generated elsewhere (potentially by a peer).
|
||||||
|
// `engine` needed to check state proofs, while really this should
|
||||||
|
// just be state machine params.
|
||||||
|
fn check_proof(&self, machine: &Machine, proof: &[u8]) -> Result<(), String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Proof generated on epoch change.
|
||||||
|
pub enum Proof {
|
||||||
|
/// Known proof (extracted from signal)
|
||||||
|
Known(Vec<u8>),
|
||||||
|
/// State dependent proof.
|
||||||
|
WithState(Arc<dyn StateDependentProof>),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generated epoch verifier.
|
||||||
|
pub enum ConstructedVerifier<'a> {
|
||||||
|
/// Fully trusted verifier.
|
||||||
|
Trusted(Box<dyn EpochVerifier>),
|
||||||
|
/// Verifier unconfirmed. Check whether given finality proof finalizes given hash
|
||||||
|
/// under previous epoch.
|
||||||
|
Unconfirmed(Box<dyn EpochVerifier>, &'a [u8], H256),
|
||||||
|
/// Error constructing verifier.
|
||||||
|
Err(Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ConstructedVerifier<'a> {
|
||||||
|
/// Convert to a result, indicating that any necessary confirmation has been done
|
||||||
|
/// already.
|
||||||
|
pub fn known_confirmed(self) -> Result<Box<dyn EpochVerifier>, Error> {
|
||||||
|
match self {
|
||||||
|
ConstructedVerifier::Trusted(v) | ConstructedVerifier::Unconfirmed(v, _, _) => Ok(v),
|
||||||
|
ConstructedVerifier::Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Results of a query of whether an epoch change occurred at the given block.
|
||||||
|
pub enum EpochChange {
|
||||||
|
/// Cannot determine until more data is passed.
|
||||||
|
Unsure(AuxiliaryRequest),
|
||||||
|
/// No epoch change.
|
||||||
|
No,
|
||||||
|
/// The epoch will change, with proof.
|
||||||
|
Yes(Proof),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based.
|
||||||
|
/// Provides hooks into each of the major parts of block import.
|
||||||
|
pub trait Engine: Sync + Send {
|
||||||
|
/// The name of this engine.
|
||||||
|
fn name(&self) -> &str;
|
||||||
|
|
||||||
|
/// Get access to the underlying state machine.
|
||||||
|
// TODO: decouple.
|
||||||
|
fn machine(&self) -> &Machine;
|
||||||
|
|
||||||
|
/// The number of additional header fields required for this engine.
|
||||||
|
fn seal_fields(&self, _header: &Header) -> usize { 0 }
|
||||||
|
|
||||||
|
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||||
|
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
||||||
|
|
||||||
|
/// Maximum number of uncles a block is allowed to declare.
|
||||||
|
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||||
|
|
||||||
|
/// Optional maximum gas limit.
|
||||||
|
fn maximum_gas_limit(&self) -> Option<U256> { None }
|
||||||
|
|
||||||
|
/// Block transformation functions, before the transactions.
|
||||||
|
/// `epoch_begin` set to true if this block kicks off an epoch.
|
||||||
|
fn on_new_block(
|
||||||
|
&self,
|
||||||
|
_block: &mut ExecutedBlock,
|
||||||
|
_epoch_begin: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Block transformation functions, after the transactions.
|
||||||
|
fn on_close_block(
|
||||||
|
&self,
|
||||||
|
_block: &mut ExecutedBlock,
|
||||||
|
_parent_header: &Header,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Allow mutating the header during seal generation. Currently only used by Clique.
|
||||||
|
fn on_seal_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { Ok(()) }
|
||||||
|
|
||||||
|
/// Returns the engine's current sealing state.
|
||||||
|
fn sealing_state(&self) -> SealingState { SealingState::External }
|
||||||
|
|
||||||
|
/// Attempt to seal the block internally.
|
||||||
|
///
|
||||||
|
/// If `Some` is returned, then you get a valid seal.
|
||||||
|
///
|
||||||
|
/// This operation is synchronous and may (quite reasonably) not be available, in which None will
|
||||||
|
/// be returned.
|
||||||
|
///
|
||||||
|
/// It is fine to require access to state or a full client for this function, since
|
||||||
|
/// light clients do not generate seals.
|
||||||
|
fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None }
|
||||||
|
|
||||||
|
/// Verify a locally-generated seal of a header.
|
||||||
|
///
|
||||||
|
/// If this engine seals internally,
|
||||||
|
/// no checks have to be done here, since all internally generated seals
|
||||||
|
/// should be valid.
|
||||||
|
///
|
||||||
|
/// Externally-generated seals (e.g. PoW) will need to be checked for validity.
|
||||||
|
///
|
||||||
|
/// It is fine to require access to state or a full client for this function, since
|
||||||
|
/// light clients do not generate seals.
|
||||||
|
fn verify_local_seal(&self, header: &Header) -> Result<(), Error>;
|
||||||
|
|
||||||
|
/// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import.
|
||||||
|
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
|
||||||
|
fn verify_block_basic(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
||||||
|
|
||||||
|
/// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import.
|
||||||
|
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
|
||||||
|
fn verify_block_unordered(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
||||||
|
|
||||||
|
/// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import.
|
||||||
|
fn verify_block_family(&self, _header: &Header, _parent: &Header) -> Result<(), Error> { Ok(()) }
|
||||||
|
|
||||||
|
/// Phase 4 verification. Verify block header against potentially external data.
|
||||||
|
/// Should only be called when `register_client` has been called previously.
|
||||||
|
fn verify_block_external(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
||||||
|
|
||||||
|
/// Genesis epoch data.
|
||||||
|
fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine_types::Call) -> Result<Vec<u8>, String> { Ok(Vec::new()) }
|
||||||
|
|
||||||
|
/// Whether an epoch change is signalled at the given header but will require finality.
|
||||||
|
/// If a change can be enacted immediately then return `No` from this function but
|
||||||
|
/// `Yes` from `is_epoch_end`.
|
||||||
|
///
|
||||||
|
/// If auxiliary data of the block is required, return an auxiliary request and the function will be
|
||||||
|
/// called again with them.
|
||||||
|
/// Return `Yes` or `No` when the answer is definitively known.
|
||||||
|
///
|
||||||
|
/// Should not interact with state.
|
||||||
|
fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange {
|
||||||
|
EpochChange::No
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether a block is the end of an epoch.
|
||||||
|
///
|
||||||
|
/// This either means that an immediate transition occurs or a block signalling transition
|
||||||
|
/// has reached finality. The `Headers` given are not guaranteed to return any blocks
|
||||||
|
/// from any epoch other than the current. The client must keep track of finality and provide
|
||||||
|
/// the latest finalized headers to check against the transition store.
|
||||||
|
///
|
||||||
|
/// Return optional transition proof.
|
||||||
|
fn is_epoch_end(
|
||||||
|
&self,
|
||||||
|
_chain_head: &Header,
|
||||||
|
_finalized: &[H256],
|
||||||
|
_chain: &Headers<Header>,
|
||||||
|
_transition_store: &PendingTransitionStore,
|
||||||
|
) -> Option<Vec<u8>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether a block is the end of an epoch.
|
||||||
|
///
|
||||||
|
/// This either means that an immediate transition occurs or a block signalling transition
|
||||||
|
/// has reached finality. The `Headers` given are not guaranteed to return any blocks
|
||||||
|
/// from any epoch other than the current. This is a specialized method to use for light
|
||||||
|
/// clients since the light client doesn't track finality of all blocks, and therefore finality
|
||||||
|
/// for blocks in the current epoch is built inside this method by the engine.
|
||||||
|
///
|
||||||
|
/// Return optional transition proof.
|
||||||
|
fn is_epoch_end_light(
|
||||||
|
&self,
|
||||||
|
_chain_head: &Header,
|
||||||
|
_chain: &Headers<Header>,
|
||||||
|
_transition_store: &PendingTransitionStore,
|
||||||
|
) -> Option<Vec<u8>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an epoch verifier from validation proof and a flag indicating
|
||||||
|
/// whether finality is required.
|
||||||
|
fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> ConstructedVerifier<'a> {
|
||||||
|
ConstructedVerifier::Trusted(Box::new(NoOp))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Populate a header's fields based on its parent's header.
|
||||||
|
/// Usually implements the chain scoring rule based on weight.
|
||||||
|
fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) { }
|
||||||
|
|
||||||
|
/// Handle any potential consensus messages;
|
||||||
|
/// updating consensus state and potentially issuing a new one.
|
||||||
|
fn handle_message(&self, _message: &[u8]) -> Result<(), EngineError> { Err(EngineError::UnexpectedMessage) }
|
||||||
|
|
||||||
|
/// Register a component which signs consensus messages.
|
||||||
|
fn set_signer(&self, _signer: Box<dyn EngineSigner>) {}
|
||||||
|
|
||||||
|
/// Sign using the EngineSigner, to be used for consensus tx signing.
|
||||||
|
fn sign(&self, _hash: H256) -> Result<Signature, Error> { unimplemented!() }
|
||||||
|
|
||||||
|
/// Add Client which can be used for sealing, potentially querying the state and sending messages.
|
||||||
|
fn register_client(&self, _client: Weak<dyn EngineClient>) {}
|
||||||
|
|
||||||
|
/// Trigger next step of the consensus engine.
|
||||||
|
fn step(&self) {}
|
||||||
|
|
||||||
|
/// Create a factory for building snapshot chunks and restoring from them.
|
||||||
|
/// Returning `None` indicates that this engine doesn't support snapshot creation.
|
||||||
|
fn snapshot_components(&self) -> Option<Box<dyn SnapshotComponents>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this engine supports warp sync.
|
||||||
|
fn supports_warp(&self) -> bool {
|
||||||
|
self.snapshot_components().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a new open block header timestamp based on the parent timestamp.
|
||||||
|
fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 {
|
||||||
|
use std::{time, cmp};
|
||||||
|
|
||||||
|
let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default();
|
||||||
|
cmp::max(now.as_secs() as u64, parent_timestamp + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check whether the parent timestamp is valid.
|
||||||
|
fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool {
|
||||||
|
header_timestamp > parent_timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that
|
||||||
|
/// the ancestry exists.
|
||||||
|
fn ancestry_actions(&self, _header: &Header, _ancestry: &mut dyn Iterator<Item = ExtendedHeader>) -> Vec<AncestryAction> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns author should used when executing tx's for this block.
|
||||||
|
fn executive_author(&self, header: &Header) -> Result<Address, Error> {
|
||||||
|
Ok(*header.author())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the general parameters of the chain.
|
||||||
|
fn params(&self) -> &CommonParams;
|
||||||
|
|
||||||
|
/// Get the EVM schedule for the given block number.
|
||||||
|
fn schedule(&self, block_number: BlockNumber) -> Schedule {
|
||||||
|
self.machine().schedule(block_number)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builtin-contracts for the chain..
|
||||||
|
fn builtins(&self) -> &BTreeMap<Address, Builtin> {
|
||||||
|
self.machine().builtins()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempt to get a handle to a built-in contract.
|
||||||
|
/// Only returns references to activated built-ins.
|
||||||
|
fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> {
|
||||||
|
self.machine().builtin(a, block_number)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
|
||||||
|
fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size }
|
||||||
|
|
||||||
|
/// The nonce with which accounts begin at given block.
|
||||||
|
fn account_start_nonce(&self, block: BlockNumber) -> U256 {
|
||||||
|
self.machine().account_start_nonce(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The network ID that transactions should be signed with.
|
||||||
|
fn signing_chain_id(&self, env_info: &EnvInfo) -> Option<u64> {
|
||||||
|
self.machine().signing_chain_id(env_info)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Perform basic/cheap transaction verification.
|
||||||
|
///
|
||||||
|
/// This should include all cheap checks that can be done before
|
||||||
|
/// actually checking the signature, like chain-replay protection.
|
||||||
|
///
|
||||||
|
/// NOTE This is done before the signature is recovered so avoid
|
||||||
|
/// doing any state-touching checks that might be expensive.
|
||||||
|
///
|
||||||
|
/// TODO: Add flags for which bits of the transaction to check.
|
||||||
|
/// TODO: consider including State in the params.
|
||||||
|
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> {
|
||||||
|
self.machine().verify_transaction_basic(t, header)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs pre-validation of RLP decoded transaction before other processing
|
||||||
|
fn decode_transaction(&self, transaction: &[u8]) -> Result<UnverifiedTransaction, transaction::Error> {
|
||||||
|
self.machine().decode_transaction(transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verifier for all blocks within an epoch with self-contained state.
|
||||||
|
pub trait EpochVerifier: Send + Sync {
|
||||||
|
/// Lightly verify the next block header.
|
||||||
|
/// This may not be a header belonging to a different epoch.
|
||||||
|
fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
||||||
|
|
||||||
|
/// Perform potentially heavier checks on the next block header.
|
||||||
|
fn verify_heavy(&self, header: &Header) -> Result<(), Error> {
|
||||||
|
self.verify_light(header)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check a finality proof against this epoch verifier.
|
||||||
|
/// Returns `Some(hashes)` if the proof proves finality of these hashes.
|
||||||
|
/// Returns `None` if the proof doesn't prove anything.
|
||||||
|
fn check_finality_proof(&self, _proof: &[u8]) -> Option<Vec<H256>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Special "no-op" verifier for stateless, epoch-less engines.
|
||||||
|
pub struct NoOp;
|
||||||
|
|
||||||
|
impl EpochVerifier for NoOp {}
|
37
ethcore/engine/src/lib.rs
Normal file
37
ethcore/engine/src/lib.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity Ethereum.
|
||||||
|
|
||||||
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! This crate defines the Engine trait and related types.
|
||||||
|
|
||||||
|
mod engine;
|
||||||
|
pub mod signer;
|
||||||
|
pub mod snapshot;
|
||||||
|
|
||||||
|
pub use crate::engine::{
|
||||||
|
Engine,
|
||||||
|
EpochVerifier,
|
||||||
|
StateDependentProof,
|
||||||
|
ConstructedVerifier,
|
||||||
|
EpochChange,
|
||||||
|
Proof,
|
||||||
|
SystemCall,
|
||||||
|
SystemOrCodeCall,
|
||||||
|
SystemOrCodeCallKind,
|
||||||
|
default_system_or_code_call,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
|
pub mod test_helpers;
|
@ -44,36 +44,3 @@ impl EngineSigner for Signer {
|
|||||||
self.0.address()
|
self.0.address()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test_signer {
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use ethkey::Password;
|
|
||||||
use accounts::{self, AccountProvider, SignError};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
impl EngineSigner for (Arc<AccountProvider>, Address, Password) {
|
|
||||||
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error> {
|
|
||||||
match self.0.sign(self.1, Some(self.2.clone()), hash) {
|
|
||||||
Err(SignError::NotUnlocked) => unreachable!(),
|
|
||||||
Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress),
|
|
||||||
Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err),
|
|
||||||
Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => {
|
|
||||||
warn!("Low level crypto error: {:?}", err);
|
|
||||||
Err(ethkey::Error::InvalidSecret)
|
|
||||||
},
|
|
||||||
Err(SignError::SStore(err)) => {
|
|
||||||
warn!("Error signing for engine: {:?}", err);
|
|
||||||
Err(ethkey::Error::InvalidSignature)
|
|
||||||
},
|
|
||||||
Ok(ok) => Ok(ok),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn address(&self) -> Address {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
90
ethcore/engine/src/snapshot.rs
Normal file
90
ethcore/engine/src/snapshot.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! This module contains traits used while creating/restoring snapshots. They
|
||||||
|
//! are here because they use and are used by the Engine trait itself.
|
||||||
|
|
||||||
|
use std::sync::{Arc, atomic::AtomicBool};
|
||||||
|
|
||||||
|
use ethereum_types::H256;
|
||||||
|
|
||||||
|
use blockchain::{BlockChain, BlockChainDB};
|
||||||
|
use common_types::{
|
||||||
|
errors::{EthcoreError as Error, SnapshotError},
|
||||||
|
snapshot::{ManifestData, ChunkSink, Progress},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::engine::Engine;
|
||||||
|
|
||||||
|
/// Restore from secondary snapshot chunks.
|
||||||
|
pub trait Rebuilder: Send {
|
||||||
|
/// Feed a chunk, potentially out of order.
|
||||||
|
///
|
||||||
|
/// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with
|
||||||
|
/// `Error::RestorationAborted`.
|
||||||
|
fn feed(
|
||||||
|
&mut self,
|
||||||
|
chunk: &[u8],
|
||||||
|
engine: &dyn Engine,
|
||||||
|
abort_flag: &AtomicBool,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
|
||||||
|
/// Finalize the restoration. Will be done after all chunks have been
|
||||||
|
/// fed successfully.
|
||||||
|
///
|
||||||
|
/// This should apply the necessary "glue" between chunks,
|
||||||
|
/// and verify against the restored state.
|
||||||
|
fn finalize(&mut self) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Components necessary for snapshot creation and restoration.
|
||||||
|
pub trait SnapshotComponents: Send {
|
||||||
|
/// Create secondary snapshot chunks; these corroborate the state data
|
||||||
|
/// in the state chunks.
|
||||||
|
///
|
||||||
|
/// Chunks shouldn't exceed the given preferred size, and should be fed
|
||||||
|
/// uncompressed into the sink.
|
||||||
|
///
|
||||||
|
/// This will vary by consensus engine, so it's exposed as a trait.
|
||||||
|
fn chunk_all(
|
||||||
|
&mut self,
|
||||||
|
chain: &BlockChain,
|
||||||
|
block_at: H256,
|
||||||
|
chunk_sink: &mut ChunkSink,
|
||||||
|
progress: &Progress,
|
||||||
|
preferred_size: usize,
|
||||||
|
) -> Result<(), SnapshotError>;
|
||||||
|
|
||||||
|
/// Create a rebuilder, which will have chunks fed into it in arbitrary
|
||||||
|
/// order and then be finalized.
|
||||||
|
///
|
||||||
|
/// The manifest, a database, and fresh `BlockChain` are supplied.
|
||||||
|
///
|
||||||
|
/// The engine passed to the `Rebuilder` methods will be the same instance
|
||||||
|
/// that created the `SnapshotComponents`.
|
||||||
|
fn rebuilder(
|
||||||
|
&self,
|
||||||
|
chain: BlockChain,
|
||||||
|
db: Arc<dyn BlockChainDB>,
|
||||||
|
manifest: &ManifestData,
|
||||||
|
) -> Result<Box<dyn Rebuilder>, Error>;
|
||||||
|
|
||||||
|
/// Minimum supported snapshot version number.
|
||||||
|
fn min_supported_version(&self) -> u64;
|
||||||
|
|
||||||
|
/// Current version number
|
||||||
|
fn current_version(&self) -> u64;
|
||||||
|
}
|
49
ethcore/engine/src/test_helpers.rs
Normal file
49
ethcore/engine/src/test_helpers.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity Ethereum.
|
||||||
|
|
||||||
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Test helpers for engine related tests
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use ethereum_types::{Address, H256};
|
||||||
|
use ethkey::{Password, Signature};
|
||||||
|
use log::warn;
|
||||||
|
use accounts::{self, AccountProvider, SignError};
|
||||||
|
|
||||||
|
use crate::signer::EngineSigner;
|
||||||
|
|
||||||
|
impl EngineSigner for (Arc<AccountProvider>, Address, Password) {
|
||||||
|
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error> {
|
||||||
|
match self.0.sign(self.1, Some(self.2.clone()), hash) {
|
||||||
|
Err(SignError::NotUnlocked) => unreachable!(),
|
||||||
|
Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress),
|
||||||
|
Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err),
|
||||||
|
Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => {
|
||||||
|
warn!("Low level crypto error: {:?}", err);
|
||||||
|
Err(ethkey::Error::InvalidSecret)
|
||||||
|
},
|
||||||
|
Err(SignError::SStore(err)) => {
|
||||||
|
warn!("Error signing for engine: {:?}", err);
|
||||||
|
Err(ethkey::Error::InvalidSignature)
|
||||||
|
},
|
||||||
|
Ok(ok) => Ok(ok),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn address(&self) -> Address {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ parity-bytes = "0.1"
|
|||||||
client-traits = { path = "../client-traits" }
|
client-traits = { path = "../client-traits" }
|
||||||
common-types = { path = "../types" }
|
common-types = { path = "../types" }
|
||||||
derive_more = "0.14.0"
|
derive_more = "0.14.0"
|
||||||
|
engine = { path = "../engine" }
|
||||||
ethcore = { path = ".."}
|
ethcore = { path = ".."}
|
||||||
ethcore-db = { path = "../db" }
|
ethcore-db = { path = "../db" }
|
||||||
ethcore-blockchain = { path = "../blockchain" }
|
ethcore-blockchain = { path = "../blockchain" }
|
||||||
|
@ -18,10 +18,12 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use common_types::encoded;
|
use common_types::{
|
||||||
use common_types::header::Header;
|
header::Header,
|
||||||
use common_types::receipt::Receipt;
|
encoded,
|
||||||
use ethcore::engines::{Engine, StateDependentProof};
|
receipt::Receipt,
|
||||||
|
};
|
||||||
|
use engine::{Engine, StateDependentProof};
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use futures::future::IntoFuture;
|
use futures::future::IntoFuture;
|
||||||
|
|
||||||
|
@ -33,11 +33,14 @@ use cht;
|
|||||||
use common_types::{
|
use common_types::{
|
||||||
block_status::BlockStatus,
|
block_status::BlockStatus,
|
||||||
encoded,
|
encoded,
|
||||||
|
engines::epoch::{
|
||||||
|
Transition as EpochTransition,
|
||||||
|
PendingTransition as PendingEpochTransition,
|
||||||
|
},
|
||||||
errors::{EthcoreError as Error, BlockError, EthcoreResult},
|
errors::{EthcoreError as Error, BlockError, EthcoreResult},
|
||||||
header::Header,
|
header::Header,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
};
|
};
|
||||||
use ethcore::engines::epoch::{Transition as EpochTransition, PendingTransition as PendingEpochTransition};
|
|
||||||
use ethcore::spec::{Spec, SpecHardcodedSync};
|
use ethcore::spec::{Spec, SpecHardcodedSync};
|
||||||
use ethereum_types::{H256, H264, U256};
|
use ethereum_types::{H256, H264, U256};
|
||||||
use parity_util_mem::{MallocSizeOf, MallocSizeOfOps};
|
use parity_util_mem::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
use std::sync::{Weak, Arc};
|
use std::sync::{Weak, Arc};
|
||||||
|
|
||||||
|
use engine::{Engine, EpochChange, Proof};
|
||||||
use ethcore::client::{ClientReport, EnvInfo, ClientIoMessage};
|
use ethcore::client::{ClientReport, EnvInfo, ClientIoMessage};
|
||||||
use ethcore::engines::{epoch, Engine, EpochChange, EpochTransition, Proof};
|
|
||||||
use ethcore::verification::queue::{self, HeaderQueue};
|
use ethcore::verification::queue::{self, HeaderQueue};
|
||||||
use ethcore::spec::{Spec, SpecHardcodedSync};
|
use ethcore::spec::{Spec, SpecHardcodedSync};
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
@ -31,11 +31,12 @@ use common_types::{
|
|||||||
block_status::BlockStatus,
|
block_status::BlockStatus,
|
||||||
blockchain_info::BlockChainInfo,
|
blockchain_info::BlockChainInfo,
|
||||||
encoded,
|
encoded,
|
||||||
|
engines::epoch::{Transition as EpochTransition, PendingTransition},
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
errors::EthcoreResult,
|
errors::EthcoreResult,
|
||||||
header::Header,
|
header::Header,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
verification_queue_info::VerificationQueueInfo as BlockQueueInfo,
|
verification::VerificationQueueInfo as BlockQueueInfo,
|
||||||
};
|
};
|
||||||
use kvdb::KeyValueDB;
|
use kvdb::KeyValueDB;
|
||||||
|
|
||||||
@ -528,7 +529,7 @@ impl<T: ChainDataFetcher> Client<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut batch = self.db.transaction();
|
let mut batch = self.db.transaction();
|
||||||
self.chain.insert_pending_transition(&mut batch, header.hash(), &epoch::PendingTransition {
|
self.chain.insert_pending_transition(&mut batch, header.hash(), &PendingTransition {
|
||||||
proof,
|
proof,
|
||||||
});
|
});
|
||||||
self.db.write_buffered(batch);
|
self.db.write_buffered(batch);
|
||||||
@ -616,13 +617,13 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ChainDataFetcher> ::ethcore::client::ChainInfo for Client<T> {
|
impl<T: ChainDataFetcher> client_traits::ChainInfo for Client<T> {
|
||||||
fn chain_info(&self) -> BlockChainInfo {
|
fn chain_info(&self) -> BlockChainInfo {
|
||||||
Client::chain_info(self)
|
Client::chain_info(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ChainDataFetcher> ::ethcore::client::EngineClient for Client<T> {
|
impl<T: ChainDataFetcher> client_traits::EngineClient for Client<T> {
|
||||||
fn update_sealing(&self) { }
|
fn update_sealing(&self) { }
|
||||||
fn submit_seal(&self, _block_hash: H256, _seal: Vec<Vec<u8>>) { }
|
fn submit_seal(&self, _block_hash: H256, _seal: Vec<Vec<u8>>) { }
|
||||||
fn broadcast_consensus_message(&self, _message: Vec<u8>) { }
|
fn broadcast_consensus_message(&self, _message: Vec<u8>) { }
|
||||||
@ -635,7 +636,7 @@ impl<T: ChainDataFetcher> ::ethcore::client::EngineClient for Client<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_full_client(&self) -> Option<&dyn (::ethcore::client::BlockChainClient)> {
|
fn as_full_client(&self) -> Option<&dyn (client_traits::BlockChainClient)> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ extern crate log;
|
|||||||
extern crate bincode;
|
extern crate bincode;
|
||||||
extern crate client_traits;
|
extern crate client_traits;
|
||||||
extern crate common_types;
|
extern crate common_types;
|
||||||
|
extern crate engine;
|
||||||
extern crate ethcore_blockchain;
|
extern crate ethcore_blockchain;
|
||||||
extern crate ethcore_db;
|
extern crate ethcore_db;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
|
@ -24,7 +24,7 @@ use common_types::basic_account::BasicAccount;
|
|||||||
use common_types::encoded;
|
use common_types::encoded;
|
||||||
use common_types::receipt::Receipt;
|
use common_types::receipt::Receipt;
|
||||||
use common_types::transaction::SignedTransaction;
|
use common_types::transaction::SignedTransaction;
|
||||||
use ethcore::engines::{Engine, StateDependentProof};
|
use engine::{Engine, StateDependentProof};
|
||||||
use ethcore::executive_state::{ProvedExecution, self};
|
use ethcore::executive_state::{ProvedExecution, self};
|
||||||
use ethereum_types::{H256, U256, Address};
|
use ethereum_types::{H256, U256, Address};
|
||||||
use ethtrie::{TrieError, TrieDB};
|
use ethtrie::{TrieError, TrieDB};
|
||||||
@ -1099,8 +1099,8 @@ mod tests {
|
|||||||
use trie::Recorder;
|
use trie::Recorder;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
|
|
||||||
use ethcore::client::{BlockChainClient, TestBlockChainClient, EachBlockWith};
|
use ethcore::client::{TestBlockChainClient, EachBlockWith};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::{BlockInfo, BlockChainClient};
|
||||||
use common_types::header::Header;
|
use common_types::header::Header;
|
||||||
use common_types::encoded;
|
use common_types::encoded;
|
||||||
use common_types::receipt::{Receipt, TransactionOutcome};
|
use common_types::receipt::{Receipt, TransactionOutcome};
|
||||||
|
@ -25,8 +25,12 @@ use common_types::{
|
|||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
transaction::PendingTransaction,
|
transaction::PendingTransaction,
|
||||||
};
|
};
|
||||||
use ethcore::client::{BlockChainClient, ProvingBlockChainClient, ChainInfo};
|
use client_traits::{
|
||||||
use client_traits::BlockInfo as ClientBlockInfo;
|
BlockChainClient,
|
||||||
|
BlockInfo as ClientBlockInfo,
|
||||||
|
ChainInfo,
|
||||||
|
ProvingBlockChainClient,
|
||||||
|
};
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
|
@ -16,58 +16,14 @@
|
|||||||
|
|
||||||
//! Transaction execution format module.
|
//! Transaction execution format module.
|
||||||
|
|
||||||
use ethereum_types::{U256, Address};
|
|
||||||
use parity_bytes::Bytes;
|
|
||||||
use vm;
|
|
||||||
use trace::{VMTrace, FlatTrace};
|
use trace::{VMTrace, FlatTrace};
|
||||||
use common_types::{
|
use common_types::{
|
||||||
state_diff::StateDiff,
|
engines::machine,
|
||||||
log_entry::LogEntry,
|
|
||||||
errors::ExecutionError,
|
errors::ExecutionError,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Transaction execution receipt.
|
/// /// Transaction execution receipt, parametrised with convenient defaults.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
pub type Executed = machine::Executed<FlatTrace, VMTrace>;
|
||||||
pub struct Executed<T = FlatTrace, V = VMTrace> {
|
|
||||||
/// True if the outer call/create resulted in an exceptional exit.
|
|
||||||
pub exception: Option<vm::Error>,
|
|
||||||
|
|
||||||
/// Gas paid up front for execution of transaction.
|
|
||||||
pub gas: U256,
|
|
||||||
|
|
||||||
/// Gas used during execution of transaction.
|
|
||||||
pub gas_used: U256,
|
|
||||||
|
|
||||||
/// Gas refunded after the execution of transaction.
|
|
||||||
/// To get gas that was required up front, add `refunded` and `gas_used`.
|
|
||||||
pub refunded: U256,
|
|
||||||
|
|
||||||
/// Cumulative gas used in current block so far.
|
|
||||||
///
|
|
||||||
/// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)`
|
|
||||||
///
|
|
||||||
/// where `tn` is current transaction.
|
|
||||||
pub cumulative_gas_used: U256,
|
|
||||||
|
|
||||||
/// Vector of logs generated by transaction.
|
|
||||||
pub logs: Vec<LogEntry>,
|
|
||||||
|
|
||||||
/// Addresses of contracts created during execution of transaction.
|
|
||||||
/// Ordered from earliest creation.
|
|
||||||
///
|
|
||||||
/// eg. sender creates contract A and A in constructor creates contract B
|
|
||||||
///
|
|
||||||
/// B creation ends first, and it will be the first element of the vector.
|
|
||||||
pub contracts_created: Vec<Address>,
|
|
||||||
/// Transaction output.
|
|
||||||
pub output: Bytes,
|
|
||||||
/// The trace of this transaction.
|
|
||||||
pub trace: Vec<T>,
|
|
||||||
/// The VM trace of this transaction.
|
|
||||||
pub vm_trace: Option<V>,
|
|
||||||
/// The state diff, if we traced it.
|
|
||||||
pub state_diff: Option<StateDiff>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transaction execution result.
|
/// Transaction execution result.
|
||||||
pub type ExecutionResult = Result<Box<Executed>, ExecutionError>;
|
pub type ExecutionResult = Result<Box<Executed>, ExecutionError>;
|
||||||
|
@ -36,14 +36,14 @@ use trace::{self, Tracer, VMTracer};
|
|||||||
use common_types::{
|
use common_types::{
|
||||||
errors::ExecutionError,
|
errors::ExecutionError,
|
||||||
transaction::{Action, SignedTransaction},
|
transaction::{Action, SignedTransaction},
|
||||||
|
engines::machine::Executed,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Machine,
|
Machine,
|
||||||
substate::Substate,
|
substate::Substate,
|
||||||
externalities::{Externalities, OutputPolicy, OriginInfo}, // todo: make explicit
|
externalities::{Externalities, OutputPolicy, OriginInfo},
|
||||||
transaction_ext::Transaction,
|
transaction_ext::Transaction,
|
||||||
executed::Executed,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
@ -20,7 +20,6 @@ use common_types::engines::params::CommonParams;
|
|||||||
use ethjson;
|
use ethjson;
|
||||||
use crate::Machine;
|
use crate::Machine;
|
||||||
|
|
||||||
|
|
||||||
pub fn load_machine(reader: &[u8]) -> Machine {
|
pub fn load_machine(reader: &[u8]) -> Machine {
|
||||||
let spec = ethjson::spec::Spec::load(reader).expect("chain spec is invalid");
|
let spec = ethjson::spec::Spec::load(reader).expect("chain spec is invalid");
|
||||||
|
|
||||||
|
@ -153,12 +153,13 @@ mod test {
|
|||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use ethereum_types::{U256, Address};
|
use ethereum_types::{U256, Address};
|
||||||
|
|
||||||
|
use client_traits::BlockChainClient;
|
||||||
use common_types::{
|
use common_types::{
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
transaction::{Transaction, Action}
|
transaction::{Transaction, Action}
|
||||||
};
|
};
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
client::{BlockChainClient, Client, ClientConfig},
|
client::{Client, ClientConfig},
|
||||||
spec::Spec,
|
spec::Spec,
|
||||||
miner::Miner,
|
miner::Miner,
|
||||||
test_helpers,
|
test_helpers,
|
||||||
|
@ -7,6 +7,7 @@ version = "1.12.0"
|
|||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
client-traits = { path = "../client-traits" }
|
||||||
common-types = { path = "../types" }
|
common-types = { path = "../types" }
|
||||||
ethcore = { path = ".."}
|
ethcore = { path = ".."}
|
||||||
ethcore-network = { path = "../../util/network" }
|
ethcore-network = { path = "../../util/network" }
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
//! Smart contract based node filter.
|
//! Smart contract based node filter.
|
||||||
|
|
||||||
|
extern crate client_traits;
|
||||||
extern crate common_types;
|
extern crate common_types;
|
||||||
extern crate ethabi;
|
extern crate ethabi;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
@ -25,8 +26,6 @@ extern crate ethereum_types;
|
|||||||
extern crate lru_cache;
|
extern crate lru_cache;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate ethabi_derive;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate ethabi_contract;
|
extern crate ethabi_contract;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -42,7 +41,8 @@ use std::collections::{HashMap, VecDeque};
|
|||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
|
|
||||||
use common_types::ids::BlockId;
|
use common_types::ids::BlockId;
|
||||||
use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks};
|
use ethcore::client::{ChainNotify, NewBlocks};
|
||||||
|
use client_traits::BlockChainClient;
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use ethabi::FunctionOutputDecoder;
|
use ethabi::FunctionOutputDecoder;
|
||||||
use network::{ConnectionFilter, ConnectionDirection};
|
use network::{ConnectionFilter, ConnectionDirection};
|
||||||
@ -54,7 +54,7 @@ use_contract!(peer_set, "res/peer_set.json");
|
|||||||
|
|
||||||
/// Connection filter that uses a contract to manage permissions.
|
/// Connection filter that uses a contract to manage permissions.
|
||||||
pub struct NodeFilter {
|
pub struct NodeFilter {
|
||||||
client: Weak<BlockChainClient>,
|
client: Weak<dyn BlockChainClient>,
|
||||||
contract_address: Address,
|
contract_address: Address,
|
||||||
cache: RwLock<Cache>
|
cache: RwLock<Cache>
|
||||||
}
|
}
|
||||||
@ -128,8 +128,10 @@ impl ChainNotify for NodeFilter {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use client_traits::BlockChainClient;
|
||||||
use ethcore::spec::Spec;
|
use ethcore::spec::Spec;
|
||||||
use ethcore::client::{BlockChainClient, Client, ClientConfig};
|
use ethcore::client::{Client, ClientConfig};
|
||||||
use ethcore::miner::Miner;
|
use ethcore::miner::Miner;
|
||||||
use ethcore::test_helpers;
|
use ethcore::test_helpers;
|
||||||
use network::{ConnectionDirection, ConnectionFilter, NodeId};
|
use network::{ConnectionDirection, ConnectionFilter, NodeId};
|
||||||
|
@ -81,7 +81,7 @@ pub struct SecretStoreEncryptor {
|
|||||||
config: EncryptorConfig,
|
config: EncryptorConfig,
|
||||||
client: FetchClient,
|
client: FetchClient,
|
||||||
sessions: Mutex<HashMap<Address, EncryptionSession>>,
|
sessions: Mutex<HashMap<Address, EncryptionSession>>,
|
||||||
signer: Arc<Signer>,
|
signer: Arc<dyn Signer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SecretStoreEncryptor {
|
impl SecretStoreEncryptor {
|
||||||
@ -89,7 +89,7 @@ impl SecretStoreEncryptor {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
config: EncryptorConfig,
|
config: EncryptorConfig,
|
||||||
client: FetchClient,
|
client: FetchClient,
|
||||||
signer: Arc<Signer>,
|
signer: Arc<dyn Signer>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
Ok(SecretStoreEncryptor {
|
Ok(SecretStoreEncryptor {
|
||||||
config,
|
config,
|
||||||
|
@ -91,11 +91,12 @@ use ethkey::{Signature, recover, public_to_address};
|
|||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
use machine::{
|
use machine::{
|
||||||
executive::{Executive, TransactOptions, contract_address as ethcore_contract_address},
|
executive::{Executive, TransactOptions, contract_address as ethcore_contract_address},
|
||||||
executed::Executed,
|
executed::Executed as FlatExecuted,
|
||||||
};
|
};
|
||||||
use types::{
|
use types::{
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}
|
transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction},
|
||||||
|
engines::machine::Executed,
|
||||||
};
|
};
|
||||||
use ethcore::client::{
|
use ethcore::client::{
|
||||||
Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, Call
|
Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, Call
|
||||||
@ -307,7 +308,7 @@ impl Provider {
|
|||||||
nonce_cache,
|
nonce_cache,
|
||||||
engine,
|
engine,
|
||||||
local_accounts,
|
local_accounts,
|
||||||
None, // refuse_service_transactions = true
|
None, // refuse_service_transactions = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,7 +457,7 @@ impl Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_required_signature(&self, desc: &PrivateTransactionSigningDesc, sign: Signature) -> Result<(bool, Address), Error> {
|
fn last_required_signature(&self, desc: &PrivateTransactionSigningDesc, sign: Signature) -> Result<(bool, Address), Error> {
|
||||||
let state_hash = self.calculate_state_hash(&desc.state, desc.contract_nonce);
|
let state_hash = self.calculate_state_hash(&desc.state, desc.contract_nonce);
|
||||||
match recover(&sign, &state_hash) {
|
match recover(&sign, &state_hash) {
|
||||||
Ok(public) => {
|
Ok(public) => {
|
||||||
@ -702,7 +703,7 @@ impl Provider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Call into private contract.
|
/// Call into private contract.
|
||||||
pub fn private_call(&self, block: BlockId, transaction: &SignedTransaction) -> Result<Executed, Error> {
|
pub fn private_call(&self, block: BlockId, transaction: &SignedTransaction) -> Result<FlatExecuted, Error> {
|
||||||
let result = self.execute_private(transaction, TransactOptions::with_no_tracing(), block)?;
|
let result = self.execute_private(transaction, TransactOptions::with_no_tracing(), block)?;
|
||||||
Ok(result.result)
|
Ok(result.result)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
//! Contract for private transactions tests.
|
//! Contract for private transactions tests.
|
||||||
|
|
||||||
|
extern crate client_traits;
|
||||||
extern crate common_types as types;
|
extern crate common_types as types;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
@ -36,11 +37,11 @@ use types::ids::BlockId;
|
|||||||
use types::transaction::{Transaction, Action};
|
use types::transaction::{Transaction, Action};
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
CreateContractAddress,
|
CreateContractAddress,
|
||||||
client::BlockChainClient,
|
|
||||||
test_helpers::{generate_dummy_client, push_block_with_transactions},
|
test_helpers::{generate_dummy_client, push_block_with_transactions},
|
||||||
miner::Miner,
|
miner::Miner,
|
||||||
spec,
|
spec,
|
||||||
};
|
};
|
||||||
|
use client_traits::BlockChainClient;
|
||||||
use ethkey::{Secret, KeyPair, Signature};
|
use ethkey::{Secret, KeyPair, Signature};
|
||||||
use machine::executive::contract_address;
|
use machine::executive::contract_address;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
|
@ -37,7 +37,7 @@ use std::sync::Arc;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use ethereum_types::{H256, U256, Address, Bloom};
|
use ethereum_types::{H256, U256, Address, Bloom};
|
||||||
|
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use trie_vm_factories::Factories;
|
use trie_vm_factories::Factories;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use account_state::State;
|
use account_state::State;
|
||||||
@ -485,17 +485,19 @@ pub fn enact_verified(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use test_helpers::get_temp_state_db;
|
use test_helpers::get_temp_state_db;
|
||||||
use super::*;
|
use super::*;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use vm::LastHashes;
|
use vm::LastHashes;
|
||||||
use trie_vm_factories::Factories;
|
use trie_vm_factories::Factories;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use ethereum_types::Address;
|
use ethereum_types::Address;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
use types::transaction::SignedTransaction;
|
|
||||||
use types::{
|
use types::{
|
||||||
header::Header, view, views::BlockView,
|
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
|
header::Header,
|
||||||
|
transaction::SignedTransaction,
|
||||||
|
view,
|
||||||
|
views::BlockView,
|
||||||
|
verification::Unverified,
|
||||||
};
|
};
|
||||||
use hash_db::EMPTY_PREFIX;
|
use hash_db::EMPTY_PREFIX;
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use engines::{Engine, EpochVerifier};
|
use engine::{Engine, EpochVerifier};
|
||||||
|
|
||||||
use blockchain::BlockChain;
|
use blockchain::BlockChain;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -21,7 +21,7 @@ use ethereum_types::H256;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use memory_cache::MemoryLruCache;
|
use memory_cache::MemoryLruCache;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
use types::verification::Unverified;
|
||||||
|
|
||||||
/// Recently seen bad blocks.
|
/// Recently seen bad blocks.
|
||||||
pub struct BadBlocks {
|
pub struct BadBlocks {
|
||||||
|
@ -39,20 +39,18 @@ use hash_db::EMPTY_PREFIX;
|
|||||||
use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
|
use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
|
||||||
use client::ancient_import::AncientVerifier;
|
use client::ancient_import::AncientVerifier;
|
||||||
use client::{
|
use client::{
|
||||||
Nonce, Balance, ChainInfo, TransactionInfo,
|
ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, StateInfo,
|
||||||
ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock,
|
Call, BlockProducer, SealedBlockImporter, ChainNotify, EngineInfo,
|
||||||
BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call,
|
ClientConfig, NewBlocks, ChainRoute, ChainMessageType, bad_blocks, ClientIoMessage,
|
||||||
AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter,
|
|
||||||
BlockChainReset
|
|
||||||
};
|
};
|
||||||
use client::{
|
use client_traits::{
|
||||||
ClientConfig, BlockChainClient,
|
BlockInfo, ScheduleInfo, StateClient, BlockChainReset,
|
||||||
TraceFilter, CallAnalytics, Mode,
|
Nonce, Balance, ChainInfo, TransactionInfo, ImportBlock,
|
||||||
ChainNotify, NewBlocks, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType,
|
AccountData, BlockChain as BlockChainTrait, BlockChainClient,
|
||||||
IoClient, BadBlocks, bad_blocks, ClientIoMessage,
|
IoClient, BadBlocks, ProvingBlockChainClient,
|
||||||
|
StateOrBlock
|
||||||
};
|
};
|
||||||
use client_traits::BlockInfo;
|
use engine::Engine;
|
||||||
use engines::{Engine, EpochTransition, ForkChoice};
|
|
||||||
use machine::{
|
use machine::{
|
||||||
executed::Executed,
|
executed::Executed,
|
||||||
executive::{Executive, TransactOptions, contract_address},
|
executive::{Executive, TransactOptions, contract_address},
|
||||||
@ -70,11 +68,14 @@ use types::{
|
|||||||
ancestry_action::AncestryAction,
|
ancestry_action::AncestryAction,
|
||||||
BlockNumber,
|
BlockNumber,
|
||||||
block::PreverifiedBlock,
|
block::PreverifiedBlock,
|
||||||
|
block_status::BlockStatus,
|
||||||
|
blockchain_info::BlockChainInfo,
|
||||||
encoded,
|
encoded,
|
||||||
engines::{
|
engines::{
|
||||||
|
ForkChoice,
|
||||||
SealingState,
|
SealingState,
|
||||||
MAX_UNCLE_AGE,
|
MAX_UNCLE_AGE,
|
||||||
epoch::PendingTransition,
|
epoch::{PendingTransition, Transition as EpochTransition},
|
||||||
machine::{AuxiliaryData, Call as MachineCall},
|
machine::{AuxiliaryData, Call as MachineCall},
|
||||||
},
|
},
|
||||||
errors::{EngineError, ExecutionError, BlockError, EthcoreError, SnapshotError, ImportError, EthcoreResult},
|
errors::{EngineError, ExecutionError, BlockError, EthcoreError, SnapshotError, ImportError, EthcoreResult},
|
||||||
@ -84,10 +85,15 @@ use types::{
|
|||||||
log_entry::LocalizedLogEntry,
|
log_entry::LocalizedLogEntry,
|
||||||
receipt::{Receipt, LocalizedReceipt},
|
receipt::{Receipt, LocalizedReceipt},
|
||||||
header::Header,
|
header::Header,
|
||||||
|
snapshot::Progress,
|
||||||
|
trace_filter::Filter as TraceFilter,
|
||||||
|
pruning_info::PruningInfo,
|
||||||
|
call_analytics::CallAnalytics,
|
||||||
|
client_types::Mode,
|
||||||
|
verification::{Unverified, VerificationQueueInfo as BlockQueueInfo},
|
||||||
};
|
};
|
||||||
|
|
||||||
use verification::queue::kind::BlockLike;
|
use verification::queue::kind::BlockLike;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
use verification::{Verifier, BlockQueue};
|
use verification::{Verifier, BlockQueue};
|
||||||
use verification;
|
use verification;
|
||||||
use ansi_term::Colour;
|
use ansi_term::Colour;
|
||||||
@ -95,9 +101,6 @@ use ethtrie::Layout;
|
|||||||
// re-export
|
// re-export
|
||||||
pub use blockchain::CacheSize as BlockChainCacheSize;
|
pub use blockchain::CacheSize as BlockChainCacheSize;
|
||||||
use db::{Writable, Readable, keys::BlockDetails};
|
use db::{Writable, Readable, keys::BlockDetails};
|
||||||
pub use types::blockchain_info::BlockChainInfo;
|
|
||||||
pub use types::block_status::BlockStatus;
|
|
||||||
pub use types::verification_queue_info::VerificationQueueInfo as BlockQueueInfo;
|
|
||||||
|
|
||||||
use_contract!(registry, "res/contracts/registrar.json");
|
use_contract!(registry, "res/contracts/registrar.json");
|
||||||
|
|
||||||
@ -604,7 +607,7 @@ impl Importer {
|
|||||||
state_db: &StateDB,
|
state_db: &StateDB,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
) -> EthcoreResult<Option<PendingTransition>> {
|
) -> EthcoreResult<Option<PendingTransition>> {
|
||||||
use engines::EpochChange;
|
use engine::EpochChange;
|
||||||
|
|
||||||
let hash = header.hash();
|
let hash = header.hash();
|
||||||
let auxiliary = AuxiliaryData {
|
let auxiliary = AuxiliaryData {
|
||||||
@ -614,7 +617,7 @@ impl Importer {
|
|||||||
|
|
||||||
match self.engine.signals_epoch_end(header, auxiliary) {
|
match self.engine.signals_epoch_end(header, auxiliary) {
|
||||||
EpochChange::Yes(proof) => {
|
EpochChange::Yes(proof) => {
|
||||||
use engines::Proof;
|
use engine::Proof;
|
||||||
|
|
||||||
let proof = match proof {
|
let proof = match proof {
|
||||||
Proof::Known(proof) => proof,
|
Proof::Known(proof) => proof,
|
||||||
@ -1163,7 +1166,7 @@ impl Client {
|
|||||||
&self,
|
&self,
|
||||||
writer: W,
|
writer: W,
|
||||||
at: BlockId,
|
at: BlockId,
|
||||||
p: &snapshot::Progress,
|
p: &Progress,
|
||||||
) -> Result<(), EthcoreError> {
|
) -> Result<(), EthcoreError> {
|
||||||
let db = self.state_db.read().journal_db().boxed_clone();
|
let db = self.state_db.read().journal_db().boxed_clone();
|
||||||
let best_block_number = self.chain_info().best_block_number;
|
let best_block_number = self.chain_info().best_block_number;
|
||||||
@ -1275,6 +1278,7 @@ impl Client {
|
|||||||
t: &SignedTransaction,
|
t: &SignedTransaction,
|
||||||
analytics: CallAnalytics,
|
analytics: CallAnalytics,
|
||||||
) -> Result<Executed, CallError> {
|
) -> Result<Executed, CallError> {
|
||||||
|
use types::engines::machine::Executed as RawExecuted;
|
||||||
fn call<V, T>(
|
fn call<V, T>(
|
||||||
state: &mut State<StateDB>,
|
state: &mut State<StateDB>,
|
||||||
env_info: &EnvInfo,
|
env_info: &EnvInfo,
|
||||||
@ -1282,7 +1286,7 @@ impl Client {
|
|||||||
state_diff: bool,
|
state_diff: bool,
|
||||||
transaction: &SignedTransaction,
|
transaction: &SignedTransaction,
|
||||||
options: TransactOptions<T, V>,
|
options: TransactOptions<T, V>,
|
||||||
) -> Result<Executed<T::Output, V::Output>, CallError> where
|
) -> Result<RawExecuted<T::Output, V::Output>, CallError> where
|
||||||
T: trace::Tracer,
|
T: trace::Tracer,
|
||||||
V: trace::VMTracer,
|
V: trace::VMTracer,
|
||||||
{
|
{
|
||||||
@ -2507,7 +2511,7 @@ impl SealedBlockImporter for Client {}
|
|||||||
impl ::miner::TransactionVerifierClient for Client {}
|
impl ::miner::TransactionVerifierClient for Client {}
|
||||||
impl ::miner::BlockChainClient for Client {}
|
impl ::miner::BlockChainClient for Client {}
|
||||||
|
|
||||||
impl super::traits::EngineClient for Client {
|
impl client_traits::EngineClient for Client {
|
||||||
fn update_sealing(&self) {
|
fn update_sealing(&self) {
|
||||||
self.importer.miner.update_sealing(self)
|
self.importer.miner.update_sealing(self)
|
||||||
}
|
}
|
||||||
@ -2523,7 +2527,7 @@ impl super::traits::EngineClient for Client {
|
|||||||
self.notify(|notify| notify.broadcast(ChainMessageType::Consensus(message.clone())));
|
self.notify(|notify| notify.broadcast(ChainMessageType::Consensus(message.clone())));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn epoch_transition_for(&self, parent_hash: H256) -> Option<::engines::EpochTransition> {
|
fn epoch_transition_for(&self, parent_hash: H256) -> Option<EpochTransition> {
|
||||||
self.chain.read().epoch_transition_for(parent_hash)
|
self.chain.read().epoch_transition_for(parent_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2657,9 +2661,10 @@ impl IoChannelQueue {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use client::{BlockChainClient, ChainInfo};
|
use client_traits::{BlockChainClient, ChainInfo};
|
||||||
use types::{
|
use types::{
|
||||||
encoded,
|
encoded,
|
||||||
|
engines::ForkChoice,
|
||||||
ids::{BlockId, TransactionId},
|
ids::{BlockId, TransactionId},
|
||||||
log_entry::{LogEntry, LocalizedLogEntry},
|
log_entry::{LogEntry, LocalizedLogEntry},
|
||||||
receipt::{Receipt, LocalizedReceipt, TransactionOutcome},
|
receipt::{Receipt, LocalizedReceipt, TransactionOutcome},
|
||||||
@ -2690,7 +2695,7 @@ mod tests {
|
|||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut batch = DBTransaction::new();
|
let mut batch = DBTransaction::new();
|
||||||
another_client.chain.read().insert_block(&mut batch, encoded::Block::new(new_block), Vec::new(), ExtrasInsert {
|
another_client.chain.read().insert_block(&mut batch, encoded::Block::new(new_block), Vec::new(), ExtrasInsert {
|
||||||
fork_choice: ::engines::ForkChoice::New,
|
fork_choice: ForkChoice::New,
|
||||||
is_finalized: false,
|
is_finalized: false,
|
||||||
});
|
});
|
||||||
go_thread.store(true, Ordering::SeqCst);
|
go_thread.store(true, Ordering::SeqCst);
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
|
||||||
|
|
||||||
use verification::{VerifierType, QueueConfig};
|
use verification::{VerifierType, QueueConfig};
|
||||||
use journaldb;
|
use journaldb;
|
||||||
use snapshot::SnapshotConfiguration;
|
use snapshot::SnapshotConfiguration;
|
||||||
|
use types::client_types::Mode;
|
||||||
|
|
||||||
pub use std::time::Duration;
|
pub use std::time::Duration;
|
||||||
pub use blockchain::Config as BlockChainConfig;
|
pub use blockchain::Config as BlockChainConfig;
|
||||||
@ -56,32 +56,6 @@ impl FromStr for DatabaseCompactionProfile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Operating mode for the client.
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
|
||||||
pub enum Mode {
|
|
||||||
/// Always on.
|
|
||||||
Active,
|
|
||||||
/// Goes offline after client is inactive for some (given) time, but
|
|
||||||
/// comes back online after a while of inactivity.
|
|
||||||
Passive(Duration, Duration),
|
|
||||||
/// Goes offline after client is inactive for some (given) time and
|
|
||||||
/// stays inactive.
|
|
||||||
Dark(Duration),
|
|
||||||
/// Always off.
|
|
||||||
Off,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Mode {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
|
||||||
match *self {
|
|
||||||
Mode::Active => write!(f, "active"),
|
|
||||||
Mode::Passive(..) => write!(f, "passive"),
|
|
||||||
Mode::Dark(..) => write!(f, "dark"),
|
|
||||||
Mode::Off => write!(f, "offline"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Client configuration. Includes configs for all sub-systems.
|
/// Client configuration. Includes configs for all sub-systems.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct ClientConfig {
|
pub struct ClientConfig {
|
||||||
|
@ -26,8 +26,8 @@ mod io_message;
|
|||||||
#[cfg(any(test, feature = "test-helpers"))]
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
mod test_client;
|
mod test_client;
|
||||||
|
|
||||||
pub use self::client::*;
|
pub use self::client::{Client, ClientReport};
|
||||||
pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType};
|
pub use self::config::{ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType};
|
||||||
#[cfg(any(test, feature = "test-helpers"))]
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess};
|
pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess};
|
||||||
pub use self::io_message::ClientIoMessage;
|
pub use self::io_message::ClientIoMessage;
|
||||||
@ -35,17 +35,11 @@ pub use self::io_message::ClientIoMessage;
|
|||||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith, TestState};
|
pub use self::test_client::{TestBlockChainClient, EachBlockWith, TestState};
|
||||||
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
|
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
|
||||||
pub use self::traits::{
|
pub use self::traits::{
|
||||||
Nonce, Balance, ChainInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
|
ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock,
|
||||||
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks,
|
Call, EngineInfo, BlockProducer, SealedBlockImporter,
|
||||||
BlockChainReset, BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient
|
|
||||||
};
|
};
|
||||||
pub use account_state::state::StateInfo;
|
pub use account_state::state::StateInfo;
|
||||||
|
|
||||||
use types::{
|
|
||||||
trace_filter::Filter as TraceFilter,
|
|
||||||
pruning_info::PruningInfo,
|
|
||||||
call_analytics::CallAnalytics,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use vm::{LastHashes, EnvInfo};
|
pub use vm::{LastHashes, EnvInfo};
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ use rustc_hex::FromHex;
|
|||||||
use types::{
|
use types::{
|
||||||
BlockNumber,
|
BlockNumber,
|
||||||
encoded,
|
encoded,
|
||||||
|
engines::epoch::Transition as EpochTransition,
|
||||||
ids::{BlockId, TransactionId, UncleId, TraceId},
|
ids::{BlockId, TransactionId, UncleId, TraceId},
|
||||||
basic_account::BasicAccount,
|
basic_account::BasicAccount,
|
||||||
errors::{EthcoreError as Error, EthcoreResult},
|
errors::{EthcoreError as Error, EthcoreResult},
|
||||||
@ -53,20 +54,26 @@ use types::{
|
|||||||
receipt::{Receipt, LocalizedReceipt, TransactionOutcome},
|
receipt::{Receipt, LocalizedReceipt, TransactionOutcome},
|
||||||
view,
|
view,
|
||||||
views::BlockView,
|
views::BlockView,
|
||||||
|
verification::Unverified,
|
||||||
|
client_types::Mode,
|
||||||
|
blockchain_info::BlockChainInfo,
|
||||||
|
block_status::BlockStatus,
|
||||||
};
|
};
|
||||||
use vm::Schedule;
|
use vm::Schedule;
|
||||||
|
|
||||||
use block::{OpenBlock, SealedBlock, ClosedBlock};
|
use block::{OpenBlock, SealedBlock, ClosedBlock};
|
||||||
use call_contract::{CallContract, RegistryInfo};
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
use client::{
|
use client::{
|
||||||
Nonce, Balance, ChainInfo, ReopenBlock, TransactionInfo,
|
ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, Call,
|
||||||
PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, Mode,
|
EngineInfo, BlockProducer, SealedBlockImporter,
|
||||||
LastHashes, ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock,
|
LastHashes,
|
||||||
ImportBlock, StateOrBlock, Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer,
|
|
||||||
SealedBlockImporter, IoClient, BadBlocks
|
|
||||||
};
|
};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::{
|
||||||
use engines::Engine;
|
BlockInfo, Nonce, Balance, ChainInfo, TransactionInfo, BlockChainClient, ImportBlock,
|
||||||
|
AccountData, BlockChain, IoClient, BadBlocks, ScheduleInfo, StateClient, ProvingBlockChainClient,
|
||||||
|
StateOrBlock
|
||||||
|
};
|
||||||
|
use engine::Engine;
|
||||||
use machine::executed::Executed;
|
use machine::executed::Executed;
|
||||||
use journaldb;
|
use journaldb;
|
||||||
use miner::{self, Miner, MinerService};
|
use miner::{self, Miner, MinerService};
|
||||||
@ -75,7 +82,6 @@ use account_state::state::StateInfo;
|
|||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use trace::LocalizedTrace;
|
use trace::LocalizedTrace;
|
||||||
use verification::queue::QueueInfo as BlockQueueInfo;
|
use verification::queue::QueueInfo as BlockQueueInfo;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
|
|
||||||
/// Test client.
|
/// Test client.
|
||||||
pub struct TestBlockChainClient {
|
pub struct TestBlockChainClient {
|
||||||
@ -945,7 +951,7 @@ impl ProvingBlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::traits::EngineClient for TestBlockChainClient {
|
impl client_traits::EngineClient for TestBlockChainClient {
|
||||||
fn update_sealing(&self) {
|
fn update_sealing(&self) {
|
||||||
self.miner.update_sealing(self)
|
self.miner.update_sealing(self)
|
||||||
}
|
}
|
||||||
@ -959,7 +965,7 @@ impl super::traits::EngineClient for TestBlockChainClient {
|
|||||||
|
|
||||||
fn broadcast_consensus_message(&self, _message: Bytes) {}
|
fn broadcast_consensus_message(&self, _message: Bytes) {}
|
||||||
|
|
||||||
fn epoch_transition_for(&self, _block_hash: H256) -> Option<::engines::EpochTransition> {
|
fn epoch_transition_for(&self, _block_hash: H256) -> Option<EpochTransition> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,138 +14,20 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use blockchain::{BlockReceipts, TreeRoute, BlockProvider};
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use call_contract::{CallContract, RegistryInfo};
|
|
||||||
use client_traits::BlockInfo;
|
|
||||||
use ethcore_miner::pool::VerifiedTransaction;
|
|
||||||
use ethereum_types::{H256, U256, Address};
|
use ethereum_types::{H256, U256, Address};
|
||||||
use evm::Schedule;
|
|
||||||
use itertools::Itertools;
|
|
||||||
use kvdb::DBValue;
|
|
||||||
use types::{
|
use types::{
|
||||||
transaction::{self, LocalizedTransaction, SignedTransaction, CallError},
|
transaction::{SignedTransaction, CallError},
|
||||||
BlockNumber,
|
|
||||||
basic_account::BasicAccount,
|
|
||||||
block_status::BlockStatus,
|
|
||||||
blockchain_info::BlockChainInfo,
|
|
||||||
call_analytics::CallAnalytics,
|
call_analytics::CallAnalytics,
|
||||||
encoded,
|
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
errors::EthcoreResult,
|
errors::EthcoreResult,
|
||||||
filter::Filter,
|
|
||||||
header::Header,
|
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 block::{OpenBlock, SealedBlock, ClosedBlock};
|
||||||
use client::Mode;
|
use engine::Engine;
|
||||||
use engines::Engine;
|
|
||||||
use machine::executed::Executed;
|
use machine::executed::Executed;
|
||||||
use account_state::state::StateInfo;
|
use account_state::state::StateInfo;
|
||||||
use trace::LocalizedTrace;
|
|
||||||
use verification::queue::kind::blocks::Unverified; // todo this is reexported from common_types
|
|
||||||
|
|
||||||
/// State information to be used during client query
|
|
||||||
pub enum StateOrBlock {
|
|
||||||
/// State to be used, may be pending
|
|
||||||
State(Box<dyn StateInfo>),
|
|
||||||
|
|
||||||
/// Id of an existing block from a chain to get state from
|
|
||||||
Block(BlockId)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Box<dyn StateInfo>> for StateOrBlock {
|
|
||||||
fn from(info: Box<dyn StateInfo>) -> StateOrBlock {
|
|
||||||
StateOrBlock::State(info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<BlockId> for StateOrBlock {
|
|
||||||
fn from(id: BlockId) -> StateOrBlock {
|
|
||||||
StateOrBlock::Block(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides `nonce` and `latest_nonce` methods
|
|
||||||
pub trait Nonce {
|
|
||||||
/// Attempt to get address nonce at given block.
|
|
||||||
/// May not fail on BlockId::Latest.
|
|
||||||
fn nonce(&self, address: &Address, id: BlockId) -> Option<U256>;
|
|
||||||
|
|
||||||
/// Get address nonce at the latest block's state.
|
|
||||||
fn latest_nonce(&self, address: &Address) -> U256 {
|
|
||||||
self.nonce(address, BlockId::Latest)
|
|
||||||
.expect("nonce will return Some when given BlockId::Latest. nonce was given BlockId::Latest. \
|
|
||||||
Therefore nonce has returned Some; qed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides `balance` and `latest_balance` methods
|
|
||||||
pub trait Balance {
|
|
||||||
/// Get address balance at the given block's state.
|
|
||||||
///
|
|
||||||
/// May not return None if given BlockId::Latest.
|
|
||||||
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
|
||||||
fn balance(&self, address: &Address, state: StateOrBlock) -> Option<U256>;
|
|
||||||
|
|
||||||
/// Get address balance at the latest block's state.
|
|
||||||
fn latest_balance(&self, address: &Address) -> U256 {
|
|
||||||
self.balance(address, BlockId::Latest.into())
|
|
||||||
.expect("balance will return Some if given BlockId::Latest. balance was given BlockId::Latest \
|
|
||||||
Therefore balance has returned Some; qed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides methods to access account info
|
|
||||||
pub trait AccountData: Nonce + Balance {}
|
|
||||||
|
|
||||||
/// Provides `chain_info` method
|
|
||||||
pub trait ChainInfo {
|
|
||||||
/// Get blockchain information.
|
|
||||||
fn chain_info(&self) -> BlockChainInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides various information on a transaction by it's ID
|
|
||||||
pub trait TransactionInfo {
|
|
||||||
/// Get the hash of block that contains the transaction, if any.
|
|
||||||
fn transaction_block(&self, id: TransactionId) -> Option<H256>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides methods to access chain state
|
|
||||||
pub trait StateClient {
|
|
||||||
/// Type representing chain state
|
|
||||||
type State: StateInfo;
|
|
||||||
|
|
||||||
/// Get a copy of the best block's state.
|
|
||||||
fn latest_state(&self) -> Self::State;
|
|
||||||
|
|
||||||
/// Attempt to get a copy of a specific block's final state.
|
|
||||||
///
|
|
||||||
/// This will not fail if given BlockId::Latest.
|
|
||||||
/// Otherwise, this can fail (but may not) if the DB prunes state or the block
|
|
||||||
/// is unknown.
|
|
||||||
fn state_at(&self, id: BlockId) -> Option<Self::State>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides various blockchain information, like block header, chain state etc.
|
|
||||||
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
|
|
||||||
|
|
||||||
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
|
|
||||||
/// Provides methods to import block into blockchain
|
|
||||||
pub trait ImportBlock {
|
|
||||||
/// Import a block into the blockchain.
|
|
||||||
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides `call` and `call_many` methods
|
/// Provides `call` and `call_many` methods
|
||||||
pub trait Call {
|
pub trait Call {
|
||||||
@ -169,201 +51,6 @@ pub trait EngineInfo {
|
|||||||
fn engine(&self) -> &dyn Engine;
|
fn engine(&self) -> &dyn Engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// IO operations that should off-load heavy work to another thread.
|
|
||||||
pub trait IoClient: Sync + Send {
|
|
||||||
/// Queue transactions for importing.
|
|
||||||
fn queue_transactions(&self, transactions: Vec<Bytes>, peer_id: usize);
|
|
||||||
|
|
||||||
/// Queue block import with transaction receipts. Does no sealing and transaction validation.
|
|
||||||
fn queue_ancient_block(&self, block_bytes: Unverified, receipts_bytes: Bytes) -> EthcoreResult<H256>;
|
|
||||||
|
|
||||||
/// Queue consensus engine message.
|
|
||||||
fn queue_consensus_message(&self, message: Bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides recently seen bad blocks.
|
|
||||||
pub trait BadBlocks {
|
|
||||||
/// Returns a list of blocks that were recently not imported because they were invalid.
|
|
||||||
fn bad_blocks(&self) -> Vec<(Unverified, String)>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
|
||||||
pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContract + RegistryInfo + ImportBlock
|
|
||||||
+ IoClient + BadBlocks {
|
|
||||||
/// Look up the block number for the given block ID.
|
|
||||||
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
|
||||||
|
|
||||||
/// Get raw block body data by block id.
|
|
||||||
/// Block body is an RLP list of two items: uncles and transactions.
|
|
||||||
fn block_body(&self, id: BlockId) -> Option<encoded::Body>;
|
|
||||||
|
|
||||||
/// Get block status by block header hash.
|
|
||||||
fn block_status(&self, id: BlockId) -> BlockStatus;
|
|
||||||
|
|
||||||
/// Get block total difficulty.
|
|
||||||
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
|
|
||||||
|
|
||||||
/// Attempt to get address storage root at given block.
|
|
||||||
/// May not fail on BlockId::Latest.
|
|
||||||
fn storage_root(&self, address: &Address, id: BlockId) -> Option<H256>;
|
|
||||||
|
|
||||||
/// Get block hash.
|
|
||||||
fn block_hash(&self, id: BlockId) -> Option<H256>;
|
|
||||||
|
|
||||||
/// Get address code at given block's state.
|
|
||||||
fn code(&self, address: &Address, state: StateOrBlock) -> Option<Option<Bytes>>;
|
|
||||||
|
|
||||||
/// Get address code at the latest block's state.
|
|
||||||
fn latest_code(&self, address: &Address) -> Option<Bytes> {
|
|
||||||
self.code(address, BlockId::Latest.into())
|
|
||||||
.expect("code will return Some if given BlockId::Latest; qed")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a reference to the `BlockProvider`.
|
|
||||||
fn chain(&self) -> Arc<dyn BlockProvider>;
|
|
||||||
|
|
||||||
/// Get block queue information.
|
|
||||||
fn queue_info(&self) -> BlockQueueInfo;
|
|
||||||
|
|
||||||
/// Get address code hash at given block's state.
|
|
||||||
|
|
||||||
/// Get value of the storage at given position at the given block's state.
|
|
||||||
///
|
|
||||||
/// May not return None if given BlockId::Latest.
|
|
||||||
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
|
||||||
fn storage_at(&self, address: &Address, position: &H256, state: StateOrBlock) -> Option<H256>;
|
|
||||||
|
|
||||||
/// Get value of the storage at given position at the latest block's state.
|
|
||||||
fn latest_storage_at(&self, address: &Address, position: &H256) -> H256 {
|
|
||||||
self.storage_at(address, position, BlockId::Latest.into())
|
|
||||||
.expect("storage_at will return Some if given BlockId::Latest. storage_at was given BlockId::Latest. \
|
|
||||||
Therefore storage_at has returned Some; qed")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`.
|
|
||||||
/// If `after` is set the list starts with the following item.
|
|
||||||
fn list_accounts(&self, id: BlockId, after: Option<&Address>, count: u64) -> Option<Vec<Address>>;
|
|
||||||
|
|
||||||
/// Get a list of all storage keys in the block `id`, if fat DB is in operation, otherwise `None`.
|
|
||||||
/// If `after` is set the list starts with the following item.
|
|
||||||
fn list_storage(&self, id: BlockId, account: &Address, after: Option<&H256>, count: u64) -> Option<Vec<H256>>;
|
|
||||||
|
|
||||||
/// Get transaction with given hash.
|
|
||||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction>;
|
|
||||||
|
|
||||||
/// Get uncle with given id.
|
|
||||||
fn uncle(&self, id: UncleId) -> Option<encoded::Header>;
|
|
||||||
|
|
||||||
/// Get transaction receipt with given hash.
|
|
||||||
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt>;
|
|
||||||
|
|
||||||
/// Get localized receipts for all transaction in given block.
|
|
||||||
fn localized_block_receipts(&self, id: BlockId) -> Option<Vec<LocalizedReceipt>>;
|
|
||||||
|
|
||||||
/// Get a tree route between `from` and `to`.
|
|
||||||
/// See `BlockChain::tree_route`.
|
|
||||||
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
|
|
||||||
|
|
||||||
/// Get all possible uncle hashes for a block.
|
|
||||||
fn find_uncles(&self, hash: &H256) -> Option<Vec<H256>>;
|
|
||||||
|
|
||||||
/// Get latest state node
|
|
||||||
fn state_data(&self, hash: &H256) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Get block receipts data by block header hash.
|
|
||||||
fn block_receipts(&self, hash: &H256) -> Option<BlockReceipts>;
|
|
||||||
|
|
||||||
/// Returns true if block queue is empty.
|
|
||||||
fn is_queue_empty(&self) -> bool {
|
|
||||||
self.queue_info().is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clear block queue and abort all import activity.
|
|
||||||
fn clear_queue(&self);
|
|
||||||
|
|
||||||
/// Returns logs matching given filter. If one of the filtering block cannot be found, returns the block id that caused the error.
|
|
||||||
fn logs(&self, filter: Filter) -> Result<Vec<LocalizedLogEntry>, BlockId>;
|
|
||||||
|
|
||||||
/// Replays a given transaction for inspection.
|
|
||||||
fn replay(&self, t: TransactionId, analytics: CallAnalytics) -> Result<Executed, CallError>;
|
|
||||||
|
|
||||||
/// Replays all the transactions in a given block for inspection.
|
|
||||||
fn replay_block_transactions(&self, block: BlockId, analytics: CallAnalytics) -> Result<Box<dyn Iterator<Item = (H256, Executed)>>, CallError>;
|
|
||||||
|
|
||||||
/// Returns traces matching given filter.
|
|
||||||
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>>;
|
|
||||||
|
|
||||||
/// Returns trace with given id.
|
|
||||||
fn trace(&self, trace: TraceId) -> Option<LocalizedTrace>;
|
|
||||||
|
|
||||||
/// Returns traces created by transaction.
|
|
||||||
fn transaction_traces(&self, trace: TransactionId) -> Option<Vec<LocalizedTrace>>;
|
|
||||||
|
|
||||||
/// Returns traces created by transaction from block.
|
|
||||||
fn block_traces(&self, trace: BlockId) -> Option<Vec<LocalizedTrace>>;
|
|
||||||
|
|
||||||
/// Get last hashes starting from best block.
|
|
||||||
fn last_hashes(&self) -> LastHashes;
|
|
||||||
|
|
||||||
/// List all ready transactions that should be propagated to other peers.
|
|
||||||
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>>;
|
|
||||||
|
|
||||||
/// Sorted list of transaction gas prices from at least last sample_size blocks.
|
|
||||||
fn gas_price_corpus(&self, sample_size: usize) -> ::stats::Corpus<U256> {
|
|
||||||
let mut h = self.chain_info().best_block_hash;
|
|
||||||
let mut corpus = Vec::new();
|
|
||||||
while corpus.is_empty() {
|
|
||||||
for _ in 0..sample_size {
|
|
||||||
let block = match self.block(BlockId::Hash(h)) {
|
|
||||||
Some(block) => block,
|
|
||||||
None => return corpus.into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if block.number() == 0 {
|
|
||||||
return corpus.into();
|
|
||||||
}
|
|
||||||
block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price()));
|
|
||||||
h = block.parent_hash().clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
corpus.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the preferred chain ID to sign on
|
|
||||||
fn signing_chain_id(&self) -> Option<u64>;
|
|
||||||
|
|
||||||
/// Get the mode.
|
|
||||||
fn mode(&self) -> Mode;
|
|
||||||
|
|
||||||
/// Set the mode.
|
|
||||||
fn set_mode(&self, mode: Mode);
|
|
||||||
|
|
||||||
/// Get the chain spec name.
|
|
||||||
fn spec_name(&self) -> String;
|
|
||||||
|
|
||||||
/// Set the chain via a spec name.
|
|
||||||
fn set_spec_name(&self, spec_name: String) -> Result<(), ()>;
|
|
||||||
|
|
||||||
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
|
||||||
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
|
||||||
fn disable(&self);
|
|
||||||
|
|
||||||
/// Returns engine-related extra info for `BlockId`.
|
|
||||||
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>>;
|
|
||||||
|
|
||||||
/// Returns engine-related extra info for `UncleId`.
|
|
||||||
fn uncle_extra_info(&self, id: UncleId) -> Option<BTreeMap<String, String>>;
|
|
||||||
|
|
||||||
/// Returns information about pruning/data availability.
|
|
||||||
fn pruning_info(&self) -> PruningInfo;
|
|
||||||
|
|
||||||
/// Schedule state-altering transaction to be executed on the next pending block.
|
|
||||||
fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error>;
|
|
||||||
|
|
||||||
/// Get the address of the registry itself.
|
|
||||||
fn registrar_address(&self) -> Option<Address>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides `reopen_block` method
|
/// Provides `reopen_block` method
|
||||||
pub trait ReopenBlock {
|
pub trait ReopenBlock {
|
||||||
/// Reopens an OpenBlock and updates uncles.
|
/// Reopens an OpenBlock and updates uncles.
|
||||||
@ -383,12 +70,6 @@ pub trait PrepareOpenBlock {
|
|||||||
/// Provides methods used for sealing new state
|
/// Provides methods used for sealing new state
|
||||||
pub trait BlockProducer: PrepareOpenBlock + ReopenBlock {}
|
pub trait BlockProducer: PrepareOpenBlock + ReopenBlock {}
|
||||||
|
|
||||||
/// Provides `latest_schedule` method
|
|
||||||
pub trait ScheduleInfo {
|
|
||||||
/// Returns latest schedule.
|
|
||||||
fn latest_schedule(&self) -> Schedule;
|
|
||||||
}
|
|
||||||
|
|
||||||
///Provides `import_sealed_block` method
|
///Provides `import_sealed_block` method
|
||||||
pub trait ImportSealedBlock {
|
pub trait ImportSealedBlock {
|
||||||
/// Import sealed block. Skips all verifications.
|
/// Import sealed block. Skips all verifications.
|
||||||
@ -403,59 +84,3 @@ pub trait BroadcastProposalBlock {
|
|||||||
|
|
||||||
/// Provides methods to import sealed block and broadcast a block proposal
|
/// Provides methods to import sealed block and broadcast a block proposal
|
||||||
pub trait SealedBlockImporter: ImportSealedBlock + BroadcastProposalBlock {}
|
pub trait SealedBlockImporter: ImportSealedBlock + BroadcastProposalBlock {}
|
||||||
|
|
||||||
/// Client facilities used by internally sealing Engines.
|
|
||||||
pub trait EngineClient: Sync + Send + ChainInfo {
|
|
||||||
/// Make a new block and seal it.
|
|
||||||
fn update_sealing(&self);
|
|
||||||
|
|
||||||
/// Submit a seal for a block in the mining queue.
|
|
||||||
fn submit_seal(&self, block_hash: H256, seal: Vec<Bytes>);
|
|
||||||
|
|
||||||
/// Broadcast a consensus message to the network.
|
|
||||||
fn broadcast_consensus_message(&self, message: Bytes);
|
|
||||||
|
|
||||||
/// Get the transition to the epoch the given parent hash is part of
|
|
||||||
/// or transitions to.
|
|
||||||
/// This will give the epoch that any children of this parent belong to.
|
|
||||||
///
|
|
||||||
/// The block corresponding the the parent hash must be stored already.
|
|
||||||
fn epoch_transition_for(&self, parent_hash: H256) -> Option<::engines::EpochTransition>;
|
|
||||||
|
|
||||||
/// Attempt to cast the engine client to a full client.
|
|
||||||
fn as_full_client(&self) -> Option<&dyn BlockChainClient>;
|
|
||||||
|
|
||||||
/// Get a block number by ID.
|
|
||||||
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
|
||||||
|
|
||||||
/// Get raw block header data by block id.
|
|
||||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extended client interface for providing proofs of the state.
|
|
||||||
pub trait ProvingBlockChainClient: BlockChainClient {
|
|
||||||
/// Prove account storage at a specific block id.
|
|
||||||
///
|
|
||||||
/// Both provided keys assume a secure trie.
|
|
||||||
/// Returns a vector of raw trie nodes (in order from the root) proving the storage query.
|
|
||||||
fn prove_storage(&self, key1: H256, key2: H256, id: BlockId) -> Option<(Vec<Bytes>, H256)>;
|
|
||||||
|
|
||||||
/// Prove account existence at a specific block id.
|
|
||||||
/// The key is the keccak hash of the account's address.
|
|
||||||
/// Returns a vector of raw trie nodes (in order from the root) proving the query.
|
|
||||||
fn prove_account(&self, key1: H256, id: BlockId) -> Option<(Vec<Bytes>, BasicAccount)>;
|
|
||||||
|
|
||||||
/// Prove execution of a transaction at the given block.
|
|
||||||
/// Returns the output of the call and a vector of database items necessary
|
|
||||||
/// to reproduce it.
|
|
||||||
fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec<DBValue>)>;
|
|
||||||
|
|
||||||
/// Get an epoch change signal by block hash.
|
|
||||||
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// resets the blockchain
|
|
||||||
pub trait BlockChainReset {
|
|
||||||
/// reset to best_block - n
|
|
||||||
fn reset(&self, num: u32) -> Result<(), String>;
|
|
||||||
}
|
|
||||||
|
@ -24,17 +24,18 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
|||||||
use std::sync::{Weak, Arc};
|
use std::sync::{Weak, Arc};
|
||||||
use std::time::{UNIX_EPOCH, Duration};
|
use std::time::{UNIX_EPOCH, Duration};
|
||||||
|
|
||||||
use client::EngineClient;
|
use client_traits::EngineClient;
|
||||||
use engines::{Engine, Seal, ConstructedVerifier};
|
use engine::{Engine,ConstructedVerifier};
|
||||||
use engines::block_reward;
|
use engines::block_reward;
|
||||||
use engines::block_reward::{BlockRewardContract, RewardKind};
|
use engines::block_reward::{BlockRewardContract, RewardKind};
|
||||||
|
use engine::snapshot::SnapshotComponents;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use machine::{
|
use machine::{
|
||||||
ExecutedBlock,
|
ExecutedBlock,
|
||||||
Machine,
|
Machine,
|
||||||
};
|
};
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use super::signer::EngineSigner;
|
use engine::signer::EngineSigner;
|
||||||
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
|
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
|
||||||
use self::finality::RollingFinality;
|
use self::finality::RollingFinality;
|
||||||
use ethkey::{self, Signature};
|
use ethkey::{self, Signature};
|
||||||
@ -49,7 +50,10 @@ use types::{
|
|||||||
BlockNumber,
|
BlockNumber,
|
||||||
header::{Header, ExtendedHeader},
|
header::{Header, ExtendedHeader},
|
||||||
engines::{
|
engines::{
|
||||||
|
Headers,
|
||||||
params::CommonParams,
|
params::CommonParams,
|
||||||
|
PendingTransitionStore,
|
||||||
|
Seal,
|
||||||
SealingState,
|
SealingState,
|
||||||
machine::{Call, AuxiliaryData},
|
machine::{Call, AuxiliaryData},
|
||||||
},
|
},
|
||||||
@ -459,7 +463,7 @@ struct EpochVerifier {
|
|||||||
empty_steps_transition: u64,
|
empty_steps_transition: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::EpochVerifier for EpochVerifier {
|
impl engine::EpochVerifier for EpochVerifier {
|
||||||
fn verify_light(&self, header: &Header) -> Result<(), Error> {
|
fn verify_light(&self, header: &Header) -> Result<(), Error> {
|
||||||
// Validate the timestamp
|
// Validate the timestamp
|
||||||
verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?)?;
|
verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?)?;
|
||||||
@ -1273,7 +1277,7 @@ impl Engine for AuthorityRound {
|
|||||||
|
|
||||||
let rewards: Vec<_> = match self.block_reward_contract {
|
let rewards: Vec<_> = match self.block_reward_contract {
|
||||||
Some(ref c) if block.header.number() >= self.block_reward_contract_transition => {
|
Some(ref c) if block.header.number() >= self.block_reward_contract_transition => {
|
||||||
let mut call = super::default_system_or_code_call(&self.machine, block);
|
let mut call = engine::default_system_or_code_call(&self.machine, block);
|
||||||
|
|
||||||
let rewards = c.reward(beneficiaries, &mut call)?;
|
let rewards = c.reward(beneficiaries, &mut call)?;
|
||||||
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
|
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
|
||||||
@ -1429,8 +1433,8 @@ impl Engine for AuthorityRound {
|
|||||||
.map(|set_proof| combine_proofs(0, &set_proof, &[]))
|
.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) -> engine::EpochChange {
|
||||||
if self.immediate_transitions { return super::EpochChange::No }
|
if self.immediate_transitions { return engine::EpochChange::No }
|
||||||
|
|
||||||
let first = header.number() == 0;
|
let first = header.number() == 0;
|
||||||
self.validators.signals_epoch_end(first, header, aux)
|
self.validators.signals_epoch_end(first, header, aux)
|
||||||
@ -1439,8 +1443,8 @@ impl Engine for AuthorityRound {
|
|||||||
fn is_epoch_end_light(
|
fn is_epoch_end_light(
|
||||||
&self,
|
&self,
|
||||||
chain_head: &Header,
|
chain_head: &Header,
|
||||||
chain: &super::Headers<Header>,
|
chain: &Headers<Header>,
|
||||||
transition_store: &super::PendingTransitionStore,
|
transition_store: &PendingTransitionStore,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Option<Vec<u8>> {
|
||||||
// epochs only matter if we want to support light clients.
|
// epochs only matter if we want to support light clients.
|
||||||
if self.immediate_transitions { return None }
|
if self.immediate_transitions { return None }
|
||||||
@ -1483,8 +1487,8 @@ impl Engine for AuthorityRound {
|
|||||||
&self,
|
&self,
|
||||||
chain_head: &Header,
|
chain_head: &Header,
|
||||||
finalized: &[H256],
|
finalized: &[H256],
|
||||||
chain: &super::Headers<Header>,
|
chain: &Headers<Header>,
|
||||||
transition_store: &super::PendingTransitionStore,
|
transition_store: &PendingTransitionStore,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Option<Vec<u8>> {
|
||||||
// epochs only matter if we want to support light clients.
|
// epochs only matter if we want to support light clients.
|
||||||
if self.immediate_transitions { return None }
|
if self.immediate_transitions { return None }
|
||||||
@ -1591,7 +1595,7 @@ impl Engine for AuthorityRound {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot_components(&self) -> Option<Box<dyn (::snapshot::SnapshotComponents)>> {
|
fn snapshot_components(&self) -> Option<Box<dyn (SnapshotComponents)>> {
|
||||||
if self.immediate_transitions {
|
if self.immediate_transitions {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -1628,7 +1632,7 @@ mod tests {
|
|||||||
use ethkey::Signature;
|
use ethkey::Signature;
|
||||||
use types::{
|
use types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
engines::params::CommonParams,
|
engines::{Seal, params::CommonParams},
|
||||||
errors::{EthcoreError as Error, EngineError},
|
errors::{EthcoreError as Error, EngineError},
|
||||||
transaction::{Action, Transaction},
|
transaction::{Action, Transaction},
|
||||||
};
|
};
|
||||||
@ -1639,7 +1643,7 @@ mod tests {
|
|||||||
TestNotify
|
TestNotify
|
||||||
};
|
};
|
||||||
use crate::spec::{Spec, self};
|
use crate::spec::{Spec, self};
|
||||||
use engines::{Seal, Engine};
|
use engine::Engine;
|
||||||
use engines::validator_set::{TestSet, SimpleList};
|
use engines::validator_set::{TestSet, SimpleList};
|
||||||
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
|
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
|
||||||
use machine::Machine;
|
use machine::Machine;
|
||||||
|
@ -20,10 +20,14 @@ use std::sync::Weak;
|
|||||||
use ethereum_types::{H256, H520};
|
use ethereum_types::{H256, H520};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use ethkey::{self, Signature};
|
use ethkey::{self, Signature};
|
||||||
use engines::{Engine, Seal, ConstructedVerifier};
|
use engine::{
|
||||||
use engines::signer::EngineSigner;
|
Engine,
|
||||||
|
ConstructedVerifier,
|
||||||
|
snapshot::SnapshotComponents,
|
||||||
|
signer::EngineSigner,
|
||||||
|
};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use client::EngineClient;
|
use client_traits::EngineClient;
|
||||||
use machine::{
|
use machine::{
|
||||||
Machine,
|
Machine,
|
||||||
executed_block::ExecutedBlock,
|
executed_block::ExecutedBlock,
|
||||||
@ -31,7 +35,10 @@ use machine::{
|
|||||||
use types::{
|
use types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
engines::{
|
engines::{
|
||||||
|
Headers,
|
||||||
|
PendingTransitionStore,
|
||||||
SealingState,
|
SealingState,
|
||||||
|
Seal,
|
||||||
params::CommonParams,
|
params::CommonParams,
|
||||||
machine::{AuxiliaryData, Call},
|
machine::{AuxiliaryData, Call},
|
||||||
},
|
},
|
||||||
@ -59,7 +66,7 @@ struct EpochVerifier {
|
|||||||
list: SimpleList,
|
list: SimpleList,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::EpochVerifier for EpochVerifier {
|
impl engine::EpochVerifier for EpochVerifier {
|
||||||
fn verify_light(&self, header: &Header) -> Result<(), Error> {
|
fn verify_light(&self, header: &Header) -> Result<(), Error> {
|
||||||
verify_external(header, &self.list)
|
verify_external(header, &self.list)
|
||||||
}
|
}
|
||||||
@ -144,13 +151,13 @@ impl Engine for BasicAuthority {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
fn signals_epoch_end(&self, _header: &Header, _auxiliary: AuxiliaryData) -> super::EpochChange {
|
fn signals_epoch_end(&self, _header: &Header, _auxiliary: AuxiliaryData) -> engine::EpochChange {
|
||||||
// don't bother signalling even though a contract might try.
|
// don't bother signalling even though a contract might try.
|
||||||
super::EpochChange::No
|
engine::EpochChange::No
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn signals_epoch_end(&self, header: &Header, auxiliary: AuxiliaryData) -> super::EpochChange {
|
fn signals_epoch_end(&self, header: &Header, auxiliary: AuxiliaryData) -> engine::EpochChange {
|
||||||
// in test mode, always signal even though they don't be finalized.
|
// in test mode, always signal even though they don't be finalized.
|
||||||
let first = header.number() == 0;
|
let first = header.number() == 0;
|
||||||
self.validators.signals_epoch_end(first, header, auxiliary)
|
self.validators.signals_epoch_end(first, header, auxiliary)
|
||||||
@ -160,8 +167,8 @@ impl Engine for BasicAuthority {
|
|||||||
&self,
|
&self,
|
||||||
chain_head: &Header,
|
chain_head: &Header,
|
||||||
_finalized: &[H256],
|
_finalized: &[H256],
|
||||||
_chain: &super::Headers<Header>,
|
_chain: &Headers<Header>,
|
||||||
_transition_store: &super::PendingTransitionStore,
|
_transition_store: &PendingTransitionStore,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Option<Vec<u8>> {
|
||||||
let first = chain_head.number() == 0;
|
let first = chain_head.number() == 0;
|
||||||
|
|
||||||
@ -172,8 +179,8 @@ impl Engine for BasicAuthority {
|
|||||||
fn is_epoch_end_light(
|
fn is_epoch_end_light(
|
||||||
&self,
|
&self,
|
||||||
chain_head: &Header,
|
chain_head: &Header,
|
||||||
chain: &super::Headers<Header>,
|
chain: &Headers<Header>,
|
||||||
transition_store: &super::PendingTransitionStore,
|
transition_store: &PendingTransitionStore,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Option<Vec<u8>> {
|
||||||
self.is_epoch_end(chain_head, &[], chain, transition_store)
|
self.is_epoch_end(chain_head, &[], chain, transition_store)
|
||||||
}
|
}
|
||||||
@ -183,7 +190,7 @@ impl Engine for BasicAuthority {
|
|||||||
|
|
||||||
match self.validators.epoch_set(first, &self.machine, header.number(), proof) {
|
match self.validators.epoch_set(first, &self.machine, header.number(), proof) {
|
||||||
Ok((list, finalize)) => {
|
Ok((list, finalize)) => {
|
||||||
let verifier = Box::new(EpochVerifier { list: list });
|
let verifier = Box::new(EpochVerifier { list });
|
||||||
|
|
||||||
// our epoch verifier will ensure no unverified verifier is ever verified.
|
// our epoch verifier will ensure no unverified verifier is ever verified.
|
||||||
match finalize {
|
match finalize {
|
||||||
@ -211,7 +218,7 @@ impl Engine for BasicAuthority {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot_components(&self) -> Option<Box<dyn (::snapshot::SnapshotComponents)>> {
|
fn snapshot_components(&self) -> Option<Box<dyn (SnapshotComponents)>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +237,7 @@ mod tests {
|
|||||||
use accounts::AccountProvider;
|
use accounts::AccountProvider;
|
||||||
use types::header::Header;
|
use types::header::Header;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use engines::{Seal, SealingState};
|
use types::engines::{Seal, SealingState};
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
|
|
||||||
/// Create a new test chain spec with `BasicAuthority` consensus engine.
|
/// Create a new test chain spec with `BasicAuthority` consensus engine.
|
||||||
|
@ -28,7 +28,7 @@ use types::{
|
|||||||
BlockNumber,
|
BlockNumber,
|
||||||
errors::{EngineError, EthcoreError as Error},
|
errors::{EngineError, EthcoreError as Error},
|
||||||
};
|
};
|
||||||
use super::{SystemOrCodeCall, SystemOrCodeCallKind};
|
use engine::{SystemOrCodeCall, SystemOrCodeCallKind};
|
||||||
use trace::{Tracer, ExecutiveTracer, Tracing};
|
use trace::{Tracer, ExecutiveTracer, Tracing};
|
||||||
|
|
||||||
use_contract!(block_reward_contract, "res/contracts/block_reward.json");
|
use_contract!(block_reward_contract, "res/contracts/block_reward.json");
|
||||||
@ -166,7 +166,7 @@ mod test {
|
|||||||
use crate::spec;
|
use crate::spec;
|
||||||
use test_helpers::generate_dummy_client_with_spec;
|
use test_helpers::generate_dummy_client_with_spec;
|
||||||
|
|
||||||
use engines::SystemOrCodeCallKind;
|
use engine::SystemOrCodeCallKind;
|
||||||
use super::{BlockRewardContract, RewardKind};
|
use super::{BlockRewardContract, RewardKind};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -65,9 +65,15 @@ use std::thread;
|
|||||||
use std::time;
|
use std::time;
|
||||||
use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use client::EngineClient;
|
use client_traits::EngineClient;
|
||||||
use engines::clique::util::{extract_signers, recover_creator};
|
use engines::{
|
||||||
use engines::{Engine, Seal, SealingState, EthashSeal};
|
clique::util::{extract_signers, recover_creator},
|
||||||
|
EthashSeal,
|
||||||
|
};
|
||||||
|
use engine::{
|
||||||
|
Engine,
|
||||||
|
signer::EngineSigner,
|
||||||
|
};
|
||||||
use ethereum_types::{Address, H64, H160, H256, U256};
|
use ethereum_types::{Address, H64, H160, H256, U256};
|
||||||
use ethkey::Signature;
|
use ethkey::Signature;
|
||||||
use hash::KECCAK_EMPTY_LIST_RLP;
|
use hash::KECCAK_EMPTY_LIST_RLP;
|
||||||
@ -79,7 +85,6 @@ use machine::{
|
|||||||
};
|
};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use super::signer::EngineSigner;
|
|
||||||
use unexpected::{Mismatch, OutOfBounds};
|
use unexpected::{Mismatch, OutOfBounds};
|
||||||
use time_utils::CheckedSystemTime;
|
use time_utils::CheckedSystemTime;
|
||||||
use types::{
|
use types::{
|
||||||
@ -87,6 +92,8 @@ use types::{
|
|||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
header::Header,
|
header::Header,
|
||||||
engines::{
|
engines::{
|
||||||
|
Seal,
|
||||||
|
SealingState,
|
||||||
params::CommonParams,
|
params::CommonParams,
|
||||||
machine::Call,
|
machine::Call,
|
||||||
},
|
},
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! Consensus tests for `PoA Clique Engine`, see http://eips.ethereum.org/EIPS/eip-225 for more information
|
//! Consensus tests for `PoA Clique Engine`, see http://eips.ethereum.org/EIPS/eip-225 for more information
|
||||||
|
|
||||||
use block::*;
|
use block::*;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use ethereum_types::{Address, H256};
|
use ethereum_types::{Address, H256};
|
||||||
use ethkey::{Secret, KeyPair};
|
use ethkey::{Secret, KeyPair};
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
|
@ -19,6 +19,7 @@ use std::collections::BTreeMap;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use engine::snapshot::SnapshotComponents;
|
||||||
use ethereum_types::{H256, H64, U256};
|
use ethereum_types::{H256, H64, U256};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use hash::{KECCAK_EMPTY_LIST_RLP};
|
use hash::{KECCAK_EMPTY_LIST_RLP};
|
||||||
@ -33,7 +34,7 @@ use types::{
|
|||||||
use unexpected::{OutOfBounds, Mismatch};
|
use unexpected::{OutOfBounds, Mismatch};
|
||||||
|
|
||||||
use engines::block_reward::{self, BlockRewardContract, RewardKind};
|
use engines::block_reward::{self, BlockRewardContract, RewardKind};
|
||||||
use engines::{self, Engine};
|
use engine::Engine;
|
||||||
use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
|
use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
|
||||||
use machine::{
|
use machine::{
|
||||||
ExecutedBlock,
|
ExecutedBlock,
|
||||||
@ -179,7 +180,7 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
|||||||
/// mainnet chains in the Olympic, Frontier and Homestead eras.
|
/// mainnet chains in the Olympic, Frontier and Homestead eras.
|
||||||
pub struct Ethash {
|
pub struct Ethash {
|
||||||
ethash_params: EthashParams,
|
ethash_params: EthashParams,
|
||||||
pow: EthashManager,
|
pow: Arc<EthashManager>,
|
||||||
machine: Machine,
|
machine: Machine,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,17 +191,48 @@ impl Ethash {
|
|||||||
ethash_params: EthashParams,
|
ethash_params: EthashParams,
|
||||||
machine: Machine,
|
machine: Machine,
|
||||||
optimize_for: T,
|
optimize_for: T,
|
||||||
) -> Arc<Self> {
|
) -> Self {
|
||||||
let progpow_transition = ethash_params.progpow_transition;
|
let progpow_transition = ethash_params.progpow_transition;
|
||||||
|
|
||||||
Arc::new(Ethash {
|
Ethash {
|
||||||
ethash_params,
|
ethash_params,
|
||||||
machine,
|
machine,
|
||||||
pow: EthashManager::new(cache_dir.as_ref(), optimize_for.into(), progpow_transition),
|
pow: Arc::new(EthashManager::new(
|
||||||
})
|
cache_dir.as_ref(),
|
||||||
|
optimize_for.into(),
|
||||||
|
progpow_transition
|
||||||
|
)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verify_block_unordered(pow: &Arc<EthashManager>, header: &Header) -> Result<(), Error> {
|
||||||
|
let seal = Seal::parse_seal(header.seal())?;
|
||||||
|
|
||||||
|
let result = pow.compute_light(
|
||||||
|
header.number() as u64,
|
||||||
|
&header.bare_hash().0,
|
||||||
|
seal.nonce.to_low_u64_be()
|
||||||
|
);
|
||||||
|
let mix = H256(result.mix_hash);
|
||||||
|
let difficulty = ethash::boundary_to_difficulty(&H256(result.value));
|
||||||
|
trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}",
|
||||||
|
num = header.number() as u64,
|
||||||
|
seed = H256(slow_hash_block_number(header.number() as u64)),
|
||||||
|
h = header.bare_hash(),
|
||||||
|
non = seal.nonce.to_low_u64_be(),
|
||||||
|
mix = H256(result.mix_hash),
|
||||||
|
res = H256(result.value));
|
||||||
|
if mix != seal.mix_hash {
|
||||||
|
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash })));
|
||||||
|
}
|
||||||
|
if &difficulty < header.difficulty() {
|
||||||
|
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO [rphmeier]
|
// TODO [rphmeier]
|
||||||
//
|
//
|
||||||
// for now, this is different than Ethash's own epochs, and signal
|
// for now, this is different than Ethash's own epochs, and signal
|
||||||
@ -209,17 +241,17 @@ impl Ethash {
|
|||||||
// for any block in the chain.
|
// for any block in the chain.
|
||||||
// in the future, we might move the Ethash epoch
|
// in the future, we might move the Ethash epoch
|
||||||
// caching onto this mechanism as well.
|
// caching onto this mechanism as well.
|
||||||
// NOTE[dvdplm]: the reason we impl this for Arc<Ethash> and not plain Ethash is the
|
struct EpochVerifier {
|
||||||
// way `epoch_verifier()` works. This means `new()` returns an `Arc<Ethash>` which is
|
pow: Arc<EthashManager>
|
||||||
// then re-wrapped in an Arc in `spec::engine()`.
|
}
|
||||||
impl engines::EpochVerifier for Arc<Ethash> {
|
|
||||||
fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
impl engine::EpochVerifier for EpochVerifier {
|
||||||
fn verify_heavy(&self, header: &Header) -> Result<(), Error> {
|
fn verify_heavy(&self, header: &Header) -> Result<(), Error> {
|
||||||
self.verify_block_unordered(header).into()
|
verify_block_unordered(&self.pow, header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine for Arc<Ethash> {
|
impl Engine for Ethash {
|
||||||
fn name(&self) -> &str { "Ethash" }
|
fn name(&self) -> &str { "Ethash" }
|
||||||
fn machine(&self) -> &Machine { &self.machine }
|
fn machine(&self) -> &Machine { &self.machine }
|
||||||
|
|
||||||
@ -241,11 +273,6 @@ impl Engine for Arc<Ethash> {
|
|||||||
|
|
||||||
fn maximum_gas_limit(&self) -> Option<U256> { Some(0x7fff_ffff_ffff_ffffu64.into()) }
|
fn maximum_gas_limit(&self) -> Option<U256> { Some(0x7fff_ffff_ffff_ffffu64.into()) }
|
||||||
|
|
||||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
|
||||||
let difficulty = self.calculate_difficulty(header, parent);
|
|
||||||
header.set_difficulty(difficulty);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Apply the block reward on finalisation of the block.
|
/// Apply the block reward on finalisation of the block.
|
||||||
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
|
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
|
||||||
fn on_close_block(&self, block: &mut ExecutedBlock, _parent_header: &Header) -> Result<(), Error> {
|
fn on_close_block(&self, block: &mut ExecutedBlock, _parent_header: &Header) -> Result<(), Error> {
|
||||||
@ -264,7 +291,7 @@ impl Engine for Arc<Ethash> {
|
|||||||
beneficiaries.push((*uncle_author, RewardKind::uncle(number, u.number())));
|
beneficiaries.push((*uncle_author, RewardKind::uncle(number, u.number())));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut call = engines::default_system_or_code_call(&self.machine, block);
|
let mut call = engine::default_system_or_code_call(&self.machine, block);
|
||||||
|
|
||||||
let rewards = c.reward(beneficiaries, &mut call)?;
|
let rewards = c.reward(beneficiaries, &mut call)?;
|
||||||
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
|
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
|
||||||
@ -346,25 +373,7 @@ impl Engine for Arc<Ethash> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_unordered(&self, header: &Header) -> Result<(), Error> {
|
fn verify_block_unordered(&self, header: &Header) -> Result<(), Error> {
|
||||||
let seal = Seal::parse_seal(header.seal())?;
|
verify_block_unordered(&self.pow, header)
|
||||||
|
|
||||||
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, seal.nonce.to_low_u64_be());
|
|
||||||
let mix = H256(result.mix_hash);
|
|
||||||
let difficulty = ethash::boundary_to_difficulty(&H256(result.value));
|
|
||||||
trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}",
|
|
||||||
num = header.number() as u64,
|
|
||||||
seed = H256(slow_hash_block_number(header.number() as u64)),
|
|
||||||
h = header.bare_hash(),
|
|
||||||
non = seal.nonce.to_low_u64_be(),
|
|
||||||
mix = H256(result.mix_hash),
|
|
||||||
res = H256(result.value));
|
|
||||||
if mix != seal.mix_hash {
|
|
||||||
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash })));
|
|
||||||
}
|
|
||||||
if &difficulty < header.difficulty() {
|
|
||||||
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_family(&self, header: &Header, parent: &Header) -> Result<(), Error> {
|
fn verify_block_family(&self, header: &Header, parent: &Header) -> Result<(), Error> {
|
||||||
@ -382,11 +391,17 @@ impl Engine for Arc<Ethash> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> engines::ConstructedVerifier<'a> {
|
fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> engine::ConstructedVerifier<'a> {
|
||||||
engines::ConstructedVerifier::Trusted(Box::new(self.clone()))
|
let v = EpochVerifier{pow: self.pow.clone()};
|
||||||
|
engine::ConstructedVerifier::Trusted(Box::new(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot_components(&self) -> Option<Box<dyn (::snapshot::SnapshotComponents)>> {
|
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||||
|
let difficulty = self.calculate_difficulty(header, parent);
|
||||||
|
header.set_difficulty(difficulty);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn snapshot_components(&self) -> Option<Box<dyn (SnapshotComponents)>> {
|
||||||
Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS)))
|
Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +517,7 @@ mod tests {
|
|||||||
errors::{BlockError, EthcoreError as Error},
|
errors::{BlockError, EthcoreError as Error},
|
||||||
};
|
};
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use crate::spec::{new_morden, new_mcip3_test, new_homestead_test_machine};
|
use crate::spec::{new_morden, new_mcip3_test, new_homestead_test_machine};
|
||||||
use super::{Ethash, EthashParams, ecip1017_eras_block_reward};
|
use super::{Ethash, EthashParams, ecip1017_eras_block_reward};
|
||||||
use rlp;
|
use rlp;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use engines::{Engine, Seal};
|
use engine::Engine;
|
||||||
use machine::{
|
use machine::{
|
||||||
ExecutedBlock,
|
ExecutedBlock,
|
||||||
Machine
|
Machine
|
||||||
@ -22,6 +22,7 @@ use machine::{
|
|||||||
use types::{
|
use types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
engines::{
|
engines::{
|
||||||
|
Seal,
|
||||||
SealingState,
|
SealingState,
|
||||||
params::CommonParams,
|
params::CommonParams,
|
||||||
},
|
},
|
||||||
@ -110,9 +111,11 @@ mod tests {
|
|||||||
use ethereum_types::{H520, Address};
|
use ethereum_types::{H520, Address};
|
||||||
use test_helpers::get_temp_state_db;
|
use test_helpers::get_temp_state_db;
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use types::header::Header;
|
use types::{
|
||||||
|
header::Header,
|
||||||
|
engines::Seal,
|
||||||
|
};
|
||||||
use block::*;
|
use block::*;
|
||||||
use engines::Seal;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instant_can_seal() {
|
fn instant_can_seal() {
|
||||||
|
@ -25,425 +25,10 @@ mod null_engine;
|
|||||||
mod validator_set;
|
mod validator_set;
|
||||||
|
|
||||||
pub mod block_reward;
|
pub mod block_reward;
|
||||||
pub mod signer;
|
|
||||||
|
|
||||||
pub use self::authority_round::AuthorityRound;
|
pub use self::authority_round::AuthorityRound;
|
||||||
pub use self::basic_authority::BasicAuthority;
|
pub use self::basic_authority::BasicAuthority;
|
||||||
pub use self::instant_seal::{InstantSeal, InstantSealParams};
|
pub use self::instant_seal::{InstantSeal, InstantSealParams};
|
||||||
pub use self::null_engine::NullEngine;
|
pub use self::null_engine::NullEngine;
|
||||||
pub use self::signer::EngineSigner;
|
|
||||||
pub use self::clique::Clique;
|
pub use self::clique::Clique;
|
||||||
pub use self::ethash::{Ethash, Seal as EthashSeal};
|
pub use self::ethash::{Ethash, Seal as EthashSeal};
|
||||||
|
|
||||||
// TODO [ToDr] Remove re-export (#10130)
|
|
||||||
pub use types::engines::ForkChoice;
|
|
||||||
pub use types::engines::epoch::{self, Transition as EpochTransition};
|
|
||||||
|
|
||||||
use std::sync::{Weak, Arc};
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
use builtin::Builtin;
|
|
||||||
use vm::{EnvInfo, Schedule, CallType, ActionValue};
|
|
||||||
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},
|
|
||||||
};
|
|
||||||
use snapshot::SnapshotComponents;
|
|
||||||
use client::EngineClient;
|
|
||||||
|
|
||||||
use ethkey::Signature;
|
|
||||||
use machine::{
|
|
||||||
Machine,
|
|
||||||
executed_block::ExecutedBlock,
|
|
||||||
};
|
|
||||||
use ethereum_types::{H256, U256, Address};
|
|
||||||
use bytes::Bytes;
|
|
||||||
|
|
||||||
/// Seal type.
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub enum Seal {
|
|
||||||
/// Regular block seal; should be part of the blockchain.
|
|
||||||
Regular(Vec<Bytes>),
|
|
||||||
/// Engine does not generate seal for this block right now.
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A system-calling closure. Enacts calls on a block's state from the system address.
|
|
||||||
pub type SystemCall<'a> = dyn FnMut(Address, Vec<u8>) -> Result<Vec<u8>, String> + 'a;
|
|
||||||
|
|
||||||
/// A system-calling closure. Enacts calls on a block's state with code either from an on-chain contract, or hard-coded EVM or WASM (if enabled on-chain) codes.
|
|
||||||
pub type SystemOrCodeCall<'a> = dyn FnMut(SystemOrCodeCallKind, Vec<u8>) -> Result<Vec<u8>, String> + 'a;
|
|
||||||
|
|
||||||
/// Kind of SystemOrCodeCall, this is either an on-chain address, or code.
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
|
||||||
pub enum SystemOrCodeCallKind {
|
|
||||||
/// On-chain address.
|
|
||||||
Address(Address),
|
|
||||||
/// Hard-coded code.
|
|
||||||
Code(Arc<Vec<u8>>, H256),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Default SystemOrCodeCall implementation.
|
|
||||||
pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut ExecutedBlock) -> impl FnMut(SystemOrCodeCallKind, Vec<u8>) -> Result<Vec<u8>, String> + 'a {
|
|
||||||
move |to, data| {
|
|
||||||
let result = match to {
|
|
||||||
SystemOrCodeCallKind::Address(address) => {
|
|
||||||
machine.execute_as_system(
|
|
||||||
block,
|
|
||||||
address,
|
|
||||||
U256::max_value(),
|
|
||||||
Some(data),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
SystemOrCodeCallKind::Code(code, code_hash) => {
|
|
||||||
machine.execute_code_as_system(
|
|
||||||
block,
|
|
||||||
None,
|
|
||||||
Some(code),
|
|
||||||
Some(code_hash),
|
|
||||||
Some(ActionValue::Apparent(U256::zero())),
|
|
||||||
U256::max_value(),
|
|
||||||
Some(data),
|
|
||||||
Some(CallType::StaticCall),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
result.map_err(|e| format!("{}", e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proof dependent on state.
|
|
||||||
pub trait StateDependentProof: Send + Sync {
|
|
||||||
/// Generate a proof, given the state.
|
|
||||||
fn generate_proof<'a>(&self, state: &machine_types::Call) -> Result<Vec<u8>, String>;
|
|
||||||
/// Check a proof generated elsewhere (potentially by a peer).
|
|
||||||
// `engine` needed to check state proofs, while really this should
|
|
||||||
// just be state machine params.
|
|
||||||
fn check_proof(&self, machine: &Machine, proof: &[u8]) -> Result<(), String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proof generated on epoch change.
|
|
||||||
pub enum Proof {
|
|
||||||
/// Known proof (extracted from signal)
|
|
||||||
Known(Vec<u8>),
|
|
||||||
/// State dependent proof.
|
|
||||||
WithState(Arc<dyn StateDependentProof>),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generated epoch verifier.
|
|
||||||
pub enum ConstructedVerifier<'a> {
|
|
||||||
/// Fully trusted verifier.
|
|
||||||
Trusted(Box<dyn EpochVerifier>),
|
|
||||||
/// Verifier unconfirmed. Check whether given finality proof finalizes given hash
|
|
||||||
/// under previous epoch.
|
|
||||||
Unconfirmed(Box<dyn EpochVerifier>, &'a [u8], H256),
|
|
||||||
/// Error constructing verifier.
|
|
||||||
Err(Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ConstructedVerifier<'a> {
|
|
||||||
/// Convert to a result, indicating that any necessary confirmation has been done
|
|
||||||
/// already.
|
|
||||||
pub fn known_confirmed(self) -> Result<Box<dyn EpochVerifier>, Error> {
|
|
||||||
match self {
|
|
||||||
ConstructedVerifier::Trusted(v) | ConstructedVerifier::Unconfirmed(v, _, _) => Ok(v),
|
|
||||||
ConstructedVerifier::Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Results of a query of whether an epoch change occurred at the given block.
|
|
||||||
pub enum EpochChange {
|
|
||||||
/// Cannot determine until more data is passed.
|
|
||||||
Unsure(AuxiliaryRequest),
|
|
||||||
/// No epoch change.
|
|
||||||
No,
|
|
||||||
/// The epoch will change, with proof.
|
|
||||||
Yes(Proof),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based.
|
|
||||||
/// Provides hooks into each of the major parts of block import.
|
|
||||||
pub trait Engine: Sync + Send {
|
|
||||||
/// The name of this engine.
|
|
||||||
fn name(&self) -> &str;
|
|
||||||
|
|
||||||
/// Get access to the underlying state machine.
|
|
||||||
// TODO: decouple.
|
|
||||||
fn machine(&self) -> &Machine;
|
|
||||||
|
|
||||||
/// The number of additional header fields required for this engine.
|
|
||||||
fn seal_fields(&self, _header: &Header) -> usize { 0 }
|
|
||||||
|
|
||||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
|
||||||
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
|
||||||
|
|
||||||
/// Maximum number of uncles a block is allowed to declare.
|
|
||||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
|
||||||
|
|
||||||
/// Optional maximum gas limit.
|
|
||||||
fn maximum_gas_limit(&self) -> Option<U256> { None }
|
|
||||||
|
|
||||||
/// Block transformation functions, before the transactions.
|
|
||||||
/// `epoch_begin` set to true if this block kicks off an epoch.
|
|
||||||
fn on_new_block(
|
|
||||||
&self,
|
|
||||||
_block: &mut ExecutedBlock,
|
|
||||||
_epoch_begin: bool,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Block transformation functions, after the transactions.
|
|
||||||
fn on_close_block(
|
|
||||||
&self,
|
|
||||||
_block: &mut ExecutedBlock,
|
|
||||||
_parent_header: &Header,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allow mutating the header during seal generation. Currently only used by Clique.
|
|
||||||
fn on_seal_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { Ok(()) }
|
|
||||||
|
|
||||||
/// Returns the engine's current sealing state.
|
|
||||||
fn sealing_state(&self) -> SealingState { SealingState::External }
|
|
||||||
|
|
||||||
/// Attempt to seal the block internally.
|
|
||||||
///
|
|
||||||
/// If `Some` is returned, then you get a valid seal.
|
|
||||||
///
|
|
||||||
/// This operation is synchronous and may (quite reasonably) not be available, in which None will
|
|
||||||
/// be returned.
|
|
||||||
///
|
|
||||||
/// It is fine to require access to state or a full client for this function, since
|
|
||||||
/// light clients do not generate seals.
|
|
||||||
fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None }
|
|
||||||
|
|
||||||
/// Verify a locally-generated seal of a header.
|
|
||||||
///
|
|
||||||
/// If this engine seals internally,
|
|
||||||
/// no checks have to be done here, since all internally generated seals
|
|
||||||
/// should be valid.
|
|
||||||
///
|
|
||||||
/// Externally-generated seals (e.g. PoW) will need to be checked for validity.
|
|
||||||
///
|
|
||||||
/// It is fine to require access to state or a full client for this function, since
|
|
||||||
/// light clients do not generate seals.
|
|
||||||
fn verify_local_seal(&self, header: &Header) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import.
|
|
||||||
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
|
|
||||||
fn verify_block_basic(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
|
||||||
|
|
||||||
/// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import.
|
|
||||||
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
|
|
||||||
fn verify_block_unordered(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
|
||||||
|
|
||||||
/// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import.
|
|
||||||
fn verify_block_family(&self, _header: &Header, _parent: &Header) -> Result<(), Error> { Ok(()) }
|
|
||||||
|
|
||||||
/// Phase 4 verification. Verify block header against potentially external data.
|
|
||||||
/// Should only be called when `register_client` has been called previously.
|
|
||||||
fn verify_block_external(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
|
||||||
|
|
||||||
/// Genesis epoch data.
|
|
||||||
fn genesis_epoch_data<'a>(&self, _header: &Header, _state: &machine_types::Call) -> Result<Vec<u8>, String> { Ok(Vec::new()) }
|
|
||||||
|
|
||||||
/// Whether an epoch change is signalled at the given header but will require finality.
|
|
||||||
/// If a change can be enacted immediately then return `No` from this function but
|
|
||||||
/// `Yes` from `is_epoch_end`.
|
|
||||||
///
|
|
||||||
/// If auxiliary data of the block is required, return an auxiliary request and the function will be
|
|
||||||
/// called again with them.
|
|
||||||
/// Return `Yes` or `No` when the answer is definitively known.
|
|
||||||
///
|
|
||||||
/// Should not interact with state.
|
|
||||||
fn signals_epoch_end<'a>(&self, _header: &Header, _aux: AuxiliaryData<'a>) -> EpochChange {
|
|
||||||
EpochChange::No
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether a block is the end of an epoch.
|
|
||||||
///
|
|
||||||
/// This either means that an immediate transition occurs or a block signalling transition
|
|
||||||
/// has reached finality. The `Headers` given are not guaranteed to return any blocks
|
|
||||||
/// from any epoch other than the current. The client must keep track of finality and provide
|
|
||||||
/// the latest finalized headers to check against the transition store.
|
|
||||||
///
|
|
||||||
/// Return optional transition proof.
|
|
||||||
fn is_epoch_end(
|
|
||||||
&self,
|
|
||||||
_chain_head: &Header,
|
|
||||||
_finalized: &[H256],
|
|
||||||
_chain: &Headers<Header>,
|
|
||||||
_transition_store: &PendingTransitionStore,
|
|
||||||
) -> Option<Vec<u8>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether a block is the end of an epoch.
|
|
||||||
///
|
|
||||||
/// This either means that an immediate transition occurs or a block signalling transition
|
|
||||||
/// has reached finality. The `Headers` given are not guaranteed to return any blocks
|
|
||||||
/// from any epoch other than the current. This is a specialized method to use for light
|
|
||||||
/// clients since the light client doesn't track finality of all blocks, and therefore finality
|
|
||||||
/// for blocks in the current epoch is built inside this method by the engine.
|
|
||||||
///
|
|
||||||
/// Return optional transition proof.
|
|
||||||
fn is_epoch_end_light(
|
|
||||||
&self,
|
|
||||||
_chain_head: &Header,
|
|
||||||
_chain: &Headers<Header>,
|
|
||||||
_transition_store: &PendingTransitionStore,
|
|
||||||
) -> Option<Vec<u8>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create an epoch verifier from validation proof and a flag indicating
|
|
||||||
/// whether finality is required.
|
|
||||||
fn epoch_verifier<'a>(&self, _header: &Header, _proof: &'a [u8]) -> ConstructedVerifier<'a> {
|
|
||||||
ConstructedVerifier::Trusted(Box::new(NoOp))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Populate a header's fields based on its parent's header.
|
|
||||||
/// Usually implements the chain scoring rule based on weight.
|
|
||||||
fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) { }
|
|
||||||
|
|
||||||
/// Handle any potential consensus messages;
|
|
||||||
/// updating consensus state and potentially issuing a new one.
|
|
||||||
fn handle_message(&self, _message: &[u8]) -> Result<(), EngineError> { Err(EngineError::UnexpectedMessage) }
|
|
||||||
|
|
||||||
/// Register a component which signs consensus messages.
|
|
||||||
fn set_signer(&self, _signer: Box<dyn EngineSigner>) {}
|
|
||||||
|
|
||||||
/// Sign using the EngineSigner, to be used for consensus tx signing.
|
|
||||||
fn sign(&self, _hash: H256) -> Result<Signature, Error> { unimplemented!() }
|
|
||||||
|
|
||||||
/// Add Client which can be used for sealing, potentially querying the state and sending messages.
|
|
||||||
fn register_client(&self, _client: Weak<dyn EngineClient>) {}
|
|
||||||
|
|
||||||
/// Trigger next step of the consensus engine.
|
|
||||||
fn step(&self) {}
|
|
||||||
|
|
||||||
/// Create a factory for building snapshot chunks and restoring from them.
|
|
||||||
/// Returning `None` indicates that this engine doesn't support snapshot creation.
|
|
||||||
fn snapshot_components(&self) -> Option<Box<dyn SnapshotComponents>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether this engine supports warp sync.
|
|
||||||
fn supports_warp(&self) -> bool {
|
|
||||||
self.snapshot_components().is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a new open block header timestamp based on the parent timestamp.
|
|
||||||
fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 {
|
|
||||||
use std::{time, cmp};
|
|
||||||
|
|
||||||
let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default();
|
|
||||||
cmp::max(now.as_secs() as u64, parent_timestamp + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check whether the parent timestamp is valid.
|
|
||||||
fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool {
|
|
||||||
header_timestamp > parent_timestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that
|
|
||||||
/// the ancestry exists.
|
|
||||||
fn ancestry_actions(&self, _header: &Header, _ancestry: &mut dyn Iterator<Item = ExtendedHeader>) -> Vec<AncestryAction> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns author should used when executing tx's for this block.
|
|
||||||
fn executive_author(&self, header: &Header) -> Result<Address, Error> {
|
|
||||||
Ok(*header.author())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the general parameters of the chain.
|
|
||||||
fn params(&self) -> &CommonParams;
|
|
||||||
|
|
||||||
/// Get the EVM schedule for the given block number.
|
|
||||||
fn schedule(&self, block_number: BlockNumber) -> Schedule {
|
|
||||||
self.machine().schedule(block_number)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builtin-contracts for the chain..
|
|
||||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> {
|
|
||||||
self.machine().builtins()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attempt to get a handle to a built-in contract.
|
|
||||||
/// Only returns references to activated built-ins.
|
|
||||||
fn builtin(&self, a: &Address, block_number: BlockNumber) -> Option<&Builtin> {
|
|
||||||
self.machine().builtin(a, block_number)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
|
|
||||||
fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size }
|
|
||||||
|
|
||||||
/// The nonce with which accounts begin at given block.
|
|
||||||
fn account_start_nonce(&self, block: BlockNumber) -> U256 {
|
|
||||||
self.machine().account_start_nonce(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The network ID that transactions should be signed with.
|
|
||||||
fn signing_chain_id(&self, env_info: &EnvInfo) -> Option<u64> {
|
|
||||||
self.machine().signing_chain_id(env_info)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Perform basic/cheap transaction verification.
|
|
||||||
///
|
|
||||||
/// This should include all cheap checks that can be done before
|
|
||||||
/// actually checking the signature, like chain-replay protection.
|
|
||||||
///
|
|
||||||
/// NOTE This is done before the signature is recovered so avoid
|
|
||||||
/// doing any state-touching checks that might be expensive.
|
|
||||||
///
|
|
||||||
/// TODO: Add flags for which bits of the transaction to check.
|
|
||||||
/// TODO: consider including State in the params.
|
|
||||||
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), transaction::Error> {
|
|
||||||
self.machine().verify_transaction_basic(t, header)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs pre-validation of RLP decoded transaction before other processing
|
|
||||||
fn decode_transaction(&self, transaction: &[u8]) -> Result<UnverifiedTransaction, transaction::Error> {
|
|
||||||
self.machine().decode_transaction(transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verifier for all blocks within an epoch with self-contained state.
|
|
||||||
pub trait EpochVerifier: Send + Sync {
|
|
||||||
/// Lightly verify the next block header.
|
|
||||||
/// This may not be a header belonging to a different epoch.
|
|
||||||
fn verify_light(&self, header: &Header) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Perform potentially heavier checks on the next block header.
|
|
||||||
fn verify_heavy(&self, header: &Header) -> Result<(), Error> {
|
|
||||||
self.verify_light(header)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check a finality proof against this epoch verifier.
|
|
||||||
/// Returns `Some(hashes)` if the proof proves finality of these hashes.
|
|
||||||
/// Returns `None` if the proof doesn't prove anything.
|
|
||||||
fn check_finality_proof(&self, _proof: &[u8]) -> Option<Vec<H256>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Special "no-op" verifier for stateless, epoch-less engines.
|
|
||||||
pub struct NoOp;
|
|
||||||
|
|
||||||
impl EpochVerifier for NoOp {
|
|
||||||
fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
|
|
||||||
}
|
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use engines::Engine;
|
use engine::snapshot::SnapshotComponents;
|
||||||
|
use engine::Engine;
|
||||||
use engines::block_reward::{self, RewardKind};
|
use engines::block_reward::{self, RewardKind};
|
||||||
use ethereum_types::U256;
|
use ethereum_types::U256;
|
||||||
use machine::{
|
use machine::{
|
||||||
@ -103,7 +104,7 @@ impl Engine for NullEngine {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot_components(&self) -> Option<Box<dyn (::snapshot::SnapshotComponents)>> {
|
fn snapshot_components(&self) -> Option<Box<dyn (SnapshotComponents)>> {
|
||||||
Some(Box::new(::snapshot::PowSnapshot::new(10000, 10000)))
|
Some(Box::new(::snapshot::PowSnapshot::new(10000, 10000)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,9 +30,10 @@ use types::{
|
|||||||
engines::machine::{Call, AuxiliaryData},
|
engines::machine::{Call, AuxiliaryData},
|
||||||
};
|
};
|
||||||
|
|
||||||
use client::EngineClient;
|
use client_traits::EngineClient;
|
||||||
|
use engine::SystemCall;
|
||||||
|
|
||||||
use super::{ValidatorSet, SimpleList, SystemCall};
|
use super::{ValidatorSet, SimpleList};
|
||||||
use super::safe_contract::ValidatorSafeContract;
|
use super::safe_contract::ValidatorSafeContract;
|
||||||
|
|
||||||
use_contract!(validator_report, "res/contracts/validator_report.json");
|
use_contract!(validator_report, "res/contracts/validator_report.json");
|
||||||
@ -93,7 +94,7 @@ impl ValidatorSet for ValidatorContract {
|
|||||||
first: bool,
|
first: bool,
|
||||||
header: &Header,
|
header: &Header,
|
||||||
aux: AuxiliaryData,
|
aux: AuxiliaryData,
|
||||||
) -> ::engines::EpochChange {
|
) -> engine::EpochChange {
|
||||||
self.validators.signals_epoch_end(first, header, aux)
|
self.validators.signals_epoch_end(first, header, aux)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,14 +146,15 @@ mod tests {
|
|||||||
use bytes::ToPretty;
|
use bytes::ToPretty;
|
||||||
use rlp::encode;
|
use rlp::encode;
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use types::header::Header;
|
use types::{
|
||||||
|
header::Header,
|
||||||
|
ids::BlockId,
|
||||||
|
};
|
||||||
use accounts::AccountProvider;
|
use accounts::AccountProvider;
|
||||||
use miner::{self, MinerService};
|
use miner::{self, MinerService};
|
||||||
use types::ids::BlockId;
|
|
||||||
use test_helpers::generate_dummy_client_with_spec;
|
use test_helpers::generate_dummy_client_with_spec;
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client::{BlockChainClient, ChainInfo};
|
use client_traits::{BlockChainClient, ChainInfo, BlockInfo};
|
||||||
use client_traits::BlockInfo;
|
|
||||||
use super::super::ValidatorSet;
|
use super::super::ValidatorSet;
|
||||||
use super::ValidatorContract;
|
use super::ValidatorContract;
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ mod multi;
|
|||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use client_traits::EngineClient;
|
||||||
|
use engine::SystemCall;
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use ethjson::spec::ValidatorSet as ValidatorSpec;
|
use ethjson::spec::ValidatorSet as ValidatorSpec;
|
||||||
use machine::Machine;
|
use machine::Machine;
|
||||||
@ -37,15 +39,13 @@ use types::{
|
|||||||
engines::machine::{Call, AuxiliaryData},
|
engines::machine::{Call, AuxiliaryData},
|
||||||
};
|
};
|
||||||
|
|
||||||
use client::EngineClient;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use self::test::TestSet;
|
pub use self::test::TestSet;
|
||||||
pub use self::simple_list::SimpleList;
|
pub use self::simple_list::SimpleList;
|
||||||
|
|
||||||
use self::contract::ValidatorContract;
|
use self::contract::ValidatorContract;
|
||||||
use self::safe_contract::ValidatorSafeContract;
|
use self::safe_contract::ValidatorSafeContract;
|
||||||
use self::multi::Multi;
|
use self::multi::Multi;
|
||||||
use super::SystemCall;
|
|
||||||
|
|
||||||
/// Creates a validator set from spec.
|
/// Creates a validator set from spec.
|
||||||
pub fn new_validator_set(spec: ValidatorSpec) -> Box<dyn ValidatorSet> {
|
pub fn new_validator_set(spec: ValidatorSpec) -> Box<dyn ValidatorSet> {
|
||||||
@ -117,7 +117,7 @@ pub trait ValidatorSet: Send + Sync + 'static {
|
|||||||
first: bool,
|
first: bool,
|
||||||
header: &Header,
|
header: &Header,
|
||||||
aux: AuxiliaryData,
|
aux: AuxiliaryData,
|
||||||
) -> ::engines::EpochChange;
|
) -> engine::EpochChange;
|
||||||
|
|
||||||
/// Recover the validator set from the given proof, the block number, and
|
/// Recover the validator set from the given proof, the block number, and
|
||||||
/// whether this header is first in its set.
|
/// whether this header is first in its set.
|
||||||
|
@ -30,7 +30,7 @@ use types::{
|
|||||||
engines::machine::{Call, AuxiliaryData},
|
engines::machine::{Call, AuxiliaryData},
|
||||||
};
|
};
|
||||||
|
|
||||||
use client::EngineClient;
|
use client_traits::EngineClient;
|
||||||
use machine::Machine;
|
use machine::Machine;
|
||||||
use super::{SystemCall, ValidatorSet};
|
use super::{SystemCall, ValidatorSet};
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ impl ValidatorSet for Multi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signals_epoch_end(&self, _first: bool, header: &Header, aux: AuxiliaryData)
|
fn signals_epoch_end(&self, _first: bool, header: &Header, aux: AuxiliaryData)
|
||||||
-> ::engines::EpochChange
|
-> engine::EpochChange
|
||||||
{
|
{
|
||||||
let (set_block, set) = self.correct_set_by_number(header.number());
|
let (set_block, set) = self.correct_set_by_number(header.number());
|
||||||
let first = set_block == header.number();
|
let first = set_block == header.number();
|
||||||
@ -155,18 +155,19 @@ mod tests {
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use accounts::AccountProvider;
|
use accounts::AccountProvider;
|
||||||
use client::{BlockChainClient, ChainInfo, ImportBlock};
|
use client_traits::{BlockChainClient, BlockInfo, ChainInfo, ImportBlock, EngineClient};
|
||||||
use client_traits::BlockInfo;
|
use engine::EpochChange;
|
||||||
use engines::EpochChange;
|
|
||||||
use engines::validator_set::ValidatorSet;
|
use engines::validator_set::ValidatorSet;
|
||||||
use ethkey::Secret;
|
use ethkey::Secret;
|
||||||
use types::header::Header;
|
use types::header::Header;
|
||||||
use miner::{self, MinerService};
|
use miner::{self, MinerService};
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
|
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
|
||||||
use types::ids::BlockId;
|
use types::{
|
||||||
|
ids::BlockId,
|
||||||
|
verification::Unverified,
|
||||||
|
};
|
||||||
use ethereum_types::Address;
|
use ethereum_types::Address;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
|
|
||||||
use super::Multi;
|
use super::Multi;
|
||||||
|
|
||||||
@ -186,24 +187,24 @@ mod tests {
|
|||||||
let signer = Box::new((tap.clone(), v1, "".into()));
|
let signer = Box::new((tap.clone(), v1, "".into()));
|
||||||
client.miner().set_author(miner::Author::Sealer(signer));
|
client.miner().set_author(miner::Author::Sealer(signer));
|
||||||
client.transact_contract(Default::default(), Default::default()).unwrap();
|
client.transact_contract(Default::default(), Default::default()).unwrap();
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
assert_eq!(client.chain_info().best_block_number, 0);
|
assert_eq!(client.chain_info().best_block_number, 0);
|
||||||
// Right signer for the first block.
|
// Right signer for the first block.
|
||||||
let signer = Box::new((tap.clone(), v0, "".into()));
|
let signer = Box::new((tap.clone(), v0, "".into()));
|
||||||
client.miner().set_author(miner::Author::Sealer(signer));
|
client.miner().set_author(miner::Author::Sealer(signer));
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
assert_eq!(client.chain_info().best_block_number, 1);
|
assert_eq!(client.chain_info().best_block_number, 1);
|
||||||
// This time v0 is wrong.
|
// This time v0 is wrong.
|
||||||
client.transact_contract(Default::default(), Default::default()).unwrap();
|
client.transact_contract(Default::default(), Default::default()).unwrap();
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
assert_eq!(client.chain_info().best_block_number, 1);
|
assert_eq!(client.chain_info().best_block_number, 1);
|
||||||
let signer = Box::new((tap.clone(), v1, "".into()));
|
let signer = Box::new((tap.clone(), v1, "".into()));
|
||||||
client.miner().set_author(miner::Author::Sealer(signer));
|
client.miner().set_author(miner::Author::Sealer(signer));
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
assert_eq!(client.chain_info().best_block_number, 2);
|
assert_eq!(client.chain_info().best_block_number, 2);
|
||||||
// v1 is still good.
|
// v1 is still good.
|
||||||
client.transact_contract(Default::default(), Default::default()).unwrap();
|
client.transact_contract(Default::default(), Default::default()).unwrap();
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
assert_eq!(client.chain_info().best_block_number, 3);
|
assert_eq!(client.chain_info().best_block_number, 3);
|
||||||
|
|
||||||
// Check syncing.
|
// Check syncing.
|
||||||
|
@ -36,7 +36,7 @@ use types::{
|
|||||||
};
|
};
|
||||||
use unexpected::Mismatch;
|
use unexpected::Mismatch;
|
||||||
|
|
||||||
use client::EngineClient;
|
use client_traits::EngineClient;
|
||||||
use machine::Machine;
|
use machine::Machine;
|
||||||
use super::{SystemCall, ValidatorSet};
|
use super::{SystemCall, ValidatorSet};
|
||||||
use super::simple_list::SimpleList;
|
use super::simple_list::SimpleList;
|
||||||
@ -59,7 +59,7 @@ struct StateProof {
|
|||||||
header: Header,
|
header: Header,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::engines::StateDependentProof for StateProof {
|
impl engine::StateDependentProof for StateProof {
|
||||||
fn generate_proof(&self, caller: &Call) -> Result<Vec<u8>, String> {
|
fn generate_proof(&self, caller: &Call) -> Result<Vec<u8>, String> {
|
||||||
prove_initial(self.contract_address, &self.header, caller)
|
prove_initial(self.contract_address, &self.header, caller)
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ impl ValidatorSet for ValidatorSafeContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signals_epoch_end(&self, first: bool, header: &Header, aux: AuxiliaryData)
|
fn signals_epoch_end(&self, first: bool, header: &Header, aux: AuxiliaryData)
|
||||||
-> ::engines::EpochChange
|
-> engine::EpochChange
|
||||||
{
|
{
|
||||||
let receipts = aux.receipts;
|
let receipts = aux.receipts;
|
||||||
|
|
||||||
@ -325,27 +325,27 @@ impl ValidatorSet for ValidatorSafeContract {
|
|||||||
contract_address: self.contract_address,
|
contract_address: self.contract_address,
|
||||||
header: header.clone(),
|
header: header.clone(),
|
||||||
});
|
});
|
||||||
return ::engines::EpochChange::Yes(::engines::Proof::WithState(state_proof as Arc<_>));
|
return engine::EpochChange::Yes(engine::Proof::WithState(state_proof as Arc<_>));
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, we're checking for logs.
|
// otherwise, we're checking for logs.
|
||||||
let bloom = self.expected_bloom(header);
|
let bloom = self.expected_bloom(header);
|
||||||
let header_bloom = header.log_bloom();
|
let header_bloom = header.log_bloom();
|
||||||
|
|
||||||
if &bloom & header_bloom != bloom { return ::engines::EpochChange::No }
|
if &bloom & header_bloom != bloom { return engine::EpochChange::No }
|
||||||
|
|
||||||
trace!(target: "engine", "detected epoch change event bloom");
|
trace!(target: "engine", "detected epoch change event bloom");
|
||||||
|
|
||||||
match receipts {
|
match receipts {
|
||||||
None => ::engines::EpochChange::Unsure(AuxiliaryRequest::Receipts),
|
None => engine::EpochChange::Unsure(AuxiliaryRequest::Receipts),
|
||||||
Some(receipts) => match self.extract_from_event(bloom, header, receipts) {
|
Some(receipts) => match self.extract_from_event(bloom, header, receipts) {
|
||||||
None => ::engines::EpochChange::No,
|
None => engine::EpochChange::No,
|
||||||
Some(list) => {
|
Some(list) => {
|
||||||
info!(target: "engine", "Signal for transition within contract. New validator list: {:?}",
|
info!(target: "engine", "Signal for transition within contract. New validator list: {:?}",
|
||||||
&*list);
|
&*list);
|
||||||
|
|
||||||
let proof = encode_proof(&header, receipts);
|
let proof = encode_proof(&header, receipts);
|
||||||
::engines::EpochChange::Yes(::engines::Proof::Known(proof))
|
engine::EpochChange::Yes(engine::Proof::Known(proof))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -452,19 +452,24 @@ mod tests {
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rustc_hex::FromHex;
|
use rustc_hex::FromHex;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
|
use engine::{EpochChange, Proof};
|
||||||
use ethereum_types::Address;
|
use ethereum_types::Address;
|
||||||
use types::ids::BlockId;
|
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use accounts::AccountProvider;
|
use accounts::AccountProvider;
|
||||||
use types::transaction::{Transaction, Action};
|
use types::{
|
||||||
use client::{ChainInfo, ImportBlock};
|
ids::BlockId,
|
||||||
use client_traits::BlockInfo;
|
engines::machine::AuxiliaryRequest,
|
||||||
|
header::Header,
|
||||||
|
log_entry::LogEntry,
|
||||||
|
transaction::{Transaction, Action},
|
||||||
|
verification::Unverified,
|
||||||
|
};
|
||||||
|
use client_traits::{BlockInfo, ChainInfo, ImportBlock, EngineClient};
|
||||||
use ethkey::Secret;
|
use ethkey::Secret;
|
||||||
use miner::{self, MinerService};
|
use miner::{self, MinerService};
|
||||||
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
|
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
|
||||||
use super::super::ValidatorSet;
|
use super::super::ValidatorSet;
|
||||||
use super::{ValidatorSafeContract, EVENT_NAME_HASH};
|
use super::{ValidatorSafeContract, EVENT_NAME_HASH};
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fetches_validators() {
|
fn fetches_validators() {
|
||||||
@ -500,7 +505,7 @@ mod tests {
|
|||||||
data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
||||||
}.sign(&s0, Some(chain_id));
|
}.sign(&s0, Some(chain_id));
|
||||||
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
assert_eq!(client.chain_info().best_block_number, 1);
|
assert_eq!(client.chain_info().best_block_number, 1);
|
||||||
// Add "1" validator back in.
|
// Add "1" validator back in.
|
||||||
let tx = Transaction {
|
let tx = Transaction {
|
||||||
@ -512,14 +517,14 @@ mod tests {
|
|||||||
data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
||||||
}.sign(&s0, Some(chain_id));
|
}.sign(&s0, Some(chain_id));
|
||||||
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
// The transaction is not yet included so still unable to seal.
|
// The transaction is not yet included so still unable to seal.
|
||||||
assert_eq!(client.chain_info().best_block_number, 1);
|
assert_eq!(client.chain_info().best_block_number, 1);
|
||||||
|
|
||||||
// Switch to the validator that is still there.
|
// Switch to the validator that is still there.
|
||||||
let signer = Box::new((tap.clone(), v0, "".into()));
|
let signer = Box::new((tap.clone(), v0, "".into()));
|
||||||
client.miner().set_author(miner::Author::Sealer(signer));
|
client.miner().set_author(miner::Author::Sealer(signer));
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
assert_eq!(client.chain_info().best_block_number, 2);
|
assert_eq!(client.chain_info().best_block_number, 2);
|
||||||
// Switch back to the added validator, since the state is updated.
|
// Switch back to the added validator, since the state is updated.
|
||||||
let signer = Box::new((tap.clone(), v1, "".into()));
|
let signer = Box::new((tap.clone(), v1, "".into()));
|
||||||
@ -533,7 +538,7 @@ mod tests {
|
|||||||
data: Vec::new(),
|
data: Vec::new(),
|
||||||
}.sign(&s0, Some(chain_id));
|
}.sign(&s0, Some(chain_id));
|
||||||
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
||||||
::client::EngineClient::update_sealing(&*client);
|
EngineClient::update_sealing(&*client);
|
||||||
// Able to seal again.
|
// Able to seal again.
|
||||||
assert_eq!(client.chain_info().best_block_number, 3);
|
assert_eq!(client.chain_info().best_block_number, 3);
|
||||||
|
|
||||||
@ -549,13 +554,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn detects_bloom() {
|
fn detects_bloom() {
|
||||||
use engines::EpochChange;
|
|
||||||
use types::{
|
|
||||||
header::Header,
|
|
||||||
log_entry::LogEntry,
|
|
||||||
engines::machine::AuxiliaryRequest,
|
|
||||||
};
|
|
||||||
|
|
||||||
let client = generate_dummy_client_with_spec(spec::new_validator_safe_contract);
|
let client = generate_dummy_client_with_spec(spec::new_validator_safe_contract);
|
||||||
let engine = client.engine().clone();
|
let engine = client.engine().clone();
|
||||||
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
|
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
|
||||||
@ -590,9 +588,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn initial_contract_is_signal() {
|
fn initial_contract_is_signal() {
|
||||||
use types::header::Header;
|
|
||||||
use engines::{EpochChange, Proof};
|
|
||||||
|
|
||||||
let client = generate_dummy_client_with_spec(spec::new_validator_safe_contract);
|
let client = generate_dummy_client_with_spec(spec::new_validator_safe_contract);
|
||||||
let engine = client.engine().clone();
|
let engine = client.engine().clone();
|
||||||
|
|
||||||
|
@ -77,9 +77,9 @@ impl ValidatorSet for SimpleList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signals_epoch_end(&self, _: bool, _: &Header, _: AuxiliaryData)
|
fn signals_epoch_end(&self, _: bool, _: &Header, _: AuxiliaryData)
|
||||||
-> ::engines::EpochChange
|
-> engine::EpochChange
|
||||||
{
|
{
|
||||||
::engines::EpochChange::No
|
engine::EpochChange::No
|
||||||
}
|
}
|
||||||
|
|
||||||
fn epoch_set(&self, _first: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option<H256>), EthcoreError> {
|
fn epoch_set(&self, _first: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option<H256>), EthcoreError> {
|
||||||
|
@ -71,9 +71,9 @@ impl ValidatorSet for TestSet {
|
|||||||
fn is_epoch_end(&self, _first: bool, _chain_head: &Header) -> Option<Vec<u8>> { None }
|
fn is_epoch_end(&self, _first: bool, _chain_head: &Header) -> Option<Vec<u8>> { None }
|
||||||
|
|
||||||
fn signals_epoch_end(&self, _: bool, _: &Header, _: AuxiliaryData)
|
fn signals_epoch_end(&self, _: bool, _: &Header, _: AuxiliaryData)
|
||||||
-> ::engines::EpochChange
|
-> engine::EpochChange
|
||||||
{
|
{
|
||||||
::engines::EpochChange::No
|
engine::EpochChange::No
|
||||||
}
|
}
|
||||||
|
|
||||||
fn epoch_set(&self, _: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option<H256>), EthcoreError> {
|
fn epoch_set(&self, _: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option<H256>), EthcoreError> {
|
||||||
|
@ -25,6 +25,7 @@ use machine::{
|
|||||||
};
|
};
|
||||||
use vm::EnvInfo;
|
use vm::EnvInfo;
|
||||||
use types::{
|
use types::{
|
||||||
|
engines::machine::Executed as RawExecuted,
|
||||||
errors::{ExecutionError, EthcoreError as Error},
|
errors::{ExecutionError, EthcoreError as Error},
|
||||||
transaction::SignedTransaction,
|
transaction::SignedTransaction,
|
||||||
receipt::{TransactionOutcome, Receipt},
|
receipt::{TransactionOutcome, Receipt},
|
||||||
@ -242,7 +243,7 @@ fn execute<B, T, V>(
|
|||||||
t: &SignedTransaction,
|
t: &SignedTransaction,
|
||||||
options: TransactOptions<T, V>,
|
options: TransactOptions<T, V>,
|
||||||
virt: bool
|
virt: bool
|
||||||
) -> Result<Executed<T::Output, V::Output>, ExecutionError>
|
) -> Result<RawExecuted<T::Output, V::Output>, ExecutionError>
|
||||||
where
|
where
|
||||||
B: Backend,
|
B: Backend,
|
||||||
T: trace::Tracer,
|
T: trace::Tracer,
|
||||||
|
@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use client::{EvmTestClient, Client, ClientConfig, ChainInfo, ImportBlock};
|
use client::{EvmTestClient, Client, ClientConfig};
|
||||||
|
use client_traits::{ImportBlock, ChainInfo};
|
||||||
use spec::Genesis;
|
use spec::Genesis;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use miner::Miner;
|
use miner::Miner;
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
use test_helpers;
|
use test_helpers;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
use types::verification::Unverified;
|
||||||
use verification::VerifierType;
|
use verification::VerifierType;
|
||||||
use super::SKIP_TEST_STATE;
|
use super::SKIP_TEST_STATE;
|
||||||
use super::HookType;
|
use super::HookType;
|
||||||
|
@ -29,7 +29,6 @@ use machine::{
|
|||||||
externalities::{OutputPolicy, OriginInfo, Externalities},
|
externalities::{OutputPolicy, OriginInfo, Externalities},
|
||||||
substate::Substate,
|
substate::Substate,
|
||||||
executive::contract_address,
|
executive::contract_address,
|
||||||
test_helpers::new_frontier_test_machine,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use test_helpers::get_temp_state;
|
use test_helpers::get_temp_state;
|
||||||
|
@ -59,6 +59,7 @@ extern crate ansi_term;
|
|||||||
extern crate client_traits;
|
extern crate client_traits;
|
||||||
extern crate common_types as types;
|
extern crate common_types as types;
|
||||||
extern crate crossbeam_utils;
|
extern crate crossbeam_utils;
|
||||||
|
extern crate engine;
|
||||||
extern crate ethabi;
|
extern crate ethabi;
|
||||||
extern crate ethash;
|
extern crate ethash;
|
||||||
extern crate ethcore_blockchain as blockchain;
|
extern crate ethcore_blockchain as blockchain;
|
||||||
@ -102,7 +103,6 @@ extern crate parity_util_mem as malloc_size_of;
|
|||||||
extern crate rustc_hex;
|
extern crate rustc_hex;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate state_db;
|
extern crate state_db;
|
||||||
extern crate stats;
|
|
||||||
extern crate time_utils;
|
extern crate time_utils;
|
||||||
extern crate trace;
|
extern crate trace;
|
||||||
extern crate triehash_ethereum as triehash;
|
extern crate triehash_ethereum as triehash;
|
||||||
|
@ -49,7 +49,7 @@ use types::{
|
|||||||
block::Block,
|
block::Block,
|
||||||
header::Header,
|
header::Header,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
engines::{SealingState},
|
engines::{Seal, SealingState},
|
||||||
errors::{EthcoreError as Error, ExecutionError},
|
errors::{EthcoreError as Error, ExecutionError},
|
||||||
receipt::RichReceipt,
|
receipt::RichReceipt,
|
||||||
};
|
};
|
||||||
@ -57,9 +57,15 @@ use using_queue::{UsingQueue, GetAction};
|
|||||||
|
|
||||||
use block::{ClosedBlock, SealedBlock};
|
use block::{ClosedBlock, SealedBlock};
|
||||||
use client::{
|
use client::{
|
||||||
BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, ClientIoMessage,
|
BlockProducer, SealedBlockImporter, ClientIoMessage,
|
||||||
|
};
|
||||||
|
use client_traits::{
|
||||||
|
BlockChain, ChainInfo, Nonce, TransactionInfo,
|
||||||
|
};
|
||||||
|
use engine::{
|
||||||
|
Engine,
|
||||||
|
signer::EngineSigner
|
||||||
};
|
};
|
||||||
use engines::{Engine, Seal, EngineSigner};
|
|
||||||
use machine::executive::contract_address;
|
use machine::executive::contract_address;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use account_state::State;
|
use account_state::State;
|
||||||
@ -1483,12 +1489,15 @@ mod tests {
|
|||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use rustc_hex::FromHex;
|
use rustc_hex::FromHex;
|
||||||
use types::BlockNumber;
|
|
||||||
|
|
||||||
use client::{TestBlockChainClient, EachBlockWith, ChainInfo, ImportSealedBlock};
|
use client::{TestBlockChainClient, EachBlockWith, ImportSealedBlock};
|
||||||
|
use client_traits::ChainInfo;
|
||||||
use miner::{MinerService, PendingOrdering};
|
use miner::{MinerService, PendingOrdering};
|
||||||
use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec};
|
use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec};
|
||||||
use types::transaction::{Transaction};
|
use types::{
|
||||||
|
BlockNumber,
|
||||||
|
transaction::Transaction
|
||||||
|
};
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -47,11 +47,8 @@ use types::{
|
|||||||
|
|
||||||
use block::SealedBlock;
|
use block::SealedBlock;
|
||||||
use call_contract::{CallContract, RegistryInfo};
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
use client::{
|
use client::{BlockProducer, SealedBlockImporter};
|
||||||
ScheduleInfo,
|
use client_traits::{BlockChain, ChainInfo, AccountData, Nonce, ScheduleInfo};
|
||||||
BlockChain, BlockProducer, SealedBlockImporter, ChainInfo,
|
|
||||||
AccountData, Nonce,
|
|
||||||
};
|
|
||||||
use account_state::state::StateInfo;
|
use account_state::state::StateInfo;
|
||||||
|
|
||||||
/// Provides methods to verify incoming external transactions
|
/// Provides methods to verify incoming external transactions
|
||||||
|
@ -39,9 +39,8 @@ use types::{
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client::Nonce;
|
use client_traits::{BlockInfo, Nonce};
|
||||||
use client_traits::BlockInfo;
|
use engine::Engine;
|
||||||
use engines::Engine;
|
|
||||||
use machine::transaction_ext::Transaction;
|
use machine::transaction_ext::Transaction;
|
||||||
use miner;
|
use miner;
|
||||||
|
|
||||||
|
@ -17,14 +17,17 @@
|
|||||||
//! Account state encoding and decoding
|
//! Account state encoding and decoding
|
||||||
|
|
||||||
use account_db::{AccountDB, AccountDBMut};
|
use account_db::{AccountDB, AccountDBMut};
|
||||||
use types::basic_account::BasicAccount;
|
use types::{
|
||||||
|
basic_account::BasicAccount,
|
||||||
|
snapshot::Progress,
|
||||||
|
errors::SnapshotError as Error,
|
||||||
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
use ethtrie::{TrieDB, TrieDBMut};
|
use ethtrie::{TrieDB, TrieDBMut};
|
||||||
use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP};
|
use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP};
|
||||||
use hash_db::HashDB;
|
use hash_db::HashDB;
|
||||||
use rlp::{RlpStream, Rlp};
|
use rlp::{RlpStream, Rlp};
|
||||||
use snapshot::{Error, Progress};
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use trie::{Trie, TrieMut};
|
use trie::{Trie, TrieMut};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
//!
|
//!
|
||||||
//! The chunks here contain state proofs of transitions, along with validator proofs.
|
//! The chunks here contain state proofs of transitions, along with validator proofs.
|
||||||
|
|
||||||
use super::{SnapshotComponents, Rebuilder, ChunkSink};
|
|
||||||
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use engines::{Engine, EpochVerifier, EpochTransition};
|
use engine::{
|
||||||
use snapshot::{ManifestData, Progress};
|
Engine,
|
||||||
|
EpochVerifier,
|
||||||
|
snapshot::{SnapshotComponents, Rebuilder}
|
||||||
|
};
|
||||||
use blockchain::{BlockChain, BlockChainDB, BlockProvider};
|
use blockchain::{BlockChain, BlockChainDB, BlockProvider};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
@ -35,10 +35,12 @@ use kvdb::KeyValueDB;
|
|||||||
use rlp::{RlpStream, Rlp};
|
use rlp::{RlpStream, Rlp};
|
||||||
use types::{
|
use types::{
|
||||||
encoded,
|
encoded,
|
||||||
|
engines::epoch::Transition as EpochTransition,
|
||||||
header::Header,
|
header::Header,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
errors::{SnapshotError, EthcoreError},
|
errors::{SnapshotError, EthcoreError},
|
||||||
receipt::Receipt,
|
receipt::Receipt,
|
||||||
|
snapshot::{ChunkSink, Progress, ManifestData}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Snapshot creation and restoration for PoA chains.
|
/// Snapshot creation and restoration for PoA chains.
|
||||||
@ -189,7 +191,7 @@ impl ChunkRebuilder {
|
|||||||
transition_rlp: Rlp,
|
transition_rlp: Rlp,
|
||||||
engine: &dyn Engine,
|
engine: &dyn Engine,
|
||||||
) -> Result<Verified, EthcoreError> {
|
) -> Result<Verified, EthcoreError> {
|
||||||
use engines::ConstructedVerifier;
|
use engine::ConstructedVerifier;
|
||||||
|
|
||||||
// decode.
|
// decode.
|
||||||
let header: Header = transition_rlp.val_at(0)?;
|
let header: Header = transition_rlp.val_at(0)?;
|
||||||
|
@ -17,81 +17,8 @@
|
|||||||
//! Secondary chunk creation and restoration, implementations for different consensus
|
//! Secondary chunk creation and restoration, implementations for different consensus
|
||||||
//! engines.
|
//! engines.
|
||||||
|
|
||||||
use std::sync::atomic::AtomicBool;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use blockchain::{BlockChain, BlockChainDB};
|
|
||||||
use engines::Engine;
|
|
||||||
use snapshot::{ManifestData, Progress};
|
|
||||||
use types::errors::{SnapshotError, EthcoreError};
|
|
||||||
|
|
||||||
use ethereum_types::H256;
|
|
||||||
|
|
||||||
mod authority;
|
mod authority;
|
||||||
mod work;
|
mod work;
|
||||||
|
|
||||||
pub use self::authority::*;
|
pub use self::authority::*;
|
||||||
pub use self::work::*;
|
pub use self::work::*;
|
||||||
|
|
||||||
/// A sink for produced chunks.
|
|
||||||
pub type ChunkSink<'a> = dyn FnMut(&[u8]) -> ::std::io::Result<()> + 'a;
|
|
||||||
|
|
||||||
/// Components necessary for snapshot creation and restoration.
|
|
||||||
pub trait SnapshotComponents: Send {
|
|
||||||
/// Create secondary snapshot chunks; these corroborate the state data
|
|
||||||
/// in the state chunks.
|
|
||||||
///
|
|
||||||
/// Chunks shouldn't exceed the given preferred size, and should be fed
|
|
||||||
/// uncompressed into the sink.
|
|
||||||
///
|
|
||||||
/// This will vary by consensus engine, so it's exposed as a trait.
|
|
||||||
fn chunk_all(
|
|
||||||
&mut self,
|
|
||||||
chain: &BlockChain,
|
|
||||||
block_at: H256,
|
|
||||||
chunk_sink: &mut ChunkSink,
|
|
||||||
progress: &Progress,
|
|
||||||
preferred_size: usize,
|
|
||||||
) -> Result<(), SnapshotError>;
|
|
||||||
|
|
||||||
/// Create a rebuilder, which will have chunks fed into it in aribtrary
|
|
||||||
/// order and then be finalized.
|
|
||||||
///
|
|
||||||
/// The manifest, a database, and fresh `BlockChain` are supplied.
|
|
||||||
///
|
|
||||||
/// The engine passed to the `Rebuilder` methods will be the same instance
|
|
||||||
/// that created the `SnapshotComponents`.
|
|
||||||
fn rebuilder(
|
|
||||||
&self,
|
|
||||||
chain: BlockChain,
|
|
||||||
db: Arc<dyn BlockChainDB>,
|
|
||||||
manifest: &ManifestData,
|
|
||||||
) -> Result<Box<dyn Rebuilder>, EthcoreError>;
|
|
||||||
|
|
||||||
/// Minimum supported snapshot version number.
|
|
||||||
fn min_supported_version(&self) -> u64;
|
|
||||||
|
|
||||||
/// Current version number
|
|
||||||
fn current_version(&self) -> u64;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Restore from secondary snapshot chunks.
|
|
||||||
pub trait Rebuilder: Send {
|
|
||||||
/// Feed a chunk, potentially out of order.
|
|
||||||
///
|
|
||||||
/// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with
|
|
||||||
/// `Error::RestorationAborted`.
|
|
||||||
fn feed(
|
|
||||||
&mut self,
|
|
||||||
chunk: &[u8],
|
|
||||||
engine: &dyn Engine,
|
|
||||||
abort_flag: &AtomicBool,
|
|
||||||
) -> Result<(), EthcoreError>;
|
|
||||||
|
|
||||||
/// Finalize the restoration. Will be done after all chunks have been
|
|
||||||
/// fed successfully.
|
|
||||||
///
|
|
||||||
/// This should apply the necessary "glue" between chunks,
|
|
||||||
/// and verify against the restored state.
|
|
||||||
fn finalize(&mut self) -> Result<(), EthcoreError>;
|
|
||||||
}
|
|
||||||
|
@ -20,15 +20,13 @@
|
|||||||
//! The secondary chunks in this instance are 30,000 "abridged blocks" from the head
|
//! The secondary chunks in this instance are 30,000 "abridged blocks" from the head
|
||||||
//! of the chain, which serve as an indication of valid chain.
|
//! of the chain, which serve as an indication of valid chain.
|
||||||
|
|
||||||
use super::{SnapshotComponents, Rebuilder, ChunkSink};
|
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use blockchain::{BlockChain, BlockChainDB, BlockProvider};
|
use blockchain::{BlockChain, BlockChainDB, BlockProvider};
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use snapshot::{ManifestData, Progress};
|
use engine::snapshot::{SnapshotComponents, Rebuilder};
|
||||||
use snapshot::block::AbridgedBlock;
|
use snapshot::block::AbridgedBlock;
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use kvdb::KeyValueDB;
|
use kvdb::KeyValueDB;
|
||||||
@ -37,7 +35,9 @@ use rlp::{RlpStream, Rlp};
|
|||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use types::{
|
use types::{
|
||||||
encoded,
|
encoded,
|
||||||
|
engines::epoch::Transition as EpochTransition,
|
||||||
errors::{SnapshotError, EthcoreError},
|
errors::{SnapshotError, EthcoreError},
|
||||||
|
snapshot::{ChunkSink, ManifestData, Progress},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Snapshot creation and restoration for PoW chains.
|
/// Snapshot creation and restoration for PoW chains.
|
||||||
@ -84,7 +84,12 @@ impl SnapshotComponents for PowSnapshot {
|
|||||||
db: Arc<dyn BlockChainDB>,
|
db: Arc<dyn BlockChainDB>,
|
||||||
manifest: &ManifestData,
|
manifest: &ManifestData,
|
||||||
) -> Result<Box<dyn Rebuilder>, EthcoreError> {
|
) -> Result<Box<dyn Rebuilder>, EthcoreError> {
|
||||||
PowRebuilder::new(chain, db.key_value().clone(), manifest, self.max_restore_blocks).map(|r| Box::new(r) as Box<_>)
|
PowRebuilder::new(
|
||||||
|
chain,
|
||||||
|
db.key_value().clone(),
|
||||||
|
manifest,
|
||||||
|
self.max_restore_blocks
|
||||||
|
).map(|r| Box::new(r) as Box<_>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min_supported_version(&self) -> u64 { ::snapshot::MIN_SUPPORTED_STATE_CHUNK_VERSION }
|
fn min_supported_version(&self) -> u64 { ::snapshot::MIN_SUPPORTED_STATE_CHUNK_VERSION }
|
||||||
@ -314,7 +319,7 @@ impl Rebuilder for PowRebuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let genesis_hash = self.chain.genesis_hash();
|
let genesis_hash = self.chain.genesis_hash();
|
||||||
self.chain.insert_epoch_transition(&mut batch, 0, ::engines::EpochTransition {
|
self.chain.insert_epoch_transition(&mut batch, 0, EpochTransition {
|
||||||
block_number: 0,
|
block_number: 0,
|
||||||
block_hash: genesis_hash,
|
block_hash: genesis_hash,
|
||||||
proof: vec![],
|
proof: vec![],
|
||||||
|
@ -22,16 +22,16 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY};
|
use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY};
|
||||||
|
|
||||||
use account_db::{AccountDB, AccountDBMut};
|
use account_db::{AccountDB, AccountDBMut};
|
||||||
use blockchain::{BlockChain, BlockProvider};
|
use blockchain::{BlockChain, BlockProvider};
|
||||||
use engines::Engine;
|
|
||||||
use types::{
|
use types::{
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::{SnapshotError as Error, EthcoreError},
|
errors::{SnapshotError as Error, EthcoreError},
|
||||||
|
snapshot::Progress,
|
||||||
};
|
};
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
use hash_db::HashDB;
|
use hash_db::HashDB;
|
||||||
@ -51,6 +51,10 @@ use self::io::SnapshotWriter;
|
|||||||
|
|
||||||
use super::state_db::StateDB;
|
use super::state_db::StateDB;
|
||||||
use account_state::Account as StateAccount;
|
use account_state::Account as StateAccount;
|
||||||
|
use engine::{
|
||||||
|
Engine,
|
||||||
|
snapshot::SnapshotComponents
|
||||||
|
};
|
||||||
|
|
||||||
use crossbeam_utils::thread;
|
use crossbeam_utils::thread;
|
||||||
use rand::{Rng, rngs::OsRng};
|
use rand::{Rng, rngs::OsRng};
|
||||||
@ -59,7 +63,7 @@ pub use self::consensus::*;
|
|||||||
pub use self::service::{SnapshotClient, Service, DatabaseRestore};
|
pub use self::service::{SnapshotClient, Service, DatabaseRestore};
|
||||||
pub use self::traits::SnapshotService;
|
pub use self::traits::SnapshotService;
|
||||||
pub use self::watcher::Watcher;
|
pub use self::watcher::Watcher;
|
||||||
pub use types::snapshot_manifest::ManifestData;
|
pub use types::snapshot::ManifestData;
|
||||||
pub use types::restoration_status::RestorationStatus;
|
pub use types::restoration_status::RestorationStatus;
|
||||||
pub use types::basic_account::BasicAccount;
|
pub use types::basic_account::BasicAccount;
|
||||||
|
|
||||||
@ -111,42 +115,6 @@ impl Default for SnapshotConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A progress indicator for snapshots.
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct Progress {
|
|
||||||
accounts: AtomicUsize,
|
|
||||||
blocks: AtomicUsize,
|
|
||||||
size: AtomicU64,
|
|
||||||
done: AtomicBool,
|
|
||||||
abort: AtomicBool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Progress {
|
|
||||||
/// Reset the progress.
|
|
||||||
pub fn reset(&self) {
|
|
||||||
self.accounts.store(0, Ordering::Release);
|
|
||||||
self.blocks.store(0, Ordering::Release);
|
|
||||||
self.size.store(0, Ordering::Release);
|
|
||||||
self.abort.store(false, Ordering::Release);
|
|
||||||
|
|
||||||
// atomic fence here to ensure the others are written first?
|
|
||||||
// logs might very rarely get polluted if not.
|
|
||||||
self.done.store(false, Ordering::Release);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the number of accounts snapshotted thus far.
|
|
||||||
pub fn accounts(&self) -> usize { self.accounts.load(Ordering::Acquire) }
|
|
||||||
|
|
||||||
/// Get the number of blocks snapshotted thus far.
|
|
||||||
pub fn blocks(&self) -> usize { self.blocks.load(Ordering::Acquire) }
|
|
||||||
|
|
||||||
/// Get the written size of the snapshot in bytes.
|
|
||||||
pub fn size(&self) -> u64 { self.size.load(Ordering::Acquire) }
|
|
||||||
|
|
||||||
/// Whether the snapshot is complete.
|
|
||||||
pub fn done(&self) -> bool { self.done.load(Ordering::Acquire) }
|
|
||||||
|
|
||||||
}
|
|
||||||
/// Take a snapshot using the given blockchain, starting block hash, and database, writing into the given writer.
|
/// Take a snapshot using the given blockchain, starting block hash, and database, writing into the given writer.
|
||||||
pub fn take_snapshot<W: SnapshotWriter + Send>(
|
pub fn take_snapshot<W: SnapshotWriter + Send>(
|
||||||
chunker: Box<dyn SnapshotComponents>,
|
chunker: Box<dyn SnapshotComponents>,
|
||||||
|
@ -24,17 +24,21 @@ use std::sync::Arc;
|
|||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
|
||||||
use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE};
|
use super::{StateRebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE};
|
||||||
use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter};
|
use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter};
|
||||||
|
|
||||||
use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler};
|
use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler};
|
||||||
use client::{BlockChainClient, Client, ChainInfo, ClientIoMessage};
|
use client::{Client, ClientIoMessage};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::{
|
||||||
use engines::Engine;
|
BlockInfo, BlockChainClient, ChainInfo
|
||||||
|
};
|
||||||
|
use engine::Engine;
|
||||||
|
use engine::snapshot::Rebuilder;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use types::{
|
use types::{
|
||||||
errors::{EthcoreError as Error, SnapshotError, SnapshotError::UnlinkedAncientBlockChain},
|
errors::{EthcoreError as Error, SnapshotError, SnapshotError::UnlinkedAncientBlockChain},
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
|
snapshot::{ManifestData, Progress},
|
||||||
};
|
};
|
||||||
|
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
@ -245,7 +249,7 @@ pub struct Service {
|
|||||||
state_chunks: AtomicUsize,
|
state_chunks: AtomicUsize,
|
||||||
block_chunks: AtomicUsize,
|
block_chunks: AtomicUsize,
|
||||||
client: Arc<dyn SnapshotClient>,
|
client: Arc<dyn SnapshotClient>,
|
||||||
progress: super::Progress,
|
progress: Progress,
|
||||||
taking_snapshot: AtomicBool,
|
taking_snapshot: AtomicBool,
|
||||||
restoring_snapshot: AtomicBool,
|
restoring_snapshot: AtomicBool,
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,9 @@ use hash::{KECCAK_NULL_RLP};
|
|||||||
use account_db::AccountDBMut;
|
use account_db::AccountDBMut;
|
||||||
use types::basic_account::BasicAccount;
|
use types::basic_account::BasicAccount;
|
||||||
use blockchain::{BlockChain, BlockChainDB};
|
use blockchain::{BlockChain, BlockChainDB};
|
||||||
use client::{Client, ChainInfo};
|
use client::Client;
|
||||||
use engines::Engine;
|
use client_traits::ChainInfo;
|
||||||
|
use engine::Engine;
|
||||||
use snapshot::{StateRebuilder};
|
use snapshot::{StateRebuilder};
|
||||||
use snapshot::io::{SnapshotReader, PackedWriter, PackedReader};
|
use snapshot::io::{SnapshotReader, PackedWriter, PackedReader};
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ use std::sync::Arc;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use accounts::AccountProvider;
|
use accounts::AccountProvider;
|
||||||
use client::{Client, BlockChainClient, ChainInfo};
|
use client::Client;
|
||||||
|
use client_traits::{BlockChainClient, ChainInfo};
|
||||||
use ethkey::Secret;
|
use ethkey::Secret;
|
||||||
use snapshot::tests::helpers as snapshot_helpers;
|
use snapshot::tests::helpers as snapshot_helpers;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
|
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use types::errors::EthcoreError as Error;
|
use types::{
|
||||||
|
errors::EthcoreError as Error,
|
||||||
|
engines::ForkChoice,
|
||||||
|
};
|
||||||
|
|
||||||
use blockchain::generator::{BlockGenerator, BlockBuilder};
|
use blockchain::generator::{BlockGenerator, BlockBuilder};
|
||||||
use blockchain::{BlockChain, ExtrasInsert};
|
use blockchain::{BlockChain, ExtrasInsert};
|
||||||
@ -50,7 +53,7 @@ fn chunk_and_restore(amount: u64) {
|
|||||||
let mut batch = DBTransaction::new();
|
let mut batch = DBTransaction::new();
|
||||||
for block in generator {
|
for block in generator {
|
||||||
bc.insert_block(&mut batch, block.encoded(), vec![], ExtrasInsert {
|
bc.insert_block(&mut batch, block.encoded(), vec![], ExtrasInsert {
|
||||||
fork_choice: ::engines::ForkChoice::New,
|
fork_choice: ForkChoice::New,
|
||||||
is_finalized: false,
|
is_finalized: false,
|
||||||
});
|
});
|
||||||
bc.commit();
|
bc.commit();
|
||||||
|
@ -21,19 +21,22 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use blockchain::BlockProvider;
|
use blockchain::BlockProvider;
|
||||||
use client::{Client, ClientConfig, ImportBlock};
|
use client::{Client, ClientConfig};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::{BlockInfo, ImportBlock};
|
||||||
use types::ids::BlockId;
|
use types::{
|
||||||
|
ids::BlockId,
|
||||||
|
snapshot::Progress,
|
||||||
|
verification::Unverified,
|
||||||
|
};
|
||||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
||||||
use snapshot::service::{Service, ServiceParams};
|
use snapshot::service::{Service, ServiceParams};
|
||||||
use snapshot::{chunk_state, chunk_secondary, ManifestData, Progress, SnapshotService, RestorationStatus};
|
use snapshot::{chunk_state, chunk_secondary, ManifestData, SnapshotService, RestorationStatus};
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use test_helpers::{new_db, new_temp_db, generate_dummy_client_with_spec_and_data, restoration_db_handler};
|
use test_helpers::{new_db, new_temp_db, generate_dummy_client_with_spec_and_data, restoration_db_handler};
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
use kvdb_rocksdb::DatabaseConfig;
|
use kvdb_rocksdb::DatabaseConfig;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn restored_is_equivalent() {
|
fn restored_is_equivalent() {
|
||||||
|
@ -39,8 +39,9 @@ use types::{
|
|||||||
use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType};
|
use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType};
|
||||||
|
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
|
use engine::Engine;
|
||||||
use engines::{
|
use engines::{
|
||||||
Engine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority, Clique,
|
NullEngine, InstantSeal, InstantSealParams, BasicAuthority, Clique,
|
||||||
AuthorityRound, Ethash,
|
AuthorityRound, Ethash,
|
||||||
};
|
};
|
||||||
use machine::{
|
use machine::{
|
||||||
|
@ -33,20 +33,24 @@ use kvdb_rocksdb::{self, Database, DatabaseConfig};
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rlp::{self, RlpStream};
|
use rlp::{self, RlpStream};
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use types::transaction::{Action, Transaction, SignedTransaction};
|
use types::{
|
||||||
use types::encoded;
|
transaction::{Action, Transaction, SignedTransaction},
|
||||||
use types::header::Header;
|
encoded,
|
||||||
use types::view;
|
engines::ForkChoice,
|
||||||
use types::views::BlockView;
|
header::Header,
|
||||||
|
view,
|
||||||
|
views::BlockView,
|
||||||
|
verification::Unverified,
|
||||||
|
};
|
||||||
|
|
||||||
use block::{OpenBlock, Drain};
|
use block::{OpenBlock, Drain};
|
||||||
use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify, ChainMessageType, PrepareOpenBlock};
|
use client::{Client, ClientConfig, ChainNotify, ChainMessageType, PrepareOpenBlock};
|
||||||
|
use client_traits::{ChainInfo, ImportBlock};
|
||||||
use trie_vm_factories::Factories;
|
use trie_vm_factories::Factories;
|
||||||
use miner::Miner;
|
use miner::Miner;
|
||||||
use spec::{Spec, self};
|
use spec::{Spec, self};
|
||||||
use account_state::*;
|
use account_state::*;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
|
|
||||||
/// Creates test block with corresponding header
|
/// Creates test block with corresponding header
|
||||||
pub fn create_test_block(header: &Header) -> Bytes {
|
pub fn create_test_block(header: &Header) -> Bytes {
|
||||||
@ -375,7 +379,7 @@ pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain {
|
|||||||
for block_order in 1..block_number {
|
for block_order in 1..block_number {
|
||||||
// Total difficulty is always 0 here.
|
// Total difficulty is always 0 here.
|
||||||
bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block(block_order, bc.best_block_hash())), vec![], ExtrasInsert {
|
bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block(block_order, bc.best_block_hash())), vec![], ExtrasInsert {
|
||||||
fork_choice: ::engines::ForkChoice::New,
|
fork_choice: ForkChoice::New,
|
||||||
is_finalized: false,
|
is_finalized: false,
|
||||||
});
|
});
|
||||||
bc.commit();
|
bc.commit();
|
||||||
@ -393,7 +397,7 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain {
|
|||||||
for block_order in 1..block_number {
|
for block_order in 1..block_number {
|
||||||
// Total difficulty is always 0 here.
|
// Total difficulty is always 0 here.
|
||||||
bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None)), vec![], ExtrasInsert {
|
bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None)), vec![], ExtrasInsert {
|
||||||
fork_choice: ::engines::ForkChoice::New,
|
fork_choice: ForkChoice::New,
|
||||||
is_finalized: false,
|
is_finalized: false,
|
||||||
});
|
});
|
||||||
bc.commit();
|
bc.commit();
|
||||||
|
@ -26,12 +26,13 @@ use types::{
|
|||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
transaction::{PendingTransaction, Transaction, Action, Condition},
|
transaction::{PendingTransaction, Transaction, Action, Condition},
|
||||||
filter::Filter,
|
filter::Filter,
|
||||||
|
verification::Unverified,
|
||||||
view,
|
view,
|
||||||
views::BlockView,
|
views::BlockView,
|
||||||
};
|
};
|
||||||
|
|
||||||
use client::{BlockChainClient, BlockChainReset, Client, ClientConfig, ChainInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock};
|
use client::{Client, ClientConfig, PrepareOpenBlock, ImportSealedBlock};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::{BlockInfo, BlockChainClient, BlockChainReset, ChainInfo, ImportBlock};
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use machine::executive::{Executive, TransactOptions};
|
use machine::executive::{Executive, TransactOptions};
|
||||||
use miner::{Miner, PendingOrdering, MinerService};
|
use miner::{Miner, PendingOrdering, MinerService};
|
||||||
@ -41,7 +42,6 @@ use test_helpers::{
|
|||||||
generate_dummy_client, push_blocks_to_client, get_test_client_with_blocks, get_good_dummy_block_seq,
|
generate_dummy_client, push_blocks_to_client, get_test_client_with_blocks, get_good_dummy_block_seq,
|
||||||
generate_dummy_client_with_data, get_good_dummy_block, get_bad_state_dummy_block
|
generate_dummy_client_with_data, get_good_dummy_block, get_bad_state_dummy_block
|
||||||
};
|
};
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn imports_from_empty() {
|
fn imports_from_empty() {
|
||||||
@ -210,7 +210,7 @@ fn can_generate_gas_price_histogram() {
|
|||||||
let client = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]);
|
let client = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]);
|
||||||
|
|
||||||
let hist = client.gas_price_corpus(20).histogram(5).unwrap();
|
let hist = client.gas_price_corpus(20).histogram(5).unwrap();
|
||||||
let correct_hist = ::stats::Histogram { bucket_bounds: vec_into![643, 2294, 3945, 5596, 7247, 8898], counts: vec![4,2,4,6,4] };
|
let correct_hist = stats::Histogram { bucket_bounds: vec_into![643, 2294, 3945, 5596, 7247, 8898], counts: vec![4,2,4,6,4] };
|
||||||
assert_eq!(hist, correct_hist);
|
assert_eq!(hist, correct_hist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ fn does_not_propagate_delayed_transactions() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn transaction_proof() {
|
fn transaction_proof() {
|
||||||
use ::client::ProvingBlockChainClient;
|
use client_traits::ProvingBlockChainClient;
|
||||||
|
|
||||||
let client = generate_dummy_client(0);
|
let client = generate_dummy_client(0);
|
||||||
let address = Address::random();
|
let address = Address::random();
|
||||||
|
@ -22,21 +22,21 @@ use block::*;
|
|||||||
use ethereum_types::{U256, Address};
|
use ethereum_types::{U256, Address};
|
||||||
use io::*;
|
use io::*;
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use client::*;
|
|
||||||
use test_helpers::get_temp_state_db;
|
use test_helpers::get_temp_state_db;
|
||||||
use client::{BlockChainClient, Client, ClientConfig};
|
use client::{Client, ClientConfig};
|
||||||
|
use client_traits::{BlockChainClient, ImportBlock};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use miner::Miner;
|
use miner::Miner;
|
||||||
use trace::{RewardType, LocalizedTrace};
|
use trace::{RewardType, LocalizedTrace};
|
||||||
use trace::trace::Action::Reward;
|
use trace::trace::Action::Reward;
|
||||||
use test_helpers;
|
use test_helpers;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
use types::{
|
use types::{
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
transaction::{Action, Transaction},
|
transaction::{Action, Transaction},
|
||||||
trace_filter::Filter as TraceFilter,
|
trace_filter::Filter as TraceFilter,
|
||||||
header::Header,
|
header::Header,
|
||||||
|
verification::Unverified,
|
||||||
view,
|
view,
|
||||||
views::BlockView,
|
views::BlockView,
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error
|
errors::EthcoreError as Error
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Definition of valid items for the verification queue.
|
//! Definition of valid items for the verification queue.
|
||||||
|
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
|
|
||||||
use parity_util_mem::MallocSizeOf;
|
use parity_util_mem::MallocSizeOf;
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
@ -69,18 +69,15 @@ pub trait Kind: 'static + Sized + Send + Sync {
|
|||||||
pub mod blocks {
|
pub mod blocks {
|
||||||
use super::{Kind, BlockLike};
|
use super::{Kind, BlockLike};
|
||||||
|
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use types::{
|
||||||
block::PreverifiedBlock,
|
block::PreverifiedBlock,
|
||||||
header::Header,
|
|
||||||
errors::{EthcoreError as Error, BlockError},
|
errors::{EthcoreError as Error, BlockError},
|
||||||
transaction::UnverifiedTransaction
|
verification::Unverified,
|
||||||
};
|
};
|
||||||
use verification::{verify_block_basic, verify_block_unordered};
|
use verification::{verify_block_basic, verify_block_unordered};
|
||||||
|
|
||||||
use parity_util_mem::MallocSizeOf;
|
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
use bytes::Bytes;
|
|
||||||
|
|
||||||
/// A mode for verifying blocks.
|
/// A mode for verifying blocks.
|
||||||
pub struct Blocks;
|
pub struct Blocks;
|
||||||
@ -116,40 +113,6 @@ pub mod blocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unverified block.
|
|
||||||
#[derive(PartialEq, Debug, MallocSizeOf)]
|
|
||||||
pub struct Unverified {
|
|
||||||
/// Unverified block header.
|
|
||||||
pub header: Header,
|
|
||||||
/// Unverified block transactions.
|
|
||||||
pub transactions: Vec<UnverifiedTransaction>,
|
|
||||||
/// Unverified block uncles.
|
|
||||||
pub uncles: Vec<Header>,
|
|
||||||
/// Raw block bytes.
|
|
||||||
pub bytes: Bytes,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Unverified {
|
|
||||||
/// Create an `Unverified` from raw bytes.
|
|
||||||
pub fn from_rlp(bytes: Bytes) -> Result<Self, ::rlp::DecoderError> {
|
|
||||||
use rlp::Rlp;
|
|
||||||
let (header, transactions, uncles) = {
|
|
||||||
let rlp = Rlp::new(&bytes);
|
|
||||||
let header = rlp.val_at(0)?;
|
|
||||||
let transactions = rlp.list_at(1)?;
|
|
||||||
let uncles = rlp.list_at(2)?;
|
|
||||||
(header, transactions, uncles)
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Unverified {
|
|
||||||
header,
|
|
||||||
transactions,
|
|
||||||
uncles,
|
|
||||||
bytes,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BlockLike for Unverified {
|
impl BlockLike for Unverified {
|
||||||
fn hash(&self) -> H256 {
|
fn hash(&self) -> H256 {
|
||||||
self.header.hash()
|
self.header.hash()
|
||||||
@ -183,7 +146,7 @@ pub mod blocks {
|
|||||||
pub mod headers {
|
pub mod headers {
|
||||||
use super::{Kind, BlockLike};
|
use super::{Kind, BlockLike};
|
||||||
|
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
|
@ -26,14 +26,14 @@ use parity_util_mem::{MallocSizeOf, MallocSizeOfExt};
|
|||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
use parking_lot::{Condvar, Mutex, RwLock};
|
use parking_lot::{Condvar, Mutex, RwLock};
|
||||||
use io::*;
|
use io::*;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use client::ClientIoMessage;
|
use client::ClientIoMessage;
|
||||||
use len_caching_lock::LenCachingMutex;
|
use len_caching_lock::LenCachingMutex;
|
||||||
use types::errors::{BlockError, EthcoreError as Error, ImportError};
|
use types::errors::{BlockError, EthcoreError as Error, ImportError};
|
||||||
|
|
||||||
use self::kind::{BlockLike, Kind};
|
use self::kind::{BlockLike, Kind};
|
||||||
|
|
||||||
pub use types::verification_queue_info::VerificationQueueInfo as QueueInfo;
|
pub use types::verification::VerificationQueueInfo as QueueInfo;
|
||||||
|
|
||||||
pub mod kind;
|
pub mod kind;
|
||||||
|
|
||||||
@ -735,13 +735,13 @@ impl<K: Kind> Drop for VerificationQueue<K> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use io::*;
|
use io::*;
|
||||||
use super::{BlockQueue, Config, State};
|
use super::{BlockQueue, Config, State};
|
||||||
use super::kind::blocks::Unverified;
|
|
||||||
use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
|
use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use types::{
|
use types::{
|
||||||
|
errors::{EthcoreError, ImportError},
|
||||||
|
verification::Unverified,
|
||||||
view,
|
view,
|
||||||
views::BlockView,
|
views::BlockView,
|
||||||
errors::{EthcoreError, ImportError},
|
|
||||||
};
|
};
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
|
|
||||||
|
@ -32,15 +32,15 @@ use unexpected::{Mismatch, OutOfBounds};
|
|||||||
use blockchain::*;
|
use blockchain::*;
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use types::{
|
||||||
BlockNumber,
|
BlockNumber,
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::{EthcoreError as Error, BlockError},
|
errors::{EthcoreError as Error, BlockError},
|
||||||
engines::MAX_UNCLE_AGE,
|
engines::MAX_UNCLE_AGE,
|
||||||
block::PreverifiedBlock,
|
block::PreverifiedBlock,
|
||||||
|
verification::Unverified,
|
||||||
};
|
};
|
||||||
use verification::queue::kind::blocks::Unverified;
|
|
||||||
|
|
||||||
use time_utils::CheckedSystemTime;
|
use time_utils::CheckedSystemTime;
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ mod tests {
|
|||||||
use blockchain::{BlockDetails, TransactionAddress, BlockReceipts};
|
use blockchain::{BlockDetails, TransactionAddress, BlockReceipts};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use ethkey::{Random, Generator};
|
use ethkey::{Random, Generator};
|
||||||
use crate::spec;
|
use crate::spec;
|
||||||
use test_helpers::{create_test_block_with_data, create_test_block};
|
use test_helpers::{create_test_block_with_data, create_test_block};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engines::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
|
@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
client-traits = { path = "../client-traits" }
|
client-traits = { path = "../client-traits" }
|
||||||
common-types = { path = "../types" }
|
common-types = { path = "../types" }
|
||||||
|
engine = { path = "../engine" }
|
||||||
enum_primitive = "0.1.1"
|
enum_primitive = "0.1.1"
|
||||||
ethcore = { path = ".." }
|
ethcore = { path = ".." }
|
||||||
ethcore-io = { path = "../../util/io" }
|
ethcore-io = { path = "../../util/io" }
|
||||||
|
@ -32,7 +32,8 @@ use futures::sync::mpsc as futures_mpsc;
|
|||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use io::{TimerToken};
|
use io::{TimerToken};
|
||||||
use ethkey::Secret;
|
use ethkey::Secret;
|
||||||
use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainMessageType};
|
use ethcore::client::{ChainNotify, NewBlocks, ChainMessageType};
|
||||||
|
use client_traits::BlockChainClient;
|
||||||
use ethcore::snapshot::SnapshotService;
|
use ethcore::snapshot::SnapshotService;
|
||||||
use types::BlockNumber;
|
use types::BlockNumber;
|
||||||
use sync_io::NetSyncIo;
|
use sync_io::NetSyncIo;
|
||||||
|
@ -22,9 +22,11 @@ use triehash_ethereum::ordered_trie_root;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use rlp::{Rlp, RlpStream, DecoderError};
|
use rlp::{Rlp, RlpStream, DecoderError};
|
||||||
use network;
|
use network;
|
||||||
use ethcore::verification::queue::kind::blocks::Unverified;
|
use types::{
|
||||||
use types::transaction::UnverifiedTransaction;
|
transaction::UnverifiedTransaction,
|
||||||
use types::header::Header as BlockHeader;
|
header::Header as BlockHeader,
|
||||||
|
verification::Unverified,
|
||||||
|
};
|
||||||
|
|
||||||
malloc_size_of_is_0!(HeaderId);
|
malloc_size_of_is_0!(HeaderId);
|
||||||
|
|
||||||
@ -541,12 +543,13 @@ impl BlockCollection {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{BlockCollection, SyncHeader};
|
use super::{BlockCollection, SyncHeader};
|
||||||
use ethcore::client::{TestBlockChainClient, EachBlockWith, BlockChainClient};
|
use client_traits::BlockChainClient;
|
||||||
|
use ethcore::client::{TestBlockChainClient, EachBlockWith};
|
||||||
use types::{
|
use types::{
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
BlockNumber
|
BlockNumber,
|
||||||
|
verification::Unverified,
|
||||||
};
|
};
|
||||||
use ethcore::verification::queue::kind::blocks::Unverified;
|
|
||||||
use rlp::*;
|
use rlp::*;
|
||||||
|
|
||||||
fn is_empty(bc: &BlockCollection) -> bool {
|
fn is_empty(bc: &BlockCollection) -> bool {
|
||||||
|
@ -19,7 +19,6 @@ use block_sync::{BlockDownloaderImportError as DownloaderImportError, DownloadAc
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use enum_primitive::FromPrimitive;
|
use enum_primitive::FromPrimitive;
|
||||||
use ethcore::snapshot::{ManifestData, RestorationStatus};
|
use ethcore::snapshot::{ManifestData, RestorationStatus};
|
||||||
use ethcore::verification::queue::kind::blocks::Unverified;
|
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use network::PeerId;
|
use network::PeerId;
|
||||||
@ -34,6 +33,7 @@ use types::{
|
|||||||
block_status::BlockStatus,
|
block_status::BlockStatus,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
errors::{EthcoreError, ImportError, BlockError},
|
errors::{EthcoreError, ImportError, BlockError},
|
||||||
|
verification::Unverified,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::sync_packet::{PacketInfo, SyncPacket};
|
use super::sync_packet::{PacketInfo, SyncPacket};
|
||||||
@ -742,9 +742,10 @@ impl SyncHandler {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ethcore::client::{ChainInfo, EachBlockWith, TestBlockChainClient};
|
use client_traits::ChainInfo;
|
||||||
|
use ethcore::client::{EachBlockWith, TestBlockChainClient};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rlp::{Rlp};
|
use rlp::Rlp;
|
||||||
use std::collections::{VecDeque};
|
use std::collections::{VecDeque};
|
||||||
use tests::helpers::{TestIo};
|
use tests::helpers::{TestIo};
|
||||||
use tests::snapshot::TestSnapshotService;
|
use tests::snapshot::TestSnapshotService;
|
||||||
|
@ -108,7 +108,7 @@ use bytes::Bytes;
|
|||||||
use rlp::{RlpStream, DecoderError};
|
use rlp::{RlpStream, DecoderError};
|
||||||
use network::{self, PeerId, PacketId};
|
use network::{self, PeerId, PacketId};
|
||||||
use network::client_version::ClientVersion;
|
use network::client_version::ClientVersion;
|
||||||
use ethcore::client::{BlockChainClient, BlockStatus, BlockChainInfo, BlockQueueInfo};
|
use client_traits::BlockChainClient;
|
||||||
use ethcore::snapshot::RestorationStatus;
|
use ethcore::snapshot::RestorationStatus;
|
||||||
use sync_io::SyncIo;
|
use sync_io::SyncIo;
|
||||||
use super::{WarpSync, SyncConfig};
|
use super::{WarpSync, SyncConfig};
|
||||||
@ -121,7 +121,10 @@ use transactions_stats::{TransactionsStats, Stats as TransactionStats};
|
|||||||
use types::{
|
use types::{
|
||||||
BlockNumber,
|
BlockNumber,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
transaction::UnverifiedTransaction
|
transaction::UnverifiedTransaction,
|
||||||
|
verification::VerificationQueueInfo as BlockQueueInfo,
|
||||||
|
blockchain_info::BlockChainInfo,
|
||||||
|
block_status::BlockStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::handler::SyncHandler;
|
use self::handler::SyncHandler;
|
||||||
@ -1373,8 +1376,8 @@ pub mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use ::SyncConfig;
|
use ::SyncConfig;
|
||||||
use super::{PeerInfo, PeerAsking};
|
use super::{PeerInfo, PeerAsking};
|
||||||
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo};
|
use ethcore::client::{EachBlockWith, TestBlockChainClient};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::{BlockInfo, BlockChainClient, ChainInfo};
|
||||||
use ethcore::miner::{MinerService, PendingOrdering};
|
use ethcore::miner::{MinerService, PendingOrdering};
|
||||||
use types::header::Header;
|
use types::header::Header;
|
||||||
|
|
||||||
|
@ -335,8 +335,8 @@ impl SyncPropagator {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ethcore::client::{ChainInfo, EachBlockWith, TestBlockChainClient};
|
use client_traits::{BlockInfo, ChainInfo};
|
||||||
use client_traits::BlockInfo;
|
use ethcore::client::{EachBlockWith, TestBlockChainClient};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rlp::Rlp;
|
use rlp::Rlp;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -376,7 +376,8 @@ mod test {
|
|||||||
use rlp::{Rlp, RlpStream};
|
use rlp::{Rlp, RlpStream};
|
||||||
use super::{*, super::tests::*};
|
use super::{*, super::tests::*};
|
||||||
use blocks::SyncHeader;
|
use blocks::SyncHeader;
|
||||||
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
|
use client_traits::BlockChainClient;
|
||||||
|
use ethcore::client::{EachBlockWith, TestBlockChainClient};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
//! https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
|
//! https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
|
||||||
//!
|
//!
|
||||||
|
|
||||||
|
extern crate client_traits;
|
||||||
extern crate common_types as types;
|
extern crate common_types as types;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
@ -46,8 +47,8 @@ extern crate ethcore_light as light;
|
|||||||
#[cfg(test)] extern crate kvdb_memorydb;
|
#[cfg(test)] extern crate kvdb_memorydb;
|
||||||
#[cfg(test)] extern crate rustc_hex;
|
#[cfg(test)] extern crate rustc_hex;
|
||||||
#[cfg(test)] extern crate rand_xorshift;
|
#[cfg(test)] extern crate rand_xorshift;
|
||||||
#[cfg(test)] extern crate client_traits;
|
|
||||||
#[cfg(test)] extern crate machine;
|
#[cfg(test)] extern crate machine;
|
||||||
|
#[cfg(test)] extern crate engine;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate enum_primitive;
|
extern crate enum_primitive;
|
||||||
|
@ -19,7 +19,7 @@ use chain::sync_packet::{PacketInfo, SyncPacket};
|
|||||||
use network::{NetworkContext, PeerId, PacketId, Error, SessionInfo, ProtocolId};
|
use network::{NetworkContext, PeerId, PacketId, Error, SessionInfo, ProtocolId};
|
||||||
use network::client_version::ClientVersion;
|
use network::client_version::ClientVersion;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use ethcore::client::BlockChainClient;
|
use client_traits::BlockChainClient;
|
||||||
use types::BlockNumber;
|
use types::BlockNumber;
|
||||||
use ethcore::snapshot::SnapshotService;
|
use ethcore::snapshot::SnapshotService;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::ids::BlockId;
|
use types::ids::BlockId;
|
||||||
use ethcore::client::{TestBlockChainClient, BlockChainClient, EachBlockWith, ChainInfo};
|
use client_traits::{BlockChainClient, ChainInfo};
|
||||||
|
use ethcore::client::{TestBlockChainClient, EachBlockWith};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use chain::SyncState;
|
use chain::SyncState;
|
||||||
use super::helpers::*;
|
use super::helpers::*;
|
||||||
|
@ -18,8 +18,9 @@ use std::sync::Arc;
|
|||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use ethereum_types::{U256, Address};
|
use ethereum_types::{U256, Address};
|
||||||
use io::{IoHandler, IoChannel};
|
use io::{IoHandler, IoChannel};
|
||||||
use ethcore::client::{ChainInfo, ClientIoMessage};
|
use client_traits::ChainInfo;
|
||||||
use ethcore::engines;
|
use engine::signer;
|
||||||
|
use ethcore::client::{ClientIoMessage};
|
||||||
use ethcore::spec;
|
use ethcore::spec;
|
||||||
use ethcore::miner::{self, MinerService};
|
use ethcore::miner::{self, MinerService};
|
||||||
use ethkey::{KeyPair, Secret};
|
use ethkey::{KeyPair, Secret};
|
||||||
@ -49,8 +50,8 @@ fn authority_round() {
|
|||||||
let io_handler0: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
let io_handler0: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
||||||
let io_handler1: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
let io_handler1: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
||||||
// Push transaction to both clients. Only one of them gets lucky to produce a block.
|
// Push transaction to both clients. Only one of them gets lucky to produce a block.
|
||||||
net.peer(0).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s0.clone())));
|
net.peer(0).miner.set_author(miner::Author::Sealer(signer::from_keypair(s0.clone())));
|
||||||
net.peer(1).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s1.clone())));
|
net.peer(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone())));
|
||||||
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
||||||
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
||||||
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler1)));
|
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler1)));
|
||||||
|
@ -22,7 +22,8 @@ use bytes::Bytes;
|
|||||||
use network::{self, PeerId, ProtocolId, PacketId, SessionInfo};
|
use network::{self, PeerId, ProtocolId, PacketId, SessionInfo};
|
||||||
use network::client_version::ClientVersion;
|
use network::client_version::ClientVersion;
|
||||||
use tests::snapshot::*;
|
use tests::snapshot::*;
|
||||||
use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient,
|
use client_traits::BlockChainClient;
|
||||||
|
use ethcore::client::{TestBlockChainClient, Client as EthcoreClient,
|
||||||
ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage};
|
ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage};
|
||||||
use ethcore::snapshot::SnapshotService;
|
use ethcore::snapshot::SnapshotService;
|
||||||
use ethcore::spec::{self, Spec};
|
use ethcore::spec::{self, Spec};
|
||||||
|
@ -19,10 +19,11 @@ use hash::keccak;
|
|||||||
use io::{IoHandler, IoChannel};
|
use io::{IoHandler, IoChannel};
|
||||||
use types::transaction::{Transaction, Action};
|
use types::transaction::{Transaction, Action};
|
||||||
use types::ids::BlockId;
|
use types::ids::BlockId;
|
||||||
|
use client_traits::BlockChainClient;
|
||||||
|
use engine::signer;
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
CreateContractAddress,
|
CreateContractAddress,
|
||||||
client::{ClientIoMessage, BlockChainClient},
|
client::ClientIoMessage,
|
||||||
engines,
|
|
||||||
miner::{self, MinerService},
|
miner::{self, MinerService},
|
||||||
spec::Spec,
|
spec::Spec,
|
||||||
test_helpers::push_block_with_transactions,
|
test_helpers::push_block_with_transactions,
|
||||||
@ -54,8 +55,8 @@ fn send_private_transaction() {
|
|||||||
let io_handler0: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
let io_handler0: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
||||||
let io_handler1: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
let io_handler1: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
||||||
|
|
||||||
net.peer(0).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s0.clone())));
|
net.peer(0).miner.set_author(miner::Author::Sealer(signer::from_keypair(s0.clone())));
|
||||||
net.peer(1).miner.set_author(miner::Author::Sealer(engines::signer::from_keypair(s1.clone())));
|
net.peer(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone())));
|
||||||
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
net.peer(0).chain.engine().register_client(Arc::downgrade(&net.peer(0).chain) as _);
|
||||||
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
net.peer(1).chain.engine().register_client(Arc::downgrade(&net.peer(1).chain) as _);
|
||||||
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler0)));
|
net.peer(0).chain.set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler0)));
|
||||||
|
49
ethcore/types/src/client_types.rs
Normal file
49
ethcore/types/src/client_types.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity Ethereum.
|
||||||
|
|
||||||
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Client related types.
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
fmt::{Display, Formatter, Error as FmtError},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Operating mode for the client.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub enum Mode {
|
||||||
|
/// Always on.
|
||||||
|
Active,
|
||||||
|
/// Goes offline after client is inactive for some (given) time, but
|
||||||
|
/// comes back online after a while of inactivity.
|
||||||
|
Passive(Duration, Duration),
|
||||||
|
/// Goes offline after client is inactive for some (given) time and
|
||||||
|
/// stays inactive.
|
||||||
|
Dark(Duration),
|
||||||
|
/// Always off.
|
||||||
|
Off,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Mode {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||||
|
match *self {
|
||||||
|
Mode::Active => write!(f, "active"),
|
||||||
|
Mode::Passive(..) => write!(f, "passive"),
|
||||||
|
Mode::Dark(..) => write!(f, "dark"),
|
||||||
|
Mode::Off => write!(f, "offline"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,9 +16,14 @@
|
|||||||
|
|
||||||
//! State machine types
|
//! State machine types
|
||||||
|
|
||||||
use ethereum_types::Address;
|
use ethereum_types::{Address, U256};
|
||||||
|
use bytes::Bytes;
|
||||||
|
|
||||||
use crate::receipt;
|
use crate::{
|
||||||
|
log_entry::LogEntry,
|
||||||
|
receipt,
|
||||||
|
state_diff::StateDiff,
|
||||||
|
};
|
||||||
|
|
||||||
/// Type alias for a function we can make calls through synchronously.
|
/// Type alias for a function we can make calls through synchronously.
|
||||||
/// Returns the call result and state proof for each call.
|
/// Returns the call result and state proof for each call.
|
||||||
@ -44,3 +49,47 @@ pub struct AuxiliaryData<'a> {
|
|||||||
/// The block receipts.
|
/// The block receipts.
|
||||||
pub receipts: Option<&'a [receipt::Receipt]>,
|
pub receipts: Option<&'a [receipt::Receipt]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Transaction execution receipt.
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub struct Executed<T, V> {
|
||||||
|
/// True if the outer call/create resulted in an exceptional exit.
|
||||||
|
pub exception: Option<vm::Error>,
|
||||||
|
|
||||||
|
/// Gas paid up front for execution of transaction.
|
||||||
|
pub gas: U256,
|
||||||
|
|
||||||
|
/// Gas used during execution of transaction.
|
||||||
|
pub gas_used: U256,
|
||||||
|
|
||||||
|
/// Gas refunded after the execution of transaction.
|
||||||
|
/// To get gas that was required up front, add `refunded` and `gas_used`.
|
||||||
|
pub refunded: U256,
|
||||||
|
|
||||||
|
/// Cumulative gas used in current block so far.
|
||||||
|
///
|
||||||
|
/// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)`
|
||||||
|
///
|
||||||
|
/// where `tn` is current transaction.
|
||||||
|
pub cumulative_gas_used: U256,
|
||||||
|
|
||||||
|
/// Vector of logs generated by transaction.
|
||||||
|
pub logs: Vec<LogEntry>,
|
||||||
|
|
||||||
|
/// Addresses of contracts created during execution of transaction.
|
||||||
|
/// Ordered from earliest creation.
|
||||||
|
///
|
||||||
|
/// eg. sender creates contract A and A in constructor creates contract B
|
||||||
|
///
|
||||||
|
/// B creation ends first, and it will be the first element of the vector.
|
||||||
|
pub contracts_created: Vec<Address>,
|
||||||
|
/// Transaction output.
|
||||||
|
pub output: Bytes,
|
||||||
|
/// The trace of this transaction.
|
||||||
|
pub trace: Vec<T>,
|
||||||
|
/// The VM trace of this transaction.
|
||||||
|
pub vm_trace: Option<V>,
|
||||||
|
/// The state diff, if we traced it.
|
||||||
|
pub state_diff: Option<StateDiff>,
|
||||||
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
//! Engine-specific types.
|
//! Engine-specific types.
|
||||||
|
|
||||||
use ethereum_types::{Address, H256};
|
use ethereum_types::{Address, H256};
|
||||||
|
use bytes::Bytes;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
|
|
||||||
use crate::BlockNumber;
|
use crate::BlockNumber;
|
||||||
@ -25,6 +26,15 @@ pub mod epoch;
|
|||||||
pub mod params;
|
pub mod params;
|
||||||
pub mod machine;
|
pub mod machine;
|
||||||
|
|
||||||
|
/// Seal type.
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum Seal {
|
||||||
|
/// Regular block seal; should be part of the blockchain.
|
||||||
|
Regular(Vec<Bytes>),
|
||||||
|
/// Engine does not generate seal for this block right now.
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
/// The type of sealing the engine is currently able to perform.
|
/// The type of sealing the engine is currently able to perform.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum SealingState {
|
pub enum SealingState {
|
||||||
|
@ -64,6 +64,7 @@ pub mod block;
|
|||||||
pub mod block_status;
|
pub mod block_status;
|
||||||
pub mod blockchain_info;
|
pub mod blockchain_info;
|
||||||
pub mod call_analytics;
|
pub mod call_analytics;
|
||||||
|
pub mod client_types;
|
||||||
pub mod encoded;
|
pub mod encoded;
|
||||||
pub mod engines;
|
pub mod engines;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
@ -75,12 +76,12 @@ pub mod pruning_info;
|
|||||||
pub mod receipt;
|
pub mod receipt;
|
||||||
pub mod restoration_status;
|
pub mod restoration_status;
|
||||||
pub mod security_level;
|
pub mod security_level;
|
||||||
pub mod snapshot_manifest;
|
pub mod snapshot;
|
||||||
pub mod state_diff;
|
pub mod state_diff;
|
||||||
pub mod trace_filter;
|
pub mod trace_filter;
|
||||||
pub mod transaction;
|
pub mod transaction;
|
||||||
pub mod tree_route;
|
pub mod tree_route;
|
||||||
pub mod verification_queue_info;
|
pub mod verification;
|
||||||
|
|
||||||
/// Type for block number.
|
/// Type for block number.
|
||||||
pub type BlockNumber = u64;
|
pub type BlockNumber = u64;
|
||||||
|
@ -14,12 +14,55 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Snapshot manifest type definition
|
//! Snapshot type definitions
|
||||||
|
|
||||||
|
use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU64, Ordering};
|
||||||
|
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use rlp::{Rlp, RlpStream, DecoderError};
|
use rlp::{Rlp, RlpStream, DecoderError};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|
||||||
|
/// A progress indicator for snapshots.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Progress {
|
||||||
|
/// Number of accounts processed so far
|
||||||
|
pub accounts: AtomicUsize,
|
||||||
|
/// Number of blocks processed so far
|
||||||
|
pub blocks: AtomicUsize,
|
||||||
|
/// Size in bytes of a all compressed chunks processed so far
|
||||||
|
pub size: AtomicU64,
|
||||||
|
/// Signals that the snapshotting process is completed
|
||||||
|
pub done: AtomicBool,
|
||||||
|
/// Signal snapshotting process to abort
|
||||||
|
pub abort: AtomicBool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Progress {
|
||||||
|
/// Reset the progress.
|
||||||
|
pub fn reset(&self) {
|
||||||
|
self.accounts.store(0, Ordering::Release);
|
||||||
|
self.blocks.store(0, Ordering::Release);
|
||||||
|
self.size.store(0, Ordering::Release);
|
||||||
|
self.abort.store(false, Ordering::Release);
|
||||||
|
|
||||||
|
// atomic fence here to ensure the others are written first?
|
||||||
|
// logs might very rarely get polluted if not.
|
||||||
|
self.done.store(false, Ordering::Release);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the number of accounts snapshotted thus far.
|
||||||
|
pub fn accounts(&self) -> usize { self.accounts.load(Ordering::Acquire) }
|
||||||
|
|
||||||
|
/// Get the number of blocks snapshotted thus far.
|
||||||
|
pub fn blocks(&self) -> usize { self.blocks.load(Ordering::Acquire) }
|
||||||
|
|
||||||
|
/// Get the written size of the snapshot in bytes.
|
||||||
|
pub fn size(&self) -> u64 { self.size.load(Ordering::Acquire) }
|
||||||
|
|
||||||
|
/// Whether the snapshot is complete.
|
||||||
|
pub fn done(&self) -> bool { self.done.load(Ordering::Acquire) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Manifest data.
|
/// Manifest data.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ManifestData {
|
pub struct ManifestData {
|
||||||
@ -67,12 +110,15 @@ impl ManifestData {
|
|||||||
let block_hash: H256 = decoder.val_at(start + 4)?;
|
let block_hash: H256 = decoder.val_at(start + 4)?;
|
||||||
|
|
||||||
Ok(ManifestData {
|
Ok(ManifestData {
|
||||||
version: version,
|
version,
|
||||||
state_hashes: state_hashes,
|
state_hashes,
|
||||||
block_hashes: block_hashes,
|
block_hashes,
|
||||||
state_root: state_root,
|
state_root,
|
||||||
block_number: block_number,
|
block_number,
|
||||||
block_hash: block_hash,
|
block_hash,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A sink for produced chunks.
|
||||||
|
pub type ChunkSink<'a> = dyn FnMut(&[u8]) -> std::io::Result<()> + 'a;
|
@ -14,7 +14,14 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Verification queue info types
|
//! Verification types
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
header::Header,
|
||||||
|
transaction::UnverifiedTransaction,
|
||||||
|
};
|
||||||
|
use bytes::Bytes;
|
||||||
|
use parity_util_mem::MallocSizeOf;
|
||||||
|
|
||||||
/// Verification queue status
|
/// Verification queue status
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -48,3 +55,38 @@ impl VerificationQueueInfo {
|
|||||||
self.unverified_queue_size + self.verified_queue_size + self.verifying_queue_size == 0
|
self.unverified_queue_size + self.verified_queue_size + self.verifying_queue_size == 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An unverified block.
|
||||||
|
#[derive(PartialEq, Debug, MallocSizeOf)]
|
||||||
|
pub struct Unverified {
|
||||||
|
/// Unverified block header.
|
||||||
|
pub header: Header,
|
||||||
|
/// Unverified block transactions.
|
||||||
|
pub transactions: Vec<UnverifiedTransaction>,
|
||||||
|
/// Unverified block uncles.
|
||||||
|
pub uncles: Vec<Header>,
|
||||||
|
/// Raw block bytes.
|
||||||
|
pub bytes: Bytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unverified {
|
||||||
|
/// Create an `Unverified` from raw bytes.
|
||||||
|
pub fn from_rlp(bytes: Bytes) -> Result<Self, rlp::DecoderError> {
|
||||||
|
use rlp::Rlp;
|
||||||
|
let (header, transactions, uncles) = {
|
||||||
|
let rlp = Rlp::new(&bytes);
|
||||||
|
let header = rlp.val_at(0)?;
|
||||||
|
let transactions = rlp.list_at(1)?;
|
||||||
|
let uncles = rlp.list_at(2)?;
|
||||||
|
(header, transactions, uncles)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Unverified {
|
||||||
|
header,
|
||||||
|
transactions,
|
||||||
|
uncles,
|
||||||
|
bytes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ license = "GPL-3.0"
|
|||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
client-traits = { path = "../ethcore/client-traits" }
|
||||||
common-types = { path = "../ethcore/types" }
|
common-types = { path = "../ethcore/types" }
|
||||||
ethcore = { path = "../ethcore" }
|
ethcore = { path = "../ethcore" }
|
||||||
parity-bytes = "0.1"
|
parity-bytes = "0.1"
|
||||||
|
@ -19,6 +19,7 @@ extern crate cid;
|
|||||||
extern crate unicase;
|
extern crate unicase;
|
||||||
|
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
extern crate client_traits;
|
||||||
extern crate common_types;
|
extern crate common_types;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
extern crate parity_bytes as bytes;
|
extern crate parity_bytes as bytes;
|
||||||
@ -35,7 +36,7 @@ use std::net::{SocketAddr, IpAddr};
|
|||||||
|
|
||||||
use core::futures::future::{self, FutureResult};
|
use core::futures::future::{self, FutureResult};
|
||||||
use core::futures::{self, Future};
|
use core::futures::{self, Future};
|
||||||
use ethcore::client::BlockChainClient;
|
use client_traits::BlockChainClient;
|
||||||
use http::hyper::{self, server, Method, StatusCode, Body,
|
use http::hyper::{self, server, Method, StatusCode, Body,
|
||||||
header::{self, HeaderValue},
|
header::{self, HeaderValue},
|
||||||
};
|
};
|
||||||
|
@ -66,7 +66,7 @@ pub struct LocalTransactionsList {
|
|||||||
max_old: usize,
|
max_old: usize,
|
||||||
transactions: LinkedHashMap<H256, Status>,
|
transactions: LinkedHashMap<H256, Status>,
|
||||||
pending: usize,
|
pending: usize,
|
||||||
in_chain: Option<Box<Fn(&H256) -> bool + Send + Sync>>,
|
in_chain: Option<Box<dyn Fn(&H256) -> bool + Send + Sync>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for LocalTransactionsList {
|
impl fmt::Debug for LocalTransactionsList {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user