diff --git a/Cargo.lock b/Cargo.lock index d4d1ceaff..259a0c4d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,7 @@ dependencies = [ "docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 0.9.99", + "ethcore-devtools 0.9.99", "ethcore-rpc 0.9.99", "ethcore-util 0.9.99", "ethsync 0.9.99", @@ -173,6 +174,7 @@ dependencies = [ "crossbeam 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 0.9.99", + "ethcore-devtools 0.9.99", "ethcore-util 0.9.99", "heapsize 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -184,6 +186,13 @@ dependencies = [ "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethcore-devtools" +version = "0.9.99" +dependencies = [ + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethcore-rpc" version = "0.9.99" @@ -212,6 +221,7 @@ dependencies = [ "elastic-array 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.4 (git+https://github.com/arkpar/rust-secp256k1.git)", + "ethcore-devtools 0.9.99", "heapsize 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "igd 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 5b59b26f1..3cb158df7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ ethcore-rpc = { path = "rpc", optional = true } fdlimit = { path = "util/fdlimit" } target_info = "0.1" daemonize = "0.2" +ethcore-devtools = { path = "devtools" } [features] default = ["rpc"] diff --git a/devtools/Cargo.toml b/devtools/Cargo.toml new file mode 100644 index 000000000..ce0260936 --- /dev/null +++ b/devtools/Cargo.toml @@ -0,0 +1,16 @@ +[package] +description = "Ethcore development/test/build tools" +homepage = "http://ethcore.io" +license = "GPL-3.0" +name = "ethcore-devtools" +version = "0.9.99" +authors = ["Ethcore "] + +[dependencies] +rand = "0.3" + +[features] + +[lib] +path = "src/lib.rs" +test = true diff --git a/devtools/README.md b/devtools/README.md new file mode 100644 index 000000000..5d5144689 --- /dev/null +++ b/devtools/README.md @@ -0,0 +1 @@ +# ethcore dev tools diff --git a/devtools/src/lib.rs b/devtools/src/lib.rs new file mode 100644 index 000000000..f310cca30 --- /dev/null +++ b/devtools/src/lib.rs @@ -0,0 +1,24 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! dev-tools + + +extern crate rand; + +pub mod random_path; + +pub use random_path::*; diff --git a/devtools/src/random_path.rs b/devtools/src/random_path.rs new file mode 100644 index 000000000..b037867fa --- /dev/null +++ b/devtools/src/random_path.rs @@ -0,0 +1,89 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Random path + +use std::path::*; +use std::fs; +use std::env; +use rand::random; + +pub struct RandomTempPath { + path: PathBuf +} + +pub fn random_filename() -> String { + (0..8).map(|_| ((random::() * 26.0) as u8 + 97) as char).collect() +} + +impl RandomTempPath { + pub fn new() -> RandomTempPath { + let mut dir = env::temp_dir(); + dir.push(random_filename()); + RandomTempPath { + path: dir.clone() + } + } + + pub fn create_dir() -> RandomTempPath { + let mut dir = env::temp_dir(); + dir.push(random_filename()); + fs::create_dir_all(dir.as_path()).unwrap(); + RandomTempPath { + path: dir.clone() + } + } + + pub fn as_path(&self) -> &PathBuf { + &self.path + } + + pub fn as_str(&self) -> &str { + self.path.to_str().unwrap() + } +} + +impl Drop for RandomTempPath { + fn drop(&mut self) { + if let Err(e) = fs::remove_dir_all(self.as_path()) { + panic!("failed to remove temp directory, probably something failed to destroyed ({})", e); + } + } +} + +#[test] +fn creates_dir() { + let temp = RandomTempPath::create_dir(); + assert!(fs::metadata(temp.as_path()).unwrap().is_dir()); +} + +#[test] +fn destroys_dir() { + let path_buf = { + let temp = RandomTempPath::create_dir(); + assert!(fs::metadata(temp.as_path()).unwrap().is_dir()); + let path_buf = temp.as_path().to_path_buf(); + path_buf + }; + + assert!(fs::metadata(&path_buf).is_err()); +} + +#[test] +fn provides_random() { + let temp = RandomTempPath::create_dir(); + assert!(temp.as_path().to_str().is_some()); +} diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 090280cae..d34a5478b 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -21,6 +21,7 @@ num_cpus = "0.2" clippy = { version = "0.0.42", optional = true } crossbeam = "0.1.5" lazy_static = "0.1" +ethcore-devtools = { path = "../devtools" } [features] jit = ["evmjit"] diff --git a/ethcore/src/blockchain.rs b/ethcore/src/blockchain.rs index 9240ff800..fc823411f 100644 --- a/ethcore/src/blockchain.rs +++ b/ethcore/src/blockchain.rs @@ -664,6 +664,7 @@ mod tests { use util::hash::*; use blockchain::*; use tests::helpers::*; + use devtools::*; #[test] fn valid_tests_extra32() { @@ -679,7 +680,7 @@ mod tests { assert_eq!(bc.best_block_hash(), genesis_hash.clone()); assert_eq!(bc.block_hash(0), Some(genesis_hash.clone())); assert_eq!(bc.block_hash(1), None); - + let first = "f90285f90219a03caa2203f3d7c136c0295ed128a7d31cea520b1ca5e27afe17d0853331798942a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bfa0d45893a296c1490a978e0bd321b5f2635d8280365c1fe9f693d65f233e791344a0c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b845627cb99a00102030405060708091011121314151617181920212223242526272829303132a08ccb2837fb2923bd97e8f2d08ea32012d6e34be018c73e49a0f98843e8f47d5d88e53be49fec01012ef866f864800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d8785012a05f200801ba0cb088b8d2ff76a7b2c6616c9d02fb6b7a501afbf8b69d7180b09928a1b80b5e4a06448fe7476c606582039bb72a9f6f4b4fad18507b8dfbd00eebbe151cc573cd2c0".from_hex().unwrap(); bc.insert_block(&first); @@ -855,7 +856,7 @@ mod tests { let temp = RandomTempPath::new(); let bc = BlockChain::new(&genesis, temp.as_path()); bc.insert_block(&b1); - + let transactions = bc.transactions(&b1_hash).unwrap(); assert_eq!(transactions.len(), 7); for t in transactions { diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 6a9f84073..a386e2854 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -20,6 +20,7 @@ use pod_state::*; use block::Block; use ethereum; use tests::helpers::*; +use devtools::*; pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { init_log(); diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 8e59cf7a2..9deb3a691 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -92,6 +92,7 @@ extern crate env_logger; extern crate num_cpus; extern crate crossbeam; +#[cfg(test)] extern crate ethcore_devtools as devtools; #[cfg(feature = "jit" )] extern crate evmjit; pub mod block; diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index db0260b06..534aab49d 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -129,6 +129,7 @@ mod tests { use super::*; use tests::helpers::*; use util::network::*; + use devtools::*; #[test] fn it_can_be_started() { diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index bbec8cd37..8bbf317c1 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -163,7 +163,7 @@ impl State { /// Mutate storage of account `address` so that it is `value` for `key`. pub fn storage_at(&self, address: &Address, key: &H256) -> H256 { - self.get(address, false).as_ref().map_or(H256::new(), |a|a.storage_at(&AccountDB::new(&self.db, address), key)) + self.get(address, false).as_ref().map_or(H256::new(), |a|a.storage_at(&AccountDB::new(&self.db, address), key)) } /// Mutate storage of account `a` so that it is `value` for `key`. @@ -341,6 +341,7 @@ use util::rlp::*; use util::uint::*; use account::*; use tests::helpers::*; +use devtools::*; #[test] fn code_from_database() { diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index d025b4b78..af25d1b72 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -17,6 +17,7 @@ use client::{BlockChainClient, Client, BlockId}; use tests::helpers::*; use common::*; +use devtools::*; #[test] fn created() { diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 93e3e0a0d..56653e820 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -15,17 +15,15 @@ // along with Parity. If not, see . use client::{BlockChainClient, Client}; -use std::env; use common::*; -use std::path::PathBuf; use spec::*; -use std::fs::{remove_dir_all}; use blockchain::{BlockChain}; use state::*; use rocksdb::*; use evm::{Schedule, Factory}; use engine::*; use ethereum; +use devtools::*; #[cfg(feature = "json-tests")] pub enum ChainEra { @@ -33,36 +31,6 @@ pub enum ChainEra { Homestead, } -pub struct RandomTempPath { - path: PathBuf -} - -impl RandomTempPath { - pub fn new() -> RandomTempPath { - let mut dir = env::temp_dir(); - dir.push(H32::random().hex()); - RandomTempPath { - path: dir.clone() - } - } - - pub fn as_path(&self) -> &PathBuf { - &self.path - } - - pub fn as_str(&self) -> &str { - self.path.to_str().unwrap() - } -} - -impl Drop for RandomTempPath { - fn drop(&mut self) { - if let Err(e) = remove_dir_all(self.as_path()) { - panic!("failed to remove temp directory, probably something failed to destroyed ({})", e); - } - } -} - #[cfg(test)] pub struct GuardedTempResult { result: Option, diff --git a/util/Cargo.toml b/util/Cargo.toml index c27d4bdc3..5d7fa697f 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -30,6 +30,7 @@ clippy = { version = "0.0.42", optional = true } json-tests = { path = "json-tests" } target_info = "0.1.0" igd = "0.4.2" +ethcore-devtools = { path = "../devtools" } libc = "0.2.7" [features] diff --git a/util/src/keys/directory.rs b/util/src/keys/directory.rs index 23c483482..bc875db3f 100644 --- a/util/src/keys/directory.rs +++ b/util/src/keys/directory.rs @@ -1030,7 +1030,7 @@ mod file_tests { mod directory_tests { use super::{KeyDirectory, new_uuid, uuid_to_string, KeyFileContent, KeyFileCrypto, MAX_CACHE_USAGE_TRACK}; use common::*; - use tests::helpers::*; + use devtools::*; #[test] fn key_directory_locates_keys() { @@ -1110,7 +1110,7 @@ mod directory_tests { mod specs { use super::*; use common::*; - use tests::helpers::*; + use devtools::*; #[test] fn can_initiate_key_directory() { diff --git a/util/src/keys/store.rs b/util/src/keys/store.rs index b8b0b0a47..ae44d567a 100644 --- a/util/src/keys/store.rs +++ b/util/src/keys/store.rs @@ -70,7 +70,7 @@ impl SecretStore { } #[cfg(test)] - fn new_test(path: &::tests::helpers::RandomTempPath) -> SecretStore { + fn new_test(path: &::devtools::RandomTempPath) -> SecretStore { SecretStore { directory: KeyDirectory::new(path.as_path()) } @@ -203,7 +203,7 @@ mod vector_tests { #[cfg(test)] mod tests { use super::*; - use tests::helpers::*; + use devtools::*; use common::*; #[test] diff --git a/util/src/lib.rs b/util/src/lib.rs index b5a0a8185..9527341ad 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -106,6 +106,7 @@ extern crate serde; #[macro_use] extern crate log as rlog; extern crate igd; +extern crate ethcore_devtools as devtools; extern crate libc; pub mod standard; @@ -161,5 +162,3 @@ pub use network::*; pub use io::*; pub use log::*; -#[cfg(test)] -mod tests; diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 78fb274fa..feddf1952 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -174,8 +174,8 @@ pub struct NetworkContext<'s, Message> where Message: Send + Sync + Clone + 'sta impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone + 'static, { /// Create a new network IO access point. Takes references to all the data that can be updated within the IO handler. - fn new(io: &'s IoContext>, - protocol: ProtocolId, + fn new(io: &'s IoContext>, + protocol: ProtocolId, session: Option, sessions: Arc>>) -> NetworkContext<'s, Message> { NetworkContext { io: io, @@ -337,9 +337,9 @@ impl Host where Message: Send + Sync + Clone { // Setup the server socket let tcp_listener = TcpListener::bind(&listen_address).unwrap(); - let keys = if let Some(ref secret) = config.use_secret { - KeyPair::from_secret(secret.clone()).unwrap() - } else { + let keys = if let Some(ref secret) = config.use_secret { + KeyPair::from_secret(secret.clone()).unwrap() + } else { config.config_path.clone().and_then(|ref p| load_key(&Path::new(&p))) .map_or_else(|| { let key = KeyPair::create().unwrap(); @@ -351,7 +351,7 @@ impl Host where Message: Send + Sync + Clone { |s| KeyPair::from_secret(s).expect("Error creating node secret key")) }; let discovery = if config.discovery_enabled && !config.pin { - Some(Discovery::new(&keys, listen_address.clone(), public_endpoint.clone(), DISCOVERY)) + Some(Discovery::new(&keys, listen_address.clone(), public_endpoint.clone(), DISCOVERY)) } else { None }; let path = config.config_path.clone(); let mut host = Host:: { @@ -546,7 +546,7 @@ impl Host where Message: Send + Sync + Clone { if let Err(e) = h.writable(io, &self.info.read().unwrap()) { debug!(target: "net", "Handshake write error: {}:{:?}", token, e); } - } + } } fn session_writable(&self, token: StreamToken, io: &IoContext>) { @@ -557,7 +557,7 @@ impl Host where Message: Send + Sync + Clone { debug!(target: "net", "Session write error: {}:{:?}", token, e); } io.update_registration(token).unwrap_or_else(|e| debug!(target: "net", "Session registration error: {:?}", e)); - } + } } fn connection_closed(&self, token: TimerToken, io: &IoContext>) { @@ -619,7 +619,7 @@ impl Host where Message: Send + Sync + Clone { }, Ok(SessionData::None) => {}, } - } + } if kill { self.kill_connection(token, io, true); //TODO: mark connection as dead an check in kill_connection } @@ -639,7 +639,7 @@ impl Host where Message: Send + Sync + Clone { if handshakes.get(token).is_none() { return; } - + // turn a handshake into a session let mut sessions = self.sessions.write().unwrap(); let mut h = handshakes.remove(token).unwrap(); @@ -782,7 +782,7 @@ impl IoHandler> for Host where Messa } io.update_registration(DISCOVERY).expect("Error updating discovery registration"); }, - TCP_ACCEPT => self.accept(io), + TCP_ACCEPT => self.accept(io), _ => panic!("Received unknown readable token"), } } @@ -858,7 +858,7 @@ impl IoHandler> for Host where Messa let session = { self.sessions.read().unwrap().get(*peer).cloned() }; if let Some(session) = session { session.lock().unwrap().disconnect(DisconnectReason::DisconnectRequested); - } + } self.kill_connection(*peer, io, false); }, NetworkIoMessage::User(ref message) => { @@ -961,14 +961,14 @@ fn load_key(path: &Path) -> Option { let mut buf = String::new(); match file.read_to_string(&mut buf) { Ok(_) => {}, - Err(e) => { + Err(e) => { warn!("Error reading key file: {:?}", e); return None; } } match Secret::from_str(&buf) { Ok(key) => Some(key), - Err(e) => { + Err(e) => { warn!("Error parsing key file: {:?}", e); None } @@ -977,7 +977,7 @@ fn load_key(path: &Path) -> Option { #[test] fn key_save_load() { - use tests::helpers::RandomTempPath; + use ::devtools::RandomTempPath; let temp_path = RandomTempPath::create_dir(); let key = H256::random(); save_key(temp_path.as_path(), &key); diff --git a/util/src/network/node_table.rs b/util/src/network/node_table.rs index 7ca060f75..ec6bad2aa 100644 --- a/util/src/network/node_table.rs +++ b/util/src/network/node_table.rs @@ -159,7 +159,7 @@ impl Display for Node { Ok(()) } } - + impl FromStr for Node { type Err = UtilError; fn from_str(s: &str) -> Result { @@ -265,7 +265,7 @@ impl NodeTable { let node_ids = self.nodes(); for i in 0 .. node_ids.len() { let node = self.nodes.get(&node_ids[i]).unwrap(); - json.push_str(&format!("\t{{ \"url\": \"{}\", \"failures\": {} }}{}\n", node, node.failures, if i == node_ids.len() - 1 {""} else {","})) + json.push_str(&format!("\t{{ \"url\": \"{}\", \"failures\": {} }}{}\n", node, node.failures, if i == node_ids.len() - 1 {""} else {","})) } json.push_str("]\n"); json.push_str("}"); @@ -297,14 +297,14 @@ impl NodeTable { let mut buf = String::new(); match file.read_to_string(&mut buf) { Ok(_) => {}, - Err(e) => { + Err(e) => { warn!("Error reading node table file: {:?}", e); return nodes; } } let json = match Json::from_str(&buf) { Ok(json) => json, - Err(e) => { + Err(e) => { warn!("Error parsing node table file: {:?}", e); return nodes; } @@ -344,7 +344,7 @@ mod tests { use std::str::FromStr; use std::net::*; use hash::*; - use tests::helpers::*; + use devtools::*; #[test] fn endpoint_parse() { diff --git a/util/src/tests/helpers.rs b/util/src/tests/helpers.rs deleted file mode 100644 index fee3d2cbb..000000000 --- a/util/src/tests/helpers.rs +++ /dev/null @@ -1,31 +0,0 @@ -use common::*; -use std::path::PathBuf; -use std::fs::{remove_dir_all}; -use std::env; - -pub struct RandomTempPath { - path: PathBuf -} - -impl RandomTempPath { - pub fn create_dir() -> RandomTempPath { - let mut dir = env::temp_dir(); - dir.push(H32::random().hex()); - fs::create_dir_all(dir.as_path()).unwrap(); - RandomTempPath { - path: dir.clone() - } - } - - pub fn as_path(&self) -> &PathBuf { - &self.path - } -} - -impl Drop for RandomTempPath { - fn drop(&mut self) { - if let Err(e) = remove_dir_all(self.as_path()) { - panic!("failed to remove temp directory, probably something failed to destroyed ({})", e); - } - } -} diff --git a/util/src/tests/mod.rs b/util/src/tests/mod.rs deleted file mode 100644 index 1630fabcd..000000000 --- a/util/src/tests/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod helpers;