diff --git a/Cargo.lock b/Cargo.lock index 69e0211d8..0117bb38d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "parity" version = "1.1.0" dependencies = [ "bincode 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 1.1.1 (git+https://github.com/tomusdrw/rust-ctrlc.git)", "daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -21,7 +21,6 @@ dependencies = [ "fdlimit 0.1.0", "hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "nanomsg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -123,7 +122,7 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.61" +version = "0.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -255,7 +254,7 @@ dependencies = [ name = "ethcore" version = "1.1.0" dependencies = [ - "clippy 0.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.1.0", @@ -283,7 +282,7 @@ name = "ethcore-ipc" version = "1.1.0" dependencies = [ "ethcore-devtools 1.1.0", - "nanomsg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nanomsg 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -305,14 +304,14 @@ version = "1.1.0" dependencies = [ "ethcore-ipc 1.1.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "nanomsg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nanomsg 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)", ] [[package]] name = "ethcore-rpc" version = "1.1.0" dependencies = [ - "clippy 0.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.1.0", "ethcore 1.1.0", "ethcore-util 1.1.0", @@ -336,7 +335,7 @@ dependencies = [ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 0.1.0", "chrono 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -368,7 +367,7 @@ dependencies = [ name = "ethcore-webapp" version = "1.1.0" dependencies = [ - "clippy 0.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.1.0", "ethcore-util 1.1.0", "hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -397,7 +396,7 @@ dependencies = [ name = "ethminer" version = "1.1.0" dependencies = [ - "clippy 0.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.1.0", "ethcore-util 1.1.0", @@ -411,7 +410,7 @@ dependencies = [ name = "ethsync" version = "1.1.0" dependencies = [ - "clippy 0.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.1.0", "ethcore-util 1.1.0", @@ -716,17 +715,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nanomsg" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/ethcore/nanomsg.rs.git#bcb1615462da2cf99a68a4e6107b9e19794bd699" dependencies = [ "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "nanomsg-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)", ] [[package]] name = "nanomsg-sys" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/ethcore/nanomsg.rs.git#bcb1615462da2cf99a68a4e6107b9e19794bd699" dependencies = [ + "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index e8c4dbe46..5dc5afcb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ daemonize = "0.2" num_cpus = "0.2" number_prefix = "0.2" rpassword = "0.1" -clippy = { version = "0.0.61", optional = true} +clippy = { version = "0.0.63", optional = true} ethcore = { path = "ethcore" } ethcore-util = { path = "util" } ethsync = { path = "sync" } @@ -33,7 +33,6 @@ ethcore-devtools = { path = "devtools" } ethcore-rpc = { path = "rpc", optional = true } ethcore-webapp = { path = "webapp", optional = true } semver = "0.2" -nanomsg = "0.5.0" ethcore-ipc-nano = { path = "ipc/nano" } "ethcore-ipc" = { path = "ipc/rpc" } bincode = "*" diff --git a/README.md b/README.md index 7aa5e8858..903794e80 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ First (if you don't already have it) get multirust: - Linux: ```bash -curl -sf https://raw.githubusercontent.com/brson/multirust/master/quick-install.sh | sudo sh -s -- --yes +curl -sf https://raw.githubusercontent.com/brson/multirust/master/quick-install.sh | sh ``` - OSX with Homebrew: diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index f2230673a..3dd283d96 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -27,7 +27,7 @@ use std::ptr; use sha3; use std::slice; use std::path::PathBuf; -use std::io::{Read, Write, self}; +use std::io::{self, Read, Write}; use std::fs::{self, File}; pub const ETHASH_EPOCH_LENGTH: u64 = 30000; @@ -44,14 +44,14 @@ const NODE_WORDS: usize = 64 / 4; const NODE_BYTES: usize = 64; const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4; const MIX_NODES: usize = MIX_WORDS / NODE_WORDS; -const FNV_PRIME: u32 = 0x01000193; +const FNV_PRIME: u32 = 0x01000193; /// Computation result pub struct ProofOfWork { /// Difficulty boundary pub value: H256, /// Mix - pub mix_hash: H256 + pub mix_hash: H256, } struct Node { @@ -148,14 +148,16 @@ impl Light { pub struct SeedHashCompute { prev_epoch: Cell, - prev_seedhash: Cell + prev_seedhash: Cell, } impl SeedHashCompute { - #[inline] pub fn new() -> SeedHashCompute { - SeedHashCompute { prev_epoch: Cell::new(0), prev_seedhash: Cell::new([0u8; 32]) } + SeedHashCompute { + prev_epoch: Cell::new(0), + prev_seedhash: Cell::new([0u8; 32]), + } } #[inline] @@ -181,7 +183,7 @@ impl SeedHashCompute { #[inline] pub fn resume_compute_seedhash(mut hash: H256, start_epoch: u64, end_epoch: u64) -> H256 { - for _ in start_epoch .. end_epoch { + for _ in start_epoch..end_epoch { unsafe { sha3::sha3_256(hash[..].as_mut_ptr(), 32, hash[..].as_ptr(), 32) }; } hash @@ -201,22 +203,22 @@ fn sha3_512(input: &[u8], output: &mut [u8]) { #[inline] fn get_cache_size(block_number: u64) -> usize { - let mut sz: u64 = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); - sz = sz - NODE_BYTES as u64; - while !is_prime(sz / NODE_BYTES as u64) { - sz = sz - 2 * NODE_BYTES as u64; - } - sz as usize + let mut sz: u64 = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); + sz = sz - NODE_BYTES as u64; + while !is_prime(sz / NODE_BYTES as u64) { + sz = sz - 2 * NODE_BYTES as u64; + } + sz as usize } #[inline] fn get_data_size(block_number: u64) -> usize { - let mut sz: u64 = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); - sz = sz - ETHASH_MIX_BYTES as u64; - while !is_prime(sz / ETHASH_MIX_BYTES as u64) { - sz = sz - 2 * ETHASH_MIX_BYTES as u64; - } - sz as usize + let mut sz: u64 = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); + sz = sz - ETHASH_MIX_BYTES as u64; + while !is_prime(sz / ETHASH_MIX_BYTES as u64) { + sz = sz - 2 * ETHASH_MIX_BYTES as u64; + } + sz as usize } @@ -249,12 +251,12 @@ pub fn light_compute(light: &Light, header_hash: &H256, nonce: u64) -> ProofOfWo hash_compute(light, full_size, header_hash, nonce) } -fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) -> ProofOfWork { +fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) -> ProofOfWork { if full_size % MIX_WORDS != 0 { panic!("Unaligned full size"); } // pack hash and nonce together into first 40 bytes of s_mix - let mut s_mix: [Node; MIX_NODES + 1] = [ Node::default(), Node::default(), Node::default() ]; + let mut s_mix: [Node; MIX_NODES + 1] = [Node::default(), Node::default(), Node::default()]; unsafe { ptr::copy_nonoverlapping(header_hash.as_ptr(), s_mix.get_unchecked_mut(0).bytes.as_mut_ptr(), 32) }; unsafe { ptr::copy_nonoverlapping(mem::transmute(&nonce), s_mix.get_unchecked_mut(0).bytes[32..].as_mut_ptr(), 8) }; @@ -295,7 +297,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64 ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), buf[64..].as_mut_ptr(), 32); ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), mix_hash.as_mut_ptr(), 32); let mut value: H256 = [0u8; 32]; - sha3::sha3_256(value.as_mut_ptr(), value.len(), buf.as_ptr(), buf.len()); + sha3::sha3_256(value.as_mut_ptr(), value.len(), buf.as_ptr(), buf.len()); ProofOfWork { mix_hash: mix_hash, value: value, @@ -348,7 +350,7 @@ fn light_new(block_number: u64) -> Light { let idx = *nodes.get_unchecked_mut(i).as_words().get_unchecked(0) as usize % num_nodes; let mut data = nodes.get_unchecked((num_nodes - 1 + i) % num_nodes).clone(); for w in 0..NODE_WORDS { - *data.as_words_mut().get_unchecked_mut(w) ^= *nodes.get_unchecked(idx).as_words().get_unchecked(w) ; + *data.as_words_mut().get_unchecked_mut(w) ^= *nodes.get_unchecked(idx).as_words().get_unchecked(w); } sha3_512(&data.bytes, &mut nodes.get_unchecked_mut(i).bytes); } @@ -362,7 +364,7 @@ fn light_new(block_number: u64) -> Light { } } -static CHARS: &'static[u8] = b"0123456789abcdef"; +static CHARS: &'static [u8] = b"0123456789abcdef"; fn to_hex(bytes: &[u8]) -> String { let mut v = Vec::with_capacity(bytes.len() * 2); for &byte in bytes.iter() { @@ -370,9 +372,7 @@ fn to_hex(bytes: &[u8]) -> String { v.push(CHARS[(byte & 0xf) as usize]); } - unsafe { - String::from_utf8_unchecked(v) - } + unsafe { String::from_utf8_unchecked(v) } } #[test] @@ -402,8 +402,8 @@ fn test_get_data_size() { #[test] fn test_difficulty_test() { - let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72]; - let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ]; + let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72]; + let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d]; let nonce = 0xd7b3ac70a301a249; let boundary_good = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84]; assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash)[..], boundary_good[..]); @@ -413,8 +413,8 @@ fn test_difficulty_test() { #[test] fn test_light_compute() { - let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72]; - let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ]; + let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72]; + let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d]; let boundary = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84]; let nonce = 0xd7b3ac70a301a249; // difficulty = 0x085657254bd9u64; diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs index 582b59d9c..3f67f2748 100644 --- a/ethash/src/lib.rs +++ b/ethash/src/lib.rs @@ -24,7 +24,7 @@ mod compute; use std::mem; use compute::Light; -pub use compute::{SeedHashCompute, quick_get_difficulty, H256, ProofOfWork, ETHASH_EPOCH_LENGTH}; +pub use compute::{ETHASH_EPOCH_LENGTH, H256, ProofOfWork, SeedHashCompute, quick_get_difficulty}; use std::sync::{Arc, Mutex}; @@ -76,7 +76,7 @@ impl EthashManager { lights.recent.clone() } _ => None, - } + }, }; match light { None => { @@ -95,7 +95,7 @@ impl EthashManager { lights.prev = mem::replace(&mut lights.recent, Some(light.clone())); light } - Some(light) => light + Some(light) => light, } }; light.compute(header_hash, nonce) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 6a158bb86..a43092b22 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -17,7 +17,7 @@ ethcore-util = { path = "../util" } evmjit = { path = "../evmjit", optional = true } ethash = { path = "../ethash" } num_cpus = "0.2" -clippy = { version = "0.0.61", optional = true} +clippy = { version = "0.0.63", optional = true} crossbeam = "0.1.5" lazy_static = "0.1" ethcore-devtools = { path = "../devtools" } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 781bea7fa..90ec8693f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -17,6 +17,7 @@ //! Blockchain database client. use std::marker::PhantomData; +use std::path::PathBuf; use util::*; use util::panics::*; use views::BlockView; @@ -126,22 +127,31 @@ impl Client { } } +/// Get the path for the databases given the root path and information on the databases. +pub fn get_db_path(path: &Path, pruning: journaldb::Algorithm, genesis_hash: H256) -> PathBuf { + let mut dir = path.to_path_buf(); + dir.push(H64::from(genesis_hash).hex()); + //TODO: sec/fat: pruned/full versioning + // version here is a bit useless now, since it's controlled only be the pruning algo. + dir.push(format!("v{}-sec-{}", CLIENT_DB_VER_STR, pruning)); + dir +} + +/// Append a path element to the given path and return the string. +pub fn append_path(path: &Path, item: &str) -> String { + let mut p = path.to_path_buf(); + p.push(item); + p.to_str().unwrap().to_owned() +} + impl Client where V: Verifier { /// Create a new client with given spec and DB path and custom verifier. pub fn new_with_verifier(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel ) -> Result>, Error> { - let mut dir = path.to_path_buf(); - dir.push(H64::from(spec.genesis_header().hash()).hex()); - //TODO: sec/fat: pruned/full versioning - // version here is a bit useless now, since it's controlled only be the pruning algo. - dir.push(format!("v{}-sec-{}", CLIENT_DB_VER_STR, config.pruning)); - let path = dir.as_path(); + let path = get_db_path(path, config.pruning, spec.genesis_header().hash()); let gb = spec.genesis_block(); - let chain = Arc::new(BlockChain::new(config.blockchain, &gb, path)); - let mut state_path = path.to_path_buf(); - state_path.push("state"); + let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path)); - let state_path_str = state_path.to_str().unwrap(); - let mut state_db = journaldb::new(state_path_str, config.pruning); + let mut state_db = journaldb::new(&append_path(&path, "state"), config.pruning); if state_db.is_empty() && spec.ensure_db_good(state_db.as_hashdb_mut()) { state_db.commit(0, &spec.genesis_header().hash(), None).expect("Error commiting genesis state to state DB"); diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index fc2f837ef..bd30e0fb6 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -140,10 +140,8 @@ impl<'a> Executive<'a> { let init_gas = t.gas - base_gas_required; // validate transaction nonce - if check_nonce { - if t.nonce != nonce { - return Err(From::from(ExecutionError::InvalidNonce { expected: nonce, got: t.nonce })); - } + if check_nonce && t.nonce != nonce { + return Err(From::from(ExecutionError::InvalidNonce { expected: nonce, got: t.nonce })); } // validate if transaction fits into given block diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index e5e232a98..1c0bb417f 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -67,6 +67,8 @@ pub struct Externalities<'a, T> where T: 'a + Tracer { } impl<'a, T> Externalities<'a, T> where T: 'a + Tracer { + + #[cfg_attr(feature="dev", allow(too_many_arguments))] /// Basic `Externalities` constructor. pub fn new(state: &'a mut State, env_info: &'a EnvInfo, diff --git a/ethcore/src/substate.rs b/ethcore/src/substate.rs index f643fea07..65b314663 100644 --- a/ethcore/src/substate.rs +++ b/ethcore/src/substate.rs @@ -19,7 +19,7 @@ use common::*; /// State changes which should be applied in finalize, /// after transaction is fully executed. -#[derive(Debug)] +#[derive(Debug, Default)] pub struct Substate { /// Any accounts that have suicided. pub suicides: HashSet
, diff --git a/ethcore/src/trace/trace.rs b/ethcore/src/trace/trace.rs index b0e2e75f5..6a90aaf8a 100644 --- a/ethcore/src/trace/trace.rs +++ b/ethcore/src/trace/trace.rs @@ -17,7 +17,7 @@ //! Tracing datatypes. use common::*; -/// TraceCall result. +/// `TraceCall` result. #[derive(Debug, Clone, PartialEq, Default)] pub struct TraceCallResult { /// Gas used by call. @@ -26,7 +26,7 @@ pub struct TraceCallResult { pub output: Bytes, } -/// TraceCreate result. +/// `TraceCreate` result. #[derive(Debug, Clone, PartialEq)] pub struct TraceCreateResult { /// Gas used by create. diff --git a/ipc/nano/Cargo.toml b/ipc/nano/Cargo.toml index c13a7b5a5..e941b1afc 100644 --- a/ipc/nano/Cargo.toml +++ b/ipc/nano/Cargo.toml @@ -8,5 +8,5 @@ license = "GPL-3.0" [dependencies] "ethcore-ipc" = { path = "../rpc" } -nanomsg = "0.5.0" +nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" } log = "0.3" diff --git a/ipc/rpc/Cargo.toml b/ipc/rpc/Cargo.toml index a6346bbf9..c07cb8ae3 100644 --- a/ipc/rpc/Cargo.toml +++ b/ipc/rpc/Cargo.toml @@ -9,4 +9,4 @@ license = "GPL-3.0" [dependencies] ethcore-devtools = { path = "../../devtools" } semver = "0.2.0" -nanomsg = "0.5.0" +nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" } diff --git a/ipc/tests/Cargo.toml b/ipc/tests/Cargo.toml index a9d9d7721..286fffd18 100644 --- a/ipc/tests/Cargo.toml +++ b/ipc/tests/Cargo.toml @@ -13,7 +13,7 @@ bincode = "*" serde = "0.7.0" ethcore-devtools = { path = "../../devtools" } semver = "0.2.0" -nanomsg = "0.5.0" +nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" } ethcore-ipc-nano = { path = "../nano" } ethcore-util = { path = "../../util" } diff --git a/json/Cargo.toml b/json/Cargo.toml index e4ae13e5b..ce15894e4 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -10,7 +10,7 @@ rustc-serialize = "0.3" serde = "0.7.0" serde_json = "0.7.0" serde_macros = { version = "0.7.0", optional = true } -clippy = { version = "0.0.61", optional = true} +clippy = { version = "0.0.63", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } diff --git a/miner/Cargo.toml b/miner/Cargo.toml index 18bf78104..f5ecb94a9 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -17,7 +17,7 @@ log = "0.3" env_logger = "0.3" rustc-serialize = "0.3" rayon = "0.3.1" -clippy = { version = "0.0.61", optional = true} +clippy = { version = "0.0.63", optional = true} [features] default = [] diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 005a37a28..27f914181 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -64,7 +64,7 @@ mod transaction_queue; pub use transaction_queue::{TransactionQueue, AccountDetails}; pub use miner::{Miner}; -use util::{H256, U256, Address, FixedHash, Bytes}; +use util::{H256, U256, Address, Bytes}; use ethcore::client::{BlockChainClient}; use ethcore::block::{ClosedBlock}; use ethcore::error::{Error}; @@ -77,14 +77,29 @@ pub trait MinerService : Send + Sync { fn status(&self) -> MinerStatus; /// Get the author that we will seal blocks as. - fn author(&self) -> Address { Address::zero() } + fn author(&self) -> Address; - /// Get the extra_data that we will seal blocks wuth. - fn extra_data(&self) -> Bytes { vec![] } + /// Set the author that we will seal blocks as. + fn set_author(&self, author: Address); + + /// Get the extra_data that we will seal blocks with. + fn extra_data(&self) -> Bytes; + + /// Set the extra_data that we will seal blocks with. + fn set_extra_data(&self, extra_data: Bytes); + + /// Get current minimal gas price for transactions accepted to queue. + fn minimal_gas_price(&self) -> U256; + + /// Set minimal gas price of transaction to be accepted for mining. + fn set_minimal_gas_price(&self, min_gas_price: U256); /// Get the gas limit we wish to target when sealing a new block. fn gas_floor_target(&self) -> U256; + /// Set the gas limit we wish to target when sealing a new block. + fn set_gas_floor_target(&self, target: U256); + /// Imports transactions to transaction queue. fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails; diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 1b00aeed6..7f7dc2980 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -69,26 +69,6 @@ impl Miner { }) } - /// Set the author that we will seal blocks as. - pub fn set_author(&self, author: Address) { - *self.author.write().unwrap() = author; - } - - /// Set the extra_data that we will seal blocks with. - pub fn set_extra_data(&self, extra_data: Bytes) { - *self.extra_data.write().unwrap() = extra_data; - } - - /// Set the gas limit we wish to target when sealing a new block. - pub fn set_gas_floor_target(&self, target: U256) { - *self.gas_floor_target.write().unwrap() = target; - } - - /// Set minimal gas price of transaction to be accepted for mining. - pub fn set_minimal_gas_price(&self, min_gas_price: U256) { - self.transaction_queue.lock().unwrap().set_minimal_gas_price(min_gas_price); - } - /// Prepares new block for sealing including top transactions from queue. #[cfg_attr(feature="dev", allow(match_same_arms))] fn prepare_sealing(&self, chain: &BlockChainClient) { @@ -195,6 +175,27 @@ impl MinerService for Miner { } } + fn set_author(&self, author: Address) { + *self.author.write().unwrap() = author; + } + + fn set_extra_data(&self, extra_data: Bytes) { + *self.extra_data.write().unwrap() = extra_data; + } + + /// Set the gas limit we wish to target when sealing a new block. + fn set_gas_floor_target(&self, target: U256) { + *self.gas_floor_target.write().unwrap() = target; + } + + fn set_minimal_gas_price(&self, min_gas_price: U256) { + self.transaction_queue.lock().unwrap().set_minimal_gas_price(min_gas_price); + } + + fn minimal_gas_price(&self) -> U256 { + *self.transaction_queue.lock().unwrap().minimal_gas_price() + } + fn sensible_gas_price(&self) -> U256 { // 10% above our minimum. *self.transaction_queue.lock().unwrap().minimal_gas_price() * x!(110) / x!(100) diff --git a/parity/main.rs b/parity/main.rs index 7b4fb5fbe..898d7e1bc 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -133,11 +133,11 @@ Networking Options: API and Console Options: -j --jsonrpc Enable the JSON-RPC API server. + --jsonrpc-port PORT Specify the port portion of the JSONRPC API server + [default: 8545]. --jsonrpc-interface IP Specify the hostname portion of the JSONRPC API server, IP should be an interface's IP address, or all (all interfaces) or local [default: local]. - --jsonrpc-port PORT Specify the port portion of the JSONRPC API server - [default: 8545]. --jsonrpc-cors URL Specify CORS header for JSON-RPC API responses [default: null]. --jsonrpc-apis APIS Specify the APIs available through the JSONRPC @@ -176,8 +176,14 @@ Sealing/Mining Options: Footprint Options: --pruning METHOD Configure pruning of the state/storage trie. METHOD - may be one of: archive, basic (experimental), fast - (experimental) [default: archive]. + may be one of auto, archive, basic, fast, light: + archive - keep all state trie data. No pruning. + basic - reference count in disk DB. Slow but light. + fast - maintain journal overlay. Fast but 50MB used. + light - early merges with partial tracking. Fast + and light. Experimental! + auto - use the method most recently synced or + default to archive if none synced [default: auto]. --cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384]. --cache-max-size BYTES Specify the maximum size of the blockchain cache in @@ -543,7 +549,26 @@ impl Configuration { ret } - fn client_config(&self) -> ClientConfig { + fn find_best_db(&self, spec: &Spec) -> Option { + let mut ret = None; + let mut latest_era = None; + let jdb_types = [journaldb::Algorithm::Archive, journaldb::Algorithm::EarlyMerge, journaldb::Algorithm::OverlayRecent, journaldb::Algorithm::RefCounted]; + for i in jdb_types.into_iter() { + let db = journaldb::new(&append_path(&get_db_path(&Path::new(&self.path()), *i, spec.genesis_header().hash()), "state"), *i); + trace!(target: "parity", "Looking for best DB: {} at {:?}", i, db.latest_era()); + match (latest_era, db.latest_era()) { + (Some(best), Some(this)) if best >= this => {} + (_, None) => {} + (_, Some(this)) => { + latest_era = Some(this); + ret = Some(*i); + } + } + } + ret + } + + fn client_config(&self, spec: &Spec) -> ClientConfig { let mut client_config = ClientConfig::default(); match self.args.flag_cache { Some(mb) => { @@ -560,8 +585,10 @@ impl Configuration { "light" => journaldb::Algorithm::EarlyMerge, "fast" => journaldb::Algorithm::OverlayRecent, "basic" => journaldb::Algorithm::RefCounted, + "auto" => self.find_best_db(spec).unwrap_or(journaldb::Algorithm::OverlayRecent), _ => { die!("Invalid pruning method given."); } }; + trace!(target: "parity", "Using pruning strategy of {}", client_config.pruning); client_config.name = self.args.flag_identity.clone(); client_config.queue.max_mem_use = self.args.flag_queue_max_size; client_config @@ -656,13 +683,14 @@ impl Configuration { let spec = self.spec(); let net_settings = self.net_settings(&spec); let sync_config = self.sync_config(&spec); + let client_config = self.client_config(&spec); // Secret Store let account_service = Arc::new(self.account_service()); // Build client let mut service = ClientService::start( - self.client_config(), spec, net_settings, &Path::new(&self.path()) + client_config, spec, net_settings, &Path::new(&self.path()) ).unwrap_or_else(|e| die_with_error(e)); panic_handler.forward_from(&service); diff --git a/parity/upgrade.rs b/parity/upgrade.rs index c9c98e174..f53d68b18 100644 --- a/parity/upgrade.rs +++ b/parity/upgrade.rs @@ -18,13 +18,15 @@ use semver::Version; use std::collections::*; -use std::fs::File; +use std::fs::{File, create_dir_all}; use std::env; use std::io::{Read, Write}; +#[cfg_attr(feature="dev", allow(enum_variant_names))] #[derive(Debug)] pub enum Error { - CannotLockVersionFile, + CannotCreateConfigPath, + CannotWriteVersionFile, CannotUpdateVersionFile, } @@ -65,7 +67,7 @@ fn dummy_upgrade() -> Result<(), Error> { Ok(()) } -fn push_updrades(upgrades: &mut UpgradeList) +fn push_upgrades(upgrades: &mut UpgradeList) { // dummy upgrade (remove when the first one is in) upgrades.insert( @@ -75,7 +77,7 @@ fn push_updrades(upgrades: &mut UpgradeList) fn upgrade_from_version(previous_version: &Version) -> Result { let mut upgrades = HashMap::new(); - push_updrades(&mut upgrades); + push_upgrades(&mut upgrades); let current_version = Version::parse(CURRENT_VERSION).unwrap(); @@ -95,6 +97,7 @@ fn with_locked_version(script: F) -> Result { let mut path = env::home_dir().expect("Applications should have a home dir"); path.push(".parity"); + try!(create_dir_all(&path).map_err(|_| Error::CannotCreateConfigPath)); path.push("ver.lock"); let version = @@ -107,16 +110,12 @@ fn with_locked_version(script: F) -> Result }) .unwrap_or_else(|| Version::parse("0.9.0").unwrap()); - let script_result = { - let mut lock = try!(File::create(&path).map_err(|_| Error::CannotLockVersionFile)); - let result = script(&version); + let mut lock = try!(File::create(&path).map_err(|_| Error::CannotWriteVersionFile)); + let result = script(&version); - let written_version = Version::parse(CURRENT_VERSION).unwrap(); - try!(lock.write_all(written_version.to_string().as_bytes()).map_err(|_| Error::CannotUpdateVersionFile)); - result - }; - - script_result + let written_version = Version::parse(CURRENT_VERSION).unwrap(); + try!(lock.write_all(written_version.to_string().as_bytes()).map_err(|_| Error::CannotUpdateVersionFile)); + result } pub fn upgrade() -> Result { diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 0fa7a9cd9..9d913e19b 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -22,7 +22,7 @@ ethminer = { path = "../miner" } rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } -clippy = { version = "0.0.61", optional = true} +clippy = { version = "0.0.63", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } diff --git a/rpc/src/v1/impls/ethcore.rs b/rpc/src/v1/impls/ethcore.rs index e46503037..d9764842c 100644 --- a/rpc/src/v1/impls/ethcore.rs +++ b/rpc/src/v1/impls/ethcore.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! Ethcore-specific rpc implementation. +use util::{U256, Address}; use std::sync::{Arc, Weak}; use jsonrpc_core::*; use ethminer::{MinerService}; @@ -37,6 +38,39 @@ impl EthcoreClient where M: MinerService { } impl Ethcore for EthcoreClient where M: MinerService + 'static { + + fn set_min_gas_price(&self, params: Params) -> Result { + from_params::<(U256,)>(params).and_then(|(gas_price,)| { + take_weak!(self.miner).set_minimal_gas_price(gas_price); + to_value(&true) + }) + } + + fn set_gas_floor_target(&self, params: Params) -> Result { + from_params::<(U256,)>(params).and_then(|(gas_floor_target,)| { + take_weak!(self.miner).set_gas_floor_target(gas_floor_target); + to_value(&true) + }) + } + + fn set_extra_data(&self, params: Params) -> Result { + from_params::<(Bytes,)>(params).and_then(|(extra_data,)| { + take_weak!(self.miner).set_extra_data(extra_data.to_vec()); + to_value(&true) + }) + } + + fn set_author(&self, params: Params) -> Result { + from_params::<(Address,)>(params).and_then(|(author,)| { + take_weak!(self.miner).set_author(author); + to_value(&true) + }) + } + + fn min_gas_price(&self, _: Params) -> Result { + to_value(&take_weak!(self.miner).minimal_gas_price()) + } + fn extra_data(&self, _: Params) -> Result { to_value(&Bytes::new(take_weak!(self.miner).extra_data())) } diff --git a/rpc/src/v1/tests/ethcore.rs b/rpc/src/v1/tests/ethcore.rs index 75c964a83..06d4ffc1c 100644 --- a/rpc/src/v1/tests/ethcore.rs +++ b/rpc/src/v1/tests/ethcore.rs @@ -15,10 +15,13 @@ // along with Parity. If not, see . use std::sync::Arc; +use std::str::FromStr; use jsonrpc_core::IoHandler; use v1::{Ethcore, EthcoreClient}; -use v1::tests::helpers::{TestMinerService}; +use ethminer::MinerService; +use v1::tests::helpers::TestMinerService; use util::numbers::*; +use rustc_serialize::hex::FromHex; fn miner_service() -> Arc { @@ -52,3 +55,71 @@ fn rpc_ethcore_gas_floor_target() { assert_eq!(io.handle_request(request), Some(response.to_owned())); } +#[test] +fn rpc_ethcore_min_gas_price() { + let miner = miner_service(); + let ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_minGasPrice", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0x01312d00","id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} + +#[test] +fn rpc_ethcore_set_min_gas_price() { + let miner = miner_service(); + let ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.minimal_gas_price(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} + +#[test] +fn rpc_ethcore_set_gas_floor_target() { + let miner = miner_service(); + let ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.gas_floor_target(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} + +#[test] +fn rpc_ethcore_set_extra_data() { + let miner = miner_service(); + let ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.extra_data(), "cd1722f3947def4cf144679da39c4c32bdc35681".from_hex().unwrap()); +} + +#[test] +fn rpc_ethcore_set_author() { + let miner = miner_service(); + let ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 5cea555a9..b2e546b2b 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -16,7 +16,7 @@ //! Test implementation of miner service. -use util::{Address, H256, Bytes, U256}; +use util::{Address, H256, Bytes, U256, FixedHash}; use util::standard::*; use ethcore::error::Error; use ethcore::client::BlockChainClient; @@ -34,6 +34,11 @@ pub struct TestMinerService { pub pending_transactions: Mutex>, /// Last nonces. pub last_nonces: RwLock>, + + min_gas_price: RwLock, + gas_floor_target: RwLock, + author: RwLock
, + extra_data: RwLock, } impl Default for TestMinerService { @@ -43,6 +48,10 @@ impl Default for TestMinerService { latest_closed_block: Mutex::new(None), pending_transactions: Mutex::new(HashMap::new()), last_nonces: RwLock::new(HashMap::new()), + min_gas_price: RwLock::new(U256::from(20_000_000)), + gas_floor_target: RwLock::new(U256::from(12345)), + author: RwLock::new(Address::zero()), + extra_data: RwLock::new(vec![1, 2, 3, 4]), } } } @@ -58,6 +67,39 @@ impl MinerService for TestMinerService { } } + fn set_author(&self, author: Address) { + *self.author.write().unwrap() = author; + } + + fn set_extra_data(&self, extra_data: Bytes) { + *self.extra_data.write().unwrap() = extra_data; + } + + /// Set the gas limit we wish to target when sealing a new block. + fn set_gas_floor_target(&self, target: U256) { + *self.gas_floor_target.write().unwrap() = target; + } + + fn set_minimal_gas_price(&self, min_gas_price: U256) { + *self.min_gas_price.write().unwrap() = min_gas_price; + } + + fn author(&self) -> Address { + *self.author.read().unwrap() + } + + fn minimal_gas_price(&self) -> U256 { + *self.min_gas_price.read().unwrap() + } + + fn extra_data(&self) -> Bytes { + self.extra_data.read().unwrap().clone() + } + + fn gas_floor_target(&self) -> U256 { + *self.gas_floor_target.read().unwrap() + } + /// Imports transactions to transaction queue. fn import_transactions(&self, transactions: Vec, _fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { @@ -111,12 +153,4 @@ impl MinerService for TestMinerService { fn submit_seal(&self, _chain: &BlockChainClient, _pow_hash: H256, _seal: Vec) -> Result<(), Error> { unimplemented!(); } - - fn extra_data(&self) -> Bytes { - vec![1, 2, 3, 4] - } - - fn gas_floor_target(&self) -> U256 { - U256::from(12345) - } } diff --git a/rpc/src/v1/traits/ethcore.rs b/rpc/src/v1/traits/ethcore.rs index bb10d62c3..fb96ef035 100644 --- a/rpc/src/v1/traits/ethcore.rs +++ b/rpc/src/v1/traits/ethcore.rs @@ -20,17 +20,39 @@ use jsonrpc_core::*; /// Ethcore-specific rpc interface. pub trait Ethcore: Sized + Send + Sync + 'static { + + /// Sets new minimal gas price for mined blocks. + fn set_min_gas_price(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Sets new gas floor target for mined blocks. + fn set_gas_floor_target(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Sets new extra data for mined blocks. + fn set_extra_data(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Sets new author for mined block. + fn set_author(&self, _: Params) -> Result { rpc_unimplemented!() } + /// Returns mining extra data. fn extra_data(&self, _: Params) -> Result { rpc_unimplemented!() } /// Returns mining gas floor target. fn gas_floor_target(&self, _: Params) -> Result { rpc_unimplemented!() } + /// Returns minimal gas price for transaction to be included in queue. + fn min_gas_price(&self, _: Params) -> Result { rpc_unimplemented!() } + /// Should be used to convert object to io delegate. fn to_delegate(self) -> IoDelegate { let mut delegate = IoDelegate::new(Arc::new(self)); + delegate.add_method("ethcore_setMinGasPrice", Ethcore::set_min_gas_price); + delegate.add_method("ethcore_setGasFloorTarget", Ethcore::set_gas_floor_target); + delegate.add_method("ethcore_setExtraData", Ethcore::set_extra_data); + delegate.add_method("ethcore_setAuthor", Ethcore::set_author); + delegate.add_method("ethcore_extraData", Ethcore::extra_data); delegate.add_method("ethcore_gasFloorTarget", Ethcore::gas_floor_target); + delegate.add_method("ethcore_minGasPrice", Ethcore::min_gas_price); delegate } } diff --git a/rpc/src/v1/types/filter.rs b/rpc/src/v1/types/filter.rs index 16a08764b..91707dfa3 100644 --- a/rpc/src/v1/types/filter.rs +++ b/rpc/src/v1/types/filter.rs @@ -61,7 +61,7 @@ pub struct Filter { impl Into for Filter { fn into(self) -> EthFilter { EthFilter { - from_block: self.from_block.map_or_else(|| BlockId::Earliest, Into::into), + from_block: self.from_block.map_or_else(|| BlockId::Latest, Into::into), to_block: self.to_block.map_or_else(|| BlockId::Latest, Into::into), address: self.address.and_then(|address| match address { VariadicValue::Null => None, diff --git a/rustfmt.toml b/rustfmt.toml index 678a324b3..aa66bf467 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,15 +1,17 @@ verbose=false -max_width=150 -ideal_width=120 +max_width=1000 +ideal_width=1000 tabs_spaces=4 -fn_call_width=100 +fn_call_width=1000 +struct_lit_width=32 fn_arg_indent="Tabbed" single_line_if_else=true where_indent="Visual" where_trailing_comma=true chain_base_indent="Inherit" -chain_indent="Tabbed" +chain_indent="Inherit" reorder_imports=true format_strings=false +chain_overflow_last=false hard_tabs=true wrap_match_arms=false diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 842924ba0..e6f17557b 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -10,7 +10,7 @@ authors = ["Ethcore (&v))) { Ok(Some(DB_VERSION)) => {}, - v => panic!("Incompatible DB version, expected {}, got {:?}", DB_VERSION, v) + v => panic!("Incompatible DB version, expected {}, got {:?}; to resolve, remove {} and restart.", DB_VERSION, v, path) } } else { backing.put(&VERSION_KEY, &encode(&DB_VERSION)).expect("Error writing version to database"); @@ -168,6 +168,8 @@ impl JournalDB for ArchiveDB { Ok((inserts + deletes) as u32) } + fn latest_era(&self) -> Option { self.latest_era } + fn state(&self, id: &H256) -> Option { self.backing.get_by_prefix(&id.bytes()[0..12]).and_then(|b| Some(b.to_vec())) } diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index eada4bbaa..62fe0023a 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -70,7 +70,7 @@ pub struct EarlyMergeDB { // all keys must be at least 12 bytes const LATEST_ERA_KEY : [u8; 12] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; const VERSION_KEY : [u8; 12] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; -const DB_VERSION : u32 = 3; +const DB_VERSION : u32 = 0x003; const PADDING : [u8; 10] = [ 0u8; 10 ]; impl EarlyMergeDB { @@ -85,7 +85,7 @@ impl EarlyMergeDB { if !backing.is_empty() { match backing.get(&VERSION_KEY).map(|d| d.map(|v| decode::(&v))) { Ok(Some(DB_VERSION)) => {}, - v => panic!("Incompatible DB version, expected {}, got {:?}", DB_VERSION, v) + v => panic!("Incompatible DB version, expected {}, got {:?}; to resolve, remove {} and restart.", DB_VERSION, v, path) } } else { backing.put(&VERSION_KEY, &encode(&DB_VERSION)).expect("Error writing version to database"); @@ -333,6 +333,8 @@ impl JournalDB for EarlyMergeDB { self.backing.get(&LATEST_ERA_KEY).expect("Low level database error").is_none() } + fn latest_era(&self) -> Option { self.latest_era } + fn mem_used(&self) -> usize { self.overlay.mem_used() + match self.refs { Some(ref c) => c.read().unwrap().heap_size_of_children(), @@ -340,7 +342,6 @@ impl JournalDB for EarlyMergeDB { } } - #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result { // journal format: diff --git a/util/src/journaldb/mod.rs b/util/src/journaldb/mod.rs index f65aebde1..6e389b3c0 100644 --- a/util/src/journaldb/mod.rs +++ b/util/src/journaldb/mod.rs @@ -29,7 +29,7 @@ mod refcounteddb; pub use self::traits::JournalDB; /// A journal database algorithm. -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub enum Algorithm { /// Keep all keys forever. Archive, diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index 0b9ad4fda..9c68b9255 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -95,7 +95,7 @@ impl Clone for OverlayRecentDB { // all keys must be at least 12 bytes const LATEST_ERA_KEY : [u8; 12] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; const VERSION_KEY : [u8; 12] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; -const DB_VERSION : u32 = 0x200 + 3; +const DB_VERSION : u32 = 0x203; const PADDING : [u8; 10] = [ 0u8; 10 ]; impl OverlayRecentDB { @@ -115,7 +115,7 @@ impl OverlayRecentDB { if !backing.is_empty() { match backing.get(&VERSION_KEY).map(|d| d.map(|v| decode::(&v))) { Ok(Some(DB_VERSION)) => {} - v => panic!("Incompatible DB version, expected {}, got {:?}", DB_VERSION, v) + v => panic!("Incompatible DB version, expected {}, got {:?}; to resolve, remove {} and restart.", DB_VERSION, v, path) } } else { backing.put(&VERSION_KEY, &encode(&DB_VERSION)).expect("Error writing version to database"); @@ -213,6 +213,8 @@ impl JournalDB for OverlayRecentDB { self.backing.get(&LATEST_ERA_KEY).expect("Low level database error").is_none() } + fn latest_era(&self) -> Option { self.journal_overlay.read().unwrap().latest_era } + fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result { // record new commit's details. trace!("commit: #{} ({}), end era: {:?}", now, id, end); diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index e69eccab7..0df4d76b1 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -42,7 +42,7 @@ pub struct RefCountedDB { const LATEST_ERA_KEY : [u8; 12] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; const VERSION_KEY : [u8; 12] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; -const DB_VERSION : u32 = 512; +const DB_VERSION : u32 = 0x200; const PADDING : [u8; 10] = [ 0u8; 10 ]; impl RefCountedDB { @@ -57,7 +57,7 @@ impl RefCountedDB { if !backing.is_empty() { match backing.get(&VERSION_KEY).map(|d| d.map(|v| decode::(&v))) { Ok(Some(DB_VERSION)) => {}, - v => panic!("Incompatible DB version, expected {}, got {:?}", DB_VERSION, v) + v => panic!("Incompatible DB version, expected {}, got {:?}; to resolve, remove {} and restart.", DB_VERSION, v, path) } } else { backing.put(&VERSION_KEY, &encode(&DB_VERSION)).expect("Error writing version to database"); @@ -112,6 +112,8 @@ impl JournalDB for RefCountedDB { self.latest_era.is_none() } + fn latest_era(&self) -> Option { self.latest_era } + fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result { // journal format: // [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ] @@ -220,6 +222,25 @@ mod tests { assert!(!jdb.exists(&h)); } + #[test] + fn latest_era_should_work() { + // history is 3 + let mut jdb = RefCountedDB::new_temp(); + assert_eq!(jdb.latest_era(), None); + let h = jdb.insert(b"foo"); + jdb.commit(0, &b"0".sha3(), None).unwrap(); + assert_eq!(jdb.latest_era(), Some(0)); + jdb.remove(&h); + jdb.commit(1, &b"1".sha3(), None).unwrap(); + assert_eq!(jdb.latest_era(), Some(1)); + jdb.commit(2, &b"2".sha3(), None).unwrap(); + assert_eq!(jdb.latest_era(), Some(2)); + jdb.commit(3, &b"3".sha3(), Some((0, b"0".sha3()))).unwrap(); + assert_eq!(jdb.latest_era(), Some(3)); + jdb.commit(4, &b"4".sha3(), Some((1, b"1".sha3()))).unwrap(); + assert_eq!(jdb.latest_era(), Some(4)); + } + #[test] fn complex() { // history is 1 diff --git a/util/src/journaldb/traits.rs b/util/src/journaldb/traits.rs index b1ba27957..10212f976 100644 --- a/util/src/journaldb/traits.rs +++ b/util/src/journaldb/traits.rs @@ -31,6 +31,9 @@ pub trait JournalDB : HashDB + Send + Sync { /// Check if this database has any commits fn is_empty(&self) -> bool; + /// Get the latest era in the DB. None if there isn't yet any data in there. + fn latest_era(&self) -> Option; + /// Commit all recent insert operations and canonical historical commits' removals from the /// old era to the backing database, reverting any non-canonical historical commit's inserts. fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result; diff --git a/webapp/Cargo.toml b/webapp/Cargo.toml index 126c5fbfb..eb3e9c042 100644 --- a/webapp/Cargo.toml +++ b/webapp/Cargo.toml @@ -19,7 +19,7 @@ parity-webapp = { git = "https://github.com/tomusdrw/parity-webapp.git" } # List of apps parity-status = { git = "https://github.com/tomusdrw/parity-status.git", version = "0.1.5" } parity-wallet = { git = "https://github.com/tomusdrw/parity-wallet.git", optional = true } -clippy = { version = "0.0.61", optional = true} +clippy = { version = "0.0.63", optional = true} [features] default = ["parity-wallet"]