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-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "len-caching-lock 0.1.1",
 | 
			
		||||
 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "machine 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-runtime 0.1.0",
 | 
			
		||||
 "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)",
 | 
			
		||||
 "patricia-trie-ethereum 0.1.0",
 | 
			
		||||
 "pod 0.1.0",
 | 
			
		||||
@ -1080,7 +1078,6 @@ dependencies = [
 | 
			
		||||
 "state-db 0.1.0",
 | 
			
		||||
 "stats 0.1.0",
 | 
			
		||||
 "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "time-utils 0.1.0",
 | 
			
		||||
 "trace 0.1.0",
 | 
			
		||||
 "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)",
 | 
			
		||||
@ -1089,6 +1086,7 @@ dependencies = [
 | 
			
		||||
 "triehash-ethereum 0.2.0",
 | 
			
		||||
 "unexpected 0.1.0",
 | 
			
		||||
 "using_queue 0.1.0",
 | 
			
		||||
 "verification 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)",
 | 
			
		||||
 "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "triehash-ethereum 0.2.0",
 | 
			
		||||
 "verification 0.1.0",
 | 
			
		||||
 "vm 0.1.0",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -1451,6 +1450,7 @@ name = "ethcore-service"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "client-traits 0.1.0",
 | 
			
		||||
 "common-types 0.1.0",
 | 
			
		||||
 "ethcore 1.12.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)",
 | 
			
		||||
 "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)",
 | 
			
		||||
 "verification 0.1.0",
 | 
			
		||||
 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -3171,6 +3172,7 @@ dependencies = [
 | 
			
		||||
 "trace 0.1.0",
 | 
			
		||||
 "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)",
 | 
			
		||||
 "verification 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)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[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]]
 | 
			
		||||
name = "version_check"
 | 
			
		||||
version = "0.1.5"
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,7 @@ spec = { path = "ethcore/spec" }
 | 
			
		||||
term_size = "0.3"
 | 
			
		||||
textwrap = "0.9"
 | 
			
		||||
toml = "0.4"
 | 
			
		||||
verification = { path = "ethcore/verification" }
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
rustc_version = "0.2"
 | 
			
		||||
 | 
			
		||||
@ -35,16 +35,14 @@ evm = { path = "evm" }
 | 
			
		||||
executive-state = { path = "executive-state" }
 | 
			
		||||
futures = "0.1"
 | 
			
		||||
hash-db = "0.15.0"
 | 
			
		||||
parity-util-mem = "0.2.0"
 | 
			
		||||
itertools = "0.5"
 | 
			
		||||
journaldb = { path = "../util/journaldb" }
 | 
			
		||||
keccak-hash = "0.2.0"
 | 
			
		||||
keccak-hasher = { path = "../util/keccak-hasher" }
 | 
			
		||||
kvdb = "0.1"
 | 
			
		||||
kvdb-memorydb = "0.1"
 | 
			
		||||
kvdb-memorydb = { version = "0.1", optional = true }
 | 
			
		||||
kvdb-rocksdb = { version = "0.1.3", optional = true }
 | 
			
		||||
lazy_static = "1.3.0"
 | 
			
		||||
len-caching-lock = { path = "../util/len-caching-lock" }
 | 
			
		||||
lazy_static = { version = "1.3", optional = true }
 | 
			
		||||
log = "0.4"
 | 
			
		||||
macros = { path = "../util/macros", optional = true }
 | 
			
		||||
machine = { path = "./machine" }
 | 
			
		||||
@ -61,20 +59,19 @@ rand_xorshift = "0.1.1"
 | 
			
		||||
rayon = "1.1"
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
rlp_derive = { path = "../util/rlp-derive" }
 | 
			
		||||
rustc-hex = "1.0"
 | 
			
		||||
rustc-hex = { version = "1", optional = true }
 | 
			
		||||
serde = "1.0"
 | 
			
		||||
serde_derive = "1.0"
 | 
			
		||||
spec = { path = "spec" }
 | 
			
		||||
state-db = { path = "state-db" }
 | 
			
		||||
stats = { path = "../util/stats" }
 | 
			
		||||
tempdir = { version = "0.3", optional = true }
 | 
			
		||||
time-utils = { path = "../util/time-utils" }
 | 
			
		||||
trace = { path = "trace" }
 | 
			
		||||
trace-time = "0.1"
 | 
			
		||||
trie-vm-factories = { path = "trie-vm-factories" }
 | 
			
		||||
triehash-ethereum = { version = "0.2",  path = "../util/triehash-ethereum" }
 | 
			
		||||
unexpected = { path = "../util/unexpected" }
 | 
			
		||||
using_queue = { path = "../miner/using-queue" }
 | 
			
		||||
verification = { path = "./verification" }
 | 
			
		||||
vm = { path = "vm" }
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
@ -88,14 +85,18 @@ ethcore-accounts = { path = "../accounts" }
 | 
			
		||||
ethjson = { path = "../json" }
 | 
			
		||||
ethkey = { path = "../accounts/ethkey" }
 | 
			
		||||
fetch = { path = "../util/fetch" }
 | 
			
		||||
kvdb-memorydb = "0.1"
 | 
			
		||||
kvdb-rocksdb = "0.1.3"
 | 
			
		||||
lazy_static = { version = "1.3" }
 | 
			
		||||
machine = { path = "./machine", features = ["test-helpers"] }
 | 
			
		||||
macros = { path = "../util/macros" }
 | 
			
		||||
null-engine = { path = "./engines/null-engine" }
 | 
			
		||||
parity-runtime = { path = "../util/runtime" }
 | 
			
		||||
pod = { path = "pod" }
 | 
			
		||||
rlp_compress = { path = "../util/rlp-compress" }
 | 
			
		||||
rustc-hex = "1"
 | 
			
		||||
serde_json = "1.0"
 | 
			
		||||
stats = { path = "../util/stats" }
 | 
			
		||||
tempdir = "0.3"
 | 
			
		||||
trie-standardmap = "0.15.0"
 | 
			
		||||
 | 
			
		||||
@ -121,14 +122,14 @@ evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
 | 
			
		||||
# EVM debug traces are printed.
 | 
			
		||||
slow-blocks = []
 | 
			
		||||
# 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.
 | 
			
		||||
ci-skip-tests = []
 | 
			
		||||
# Run memory/cpu heavy tests.
 | 
			
		||||
test-heavy = []
 | 
			
		||||
# Compile test helpers
 | 
			
		||||
# 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]]
 | 
			
		||||
name = "builtin"
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ use common_types::{
 | 
			
		||||
	client_types::Mode,
 | 
			
		||||
	encoded,
 | 
			
		||||
	engines::{epoch::Transition as EpochTransition, machine::Executed},
 | 
			
		||||
	errors::EthcoreResult,
 | 
			
		||||
	errors::{EthcoreError, EthcoreResult},
 | 
			
		||||
	filter::Filter,
 | 
			
		||||
	header::Header,
 | 
			
		||||
	ids::{BlockId, TransactionId, TraceId, UncleId},
 | 
			
		||||
@ -56,6 +56,8 @@ use trace::{
 | 
			
		||||
};
 | 
			
		||||
use vm::{LastHashes, Schedule};
 | 
			
		||||
 | 
			
		||||
use common_types::snapshot::Progress;
 | 
			
		||||
 | 
			
		||||
/// State information to be used during client query
 | 
			
		||||
pub enum StateOrBlock {
 | 
			
		||||
	/// 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>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
 | 
			
		||||
/// Provides methods to import block into blockchain
 | 
			
		||||
pub trait ImportBlock {
 | 
			
		||||
	/// Import a block into the blockchain.
 | 
			
		||||
	fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
 | 
			
		||||
 | 
			
		||||
	/// 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.
 | 
			
		||||
@ -187,6 +192,14 @@ pub trait IoClient: Sync + Send {
 | 
			
		||||
	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.
 | 
			
		||||
pub trait BadBlocks {
 | 
			
		||||
	/// 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 {
 | 
			
		||||
	/// reset to best_block - n
 | 
			
		||||
	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.
 | 
			
		||||
	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" }
 | 
			
		||||
derive_more = "0.14.0"
 | 
			
		||||
engine = { path = "../engine" }
 | 
			
		||||
ethcore = { path = ".."}
 | 
			
		||||
ethcore-db = { path = "../db" }
 | 
			
		||||
ethcore-blockchain = { path = "../blockchain" }
 | 
			
		||||
ethereum-types = "0.6.0"
 | 
			
		||||
@ -49,6 +48,7 @@ kvdb = "0.1"
 | 
			
		||||
memory-cache = { path = "../../util/memory-cache" }
 | 
			
		||||
error-chain = { version = "0.12", default-features = false }
 | 
			
		||||
journaldb = { path = "../../util/journaldb" }
 | 
			
		||||
verification = { path = "../verification" }
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
ethcore = { path = "..", features = ["test-helpers"] }
 | 
			
		||||
 | 
			
		||||
@ -19,8 +19,7 @@
 | 
			
		||||
use std::sync::{Weak, Arc};
 | 
			
		||||
 | 
			
		||||
use engine::{Engine, EpochChange, Proof};
 | 
			
		||||
use ethcore::client::{ClientReport, ClientIoMessage};
 | 
			
		||||
use ethcore::verification::queue::{self, HeaderQueue};
 | 
			
		||||
use verification::queue::{self, HeaderQueue};
 | 
			
		||||
use spec::{Spec, SpecHardcodedSync};
 | 
			
		||||
use io::IoChannel;
 | 
			
		||||
use parking_lot::{Mutex, RwLock};
 | 
			
		||||
@ -30,12 +29,14 @@ use common_types::{
 | 
			
		||||
	BlockNumber,
 | 
			
		||||
	block_status::BlockStatus,
 | 
			
		||||
	blockchain_info::BlockChainInfo,
 | 
			
		||||
	client_types::ClientReport,
 | 
			
		||||
	encoded,
 | 
			
		||||
	engines::epoch::{Transition as EpochTransition, PendingTransition},
 | 
			
		||||
	errors::EthcoreError as Error,
 | 
			
		||||
	errors::EthcoreResult,
 | 
			
		||||
	header::Header,
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	verification::VerificationQueueInfo as BlockQueueInfo,
 | 
			
		||||
};
 | 
			
		||||
use kvdb::KeyValueDB;
 | 
			
		||||
@ -162,7 +163,7 @@ impl<T: LightChainClient> AsLightClient for T {
 | 
			
		||||
 | 
			
		||||
/// Light client implementation.
 | 
			
		||||
pub struct Client<T> {
 | 
			
		||||
	queue: HeaderQueue,
 | 
			
		||||
	queue: HeaderQueue<()>,
 | 
			
		||||
	engine: Arc<dyn Engine>,
 | 
			
		||||
	chain: HeaderChain,
 | 
			
		||||
	report: RwLock<ClientReport>,
 | 
			
		||||
@ -183,7 +184,7 @@ impl<T: ChainDataFetcher> Client<T> {
 | 
			
		||||
		chain_col: Option<u32>,
 | 
			
		||||
		spec: &Spec,
 | 
			
		||||
		fetcher: T,
 | 
			
		||||
		io_channel: IoChannel<ClientIoMessage>,
 | 
			
		||||
		io_channel: IoChannel<ClientIoMessage<()>>,
 | 
			
		||||
		cache: Arc<Mutex<Cache>>
 | 
			
		||||
	) -> Result<Self, Error> {
 | 
			
		||||
		Ok(Self {
 | 
			
		||||
@ -649,3 +650,5 @@ impl<T: ChainDataFetcher> client_traits::EngineClient for Client<T> {
 | 
			
		||||
		Client::block_header(self, id)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> client_traits::Tick for Client<T> {}
 | 
			
		||||
 | 
			
		||||
@ -20,10 +20,12 @@
 | 
			
		||||
use std::fmt;
 | 
			
		||||
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_blockchain::BlockChainDB;
 | 
			
		||||
use ethcore::client::ClientIoMessage;
 | 
			
		||||
use spec::Spec;
 | 
			
		||||
use io::{IoContext, IoError, IoHandler, IoService};
 | 
			
		||||
 | 
			
		||||
@ -58,15 +60,15 @@ impl fmt::Display for Error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Light client service.
 | 
			
		||||
pub struct Service<T> {
 | 
			
		||||
pub struct Service<T: 'static> {
 | 
			
		||||
	client: Arc<Client<T>>,
 | 
			
		||||
	io_service: IoService<ClientIoMessage>,
 | 
			
		||||
	io_service: IoService<ClientIoMessage<()>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: ChainDataFetcher> Service<T> {
 | 
			
		||||
	/// 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> {
 | 
			
		||||
		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,
 | 
			
		||||
			db.key_value().clone(),
 | 
			
		||||
			db::COL_LIGHT_CHAIN,
 | 
			
		||||
@ -90,7 +92,7 @@ impl<T: ChainDataFetcher> Service<T> {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// 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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -102,8 +104,8 @@ impl<T: ChainDataFetcher> Service<T> {
 | 
			
		||||
 | 
			
		||||
struct ImportBlocks<T>(Arc<Client<T>>);
 | 
			
		||||
 | 
			
		||||
impl<T: ChainDataFetcher> IoHandler<ClientIoMessage> for ImportBlocks<T> {
 | 
			
		||||
	fn message(&self, _io: &IoContext<ClientIoMessage>, message: &ClientIoMessage) {
 | 
			
		||||
impl<T: ChainDataFetcher> IoHandler<ClientIoMessage<()>> for ImportBlocks<T> {
 | 
			
		||||
	fn message(&self, _io: &IoContext<ClientIoMessage<()>>, message: &ClientIoMessage<()>) {
 | 
			
		||||
		if let ClientIoMessage::BlockVerified = *message {
 | 
			
		||||
			self.0.import_verified();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -65,7 +65,6 @@ extern crate executive_state;
 | 
			
		||||
extern crate parity_bytes as bytes;
 | 
			
		||||
extern crate ethereum_types;
 | 
			
		||||
extern crate ethcore_miner as miner;
 | 
			
		||||
extern crate ethcore;
 | 
			
		||||
extern crate hash_db;
 | 
			
		||||
extern crate parity_util_mem;
 | 
			
		||||
extern crate parity_util_mem as mem;
 | 
			
		||||
@ -94,7 +93,10 @@ extern crate triehash_ethereum as triehash;
 | 
			
		||||
extern crate kvdb;
 | 
			
		||||
extern crate memory_cache;
 | 
			
		||||
extern crate derive_more;
 | 
			
		||||
extern crate verification;
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
extern crate ethcore;
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
extern crate kvdb_memorydb;
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
 | 
			
		||||
@ -104,11 +104,12 @@ use machine::{
 | 
			
		||||
};
 | 
			
		||||
use types::{
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction},
 | 
			
		||||
	engines::machine::Executed,
 | 
			
		||||
};
 | 
			
		||||
use ethcore::client::{
 | 
			
		||||
	Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, Call
 | 
			
		||||
	Client, ChainNotify, NewBlocks, ChainMessageType, Call
 | 
			
		||||
};
 | 
			
		||||
use client_traits::BlockInfo;
 | 
			
		||||
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
 | 
			
		||||
@ -213,7 +214,7 @@ pub struct Provider {
 | 
			
		||||
	client: Arc<Client>,
 | 
			
		||||
	miner: Arc<Miner>,
 | 
			
		||||
	accounts: Arc<dyn Signer>,
 | 
			
		||||
	channel: IoChannel<ClientIoMessage>,
 | 
			
		||||
	channel: IoChannel<ClientIoMessage<Client>>,
 | 
			
		||||
	keys_provider: Arc<dyn KeyProvider>,
 | 
			
		||||
	logging: Option<Logging>,
 | 
			
		||||
	use_offchain_storage: bool,
 | 
			
		||||
@ -236,7 +237,7 @@ impl Provider {
 | 
			
		||||
		accounts: Arc<dyn Signer>,
 | 
			
		||||
		encryptor: Box<dyn Encryptor>,
 | 
			
		||||
		config: ProviderConfig,
 | 
			
		||||
		channel: IoChannel<ClientIoMessage>,
 | 
			
		||||
		channel: IoChannel<ClientIoMessage<Client>>,
 | 
			
		||||
		keys_provider: Arc<dyn KeyProvider>,
 | 
			
		||||
		db: Arc<dyn KeyValueDB>,
 | 
			
		||||
	) -> Self {
 | 
			
		||||
@ -490,7 +491,7 @@ impl Provider {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		Ok(())
 | 
			
		||||
 	}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn contract_address_from_transaction(transaction: &SignedTransaction) -> Result<Address, Error> {
 | 
			
		||||
		match transaction.action {
 | 
			
		||||
@ -876,14 +877,14 @@ impl Provider {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl IoHandler<ClientIoMessage> for Provider {
 | 
			
		||||
	fn initialize(&self, io: &IoContext<ClientIoMessage>) {
 | 
			
		||||
impl IoHandler<ClientIoMessage<Client>> for Provider {
 | 
			
		||||
	fn initialize(&self, io: &IoContext<ClientIoMessage<Client>>) {
 | 
			
		||||
		if self.use_offchain_storage {
 | 
			
		||||
			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 {
 | 
			
		||||
			STATE_RETRIEVAL_TIMER => self.state_storage.tick(&self.logging),
 | 
			
		||||
			_ => warn!("IO service triggered unregistered timer '{}'", timer),
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
 | 
			
		||||
[dependencies]
 | 
			
		||||
ansi_term = "0.11"
 | 
			
		||||
common-types = { path = "../types" }
 | 
			
		||||
client-traits = { path = "../client-traits" }
 | 
			
		||||
ethcore = { path = ".." }
 | 
			
		||||
ethcore-blockchain = { path = "../blockchain" }
 | 
			
		||||
ethcore-io = { path = "../../util/io" }
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@
 | 
			
		||||
 | 
			
		||||
extern crate ansi_term;
 | 
			
		||||
extern crate common_types;
 | 
			
		||||
extern crate client_traits;
 | 
			
		||||
extern crate ethcore;
 | 
			
		||||
extern crate ethcore_blockchain as blockchain;
 | 
			
		||||
extern crate ethcore_io as io;
 | 
			
		||||
 | 
			
		||||
@ -26,15 +26,17 @@ use io::{IoContext, TimerToken, IoHandler, IoService, IoError};
 | 
			
		||||
 | 
			
		||||
use sync::PrivateTxHandler;
 | 
			
		||||
use blockchain::{BlockChainDB, BlockChainDBHandler};
 | 
			
		||||
use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage};
 | 
			
		||||
use ethcore::client::{Client, ClientConfig, ChainNotify};
 | 
			
		||||
use ethcore::miner::Miner;
 | 
			
		||||
use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams};
 | 
			
		||||
use ethcore::snapshot::{SnapshotService as _SnapshotService};
 | 
			
		||||
use spec::Spec;
 | 
			
		||||
use common_types::{
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	errors::{EthcoreError, SnapshotError},
 | 
			
		||||
	snapshot::RestorationStatus,
 | 
			
		||||
};
 | 
			
		||||
use client_traits::{ImportBlock, SnapshotClient, Tick};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
pub struct ClientService {
 | 
			
		||||
	io_service: Arc<IoService<ClientIoMessage>>,
 | 
			
		||||
	io_service: Arc<IoService<ClientIoMessage<Client>>>,
 | 
			
		||||
	client: Arc<Client>,
 | 
			
		||||
	snapshot: Arc<SnapshotService>,
 | 
			
		||||
	private_tx: Arc<PrivateTxService>,
 | 
			
		||||
@ -113,7 +115,7 @@ impl ClientService {
 | 
			
		||||
		private_encryptor_conf: ethcore_private_tx::EncryptorConfig,
 | 
			
		||||
		) -> 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()));
 | 
			
		||||
 | 
			
		||||
@ -165,15 +167,15 @@ impl ClientService {
 | 
			
		||||
 | 
			
		||||
		Ok(ClientService {
 | 
			
		||||
			io_service: Arc::new(io_service),
 | 
			
		||||
			client: client,
 | 
			
		||||
			snapshot: snapshot,
 | 
			
		||||
			client,
 | 
			
		||||
			snapshot,
 | 
			
		||||
			private_tx,
 | 
			
		||||
			database: blockchain_db,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// 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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -193,7 +195,7 @@ impl ClientService {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Get network service component
 | 
			
		||||
	pub fn io(&self) -> Arc<IoService<ClientIoMessage>> {
 | 
			
		||||
	pub fn io(&self) -> Arc<IoService<ClientIoMessage<Client>>> {
 | 
			
		||||
		self.io_service.clone()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -213,8 +215,8 @@ impl ClientService {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// IO interface for the Client handler
 | 
			
		||||
struct ClientIoHandler {
 | 
			
		||||
	client: Arc<Client>,
 | 
			
		||||
struct ClientIoHandler<C> {
 | 
			
		||||
	client: Arc<C>,
 | 
			
		||||
	snapshot: Arc<SnapshotService>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -224,13 +226,16 @@ const SNAPSHOT_TICK_TIMER: TimerToken = 1;
 | 
			
		||||
const CLIENT_TICK: Duration = Duration::from_secs(5);
 | 
			
		||||
const SNAPSHOT_TICK: Duration = Duration::from_secs(10);
 | 
			
		||||
 | 
			
		||||
impl IoHandler<ClientIoMessage> for ClientIoHandler {
 | 
			
		||||
	fn initialize(&self, io: &IoContext<ClientIoMessage>) {
 | 
			
		||||
impl<C> IoHandler<ClientIoMessage<C>> for ClientIoHandler<C>
 | 
			
		||||
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(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");
 | 
			
		||||
		match 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");
 | 
			
		||||
		use std::thread;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
// You should have received a copy of the GNU General Public License
 | 
			
		||||
// 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::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
 | 
			
		||||
use std::sync::{Arc, Weak};
 | 
			
		||||
@ -42,14 +42,15 @@ use client::ancient_import::AncientVerifier;
 | 
			
		||||
use client::{
 | 
			
		||||
	ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock,
 | 
			
		||||
	Call, BlockProducer, SealedBlockImporter, ChainNotify, EngineInfo,
 | 
			
		||||
	ClientConfig, NewBlocks, ChainRoute, ChainMessageType, bad_blocks, ClientIoMessage,
 | 
			
		||||
	ClientConfig, NewBlocks, ChainRoute, ChainMessageType, bad_blocks,
 | 
			
		||||
};
 | 
			
		||||
use client_traits::{
 | 
			
		||||
	BlockInfo, ScheduleInfo, StateClient, BlockChainReset,
 | 
			
		||||
	Nonce, Balance, ChainInfo, TransactionInfo, ImportBlock,
 | 
			
		||||
	AccountData, BlockChain as BlockChainTrait, BlockChainClient,
 | 
			
		||||
	IoClient, BadBlocks, ProvingBlockChainClient,
 | 
			
		||||
	StateOrBlock
 | 
			
		||||
	IoClient, BadBlocks, ProvingBlockChainClient, SnapshotClient,
 | 
			
		||||
	DatabaseRestore, SnapshotWriter, Tick,
 | 
			
		||||
	StateOrBlock,
 | 
			
		||||
};
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use machine::{
 | 
			
		||||
@ -59,7 +60,7 @@ use machine::{
 | 
			
		||||
};
 | 
			
		||||
use trie_vm_factories::{Factories, VmFactory};
 | 
			
		||||
use miner::{Miner, MinerService};
 | 
			
		||||
use snapshot::{self, io as snapshot_io, SnapshotClient};
 | 
			
		||||
use snapshot;
 | 
			
		||||
use spec::Spec;
 | 
			
		||||
use account_state::State;
 | 
			
		||||
use executive_state;
 | 
			
		||||
@ -71,6 +72,8 @@ use types::{
 | 
			
		||||
	block::PreverifiedBlock,
 | 
			
		||||
	block_status::BlockStatus,
 | 
			
		||||
	blockchain_info::BlockChainInfo,
 | 
			
		||||
	client_types::ClientReport,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	encoded,
 | 
			
		||||
	engines::{
 | 
			
		||||
		ForkChoice,
 | 
			
		||||
@ -111,44 +114,6 @@ const MAX_ANCIENT_BLOCKS_TO_IMPORT: usize = 4;
 | 
			
		||||
const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2;
 | 
			
		||||
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 {
 | 
			
		||||
	last_activity: Option<Instant>,
 | 
			
		||||
	last_autosleep: Option<Instant>,
 | 
			
		||||
@ -171,7 +136,7 @@ struct Importer {
 | 
			
		||||
	pub verifier: Box<dyn Verifier<Client>>,
 | 
			
		||||
 | 
			
		||||
	/// Queue containing pending blocks
 | 
			
		||||
	pub block_queue: BlockQueue,
 | 
			
		||||
	pub block_queue: BlockQueue<Client>,
 | 
			
		||||
 | 
			
		||||
	/// Handles block sealing
 | 
			
		||||
	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`.
 | 
			
		||||
	liveness: AtomicBool,
 | 
			
		||||
	io_channel: RwLock<IoChannel<ClientIoMessage>>,
 | 
			
		||||
	io_channel: RwLock<IoChannel<ClientIoMessage<Self>>>,
 | 
			
		||||
 | 
			
		||||
	/// List of actors to be notified on certain chain events
 | 
			
		||||
	notify: RwLock<Vec<Weak<dyn ChainNotify>>>,
 | 
			
		||||
@ -261,7 +226,7 @@ impl Importer {
 | 
			
		||||
	pub fn new(
 | 
			
		||||
		config: &ClientConfig,
 | 
			
		||||
		engine: Arc<dyn Engine>,
 | 
			
		||||
		message_channel: IoChannel<ClientIoMessage>,
 | 
			
		||||
		message_channel: IoChannel<ClientIoMessage<Client>>,
 | 
			
		||||
		miner: Arc<Miner>,
 | 
			
		||||
	) -> Result<Importer, EthcoreError> {
 | 
			
		||||
		let block_queue = BlockQueue::new(
 | 
			
		||||
@ -723,7 +688,7 @@ impl Client {
 | 
			
		||||
		spec: &Spec,
 | 
			
		||||
		db: Arc<dyn BlockChainDB>,
 | 
			
		||||
		miner: Arc<Miner>,
 | 
			
		||||
		message_channel: IoChannel<ClientIoMessage>,
 | 
			
		||||
		message_channel: IoChannel<ClientIoMessage<Self>>,
 | 
			
		||||
	) -> Result<Arc<Client>, EthcoreError> {
 | 
			
		||||
		let trie_spec = match config.fat_db {
 | 
			
		||||
			true => TrieSpec::Fat,
 | 
			
		||||
@ -948,11 +913,6 @@ impl Client {
 | 
			
		||||
		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.
 | 
			
		||||
	fn with_proving_caller<F, T>(&self, id: BlockId, with_call: F) -> T
 | 
			
		||||
		where F: FnOnce(&MachineCall) -> T
 | 
			
		||||
@ -1037,7 +997,7 @@ impl Client {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// 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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -1112,15 +1072,6 @@ impl Client {
 | 
			
		||||
		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) {
 | 
			
		||||
		self.chain.read().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> {
 | 
			
		||||
		match id {
 | 
			
		||||
			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
 | 
			
		||||
	fn restore_db(&self, new_db: &str) -> Result<(), EthcoreError> {
 | 
			
		||||
		trace!(target: "snapshot", "Replacing client database with {:?}", new_db);
 | 
			
		||||
@ -1426,6 +1319,11 @@ impl BlockChainReset for Client {
 | 
			
		||||
 | 
			
		||||
		Ok(())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Ask the client what the history parameter is.
 | 
			
		||||
	fn pruning_history(&self) -> u64 {
 | 
			
		||||
		self.history
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Nonce for Client {
 | 
			
		||||
@ -1547,6 +1445,11 @@ impl ImportBlock for Client {
 | 
			
		||||
			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 {
 | 
			
		||||
@ -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 {
 | 
			
		||||
@ -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`
 | 
			
		||||
/// 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,
 | 
			
		||||
	{
 | 
			
		||||
		let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed);
 | 
			
		||||
 | 
			
		||||
@ -22,15 +22,13 @@ mod client;
 | 
			
		||||
mod config;
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
mod evm_test_client;
 | 
			
		||||
mod io_message;
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
mod test_client;
 | 
			
		||||
 | 
			
		||||
pub use self::client::{Client, ClientReport};
 | 
			
		||||
pub use self::client::Client;
 | 
			
		||||
pub use self::config::{ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType};
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess};
 | 
			
		||||
pub use self::io_message::ClientIoMessage;
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith, TestState};
 | 
			
		||||
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
 | 
			
		||||
 | 
			
		||||
@ -592,6 +592,10 @@ impl ImportBlock for TestBlockChainClient {
 | 
			
		||||
		}
 | 
			
		||||
		Ok(h)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn import_verified_blocks(&self) -> usize {
 | 
			
		||||
		unimplemented!("TestClient does not implement import_verified_blocks()")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
						let _ = client.import_block(block);
 | 
			
		||||
						client.flush_queue();
 | 
			
		||||
						client.import_verified_blocks();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				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 ethereum_types;
 | 
			
		||||
extern crate executive_state;
 | 
			
		||||
extern crate trie_vm_factories;
 | 
			
		||||
extern crate futures;
 | 
			
		||||
extern crate hash_db;
 | 
			
		||||
extern crate itertools;
 | 
			
		||||
@ -77,10 +76,6 @@ extern crate journaldb;
 | 
			
		||||
extern crate keccak_hash as hash;
 | 
			
		||||
extern crate keccak_hasher;
 | 
			
		||||
extern crate kvdb;
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
extern crate kvdb_memorydb;
 | 
			
		||||
 | 
			
		||||
extern crate len_caching_lock;
 | 
			
		||||
extern crate machine;
 | 
			
		||||
extern crate memory_cache;
 | 
			
		||||
extern crate num_cpus;
 | 
			
		||||
@ -92,18 +87,15 @@ extern crate patricia_trie_ethereum as ethtrie;
 | 
			
		||||
extern crate rand;
 | 
			
		||||
extern crate rayon;
 | 
			
		||||
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 spec;
 | 
			
		||||
extern crate state_db;
 | 
			
		||||
extern crate time_utils;
 | 
			
		||||
extern crate trace;
 | 
			
		||||
extern crate trie_vm_factories;
 | 
			
		||||
extern crate triehash_ethereum as triehash;
 | 
			
		||||
extern crate unexpected;
 | 
			
		||||
extern crate using_queue;
 | 
			
		||||
extern crate verification;
 | 
			
		||||
extern crate vm;
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
@ -119,8 +111,8 @@ extern crate ethash;
 | 
			
		||||
extern crate ethkey;
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
extern crate ethjson;
 | 
			
		||||
#[cfg(any(test, feature = "tempdir"))]
 | 
			
		||||
extern crate tempdir;
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
extern crate kvdb_memorydb;
 | 
			
		||||
#[cfg(any(test, feature = "kvdb-rocksdb"))]
 | 
			
		||||
extern crate kvdb_rocksdb;
 | 
			
		||||
#[cfg(any(test, feature = "json-tests"))]
 | 
			
		||||
@ -137,8 +129,12 @@ extern crate pod;
 | 
			
		||||
extern crate blooms_db;
 | 
			
		||||
#[cfg(any(test, feature = "env_logger"))]
 | 
			
		||||
extern crate env_logger;
 | 
			
		||||
#[cfg(any(test, feature = "test-helpers"))]
 | 
			
		||||
extern crate rustc_hex;
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
extern crate serde_json;
 | 
			
		||||
#[cfg(any(test, feature = "tempdir"))]
 | 
			
		||||
extern crate tempdir;
 | 
			
		||||
 | 
			
		||||
#[macro_use]
 | 
			
		||||
extern crate ethabi_contract;
 | 
			
		||||
@ -162,7 +158,6 @@ pub mod block;
 | 
			
		||||
pub mod client;
 | 
			
		||||
pub mod miner;
 | 
			
		||||
pub mod snapshot;
 | 
			
		||||
pub mod verification;
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests;
 | 
			
		||||
 | 
			
		||||
@ -36,36 +36,30 @@ use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache};
 | 
			
		||||
use miner;
 | 
			
		||||
use parking_lot::{Mutex, RwLock};
 | 
			
		||||
use rayon::prelude::*;
 | 
			
		||||
use types::transaction::{
 | 
			
		||||
	self,
 | 
			
		||||
	Action,
 | 
			
		||||
	UnverifiedTransaction,
 | 
			
		||||
	SignedTransaction,
 | 
			
		||||
	PendingTransaction,
 | 
			
		||||
};
 | 
			
		||||
use types::{
 | 
			
		||||
	BlockNumber,
 | 
			
		||||
	ids::TransactionId,
 | 
			
		||||
	block::Block,
 | 
			
		||||
	header::Header,
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	engines::{Seal, SealingState},
 | 
			
		||||
	errors::{EthcoreError as Error, ExecutionError},
 | 
			
		||||
	receipt::RichReceipt,
 | 
			
		||||
	transaction::{
 | 
			
		||||
		self,
 | 
			
		||||
		Action,
 | 
			
		||||
		UnverifiedTransaction,
 | 
			
		||||
		SignedTransaction,
 | 
			
		||||
		PendingTransaction,
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
use using_queue::{UsingQueue, GetAction};
 | 
			
		||||
 | 
			
		||||
use block::{ClosedBlock, SealedBlock};
 | 
			
		||||
use client::{
 | 
			
		||||
	BlockProducer, SealedBlockImporter, ClientIoMessage,
 | 
			
		||||
};
 | 
			
		||||
use client_traits::{
 | 
			
		||||
	BlockChain, ChainInfo, Nonce, TransactionInfo,
 | 
			
		||||
};
 | 
			
		||||
use engine::{
 | 
			
		||||
	Engine,
 | 
			
		||||
	signer::EngineSigner
 | 
			
		||||
};
 | 
			
		||||
use client::{BlockProducer, SealedBlockImporter, Client};
 | 
			
		||||
use client_traits::{BlockChain, ChainInfo, Nonce, TransactionInfo};
 | 
			
		||||
use engine::{Engine, signer::EngineSigner};
 | 
			
		||||
use machine::executive::contract_address;
 | 
			
		||||
use spec::Spec;
 | 
			
		||||
use account_state::State;
 | 
			
		||||
@ -262,7 +256,7 @@ pub struct Miner {
 | 
			
		||||
	transaction_queue: Arc<TransactionQueue>,
 | 
			
		||||
	engine: Arc<dyn Engine>,
 | 
			
		||||
	accounts: Arc<dyn LocalAccounts>,
 | 
			
		||||
	io_channel: RwLock<Option<IoChannel<ClientIoMessage>>>,
 | 
			
		||||
	io_channel: RwLock<Option<IoChannel<ClientIoMessage<Client>>>>,
 | 
			
		||||
	service_transaction_checker: Option<ServiceTransactionChecker>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -346,7 +340,7 @@ impl Miner {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// 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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -1426,7 +1420,7 @@ impl miner::MinerService for Miner {
 | 
			
		||||
				let accounts = self.accounts.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(
 | 
			
		||||
						chain,
 | 
			
		||||
						&nonce_cache,
 | 
			
		||||
@ -1437,7 +1431,7 @@ impl miner::MinerService for Miner {
 | 
			
		||||
					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);
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
@ -221,30 +221,30 @@ impl<'a, C: 'a> CachedNonceClient<'a, C> {
 | 
			
		||||
impl<'a, C: 'a> NonceClient for CachedNonceClient<'a, C> where
 | 
			
		||||
	C: Nonce + Sync,
 | 
			
		||||
{
 | 
			
		||||
  fn account_nonce(&self, address: &Address) -> U256 {
 | 
			
		||||
	  if let Some(nonce) = self.cache.nonces.read().get(address) {
 | 
			
		||||
		  return *nonce;
 | 
			
		||||
	  }
 | 
			
		||||
	fn account_nonce(&self, address: &Address) -> U256 {
 | 
			
		||||
		if let Some(nonce) = self.cache.nonces.read().get(address) {
 | 
			
		||||
			return *nonce;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	  // We don't check again if cache has been populated.
 | 
			
		||||
	  // It's not THAT expensive to fetch the nonce from state.
 | 
			
		||||
	  let mut cache = self.cache.nonces.write();
 | 
			
		||||
	  let nonce = self.client.latest_nonce(address);
 | 
			
		||||
	  cache.insert(*address, nonce);
 | 
			
		||||
		// We don't check again if cache has been populated.
 | 
			
		||||
		// It's not THAT expensive to fetch the nonce from state.
 | 
			
		||||
		let mut cache = self.cache.nonces.write();
 | 
			
		||||
		let nonce = self.client.latest_nonce(address);
 | 
			
		||||
		cache.insert(*address, nonce);
 | 
			
		||||
 | 
			
		||||
	  if cache.len() < self.cache.limit {
 | 
			
		||||
		  return nonce
 | 
			
		||||
	  }
 | 
			
		||||
		if cache.len() < self.cache.limit {
 | 
			
		||||
			return nonce
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	  debug!(target: "txpool", "NonceCache: reached limit.");
 | 
			
		||||
	  trace_time!("nonce_cache:clear");
 | 
			
		||||
		debug!(target: "txpool", "NonceCache: reached limit.");
 | 
			
		||||
		trace_time!("nonce_cache:clear");
 | 
			
		||||
 | 
			
		||||
	  // Remove excessive amount of entries from the cache
 | 
			
		||||
	  let to_remove: Vec<_> = cache.keys().take(self.cache.limit / 2).cloned().collect();
 | 
			
		||||
	  for x in to_remove {
 | 
			
		||||
		cache.remove(&x);
 | 
			
		||||
	  }
 | 
			
		||||
		// Remove excessive amount of entries from the cache
 | 
			
		||||
		let to_remove: Vec<_> = cache.keys().take(self.cache.limit / 2).cloned().collect();
 | 
			
		||||
		for x in to_remove {
 | 
			
		||||
			cache.remove(&x);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	  nonce
 | 
			
		||||
  }
 | 
			
		||||
		nonce
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ use std::fs::{self, File};
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
 | 
			
		||||
use bytes::Bytes;
 | 
			
		||||
use client_traits::SnapshotWriter;
 | 
			
		||||
use ethereum_types::H256;
 | 
			
		||||
use rlp::{RlpStream, Rlp};
 | 
			
		||||
use types::{
 | 
			
		||||
@ -35,20 +36,6 @@ use types::{
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
#[derive(RlpEncodable, RlpDecodable)]
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,8 @@ use bloom_journal::Bloom;
 | 
			
		||||
use num_cpus;
 | 
			
		||||
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 account_state::Account as StateAccount;
 | 
			
		||||
@ -58,7 +59,7 @@ use crossbeam_utils::thread;
 | 
			
		||||
use rand::{Rng, rngs::OsRng};
 | 
			
		||||
 | 
			
		||||
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::watcher::Watcher;
 | 
			
		||||
pub use types::basic_account::BasicAccount;
 | 
			
		||||
 | 
			
		||||
@ -29,16 +29,21 @@ use super::{
 | 
			
		||||
	SnapshotService,
 | 
			
		||||
	Rebuilder,
 | 
			
		||||
	MAX_CHUNK_SIZE,
 | 
			
		||||
	io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter},
 | 
			
		||||
	io::{SnapshotReader, LooseReader,  LooseWriter},
 | 
			
		||||
	chunker,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler};
 | 
			
		||||
use client::{Client, ClientIoMessage};
 | 
			
		||||
use client_traits::{BlockInfo, BlockChainClient, ChainInfo};
 | 
			
		||||
use client::Client;
 | 
			
		||||
// todo[dvdplm] put SnapshotWriter back in snapshots once extracted
 | 
			
		||||
use client_traits::{
 | 
			
		||||
	BlockInfo, BlockChainClient, ChainInfo,
 | 
			
		||||
	SnapshotClient, SnapshotWriter, DatabaseRestore,
 | 
			
		||||
};
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use hash::keccak;
 | 
			
		||||
use types::{
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	errors::{EthcoreError as Error, SnapshotError, SnapshotError::UnlinkedAncientBlockChain},
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	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.
 | 
			
		||||
struct Restoration {
 | 
			
		||||
	manifest: ManifestData,
 | 
			
		||||
@ -213,10 +212,7 @@ impl Restoration {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Type alias for client io channel.
 | 
			
		||||
pub type Channel = IoChannel<ClientIoMessage>;
 | 
			
		||||
 | 
			
		||||
/// Trait alias for the Client Service used
 | 
			
		||||
pub trait SnapshotClient: BlockChainClient + BlockInfo + DatabaseRestore {}
 | 
			
		||||
pub type Channel = IoChannel<ClientIoMessage<Client>>;
 | 
			
		||||
 | 
			
		||||
/// Snapshot service parameters.
 | 
			
		||||
pub struct ServiceParams {
 | 
			
		||||
@ -234,7 +230,7 @@ pub struct ServiceParams {
 | 
			
		||||
	/// Usually "<chain hash>/snapshot"
 | 
			
		||||
	pub snapshot_root: PathBuf,
 | 
			
		||||
	/// A handle for database restoration.
 | 
			
		||||
	pub client: Arc<dyn SnapshotClient>,
 | 
			
		||||
	pub client: Arc<Client>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// `SnapshotService` implementation.
 | 
			
		||||
@ -251,7 +247,7 @@ pub struct Service {
 | 
			
		||||
	genesis_block: Bytes,
 | 
			
		||||
	state_chunks: AtomicUsize,
 | 
			
		||||
	block_chunks: AtomicUsize,
 | 
			
		||||
	client: Arc<dyn SnapshotClient>,
 | 
			
		||||
	client: Arc<Client>,
 | 
			
		||||
	progress: Progress,
 | 
			
		||||
	taking_snapshot: AtomicBool,
 | 
			
		||||
	restoring_snapshot: AtomicBool,
 | 
			
		||||
@ -483,7 +479,10 @@ impl Service {
 | 
			
		||||
	/// calling this while a restoration is in progress or vice versa
 | 
			
		||||
	/// will lead to a race condition where the first one to finish will
 | 
			
		||||
	/// 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) {
 | 
			
		||||
			info!("Skipping snapshot at #{} as another one is currently in-progress.", num);
 | 
			
		||||
			return Ok(());
 | 
			
		||||
@ -905,13 +904,16 @@ impl Drop for Service {
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
	use client::ClientIoMessage;
 | 
			
		||||
	use client::Client;
 | 
			
		||||
	use io::{IoService};
 | 
			
		||||
	use spec;
 | 
			
		||||
	use journaldb::Algorithm;
 | 
			
		||||
	use snapshot::SnapshotService;
 | 
			
		||||
	use super::*;
 | 
			
		||||
	use types::snapshot::{ManifestData, RestorationStatus};
 | 
			
		||||
	use types::{
 | 
			
		||||
		io_message::ClientIoMessage,
 | 
			
		||||
		snapshot::{ManifestData, RestorationStatus}
 | 
			
		||||
	};
 | 
			
		||||
	use tempdir::TempDir;
 | 
			
		||||
	use test_helpers::{generate_dummy_client_with_spec_and_data, restoration_db_handler};
 | 
			
		||||
 | 
			
		||||
@ -919,7 +921,7 @@ mod tests {
 | 
			
		||||
	fn sends_async_messages() {
 | 
			
		||||
		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 service = IoService::<ClientIoMessage>::start().unwrap();
 | 
			
		||||
		let service = IoService::<ClientIoMessage<Client>>::start().unwrap();
 | 
			
		||||
		let spec = spec::new_test();
 | 
			
		||||
 | 
			
		||||
		let tempdir = TempDir::new("").unwrap();
 | 
			
		||||
@ -932,7 +934,7 @@ mod tests {
 | 
			
		||||
			pruning: Algorithm::Archive,
 | 
			
		||||
			channel: service.channel(),
 | 
			
		||||
			snapshot_root: dir,
 | 
			
		||||
			client: client,
 | 
			
		||||
			client,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		let service = Service::new(snapshot_params).unwrap();
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ use account_db::AccountDBMut;
 | 
			
		||||
use types::basic_account::BasicAccount;
 | 
			
		||||
use blockchain::{BlockChain, BlockChainDB};
 | 
			
		||||
use client::Client;
 | 
			
		||||
use client_traits::ChainInfo;
 | 
			
		||||
use client_traits::{ChainInfo, SnapshotClient};
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use snapshot::{StateRebuilder};
 | 
			
		||||
use snapshot::io::{SnapshotReader, PackedWriter, PackedReader};
 | 
			
		||||
 | 
			
		||||
@ -26,8 +26,9 @@ use types::{
 | 
			
		||||
 | 
			
		||||
use blockchain::generator::{BlockGenerator, BlockBuilder};
 | 
			
		||||
use blockchain::{BlockChain, ExtrasInsert};
 | 
			
		||||
use client_traits::SnapshotWriter;
 | 
			
		||||
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 snappy;
 | 
			
		||||
 | 
			
		||||
@ -22,14 +22,14 @@ use std::sync::Arc;
 | 
			
		||||
use tempdir::TempDir;
 | 
			
		||||
use blockchain::BlockProvider;
 | 
			
		||||
use client::{Client, ClientConfig};
 | 
			
		||||
use client_traits::{BlockInfo, ImportBlock};
 | 
			
		||||
use client_traits::{BlockInfo, ImportBlock, SnapshotWriter};
 | 
			
		||||
use types::{
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	snapshot::Progress,
 | 
			
		||||
	verification::Unverified,
 | 
			
		||||
	snapshot::{ManifestData, RestorationStatus},
 | 
			
		||||
};
 | 
			
		||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
 | 
			
		||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader};
 | 
			
		||||
use snapshot::service::{Service, ServiceParams};
 | 
			
		||||
use snapshot::{chunk_state, chunk_secondary, SnapshotService};
 | 
			
		||||
use spec;
 | 
			
		||||
@ -77,7 +77,7 @@ fn restored_is_equivalent() {
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	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();
 | 
			
		||||
 | 
			
		||||
@ -226,7 +226,6 @@ fn keep_ancient_blocks() {
 | 
			
		||||
		client2.import_block(Unverified::from_rlp(block.into_inner()).unwrap()).unwrap();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client2.import_verified_blocks();
 | 
			
		||||
	client2.flush_queue();
 | 
			
		||||
 | 
			
		||||
	// Restore the Snapshot
 | 
			
		||||
@ -304,7 +303,7 @@ fn recover_aborted_recovery() {
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	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();
 | 
			
		||||
	service.init_restore(manifest.clone(), true).unwrap();
 | 
			
		||||
 | 
			
		||||
@ -24,9 +24,10 @@ use types::{
 | 
			
		||||
	basic_account::BasicAccount,
 | 
			
		||||
	errors::EthcoreError as Error,
 | 
			
		||||
};
 | 
			
		||||
use client_traits::SnapshotWriter;
 | 
			
		||||
use snapshot::account;
 | 
			
		||||
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 rand::SeedableRng;
 | 
			
		||||
use rand_xorshift::XorShiftRng;
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,12 @@
 | 
			
		||||
//! Watcher for snapshot-related chain events.
 | 
			
		||||
 | 
			
		||||
use parking_lot::Mutex;
 | 
			
		||||
use client::{Client, ChainNotify, NewBlocks, ClientIoMessage};
 | 
			
		||||
use client::{Client, ChainNotify, NewBlocks};
 | 
			
		||||
use client_traits::BlockInfo;
 | 
			
		||||
use types::ids::BlockId;
 | 
			
		||||
use types::{
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use io::IoChannel;
 | 
			
		||||
use ethereum_types::H256;
 | 
			
		||||
@ -55,7 +58,7 @@ trait Broadcast: Send + Sync {
 | 
			
		||||
	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>) {
 | 
			
		||||
		let num = match num {
 | 
			
		||||
			Some(n) => n,
 | 
			
		||||
@ -83,7 +86,7 @@ impl Watcher {
 | 
			
		||||
	/// Create a new `Watcher` which will trigger a snapshot event
 | 
			
		||||
	/// once every `period` blocks, but only after that block is
 | 
			
		||||
	/// `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
 | 
			
		||||
	{
 | 
			
		||||
		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;
 | 
			
		||||
	}
 | 
			
		||||
	client.flush_queue();
 | 
			
		||||
	client.import_verified_blocks();
 | 
			
		||||
	client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -239,7 +238,6 @@ pub fn push_block_with_transactions(client: &Arc<Client>, transactions: &[Signed
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client.flush_queue();
 | 
			
		||||
	client.import_verified_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.import_verified_blocks();
 | 
			
		||||
	client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,10 @@ use types::{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 machine::executive::{Executive, TransactOptions};
 | 
			
		||||
use miner::{Miner, PendingOrdering, MinerService};
 | 
			
		||||
@ -55,7 +58,6 @@ fn imports_from_empty() {
 | 
			
		||||
		Arc::new(Miner::new_for_tests(&spec, None)),
 | 
			
		||||
		IoChannel::disconnected(),
 | 
			
		||||
	).unwrap();
 | 
			
		||||
	client.import_verified_blocks();
 | 
			
		||||
	client.flush_queue();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -102,7 +104,6 @@ fn imports_good_block() {
 | 
			
		||||
		panic!("error importing block being good by definition");
 | 
			
		||||
	}
 | 
			
		||||
	client.flush_queue();
 | 
			
		||||
	client.import_verified_blocks();
 | 
			
		||||
 | 
			
		||||
	let block = client.block_header(BlockId::Number(1)).unwrap();
 | 
			
		||||
	assert!(!block.into_inner().is_empty());
 | 
			
		||||
 | 
			
		||||
@ -181,7 +181,6 @@ fn can_trace_block_and_uncle_reward() {
 | 
			
		||||
 | 
			
		||||
	block.drain();
 | 
			
		||||
	client.flush_queue();
 | 
			
		||||
	client.import_verified_blocks();
 | 
			
		||||
 | 
			
		||||
	// Test0. Check overall filter
 | 
			
		||||
	let filter = TraceFilter {
 | 
			
		||||
 | 
			
		||||
@ -20,11 +20,14 @@ use ethereum_types::{U256, Address};
 | 
			
		||||
use io::{IoHandler, IoChannel};
 | 
			
		||||
use client_traits::ChainInfo;
 | 
			
		||||
use engine::signer;
 | 
			
		||||
use ethcore::client::{ClientIoMessage};
 | 
			
		||||
use spec;
 | 
			
		||||
use ethcore::client::Client;
 | 
			
		||||
use ethcore::miner::{self, MinerService};
 | 
			
		||||
use ethkey::{KeyPair, Secret};
 | 
			
		||||
use types::transaction::{Action, PendingTransaction, Transaction};
 | 
			
		||||
use types::{
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	transaction::{Action, PendingTransaction, Transaction}
 | 
			
		||||
};
 | 
			
		||||
use super::helpers::*;
 | 
			
		||||
use SyncConfig;
 | 
			
		||||
 | 
			
		||||
@ -47,8 +50,8 @@ fn authority_round() {
 | 
			
		||||
 | 
			
		||||
	let chain_id = spec::new_test_round().chain_id();
 | 
			
		||||
	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_handler1: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).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<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.
 | 
			
		||||
	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())));
 | 
			
		||||
@ -115,7 +118,7 @@ fn authority_round() {
 | 
			
		||||
	net.peer(1).chain.engine().step();
 | 
			
		||||
	net.peer(1).chain.engine().step();
 | 
			
		||||
	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();
 | 
			
		||||
	let ci0 = net.peer(0).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::client_version::ClientVersion;
 | 
			
		||||
use tests::snapshot::*;
 | 
			
		||||
use types::io_message::ClientIoMessage;
 | 
			
		||||
use client_traits::BlockChainClient;
 | 
			
		||||
use ethcore::client::{TestBlockChainClient, Client as EthcoreClient,
 | 
			
		||||
	ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage};
 | 
			
		||||
	ClientConfig, ChainNotify, NewBlocks, ChainMessageType};
 | 
			
		||||
use ethcore::snapshot::SnapshotService;
 | 
			
		||||
use spec::{self, Spec};
 | 
			
		||||
use ethcore_private_tx::PrivateStateDB;
 | 
			
		||||
@ -554,8 +555,8 @@ impl TestIoHandler {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl IoHandler<ClientIoMessage> for TestIoHandler {
 | 
			
		||||
	fn message(&self, _io: &IoContext<ClientIoMessage>, net_message: &ClientIoMessage) {
 | 
			
		||||
impl IoHandler<ClientIoMessage<EthcoreClient>> for TestIoHandler {
 | 
			
		||||
	fn message(&self, _io: &IoContext<ClientIoMessage<EthcoreClient>>, net_message: &ClientIoMessage<EthcoreClient>) {
 | 
			
		||||
		match *net_message {
 | 
			
		||||
			ClientIoMessage::Execute(ref exec) => {
 | 
			
		||||
				*self.private_tx_queued.lock() += 1;
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,15 @@ use std::sync::Arc;
 | 
			
		||||
use hash::keccak;
 | 
			
		||||
use io::{IoHandler, IoChannel};
 | 
			
		||||
use types::transaction::{Transaction, Action};
 | 
			
		||||
use types::ids::BlockId;
 | 
			
		||||
use types::{
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
};
 | 
			
		||||
use client_traits::BlockChainClient;
 | 
			
		||||
use engine::signer;
 | 
			
		||||
use ethcore::{
 | 
			
		||||
	client::Client,
 | 
			
		||||
	CreateContractAddress,
 | 
			
		||||
	client::ClientIoMessage,
 | 
			
		||||
	miner::{self, MinerService},
 | 
			
		||||
	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 client0 = net.peer(0).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_handler1: Arc<dyn IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).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<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(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 chain_id = client0.signing_chain_id();
 | 
			
		||||
 | 
			
		||||
	// Exhange statuses
 | 
			
		||||
	// Exchange statuses
 | 
			
		||||
	net.sync();
 | 
			
		||||
 | 
			
		||||
	// Setup private providers
 | 
			
		||||
@ -173,8 +176,8 @@ fn sync_private_state() {
 | 
			
		||||
	let mut net = TestNet::with_spec(2, SyncConfig::default(), seal_spec);
 | 
			
		||||
	let client0 = net.peer(0).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_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler::new(net.peer(1).chain.clone()));
 | 
			
		||||
	let io_handler0: Arc<IoHandler<ClientIoMessage<Client>>> = Arc::new(TestIoHandler::new(net.peer(0).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(1).miner.set_author(miner::Author::Sealer(signer::from_keypair(s1.clone())));
 | 
			
		||||
 | 
			
		||||
@ -18,8 +18,12 @@
 | 
			
		||||
 | 
			
		||||
use std::{
 | 
			
		||||
	fmt::{Display, Formatter, Error as FmtError},
 | 
			
		||||
	ops,
 | 
			
		||||
	cmp,
 | 
			
		||||
	time::Duration,
 | 
			
		||||
};
 | 
			
		||||
use ethereum_types::U256;
 | 
			
		||||
use crate::header::Header;
 | 
			
		||||
 | 
			
		||||
/// Operating mode for the client.
 | 
			
		||||
#[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
 | 
			
		||||
// 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 bytes::Bytes;
 | 
			
		||||
use client::Client;
 | 
			
		||||
use ethereum_types::H256;
 | 
			
		||||
use types::snapshot::ManifestData;
 | 
			
		||||
use crate::snapshot::ManifestData;
 | 
			
		||||
 | 
			
		||||
/// Message type for external and internal events
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum ClientIoMessage {
 | 
			
		||||
pub enum ClientIoMessage<C> {
 | 
			
		||||
	/// Best Block Hash in chain has been changed
 | 
			
		||||
	NewChainHead,
 | 
			
		||||
	/// A block is ready
 | 
			
		||||
@ -36,20 +38,20 @@ pub enum ClientIoMessage {
 | 
			
		||||
	/// Take a snapshot for the block with given number.
 | 
			
		||||
	TakeSnapshot(u64),
 | 
			
		||||
	/// Execute wrapped closure
 | 
			
		||||
	Execute(Callback),
 | 
			
		||||
	Execute(Callback<C>),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ClientIoMessage {
 | 
			
		||||
impl<C> ClientIoMessage<C> {
 | 
			
		||||
	/// 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)))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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 {
 | 
			
		||||
		write!(fmt, "<callback>")
 | 
			
		||||
	}
 | 
			
		||||
@ -71,6 +71,7 @@ pub mod errors;
 | 
			
		||||
pub mod filter;
 | 
			
		||||
pub mod header;
 | 
			
		||||
pub mod ids;
 | 
			
		||||
pub mod io_message;
 | 
			
		||||
pub mod log_entry;
 | 
			
		||||
pub mod pruning_info;
 | 
			
		||||
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 client_traits::BlockInfo;
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use types::{
 | 
			
		||||
use common_types::{
 | 
			
		||||
	header::Header,
 | 
			
		||||
	errors::EthcoreError as Error,
 | 
			
		||||
};
 | 
			
		||||
@ -18,6 +18,8 @@
 | 
			
		||||
 | 
			
		||||
use call_contract::CallContract;
 | 
			
		||||
use client_traits::BlockInfo;
 | 
			
		||||
// The MallocSizeOf derive looks for this in the root
 | 
			
		||||
use parity_util_mem as malloc_size_of;
 | 
			
		||||
 | 
			
		||||
mod verification;
 | 
			
		||||
mod verifier;
 | 
			
		||||
@ -29,11 +31,6 @@ pub use self::verification::FullFamilyParams;
 | 
			
		||||
pub use self::verifier::Verifier;
 | 
			
		||||
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::noop_verifier::NoopVerifier;
 | 
			
		||||
 | 
			
		||||
@ -18,11 +18,11 @@
 | 
			
		||||
 | 
			
		||||
use call_contract::CallContract;
 | 
			
		||||
use client_traits::BlockInfo;
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use types::{
 | 
			
		||||
use common_types::{
 | 
			
		||||
	header::Header,
 | 
			
		||||
	errors::EthcoreError as Error
 | 
			
		||||
};
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use super::{verification, Verifier};
 | 
			
		||||
 | 
			
		||||
/// 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 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::headers::Headers;
 | 
			
		||||
@ -70,12 +70,13 @@ pub mod blocks {
 | 
			
		||||
	use super::{Kind, BlockLike};
 | 
			
		||||
 | 
			
		||||
	use engine::Engine;
 | 
			
		||||
	use types::{
 | 
			
		||||
	use common_types::{
 | 
			
		||||
		block::PreverifiedBlock,
 | 
			
		||||
		errors::{EthcoreError as Error, BlockError},
 | 
			
		||||
		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};
 | 
			
		||||
 | 
			
		||||
@ -147,11 +148,11 @@ pub mod headers {
 | 
			
		||||
	use super::{Kind, BlockLike};
 | 
			
		||||
 | 
			
		||||
	use engine::Engine;
 | 
			
		||||
	use types::{
 | 
			
		||||
	use common_types::{
 | 
			
		||||
		header::Header,
 | 
			
		||||
		errors::EthcoreError as Error,
 | 
			
		||||
	};
 | 
			
		||||
	use verification::verify_header_params;
 | 
			
		||||
	use crate::verification::verify_header_params;
 | 
			
		||||
 | 
			
		||||
	use ethereum_types::{H256, U256};
 | 
			
		||||
 | 
			
		||||
@ -22,17 +22,19 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering};
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use std::cmp;
 | 
			
		||||
use std::collections::{VecDeque, HashSet, HashMap};
 | 
			
		||||
use parity_util_mem::{MallocSizeOf, MallocSizeOfExt};
 | 
			
		||||
use ethereum_types::{H256, U256};
 | 
			
		||||
use parking_lot::{Condvar, Mutex, RwLock};
 | 
			
		||||
use io::*;
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use client::ClientIoMessage;
 | 
			
		||||
use len_caching_lock::LenCachingMutex;
 | 
			
		||||
use types::{
 | 
			
		||||
use common_types::{
 | 
			
		||||
	block_status::BlockStatus,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	errors::{BlockError, EthcoreError as Error, ImportError},
 | 
			
		||||
	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};
 | 
			
		||||
 | 
			
		||||
@ -42,10 +44,10 @@ const MIN_MEM_LIMIT: usize = 16384;
 | 
			
		||||
const MIN_QUEUE_LIMIT: usize = 512;
 | 
			
		||||
 | 
			
		||||
/// 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.
 | 
			
		||||
pub type HeaderQueue = VerificationQueue<self::kind::Headers>;
 | 
			
		||||
pub type HeaderQueue<C> = VerificationQueue<self::kind::Headers, C>;
 | 
			
		||||
 | 
			
		||||
/// Verification queue configuration
 | 
			
		||||
#[derive(Debug, PartialEq, Clone)]
 | 
			
		||||
@ -84,7 +86,7 @@ impl Default for VerifierSettings {
 | 
			
		||||
	fn default() -> Self {
 | 
			
		||||
		VerifierSettings {
 | 
			
		||||
			scale_verifiers: false,
 | 
			
		||||
			num_verifiers: ::num_cpus::get(),
 | 
			
		||||
			num_verifiers: num_cpus::get(),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -113,9 +115,8 @@ pub enum Status {
 | 
			
		||||
	Unknown,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Into<::types::block_status::BlockStatus> for Status {
 | 
			
		||||
	fn into(self) -> ::types::block_status::BlockStatus {
 | 
			
		||||
		use ::types::block_status::BlockStatus;
 | 
			
		||||
impl Into<BlockStatus> for Status {
 | 
			
		||||
	fn into(self) -> BlockStatus {
 | 
			
		||||
		match self {
 | 
			
		||||
			Status::Queued => BlockStatus::Queued,
 | 
			
		||||
			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`.
 | 
			
		||||
/// 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>,
 | 
			
		||||
	more_to_verify: Arc<Condvar>,
 | 
			
		||||
	verification: Arc<Verification<K>>,
 | 
			
		||||
	deleting: Arc<AtomicBool>,
 | 
			
		||||
	ready_signal: Arc<QueueSignal>,
 | 
			
		||||
	ready_signal: Arc<QueueSignal<C>>,
 | 
			
		||||
	empty: Arc<Condvar>,
 | 
			
		||||
	processing: RwLock<HashMap<H256, U256>>, // hash to difficulty
 | 
			
		||||
	ticks_since_adjustment: AtomicUsize,
 | 
			
		||||
@ -150,13 +151,13 @@ pub struct VerificationQueue<K: Kind> {
 | 
			
		||||
	total_difficulty: RwLock<U256>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct QueueSignal {
 | 
			
		||||
struct QueueSignal<C: 'static> {
 | 
			
		||||
	deleting: Arc<AtomicBool>,
 | 
			
		||||
	signalled: AtomicBool,
 | 
			
		||||
	message_channel: Mutex<IoChannel<ClientIoMessage>>,
 | 
			
		||||
	message_channel: Mutex<IoChannel<ClientIoMessage<C>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl QueueSignal {
 | 
			
		||||
impl<C> QueueSignal<C> {
 | 
			
		||||
	fn set_sync(&self) {
 | 
			
		||||
		// Do not signal when we are about to close
 | 
			
		||||
		if self.deleting.load(AtomicOrdering::Relaxed) {
 | 
			
		||||
@ -200,9 +201,9 @@ struct Verification<K: Kind> {
 | 
			
		||||
	check_seal: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<K: Kind> VerificationQueue<K> {
 | 
			
		||||
impl<K: Kind, C> VerificationQueue<K, C> {
 | 
			
		||||
	/// 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 {
 | 
			
		||||
			unverified: LenCachingMutex::new(VecDeque::new()),
 | 
			
		||||
			verifying: LenCachingMutex::new(VecDeque::new()),
 | 
			
		||||
@ -213,7 +214,7 @@ impl<K: Kind> VerificationQueue<K> {
 | 
			
		||||
				verifying: AtomicUsize::new(0),
 | 
			
		||||
				verified: AtomicUsize::new(0),
 | 
			
		||||
			},
 | 
			
		||||
			check_seal: check_seal,
 | 
			
		||||
			check_seal,
 | 
			
		||||
		});
 | 
			
		||||
		let more_to_verify = Arc::new(Condvar::new());
 | 
			
		||||
		let deleting = Arc::new(AtomicBool::new(false));
 | 
			
		||||
@ -270,19 +271,19 @@ impl<K: Kind> VerificationQueue<K> {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		VerificationQueue {
 | 
			
		||||
			engine: engine,
 | 
			
		||||
			ready_signal: ready_signal,
 | 
			
		||||
			more_to_verify: more_to_verify,
 | 
			
		||||
			verification: verification,
 | 
			
		||||
			deleting: deleting,
 | 
			
		||||
			engine,
 | 
			
		||||
			ready_signal,
 | 
			
		||||
			more_to_verify,
 | 
			
		||||
			verification,
 | 
			
		||||
			deleting,
 | 
			
		||||
			processing: RwLock::new(HashMap::new()),
 | 
			
		||||
			empty: empty,
 | 
			
		||||
			empty,
 | 
			
		||||
			ticks_since_adjustment: AtomicUsize::new(0),
 | 
			
		||||
			max_queue_size: cmp::max(config.max_queue_size, MIN_QUEUE_LIMIT),
 | 
			
		||||
			max_mem_use: cmp::max(config.max_mem_use, MIN_MEM_LIMIT),
 | 
			
		||||
			scale_verifiers: scale_verifiers,
 | 
			
		||||
			verifier_handles: verifier_handles,
 | 
			
		||||
			state: state,
 | 
			
		||||
			scale_verifiers,
 | 
			
		||||
			verifier_handles,
 | 
			
		||||
			state,
 | 
			
		||||
			total_difficulty: RwLock::new(0.into()),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -291,7 +292,7 @@ impl<K: Kind> VerificationQueue<K> {
 | 
			
		||||
		verification: Arc<Verification<K>>,
 | 
			
		||||
		engine: Arc<dyn Engine>,
 | 
			
		||||
		wait: Arc<Condvar>,
 | 
			
		||||
		ready: Arc<QueueSignal>,
 | 
			
		||||
		ready: Arc<QueueSignal<C>>,
 | 
			
		||||
		empty: Arc<Condvar>,
 | 
			
		||||
		state: Arc<(Mutex<State>, Condvar)>,
 | 
			
		||||
		id: usize,
 | 
			
		||||
@ -373,7 +374,7 @@ impl<K: Kind> VerificationQueue<K> {
 | 
			
		||||
						// we're next!
 | 
			
		||||
						let mut verified = verification.verified.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
 | 
			
		||||
					} else {
 | 
			
		||||
						false
 | 
			
		||||
@ -388,7 +389,7 @@ impl<K: Kind> VerificationQueue<K> {
 | 
			
		||||
					verifying.retain(|e| e.hash != hash);
 | 
			
		||||
 | 
			
		||||
					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
 | 
			
		||||
					} else {
 | 
			
		||||
						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) {
 | 
			
		||||
		trace!(target: "shutdown", "[VerificationQueue] Closing...");
 | 
			
		||||
		self.clear();
 | 
			
		||||
@ -734,11 +735,12 @@ impl<K: Kind> Drop for VerificationQueue<K> {
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
	use io::*;
 | 
			
		||||
	use ethcore_io::*;
 | 
			
		||||
	use super::{BlockQueue, Config, State};
 | 
			
		||||
	use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
 | 
			
		||||
	use bytes::Bytes;
 | 
			
		||||
	use types::{
 | 
			
		||||
	use ethcore::test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
 | 
			
		||||
	use ethcore::client::Client;
 | 
			
		||||
	use parity_bytes::Bytes;
 | 
			
		||||
	use common_types::{
 | 
			
		||||
		errors::{EthcoreError, ImportError},
 | 
			
		||||
		verification::Unverified,
 | 
			
		||||
		view,
 | 
			
		||||
@ -748,7 +750,7 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
	// create a test block queue.
 | 
			
		||||
	// 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 engine = spec.engine;
 | 
			
		||||
 | 
			
		||||
@ -773,7 +775,7 @@ mod tests {
 | 
			
		||||
		// TODO better test
 | 
			
		||||
		let spec = spec::new_test();
 | 
			
		||||
		let engine = spec.engine;
 | 
			
		||||
		let _ = BlockQueue::new(Config::default(), engine, IoChannel::disconnected(), true);
 | 
			
		||||
		let _ = BlockQueue::<Client>::new(Config::default(), engine, IoChannel::disconnected(), true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
@ -853,7 +855,7 @@ mod tests {
 | 
			
		||||
		let engine = spec.engine;
 | 
			
		||||
		let mut config = Config::default();
 | 
			
		||||
		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());
 | 
			
		||||
		let mut blocks = get_good_dummy_block_seq(50);
 | 
			
		||||
		for b in blocks.drain(..) {
 | 
			
		||||
@ -903,7 +905,7 @@ mod tests {
 | 
			
		||||
			let spec = spec::new_test();
 | 
			
		||||
			let engine = spec.engine;
 | 
			
		||||
			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);
 | 
			
		||||
		}
 | 
			
		||||
@ -913,7 +915,7 @@ mod tests {
 | 
			
		||||
			let spec = spec::new_test();
 | 
			
		||||
			let engine = spec.engine;
 | 
			
		||||
			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);
 | 
			
		||||
		}
 | 
			
		||||
@ -923,7 +925,7 @@ mod tests {
 | 
			
		||||
			let spec = spec::new_test();
 | 
			
		||||
			let engine = spec.engine;
 | 
			
		||||
			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();
 | 
			
		||||
 | 
			
		||||
			assert_eq!(queue.num_verifiers(), num_cpus);
 | 
			
		||||
@ -937,7 +939,7 @@ mod tests {
 | 
			
		||||
				let spec = spec::new_test();
 | 
			
		||||
				let engine = spec.engine;
 | 
			
		||||
				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);
 | 
			
		||||
 | 
			
		||||
				assert_eq!(queue.num_verifiers(), num_cpus);
 | 
			
		||||
@ -24,7 +24,7 @@
 | 
			
		||||
use std::collections::HashSet;
 | 
			
		||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
 | 
			
		||||
 | 
			
		||||
use hash::keccak;
 | 
			
		||||
use keccak_hash::keccak;
 | 
			
		||||
use rlp::Rlp;
 | 
			
		||||
use triehash::ordered_trie_root;
 | 
			
		||||
use unexpected::{Mismatch, OutOfBounds};
 | 
			
		||||
@ -33,7 +33,7 @@ use blockchain::*;
 | 
			
		||||
use call_contract::CallContract;
 | 
			
		||||
use client_traits::BlockInfo;
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use types::{
 | 
			
		||||
use common_types::{
 | 
			
		||||
	BlockNumber,
 | 
			
		||||
	header::Header,
 | 
			
		||||
	errors::{EthcoreError as Error, BlockError},
 | 
			
		||||
@ -366,15 +366,19 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
	use std::collections::{BTreeMap, HashMap};
 | 
			
		||||
	use std::time::{SystemTime, UNIX_EPOCH};
 | 
			
		||||
 | 
			
		||||
	use ethereum_types::{H256, BloomRef, U256, Address};
 | 
			
		||||
	use blockchain::{BlockDetails, TransactionAddress, BlockReceipts};
 | 
			
		||||
	use bytes::Bytes;
 | 
			
		||||
	use hash::keccak;
 | 
			
		||||
	use parity_bytes::Bytes;
 | 
			
		||||
	use keccak_hash::keccak;
 | 
			
		||||
	use engine::Engine;
 | 
			
		||||
	use ethkey::{Random, Generator};
 | 
			
		||||
	use spec;
 | 
			
		||||
	use test_helpers::{create_test_block_with_data, create_test_block};
 | 
			
		||||
	use types::{
 | 
			
		||||
	use ethcore::{
 | 
			
		||||
		client::TestBlockChainClient,
 | 
			
		||||
		test_helpers::{create_test_block_with_data, create_test_block}
 | 
			
		||||
	};
 | 
			
		||||
	use common_types::{
 | 
			
		||||
		encoded,
 | 
			
		||||
		engines::params::CommonParams,
 | 
			
		||||
		errors::BlockError::*,
 | 
			
		||||
@ -383,6 +387,8 @@ mod tests {
 | 
			
		||||
	};
 | 
			
		||||
	use rlp;
 | 
			
		||||
	use triehash::ordered_trie_root;
 | 
			
		||||
	use machine::Machine;
 | 
			
		||||
	use null_engine::NullEngine;
 | 
			
		||||
 | 
			
		||||
	fn check_ok(result: Result<(), Error>) {
 | 
			
		||||
		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)
 | 
			
		||||
		// no existing tests need access to test, so having this not function
 | 
			
		||||
		// is fine.
 | 
			
		||||
		let client = ::client::TestBlockChainClient::default();
 | 
			
		||||
		let client = TestBlockChainClient::default();
 | 
			
		||||
		let parent = bc.block_header_data(header.parent_hash())
 | 
			
		||||
			.ok_or(BlockError::UnknownParent(*header.parent_hash()))?
 | 
			
		||||
			.decode()?;
 | 
			
		||||
@ -779,11 +785,6 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	fn dust_protection() {
 | 
			
		||||
		use ethkey::{Generator, Random};
 | 
			
		||||
		use types::transaction::{Transaction, Action};
 | 
			
		||||
		use machine::Machine;
 | 
			
		||||
		use null_engine::NullEngine;
 | 
			
		||||
 | 
			
		||||
		let mut params = CommonParams::default();
 | 
			
		||||
		params.dust_protection_transition = 0;
 | 
			
		||||
		params.nonce_cap_increment = 2;
 | 
			
		||||
@ -18,11 +18,12 @@
 | 
			
		||||
 | 
			
		||||
use call_contract::CallContract;
 | 
			
		||||
use client_traits::BlockInfo;
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
use types::{
 | 
			
		||||
use common_types::{
 | 
			
		||||
	header::Header,
 | 
			
		||||
	errors::EthcoreError as Error,
 | 
			
		||||
};
 | 
			
		||||
use engine::Engine;
 | 
			
		||||
 | 
			
		||||
use super::verification;
 | 
			
		||||
 | 
			
		||||
/// Should be used to verify blocks.
 | 
			
		||||
@ -30,7 +30,6 @@ use client_traits::{BlockInfo, BlockChainReset, Nonce, Balance, BlockChainClient
 | 
			
		||||
use ethcore::{
 | 
			
		||||
	client::{DatabaseCompactionProfile, VMType},
 | 
			
		||||
	miner::Miner,
 | 
			
		||||
	verification::queue::VerifierSettings,
 | 
			
		||||
};
 | 
			
		||||
use ethcore_service::ClientService;
 | 
			
		||||
use cache::CacheConfig;
 | 
			
		||||
@ -48,6 +47,7 @@ use types::{
 | 
			
		||||
	client_types::Mode,
 | 
			
		||||
	verification::Unverified,
 | 
			
		||||
};
 | 
			
		||||
use verification::queue::VerifierSettings;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
pub enum DataFormat {
 | 
			
		||||
@ -234,7 +234,7 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> {
 | 
			
		||||
						 &cmd.cache_config,
 | 
			
		||||
						 &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 service = LightClientService::start(config, &spec, fetch, db, cache)
 | 
			
		||||
		.map_err(|e| format!("Failed to start client: {}", e))?;
 | 
			
		||||
 | 
			
		||||
@ -32,8 +32,8 @@ use ethkey::{Secret, Public};
 | 
			
		||||
use ethcore::client::{VMType};
 | 
			
		||||
use ethcore::miner::{stratum, MinerOptions};
 | 
			
		||||
use ethcore::snapshot::SnapshotConfiguration;
 | 
			
		||||
use ethcore::verification::queue::VerifierSettings;
 | 
			
		||||
use miner::pool;
 | 
			
		||||
use verification::queue::VerifierSettings;
 | 
			
		||||
 | 
			
		||||
use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration};
 | 
			
		||||
use parity_rpc::NetworkSettings;
 | 
			
		||||
 | 
			
		||||
@ -23,13 +23,13 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
 | 
			
		||||
use std::time::{Instant, Duration};
 | 
			
		||||
 | 
			
		||||
use atty;
 | 
			
		||||
use ethcore::client::{
 | 
			
		||||
	ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage
 | 
			
		||||
};
 | 
			
		||||
use client_traits::{BlockInfo, ChainInfo, BlockChainClient};
 | 
			
		||||
use ethcore::client::{ChainNotify, NewBlocks, Client};
 | 
			
		||||
use client_traits::{BlockInfo, ChainInfo, BlockChainClient, IoClient};
 | 
			
		||||
use types::{
 | 
			
		||||
	BlockNumber,
 | 
			
		||||
	client_types::ClientReport,
 | 
			
		||||
	ids::BlockId,
 | 
			
		||||
	io_message::ClientIoMessage,
 | 
			
		||||
	blockchain_info::BlockChainInfo,
 | 
			
		||||
	verification::VerificationQueueInfo as BlockQueueInfo,
 | 
			
		||||
	snapshot::RestorationStatus,
 | 
			
		||||
@ -451,12 +451,16 @@ impl LightChainNotify for Informant<LightNodeInformantData> {
 | 
			
		||||
 | 
			
		||||
const INFO_TIMER: TimerToken = 0;
 | 
			
		||||
 | 
			
		||||
impl<T: InformantData> IoHandler<ClientIoMessage> for Informant<T> {
 | 
			
		||||
	fn initialize(&self, io: &IoContext<ClientIoMessage>) {
 | 
			
		||||
impl<T, C> IoHandler<ClientIoMessage<C>> for Informant<T>
 | 
			
		||||
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");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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) {
 | 
			
		||||
			self.tick();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -74,6 +74,7 @@ extern crate parity_updater as updater;
 | 
			
		||||
extern crate parity_version;
 | 
			
		||||
extern crate registrar;
 | 
			
		||||
extern crate spec;
 | 
			
		||||
extern crate verification;
 | 
			
		||||
 | 
			
		||||
#[macro_use]
 | 
			
		||||
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::snapshot::{self, SnapshotConfiguration};
 | 
			
		||||
use spec::SpecParams;
 | 
			
		||||
use ethcore::verification::queue::VerifierSettings;
 | 
			
		||||
use verification::queue::VerifierSettings;
 | 
			
		||||
use ethcore_logger::{Config as LogConfig, RotatingLogger};
 | 
			
		||||
use ethcore_service::ClientService;
 | 
			
		||||
use ethereum_types::Address;
 | 
			
		||||
@ -307,18 +307,18 @@ fn execute_light_impl<Cr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq
 | 
			
		||||
 | 
			
		||||
	// start RPCs
 | 
			
		||||
	let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
 | 
			
		||||
		signer_service: signer_service,
 | 
			
		||||
		signer_service,
 | 
			
		||||
		client: client.clone(),
 | 
			
		||||
		sync: light_sync.clone(),
 | 
			
		||||
		net: light_sync.clone(),
 | 
			
		||||
		accounts: account_provider,
 | 
			
		||||
		logger: logger,
 | 
			
		||||
		logger,
 | 
			
		||||
		settings: Arc::new(cmd.net_settings),
 | 
			
		||||
		on_demand: on_demand,
 | 
			
		||||
		on_demand,
 | 
			
		||||
		cache: cache.clone(),
 | 
			
		||||
		transaction_queue: txq,
 | 
			
		||||
		ws_address: cmd.ws_conf.address(),
 | 
			
		||||
		fetch: fetch,
 | 
			
		||||
		fetch,
 | 
			
		||||
		geth_compatibility: cmd.geth_compatibility,
 | 
			
		||||
		experimental_rpcs: cmd.experimental_rpcs,
 | 
			
		||||
		executor: runtime.executor(),
 | 
			
		||||
@ -344,7 +344,7 @@ fn execute_light_impl<Cr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq
 | 
			
		||||
		LightNodeInformantData {
 | 
			
		||||
			client: client.clone(),
 | 
			
		||||
			sync: light_sync.clone(),
 | 
			
		||||
			cache: cache,
 | 
			
		||||
			cache,
 | 
			
		||||
		},
 | 
			
		||||
		None,
 | 
			
		||||
		Some(rpc_stats),
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ use std::time::Duration;
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
 | 
			
		||||
use client_traits::SnapshotClient;
 | 
			
		||||
use hash::keccak;
 | 
			
		||||
use ethcore::snapshot::{SnapshotConfiguration, SnapshotService as SS};
 | 
			
		||||
use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter};
 | 
			
		||||
 | 
			
		||||
@ -67,6 +67,7 @@ account-state = { path = "../ethcore/account-state" }
 | 
			
		||||
stats = { path = "../util/stats" }
 | 
			
		||||
trace = { path = "../ethcore/trace" }
 | 
			
		||||
vm = { path = "../ethcore/vm" }
 | 
			
		||||
verification = { path = "../ethcore/verification" }
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
client-traits = { path = "../ethcore/client-traits" }
 | 
			
		||||
 | 
			
		||||
@ -89,6 +89,7 @@ extern crate account_state;
 | 
			
		||||
extern crate stats;
 | 
			
		||||
extern crate tempdir;
 | 
			
		||||
extern crate trace;
 | 
			
		||||
extern crate verification;
 | 
			
		||||
extern crate vm;
 | 
			
		||||
 | 
			
		||||
#[cfg(any(test, feature = "ethcore-accounts"))]
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ use ethcore::client::{Client, ClientConfig};
 | 
			
		||||
use ethcore::miner::Miner;
 | 
			
		||||
use spec::{Genesis, Spec, self};
 | 
			
		||||
use ethcore::test_helpers;
 | 
			
		||||
use ethcore::verification::VerifierType;
 | 
			
		||||
use verification::VerifierType;
 | 
			
		||||
use ethereum_types::{Address, H256, U256};
 | 
			
		||||
use ethjson::blockchain::BlockChain;
 | 
			
		||||
use ethjson::spec::ForkSpec;
 | 
			
		||||
@ -98,7 +98,6 @@ impl EthTester {
 | 
			
		||||
			if let Ok(block) = Unverified::from_rlp(b) {
 | 
			
		||||
				let _ = tester.client.import_block(block);
 | 
			
		||||
				tester.client.flush_queue();
 | 
			
		||||
				tester.client.import_verified_blocks();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user