Merge branch 'master' of github.com:ethcore/parity into db
This commit is contained in:
commit
61949d0ed4
28
Cargo.lock
generated
28
Cargo.lock
generated
@ -8,13 +8,13 @@ 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",
|
||||
"fdlimit 0.1.0",
|
||||
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -52,6 +52,11 @@ name = "bitflags"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "blastfig"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.3.0"
|
||||
@ -173,6 +178,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)",
|
||||
@ -183,6 +189,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"
|
||||
@ -198,7 +211,6 @@ dependencies = [
|
||||
"serde_codegen 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -211,6 +223,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)",
|
||||
@ -223,12 +236,14 @@ dependencies = [
|
||||
"rocksdb 0.3.0 (git+https://github.com/arkpar/rust-rocksdb.git)",
|
||||
"rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha3 0.1.0",
|
||||
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -793,6 +808,15 @@ dependencies = [
|
||||
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vergen"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"blastfig 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.5"
|
||||
|
@ -17,8 +17,8 @@ ethcore = { path = "ethcore" }
|
||||
ethsync = { path = "sync" }
|
||||
ethcore-rpc = { path = "rpc", optional = true }
|
||||
fdlimit = { path = "util/fdlimit" }
|
||||
target_info = "0.1"
|
||||
daemonize = "0.2"
|
||||
ethcore-devtools = { path = "devtools" }
|
||||
|
||||
[features]
|
||||
default = ["rpc"]
|
||||
|
16
devtools/Cargo.toml
Normal file
16
devtools/Cargo.toml
Normal file
@ -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 <admin@ethcore.io>"]
|
||||
|
||||
[dependencies]
|
||||
rand = "0.3"
|
||||
|
||||
[features]
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
test = true
|
1
devtools/README.md
Normal file
1
devtools/README.md
Normal file
@ -0,0 +1 @@
|
||||
# ethcore dev tools
|
24
devtools/src/lib.rs
Normal file
24
devtools/src/lib.rs
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! dev-tools
|
||||
|
||||
|
||||
extern crate rand;
|
||||
|
||||
pub mod random_path;
|
||||
|
||||
pub use random_path::*;
|
89
devtools/src/random_path.rs
Normal file
89
devtools/src/random_path.rs
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! 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::<f32>() * 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());
|
||||
}
|
@ -20,6 +20,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"]
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 3116f85a499ceaf4dfdc46726060fc056e2d7829
|
||||
Subproject commit f32954b3ddb5af2dc3dc9ec6d9a28bee848fdf70
|
@ -663,6 +663,7 @@ mod tests {
|
||||
use util::hash::*;
|
||||
use blockchain::*;
|
||||
use tests::helpers::*;
|
||||
use devtools::*;
|
||||
|
||||
#[test]
|
||||
fn valid_tests_extra32() {
|
||||
@ -678,7 +679,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);
|
||||
@ -695,7 +696,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(cyclomatic_complexity)]
|
||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
||||
fn test_small_fork() {
|
||||
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a059262c330941f3fe2a34d16d6e3c7b30d2ceb37c6a0e9a994c494ee1a61d2410885aa4c8bf8e56e264c0c0".from_hex().unwrap();
|
||||
let b1 = "f90261f901f9a05716670833ec874362d65fea27a7cd35af5897d275b31a44944113111e4e96d2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a0e78628dd45a1f8dc495594d83b76c588a3ee67463260f8b7d4a42f574aeab29aa0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882520884562791e580a051b3ecba4e3f2b49c11d42dd0851ec514b1be3138080f72a2b6e83868275d98f8877671f479c414b47f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca09e2709d7ec9bbe6b1bbbf0b2088828d14cd5e8642a1fee22dc74bfa89761a7f9a04bd8813dee4be989accdb708b1c2e325a7e9c695a8024e30e89d6c644e424747c0".from_hex().unwrap();
|
||||
@ -854,7 +855,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 {
|
||||
|
@ -25,7 +25,7 @@ struct FakeLogEntry {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug)]
|
||||
#[allow(enum_variant_names)] // Common prefix is C ;)
|
||||
#[cfg_attr(feature="dev", allow(enum_variant_names))] // Common prefix is C ;)
|
||||
enum FakeCallType {
|
||||
CALL, CREATE
|
||||
}
|
||||
|
@ -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<String> {
|
||||
init_log();
|
||||
|
@ -91,6 +91,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;
|
||||
|
@ -129,6 +129,7 @@ mod tests {
|
||||
use super::*;
|
||||
use tests::helpers::*;
|
||||
use util::network::*;
|
||||
use devtools::*;
|
||||
|
||||
#[test]
|
||||
fn it_can_be_started() {
|
||||
|
@ -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() {
|
||||
|
@ -17,6 +17,7 @@
|
||||
use client::{BlockChainClient, Client, BlockId};
|
||||
use tests::helpers::*;
|
||||
use common::*;
|
||||
use devtools::*;
|
||||
|
||||
#[test]
|
||||
fn created() {
|
||||
|
@ -15,16 +15,14 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
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 evm::{Schedule, Factory};
|
||||
use engine::*;
|
||||
use ethereum;
|
||||
use devtools::*;
|
||||
|
||||
#[cfg(feature = "json-tests")]
|
||||
pub enum ChainEra {
|
||||
@ -32,36 +30,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<T> {
|
||||
result: Option<T>,
|
||||
|
@ -425,7 +425,7 @@ function run_installer()
|
||||
depFound=$((depFound+1))
|
||||
check "multirust"
|
||||
isMultirust=true
|
||||
if [[ $(multirust show-default 2>/dev/null | grep beta | wc -l) == 4 ]]; then
|
||||
if [[ $(multirust show-default 2>/dev/null | grep beta | wc -l) == 3 ]]; then
|
||||
depFound=$((depFound+1))
|
||||
check "rust beta"
|
||||
isMultirustBeta=true
|
||||
|
@ -29,7 +29,6 @@ extern crate log as rlog;
|
||||
extern crate env_logger;
|
||||
extern crate ctrlc;
|
||||
extern crate fdlimit;
|
||||
extern crate target_info;
|
||||
extern crate daemonize;
|
||||
|
||||
#[cfg(feature = "rpc")]
|
||||
@ -51,7 +50,6 @@ use ethcore::ethereum;
|
||||
use ethcore::blockchain::CacheSize;
|
||||
use ethsync::EthSync;
|
||||
use docopt::Docopt;
|
||||
use target_info::Target;
|
||||
use daemonize::Daemonize;
|
||||
|
||||
const USAGE: &'static str = "
|
||||
@ -146,14 +144,15 @@ fn setup_rpc_server(_client: Arc<Client>, _sync: Arc<EthSync>, _url: &str) {
|
||||
|
||||
fn print_version() {
|
||||
println!("\
|
||||
Parity version {} ({}-{}-{})
|
||||
Parity
|
||||
version {}
|
||||
Copyright 2015, 2016 Ethcore (UK) Limited
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
By Wood/Paronyan/Kotewicz/Drwięga/Volf.\
|
||||
", env!("CARGO_PKG_VERSION"), Target::arch(), Target::env(), Target::os());
|
||||
", version());
|
||||
}
|
||||
|
||||
fn die_with_message(msg: &str) -> ! {
|
||||
|
@ -17,7 +17,6 @@ ethcore-util = { path = "../util" }
|
||||
ethcore = { path = "../ethcore" }
|
||||
ethsync = { path = "../sync" }
|
||||
clippy = { version = "0.0.42", optional = true }
|
||||
target_info = "0.1.0"
|
||||
rustc-serialize = "0.3"
|
||||
serde_macros = { version = "0.6.13", optional = true }
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#![cfg_attr(nightly, plugin(serde_macros, clippy))]
|
||||
|
||||
extern crate rustc_serialize;
|
||||
extern crate target_info;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate jsonrpc_core;
|
||||
|
@ -15,8 +15,8 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Web3 rpc implementation.
|
||||
use target_info::Target;
|
||||
use jsonrpc_core::*;
|
||||
use util::version;
|
||||
use v1::traits::Web3;
|
||||
|
||||
/// Web3 rpc implementation.
|
||||
@ -30,7 +30,9 @@ impl Web3Client {
|
||||
impl Web3 for Web3Client {
|
||||
fn client_version(&self, params: Params) -> Result<Value, Error> {
|
||||
match params {
|
||||
Params::None => Ok(Value::String(format!("Parity/-/{}/{}-{}-{}/rust1.8-nightly", env!("CARGO_PKG_VERSION"), Target::arch(), Target::env(), Target::os()))),
|
||||
Params::None => {
|
||||
Ok(Value::String(version())),
|
||||
}
|
||||
_ => Err(Error::invalid_params())
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ license = "GPL-3.0"
|
||||
name = "ethcore-util"
|
||||
version = "0.9.99"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
log = "0.3"
|
||||
@ -28,10 +29,16 @@ sha3 = { path = "sha3" }
|
||||
serde = "0.6.7"
|
||||
clippy = { version = "0.0.42", optional = true }
|
||||
json-tests = { path = "json-tests" }
|
||||
target_info = "0.1.0"
|
||||
rustc_version = "0.1.0"
|
||||
igd = "0.4.2"
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
libc = "0.2.7"
|
||||
vergen = "0.1"
|
||||
target_info = "0.1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
dev = ["clippy"]
|
||||
|
||||
[build-dependencies]
|
||||
vergen = "*"
|
||||
|
6
util/build.rs
Normal file
6
util/build.rs
Normal file
@ -0,0 +1,6 @@
|
||||
extern crate vergen;
|
||||
use vergen::*;
|
||||
|
||||
fn main() {
|
||||
vergen(OutputFns::all()).unwrap();
|
||||
}
|
@ -635,7 +635,7 @@ mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
#[allow(eq_op)]
|
||||
#[cfg_attr(feature="dev", allow(eq_op))]
|
||||
fn hash() {
|
||||
let h = H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
|
||||
assert_eq!(H64::from_str("0123456789abcdef").unwrap(), h);
|
||||
|
@ -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() {
|
||||
|
@ -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]
|
||||
|
@ -82,7 +82,6 @@
|
||||
//! cargo build --release
|
||||
//! ```
|
||||
|
||||
extern crate target_info;
|
||||
extern crate slab;
|
||||
extern crate rustc_serialize;
|
||||
extern crate mio;
|
||||
@ -106,7 +105,11 @@ extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate log as rlog;
|
||||
extern crate igd;
|
||||
extern crate ethcore_devtools as devtools;
|
||||
extern crate libc;
|
||||
extern crate rustc_version;
|
||||
extern crate target_info;
|
||||
extern crate vergen;
|
||||
|
||||
pub mod standard;
|
||||
#[macro_use]
|
||||
@ -163,5 +166,3 @@ pub use io::*;
|
||||
pub use log::*;
|
||||
pub use kvdb::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
@ -18,6 +18,10 @@
|
||||
|
||||
use std::fs::File;
|
||||
use common::*;
|
||||
use target_info::Target;
|
||||
use rustc_version;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/version.rs"));
|
||||
|
||||
#[derive(Debug,Clone,PartialEq,Eq)]
|
||||
/// Diff type for specifying a change (or not).
|
||||
@ -62,3 +66,8 @@ pub fn contents(name: &str) -> Result<Bytes, UtilError> {
|
||||
try!(file.read_to_end(&mut ret));
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
/// Get the standard version string for this software.
|
||||
pub fn version() -> String {
|
||||
format!("Parity//{}-{}-{}/{}-{}-{}/rustc{}", env!("CARGO_PKG_VERSION"), short_sha(), commit_date().replace("-", ""), Target::arch(), Target::os(), Target::env(), rustc_version::version())
|
||||
}
|
@ -175,13 +175,26 @@ impl Connection {
|
||||
self.socket.peer_addr()
|
||||
}
|
||||
|
||||
/// Clone this connection. Clears the receiving buffer of the returned connection.
|
||||
pub fn try_clone(&self) -> io::Result<Self> {
|
||||
Ok(Connection {
|
||||
token: self.token,
|
||||
socket: try!(self.socket.try_clone()),
|
||||
rec_buf: Vec::new(),
|
||||
rec_size: 0,
|
||||
send_queue: self.send_queue.clone(),
|
||||
interest: EventSet::hup() | EventSet::readable(),
|
||||
stats: self.stats.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Register this connection with the IO event loop.
|
||||
pub fn register_socket<Host: Handler>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> io::Result<()> {
|
||||
trace!(target: "net", "connection register; token={:?}", reg);
|
||||
event_loop.register(&self.socket, reg, self.interest, PollOpt::edge() | PollOpt::oneshot()).or_else(|e| {
|
||||
if let Err(e) = event_loop.register(&self.socket, reg, self.interest, PollOpt::edge() | PollOpt::oneshot()) {
|
||||
debug!("Failed to register {:?}, {:?}", reg, e);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update connection registration. Should be called at the end of the IO handler.
|
||||
@ -265,7 +278,7 @@ impl EncryptedConnection {
|
||||
}
|
||||
|
||||
/// Create an encrypted connection out of the handshake. Consumes a handshake object.
|
||||
pub fn new(mut handshake: Handshake) -> Result<EncryptedConnection, UtilError> {
|
||||
pub fn new(handshake: &mut Handshake) -> Result<EncryptedConnection, UtilError> {
|
||||
let shared = try!(crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_public));
|
||||
let mut nonce_material = H512::new();
|
||||
if handshake.originated {
|
||||
@ -300,9 +313,8 @@ impl EncryptedConnection {
|
||||
ingress_mac.update(&mac_material);
|
||||
ingress_mac.update(if handshake.originated { &handshake.ack_cipher } else { &handshake.auth_cipher });
|
||||
|
||||
handshake.connection.expect(ENCRYPTED_HEADER_LEN);
|
||||
Ok(EncryptedConnection {
|
||||
connection: handshake.connection,
|
||||
let mut enc = EncryptedConnection {
|
||||
connection: try!(handshake.connection.try_clone()),
|
||||
encoder: encoder,
|
||||
decoder: decoder,
|
||||
mac_encoder: mac_encoder,
|
||||
@ -311,7 +323,9 @@ impl EncryptedConnection {
|
||||
read_state: EncryptedConnectionState::Header,
|
||||
protocol_id: 0,
|
||||
payload_len: 0
|
||||
})
|
||||
};
|
||||
enc.connection.expect(ENCRYPTED_HEADER_LEN);
|
||||
Ok(enc)
|
||||
}
|
||||
|
||||
/// Send a packet
|
||||
@ -440,6 +454,12 @@ impl EncryptedConnection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Register socket with the event lpop. This should be called at the end of the event loop.
|
||||
pub fn register_socket<Host:Handler>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
|
||||
try!(self.connection.register_socket(reg, event_loop));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update connection registration. This should be called at the end of the event loop.
|
||||
pub fn update_socket<Host:Handler>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
|
||||
try!(self.connection.update_socket(reg, event_loop));
|
||||
|
@ -63,7 +63,9 @@ pub struct Handshake {
|
||||
/// A copy of received encryped auth packet
|
||||
pub auth_cipher: Bytes,
|
||||
/// A copy of received encryped ack packet
|
||||
pub ack_cipher: Bytes
|
||||
pub ack_cipher: Bytes,
|
||||
/// This Handshake is marked for deleteion flag
|
||||
pub expired: bool,
|
||||
}
|
||||
|
||||
const AUTH_PACKET_SIZE: usize = 307;
|
||||
@ -84,6 +86,7 @@ impl Handshake {
|
||||
remote_nonce: H256::new(),
|
||||
auth_cipher: Bytes::new(),
|
||||
ack_cipher: Bytes::new(),
|
||||
expired: false,
|
||||
})
|
||||
}
|
||||
|
||||
@ -97,6 +100,16 @@ impl Handshake {
|
||||
self.connection.token()
|
||||
}
|
||||
|
||||
/// Mark this handshake as inactive to be deleted lated.
|
||||
pub fn set_expired(&mut self) {
|
||||
self.expired = true;
|
||||
}
|
||||
|
||||
/// Check if this handshake is expired.
|
||||
pub fn expired(&self) -> bool {
|
||||
self.expired
|
||||
}
|
||||
|
||||
/// Start a handhsake
|
||||
pub fn start<Message>(&mut self, io: &IoContext<Message>, host: &HostInfo, originated: bool) -> Result<(), UtilError> where Message: Send + Clone{
|
||||
self.originated = originated;
|
||||
@ -118,47 +131,56 @@ impl Handshake {
|
||||
|
||||
/// Readable IO handler. Drives the state change.
|
||||
pub fn readable<Message>(&mut self, io: &IoContext<Message>, host: &HostInfo) -> Result<(), UtilError> where Message: Send + Clone {
|
||||
io.clear_timer(self.connection.token).unwrap();
|
||||
match self.state {
|
||||
HandshakeState::ReadingAuth => {
|
||||
if let Some(data) = try!(self.connection.readable()) {
|
||||
try!(self.read_auth(host, &data));
|
||||
try!(self.write_ack());
|
||||
};
|
||||
},
|
||||
HandshakeState::ReadingAck => {
|
||||
if let Some(data) = try!(self.connection.readable()) {
|
||||
try!(self.read_ack(host, &data));
|
||||
self.state = HandshakeState::StartSession;
|
||||
};
|
||||
},
|
||||
HandshakeState::StartSession => {},
|
||||
_ => { panic!("Unexpected state"); }
|
||||
}
|
||||
if self.state != HandshakeState::StartSession {
|
||||
try!(io.update_registration(self.connection.token));
|
||||
if !self.expired() {
|
||||
io.clear_timer(self.connection.token).unwrap();
|
||||
match self.state {
|
||||
HandshakeState::ReadingAuth => {
|
||||
if let Some(data) = try!(self.connection.readable()) {
|
||||
try!(self.read_auth(host, &data));
|
||||
try!(self.write_ack());
|
||||
};
|
||||
},
|
||||
HandshakeState::ReadingAck => {
|
||||
if let Some(data) = try!(self.connection.readable()) {
|
||||
try!(self.read_ack(host, &data));
|
||||
self.state = HandshakeState::StartSession;
|
||||
};
|
||||
},
|
||||
HandshakeState::StartSession => {},
|
||||
_ => { panic!("Unexpected state"); }
|
||||
}
|
||||
if self.state != HandshakeState::StartSession {
|
||||
try!(io.update_registration(self.connection.token));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writabe IO handler.
|
||||
pub fn writable<Message>(&mut self, io: &IoContext<Message>, _host: &HostInfo) -> Result<(), UtilError> where Message: Send + Clone {
|
||||
io.clear_timer(self.connection.token).unwrap();
|
||||
try!(self.connection.writable());
|
||||
if self.state != HandshakeState::StartSession {
|
||||
io.update_registration(self.connection.token).unwrap();
|
||||
if !self.expired() {
|
||||
io.clear_timer(self.connection.token).unwrap();
|
||||
try!(self.connection.writable());
|
||||
if self.state != HandshakeState::StartSession {
|
||||
io.update_registration(self.connection.token).unwrap();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Register the socket with the event loop
|
||||
pub fn register_socket<Host:Handler<Timeout=Token>>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
|
||||
try!(self.connection.register_socket(reg, event_loop));
|
||||
if !self.expired() {
|
||||
try!(self.connection.register_socket(reg, event_loop));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update socket registration with the event loop.
|
||||
pub fn update_socket<Host:Handler<Timeout=Token>>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
|
||||
try!(self.connection.update_socket(reg, event_loop));
|
||||
if !self.expired() {
|
||||
try!(self.connection.update_socket(reg, event_loop));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ use std::io::{Read, Write};
|
||||
use std::fs;
|
||||
use mio::*;
|
||||
use mio::tcp::*;
|
||||
use target_info::Target;
|
||||
use hash::*;
|
||||
use misc::version;
|
||||
use crypto::*;
|
||||
use sha3::Hashable;
|
||||
use rlp::*;
|
||||
@ -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<NetworkIoMessage<Message>>,
|
||||
protocol: ProtocolId,
|
||||
fn new(io: &'s IoContext<NetworkIoMessage<Message>>,
|
||||
protocol: ProtocolId,
|
||||
session: Option<StreamToken>, sessions: Arc<RwLock<Slab<SharedSession>>>) -> NetworkContext<'s, Message> {
|
||||
NetworkContext {
|
||||
io: io,
|
||||
@ -190,11 +190,11 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone
|
||||
let session = { self.sessions.read().unwrap().get(peer).cloned() };
|
||||
if let Some(session) = session {
|
||||
session.lock().unwrap().deref_mut().send_packet(self.protocol, packet_id as u8, &data).unwrap_or_else(|e| {
|
||||
warn!(target: "net", "Send error: {:?}", e);
|
||||
warn!(target: "network", "Send error: {:?}", e);
|
||||
}); //TODO: don't copy vector data
|
||||
try!(self.io.update_registration(peer));
|
||||
} else {
|
||||
trace!(target: "net", "Send: Peer no longer exist")
|
||||
trace!(target: "network", "Send: Peer no longer exist")
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -337,9 +337,9 @@ impl<Message> Host<Message> 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<Message> Host<Message> 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::<Message> {
|
||||
@ -360,7 +360,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
config: config,
|
||||
nonce: H256::random(),
|
||||
protocol_version: PROTOCOL_VERSION,
|
||||
client_version: format!("Parity/{}/{}-{}-{}", env!("CARGO_PKG_VERSION"), Target::arch(), Target::env(), Target::os()),
|
||||
client_version: version(),
|
||||
listen_port: 0,
|
||||
capabilities: Vec::new(),
|
||||
}),
|
||||
@ -470,18 +470,18 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
.take(min(MAX_HANDSHAKES_PER_ROUND, handshake_limit - handshake_count)) {
|
||||
self.connect_peer(&id, io);
|
||||
}
|
||||
debug!(target: "net", "Connecting peers: {} sessions, {} pending", self.session_count(), self.handshake_count());
|
||||
debug!(target: "network", "Connecting peers: {} sessions, {} pending", self.session_count(), self.handshake_count());
|
||||
}
|
||||
|
||||
#[cfg_attr(feature="dev", allow(single_match))]
|
||||
fn connect_peer(&self, id: &NodeId, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
if self.have_session(id)
|
||||
{
|
||||
trace!("Aborted connect. Node already connected.");
|
||||
trace!(target: "network", "Aborted connect. Node already connected.");
|
||||
return;
|
||||
}
|
||||
if self.connecting_to(id) {
|
||||
trace!("Aborted connect. Node already connecting.");
|
||||
trace!(target: "network", "Aborted connect. Node already connecting.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -493,7 +493,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
node.endpoint.address
|
||||
}
|
||||
else {
|
||||
debug!("Connection to expired node aborted");
|
||||
debug!(target: "network", "Connection to expired node aborted");
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -515,16 +515,16 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
if handshakes.insert_with(|token| {
|
||||
let mut handshake = Handshake::new(token, id, socket, &nonce, self.stats.clone()).expect("Can't create handshake");
|
||||
handshake.start(io, &self.info.read().unwrap(), id.is_some()).and_then(|_| io.register_stream(token)).unwrap_or_else (|e| {
|
||||
debug!(target: "net", "Handshake create error: {:?}", e);
|
||||
debug!(target: "network", "Handshake create error: {:?}", e);
|
||||
});
|
||||
Arc::new(Mutex::new(handshake))
|
||||
}).is_none() {
|
||||
debug!("Max handshakes reached");
|
||||
debug!(target: "network", "Max handshakes reached");
|
||||
}
|
||||
}
|
||||
|
||||
fn accept(&self, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
trace!(target: "net", "accept");
|
||||
trace!(target: "network", "Accepting incoming connection");
|
||||
loop {
|
||||
let socket = match self.tcp_listener.lock().unwrap().accept() {
|
||||
Ok(None) => break,
|
||||
@ -544,9 +544,9 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
if let Some(handshake) = handshake {
|
||||
let mut h = handshake.lock().unwrap();
|
||||
if let Err(e) = h.writable(io, &self.info.read().unwrap()) {
|
||||
debug!(target: "net", "Handshake write error: {}:{:?}", token, e);
|
||||
trace!(target: "network", "Handshake write error: {}: {:?}", token, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn session_writable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
@ -554,10 +554,10 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
if let Some(session) = session {
|
||||
let mut s = session.lock().unwrap();
|
||||
if let Err(e) = s.writable(io, &self.info.read().unwrap()) {
|
||||
debug!(target: "net", "Session write error: {}:{:?}", token, e);
|
||||
trace!(target: "network", "Session write error: {}: {:?}", token, e);
|
||||
}
|
||||
io.update_registration(token).unwrap_or_else(|e| debug!(target: "net", "Session registration error: {:?}", e));
|
||||
}
|
||||
io.update_registration(token).unwrap_or_else(|e| debug!(target: "network", "Session registration error: {:?}", e));
|
||||
}
|
||||
}
|
||||
|
||||
fn connection_closed(&self, token: TimerToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
@ -571,7 +571,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
if let Some(handshake) = handshake {
|
||||
let mut h = handshake.lock().unwrap();
|
||||
if let Err(e) = h.readable(io, &self.info.read().unwrap()) {
|
||||
debug!(target: "net", "Handshake read error: {}:{:?}", token, e);
|
||||
debug!(target: "network", "Handshake read error: {}: {:?}", token, e);
|
||||
kill = true;
|
||||
}
|
||||
if h.done() {
|
||||
@ -583,9 +583,9 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
return;
|
||||
} else if create_session {
|
||||
self.start_session(token, io);
|
||||
io.update_registration(token).unwrap_or_else(|e| debug!(target: "net", "Session registration error: {:?}", e));
|
||||
return;
|
||||
}
|
||||
io.update_registration(token).unwrap_or_else(|e| debug!(target: "net", "Token registration error: {:?}", e));
|
||||
io.update_registration(token).unwrap_or_else(|e| debug!(target: "network", "Token registration error: {:?}", e));
|
||||
}
|
||||
|
||||
fn session_readable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
@ -597,7 +597,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
let mut s = session.lock().unwrap();
|
||||
match s.readable(io, &self.info.read().unwrap()) {
|
||||
Err(e) => {
|
||||
debug!(target: "net", "Session read error: {}:{:?}", token, e);
|
||||
debug!(target: "network", "Session read error: {}: {:?}", token, e);
|
||||
kill = true;
|
||||
},
|
||||
Ok(SessionData::Ready) => {
|
||||
@ -613,13 +613,13 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
packet_id,
|
||||
}) => {
|
||||
match self.handlers.read().unwrap().get(protocol) {
|
||||
None => { warn!(target: "net", "No handler found for protocol: {:?}", protocol) },
|
||||
None => { warn!(target: "network", "No handler found for protocol: {:?}", protocol) },
|
||||
Some(_) => packet_data = Some((protocol, packet_id, data)),
|
||||
}
|
||||
},
|
||||
Ok(SessionData::None) => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
if kill {
|
||||
self.kill_connection(token, io, true); //TODO: mark connection as dead an check in kill_connection
|
||||
}
|
||||
@ -631,7 +631,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
let h = self.handlers.read().unwrap().get(p).unwrap().clone();
|
||||
h.read(&NetworkContext::new(io, p, Some(token), self.sessions.clone()), &token, packet_id, &data[1..]);
|
||||
}
|
||||
io.update_registration(token).unwrap_or_else(|e| debug!(target: "net", "Token registration error: {:?}", e));
|
||||
io.update_registration(token).unwrap_or_else(|e| debug!(target: "network", "Token registration error: {:?}", e));
|
||||
}
|
||||
|
||||
fn start_session(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||
@ -639,29 +639,28 @@ impl<Message> Host<Message> 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();
|
||||
// wait for other threads to stop using it
|
||||
{
|
||||
while Arc::get_mut(&mut h).is_none() {
|
||||
h.lock().ok();
|
||||
}
|
||||
let mut h = handshakes.get_mut(token).unwrap().lock().unwrap();
|
||||
if h.expired {
|
||||
return;
|
||||
}
|
||||
let h = Arc::try_unwrap(h).ok().unwrap().into_inner().unwrap();
|
||||
let originated = h.originated;
|
||||
let mut session = match Session::new(h, &self.info.read().unwrap()) {
|
||||
let mut session = match Session::new(&mut h, &self.info.read().unwrap()) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
debug!("Session creation error: {:?}", e);
|
||||
debug!(target: "network", "Session creation error: {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let result = sessions.insert_with(move |session_token| {
|
||||
session.set_token(session_token);
|
||||
io.update_registration(session_token).expect("Error updating session registration");
|
||||
io.deregister_stream(token).expect("Error deleting handshake registration");
|
||||
h.set_expired();
|
||||
io.register_stream(session_token).expect("Error creating session registration");
|
||||
self.stats.inc_sessions();
|
||||
trace!(target: "network", "Creating session {} -> {}", token, session_token);
|
||||
if !originated {
|
||||
// Add it no node table
|
||||
if let Ok(address) = session.remote_addr() {
|
||||
@ -690,26 +689,34 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
||||
FIRST_HANDSHAKE ... LAST_HANDSHAKE => {
|
||||
let handshakes = self.handshakes.write().unwrap();
|
||||
if let Some(handshake) = handshakes.get(token).cloned() {
|
||||
failure_id = Some(handshake.lock().unwrap().id().clone());
|
||||
let mut handshake = handshake.lock().unwrap();
|
||||
if !handshake.expired() {
|
||||
handshake.set_expired();
|
||||
failure_id = Some(handshake.id().clone());
|
||||
io.deregister_stream(token).expect("Error deregistering stream");
|
||||
}
|
||||
}
|
||||
},
|
||||
FIRST_SESSION ... LAST_SESSION => {
|
||||
let sessions = self.sessions.write().unwrap();
|
||||
if let Some(session) = sessions.get(token).cloned() {
|
||||
let s = session.lock().unwrap();
|
||||
if s.is_ready() {
|
||||
for (p, _) in self.handlers.read().unwrap().iter() {
|
||||
if s.have_capability(p) {
|
||||
to_disconnect.push(p);
|
||||
let mut s = session.lock().unwrap();
|
||||
if !s.expired() {
|
||||
if s.is_ready() {
|
||||
for (p, _) in self.handlers.read().unwrap().iter() {
|
||||
if s.have_capability(p) {
|
||||
to_disconnect.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
s.set_expired();
|
||||
failure_id = Some(s.id().clone());
|
||||
io.deregister_stream(token).expect("Error deregistering stream");
|
||||
}
|
||||
failure_id = Some(s.id().clone());
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
io.deregister_stream(token).expect("Error deregistering stream");
|
||||
if let Some(id) = failure_id {
|
||||
if remote {
|
||||
self.nodes.write().unwrap().note_failure(&id);
|
||||
@ -764,11 +771,11 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
||||
}
|
||||
|
||||
fn stream_hup(&self, io: &IoContext<NetworkIoMessage<Message>>, stream: StreamToken) {
|
||||
trace!(target: "net", "Hup: {}", stream);
|
||||
trace!(target: "network", "Hup: {}", stream);
|
||||
match stream {
|
||||
FIRST_SESSION ... LAST_SESSION => self.connection_closed(stream, io),
|
||||
FIRST_HANDSHAKE ... LAST_HANDSHAKE => self.connection_closed(stream, io),
|
||||
_ => warn!(target: "net", "Unexpected hup"),
|
||||
_ => warn!(target: "network", "Unexpected hup"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -777,12 +784,13 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
||||
FIRST_SESSION ... LAST_SESSION => self.session_readable(stream, io),
|
||||
FIRST_HANDSHAKE ... LAST_HANDSHAKE => self.handshake_readable(stream, io),
|
||||
DISCOVERY => {
|
||||
if let Some(node_changes) = self.discovery.as_ref().unwrap().lock().unwrap().readable() {
|
||||
let node_changes = { self.discovery.as_ref().unwrap().lock().unwrap().readable() };
|
||||
if let Some(node_changes) = node_changes {
|
||||
self.update_nodes(io, node_changes);
|
||||
}
|
||||
io.update_registration(DISCOVERY).expect("Error updating discovery registration");
|
||||
},
|
||||
TCP_ACCEPT => self.accept(io),
|
||||
TCP_ACCEPT => self.accept(io),
|
||||
_ => panic!("Received unknown readable token"),
|
||||
}
|
||||
}
|
||||
@ -809,14 +817,15 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
||||
io.update_registration(DISCOVERY).expect("Error updating discovery registration");
|
||||
},
|
||||
DISCOVERY_ROUND => {
|
||||
if let Some(node_changes) = self.discovery.as_ref().unwrap().lock().unwrap().round() {
|
||||
let node_changes = { self.discovery.as_ref().unwrap().lock().unwrap().round() };
|
||||
if let Some(node_changes) = node_changes {
|
||||
self.update_nodes(io, node_changes);
|
||||
}
|
||||
io.update_registration(DISCOVERY).expect("Error updating discovery registration");
|
||||
},
|
||||
_ => match self.timers.read().unwrap().get(&token).cloned() {
|
||||
Some(timer) => match self.handlers.read().unwrap().get(timer.protocol).cloned() {
|
||||
None => { warn!(target: "net", "No handler found for protocol: {:?}", timer.protocol) },
|
||||
None => { warn!(target: "network", "No handler found for protocol: {:?}", timer.protocol) },
|
||||
Some(h) => { h.timeout(&NetworkContext::new(io, timer.protocol, None, self.sessions.clone()), timer.token); }
|
||||
},
|
||||
None => { warn!("Unknown timer token: {}", token); } // timer is not registerd through us
|
||||
@ -858,7 +867,7 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> 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) => {
|
||||
@ -872,7 +881,10 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
||||
fn register_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
|
||||
match stream {
|
||||
FIRST_SESSION ... LAST_SESSION => {
|
||||
warn!("Unexpected session stream registration");
|
||||
let session = { self.sessions.read().unwrap().get(stream).cloned() };
|
||||
if let Some(session) = session {
|
||||
session.lock().unwrap().register_socket(reg, event_loop).expect("Error registering socket");
|
||||
}
|
||||
}
|
||||
FIRST_HANDSHAKE ... LAST_HANDSHAKE => {
|
||||
let connection = { self.handshakes.read().unwrap().get(stream).cloned() };
|
||||
@ -961,14 +973,14 @@ fn load_key(path: &Path) -> Option<Secret> {
|
||||
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 +989,7 @@ fn load_key(path: &Path) -> Option<Secret> {
|
||||
|
||||
#[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);
|
||||
|
@ -159,7 +159,7 @@ impl Display for Node {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl FromStr for Node {
|
||||
type Err = UtilError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
@ -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() {
|
||||
|
@ -41,6 +41,8 @@ pub struct Session {
|
||||
connection: EncryptedConnection,
|
||||
/// Session ready flag. Set after successfull Hello packet exchange
|
||||
had_hello: bool,
|
||||
/// Session is no longer active flag.
|
||||
expired: bool,
|
||||
ping_time_ns: u64,
|
||||
pong_time_ns: Option<u64>,
|
||||
}
|
||||
@ -109,8 +111,9 @@ const PACKET_USER: u8 = 0x10;
|
||||
const PACKET_LAST: u8 = 0x7f;
|
||||
|
||||
impl Session {
|
||||
/// Create a new session out of comepleted handshake. Consumes handshake object.
|
||||
pub fn new(h: Handshake, host: &HostInfo) -> Result<Session, UtilError> {
|
||||
/// Create a new session out of comepleted handshake. This clones the handshake connection object
|
||||
/// and leaves the handhsake in limbo to be deregistered from the event loop.
|
||||
pub fn new(h: &mut Handshake, host: &HostInfo) -> Result<Session, UtilError> {
|
||||
let id = h.id.clone();
|
||||
let connection = try!(EncryptedConnection::new(h));
|
||||
let mut session = Session {
|
||||
@ -125,6 +128,7 @@ impl Session {
|
||||
},
|
||||
ping_time_ns: 0,
|
||||
pong_time_ns: None,
|
||||
expired: false,
|
||||
};
|
||||
try!(session.write_hello(host));
|
||||
try!(session.send_ping());
|
||||
@ -141,6 +145,16 @@ impl Session {
|
||||
self.had_hello
|
||||
}
|
||||
|
||||
/// Mark this session as inactive to be deleted lated.
|
||||
pub fn set_expired(&mut self) {
|
||||
self.expired = true;
|
||||
}
|
||||
|
||||
/// Check if this session is expired.
|
||||
pub fn expired(&self) -> bool {
|
||||
self.expired
|
||||
}
|
||||
|
||||
/// Replace socket token
|
||||
pub fn set_token(&mut self, token: StreamToken) {
|
||||
self.connection.set_token(token);
|
||||
@ -153,6 +167,9 @@ impl Session {
|
||||
|
||||
/// Readable IO handler. Returns packet data if available.
|
||||
pub fn readable<Message>(&mut self, io: &IoContext<Message>, host: &HostInfo) -> Result<SessionData, UtilError> where Message: Send + Sync + Clone {
|
||||
if self.expired() {
|
||||
return Ok(SessionData::None)
|
||||
}
|
||||
match try!(self.connection.readable(io)) {
|
||||
Some(data) => Ok(try!(self.read_packet(data, host))),
|
||||
None => Ok(SessionData::None)
|
||||
@ -161,6 +178,9 @@ impl Session {
|
||||
|
||||
/// Writable IO handler. Sends pending packets.
|
||||
pub fn writable<Message>(&mut self, io: &IoContext<Message>, _host: &HostInfo) -> Result<(), UtilError> where Message: Send + Sync + Clone {
|
||||
if self.expired() {
|
||||
return Ok(())
|
||||
}
|
||||
self.connection.writable(io)
|
||||
}
|
||||
|
||||
@ -169,8 +189,20 @@ impl Session {
|
||||
self.info.capabilities.iter().any(|c| c.protocol == protocol)
|
||||
}
|
||||
|
||||
/// Register the session socket with the event loop
|
||||
pub fn register_socket<Host:Handler<Timeout = Token>>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
|
||||
if self.expired() {
|
||||
return Ok(());
|
||||
}
|
||||
try!(self.connection.register_socket(reg, event_loop));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update registration with the event loop. Should be called at the end of the IO handler.
|
||||
pub fn update_socket<Host:Handler>(&self, reg:Token, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
|
||||
if self.expired() {
|
||||
return Ok(());
|
||||
}
|
||||
self.connection.update_socket(reg, event_loop)
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ impl NetworkProtocolHandler<TestProtocolMessage> for TestProtocol {
|
||||
}
|
||||
|
||||
fn connected(&self, io: &NetworkContext<TestProtocolMessage>, peer: &PeerId) {
|
||||
assert!(io.peer_info(*peer).contains("parity"));
|
||||
assert!(io.peer_info(*peer).contains("Parity"));
|
||||
if self.drop_session {
|
||||
io.disconnect_peer(*peer)
|
||||
} else {
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
use std::thread;
|
||||
use std::ops::DerefMut;
|
||||
use std::any::Any;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
/// Thread-safe closure for handling possible panics
|
||||
@ -73,9 +72,8 @@ impl PanicHandler {
|
||||
/// Invoke closure and catch any possible panics.
|
||||
/// In case of panic notifies all listeners about it.
|
||||
#[cfg_attr(feature="dev", allow(deprecated))]
|
||||
// TODO [todr] catch_panic is deprecated but panic::recover has different bounds (not allowing mutex)
|
||||
pub fn catch_panic<G, R>(&self, g: G) -> thread::Result<R> where G: FnOnce() -> R + Send + 'static {
|
||||
let guard = PanicGuard { handler: self };
|
||||
let _guard = PanicGuard { handler: self };
|
||||
let result = g();
|
||||
Ok(result)
|
||||
}
|
||||
@ -108,13 +106,6 @@ impl<F> OnPanicListener for F
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_to_string(t: &Box<Any + Send>) -> Option<String> {
|
||||
let as_str = t.downcast_ref::<&'static str>().cloned().map(|t| t.to_owned());
|
||||
let as_string = t.downcast_ref::<String>().cloned();
|
||||
|
||||
as_str.or(as_string)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // panic forwarding doesnt work on the same thread in beta
|
||||
fn should_notify_listeners_about_panic () {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
pub mod helpers;
|
@ -991,7 +991,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(eq_op)]
|
||||
#[cfg_attr(feature="dev", allow(eq_op))]
|
||||
pub fn uint256_comp_test() {
|
||||
let small = U256([10u64, 0, 0, 0]);
|
||||
let big = U256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]);
|
||||
|
Loading…
Reference in New Issue
Block a user