Make ClientIoMessage generic over the Client (#10981)
* 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 * Extract the Clique engine to own crate * Extract NullEngine and the block_reward module from ethcore * Extract InstantSeal engine to own crate * Extract remaining engines * Extract executive_state to own crate so it can be used by engine crates * Remove snapshot stuff from the engine crate * Put snapshot traits back in ethcore * cleanup * Remove stuff from ethcore * Don't use itertools * itertools in aura is legit-ish * More post-merge fixes * Re-export less types in client * cleanup * Extract spec to own crate * Put back the test-helpers from basic-authority * Fix ethcore benchmarks * Reduce the public api of ethcore/verification * WIP * Add Cargo.toml * Fix compilation outside ethcore * Audit uses of import_verified_blocks() and remove unneeded calls Cleanup * cleanup * Remove unused imports from ethcore * Cleanup * remove double semi-colons * Add missing generic param * More missing generics * Update ethcore/block-reward/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/basic-authority/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/ethash/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/clique/src/lib.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * signers is already a ref * Add an EngineType enum to tighten up Engine.name() * Introduce Snapshotting enum to distinguish the type of snapshots a chain uses * Rename supports_warp to snapshot_mode * Missing import * Update ethcore/src/snapshot/consensus/mod.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * missing import * Fix import * double semi * Fix merge problem * cleanup * Parametrise `ClientIoMessage` with `()` for the light client * Add impl Tick for () * Address review feedback * Move ClientIoMessage to common-types * remove superseeded fixme * fix merge conflict errors
This commit is contained in:
parent
974b24549b
commit
cd26526868
37
Cargo.lock
generated
37
Cargo.lock
generated
@ -1052,7 +1052,6 @@ dependencies = [
|
|||||||
"kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"len-caching-lock 0.1.1",
|
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"machine 0.1.0",
|
"machine 0.1.0",
|
||||||
"macros 0.1.0",
|
"macros 0.1.0",
|
||||||
@ -1062,7 +1061,6 @@ dependencies = [
|
|||||||
"parity-bytes 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)",
|
||||||
"parity-runtime 0.1.0",
|
"parity-runtime 0.1.0",
|
||||||
"parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"patricia-trie-ethereum 0.1.0",
|
"patricia-trie-ethereum 0.1.0",
|
||||||
"pod 0.1.0",
|
"pod 0.1.0",
|
||||||
@ -1080,7 +1078,6 @@ dependencies = [
|
|||||||
"state-db 0.1.0",
|
"state-db 0.1.0",
|
||||||
"stats 0.1.0",
|
"stats 0.1.0",
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time-utils 0.1.0",
|
|
||||||
"trace 0.1.0",
|
"trace 0.1.0",
|
||||||
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1089,6 +1086,7 @@ dependencies = [
|
|||||||
"triehash-ethereum 0.2.0",
|
"triehash-ethereum 0.2.0",
|
||||||
"unexpected 0.1.0",
|
"unexpected 0.1.0",
|
||||||
"using_queue 0.1.0",
|
"using_queue 0.1.0",
|
||||||
|
"verification 0.1.0",
|
||||||
"vm 0.1.0",
|
"vm 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1245,6 +1243,7 @@ dependencies = [
|
|||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"triehash-ethereum 0.2.0",
|
"triehash-ethereum 0.2.0",
|
||||||
|
"verification 0.1.0",
|
||||||
"vm 0.1.0",
|
"vm 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1451,6 +1450,7 @@ name = "ethcore-service"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.11.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",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
@ -3021,6 +3021,7 @@ dependencies = [
|
|||||||
"term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"verification 0.1.0",
|
||||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3171,6 +3172,7 @@ dependencies = [
|
|||||||
"trace 0.1.0",
|
"trace 0.1.0",
|
||||||
"transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"verification 0.1.0",
|
||||||
"vm 0.1.0",
|
"vm 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4947,6 +4949,35 @@ dependencies = [
|
|||||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "verification"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"client-traits 0.1.0",
|
||||||
|
"common-types 0.1.0",
|
||||||
|
"engine 0.1.0",
|
||||||
|
"ethcore 1.12.0",
|
||||||
|
"ethcore-blockchain 0.1.0",
|
||||||
|
"ethcore-call-contract 0.1.0",
|
||||||
|
"ethcore-io 1.12.0",
|
||||||
|
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethkey 0.3.0",
|
||||||
|
"keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"len-caching-lock 0.1.1",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"machine 0.1.0",
|
||||||
|
"null-engine 0.1.0",
|
||||||
|
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"spec 0.1.0",
|
||||||
|
"time-utils 0.1.0",
|
||||||
|
"triehash-ethereum 0.2.0",
|
||||||
|
"unexpected 0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -73,6 +73,7 @@ spec = { path = "ethcore/spec" }
|
|||||||
term_size = "0.3"
|
term_size = "0.3"
|
||||||
textwrap = "0.9"
|
textwrap = "0.9"
|
||||||
toml = "0.4"
|
toml = "0.4"
|
||||||
|
verification = { path = "ethcore/verification" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
rustc_version = "0.2"
|
rustc_version = "0.2"
|
||||||
|
@ -35,16 +35,14 @@ evm = { path = "evm" }
|
|||||||
executive-state = { path = "executive-state" }
|
executive-state = { path = "executive-state" }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hash-db = "0.15.0"
|
hash-db = "0.15.0"
|
||||||
parity-util-mem = "0.2.0"
|
|
||||||
itertools = "0.5"
|
itertools = "0.5"
|
||||||
journaldb = { path = "../util/journaldb" }
|
journaldb = { path = "../util/journaldb" }
|
||||||
keccak-hash = "0.2.0"
|
keccak-hash = "0.2.0"
|
||||||
keccak-hasher = { path = "../util/keccak-hasher" }
|
keccak-hasher = { path = "../util/keccak-hasher" }
|
||||||
kvdb = "0.1"
|
kvdb = "0.1"
|
||||||
kvdb-memorydb = "0.1"
|
kvdb-memorydb = { version = "0.1", optional = true }
|
||||||
kvdb-rocksdb = { version = "0.1.3", optional = true }
|
kvdb-rocksdb = { version = "0.1.3", optional = true }
|
||||||
lazy_static = "1.3.0"
|
lazy_static = { version = "1.3", optional = true }
|
||||||
len-caching-lock = { path = "../util/len-caching-lock" }
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
macros = { path = "../util/macros", optional = true }
|
macros = { path = "../util/macros", optional = true }
|
||||||
machine = { path = "./machine" }
|
machine = { path = "./machine" }
|
||||||
@ -61,20 +59,19 @@ 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 = { version = "1", optional = true }
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
spec = { path = "spec" }
|
spec = { path = "spec" }
|
||||||
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" }
|
|
||||||
trace = { path = "trace" }
|
trace = { path = "trace" }
|
||||||
trace-time = "0.1"
|
trace-time = "0.1"
|
||||||
trie-vm-factories = { path = "trie-vm-factories" }
|
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" }
|
||||||
|
verification = { path = "./verification" }
|
||||||
vm = { path = "vm" }
|
vm = { path = "vm" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
@ -88,14 +85,18 @@ ethcore-accounts = { path = "../accounts" }
|
|||||||
ethjson = { path = "../json" }
|
ethjson = { path = "../json" }
|
||||||
ethkey = { path = "../accounts/ethkey" }
|
ethkey = { path = "../accounts/ethkey" }
|
||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
|
kvdb-memorydb = "0.1"
|
||||||
kvdb-rocksdb = "0.1.3"
|
kvdb-rocksdb = "0.1.3"
|
||||||
|
lazy_static = { version = "1.3" }
|
||||||
machine = { path = "./machine", features = ["test-helpers"] }
|
machine = { path = "./machine", features = ["test-helpers"] }
|
||||||
macros = { path = "../util/macros" }
|
macros = { path = "../util/macros" }
|
||||||
null-engine = { path = "./engines/null-engine" }
|
null-engine = { path = "./engines/null-engine" }
|
||||||
parity-runtime = { path = "../util/runtime" }
|
parity-runtime = { path = "../util/runtime" }
|
||||||
pod = { path = "pod" }
|
pod = { path = "pod" }
|
||||||
rlp_compress = { path = "../util/rlp-compress" }
|
rlp_compress = { path = "../util/rlp-compress" }
|
||||||
|
rustc-hex = "1"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
stats = { path = "../util/stats" }
|
||||||
tempdir = "0.3"
|
tempdir = "0.3"
|
||||||
trie-standardmap = "0.15.0"
|
trie-standardmap = "0.15.0"
|
||||||
|
|
||||||
@ -121,14 +122,14 @@ evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
|
|||||||
# EVM debug traces are printed.
|
# EVM debug traces are printed.
|
||||||
slow-blocks = []
|
slow-blocks = []
|
||||||
# Run JSON consensus tests.
|
# Run JSON consensus tests.
|
||||||
json-tests = ["env_logger", "test-helpers", "machine/test-helpers"]
|
json-tests = ["env_logger", "test-helpers", "lazy_static", "machine/test-helpers"]
|
||||||
# Skip JSON consensus tests with pending issues.
|
# Skip JSON consensus tests with pending issues.
|
||||||
ci-skip-tests = []
|
ci-skip-tests = []
|
||||||
# Run memory/cpu heavy tests.
|
# Run memory/cpu heavy tests.
|
||||||
test-heavy = []
|
test-heavy = []
|
||||||
# Compile test helpers
|
# Compile test helpers
|
||||||
# note[dvdplm]: "basic-authority/test-helpers" is needed so that `generate_dummy_client_with_spec` works
|
# note[dvdplm]: "basic-authority/test-helpers" is needed so that `generate_dummy_client_with_spec` works
|
||||||
test-helpers = ["tempdir", "kvdb-rocksdb", "blooms-db", "ethash", "ethjson", "ethkey", "macros", "pod", "basic-authority/test-helpers"]
|
test-helpers = ["tempdir", "kvdb-memorydb", "kvdb-rocksdb", "blooms-db", "ethash", "ethjson", "ethkey", "macros", "pod", "rustc-hex", "basic-authority/test-helpers"]
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "builtin"
|
name = "builtin"
|
||||||
|
@ -32,7 +32,7 @@ use common_types::{
|
|||||||
client_types::Mode,
|
client_types::Mode,
|
||||||
encoded,
|
encoded,
|
||||||
engines::{epoch::Transition as EpochTransition, machine::Executed},
|
engines::{epoch::Transition as EpochTransition, machine::Executed},
|
||||||
errors::EthcoreResult,
|
errors::{EthcoreError, EthcoreResult},
|
||||||
filter::Filter,
|
filter::Filter,
|
||||||
header::Header,
|
header::Header,
|
||||||
ids::{BlockId, TransactionId, TraceId, UncleId},
|
ids::{BlockId, TransactionId, TraceId, UncleId},
|
||||||
@ -56,6 +56,8 @@ use trace::{
|
|||||||
};
|
};
|
||||||
use vm::{LastHashes, Schedule};
|
use vm::{LastHashes, Schedule};
|
||||||
|
|
||||||
|
use common_types::snapshot::Progress;
|
||||||
|
|
||||||
/// State information to be used during client query
|
/// State information to be used during client query
|
||||||
pub enum StateOrBlock {
|
pub enum StateOrBlock {
|
||||||
/// State to be used, may be pending
|
/// State to be used, may be pending
|
||||||
@ -168,11 +170,14 @@ pub trait EngineClient: Sync + Send + ChainInfo {
|
|||||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
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
|
/// Provides methods to import block into blockchain
|
||||||
pub trait ImportBlock {
|
pub trait ImportBlock {
|
||||||
/// Import a block into the blockchain.
|
/// Import a block into the blockchain.
|
||||||
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
|
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
|
||||||
|
|
||||||
|
/// Triggered by a message from a block queue when the block is ready for insertion.
|
||||||
|
/// Returns the number of blocks imported.
|
||||||
|
fn import_verified_blocks(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// IO operations that should off-load heavy work to another thread.
|
/// IO operations that should off-load heavy work to another thread.
|
||||||
@ -187,6 +192,14 @@ pub trait IoClient: Sync + Send {
|
|||||||
fn queue_consensus_message(&self, message: Bytes);
|
fn queue_consensus_message(&self, message: Bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implement this for clients that need logic to decide when/how to advance.
|
||||||
|
pub trait Tick {
|
||||||
|
/// Tick the client
|
||||||
|
fn tick(&self, _prevent_sleep: bool) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tick for () {}
|
||||||
|
|
||||||
/// Provides recently seen bad blocks.
|
/// Provides recently seen bad blocks.
|
||||||
pub trait BadBlocks {
|
pub trait BadBlocks {
|
||||||
/// Returns a list of blocks that were recently not imported because they were invalid.
|
/// Returns a list of blocks that were recently not imported because they were invalid.
|
||||||
@ -377,6 +390,9 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra
|
|||||||
pub trait BlockChainReset {
|
pub trait BlockChainReset {
|
||||||
/// reset to best_block - n
|
/// reset to best_block - n
|
||||||
fn reset(&self, num: u32) -> Result<(), String>;
|
fn reset(&self, num: u32) -> Result<(), String>;
|
||||||
|
|
||||||
|
/// Number of eras kept in a journal before they are pruned
|
||||||
|
fn pruning_history(&self) -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -423,3 +439,38 @@ pub trait ProvingBlockChainClient: BlockChainClient {
|
|||||||
/// Get an epoch change signal by block hash.
|
/// Get an epoch change signal by block hash.
|
||||||
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>>;
|
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// External database restoration handler
|
||||||
|
pub trait DatabaseRestore: Send + Sync {
|
||||||
|
/// Restart with a new backend. Takes ownership of passed database and moves it to a new location.
|
||||||
|
fn restore_db(&self, new_db: &str) -> Result<(), EthcoreError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Snapshot related functionality
|
||||||
|
pub trait SnapshotClient: BlockChainClient + BlockInfo + DatabaseRestore + BlockChainReset {
|
||||||
|
/// Take a snapshot at the given block.
|
||||||
|
/// If the ID given is "latest", this will default to 1000 blocks behind.
|
||||||
|
fn take_snapshot<W: SnapshotWriter + Send>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
at: BlockId,
|
||||||
|
p: &Progress,
|
||||||
|
) -> Result<(), EthcoreError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// todo[dvdplm] move this back to snapshot once extracted from ethcore
|
||||||
|
/// Something which can write snapshots.
|
||||||
|
/// Writing the same chunk multiple times will lead to implementation-defined
|
||||||
|
/// behavior, and is not advised.
|
||||||
|
pub trait SnapshotWriter {
|
||||||
|
/// Write a compressed state chunk.
|
||||||
|
fn write_state_chunk(&mut self, hash: H256, chunk: &[u8]) -> std::io::Result<()>;
|
||||||
|
|
||||||
|
/// Write a compressed block chunk.
|
||||||
|
fn write_block_chunk(&mut self, hash: H256, chunk: &[u8]) -> std::io::Result<()>;
|
||||||
|
|
||||||
|
/// Complete writing. The manifest's chunk lists must be consistent
|
||||||
|
/// with the chunks written.
|
||||||
|
fn finish(self, manifest: common_types::snapshot::ManifestData) -> std::io::Result<()> where Self: Sized;
|
||||||
|
}
|
||||||
|
@ -13,7 +13,6 @@ 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" }
|
engine = { path = "../engine" }
|
||||||
ethcore = { path = ".."}
|
|
||||||
ethcore-db = { path = "../db" }
|
ethcore-db = { path = "../db" }
|
||||||
ethcore-blockchain = { path = "../blockchain" }
|
ethcore-blockchain = { path = "../blockchain" }
|
||||||
ethereum-types = "0.6.0"
|
ethereum-types = "0.6.0"
|
||||||
@ -49,6 +48,7 @@ kvdb = "0.1"
|
|||||||
memory-cache = { path = "../../util/memory-cache" }
|
memory-cache = { path = "../../util/memory-cache" }
|
||||||
error-chain = { version = "0.12", default-features = false }
|
error-chain = { version = "0.12", default-features = false }
|
||||||
journaldb = { path = "../../util/journaldb" }
|
journaldb = { path = "../../util/journaldb" }
|
||||||
|
verification = { path = "../verification" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ethcore = { path = "..", features = ["test-helpers"] }
|
ethcore = { path = "..", features = ["test-helpers"] }
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
use std::sync::{Weak, Arc};
|
use std::sync::{Weak, Arc};
|
||||||
|
|
||||||
use engine::{Engine, EpochChange, Proof};
|
use engine::{Engine, EpochChange, Proof};
|
||||||
use ethcore::client::{ClientReport, ClientIoMessage};
|
use verification::queue::{self, HeaderQueue};
|
||||||
use ethcore::verification::queue::{self, HeaderQueue};
|
|
||||||
use spec::{Spec, SpecHardcodedSync};
|
use spec::{Spec, SpecHardcodedSync};
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
@ -30,12 +29,14 @@ use common_types::{
|
|||||||
BlockNumber,
|
BlockNumber,
|
||||||
block_status::BlockStatus,
|
block_status::BlockStatus,
|
||||||
blockchain_info::BlockChainInfo,
|
blockchain_info::BlockChainInfo,
|
||||||
|
client_types::ClientReport,
|
||||||
encoded,
|
encoded,
|
||||||
engines::epoch::{Transition as EpochTransition, PendingTransition},
|
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,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
verification::VerificationQueueInfo as BlockQueueInfo,
|
verification::VerificationQueueInfo as BlockQueueInfo,
|
||||||
};
|
};
|
||||||
use kvdb::KeyValueDB;
|
use kvdb::KeyValueDB;
|
||||||
@ -162,7 +163,7 @@ impl<T: LightChainClient> AsLightClient for T {
|
|||||||
|
|
||||||
/// Light client implementation.
|
/// Light client implementation.
|
||||||
pub struct Client<T> {
|
pub struct Client<T> {
|
||||||
queue: HeaderQueue,
|
queue: HeaderQueue<()>,
|
||||||
engine: Arc<dyn Engine>,
|
engine: Arc<dyn Engine>,
|
||||||
chain: HeaderChain,
|
chain: HeaderChain,
|
||||||
report: RwLock<ClientReport>,
|
report: RwLock<ClientReport>,
|
||||||
@ -183,7 +184,7 @@ impl<T: ChainDataFetcher> Client<T> {
|
|||||||
chain_col: Option<u32>,
|
chain_col: Option<u32>,
|
||||||
spec: &Spec,
|
spec: &Spec,
|
||||||
fetcher: T,
|
fetcher: T,
|
||||||
io_channel: IoChannel<ClientIoMessage>,
|
io_channel: IoChannel<ClientIoMessage<()>>,
|
||||||
cache: Arc<Mutex<Cache>>
|
cache: Arc<Mutex<Cache>>
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -649,3 +650,5 @@ impl<T: ChainDataFetcher> client_traits::EngineClient for Client<T> {
|
|||||||
Client::block_header(self, id)
|
Client::block_header(self, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> client_traits::Tick for Client<T> {}
|
||||||
|
@ -20,10 +20,12 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use common_types::errors::EthcoreError as CoreError;
|
use common_types::{
|
||||||
|
errors::EthcoreError as CoreError,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
|
};
|
||||||
use ethcore_db as db;
|
use ethcore_db as db;
|
||||||
use ethcore_blockchain::BlockChainDB;
|
use ethcore_blockchain::BlockChainDB;
|
||||||
use ethcore::client::ClientIoMessage;
|
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use io::{IoContext, IoError, IoHandler, IoService};
|
use io::{IoContext, IoError, IoHandler, IoService};
|
||||||
|
|
||||||
@ -58,15 +60,15 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Light client service.
|
/// Light client service.
|
||||||
pub struct Service<T> {
|
pub struct Service<T: 'static> {
|
||||||
client: Arc<Client<T>>,
|
client: Arc<Client<T>>,
|
||||||
io_service: IoService<ClientIoMessage>,
|
io_service: IoService<ClientIoMessage<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ChainDataFetcher> Service<T> {
|
impl<T: ChainDataFetcher> Service<T> {
|
||||||
/// Start the service: initialize I/O workers and client itself.
|
/// Start the service: initialize I/O workers and client itself.
|
||||||
pub fn start(config: ClientConfig, spec: &Spec, fetcher: T, db: Arc<dyn BlockChainDB>, cache: Arc<Mutex<Cache>>) -> Result<Self, Error> {
|
pub fn start(config: ClientConfig, spec: &Spec, fetcher: T, db: Arc<dyn BlockChainDB>, cache: Arc<Mutex<Cache>>) -> Result<Self, Error> {
|
||||||
let io_service = IoService::<ClientIoMessage>::start().map_err(Error::Io)?;
|
let io_service = IoService::<ClientIoMessage<()>>::start().map_err(Error::Io)?;
|
||||||
let client = Arc::new(Client::new(config,
|
let client = Arc::new(Client::new(config,
|
||||||
db.key_value().clone(),
|
db.key_value().clone(),
|
||||||
db::COL_LIGHT_CHAIN,
|
db::COL_LIGHT_CHAIN,
|
||||||
@ -90,7 +92,7 @@ impl<T: ChainDataFetcher> Service<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Register an I/O handler on the service.
|
/// Register an I/O handler on the service.
|
||||||
pub fn register_handler(&self, handler: Arc<dyn IoHandler<ClientIoMessage> + Send>) -> Result<(), IoError> {
|
pub fn register_handler(&self, handler: Arc<dyn IoHandler<ClientIoMessage<()>> + Send>) -> Result<(), IoError> {
|
||||||
self.io_service.register_handler(handler)
|
self.io_service.register_handler(handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +104,8 @@ impl<T: ChainDataFetcher> Service<T> {
|
|||||||
|
|
||||||
struct ImportBlocks<T>(Arc<Client<T>>);
|
struct ImportBlocks<T>(Arc<Client<T>>);
|
||||||
|
|
||||||
impl<T: ChainDataFetcher> IoHandler<ClientIoMessage> for ImportBlocks<T> {
|
impl<T: ChainDataFetcher> IoHandler<ClientIoMessage<()>> for ImportBlocks<T> {
|
||||||
fn message(&self, _io: &IoContext<ClientIoMessage>, message: &ClientIoMessage) {
|
fn message(&self, _io: &IoContext<ClientIoMessage<()>>, message: &ClientIoMessage<()>) {
|
||||||
if let ClientIoMessage::BlockVerified = *message {
|
if let ClientIoMessage::BlockVerified = *message {
|
||||||
self.0.import_verified();
|
self.0.import_verified();
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,6 @@ extern crate executive_state;
|
|||||||
extern crate parity_bytes as bytes;
|
extern crate parity_bytes as bytes;
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate ethcore_miner as miner;
|
extern crate ethcore_miner as miner;
|
||||||
extern crate ethcore;
|
|
||||||
extern crate hash_db;
|
extern crate hash_db;
|
||||||
extern crate parity_util_mem;
|
extern crate parity_util_mem;
|
||||||
extern crate parity_util_mem as mem;
|
extern crate parity_util_mem as mem;
|
||||||
@ -94,7 +93,10 @@ extern crate triehash_ethereum as triehash;
|
|||||||
extern crate kvdb;
|
extern crate kvdb;
|
||||||
extern crate memory_cache;
|
extern crate memory_cache;
|
||||||
extern crate derive_more;
|
extern crate derive_more;
|
||||||
|
extern crate verification;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
extern crate ethcore;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate kvdb_memorydb;
|
extern crate kvdb_memorydb;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -104,11 +104,12 @@ use machine::{
|
|||||||
};
|
};
|
||||||
use types::{
|
use types::{
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction},
|
transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction},
|
||||||
engines::machine::Executed,
|
engines::machine::Executed,
|
||||||
};
|
};
|
||||||
use ethcore::client::{
|
use ethcore::client::{
|
||||||
Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, Call
|
Client, ChainNotify, NewBlocks, ChainMessageType, Call
|
||||||
};
|
};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
|
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
|
||||||
@ -213,7 +214,7 @@ pub struct Provider {
|
|||||||
client: Arc<Client>,
|
client: Arc<Client>,
|
||||||
miner: Arc<Miner>,
|
miner: Arc<Miner>,
|
||||||
accounts: Arc<dyn Signer>,
|
accounts: Arc<dyn Signer>,
|
||||||
channel: IoChannel<ClientIoMessage>,
|
channel: IoChannel<ClientIoMessage<Client>>,
|
||||||
keys_provider: Arc<dyn KeyProvider>,
|
keys_provider: Arc<dyn KeyProvider>,
|
||||||
logging: Option<Logging>,
|
logging: Option<Logging>,
|
||||||
use_offchain_storage: bool,
|
use_offchain_storage: bool,
|
||||||
@ -236,7 +237,7 @@ impl Provider {
|
|||||||
accounts: Arc<dyn Signer>,
|
accounts: Arc<dyn Signer>,
|
||||||
encryptor: Box<dyn Encryptor>,
|
encryptor: Box<dyn Encryptor>,
|
||||||
config: ProviderConfig,
|
config: ProviderConfig,
|
||||||
channel: IoChannel<ClientIoMessage>,
|
channel: IoChannel<ClientIoMessage<Client>>,
|
||||||
keys_provider: Arc<dyn KeyProvider>,
|
keys_provider: Arc<dyn KeyProvider>,
|
||||||
db: Arc<dyn KeyValueDB>,
|
db: Arc<dyn KeyValueDB>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -490,7 +491,7 @@ impl Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contract_address_from_transaction(transaction: &SignedTransaction) -> Result<Address, Error> {
|
fn contract_address_from_transaction(transaction: &SignedTransaction) -> Result<Address, Error> {
|
||||||
match transaction.action {
|
match transaction.action {
|
||||||
@ -876,14 +877,14 @@ impl Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IoHandler<ClientIoMessage> for Provider {
|
impl IoHandler<ClientIoMessage<Client>> for Provider {
|
||||||
fn initialize(&self, io: &IoContext<ClientIoMessage>) {
|
fn initialize(&self, io: &IoContext<ClientIoMessage<Client>>) {
|
||||||
if self.use_offchain_storage {
|
if self.use_offchain_storage {
|
||||||
io.register_timer(STATE_RETRIEVAL_TIMER, STATE_RETRIEVAL_TICK).expect("Error registering state retrieval timer");
|
io.register_timer(STATE_RETRIEVAL_TIMER, STATE_RETRIEVAL_TICK).expect("Error registering state retrieval timer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
|
fn timeout(&self, _io: &IoContext<ClientIoMessage<Client>>, timer: TimerToken) {
|
||||||
match timer {
|
match timer {
|
||||||
STATE_RETRIEVAL_TIMER => self.state_storage.tick(&self.logging),
|
STATE_RETRIEVAL_TIMER => self.state_storage.tick(&self.logging),
|
||||||
_ => warn!("IO service triggered unregistered timer '{}'", timer),
|
_ => warn!("IO service triggered unregistered timer '{}'", timer),
|
||||||
|
@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ansi_term = "0.11"
|
ansi_term = "0.11"
|
||||||
common-types = { path = "../types" }
|
common-types = { path = "../types" }
|
||||||
|
client-traits = { path = "../client-traits" }
|
||||||
ethcore = { path = ".." }
|
ethcore = { path = ".." }
|
||||||
ethcore-blockchain = { path = "../blockchain" }
|
ethcore-blockchain = { path = "../blockchain" }
|
||||||
ethcore-io = { path = "../../util/io" }
|
ethcore-io = { path = "../../util/io" }
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
extern crate common_types;
|
extern crate common_types;
|
||||||
|
extern crate client_traits;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
extern crate ethcore_blockchain as blockchain;
|
extern crate ethcore_blockchain as blockchain;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
|
@ -26,15 +26,17 @@ use io::{IoContext, TimerToken, IoHandler, IoService, IoError};
|
|||||||
|
|
||||||
use sync::PrivateTxHandler;
|
use sync::PrivateTxHandler;
|
||||||
use blockchain::{BlockChainDB, BlockChainDBHandler};
|
use blockchain::{BlockChainDB, BlockChainDBHandler};
|
||||||
use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage};
|
use ethcore::client::{Client, ClientConfig, ChainNotify};
|
||||||
use ethcore::miner::Miner;
|
use ethcore::miner::Miner;
|
||||||
use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams};
|
use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams};
|
||||||
use ethcore::snapshot::{SnapshotService as _SnapshotService};
|
use ethcore::snapshot::{SnapshotService as _SnapshotService};
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use common_types::{
|
use common_types::{
|
||||||
|
io_message::ClientIoMessage,
|
||||||
errors::{EthcoreError, SnapshotError},
|
errors::{EthcoreError, SnapshotError},
|
||||||
snapshot::RestorationStatus,
|
snapshot::RestorationStatus,
|
||||||
};
|
};
|
||||||
|
use client_traits::{ImportBlock, SnapshotClient, Tick};
|
||||||
|
|
||||||
|
|
||||||
use ethcore_private_tx::{self, Importer, Signer};
|
use ethcore_private_tx::{self, Importer, Signer};
|
||||||
@ -90,7 +92,7 @@ impl PrivateTxHandler for PrivateTxService {
|
|||||||
|
|
||||||
/// Client service setup. Creates and registers client and network services with the IO subsystem.
|
/// Client service setup. Creates and registers client and network services with the IO subsystem.
|
||||||
pub struct ClientService {
|
pub struct ClientService {
|
||||||
io_service: Arc<IoService<ClientIoMessage>>,
|
io_service: Arc<IoService<ClientIoMessage<Client>>>,
|
||||||
client: Arc<Client>,
|
client: Arc<Client>,
|
||||||
snapshot: Arc<SnapshotService>,
|
snapshot: Arc<SnapshotService>,
|
||||||
private_tx: Arc<PrivateTxService>,
|
private_tx: Arc<PrivateTxService>,
|
||||||
@ -113,7 +115,7 @@ impl ClientService {
|
|||||||
private_encryptor_conf: ethcore_private_tx::EncryptorConfig,
|
private_encryptor_conf: ethcore_private_tx::EncryptorConfig,
|
||||||
) -> Result<ClientService, EthcoreError>
|
) -> Result<ClientService, EthcoreError>
|
||||||
{
|
{
|
||||||
let io_service = IoService::<ClientIoMessage>::start()?;
|
let io_service = IoService::<ClientIoMessage<Client>>::start()?;
|
||||||
|
|
||||||
info!("Configured for {} using {} engine", Colour::White.bold().paint(spec.name.clone()), Colour::Yellow.bold().paint(spec.engine.name().to_string()));
|
info!("Configured for {} using {} engine", Colour::White.bold().paint(spec.name.clone()), Colour::Yellow.bold().paint(spec.engine.name().to_string()));
|
||||||
|
|
||||||
@ -165,15 +167,15 @@ impl ClientService {
|
|||||||
|
|
||||||
Ok(ClientService {
|
Ok(ClientService {
|
||||||
io_service: Arc::new(io_service),
|
io_service: Arc::new(io_service),
|
||||||
client: client,
|
client,
|
||||||
snapshot: snapshot,
|
snapshot,
|
||||||
private_tx,
|
private_tx,
|
||||||
database: blockchain_db,
|
database: blockchain_db,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get general IO interface
|
/// Get general IO interface
|
||||||
pub fn register_io_handler(&self, handler: Arc<dyn IoHandler<ClientIoMessage> + Send>) -> Result<(), IoError> {
|
pub fn register_io_handler(&self, handler: Arc<dyn IoHandler<ClientIoMessage<Client>> + Send>) -> Result<(), IoError> {
|
||||||
self.io_service.register_handler(handler)
|
self.io_service.register_handler(handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +195,7 @@ impl ClientService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get network service component
|
/// Get network service component
|
||||||
pub fn io(&self) -> Arc<IoService<ClientIoMessage>> {
|
pub fn io(&self) -> Arc<IoService<ClientIoMessage<Client>>> {
|
||||||
self.io_service.clone()
|
self.io_service.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,8 +215,8 @@ impl ClientService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// IO interface for the Client handler
|
/// IO interface for the Client handler
|
||||||
struct ClientIoHandler {
|
struct ClientIoHandler<C> {
|
||||||
client: Arc<Client>,
|
client: Arc<C>,
|
||||||
snapshot: Arc<SnapshotService>,
|
snapshot: Arc<SnapshotService>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,13 +226,16 @@ const SNAPSHOT_TICK_TIMER: TimerToken = 1;
|
|||||||
const CLIENT_TICK: Duration = Duration::from_secs(5);
|
const CLIENT_TICK: Duration = Duration::from_secs(5);
|
||||||
const SNAPSHOT_TICK: Duration = Duration::from_secs(10);
|
const SNAPSHOT_TICK: Duration = Duration::from_secs(10);
|
||||||
|
|
||||||
impl IoHandler<ClientIoMessage> for ClientIoHandler {
|
impl<C> IoHandler<ClientIoMessage<C>> for ClientIoHandler<C>
|
||||||
fn initialize(&self, io: &IoContext<ClientIoMessage>) {
|
where
|
||||||
|
C: ImportBlock + SnapshotClient + Tick + 'static,
|
||||||
|
{
|
||||||
|
fn initialize(&self, io: &IoContext<ClientIoMessage<C>>) {
|
||||||
io.register_timer(CLIENT_TICK_TIMER, CLIENT_TICK).expect("Error registering client timer");
|
io.register_timer(CLIENT_TICK_TIMER, CLIENT_TICK).expect("Error registering client timer");
|
||||||
io.register_timer(SNAPSHOT_TICK_TIMER, SNAPSHOT_TICK).expect("Error registering snapshot timer");
|
io.register_timer(SNAPSHOT_TICK_TIMER, SNAPSHOT_TICK).expect("Error registering snapshot timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
|
fn timeout(&self, _io: &IoContext<ClientIoMessage<C>>, timer: TimerToken) {
|
||||||
trace_time!("service::read");
|
trace_time!("service::read");
|
||||||
match timer {
|
match timer {
|
||||||
CLIENT_TICK_TIMER => {
|
CLIENT_TICK_TIMER => {
|
||||||
@ -243,7 +248,7 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn message(&self, _io: &IoContext<ClientIoMessage>, net_message: &ClientIoMessage) {
|
fn message(&self, _io: &IoContext<ClientIoMessage<C>>, net_message: &ClientIoMessage<C>) {
|
||||||
trace_time!("service::message");
|
trace_time!("service::message");
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
@ -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 std::{cmp, ops};
|
use std::cmp;
|
||||||
use std::collections::{HashSet, BTreeMap, VecDeque};
|
use std::collections::{HashSet, BTreeMap, VecDeque};
|
||||||
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
@ -42,14 +42,15 @@ use client::ancient_import::AncientVerifier;
|
|||||||
use client::{
|
use client::{
|
||||||
ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock,
|
ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock,
|
||||||
Call, BlockProducer, SealedBlockImporter, ChainNotify, EngineInfo,
|
Call, BlockProducer, SealedBlockImporter, ChainNotify, EngineInfo,
|
||||||
ClientConfig, NewBlocks, ChainRoute, ChainMessageType, bad_blocks, ClientIoMessage,
|
ClientConfig, NewBlocks, ChainRoute, ChainMessageType, bad_blocks,
|
||||||
};
|
};
|
||||||
use client_traits::{
|
use client_traits::{
|
||||||
BlockInfo, ScheduleInfo, StateClient, BlockChainReset,
|
BlockInfo, ScheduleInfo, StateClient, BlockChainReset,
|
||||||
Nonce, Balance, ChainInfo, TransactionInfo, ImportBlock,
|
Nonce, Balance, ChainInfo, TransactionInfo, ImportBlock,
|
||||||
AccountData, BlockChain as BlockChainTrait, BlockChainClient,
|
AccountData, BlockChain as BlockChainTrait, BlockChainClient,
|
||||||
IoClient, BadBlocks, ProvingBlockChainClient,
|
IoClient, BadBlocks, ProvingBlockChainClient, SnapshotClient,
|
||||||
StateOrBlock
|
DatabaseRestore, SnapshotWriter, Tick,
|
||||||
|
StateOrBlock,
|
||||||
};
|
};
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use machine::{
|
use machine::{
|
||||||
@ -59,7 +60,7 @@ use machine::{
|
|||||||
};
|
};
|
||||||
use trie_vm_factories::{Factories, VmFactory};
|
use trie_vm_factories::{Factories, VmFactory};
|
||||||
use miner::{Miner, MinerService};
|
use miner::{Miner, MinerService};
|
||||||
use snapshot::{self, io as snapshot_io, SnapshotClient};
|
use snapshot;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use account_state::State;
|
use account_state::State;
|
||||||
use executive_state;
|
use executive_state;
|
||||||
@ -71,6 +72,8 @@ use types::{
|
|||||||
block::PreverifiedBlock,
|
block::PreverifiedBlock,
|
||||||
block_status::BlockStatus,
|
block_status::BlockStatus,
|
||||||
blockchain_info::BlockChainInfo,
|
blockchain_info::BlockChainInfo,
|
||||||
|
client_types::ClientReport,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
encoded,
|
encoded,
|
||||||
engines::{
|
engines::{
|
||||||
ForkChoice,
|
ForkChoice,
|
||||||
@ -111,44 +114,6 @@ const MAX_ANCIENT_BLOCKS_TO_IMPORT: usize = 4;
|
|||||||
const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2;
|
const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2;
|
||||||
const MIN_HISTORY_SIZE: u64 = 8;
|
const MIN_HISTORY_SIZE: u64 = 8;
|
||||||
|
|
||||||
/// Report on the status of a client.
|
|
||||||
#[derive(Default, Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct ClientReport {
|
|
||||||
/// How many blocks have been imported so far.
|
|
||||||
pub blocks_imported: usize,
|
|
||||||
/// How many transactions have been applied so far.
|
|
||||||
pub transactions_applied: usize,
|
|
||||||
/// How much gas has been processed so far.
|
|
||||||
pub gas_processed: U256,
|
|
||||||
/// Memory used by state DB
|
|
||||||
pub state_db_mem: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientReport {
|
|
||||||
/// Alter internal reporting to reflect the additional `block` has been processed.
|
|
||||||
pub fn accrue_block(&mut self, header: &Header, transactions: usize) {
|
|
||||||
self.blocks_imported += 1;
|
|
||||||
self.transactions_applied += transactions;
|
|
||||||
self.gas_processed = self.gas_processed + *header.gas_used();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ops::Sub<&'a ClientReport> for ClientReport {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn sub(mut self, other: &'a ClientReport) -> Self {
|
|
||||||
let higher_mem = cmp::max(self.state_db_mem, other.state_db_mem);
|
|
||||||
let lower_mem = cmp::min(self.state_db_mem, other.state_db_mem);
|
|
||||||
|
|
||||||
self.blocks_imported -= other.blocks_imported;
|
|
||||||
self.transactions_applied -= other.transactions_applied;
|
|
||||||
self.gas_processed = self.gas_processed - other.gas_processed;
|
|
||||||
self.state_db_mem = higher_mem - lower_mem;
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SleepState {
|
struct SleepState {
|
||||||
last_activity: Option<Instant>,
|
last_activity: Option<Instant>,
|
||||||
last_autosleep: Option<Instant>,
|
last_autosleep: Option<Instant>,
|
||||||
@ -171,7 +136,7 @@ struct Importer {
|
|||||||
pub verifier: Box<dyn Verifier<Client>>,
|
pub verifier: Box<dyn Verifier<Client>>,
|
||||||
|
|
||||||
/// Queue containing pending blocks
|
/// Queue containing pending blocks
|
||||||
pub block_queue: BlockQueue,
|
pub block_queue: BlockQueue<Client>,
|
||||||
|
|
||||||
/// Handles block sealing
|
/// Handles block sealing
|
||||||
pub miner: Arc<Miner>,
|
pub miner: Arc<Miner>,
|
||||||
@ -222,7 +187,7 @@ pub struct Client {
|
|||||||
|
|
||||||
/// Flag changed by `sleep` and `wake_up` methods. Not to be confused with `enabled`.
|
/// Flag changed by `sleep` and `wake_up` methods. Not to be confused with `enabled`.
|
||||||
liveness: AtomicBool,
|
liveness: AtomicBool,
|
||||||
io_channel: RwLock<IoChannel<ClientIoMessage>>,
|
io_channel: RwLock<IoChannel<ClientIoMessage<Self>>>,
|
||||||
|
|
||||||
/// List of actors to be notified on certain chain events
|
/// List of actors to be notified on certain chain events
|
||||||
notify: RwLock<Vec<Weak<dyn ChainNotify>>>,
|
notify: RwLock<Vec<Weak<dyn ChainNotify>>>,
|
||||||
@ -261,7 +226,7 @@ impl Importer {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
config: &ClientConfig,
|
config: &ClientConfig,
|
||||||
engine: Arc<dyn Engine>,
|
engine: Arc<dyn Engine>,
|
||||||
message_channel: IoChannel<ClientIoMessage>,
|
message_channel: IoChannel<ClientIoMessage<Client>>,
|
||||||
miner: Arc<Miner>,
|
miner: Arc<Miner>,
|
||||||
) -> Result<Importer, EthcoreError> {
|
) -> Result<Importer, EthcoreError> {
|
||||||
let block_queue = BlockQueue::new(
|
let block_queue = BlockQueue::new(
|
||||||
@ -723,7 +688,7 @@ impl Client {
|
|||||||
spec: &Spec,
|
spec: &Spec,
|
||||||
db: Arc<dyn BlockChainDB>,
|
db: Arc<dyn BlockChainDB>,
|
||||||
miner: Arc<Miner>,
|
miner: Arc<Miner>,
|
||||||
message_channel: IoChannel<ClientIoMessage>,
|
message_channel: IoChannel<ClientIoMessage<Self>>,
|
||||||
) -> Result<Arc<Client>, EthcoreError> {
|
) -> Result<Arc<Client>, EthcoreError> {
|
||||||
let trie_spec = match config.fat_db {
|
let trie_spec = match config.fat_db {
|
||||||
true => TrieSpec::Fat,
|
true => TrieSpec::Fat,
|
||||||
@ -948,11 +913,6 @@ impl Client {
|
|||||||
Arc::new(last_hashes)
|
Arc::new(last_hashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is triggered by a message coming from a block queue when the block is ready for insertion
|
|
||||||
pub fn import_verified_blocks(&self) -> usize {
|
|
||||||
self.importer.import_verified_blocks(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
// use a state-proving closure for the given block.
|
// use a state-proving closure for the given block.
|
||||||
fn with_proving_caller<F, T>(&self, id: BlockId, with_call: F) -> T
|
fn with_proving_caller<F, T>(&self, id: BlockId, with_call: F) -> T
|
||||||
where F: FnOnce(&MachineCall) -> T
|
where F: FnOnce(&MachineCall) -> T
|
||||||
@ -1037,7 +997,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Replace io channel. Useful for testing.
|
/// Replace io channel. Useful for testing.
|
||||||
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
|
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage<Self>>) {
|
||||||
*self.io_channel.write() = io_channel;
|
*self.io_channel.write() = io_channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,15 +1072,6 @@ impl Client {
|
|||||||
report
|
report
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tick the client.
|
|
||||||
// TODO: manage by real events.
|
|
||||||
pub fn tick(&self, prevent_sleep: bool) {
|
|
||||||
self.check_garbage();
|
|
||||||
if !prevent_sleep {
|
|
||||||
self.check_snooze();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_garbage(&self) {
|
fn check_garbage(&self) {
|
||||||
self.chain.read().collect_garbage();
|
self.chain.read().collect_garbage();
|
||||||
self.importer.block_queue.collect_garbage();
|
self.importer.block_queue.collect_garbage();
|
||||||
@ -1161,64 +1112,6 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take a snapshot at the given block.
|
|
||||||
/// If the ID given is "latest", this will default to 1000 blocks behind.
|
|
||||||
pub fn take_snapshot<W: snapshot_io::SnapshotWriter + Send>(
|
|
||||||
&self,
|
|
||||||
writer: W,
|
|
||||||
at: BlockId,
|
|
||||||
p: &Progress,
|
|
||||||
) -> Result<(), EthcoreError> {
|
|
||||||
if let Snapshotting::Unsupported = self.engine.snapshot_mode() {
|
|
||||||
return Err(EthcoreError::Snapshot(SnapshotError::SnapshotsUnsupported));
|
|
||||||
}
|
|
||||||
let db = self.state_db.read().journal_db().boxed_clone();
|
|
||||||
let best_block_number = self.chain_info().best_block_number;
|
|
||||||
let block_number = self.block_number(at).ok_or_else(|| SnapshotError::InvalidStartingBlock(at))?;
|
|
||||||
|
|
||||||
if db.is_prunable() && self.pruning_info().earliest_state > block_number {
|
|
||||||
return Err(SnapshotError::OldBlockPrunedDB.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let history = cmp::min(self.history, 1000);
|
|
||||||
|
|
||||||
let start_hash = match at {
|
|
||||||
BlockId::Latest => {
|
|
||||||
let start_num = match db.earliest_era() {
|
|
||||||
Some(era) => cmp::max(era, best_block_number.saturating_sub(history)),
|
|
||||||
None => best_block_number.saturating_sub(history),
|
|
||||||
};
|
|
||||||
|
|
||||||
match self.block_hash(BlockId::Number(start_num)) {
|
|
||||||
Some(h) => h,
|
|
||||||
None => return Err(SnapshotError::InvalidStartingBlock(at).into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => match self.block_hash(at) {
|
|
||||||
Some(hash) => hash,
|
|
||||||
None => return Err(SnapshotError::InvalidStartingBlock(at).into()),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let processing_threads = self.config.snapshot.processing_threads;
|
|
||||||
let chunker = snapshot::chunker(self.engine.snapshot_mode()).ok_or_else(|| SnapshotError::SnapshotsUnsupported)?;
|
|
||||||
snapshot::take_snapshot(
|
|
||||||
chunker,
|
|
||||||
&self.chain.read(),
|
|
||||||
start_hash,
|
|
||||||
db.as_hash_db(),
|
|
||||||
writer,
|
|
||||||
p,
|
|
||||||
processing_threads,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ask the client what the history parameter is.
|
|
||||||
pub fn pruning_history(&self) -> u64 {
|
|
||||||
self.history
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> {
|
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> {
|
||||||
match id {
|
match id {
|
||||||
BlockId::Hash(hash) => Some(hash),
|
BlockId::Hash(hash) => Some(hash),
|
||||||
@ -1342,7 +1235,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl snapshot::DatabaseRestore for Client {
|
impl DatabaseRestore for Client {
|
||||||
/// Restart the client with a new backend
|
/// Restart the client with a new backend
|
||||||
fn restore_db(&self, new_db: &str) -> Result<(), EthcoreError> {
|
fn restore_db(&self, new_db: &str) -> Result<(), EthcoreError> {
|
||||||
trace!(target: "snapshot", "Replacing client database with {:?}", new_db);
|
trace!(target: "snapshot", "Replacing client database with {:?}", new_db);
|
||||||
@ -1426,6 +1319,11 @@ impl BlockChainReset for Client {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ask the client what the history parameter is.
|
||||||
|
fn pruning_history(&self) -> u64 {
|
||||||
|
self.history
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Nonce for Client {
|
impl Nonce for Client {
|
||||||
@ -1547,6 +1445,11 @@ impl ImportBlock for Client {
|
|||||||
Err((_, e)) => Err(e),
|
Err((_, e)) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Triggered by a message from a block queue when the block is ready for insertion
|
||||||
|
fn import_verified_blocks(&self) -> usize {
|
||||||
|
self.importer.import_verified_blocks(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateClient for Client {
|
impl StateClient for Client {
|
||||||
@ -2341,6 +2244,18 @@ impl IoClient for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tick for Client {
|
||||||
|
/// Tick the client.
|
||||||
|
// TODO: manage by real events.
|
||||||
|
fn tick(&self, prevent_sleep: bool) {
|
||||||
|
self.check_garbage();
|
||||||
|
if !prevent_sleep {
|
||||||
|
self.check_snooze();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReopenBlock for Client {
|
impl ReopenBlock for Client {
|
||||||
@ -2581,7 +2496,60 @@ impl ProvingBlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SnapshotClient for Client {}
|
impl SnapshotClient for Client {
|
||||||
|
fn take_snapshot<W: SnapshotWriter + Send>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
at: BlockId,
|
||||||
|
p: &Progress,
|
||||||
|
) -> Result<(), EthcoreError> {
|
||||||
|
if let Snapshotting::Unsupported = self.engine.snapshot_mode() {
|
||||||
|
return Err(EthcoreError::Snapshot(SnapshotError::SnapshotsUnsupported));
|
||||||
|
}
|
||||||
|
let db = self.state_db.read().journal_db().boxed_clone();
|
||||||
|
let best_block_number = self.chain_info().best_block_number;
|
||||||
|
let block_number = self.block_number(at).ok_or_else(|| SnapshotError::InvalidStartingBlock(at))?;
|
||||||
|
|
||||||
|
if db.is_prunable() && self.pruning_info().earliest_state > block_number {
|
||||||
|
return Err(SnapshotError::OldBlockPrunedDB.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let history = cmp::min(self.history, 1000);
|
||||||
|
|
||||||
|
let start_hash = match at {
|
||||||
|
BlockId::Latest => {
|
||||||
|
let start_num = match db.earliest_era() {
|
||||||
|
Some(era) => cmp::max(era, best_block_number.saturating_sub(history)),
|
||||||
|
None => best_block_number.saturating_sub(history),
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.block_hash(BlockId::Number(start_num)) {
|
||||||
|
Some(h) => h,
|
||||||
|
None => return Err(SnapshotError::InvalidStartingBlock(at).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => match self.block_hash(at) {
|
||||||
|
Some(hash) => hash,
|
||||||
|
None => return Err(SnapshotError::InvalidStartingBlock(at).into()),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let processing_threads = self.config.snapshot.processing_threads;
|
||||||
|
let chunker = snapshot::chunker(self.engine.snapshot_mode()).ok_or_else(|| SnapshotError::SnapshotsUnsupported)?;
|
||||||
|
snapshot::take_snapshot(
|
||||||
|
chunker,
|
||||||
|
&self.chain.read(),
|
||||||
|
start_hash,
|
||||||
|
db.as_hash_db(),
|
||||||
|
writer,
|
||||||
|
p,
|
||||||
|
processing_threads,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `LocalizedReceipt` given `LocalizedTransaction`
|
/// Returns `LocalizedReceipt` given `LocalizedTransaction`
|
||||||
/// and a vector of receipts from given block up to transaction index.
|
/// and a vector of receipts from given block up to transaction index.
|
||||||
@ -2641,7 +2609,7 @@ impl IoChannelQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn queue<F>(&self, channel: &IoChannel<ClientIoMessage>, count: usize, fun: F) -> EthcoreResult<()> where
|
pub fn queue<F>(&self, channel: &IoChannel<ClientIoMessage<Client>>, count: usize, fun: F) -> EthcoreResult<()> where
|
||||||
F: Fn(&Client) + Send + Sync + 'static,
|
F: Fn(&Client) + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed);
|
let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed);
|
||||||
|
@ -22,15 +22,13 @@ mod client;
|
|||||||
mod config;
|
mod config;
|
||||||
#[cfg(any(test, feature = "test-helpers"))]
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
mod evm_test_client;
|
mod evm_test_client;
|
||||||
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::{Client, ClientReport};
|
pub use self::client::Client;
|
||||||
pub use self::config::{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;
|
|
||||||
#[cfg(any(test, feature = "test-helpers"))]
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
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};
|
||||||
|
@ -592,6 +592,10 @@ impl ImportBlock for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
Ok(h)
|
Ok(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn import_verified_blocks(&self) -> usize {
|
||||||
|
unimplemented!("TestClient does not implement import_verified_blocks()")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Call for TestBlockChainClient {
|
impl Call for TestBlockChainClient {
|
||||||
|
@ -100,7 +100,6 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
|
|||||||
if let Ok(block) = Unverified::from_rlp(b) {
|
if let Ok(block) = Unverified::from_rlp(b) {
|
||||||
let _ = client.import_block(block);
|
let _ = client.import_block(block);
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
client.import_verified_blocks();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fail_unless(client.chain_info().best_block_hash == blockchain.best_block.into());
|
fail_unless(client.chain_info().best_block_hash == blockchain.best_block.into());
|
||||||
|
@ -69,7 +69,6 @@ extern crate ethcore_io as io;
|
|||||||
extern crate ethcore_miner;
|
extern crate ethcore_miner;
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate executive_state;
|
extern crate executive_state;
|
||||||
extern crate trie_vm_factories;
|
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate hash_db;
|
extern crate hash_db;
|
||||||
extern crate itertools;
|
extern crate itertools;
|
||||||
@ -77,10 +76,6 @@ extern crate journaldb;
|
|||||||
extern crate keccak_hash as hash;
|
extern crate keccak_hash as hash;
|
||||||
extern crate keccak_hasher;
|
extern crate keccak_hasher;
|
||||||
extern crate kvdb;
|
extern crate kvdb;
|
||||||
#[cfg(any(test, feature = "test-helpers"))]
|
|
||||||
extern crate kvdb_memorydb;
|
|
||||||
|
|
||||||
extern crate len_caching_lock;
|
|
||||||
extern crate machine;
|
extern crate machine;
|
||||||
extern crate memory_cache;
|
extern crate memory_cache;
|
||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
@ -92,18 +87,15 @@ extern crate patricia_trie_ethereum as ethtrie;
|
|||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate parity_util_mem;
|
|
||||||
extern crate parity_util_mem as malloc_size_of;
|
|
||||||
#[cfg(any(test, feature = "test-helpers"))]
|
|
||||||
extern crate rustc_hex;
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate spec;
|
extern crate spec;
|
||||||
extern crate state_db;
|
extern crate state_db;
|
||||||
extern crate time_utils;
|
|
||||||
extern crate trace;
|
extern crate trace;
|
||||||
|
extern crate trie_vm_factories;
|
||||||
extern crate triehash_ethereum as triehash;
|
extern crate triehash_ethereum as triehash;
|
||||||
extern crate unexpected;
|
extern crate unexpected;
|
||||||
extern crate using_queue;
|
extern crate using_queue;
|
||||||
|
extern crate verification;
|
||||||
extern crate vm;
|
extern crate vm;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -119,8 +111,8 @@ extern crate ethash;
|
|||||||
extern crate ethkey;
|
extern crate ethkey;
|
||||||
#[cfg(any(test, feature = "test-helpers"))]
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
extern crate ethjson;
|
extern crate ethjson;
|
||||||
#[cfg(any(test, feature = "tempdir"))]
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
extern crate tempdir;
|
extern crate kvdb_memorydb;
|
||||||
#[cfg(any(test, feature = "kvdb-rocksdb"))]
|
#[cfg(any(test, feature = "kvdb-rocksdb"))]
|
||||||
extern crate kvdb_rocksdb;
|
extern crate kvdb_rocksdb;
|
||||||
#[cfg(any(test, feature = "json-tests"))]
|
#[cfg(any(test, feature = "json-tests"))]
|
||||||
@ -137,8 +129,12 @@ extern crate pod;
|
|||||||
extern crate blooms_db;
|
extern crate blooms_db;
|
||||||
#[cfg(any(test, feature = "env_logger"))]
|
#[cfg(any(test, feature = "env_logger"))]
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
|
extern crate rustc_hex;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
#[cfg(any(test, feature = "tempdir"))]
|
||||||
|
extern crate tempdir;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate ethabi_contract;
|
extern crate ethabi_contract;
|
||||||
@ -162,7 +158,6 @@ pub mod block;
|
|||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod miner;
|
pub mod miner;
|
||||||
pub mod snapshot;
|
pub mod snapshot;
|
||||||
pub mod verification;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -36,36 +36,30 @@ use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache};
|
|||||||
use miner;
|
use miner;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use types::transaction::{
|
|
||||||
self,
|
|
||||||
Action,
|
|
||||||
UnverifiedTransaction,
|
|
||||||
SignedTransaction,
|
|
||||||
PendingTransaction,
|
|
||||||
};
|
|
||||||
use types::{
|
use types::{
|
||||||
BlockNumber,
|
BlockNumber,
|
||||||
ids::TransactionId,
|
ids::TransactionId,
|
||||||
block::Block,
|
block::Block,
|
||||||
header::Header,
|
header::Header,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
engines::{Seal, SealingState},
|
engines::{Seal, SealingState},
|
||||||
errors::{EthcoreError as Error, ExecutionError},
|
errors::{EthcoreError as Error, ExecutionError},
|
||||||
receipt::RichReceipt,
|
receipt::RichReceipt,
|
||||||
|
transaction::{
|
||||||
|
self,
|
||||||
|
Action,
|
||||||
|
UnverifiedTransaction,
|
||||||
|
SignedTransaction,
|
||||||
|
PendingTransaction,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use using_queue::{UsingQueue, GetAction};
|
use using_queue::{UsingQueue, GetAction};
|
||||||
|
|
||||||
use block::{ClosedBlock, SealedBlock};
|
use block::{ClosedBlock, SealedBlock};
|
||||||
use client::{
|
use client::{BlockProducer, SealedBlockImporter, Client};
|
||||||
BlockProducer, SealedBlockImporter, ClientIoMessage,
|
use client_traits::{BlockChain, ChainInfo, Nonce, TransactionInfo};
|
||||||
};
|
use engine::{Engine, signer::EngineSigner};
|
||||||
use client_traits::{
|
|
||||||
BlockChain, ChainInfo, Nonce, TransactionInfo,
|
|
||||||
};
|
|
||||||
use engine::{
|
|
||||||
Engine,
|
|
||||||
signer::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;
|
||||||
@ -262,7 +256,7 @@ pub struct Miner {
|
|||||||
transaction_queue: Arc<TransactionQueue>,
|
transaction_queue: Arc<TransactionQueue>,
|
||||||
engine: Arc<dyn Engine>,
|
engine: Arc<dyn Engine>,
|
||||||
accounts: Arc<dyn LocalAccounts>,
|
accounts: Arc<dyn LocalAccounts>,
|
||||||
io_channel: RwLock<Option<IoChannel<ClientIoMessage>>>,
|
io_channel: RwLock<Option<IoChannel<ClientIoMessage<Client>>>>,
|
||||||
service_transaction_checker: Option<ServiceTransactionChecker>,
|
service_transaction_checker: Option<ServiceTransactionChecker>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +340,7 @@ impl Miner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets `IoChannel`
|
/// Sets `IoChannel`
|
||||||
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
|
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage<Client>>) {
|
||||||
*self.io_channel.write() = Some(io_channel);
|
*self.io_channel.write() = Some(io_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1426,7 +1420,7 @@ impl miner::MinerService for Miner {
|
|||||||
let accounts = self.accounts.clone();
|
let accounts = self.accounts.clone();
|
||||||
let service_transaction_checker = self.service_transaction_checker.clone();
|
let service_transaction_checker = self.service_transaction_checker.clone();
|
||||||
|
|
||||||
let cull = move |chain: &::client::Client| {
|
let cull = move |chain: &Client| {
|
||||||
let client = PoolClient::new(
|
let client = PoolClient::new(
|
||||||
chain,
|
chain,
|
||||||
&nonce_cache,
|
&nonce_cache,
|
||||||
@ -1437,7 +1431,7 @@ impl miner::MinerService for Miner {
|
|||||||
queue.cull(client);
|
queue.cull(client);
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = channel.send(ClientIoMessage::execute(cull)) {
|
if let Err(e) = channel.send(ClientIoMessage::<Client>::execute(cull)) {
|
||||||
warn!(target: "miner", "Error queueing cull: {:?}", e);
|
warn!(target: "miner", "Error queueing cull: {:?}", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -221,30 +221,30 @@ impl<'a, C: 'a> CachedNonceClient<'a, C> {
|
|||||||
impl<'a, C: 'a> NonceClient for CachedNonceClient<'a, C> where
|
impl<'a, C: 'a> NonceClient for CachedNonceClient<'a, C> where
|
||||||
C: Nonce + Sync,
|
C: Nonce + Sync,
|
||||||
{
|
{
|
||||||
fn account_nonce(&self, address: &Address) -> U256 {
|
fn account_nonce(&self, address: &Address) -> U256 {
|
||||||
if let Some(nonce) = self.cache.nonces.read().get(address) {
|
if let Some(nonce) = self.cache.nonces.read().get(address) {
|
||||||
return *nonce;
|
return *nonce;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't check again if cache has been populated.
|
// We don't check again if cache has been populated.
|
||||||
// It's not THAT expensive to fetch the nonce from state.
|
// It's not THAT expensive to fetch the nonce from state.
|
||||||
let mut cache = self.cache.nonces.write();
|
let mut cache = self.cache.nonces.write();
|
||||||
let nonce = self.client.latest_nonce(address);
|
let nonce = self.client.latest_nonce(address);
|
||||||
cache.insert(*address, nonce);
|
cache.insert(*address, nonce);
|
||||||
|
|
||||||
if cache.len() < self.cache.limit {
|
if cache.len() < self.cache.limit {
|
||||||
return nonce
|
return nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(target: "txpool", "NonceCache: reached limit.");
|
debug!(target: "txpool", "NonceCache: reached limit.");
|
||||||
trace_time!("nonce_cache:clear");
|
trace_time!("nonce_cache:clear");
|
||||||
|
|
||||||
// Remove excessive amount of entries from the cache
|
// Remove excessive amount of entries from the cache
|
||||||
let to_remove: Vec<_> = cache.keys().take(self.cache.limit / 2).cloned().collect();
|
let to_remove: Vec<_> = cache.keys().take(self.cache.limit / 2).cloned().collect();
|
||||||
for x in to_remove {
|
for x in to_remove {
|
||||||
cache.remove(&x);
|
cache.remove(&x);
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce
|
nonce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ use std::fs::{self, File};
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use client_traits::SnapshotWriter;
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use rlp::{RlpStream, Rlp};
|
use rlp::{RlpStream, Rlp};
|
||||||
use types::{
|
use types::{
|
||||||
@ -35,20 +36,6 @@ use types::{
|
|||||||
|
|
||||||
const SNAPSHOT_VERSION: u64 = 2;
|
const SNAPSHOT_VERSION: u64 = 2;
|
||||||
|
|
||||||
/// Something which can write snapshots.
|
|
||||||
/// Writing the same chunk multiple times will lead to implementation-defined
|
|
||||||
/// behavior, and is not advised.
|
|
||||||
pub trait SnapshotWriter {
|
|
||||||
/// Write a compressed state chunk.
|
|
||||||
fn write_state_chunk(&mut self, hash: H256, chunk: &[u8]) -> io::Result<()>;
|
|
||||||
|
|
||||||
/// Write a compressed block chunk.
|
|
||||||
fn write_block_chunk(&mut self, hash: H256, chunk: &[u8]) -> io::Result<()>;
|
|
||||||
|
|
||||||
/// Complete writing. The manifest's chunk lists must be consistent
|
|
||||||
/// with the chunks written.
|
|
||||||
fn finish(self, manifest: ManifestData) -> io::Result<()> where Self: Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (hash, len, offset)
|
// (hash, len, offset)
|
||||||
#[derive(RlpEncodable, RlpDecodable)]
|
#[derive(RlpEncodable, RlpDecodable)]
|
||||||
|
@ -48,7 +48,8 @@ use bloom_journal::Bloom;
|
|||||||
use num_cpus;
|
use num_cpus;
|
||||||
use types::snapshot::ManifestData;
|
use types::snapshot::ManifestData;
|
||||||
|
|
||||||
use self::io::SnapshotWriter;
|
// todo[dvdplm] put back in snapshots once it's extracted
|
||||||
|
use client_traits::SnapshotWriter;
|
||||||
|
|
||||||
use super::state_db::StateDB;
|
use super::state_db::StateDB;
|
||||||
use account_state::Account as StateAccount;
|
use account_state::Account as StateAccount;
|
||||||
@ -58,7 +59,7 @@ use crossbeam_utils::thread;
|
|||||||
use rand::{Rng, rngs::OsRng};
|
use rand::{Rng, rngs::OsRng};
|
||||||
|
|
||||||
pub use self::consensus::*;
|
pub use self::consensus::*;
|
||||||
pub use self::service::{SnapshotClient, Service, DatabaseRestore};
|
pub use self::service::Service;
|
||||||
pub use self::traits::{SnapshotService, SnapshotComponents, Rebuilder};
|
pub use self::traits::{SnapshotService, SnapshotComponents, Rebuilder};
|
||||||
pub use self::watcher::Watcher;
|
pub use self::watcher::Watcher;
|
||||||
pub use types::basic_account::BasicAccount;
|
pub use types::basic_account::BasicAccount;
|
||||||
|
@ -29,16 +29,21 @@ use super::{
|
|||||||
SnapshotService,
|
SnapshotService,
|
||||||
Rebuilder,
|
Rebuilder,
|
||||||
MAX_CHUNK_SIZE,
|
MAX_CHUNK_SIZE,
|
||||||
io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter},
|
io::{SnapshotReader, LooseReader, LooseWriter},
|
||||||
chunker,
|
chunker,
|
||||||
};
|
};
|
||||||
|
|
||||||
use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler};
|
use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler};
|
||||||
use client::{Client, ClientIoMessage};
|
use client::Client;
|
||||||
use client_traits::{BlockInfo, BlockChainClient, ChainInfo};
|
// todo[dvdplm] put SnapshotWriter back in snapshots once extracted
|
||||||
|
use client_traits::{
|
||||||
|
BlockInfo, BlockChainClient, ChainInfo,
|
||||||
|
SnapshotClient, SnapshotWriter, DatabaseRestore,
|
||||||
|
};
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use types::{
|
use types::{
|
||||||
|
io_message::ClientIoMessage,
|
||||||
errors::{EthcoreError as Error, SnapshotError, SnapshotError::UnlinkedAncientBlockChain},
|
errors::{EthcoreError as Error, SnapshotError, SnapshotError::UnlinkedAncientBlockChain},
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
snapshot::{ManifestData, Progress, RestorationStatus},
|
snapshot::{ManifestData, Progress, RestorationStatus},
|
||||||
@ -73,12 +78,6 @@ impl Drop for Guard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// External database restoration handler
|
|
||||||
pub trait DatabaseRestore: Send + Sync {
|
|
||||||
/// Restart with a new backend. Takes ownership of passed database and moves it to a new location.
|
|
||||||
fn restore_db(&self, new_db: &str) -> Result<(), Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// State restoration manager.
|
/// State restoration manager.
|
||||||
struct Restoration {
|
struct Restoration {
|
||||||
manifest: ManifestData,
|
manifest: ManifestData,
|
||||||
@ -213,10 +212,7 @@ impl Restoration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Type alias for client io channel.
|
/// Type alias for client io channel.
|
||||||
pub type Channel = IoChannel<ClientIoMessage>;
|
pub type Channel = IoChannel<ClientIoMessage<Client>>;
|
||||||
|
|
||||||
/// Trait alias for the Client Service used
|
|
||||||
pub trait SnapshotClient: BlockChainClient + BlockInfo + DatabaseRestore {}
|
|
||||||
|
|
||||||
/// Snapshot service parameters.
|
/// Snapshot service parameters.
|
||||||
pub struct ServiceParams {
|
pub struct ServiceParams {
|
||||||
@ -234,7 +230,7 @@ pub struct ServiceParams {
|
|||||||
/// Usually "<chain hash>/snapshot"
|
/// Usually "<chain hash>/snapshot"
|
||||||
pub snapshot_root: PathBuf,
|
pub snapshot_root: PathBuf,
|
||||||
/// A handle for database restoration.
|
/// A handle for database restoration.
|
||||||
pub client: Arc<dyn SnapshotClient>,
|
pub client: Arc<Client>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `SnapshotService` implementation.
|
/// `SnapshotService` implementation.
|
||||||
@ -251,7 +247,7 @@ pub struct Service {
|
|||||||
genesis_block: Bytes,
|
genesis_block: Bytes,
|
||||||
state_chunks: AtomicUsize,
|
state_chunks: AtomicUsize,
|
||||||
block_chunks: AtomicUsize,
|
block_chunks: AtomicUsize,
|
||||||
client: Arc<dyn SnapshotClient>,
|
client: Arc<Client>,
|
||||||
progress: Progress,
|
progress: Progress,
|
||||||
taking_snapshot: AtomicBool,
|
taking_snapshot: AtomicBool,
|
||||||
restoring_snapshot: AtomicBool,
|
restoring_snapshot: AtomicBool,
|
||||||
@ -483,7 +479,10 @@ impl Service {
|
|||||||
/// calling this while a restoration is in progress or vice versa
|
/// calling this while a restoration is in progress or vice versa
|
||||||
/// will lead to a race condition where the first one to finish will
|
/// will lead to a race condition where the first one to finish will
|
||||||
/// have their produced snapshot overwritten.
|
/// have their produced snapshot overwritten.
|
||||||
pub fn take_snapshot(&self, client: &Client, num: u64) -> Result<(), Error> {
|
pub fn take_snapshot<C>(&self, client: &C, num: u64) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
C: ChainInfo + SnapshotClient
|
||||||
|
{
|
||||||
if self.taking_snapshot.compare_and_swap(false, true, Ordering::SeqCst) {
|
if self.taking_snapshot.compare_and_swap(false, true, Ordering::SeqCst) {
|
||||||
info!("Skipping snapshot at #{} as another one is currently in-progress.", num);
|
info!("Skipping snapshot at #{} as another one is currently in-progress.", num);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -905,13 +904,16 @@ impl Drop for Service {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use client::ClientIoMessage;
|
use client::Client;
|
||||||
use io::{IoService};
|
use io::{IoService};
|
||||||
use spec;
|
use spec;
|
||||||
use journaldb::Algorithm;
|
use journaldb::Algorithm;
|
||||||
use snapshot::SnapshotService;
|
use snapshot::SnapshotService;
|
||||||
use super::*;
|
use super::*;
|
||||||
use types::snapshot::{ManifestData, RestorationStatus};
|
use types::{
|
||||||
|
io_message::ClientIoMessage,
|
||||||
|
snapshot::{ManifestData, RestorationStatus}
|
||||||
|
};
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use test_helpers::{generate_dummy_client_with_spec_and_data, restoration_db_handler};
|
use test_helpers::{generate_dummy_client_with_spec_and_data, restoration_db_handler};
|
||||||
|
|
||||||
@ -919,7 +921,7 @@ mod tests {
|
|||||||
fn sends_async_messages() {
|
fn sends_async_messages() {
|
||||||
let gas_prices = vec![1.into(), 2.into(), 3.into(), 999.into()];
|
let gas_prices = vec![1.into(), 2.into(), 3.into(), 999.into()];
|
||||||
let client = generate_dummy_client_with_spec_and_data(spec::new_null, 400, 5, &gas_prices);
|
let client = generate_dummy_client_with_spec_and_data(spec::new_null, 400, 5, &gas_prices);
|
||||||
let service = IoService::<ClientIoMessage>::start().unwrap();
|
let service = IoService::<ClientIoMessage<Client>>::start().unwrap();
|
||||||
let spec = spec::new_test();
|
let spec = spec::new_test();
|
||||||
|
|
||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
@ -932,7 +934,7 @@ mod tests {
|
|||||||
pruning: Algorithm::Archive,
|
pruning: Algorithm::Archive,
|
||||||
channel: service.channel(),
|
channel: service.channel(),
|
||||||
snapshot_root: dir,
|
snapshot_root: dir,
|
||||||
client: client,
|
client,
|
||||||
};
|
};
|
||||||
|
|
||||||
let service = Service::new(snapshot_params).unwrap();
|
let service = Service::new(snapshot_params).unwrap();
|
||||||
|
@ -26,7 +26,7 @@ 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;
|
use client::Client;
|
||||||
use client_traits::ChainInfo;
|
use client_traits::{ChainInfo, SnapshotClient};
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use snapshot::{StateRebuilder};
|
use snapshot::{StateRebuilder};
|
||||||
use snapshot::io::{SnapshotReader, PackedWriter, PackedReader};
|
use snapshot::io::{SnapshotReader, PackedWriter, PackedReader};
|
||||||
|
@ -26,8 +26,9 @@ use types::{
|
|||||||
|
|
||||||
use blockchain::generator::{BlockGenerator, BlockBuilder};
|
use blockchain::generator::{BlockGenerator, BlockBuilder};
|
||||||
use blockchain::{BlockChain, ExtrasInsert};
|
use blockchain::{BlockChain, ExtrasInsert};
|
||||||
|
use client_traits::SnapshotWriter;
|
||||||
use snapshot::{chunk_secondary, Error as SnapshotError, SnapshotComponents};
|
use snapshot::{chunk_secondary, Error as SnapshotError, SnapshotComponents};
|
||||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader};
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use snappy;
|
use snappy;
|
||||||
|
@ -22,14 +22,14 @@ use std::sync::Arc;
|
|||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use blockchain::BlockProvider;
|
use blockchain::BlockProvider;
|
||||||
use client::{Client, ClientConfig};
|
use client::{Client, ClientConfig};
|
||||||
use client_traits::{BlockInfo, ImportBlock};
|
use client_traits::{BlockInfo, ImportBlock, SnapshotWriter};
|
||||||
use types::{
|
use types::{
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
snapshot::Progress,
|
snapshot::Progress,
|
||||||
verification::Unverified,
|
verification::Unverified,
|
||||||
snapshot::{ManifestData, RestorationStatus},
|
snapshot::{ManifestData, RestorationStatus},
|
||||||
};
|
};
|
||||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader};
|
||||||
use snapshot::service::{Service, ServiceParams};
|
use snapshot::service::{Service, ServiceParams};
|
||||||
use snapshot::{chunk_state, chunk_secondary, SnapshotService};
|
use snapshot::{chunk_state, chunk_secondary, SnapshotService};
|
||||||
use spec;
|
use spec;
|
||||||
@ -77,7 +77,7 @@ fn restored_is_equivalent() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let service = Service::new(service_params).unwrap();
|
let service = Service::new(service_params).unwrap();
|
||||||
service.take_snapshot(&client, NUM_BLOCKS as u64).unwrap();
|
service.take_snapshot(&*client, NUM_BLOCKS as u64).unwrap();
|
||||||
|
|
||||||
let manifest = service.manifest().unwrap();
|
let manifest = service.manifest().unwrap();
|
||||||
|
|
||||||
@ -226,7 +226,6 @@ fn keep_ancient_blocks() {
|
|||||||
client2.import_block(Unverified::from_rlp(block.into_inner()).unwrap()).unwrap();
|
client2.import_block(Unverified::from_rlp(block.into_inner()).unwrap()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
client2.import_verified_blocks();
|
|
||||||
client2.flush_queue();
|
client2.flush_queue();
|
||||||
|
|
||||||
// Restore the Snapshot
|
// Restore the Snapshot
|
||||||
@ -304,7 +303,7 @@ fn recover_aborted_recovery() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let service = Service::new(service_params).unwrap();
|
let service = Service::new(service_params).unwrap();
|
||||||
service.take_snapshot(&client, NUM_BLOCKS as u64).unwrap();
|
service.take_snapshot(&*client, NUM_BLOCKS as u64).unwrap();
|
||||||
|
|
||||||
let manifest = service.manifest().unwrap();
|
let manifest = service.manifest().unwrap();
|
||||||
service.init_restore(manifest.clone(), true).unwrap();
|
service.init_restore(manifest.clone(), true).unwrap();
|
||||||
|
@ -24,9 +24,10 @@ use types::{
|
|||||||
basic_account::BasicAccount,
|
basic_account::BasicAccount,
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
};
|
};
|
||||||
|
use client_traits::SnapshotWriter;
|
||||||
use snapshot::account;
|
use snapshot::account;
|
||||||
use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder, SNAPSHOT_SUBPARTS};
|
use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder, SNAPSHOT_SUBPARTS};
|
||||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader};
|
||||||
use super::helpers::StateProducer;
|
use super::helpers::StateProducer;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
|
@ -17,9 +17,12 @@
|
|||||||
//! Watcher for snapshot-related chain events.
|
//! Watcher for snapshot-related chain events.
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use client::{Client, ChainNotify, NewBlocks, ClientIoMessage};
|
use client::{Client, ChainNotify, NewBlocks};
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use types::ids::BlockId;
|
use types::{
|
||||||
|
ids::BlockId,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
|
};
|
||||||
|
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
@ -55,7 +58,7 @@ trait Broadcast: Send + Sync {
|
|||||||
fn take_at(&self, num: Option<u64>);
|
fn take_at(&self, num: Option<u64>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Broadcast for Mutex<IoChannel<ClientIoMessage>> {
|
impl Broadcast for Mutex<IoChannel<ClientIoMessage<Client>>> {
|
||||||
fn take_at(&self, num: Option<u64>) {
|
fn take_at(&self, num: Option<u64>) {
|
||||||
let num = match num {
|
let num = match num {
|
||||||
Some(n) => n,
|
Some(n) => n,
|
||||||
@ -83,7 +86,7 @@ impl Watcher {
|
|||||||
/// Create a new `Watcher` which will trigger a snapshot event
|
/// Create a new `Watcher` which will trigger a snapshot event
|
||||||
/// once every `period` blocks, but only after that block is
|
/// once every `period` blocks, but only after that block is
|
||||||
/// `history` blocks old.
|
/// `history` blocks old.
|
||||||
pub fn new<F>(client: Arc<Client>, sync_status: F, channel: IoChannel<ClientIoMessage>, period: u64, history: u64) -> Self
|
pub fn new<F>(client: Arc<Client>, sync_status: F, channel: IoChannel<ClientIoMessage<Client>>, period: u64, history: u64) -> Self
|
||||||
where F: 'static + Send + Sync + Fn() -> bool
|
where F: 'static + Send + Sync + Fn() -> bool
|
||||||
{
|
{
|
||||||
Watcher {
|
Watcher {
|
||||||
|
@ -186,7 +186,6 @@ pub fn generate_dummy_client_with_spec_and_data<F>(test_spec: F, block_number: u
|
|||||||
db = b.drain().state.drop().1;
|
db = b.drain().state.drop().1;
|
||||||
}
|
}
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
client.import_verified_blocks();
|
|
||||||
client
|
client
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +238,6 @@ pub fn push_block_with_transactions(client: &Arc<Client>, transactions: &[Signed
|
|||||||
}
|
}
|
||||||
|
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
client.import_verified_blocks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates dummy client (not test client) with corresponding blocks
|
/// Creates dummy client (not test client) with corresponding blocks
|
||||||
@ -261,7 +259,6 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> Arc<Client> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
client.import_verified_blocks();
|
|
||||||
client
|
client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,10 @@ use types::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use client::{Client, ClientConfig, PrepareOpenBlock, ImportSealedBlock};
|
use client::{Client, ClientConfig, PrepareOpenBlock, ImportSealedBlock};
|
||||||
use client_traits::{BlockInfo, BlockChainClient, BlockChainReset, ChainInfo, ImportBlock};
|
use client_traits::{
|
||||||
|
BlockInfo, BlockChainClient, BlockChainReset, ChainInfo,
|
||||||
|
ImportBlock, Tick,
|
||||||
|
};
|
||||||
use spec;
|
use spec;
|
||||||
use machine::executive::{Executive, TransactOptions};
|
use machine::executive::{Executive, TransactOptions};
|
||||||
use miner::{Miner, PendingOrdering, MinerService};
|
use miner::{Miner, PendingOrdering, MinerService};
|
||||||
@ -55,7 +58,6 @@ fn imports_from_empty() {
|
|||||||
Arc::new(Miner::new_for_tests(&spec, None)),
|
Arc::new(Miner::new_for_tests(&spec, None)),
|
||||||
IoChannel::disconnected(),
|
IoChannel::disconnected(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
client.import_verified_blocks();
|
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +104,6 @@ fn imports_good_block() {
|
|||||||
panic!("error importing block being good by definition");
|
panic!("error importing block being good by definition");
|
||||||
}
|
}
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
client.import_verified_blocks();
|
|
||||||
|
|
||||||
let block = client.block_header(BlockId::Number(1)).unwrap();
|
let block = client.block_header(BlockId::Number(1)).unwrap();
|
||||||
assert!(!block.into_inner().is_empty());
|
assert!(!block.into_inner().is_empty());
|
||||||
|
@ -181,7 +181,6 @@ fn can_trace_block_and_uncle_reward() {
|
|||||||
|
|
||||||
block.drain();
|
block.drain();
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
client.import_verified_blocks();
|
|
||||||
|
|
||||||
// Test0. Check overall filter
|
// Test0. Check overall filter
|
||||||
let filter = TraceFilter {
|
let filter = TraceFilter {
|
||||||
|
@ -20,11 +20,14 @@ use ethereum_types::{U256, Address};
|
|||||||
use io::{IoHandler, IoChannel};
|
use io::{IoHandler, IoChannel};
|
||||||
use client_traits::ChainInfo;
|
use client_traits::ChainInfo;
|
||||||
use engine::signer;
|
use engine::signer;
|
||||||
use ethcore::client::{ClientIoMessage};
|
|
||||||
use spec;
|
use spec;
|
||||||
|
use ethcore::client::Client;
|
||||||
use ethcore::miner::{self, MinerService};
|
use ethcore::miner::{self, MinerService};
|
||||||
use ethkey::{KeyPair, Secret};
|
use ethkey::{KeyPair, Secret};
|
||||||
use types::transaction::{Action, PendingTransaction, Transaction};
|
use types::{
|
||||||
|
io_message::ClientIoMessage,
|
||||||
|
transaction::{Action, PendingTransaction, Transaction}
|
||||||
|
};
|
||||||
use super::helpers::*;
|
use super::helpers::*;
|
||||||
use SyncConfig;
|
use SyncConfig;
|
||||||
|
|
||||||
@ -47,8 +50,8 @@ fn authority_round() {
|
|||||||
|
|
||||||
let chain_id = spec::new_test_round().chain_id();
|
let chain_id = spec::new_test_round().chain_id();
|
||||||
let mut net = TestNet::with_spec(2, SyncConfig::default(), spec::new_test_round);
|
let mut net = TestNet::with_spec(2, SyncConfig::default(), spec::new_test_round);
|
||||||
let io_handler0: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
let io_handler0: Arc<dyn IoHandler<ClientIoMessage<Client>>> = 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<Client>>> = 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(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(signer::from_keypair(s1.clone())));
|
net.peer(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone())));
|
||||||
@ -115,7 +118,7 @@ fn authority_round() {
|
|||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 5);
|
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 5);
|
||||||
// Reorg to the longest chain one not ealier view one.
|
// Reorg to the longest chain one not earlier view one.
|
||||||
net.sync();
|
net.sync();
|
||||||
let ci0 = net.peer(0).chain.chain_info();
|
let ci0 = net.peer(0).chain.chain_info();
|
||||||
let ci1 = net.peer(1).chain.chain_info();
|
let ci1 = net.peer(1).chain.chain_info();
|
||||||
|
@ -22,9 +22,10 @@ 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 types::io_message::ClientIoMessage;
|
||||||
use client_traits::BlockChainClient;
|
use client_traits::BlockChainClient;
|
||||||
use ethcore::client::{TestBlockChainClient, Client as EthcoreClient,
|
use ethcore::client::{TestBlockChainClient, Client as EthcoreClient,
|
||||||
ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage};
|
ClientConfig, ChainNotify, NewBlocks, ChainMessageType};
|
||||||
use ethcore::snapshot::SnapshotService;
|
use ethcore::snapshot::SnapshotService;
|
||||||
use spec::{self, Spec};
|
use spec::{self, Spec};
|
||||||
use ethcore_private_tx::PrivateStateDB;
|
use ethcore_private_tx::PrivateStateDB;
|
||||||
@ -554,8 +555,8 @@ impl TestIoHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IoHandler<ClientIoMessage> for TestIoHandler {
|
impl IoHandler<ClientIoMessage<EthcoreClient>> for TestIoHandler {
|
||||||
fn message(&self, _io: &IoContext<ClientIoMessage>, net_message: &ClientIoMessage) {
|
fn message(&self, _io: &IoContext<ClientIoMessage<EthcoreClient>>, net_message: &ClientIoMessage<EthcoreClient>) {
|
||||||
match *net_message {
|
match *net_message {
|
||||||
ClientIoMessage::Execute(ref exec) => {
|
ClientIoMessage::Execute(ref exec) => {
|
||||||
*self.private_tx_queued.lock() += 1;
|
*self.private_tx_queued.lock() += 1;
|
||||||
|
@ -18,12 +18,15 @@ use std::sync::Arc;
|
|||||||
use hash::keccak;
|
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,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
|
};
|
||||||
use client_traits::BlockChainClient;
|
use client_traits::BlockChainClient;
|
||||||
use engine::signer;
|
use engine::signer;
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
|
client::Client,
|
||||||
CreateContractAddress,
|
CreateContractAddress,
|
||||||
client::ClientIoMessage,
|
|
||||||
miner::{self, MinerService},
|
miner::{self, MinerService},
|
||||||
test_helpers::{push_block_with_transactions, new_db},
|
test_helpers::{push_block_with_transactions, new_db},
|
||||||
};
|
};
|
||||||
@ -52,8 +55,8 @@ fn send_private_transaction() {
|
|||||||
let mut net = TestNet::with_spec(2, SyncConfig::default(), seal_spec);
|
let mut net = TestNet::with_spec(2, SyncConfig::default(), seal_spec);
|
||||||
let client0 = net.peer(0).chain.clone();
|
let client0 = net.peer(0).chain.clone();
|
||||||
let client1 = net.peer(1).chain.clone();
|
let client1 = net.peer(1).chain.clone();
|
||||||
let io_handler0: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
let io_handler0: Arc<dyn IoHandler<ClientIoMessage<Client>>> = 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<Client>>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
||||||
|
|
||||||
net.peer(0).miner.set_author(miner::Author::Sealer(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(signer::from_keypair(s1.clone())));
|
net.peer(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone())));
|
||||||
@ -65,7 +68,7 @@ fn send_private_transaction() {
|
|||||||
let (address, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &s0.address(), &0.into(), &[]);
|
let (address, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &s0.address(), &0.into(), &[]);
|
||||||
let chain_id = client0.signing_chain_id();
|
let chain_id = client0.signing_chain_id();
|
||||||
|
|
||||||
// Exhange statuses
|
// Exchange statuses
|
||||||
net.sync();
|
net.sync();
|
||||||
|
|
||||||
// Setup private providers
|
// Setup private providers
|
||||||
@ -173,8 +176,8 @@ fn sync_private_state() {
|
|||||||
let mut net = TestNet::with_spec(2, SyncConfig::default(), seal_spec);
|
let mut net = TestNet::with_spec(2, SyncConfig::default(), seal_spec);
|
||||||
let client0 = net.peer(0).chain.clone();
|
let client0 = net.peer(0).chain.clone();
|
||||||
let client1 = net.peer(1).chain.clone();
|
let client1 = net.peer(1).chain.clone();
|
||||||
let io_handler0: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
let io_handler0: Arc<IoHandler<ClientIoMessage<Client>>> = Arc::new(TestIoHandler::new(net.peer(0).chain.clone()));
|
||||||
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
let io_handler1: Arc<IoHandler<ClientIoMessage<Client>>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
|
||||||
|
|
||||||
net.peer(0).miner.set_author(miner::Author::Sealer(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(signer::from_keypair(s1.clone())));
|
net.peer(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone())));
|
||||||
|
@ -18,8 +18,12 @@
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Display, Formatter, Error as FmtError},
|
fmt::{Display, Formatter, Error as FmtError},
|
||||||
|
ops,
|
||||||
|
cmp,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
use ethereum_types::U256;
|
||||||
|
use crate::header::Header;
|
||||||
|
|
||||||
/// Operating mode for the client.
|
/// Operating mode for the client.
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
@ -47,3 +51,41 @@ impl Display for Mode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Report on the status of a client.
|
||||||
|
#[derive(Default, Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct ClientReport {
|
||||||
|
/// How many blocks have been imported so far.
|
||||||
|
pub blocks_imported: usize,
|
||||||
|
/// How many transactions have been applied so far.
|
||||||
|
pub transactions_applied: usize,
|
||||||
|
/// How much gas has been processed so far.
|
||||||
|
pub gas_processed: U256,
|
||||||
|
/// Memory used by state DB
|
||||||
|
pub state_db_mem: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientReport {
|
||||||
|
/// Alter internal reporting to reflect the additional `block` has been processed.
|
||||||
|
pub fn accrue_block(&mut self, header: &Header, transactions: usize) {
|
||||||
|
self.blocks_imported += 1;
|
||||||
|
self.transactions_applied += transactions;
|
||||||
|
self.gas_processed = self.gas_processed + *header.gas_used();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ops::Sub<&'a ClientReport> for ClientReport {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn sub(mut self, other: &'a ClientReport) -> Self {
|
||||||
|
let higher_mem = cmp::max(self.state_db_mem, other.state_db_mem);
|
||||||
|
let lower_mem = cmp::min(self.state_db_mem, other.state_db_mem);
|
||||||
|
|
||||||
|
self.blocks_imported -= other.blocks_imported;
|
||||||
|
self.transactions_applied -= other.transactions_applied;
|
||||||
|
self.gas_processed = self.gas_processed - other.gas_processed;
|
||||||
|
self.state_db_mem = higher_mem - lower_mem;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -14,15 +14,17 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
|
//! Defines the `ClientIoMessage` type, used pervasively throughout various parts of the project to
|
||||||
|
//! communicate between each other.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use client::Client;
|
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use types::snapshot::ManifestData;
|
use crate::snapshot::ManifestData;
|
||||||
|
|
||||||
/// Message type for external and internal events
|
/// Message type for external and internal events
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ClientIoMessage {
|
pub enum ClientIoMessage<C> {
|
||||||
/// Best Block Hash in chain has been changed
|
/// Best Block Hash in chain has been changed
|
||||||
NewChainHead,
|
NewChainHead,
|
||||||
/// A block is ready
|
/// A block is ready
|
||||||
@ -36,20 +38,20 @@ pub enum ClientIoMessage {
|
|||||||
/// Take a snapshot for the block with given number.
|
/// Take a snapshot for the block with given number.
|
||||||
TakeSnapshot(u64),
|
TakeSnapshot(u64),
|
||||||
/// Execute wrapped closure
|
/// Execute wrapped closure
|
||||||
Execute(Callback),
|
Execute(Callback<C>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientIoMessage {
|
impl<C> ClientIoMessage<C> {
|
||||||
/// Create new `ClientIoMessage` that executes given procedure.
|
/// Create new `ClientIoMessage` that executes given procedure.
|
||||||
pub fn execute<F: Fn(&Client) + Send + Sync + 'static>(fun: F) -> Self {
|
pub fn execute<F: Fn(&C) + Send + Sync + 'static>(fun: F) -> Self {
|
||||||
ClientIoMessage::Execute(Callback(Box::new(fun)))
|
ClientIoMessage::Execute(Callback(Box::new(fun)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A function to invoke in the client thread.
|
/// A function to invoke in the client thread.
|
||||||
pub struct Callback(pub Box<dyn Fn(&Client) + Send + Sync>);
|
pub struct Callback<C>(pub Box<dyn Fn(&C) + Send + Sync>);
|
||||||
|
|
||||||
impl fmt::Debug for Callback {
|
impl<C> fmt::Debug for Callback<C> {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(fmt, "<callback>")
|
write!(fmt, "<callback>")
|
||||||
}
|
}
|
@ -71,6 +71,7 @@ pub mod errors;
|
|||||||
pub mod filter;
|
pub mod filter;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
pub mod ids;
|
pub mod ids;
|
||||||
|
pub mod io_message;
|
||||||
pub mod log_entry;
|
pub mod log_entry;
|
||||||
pub mod pruning_info;
|
pub mod pruning_info;
|
||||||
pub mod receipt;
|
pub mod receipt;
|
||||||
|
34
ethcore/verification/Cargo.toml
Normal file
34
ethcore/verification/Cargo.toml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[package]
|
||||||
|
description = "Block verification utilities."
|
||||||
|
name = "verification"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
blockchain = { package = "ethcore-blockchain", path = "../blockchain" }
|
||||||
|
call-contract = { package = "ethcore-call-contract", path = "../call-contract" }
|
||||||
|
client-traits = { path = "../client-traits" }
|
||||||
|
common-types = { path = "../types" }
|
||||||
|
engine = { path = "../engine" }
|
||||||
|
ethcore-io = { path = "../../util/io" }
|
||||||
|
ethereum-types = "0.6.0"
|
||||||
|
keccak-hash = "0.2.0"
|
||||||
|
len-caching-lock = { path = "../../util/len-caching-lock" }
|
||||||
|
log = "0.4"
|
||||||
|
num_cpus = "1.2"
|
||||||
|
parity-bytes = "0.1.0"
|
||||||
|
parity-util-mem = "0.2.0"
|
||||||
|
parking_lot = "0.8.0"
|
||||||
|
rlp = "0.4.2"
|
||||||
|
time-utils = { path = "../../util/time-utils" }
|
||||||
|
triehash = { package = "triehash-ethereum", version = "0.2", path = "../../util/triehash-ethereum" }
|
||||||
|
unexpected = { path = "../../util/unexpected" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
ethcore = { path = "../", features = ["test-helpers"] }
|
||||||
|
ethkey = { path = "../../accounts/ethkey" }
|
||||||
|
machine = { path = "../machine" }
|
||||||
|
null-engine = { path = "../engines/null-engine" }
|
||||||
|
spec = { path = "../spec" }
|
@ -19,7 +19,7 @@
|
|||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use common_types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
};
|
};
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
|
// The MallocSizeOf derive looks for this in the root
|
||||||
|
use parity_util_mem as malloc_size_of;
|
||||||
|
|
||||||
mod verification;
|
mod verification;
|
||||||
mod verifier;
|
mod verifier;
|
||||||
@ -29,11 +31,6 @@ pub use self::verification::FullFamilyParams;
|
|||||||
pub use self::verifier::Verifier;
|
pub use self::verifier::Verifier;
|
||||||
pub use self::queue::{BlockQueue, Config as QueueConfig};
|
pub use self::queue::{BlockQueue, Config as QueueConfig};
|
||||||
|
|
||||||
use self::verification::{
|
|
||||||
verify_block_basic,
|
|
||||||
verify_block_unordered,
|
|
||||||
verify_header_params,
|
|
||||||
};
|
|
||||||
use self::canon_verifier::CanonVerifier;
|
use self::canon_verifier::CanonVerifier;
|
||||||
use self::noop_verifier::NoopVerifier;
|
use self::noop_verifier::NoopVerifier;
|
||||||
|
|
@ -18,11 +18,11 @@
|
|||||||
|
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engine::Engine;
|
use common_types::{
|
||||||
use types::{
|
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error
|
errors::EthcoreError as Error
|
||||||
};
|
};
|
||||||
|
use engine::Engine;
|
||||||
use super::{verification, Verifier};
|
use super::{verification, Verifier};
|
||||||
|
|
||||||
/// A no-op verifier -- this will verify everything it's given immediately.
|
/// A no-op verifier -- this will verify everything it's given immediately.
|
@ -21,7 +21,7 @@ use engine::Engine;
|
|||||||
use parity_util_mem::MallocSizeOf;
|
use parity_util_mem::MallocSizeOf;
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
|
|
||||||
use types::errors::EthcoreError as Error;
|
use common_types::errors::EthcoreError as Error;
|
||||||
|
|
||||||
pub use self::blocks::Blocks;
|
pub use self::blocks::Blocks;
|
||||||
pub use self::headers::Headers;
|
pub use self::headers::Headers;
|
||||||
@ -70,12 +70,13 @@ pub mod blocks {
|
|||||||
use super::{Kind, BlockLike};
|
use super::{Kind, BlockLike};
|
||||||
|
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use common_types::{
|
||||||
block::PreverifiedBlock,
|
block::PreverifiedBlock,
|
||||||
errors::{EthcoreError as Error, BlockError},
|
errors::{EthcoreError as Error, BlockError},
|
||||||
verification::Unverified,
|
verification::Unverified,
|
||||||
};
|
};
|
||||||
use verification::{verify_block_basic, verify_block_unordered};
|
use log::{debug, warn};
|
||||||
|
use crate::verification::{verify_block_basic, verify_block_unordered};
|
||||||
|
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
|
|
||||||
@ -147,11 +148,11 @@ pub mod headers {
|
|||||||
use super::{Kind, BlockLike};
|
use super::{Kind, BlockLike};
|
||||||
|
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use common_types::{
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
};
|
};
|
||||||
use verification::verify_header_params;
|
use crate::verification::verify_header_params;
|
||||||
|
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
|
|
@ -22,17 +22,19 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::{VecDeque, HashSet, HashMap};
|
use std::collections::{VecDeque, HashSet, HashMap};
|
||||||
use parity_util_mem::{MallocSizeOf, MallocSizeOfExt};
|
use common_types::{
|
||||||
use ethereum_types::{H256, U256};
|
block_status::BlockStatus,
|
||||||
use parking_lot::{Condvar, Mutex, RwLock};
|
io_message::ClientIoMessage,
|
||||||
use io::*;
|
|
||||||
use engine::Engine;
|
|
||||||
use client::ClientIoMessage;
|
|
||||||
use len_caching_lock::LenCachingMutex;
|
|
||||||
use types::{
|
|
||||||
errors::{BlockError, EthcoreError as Error, ImportError},
|
errors::{BlockError, EthcoreError as Error, ImportError},
|
||||||
verification::VerificationQueueInfo as QueueInfo,
|
verification::VerificationQueueInfo as QueueInfo,
|
||||||
};
|
};
|
||||||
|
use ethcore_io::*;
|
||||||
|
use ethereum_types::{H256, U256};
|
||||||
|
use engine::Engine;
|
||||||
|
use len_caching_lock::LenCachingMutex;
|
||||||
|
use log::{debug, trace};
|
||||||
|
use parity_util_mem::{MallocSizeOf, MallocSizeOfExt};
|
||||||
|
use parking_lot::{Condvar, Mutex, RwLock};
|
||||||
|
|
||||||
use self::kind::{BlockLike, Kind};
|
use self::kind::{BlockLike, Kind};
|
||||||
|
|
||||||
@ -42,10 +44,10 @@ const MIN_MEM_LIMIT: usize = 16384;
|
|||||||
const MIN_QUEUE_LIMIT: usize = 512;
|
const MIN_QUEUE_LIMIT: usize = 512;
|
||||||
|
|
||||||
/// Type alias for block queue convenience.
|
/// Type alias for block queue convenience.
|
||||||
pub type BlockQueue = VerificationQueue<self::kind::Blocks>;
|
pub type BlockQueue<C> = VerificationQueue<self::kind::Blocks, C>;
|
||||||
|
|
||||||
/// Type alias for header queue convenience.
|
/// Type alias for header queue convenience.
|
||||||
pub type HeaderQueue = VerificationQueue<self::kind::Headers>;
|
pub type HeaderQueue<C> = VerificationQueue<self::kind::Headers, C>;
|
||||||
|
|
||||||
/// Verification queue configuration
|
/// Verification queue configuration
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
@ -84,7 +86,7 @@ impl Default for VerifierSettings {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
VerifierSettings {
|
VerifierSettings {
|
||||||
scale_verifiers: false,
|
scale_verifiers: false,
|
||||||
num_verifiers: ::num_cpus::get(),
|
num_verifiers: num_cpus::get(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,9 +115,8 @@ pub enum Status {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<::types::block_status::BlockStatus> for Status {
|
impl Into<BlockStatus> for Status {
|
||||||
fn into(self) -> ::types::block_status::BlockStatus {
|
fn into(self) -> BlockStatus {
|
||||||
use ::types::block_status::BlockStatus;
|
|
||||||
match self {
|
match self {
|
||||||
Status::Queued => BlockStatus::Queued,
|
Status::Queued => BlockStatus::Queued,
|
||||||
Status::Bad => BlockStatus::Bad,
|
Status::Bad => BlockStatus::Bad,
|
||||||
@ -133,12 +134,12 @@ struct Sizes {
|
|||||||
|
|
||||||
/// A queue of items to be verified. Sits between network or other I/O and the `BlockChain`.
|
/// A queue of items to be verified. Sits between network or other I/O and the `BlockChain`.
|
||||||
/// Keeps them in the same order as inserted, minus invalid items.
|
/// Keeps them in the same order as inserted, minus invalid items.
|
||||||
pub struct VerificationQueue<K: Kind> {
|
pub struct VerificationQueue<K: Kind, C: 'static> {
|
||||||
engine: Arc<dyn Engine>,
|
engine: Arc<dyn Engine>,
|
||||||
more_to_verify: Arc<Condvar>,
|
more_to_verify: Arc<Condvar>,
|
||||||
verification: Arc<Verification<K>>,
|
verification: Arc<Verification<K>>,
|
||||||
deleting: Arc<AtomicBool>,
|
deleting: Arc<AtomicBool>,
|
||||||
ready_signal: Arc<QueueSignal>,
|
ready_signal: Arc<QueueSignal<C>>,
|
||||||
empty: Arc<Condvar>,
|
empty: Arc<Condvar>,
|
||||||
processing: RwLock<HashMap<H256, U256>>, // hash to difficulty
|
processing: RwLock<HashMap<H256, U256>>, // hash to difficulty
|
||||||
ticks_since_adjustment: AtomicUsize,
|
ticks_since_adjustment: AtomicUsize,
|
||||||
@ -150,13 +151,13 @@ pub struct VerificationQueue<K: Kind> {
|
|||||||
total_difficulty: RwLock<U256>,
|
total_difficulty: RwLock<U256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueueSignal {
|
struct QueueSignal<C: 'static> {
|
||||||
deleting: Arc<AtomicBool>,
|
deleting: Arc<AtomicBool>,
|
||||||
signalled: AtomicBool,
|
signalled: AtomicBool,
|
||||||
message_channel: Mutex<IoChannel<ClientIoMessage>>,
|
message_channel: Mutex<IoChannel<ClientIoMessage<C>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QueueSignal {
|
impl<C> QueueSignal<C> {
|
||||||
fn set_sync(&self) {
|
fn set_sync(&self) {
|
||||||
// Do not signal when we are about to close
|
// Do not signal when we are about to close
|
||||||
if self.deleting.load(AtomicOrdering::Relaxed) {
|
if self.deleting.load(AtomicOrdering::Relaxed) {
|
||||||
@ -200,9 +201,9 @@ struct Verification<K: Kind> {
|
|||||||
check_seal: bool,
|
check_seal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Kind> VerificationQueue<K> {
|
impl<K: Kind, C> VerificationQueue<K, C> {
|
||||||
/// Creates a new queue instance.
|
/// Creates a new queue instance.
|
||||||
pub fn new(config: Config, engine: Arc<dyn Engine>, message_channel: IoChannel<ClientIoMessage>, check_seal: bool) -> Self {
|
pub fn new(config: Config, engine: Arc<dyn Engine>, message_channel: IoChannel<ClientIoMessage<C>>, check_seal: bool) -> Self {
|
||||||
let verification = Arc::new(Verification {
|
let verification = Arc::new(Verification {
|
||||||
unverified: LenCachingMutex::new(VecDeque::new()),
|
unverified: LenCachingMutex::new(VecDeque::new()),
|
||||||
verifying: LenCachingMutex::new(VecDeque::new()),
|
verifying: LenCachingMutex::new(VecDeque::new()),
|
||||||
@ -213,7 +214,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
verifying: AtomicUsize::new(0),
|
verifying: AtomicUsize::new(0),
|
||||||
verified: AtomicUsize::new(0),
|
verified: AtomicUsize::new(0),
|
||||||
},
|
},
|
||||||
check_seal: check_seal,
|
check_seal,
|
||||||
});
|
});
|
||||||
let more_to_verify = Arc::new(Condvar::new());
|
let more_to_verify = Arc::new(Condvar::new());
|
||||||
let deleting = Arc::new(AtomicBool::new(false));
|
let deleting = Arc::new(AtomicBool::new(false));
|
||||||
@ -270,19 +271,19 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VerificationQueue {
|
VerificationQueue {
|
||||||
engine: engine,
|
engine,
|
||||||
ready_signal: ready_signal,
|
ready_signal,
|
||||||
more_to_verify: more_to_verify,
|
more_to_verify,
|
||||||
verification: verification,
|
verification,
|
||||||
deleting: deleting,
|
deleting,
|
||||||
processing: RwLock::new(HashMap::new()),
|
processing: RwLock::new(HashMap::new()),
|
||||||
empty: empty,
|
empty,
|
||||||
ticks_since_adjustment: AtomicUsize::new(0),
|
ticks_since_adjustment: AtomicUsize::new(0),
|
||||||
max_queue_size: cmp::max(config.max_queue_size, MIN_QUEUE_LIMIT),
|
max_queue_size: cmp::max(config.max_queue_size, MIN_QUEUE_LIMIT),
|
||||||
max_mem_use: cmp::max(config.max_mem_use, MIN_MEM_LIMIT),
|
max_mem_use: cmp::max(config.max_mem_use, MIN_MEM_LIMIT),
|
||||||
scale_verifiers: scale_verifiers,
|
scale_verifiers,
|
||||||
verifier_handles: verifier_handles,
|
verifier_handles,
|
||||||
state: state,
|
state,
|
||||||
total_difficulty: RwLock::new(0.into()),
|
total_difficulty: RwLock::new(0.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,7 +292,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
verification: Arc<Verification<K>>,
|
verification: Arc<Verification<K>>,
|
||||||
engine: Arc<dyn Engine>,
|
engine: Arc<dyn Engine>,
|
||||||
wait: Arc<Condvar>,
|
wait: Arc<Condvar>,
|
||||||
ready: Arc<QueueSignal>,
|
ready: Arc<QueueSignal<C>>,
|
||||||
empty: Arc<Condvar>,
|
empty: Arc<Condvar>,
|
||||||
state: Arc<(Mutex<State>, Condvar)>,
|
state: Arc<(Mutex<State>, Condvar)>,
|
||||||
id: usize,
|
id: usize,
|
||||||
@ -373,7 +374,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
// we're next!
|
// we're next!
|
||||||
let mut verified = verification.verified.lock();
|
let mut verified = verification.verified.lock();
|
||||||
let mut bad = verification.bad.lock();
|
let mut bad = verification.bad.lock();
|
||||||
VerificationQueue::drain_verifying(&mut verifying, &mut verified, &mut bad, &verification.sizes);
|
VerificationQueue::<_, C>::drain_verifying(&mut verifying, &mut verified, &mut bad, &verification.sizes);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -388,7 +389,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
verifying.retain(|e| e.hash != hash);
|
verifying.retain(|e| e.hash != hash);
|
||||||
|
|
||||||
if verifying.front().map_or(false, |x| x.output.is_some()) {
|
if verifying.front().map_or(false, |x| x.output.is_some()) {
|
||||||
VerificationQueue::drain_verifying(&mut verifying, &mut verified, &mut bad, &verification.sizes);
|
VerificationQueue::<_, C>::drain_verifying(&mut verifying, &mut verified, &mut bad, &verification.sizes);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -706,7 +707,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Kind> Drop for VerificationQueue<K> {
|
impl<K: Kind, C> Drop for VerificationQueue<K, C> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
trace!(target: "shutdown", "[VerificationQueue] Closing...");
|
trace!(target: "shutdown", "[VerificationQueue] Closing...");
|
||||||
self.clear();
|
self.clear();
|
||||||
@ -734,11 +735,12 @@ impl<K: Kind> Drop for VerificationQueue<K> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use io::*;
|
use ethcore_io::*;
|
||||||
use super::{BlockQueue, Config, State};
|
use super::{BlockQueue, Config, State};
|
||||||
use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
|
use ethcore::test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
|
||||||
use bytes::Bytes;
|
use ethcore::client::Client;
|
||||||
use types::{
|
use parity_bytes::Bytes;
|
||||||
|
use common_types::{
|
||||||
errors::{EthcoreError, ImportError},
|
errors::{EthcoreError, ImportError},
|
||||||
verification::Unverified,
|
verification::Unverified,
|
||||||
view,
|
view,
|
||||||
@ -748,7 +750,7 @@ mod tests {
|
|||||||
|
|
||||||
// create a test block queue.
|
// create a test block queue.
|
||||||
// auto_scaling enables verifier adjustment.
|
// auto_scaling enables verifier adjustment.
|
||||||
fn get_test_queue(auto_scale: bool) -> BlockQueue {
|
fn get_test_queue(auto_scale: bool) -> BlockQueue<Client> {
|
||||||
let spec = spec::new_test();
|
let spec = spec::new_test();
|
||||||
let engine = spec.engine;
|
let engine = spec.engine;
|
||||||
|
|
||||||
@ -773,7 +775,7 @@ mod tests {
|
|||||||
// TODO better test
|
// TODO better test
|
||||||
let spec = spec::new_test();
|
let spec = spec::new_test();
|
||||||
let engine = spec.engine;
|
let engine = spec.engine;
|
||||||
let _ = BlockQueue::new(Config::default(), engine, IoChannel::disconnected(), true);
|
let _ = BlockQueue::<Client>::new(Config::default(), engine, IoChannel::disconnected(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -853,7 +855,7 @@ mod tests {
|
|||||||
let engine = spec.engine;
|
let engine = spec.engine;
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.max_mem_use = super::MIN_MEM_LIMIT; // empty queue uses about 15000
|
config.max_mem_use = super::MIN_MEM_LIMIT; // empty queue uses about 15000
|
||||||
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
|
let queue = BlockQueue::<Client>::new(config, engine, IoChannel::disconnected(), true);
|
||||||
assert!(!queue.queue_info().is_full());
|
assert!(!queue.queue_info().is_full());
|
||||||
let mut blocks = get_good_dummy_block_seq(50);
|
let mut blocks = get_good_dummy_block_seq(50);
|
||||||
for b in blocks.drain(..) {
|
for b in blocks.drain(..) {
|
||||||
@ -903,7 +905,7 @@ mod tests {
|
|||||||
let spec = spec::new_test();
|
let spec = spec::new_test();
|
||||||
let engine = spec.engine;
|
let engine = spec.engine;
|
||||||
let config = get_test_config(1, false);
|
let config = get_test_config(1, false);
|
||||||
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
|
let queue = BlockQueue::<Client>::new(config, engine, IoChannel::disconnected(), true);
|
||||||
|
|
||||||
assert_eq!(queue.num_verifiers(), 1);
|
assert_eq!(queue.num_verifiers(), 1);
|
||||||
}
|
}
|
||||||
@ -913,7 +915,7 @@ mod tests {
|
|||||||
let spec = spec::new_test();
|
let spec = spec::new_test();
|
||||||
let engine = spec.engine;
|
let engine = spec.engine;
|
||||||
let config = get_test_config(0, false);
|
let config = get_test_config(0, false);
|
||||||
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
|
let queue = BlockQueue::<Client>::new(config, engine, IoChannel::disconnected(), true);
|
||||||
|
|
||||||
assert_eq!(queue.num_verifiers(), 1);
|
assert_eq!(queue.num_verifiers(), 1);
|
||||||
}
|
}
|
||||||
@ -923,7 +925,7 @@ mod tests {
|
|||||||
let spec = spec::new_test();
|
let spec = spec::new_test();
|
||||||
let engine = spec.engine;
|
let engine = spec.engine;
|
||||||
let config = get_test_config(10_000, false);
|
let config = get_test_config(10_000, false);
|
||||||
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
|
let queue = BlockQueue::<Client>::new(config, engine, IoChannel::disconnected(), true);
|
||||||
let num_cpus = ::num_cpus::get();
|
let num_cpus = ::num_cpus::get();
|
||||||
|
|
||||||
assert_eq!(queue.num_verifiers(), num_cpus);
|
assert_eq!(queue.num_verifiers(), num_cpus);
|
||||||
@ -937,7 +939,7 @@ mod tests {
|
|||||||
let spec = spec::new_test();
|
let spec = spec::new_test();
|
||||||
let engine = spec.engine;
|
let engine = spec.engine;
|
||||||
let config = get_test_config(num_cpus - 1, true);
|
let config = get_test_config(num_cpus - 1, true);
|
||||||
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
|
let queue = BlockQueue::<Client>::new(config, engine, IoChannel::disconnected(), true);
|
||||||
queue.scale_verifiers(num_cpus);
|
queue.scale_verifiers(num_cpus);
|
||||||
|
|
||||||
assert_eq!(queue.num_verifiers(), num_cpus);
|
assert_eq!(queue.num_verifiers(), num_cpus);
|
@ -24,7 +24,7 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use hash::keccak;
|
use keccak_hash::keccak;
|
||||||
use rlp::Rlp;
|
use rlp::Rlp;
|
||||||
use triehash::ordered_trie_root;
|
use triehash::ordered_trie_root;
|
||||||
use unexpected::{Mismatch, OutOfBounds};
|
use unexpected::{Mismatch, OutOfBounds};
|
||||||
@ -33,7 +33,7 @@ use blockchain::*;
|
|||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use types::{
|
use common_types::{
|
||||||
BlockNumber,
|
BlockNumber,
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::{EthcoreError as Error, BlockError},
|
errors::{EthcoreError as Error, BlockError},
|
||||||
@ -366,15 +366,19 @@ mod tests {
|
|||||||
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use ethereum_types::{H256, BloomRef, U256, Address};
|
use ethereum_types::{H256, BloomRef, U256, Address};
|
||||||
use blockchain::{BlockDetails, TransactionAddress, BlockReceipts};
|
use blockchain::{BlockDetails, TransactionAddress, BlockReceipts};
|
||||||
use bytes::Bytes;
|
use parity_bytes::Bytes;
|
||||||
use hash::keccak;
|
use keccak_hash::keccak;
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use ethkey::{Random, Generator};
|
use ethkey::{Random, Generator};
|
||||||
use spec;
|
use spec;
|
||||||
use test_helpers::{create_test_block_with_data, create_test_block};
|
use ethcore::{
|
||||||
use types::{
|
client::TestBlockChainClient,
|
||||||
|
test_helpers::{create_test_block_with_data, create_test_block}
|
||||||
|
};
|
||||||
|
use common_types::{
|
||||||
encoded,
|
encoded,
|
||||||
engines::params::CommonParams,
|
engines::params::CommonParams,
|
||||||
errors::BlockError::*,
|
errors::BlockError::*,
|
||||||
@ -383,6 +387,8 @@ mod tests {
|
|||||||
};
|
};
|
||||||
use rlp;
|
use rlp;
|
||||||
use triehash::ordered_trie_root;
|
use triehash::ordered_trie_root;
|
||||||
|
use machine::Machine;
|
||||||
|
use null_engine::NullEngine;
|
||||||
|
|
||||||
fn check_ok(result: Result<(), Error>) {
|
fn check_ok(result: Result<(), Error>) {
|
||||||
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
||||||
@ -518,7 +524,7 @@ mod tests {
|
|||||||
// additions that need access to state (tx filter in specific)
|
// additions that need access to state (tx filter in specific)
|
||||||
// no existing tests need access to test, so having this not function
|
// no existing tests need access to test, so having this not function
|
||||||
// is fine.
|
// is fine.
|
||||||
let client = ::client::TestBlockChainClient::default();
|
let client = TestBlockChainClient::default();
|
||||||
let parent = bc.block_header_data(header.parent_hash())
|
let parent = bc.block_header_data(header.parent_hash())
|
||||||
.ok_or(BlockError::UnknownParent(*header.parent_hash()))?
|
.ok_or(BlockError::UnknownParent(*header.parent_hash()))?
|
||||||
.decode()?;
|
.decode()?;
|
||||||
@ -779,11 +785,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dust_protection() {
|
fn dust_protection() {
|
||||||
use ethkey::{Generator, Random};
|
|
||||||
use types::transaction::{Transaction, Action};
|
|
||||||
use machine::Machine;
|
|
||||||
use null_engine::NullEngine;
|
|
||||||
|
|
||||||
let mut params = CommonParams::default();
|
let mut params = CommonParams::default();
|
||||||
params.dust_protection_transition = 0;
|
params.dust_protection_transition = 0;
|
||||||
params.nonce_cap_increment = 2;
|
params.nonce_cap_increment = 2;
|
@ -18,11 +18,12 @@
|
|||||||
|
|
||||||
use call_contract::CallContract;
|
use call_contract::CallContract;
|
||||||
use client_traits::BlockInfo;
|
use client_traits::BlockInfo;
|
||||||
use engine::Engine;
|
use common_types::{
|
||||||
use types::{
|
|
||||||
header::Header,
|
header::Header,
|
||||||
errors::EthcoreError as Error,
|
errors::EthcoreError as Error,
|
||||||
};
|
};
|
||||||
|
use engine::Engine;
|
||||||
|
|
||||||
use super::verification;
|
use super::verification;
|
||||||
|
|
||||||
/// Should be used to verify blocks.
|
/// Should be used to verify blocks.
|
@ -30,7 +30,6 @@ use client_traits::{BlockInfo, BlockChainReset, Nonce, Balance, BlockChainClient
|
|||||||
use ethcore::{
|
use ethcore::{
|
||||||
client::{DatabaseCompactionProfile, VMType},
|
client::{DatabaseCompactionProfile, VMType},
|
||||||
miner::Miner,
|
miner::Miner,
|
||||||
verification::queue::VerifierSettings,
|
|
||||||
};
|
};
|
||||||
use ethcore_service::ClientService;
|
use ethcore_service::ClientService;
|
||||||
use cache::CacheConfig;
|
use cache::CacheConfig;
|
||||||
@ -48,6 +47,7 @@ use types::{
|
|||||||
client_types::Mode,
|
client_types::Mode,
|
||||||
verification::Unverified,
|
verification::Unverified,
|
||||||
};
|
};
|
||||||
|
use verification::queue::VerifierSettings;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum DataFormat {
|
pub enum DataFormat {
|
||||||
@ -234,7 +234,7 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> {
|
|||||||
&cmd.cache_config,
|
&cmd.cache_config,
|
||||||
&cmd.compaction).map_err(|e| format!("Failed to open database: {:?}", e))?;
|
&cmd.compaction).map_err(|e| format!("Failed to open database: {:?}", e))?;
|
||||||
|
|
||||||
// TODO: could epoch signals be avilable at the end of the file?
|
// TODO: could epoch signals be available at the end of the file?
|
||||||
let fetch = ::light::client::fetch::unavailable();
|
let fetch = ::light::client::fetch::unavailable();
|
||||||
let service = LightClientService::start(config, &spec, fetch, db, cache)
|
let service = LightClientService::start(config, &spec, fetch, db, cache)
|
||||||
.map_err(|e| format!("Failed to start client: {}", e))?;
|
.map_err(|e| format!("Failed to start client: {}", e))?;
|
||||||
|
@ -32,8 +32,8 @@ use ethkey::{Secret, Public};
|
|||||||
use ethcore::client::{VMType};
|
use ethcore::client::{VMType};
|
||||||
use ethcore::miner::{stratum, MinerOptions};
|
use ethcore::miner::{stratum, MinerOptions};
|
||||||
use ethcore::snapshot::SnapshotConfiguration;
|
use ethcore::snapshot::SnapshotConfiguration;
|
||||||
use ethcore::verification::queue::VerifierSettings;
|
|
||||||
use miner::pool;
|
use miner::pool;
|
||||||
|
use verification::queue::VerifierSettings;
|
||||||
|
|
||||||
use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration};
|
use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration};
|
||||||
use parity_rpc::NetworkSettings;
|
use parity_rpc::NetworkSettings;
|
||||||
|
@ -23,13 +23,13 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
|||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
|
|
||||||
use atty;
|
use atty;
|
||||||
use ethcore::client::{
|
use ethcore::client::{ChainNotify, NewBlocks, Client};
|
||||||
ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage
|
use client_traits::{BlockInfo, ChainInfo, BlockChainClient, IoClient};
|
||||||
};
|
|
||||||
use client_traits::{BlockInfo, ChainInfo, BlockChainClient};
|
|
||||||
use types::{
|
use types::{
|
||||||
BlockNumber,
|
BlockNumber,
|
||||||
|
client_types::ClientReport,
|
||||||
ids::BlockId,
|
ids::BlockId,
|
||||||
|
io_message::ClientIoMessage,
|
||||||
blockchain_info::BlockChainInfo,
|
blockchain_info::BlockChainInfo,
|
||||||
verification::VerificationQueueInfo as BlockQueueInfo,
|
verification::VerificationQueueInfo as BlockQueueInfo,
|
||||||
snapshot::RestorationStatus,
|
snapshot::RestorationStatus,
|
||||||
@ -451,12 +451,16 @@ impl LightChainNotify for Informant<LightNodeInformantData> {
|
|||||||
|
|
||||||
const INFO_TIMER: TimerToken = 0;
|
const INFO_TIMER: TimerToken = 0;
|
||||||
|
|
||||||
impl<T: InformantData> IoHandler<ClientIoMessage> for Informant<T> {
|
impl<T, C> IoHandler<ClientIoMessage<C>> for Informant<T>
|
||||||
fn initialize(&self, io: &IoContext<ClientIoMessage>) {
|
where
|
||||||
|
T: InformantData,
|
||||||
|
C: client_traits::Tick + 'static,
|
||||||
|
{
|
||||||
|
fn initialize(&self, io: &IoContext<ClientIoMessage<C>>) {
|
||||||
io.register_timer(INFO_TIMER, Duration::from_secs(5)).expect("Error registering timer");
|
io.register_timer(INFO_TIMER, Duration::from_secs(5)).expect("Error registering timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
|
fn timeout(&self, _io: &IoContext<ClientIoMessage<C>>, timer: TimerToken) {
|
||||||
if timer == INFO_TIMER && !self.in_shutdown.load(AtomicOrdering::SeqCst) {
|
if timer == INFO_TIMER && !self.in_shutdown.load(AtomicOrdering::SeqCst) {
|
||||||
self.tick();
|
self.tick();
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ extern crate parity_updater as updater;
|
|||||||
extern crate parity_version;
|
extern crate parity_version;
|
||||||
extern crate registrar;
|
extern crate registrar;
|
||||||
extern crate spec;
|
extern crate spec;
|
||||||
|
extern crate verification;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log as rlog;
|
extern crate log as rlog;
|
||||||
|
@ -27,7 +27,7 @@ use ethcore::client::{Client, DatabaseCompactionProfile, VMType};
|
|||||||
use ethcore::miner::{self, stratum, Miner, MinerService, MinerOptions};
|
use ethcore::miner::{self, stratum, Miner, MinerService, MinerOptions};
|
||||||
use ethcore::snapshot::{self, SnapshotConfiguration};
|
use ethcore::snapshot::{self, SnapshotConfiguration};
|
||||||
use spec::SpecParams;
|
use spec::SpecParams;
|
||||||
use ethcore::verification::queue::VerifierSettings;
|
use verification::queue::VerifierSettings;
|
||||||
use ethcore_logger::{Config as LogConfig, RotatingLogger};
|
use ethcore_logger::{Config as LogConfig, RotatingLogger};
|
||||||
use ethcore_service::ClientService;
|
use ethcore_service::ClientService;
|
||||||
use ethereum_types::Address;
|
use ethereum_types::Address;
|
||||||
@ -307,18 +307,18 @@ fn execute_light_impl<Cr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq
|
|||||||
|
|
||||||
// start RPCs
|
// start RPCs
|
||||||
let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
|
let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
|
||||||
signer_service: signer_service,
|
signer_service,
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
sync: light_sync.clone(),
|
sync: light_sync.clone(),
|
||||||
net: light_sync.clone(),
|
net: light_sync.clone(),
|
||||||
accounts: account_provider,
|
accounts: account_provider,
|
||||||
logger: logger,
|
logger,
|
||||||
settings: Arc::new(cmd.net_settings),
|
settings: Arc::new(cmd.net_settings),
|
||||||
on_demand: on_demand,
|
on_demand,
|
||||||
cache: cache.clone(),
|
cache: cache.clone(),
|
||||||
transaction_queue: txq,
|
transaction_queue: txq,
|
||||||
ws_address: cmd.ws_conf.address(),
|
ws_address: cmd.ws_conf.address(),
|
||||||
fetch: fetch,
|
fetch,
|
||||||
geth_compatibility: cmd.geth_compatibility,
|
geth_compatibility: cmd.geth_compatibility,
|
||||||
experimental_rpcs: cmd.experimental_rpcs,
|
experimental_rpcs: cmd.experimental_rpcs,
|
||||||
executor: runtime.executor(),
|
executor: runtime.executor(),
|
||||||
@ -344,7 +344,7 @@ fn execute_light_impl<Cr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq
|
|||||||
LightNodeInformantData {
|
LightNodeInformantData {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
sync: light_sync.clone(),
|
sync: light_sync.clone(),
|
||||||
cache: cache,
|
cache,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
Some(rpc_stats),
|
Some(rpc_stats),
|
||||||
|
@ -20,6 +20,7 @@ use std::time::Duration;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use client_traits::SnapshotClient;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use ethcore::snapshot::{SnapshotConfiguration, SnapshotService as SS};
|
use ethcore::snapshot::{SnapshotConfiguration, SnapshotService as SS};
|
||||||
use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter};
|
use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter};
|
||||||
|
@ -67,6 +67,7 @@ account-state = { path = "../ethcore/account-state" }
|
|||||||
stats = { path = "../util/stats" }
|
stats = { path = "../util/stats" }
|
||||||
trace = { path = "../ethcore/trace" }
|
trace = { path = "../ethcore/trace" }
|
||||||
vm = { path = "../ethcore/vm" }
|
vm = { path = "../ethcore/vm" }
|
||||||
|
verification = { path = "../ethcore/verification" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
client-traits = { path = "../ethcore/client-traits" }
|
client-traits = { path = "../ethcore/client-traits" }
|
||||||
|
@ -89,6 +89,7 @@ extern crate account_state;
|
|||||||
extern crate stats;
|
extern crate stats;
|
||||||
extern crate tempdir;
|
extern crate tempdir;
|
||||||
extern crate trace;
|
extern crate trace;
|
||||||
|
extern crate verification;
|
||||||
extern crate vm;
|
extern crate vm;
|
||||||
|
|
||||||
#[cfg(any(test, feature = "ethcore-accounts"))]
|
#[cfg(any(test, feature = "ethcore-accounts"))]
|
||||||
|
@ -24,7 +24,7 @@ use ethcore::client::{Client, ClientConfig};
|
|||||||
use ethcore::miner::Miner;
|
use ethcore::miner::Miner;
|
||||||
use spec::{Genesis, Spec, self};
|
use spec::{Genesis, Spec, self};
|
||||||
use ethcore::test_helpers;
|
use ethcore::test_helpers;
|
||||||
use ethcore::verification::VerifierType;
|
use verification::VerifierType;
|
||||||
use ethereum_types::{Address, H256, U256};
|
use ethereum_types::{Address, H256, U256};
|
||||||
use ethjson::blockchain::BlockChain;
|
use ethjson::blockchain::BlockChain;
|
||||||
use ethjson::spec::ForkSpec;
|
use ethjson::spec::ForkSpec;
|
||||||
@ -98,7 +98,6 @@ impl EthTester {
|
|||||||
if let Ok(block) = Unverified::from_rlp(b) {
|
if let Ok(block) = Unverified::from_rlp(b) {
|
||||||
let _ = tester.client.import_block(block);
|
let _ = tester.client.import_block(block);
|
||||||
tester.client.flush_queue();
|
tester.client.flush_queue();
|
||||||
tester.client.import_verified_blocks();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user