From 18582d7b654382473a831eda59dc3d5139b39efe Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 30 Jun 2017 11:26:09 +0300 Subject: [PATCH 001/119] do not cache ACL storage contract --- secret_store/src/acl_storage.rs | 54 ++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index 816d100dc..8ddc9a6e3 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -20,6 +20,7 @@ use parking_lot::Mutex; use ethkey::public_to_address; use ethcore::client::{Client, BlockChainClient, BlockId}; use native_contracts::SecretStoreAclStorage; +use util::{H256, Address}; use types::all::{Error, ServerKeyId, Public}; const ACL_CHECKER_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_acl_checker"; @@ -32,33 +33,64 @@ pub trait AclStorage: Send + Sync { /// On-chain ACL storage implementation. pub struct OnChainAclStorage { + /// Cached on-chain contract. + contract: Mutex, +} + +/// Cached on-chain ACL storage contract. +struct CachedContract { /// Blockchain client. client: Arc, - /// On-chain contract. - contract: Mutex>, + /// Hash of best block, when contract address has been read. + best_block_hash: Option, + /// Contract address. + contract_addr: Option
, + /// Contract at given address. + contract: Option, } impl OnChainAclStorage { pub fn new(client: Arc) -> Self { OnChainAclStorage { - client: client, - contract: Mutex::new(None), + contract: Mutex::new(CachedContract::new(client)), } } } impl AclStorage for OnChainAclStorage { fn check(&self, public: &Public, document: &ServerKeyId) -> Result { - let mut contract = self.contract.lock(); - if !contract.is_some() { - *contract = self.client.registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.to_owned()) - .and_then(|contract_addr| { + self.contract.lock().check(public, document) + } +} + +impl CachedContract { + pub fn new(client: Arc) -> Self { + CachedContract { + client: client, + best_block_hash: None, + contract_addr: None, + contract: None, + } + } + + pub fn check(&mut self, public: &Public, document: &ServerKeyId) -> Result { + let new_best_block_hash = self.client.best_block_header().hash(); + if self.best_block_hash.as_ref() != Some(&new_best_block_hash) { + let new_contract_addr = self.client.registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.to_owned()); + if self.contract_addr.as_ref() != new_contract_addr.as_ref() { + self.contract = new_contract_addr.map(|contract_addr| { trace!(target: "secretstore", "Configuring for ACL checker contract from {}", contract_addr); - Some(SecretStoreAclStorage::new(contract_addr)) - }) + SecretStoreAclStorage::new(contract_addr) + }); + + self.contract_addr = new_contract_addr; + } + + self.best_block_hash = Some(new_best_block_hash); } - if let Some(ref contract) = *contract { + + if let Some(contract) = self.contract.as_ref() { let address = public_to_address(&public); let do_call = |a, d| future::done(self.client.call_contract(BlockId::Latest, a, d)); contract.check_permissions(do_call, address, document.clone()) From 5cc40d45251196353bf2b99dd0ad09c38c9ecae1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 14 Jul 2017 14:51:24 +0300 Subject: [PATCH 002/119] when error comes before initialization --- .../key_server_cluster/jobs/job_session.rs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/secret_store/src/key_server_cluster/jobs/job_session.rs b/secret_store/src/key_server_cluster/jobs/job_session.rs index 7ae1da42a..6608397dd 100644 --- a/secret_store/src/key_server_cluster/jobs/job_session.rs +++ b/secret_store/src/key_server_cluster/jobs/job_session.rs @@ -299,22 +299,22 @@ impl JobSession where Executor: JobExe return Err(Error::ConsensusUnreachable); } - let active_data = self.data.active_data.as_mut() - .expect("we have checked that we are on master node; on master nodes active_data is filled during initialization; qed"); - if active_data.rejects.contains(node) { - return Ok(()); - } - if active_data.requests.remove(node) || active_data.responses.remove(node).is_some() { - active_data.rejects.insert(node.clone()); - if self.data.state == JobSessionState::Finished && active_data.responses.len() < self.meta.threshold + 1 { - self.data.state = JobSessionState::Active; - } - if active_data.requests.len() + active_data.responses.len() >= self.meta.threshold + 1 { + if let Some(active_data) = self.data.active_data.as_mut() { + if active_data.rejects.contains(node) { return Ok(()); } + if active_data.requests.remove(node) || active_data.responses.remove(node).is_some() { + active_data.rejects.insert(node.clone()); + if self.data.state == JobSessionState::Finished && active_data.responses.len() < self.meta.threshold + 1 { + self.data.state = JobSessionState::Active; + } + if active_data.requests.len() + active_data.responses.len() >= self.meta.threshold + 1 { + return Ok(()); + } - self.data.state = JobSessionState::Failed; - return Err(Error::ConsensusUnreachable); + self.data.state = JobSessionState::Failed; + return Err(Error::ConsensusUnreachable); + } } Ok(()) From 81de7e1075600dbaca46bc14baab6cf56ec7c4e0 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 19 Jul 2017 11:35:17 +0300 Subject: [PATCH 003/119] initial KeyServerSet commit --- Cargo.lock | 1 + ethcore/native_contracts/build.rs | 2 + .../native_contracts/res/key_server_set.json | 1 + .../native_contracts/src/key_server_set.rs | 21 +++ ethcore/native_contracts/src/lib.rs | 2 + secret_store/Cargo.toml | 1 + secret_store/src/acl_storage.rs | 61 ++++---- secret_store/src/key_server.rs | 11 +- .../src/key_server_cluster/cluster.rs | 13 +- .../key_server_cluster/cluster_sessions.rs | 2 +- secret_store/src/key_server_cluster/mod.rs | 1 + secret_store/src/key_server_set.rs | 145 ++++++++++++++++++ secret_store/src/lib.rs | 10 +- 13 files changed, 230 insertions(+), 41 deletions(-) create mode 100644 ethcore/native_contracts/res/key_server_set.json create mode 100644 ethcore/native_contracts/src/key_server_set.rs create mode 100644 secret_store/src/key_server_set.rs diff --git a/Cargo.lock b/Cargo.lock index ad3cca5c7..ae33d7590 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -669,6 +669,7 @@ dependencies = [ "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "native-contracts 0.1.0", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/native_contracts/build.rs b/ethcore/native_contracts/build.rs index cec830929..bcb64067c 100644 --- a/ethcore/native_contracts/build.rs +++ b/ethcore/native_contracts/build.rs @@ -21,6 +21,7 @@ use std::fs::File; use std::io::Write; // TODO: just walk the "res" directory and generate whole crate automatically. +const KEY_SERVER_SET_ABI: &'static str = include_str!("res/key_server_set.json"); const REGISTRY_ABI: &'static str = include_str!("res/registrar.json"); const URLHINT_ABI: &'static str = include_str!("res/urlhint.json"); const SERVICE_TRANSACTION_ABI: &'static str = include_str!("res/service_transaction.json"); @@ -45,6 +46,7 @@ fn build_test_contracts() { } fn main() { + build_file("KeyServerSet", KEY_SERVER_SET_ABI, "key_server_set.rs"); build_file("Registry", REGISTRY_ABI, "registry.rs"); build_file("Urlhint", URLHINT_ABI, "urlhint.rs"); build_file("ServiceTransactionChecker", SERVICE_TRANSACTION_ABI, "service_transaction.rs"); diff --git a/ethcore/native_contracts/res/key_server_set.json b/ethcore/native_contracts/res/key_server_set.json new file mode 100644 index 000000000..93f68837a --- /dev/null +++ b/ethcore/native_contracts/res/key_server_set.json @@ -0,0 +1 @@ +[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"keyServersList","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"keyServer","type":"address"}],"name":"getKeyServerPublic","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getKeyServers","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"keyServer","type":"address"}],"name":"getKeyServerAddress","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"keyServer","type":"address"}],"name":"removeKeyServer","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"keyServerPublic","type":"bytes"},{"name":"keyServerIp","type":"string"}],"name":"addKeyServer","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keyServer","type":"address"}],"name":"KeyServerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keyServer","type":"address"}],"name":"KeyServerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}] \ No newline at end of file diff --git a/ethcore/native_contracts/src/key_server_set.rs b/ethcore/native_contracts/src/key_server_set.rs new file mode 100644 index 000000000..60b137aae --- /dev/null +++ b/ethcore/native_contracts/src/key_server_set.rs @@ -0,0 +1,21 @@ +// Copyright 2015-2017 Parity Technologies (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 . + +#![allow(unused_mut, unused_variables, unused_imports)] + +//! Secret store Key Server set contract. + +include!(concat!(env!("OUT_DIR"), "/key_server_set.rs")); diff --git a/ethcore/native_contracts/src/lib.rs b/ethcore/native_contracts/src/lib.rs index e35a4ec19..33cb91563 100644 --- a/ethcore/native_contracts/src/lib.rs +++ b/ethcore/native_contracts/src/lib.rs @@ -23,6 +23,7 @@ extern crate byteorder; extern crate ethabi; extern crate ethcore_util as util; +mod key_server_set; mod registry; mod urlhint; mod service_transaction; @@ -32,6 +33,7 @@ mod validator_report; pub mod test_contracts; +pub use self::key_server_set::KeyServerSet; pub use self::registry::Registry; pub use self::urlhint::Urlhint; pub use self::service_transaction::ServiceTransactionChecker; diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index eea49978d..19f342aa9 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -35,3 +35,4 @@ ethcore-logger = { path = "../logger" } ethcrypto = { path = "../ethcrypto" } ethkey = { path = "../ethkey" } native-contracts = { path = "../ethcore/native_contracts" } +lazy_static = "0.2" diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index 8ddc9a6e3..7ae72cbfc 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::sync::Arc; +use std::sync::{Arc, Weak}; use futures::{future, Future}; use parking_lot::Mutex; use ethkey::public_to_address; -use ethcore::client::{Client, BlockChainClient, BlockId}; +use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify}; use native_contracts::SecretStoreAclStorage; -use util::{H256, Address}; +use util::{H256, Address, Bytes}; use types::all::{Error, ServerKeyId, Public}; const ACL_CHECKER_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_acl_checker"; @@ -40,9 +40,7 @@ pub struct OnChainAclStorage { /// Cached on-chain ACL storage contract. struct CachedContract { /// Blockchain client. - client: Arc, - /// Hash of best block, when contract address has been read. - best_block_hash: Option, + client: Weak, /// Contract address. contract_addr: Option
, /// Contract at given address. @@ -50,10 +48,12 @@ struct CachedContract { } impl OnChainAclStorage { - pub fn new(client: Arc) -> Self { - OnChainAclStorage { + pub fn new(client: &Arc) -> Arc { + let acl_storage = Arc::new(OnChainAclStorage { contract: Mutex::new(CachedContract::new(client)), - } + }); + client.add_notify(acl_storage.clone()); + acl_storage } } @@ -63,20 +63,24 @@ impl AclStorage for OnChainAclStorage { } } +impl ChainNotify for OnChainAclStorage { + fn new_blocks(&self, _imported: Vec, _invalid: Vec, _enacted: Vec, _retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { + self.contract.lock().update() + } +} + impl CachedContract { - pub fn new(client: Arc) -> Self { + pub fn new(client: &Arc) -> Self { CachedContract { - client: client, - best_block_hash: None, + client: Arc::downgrade(client), contract_addr: None, contract: None, } } - pub fn check(&mut self, public: &Public, document: &ServerKeyId) -> Result { - let new_best_block_hash = self.client.best_block_header().hash(); - if self.best_block_hash.as_ref() != Some(&new_best_block_hash) { - let new_contract_addr = self.client.registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.to_owned()); + pub fn update(&mut self) { + if let Some(client) = self.client.upgrade() { + let new_contract_addr = client.registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.to_owned()); if self.contract_addr.as_ref() != new_contract_addr.as_ref() { self.contract = new_contract_addr.map(|contract_addr| { trace!(target: "secretstore", "Configuring for ACL checker contract from {}", contract_addr); @@ -86,18 +90,23 @@ impl CachedContract { self.contract_addr = new_contract_addr; } - - self.best_block_hash = Some(new_best_block_hash); } + } - if let Some(contract) = self.contract.as_ref() { - let address = public_to_address(&public); - let do_call = |a, d| future::done(self.client.call_contract(BlockId::Latest, a, d)); - contract.check_permissions(do_call, address, document.clone()) - .map_err(|err| Error::Internal(err)) - .wait() - } else { - Err(Error::Internal("ACL checker contract is not configured".to_owned())) + pub fn check(&mut self, public: &Public, document: &ServerKeyId) -> Result { + match self.contract.as_ref() { + Some(contract) => { + let address = public_to_address(&public); + let do_call = |a, d| future::done( + self.client + .upgrade() + .ok_or("Calling contract without client".into()) + .and_then(|c| c.call_contract(BlockId::Latest, a, d))); + contract.check_permissions(do_call, address, document.clone()) + .map_err(|err| Error::Internal(err)) + .wait() + }, + None => Err(Error::Internal("ACL checker contract is not configured".to_owned())), } } } diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index fd4e154fa..969782ca2 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -24,6 +24,7 @@ use ethcrypto; use ethkey; use super::acl_storage::AclStorage; use super::key_storage::KeyStorage; +use super::key_server_set::KeyServerSet; use key_server_cluster::{math, ClusterCore}; use traits::{ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer}; use types::all::{Error, Public, RequestSignature, ServerKeyId, EncryptedDocumentKey, EncryptedDocumentKeyShadow, @@ -44,9 +45,9 @@ pub struct KeyServerCore { impl KeyServerImpl { /// Create new key server instance - pub fn new(config: &ClusterConfiguration, acl_storage: Arc, key_storage: Arc) -> Result { + pub fn new(config: &ClusterConfiguration, key_server_set: Arc, acl_storage: Arc, key_storage: Arc) -> Result { Ok(KeyServerImpl { - data: Arc::new(Mutex::new(KeyServerCore::new(config, acl_storage, key_storage)?)), + data: Arc::new(Mutex::new(KeyServerCore::new(config, key_server_set, acl_storage, key_storage)?)), }) } @@ -143,14 +144,12 @@ impl MessageSigner for KeyServerImpl { } impl KeyServerCore { - pub fn new(config: &ClusterConfiguration, acl_storage: Arc, key_storage: Arc) -> Result { + pub fn new(config: &ClusterConfiguration, key_server_set: Arc, acl_storage: Arc, key_storage: Arc) -> Result { let config = NetClusterConfiguration { threads: config.threads, self_key_pair: ethkey::KeyPair::from_secret_slice(&config.self_private)?, listen_address: (config.listener_address.address.clone(), config.listener_address.port), - nodes: config.nodes.iter() - .map(|(node_id, node_address)| (node_id.clone(), (node_address.address.clone(), node_address.port))) - .collect(), + key_server_set: key_server_set, allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes, acl_storage: acl_storage, key_storage: key_storage, diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index c86f30267..b929e835d 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -28,7 +28,7 @@ use tokio_core::reactor::{Handle, Remote, Interval}; use tokio_core::net::{TcpListener, TcpStream}; use ethkey::{Public, KeyPair, Signature, Random, Generator}; use util::H256; -use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage}; +use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet}; use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, GenerationSessionWrapper, EncryptionSessionWrapper, DecryptionSessionWrapper, SigningSessionWrapper}; use key_server_cluster::message::{self, Message, ClusterMessage, GenerationMessage, EncryptionMessage, DecryptionMessage, @@ -102,8 +102,8 @@ pub struct ClusterConfiguration { pub self_key_pair: KeyPair, /// Interface to listen to. pub listen_address: (String, u16), - /// Cluster nodes. - pub nodes: BTreeMap, + /// Cluster nodes set. + pub key_server_set: Arc, /// Reference to key storage pub key_storage: Arc, /// Reference to ACL storage @@ -671,9 +671,10 @@ impl ClusterConnections { connections: RwLock::new(BTreeMap::new()), }; - for (node_id, &(ref node_addr, node_port)) in config.nodes.iter().filter(|&(node_id, _)| node_id != config.self_key_pair.public()) { - let socket_address = make_socket_address(&node_addr, node_port)?; - connections.nodes.insert(node_id.clone(), socket_address); + let nodes = config.key_server_set.get(); + for (node_id, socket_address) in nodes.iter().filter(|&(node_id, _)| node_id != config.self_key_pair.public()) { + //let socket_address = make_socket_address(&node_addr, node_port)?; + connections.nodes.insert(node_id.clone(), socket_address.clone()); } Ok(connections) diff --git a/secret_store/src/key_server_cluster/cluster_sessions.rs b/secret_store/src/key_server_cluster/cluster_sessions.rs index f66ad972f..f8e4974b1 100644 --- a/secret_store/src/key_server_cluster/cluster_sessions.rs +++ b/secret_store/src/key_server_cluster/cluster_sessions.rs @@ -135,7 +135,7 @@ impl ClusterSessions { pub fn new(config: &ClusterConfiguration) -> Self { ClusterSessions { self_node_id: config.self_key_pair.public().clone(), - nodes: config.nodes.keys().cloned().collect(), + nodes: config.key_server_set.get().keys().cloned().collect(), acl_storage: config.acl_storage.clone(), key_storage: config.key_storage.clone(), generation_sessions: ClusterSessionsContainer::new(), diff --git a/secret_store/src/key_server_cluster/mod.rs b/secret_store/src/key_server_cluster/mod.rs index 71c505f95..11c32d528 100644 --- a/secret_store/src/key_server_cluster/mod.rs +++ b/secret_store/src/key_server_cluster/mod.rs @@ -23,6 +23,7 @@ use super::types::all::ServerKeyId; pub use super::types::all::{NodeId, EncryptedDocumentKeyShadow}; pub use super::acl_storage::AclStorage; pub use super::key_storage::{KeyStorage, DocumentKeyShare}; +pub use super::key_server_set::KeyServerSet; pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic, SerializableMessageHash}; pub use self::cluster::{ClusterCore, ClusterConfiguration, ClusterClient}; pub use self::generation_session::Session as GenerationSession; diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs new file mode 100644 index 000000000..22ffbdb07 --- /dev/null +++ b/secret_store/src/key_server_set.rs @@ -0,0 +1,145 @@ +// Copyright 2015-2017 Parity Technologies (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 . + +use std::sync::{Arc, Weak}; +use std::net::SocketAddr; +use std::collections::HashMap; +use futures::{future, Future}; +use parking_lot::Mutex; +use ethcore::filter::Filter; +use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify}; +use native_contracts::KeyServerSet as KeyServerSetContract; +use util::{H256, Address, Bytes, Hashable}; +use types::all::Public; + +const KEY_SERVER_SET_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_server_set"; + +// TODO: ethabi should be able to generate this. +const ADDED_EVENT_NAME: &'static [u8] = &*b"KeyServerAdded()"; +const REMOVED_EVENT_NAME: &'static [u8] = &*b"KeyServerRemoved()"; + +lazy_static! { + static ref ADDED_EVENT_NAME_HASH: H256 = ADDED_EVENT_NAME.sha3(); + static ref REMOVED_EVENT_NAME_HASH: H256 = REMOVED_EVENT_NAME.sha3(); +} + +/// Key Server set +pub trait KeyServerSet: Send + Sync { + /// Get set of configured key servers + fn get(&self) -> HashMap; +} + +/// On-chain Key Server set implementation. +pub struct OnChainKeyServerSet { + /// Cached on-chain contract. + contract: Mutex, +} + +/// Cached on-chain Key Server set contract. +struct CachedContract { + /// Blockchain client. + client: Weak, + /// Contract address. + contract_addr: Option
, + /// Active set of key servers. + key_servers: HashMap, +} + +impl OnChainKeyServerSet { + pub fn new(client: &Arc, key_servers: HashMap) -> Arc { + let key_server_set = Arc::new(OnChainKeyServerSet { + contract: Mutex::new(CachedContract::new(client, key_servers)), + }); + client.add_notify(key_server_set.clone()); + key_server_set + } +} + +impl KeyServerSet for OnChainKeyServerSet { + fn get(&self) -> HashMap { + self.contract.lock().get() + } +} + +impl ChainNotify for OnChainKeyServerSet { + fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { + self.contract.lock().update(enacted, retracted) + } +} + +impl CachedContract { + pub fn new(client: &Arc, key_servers: HashMap) -> Self { + CachedContract { + client: Arc::downgrade(client), + contract_addr: None, + key_servers: key_servers, + } + } + + pub fn update(&mut self, enacted: Vec, _retracted: Vec) { + if let Some(client) = self.client.upgrade() { + let new_contract_addr = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned()); + + // new contract installed + if self.contract_addr.as_ref() != new_contract_addr.as_ref() { +println!("=== Installing contract from address: {:?}", new_contract_addr); + self.key_servers = new_contract_addr.map(|contract_addr| { + trace!(target: "secretstore", "Configuring for key server set contract from {}", contract_addr); + + KeyServerSetContract::new(contract_addr) + }) + .map(|contract| { + let mut key_servers = HashMap::new(); + let do_call = |a, d| future::done(self.client.upgrade().ok_or("Calling contract without client".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))); + let key_servers_list = contract.get_key_servers(do_call).wait() + .map_err(|err| { trace!(target: "secretstore", "Error {} reading list of key servers from contract", err); err }) + .unwrap_or_default(); + for key_server in key_servers_list { + let key_server_public = contract.get_key_server_public( + |a, d| future::done(self.client.upgrade().ok_or("Calling contract without client".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))), key_server).wait() + .and_then(|p| if p.len() == 64 { Ok(Public::from_slice(&p)) } else { Err(format!("Invalid public length {}", p.len())) }); + let key_server_ip = contract.get_key_server_address( + |a, d| future::done(self.client.upgrade().ok_or("Calling contract without client".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))), key_server).wait() + .and_then(|a| a.parse().map_err(|e| format!("Invalid ip address: {}", e))); + if let (Ok(key_server_public), Ok(key_server_ip)) = (key_server_public, key_server_ip) { + key_servers.insert(key_server_public, key_server_ip); + } + } + key_servers + }) + .unwrap_or_default(); + + return; + } + + // check for events + for enacted_hash in enacted { + let filter = Filter { + from_block: BlockId::Hash(enacted_hash.clone()), + to_block: BlockId::Hash(enacted_hash.clone()), + address: self.contract_addr.clone().map(|a| vec![a]), + topics: vec![Some(vec![*ADDED_EVENT_NAME_HASH]), Some(vec![*REMOVED_EVENT_NAME_HASH])], + limit: None, + }; + println!("=== Number of filtered log entries: {}", client.logs(filter).len()); + } + } + } + + fn get(&self) -> HashMap { + self.key_servers.clone() + } +} diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index f8a74dd1a..235d0edd9 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -21,6 +21,8 @@ extern crate log; extern crate futures; extern crate futures_cpupool; extern crate hyper; +#[macro_use] +extern crate lazy_static; extern crate parking_lot; extern crate rustc_hex; extern crate serde; @@ -56,6 +58,7 @@ mod http_listener; mod key_server; mod key_storage; mod serialization; +mod key_server_set; use std::sync::Arc; use ethcore::client::Client; @@ -68,9 +71,12 @@ pub use traits::{KeyServer}; pub fn start(client: Arc, config: ServiceConfiguration) -> Result, Error> { use std::sync::Arc; - let acl_storage = Arc::new(acl_storage::OnChainAclStorage::new(client)); + let acl_storage = acl_storage::OnChainAclStorage::new(&client); + let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone() + .into_iter() + .map(|a| (a.0, format!("{}:{}", a.1.address, a.1.port).parse().unwrap())).collect()); // TODO: remove after switching to enode:/// let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?); - let key_server = key_server::KeyServerImpl::new(&config.cluster_config, acl_storage, key_storage)?; + let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, acl_storage, key_storage)?; let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?; Ok(Box::new(listener)) } From 5080cc3c9edd822d3436df989bf453f89336a89d Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 19 Jul 2017 12:36:40 +0300 Subject: [PATCH 004/119] update_nodes_set in maintain --- .../src/key_server_cluster/cluster.rs | 70 ++++++++++++------- secret_store/src/key_server_set.rs | 16 ++--- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index b929e835d..3f381b6f0 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -158,9 +158,17 @@ pub struct ClusterConnections { /// Self node id. pub self_node_id: NodeId, /// All known other key servers. - pub nodes: BTreeMap, + pub key_server_set: Arc, + /// Connections data. + pub data: RwLock, +} + +/// Cluster connections data. +pub struct ClusterConnectionsData { + /// Active key servers set. + pub nodes: BTreeMap, /// Active connections to key servers. - pub connections: RwLock>>, + pub connections: BTreeMap>, } /// Cluster view core. @@ -354,6 +362,7 @@ impl ClusterCore { /// Try to connect to every disconnected node. fn connect_disconnected_nodes(data: Arc) { + data.connections.update_nodes_set(); for (node_id, node_address) in data.connections.disconnected_nodes() { if data.config.allow_connecting_to_higher_nodes || data.self_key_pair.public() < &node_id { ClusterCore::connect(data.clone(), node_address); @@ -665,34 +674,29 @@ impl ClusterCore { impl ClusterConnections { pub fn new(config: &ClusterConfiguration) -> Result { - let mut connections = ClusterConnections { + Ok(ClusterConnections { self_node_id: config.self_key_pair.public().clone(), - nodes: BTreeMap::new(), - connections: RwLock::new(BTreeMap::new()), - }; - - let nodes = config.key_server_set.get(); - for (node_id, socket_address) in nodes.iter().filter(|&(node_id, _)| node_id != config.self_key_pair.public()) { - //let socket_address = make_socket_address(&node_addr, node_port)?; - connections.nodes.insert(node_id.clone(), socket_address.clone()); - } - - Ok(connections) + key_server_set: config.key_server_set.clone(), + data: RwLock::new(ClusterConnectionsData { + nodes: config.key_server_set.get(), + connections: BTreeMap::new(), + }), + }) } pub fn cluster_state(&self) -> ClusterState { ClusterState { - connected: self.connections.read().keys().cloned().collect(), + connected: self.data.read().connections.keys().cloned().collect(), } } pub fn get(&self, node: &NodeId) -> Option> { - self.connections.read().get(node).cloned() + self.data.read().connections.get(node).cloned() } pub fn insert(&self, connection: Arc) -> bool { - let mut connections = self.connections.write(); - if connections.contains_key(connection.node_id()) { + let mut data = self.data.write(); + if data.connections.contains_key(connection.node_id()) { // we have already connected to the same node // the agreement is that node with lower id must establish connection to node with higher id if (&self.self_node_id < connection.node_id() && connection.is_inbound()) @@ -702,13 +706,13 @@ impl ClusterConnections { } trace!(target: "secretstore_net", "{}: inserting connection to {} at {}", self.self_node_id, connection.node_id(), connection.node_address()); - connections.insert(connection.node_id().clone(), connection); + data.connections.insert(connection.node_id().clone(), connection); true } pub fn remove(&self, node: &NodeId, is_inbound: bool) { - let mut connections = self.connections.write(); - if let Entry::Occupied(entry) = connections.entry(node.clone()) { + let mut data = self.data.write(); + if let Entry::Occupied(entry) = data.connections.entry(node.clone()) { if entry.get().is_inbound() != is_inbound { return; } @@ -719,20 +723,34 @@ impl ClusterConnections { } pub fn connected_nodes(&self) -> BTreeSet { - self.connections.read().keys().cloned().collect() + self.data.read().connections.keys().cloned().collect() } pub fn active_connections(&self)-> Vec> { - self.connections.read().values().cloned().collect() + self.data.read().connections.values().cloned().collect() } pub fn disconnected_nodes(&self) -> BTreeMap { - let connections = self.connections.read(); - self.nodes.iter() - .filter(|&(node_id, _)| !connections.contains_key(node_id)) + let data = self.data.read(); + data.nodes.iter() + .filter(|&(node_id, _)| !data.connections.contains_key(node_id)) .map(|(node_id, node_address)| (node_id.clone(), node_address.clone())) .collect() } + + pub fn update_nodes_set(&self) { + let mut data = self.data.write(); + let new_nodes = self.key_server_set.get(); + for obsolete_node in data.nodes.keys().cloned().collect::>() { + if !new_nodes.contains_key(&obsolete_node) { + data.nodes.remove(&obsolete_node); + data.connections.remove(&obsolete_node); + } + } + for (new_node_public, new_node_addr) in new_nodes { + data.nodes.insert(new_node_public, new_node_addr); + } + } } impl ClusterData { diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 22ffbdb07..eecfa3091 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -16,7 +16,7 @@ use std::sync::{Arc, Weak}; use std::net::SocketAddr; -use std::collections::HashMap; +use std::collections::BTreeMap; use futures::{future, Future}; use parking_lot::Mutex; use ethcore::filter::Filter; @@ -39,7 +39,7 @@ lazy_static! { /// Key Server set pub trait KeyServerSet: Send + Sync { /// Get set of configured key servers - fn get(&self) -> HashMap; + fn get(&self) -> BTreeMap; } /// On-chain Key Server set implementation. @@ -55,11 +55,11 @@ struct CachedContract { /// Contract address. contract_addr: Option
, /// Active set of key servers. - key_servers: HashMap, + key_servers: BTreeMap, } impl OnChainKeyServerSet { - pub fn new(client: &Arc, key_servers: HashMap) -> Arc { + pub fn new(client: &Arc, key_servers: BTreeMap) -> Arc { let key_server_set = Arc::new(OnChainKeyServerSet { contract: Mutex::new(CachedContract::new(client, key_servers)), }); @@ -69,7 +69,7 @@ impl OnChainKeyServerSet { } impl KeyServerSet for OnChainKeyServerSet { - fn get(&self) -> HashMap { + fn get(&self) -> BTreeMap { self.contract.lock().get() } } @@ -81,7 +81,7 @@ impl ChainNotify for OnChainKeyServerSet { } impl CachedContract { - pub fn new(client: &Arc, key_servers: HashMap) -> Self { + pub fn new(client: &Arc, key_servers: BTreeMap) -> Self { CachedContract { client: Arc::downgrade(client), contract_addr: None, @@ -102,7 +102,7 @@ println!("=== Installing contract from address: {:?}", new_contract_addr); KeyServerSetContract::new(contract_addr) }) .map(|contract| { - let mut key_servers = HashMap::new(); + let mut key_servers = BTreeMap::new(); let do_call = |a, d| future::done(self.client.upgrade().ok_or("Calling contract without client".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))); let key_servers_list = contract.get_key_servers(do_call).wait() .map_err(|err| { trace!(target: "secretstore", "Error {} reading list of key servers from contract", err); err }) @@ -139,7 +139,7 @@ println!("=== Installing contract from address: {:?}", new_contract_addr); } } - fn get(&self) -> HashMap { + fn get(&self) -> BTreeMap { self.key_servers.clone() } } From 7664ff5acd26d781eb9c4d5708d37735b9da01fc Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 19 Jul 2017 15:14:37 +0300 Subject: [PATCH 005/119] do not connect to self --- .../src/key_server_cluster/cluster.rs | 9 ++- secret_store/src/key_server_set.rs | 74 +++++++++++-------- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index 3f381b6f0..87c602eae 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -674,11 +674,14 @@ impl ClusterCore { impl ClusterConnections { pub fn new(config: &ClusterConfiguration) -> Result { + let mut nodes = config.key_server_set.get(); + nodes.remove(config.self_key_pair.public()); + Ok(ClusterConnections { self_node_id: config.self_key_pair.public().clone(), key_server_set: config.key_server_set.clone(), data: RwLock::new(ClusterConnectionsData { - nodes: config.key_server_set.get(), + nodes: nodes, connections: BTreeMap::new(), }), }) @@ -740,7 +743,9 @@ impl ClusterConnections { pub fn update_nodes_set(&self) { let mut data = self.data.write(); - let new_nodes = self.key_server_set.get(); + let mut new_nodes = self.key_server_set.get(); + new_nodes.remove(&self.self_node_id); + for obsolete_node in data.nodes.keys().cloned().collect::>() { if !new_nodes.contains_key(&obsolete_node) { data.nodes.remove(&obsolete_node); diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index eecfa3091..f9ec120fd 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -60,8 +60,15 @@ struct CachedContract { impl OnChainKeyServerSet { pub fn new(client: &Arc, key_servers: BTreeMap) -> Arc { + let mut cached_contract = CachedContract::new(client, key_servers); + let key_server_contract_address = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned()); + // only initialize from contract if it is installed. otherwise - use default nodes + if key_server_contract_address.is_some() { + cached_contract.read_from_registry(&*client, key_server_contract_address); + } + let key_server_set = Arc::new(OnChainKeyServerSet { - contract: Mutex::new(CachedContract::new(client, key_servers)), + contract: Mutex::new(cached_contract), }); client.add_notify(key_server_set.clone()); key_server_set @@ -76,6 +83,7 @@ impl KeyServerSet for OnChainKeyServerSet { impl ChainNotify for OnChainKeyServerSet { fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { +println!("=== new_blocks: imported {}, invalid: {}, enactd: {}, retracted: {}, sealed: {}, proposed: {}", _imported.len(), _invalid.len(), enacted.len(), retracted.len(), _sealed.len(), _proposed.len()); self.contract.lock().update(enacted, retracted) } } @@ -92,36 +100,10 @@ impl CachedContract { pub fn update(&mut self, enacted: Vec, _retracted: Vec) { if let Some(client) = self.client.upgrade() { let new_contract_addr = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned()); - +println!("=== Registry address = {:?}", new_contract_addr); // new contract installed if self.contract_addr.as_ref() != new_contract_addr.as_ref() { -println!("=== Installing contract from address: {:?}", new_contract_addr); - self.key_servers = new_contract_addr.map(|contract_addr| { - trace!(target: "secretstore", "Configuring for key server set contract from {}", contract_addr); - - KeyServerSetContract::new(contract_addr) - }) - .map(|contract| { - let mut key_servers = BTreeMap::new(); - let do_call = |a, d| future::done(self.client.upgrade().ok_or("Calling contract without client".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))); - let key_servers_list = contract.get_key_servers(do_call).wait() - .map_err(|err| { trace!(target: "secretstore", "Error {} reading list of key servers from contract", err); err }) - .unwrap_or_default(); - for key_server in key_servers_list { - let key_server_public = contract.get_key_server_public( - |a, d| future::done(self.client.upgrade().ok_or("Calling contract without client".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))), key_server).wait() - .and_then(|p| if p.len() == 64 { Ok(Public::from_slice(&p)) } else { Err(format!("Invalid public length {}", p.len())) }); - let key_server_ip = contract.get_key_server_address( - |a, d| future::done(self.client.upgrade().ok_or("Calling contract without client".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))), key_server).wait() - .and_then(|a| a.parse().map_err(|e| format!("Invalid ip address: {}", e))); - if let (Ok(key_server_public), Ok(key_server_ip)) = (key_server_public, key_server_ip) { - key_servers.insert(key_server_public, key_server_ip); - } - } - key_servers - }) - .unwrap_or_default(); - + self.read_from_registry(&*client, new_contract_addr); return; } @@ -139,7 +121,39 @@ println!("=== Installing contract from address: {:?}", new_contract_addr); } } - fn get(&self) -> BTreeMap { + pub fn get(&self) -> BTreeMap { self.key_servers.clone() } + + fn read_from_registry(&mut self, client: &Client, new_contract_address: Option
) { +println!("=== Installing contract from address: {:?}", new_contract_address); + self.key_servers = new_contract_address.map(|contract_addr| { + trace!(target: "secretstore", "Configuring for key server set contract from {}", contract_addr); + + KeyServerSetContract::new(contract_addr) + }) + .map(|contract| { + let mut key_servers = BTreeMap::new(); + let do_call = |a, d| future::done(client.call_contract(BlockId::Latest, a, d)); + let key_servers_list = contract.get_key_servers(do_call).wait() + .map_err(|err| { trace!(target: "secretstore", "Error {} reading list of key servers from contract", err); err }) + .unwrap_or_default(); + for key_server in key_servers_list { + let key_server_public = contract.get_key_server_public( + |a, d| future::done(client.call_contract(BlockId::Latest, a, d)), key_server).wait() + .and_then(|p| if p.len() == 64 { Ok(Public::from_slice(&p)) } else { Err(format!("Invalid public length {}", p.len())) }); + let key_server_ip = contract.get_key_server_address( + |a, d| future::done(client.call_contract(BlockId::Latest, a, d)), key_server).wait() + .and_then(|a| a.parse().map_err(|e| format!("Invalid ip address: {}", e))); + if let (Ok(key_server_public), Ok(key_server_ip)) = (key_server_public, key_server_ip) { +println!("=== PARSED {:?} {:?}", key_server_public, key_server_ip); + key_servers.insert(key_server_public, key_server_ip); + } +else { println!("=== ERROR parsing"); } + } + key_servers + }) + .unwrap_or_default(); + self.contract_addr = new_contract_address; + } } From 80b9e931f55f06034fc597a49174d13683f6288e Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 20 Jul 2017 12:19:29 +0300 Subject: [PATCH 006/119] fixed connection establishing --- .../src/key_server_cluster/cluster.rs | 44 ++++++++++++++++--- .../src/key_server_cluster/io/handshake.rs | 13 +++--- .../net/accept_connection.rs | 7 ++- secret_store/src/key_server_set.rs | 37 +++++++++------- 4 files changed, 67 insertions(+), 34 deletions(-) diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index 87c602eae..ff9ff9b22 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -289,8 +289,7 @@ impl ClusterCore { /// Accept connection future. fn accept_connection_future(handle: &Handle, data: Arc, stream: TcpStream, node_address: SocketAddr) -> BoxedEmptyFuture { - let disconnected_nodes = data.connections.disconnected_nodes().keys().cloned().collect(); - net_accept_connection(node_address, stream, handle, data.self_key_pair.clone(), disconnected_nodes) + net_accept_connection(node_address, stream, handle, data.self_key_pair.clone()) .then(move |result| ClusterCore::process_connection_result(data, true, result)) .then(|_| finished(())) .boxed() @@ -381,14 +380,16 @@ impl ClusterCore { finished(Ok(())).boxed() } }, - Ok(DeadlineStatus::Meet(Err(_))) => { + Ok(DeadlineStatus::Meet(Err(err))) => { + warn!(target: "secretstore_net", "{}: protocol error {} when establishind connection", data.self_key_pair.public(), err); finished(Ok(())).boxed() }, Ok(DeadlineStatus::Timeout) => { + warn!(target: "secretstore_net", "{}: timeout when establishind connection", data.self_key_pair.public()); finished(Ok(())).boxed() }, - Err(_) => { - // network error + Err(err) => { + warn!(target: "secretstore_net", "{}: network error {} when establishind connection", data.self_key_pair.public(), err); finished(Ok(())).boxed() }, } @@ -699,6 +700,12 @@ impl ClusterConnections { pub fn insert(&self, connection: Arc) -> bool { let mut data = self.data.write(); + if !data.nodes.contains_key(connection.node_id()) { + // incoming connections are checked here + trace!(target: "secretstore_net", "{}: ignoring unknown connection from {} at {}", self.self_node_id, connection.node_id(), connection.node_address()); + debug_assert!(connection.is_inbound()); + return false; + } if data.connections.contains_key(connection.node_id()) { // we have already connected to the same node // the agreement is that node with lower id must establish connection to node with higher id @@ -746,14 +753,37 @@ impl ClusterConnections { let mut new_nodes = self.key_server_set.get(); new_nodes.remove(&self.self_node_id); + let mut num_added_nodes = 0; + let mut num_removed_nodes = 0; + let mut num_changed_nodes = 0; + for obsolete_node in data.nodes.keys().cloned().collect::>() { if !new_nodes.contains_key(&obsolete_node) { + if let Entry::Occupied(entry) = data.connections.entry(obsolete_node) { + trace!(target: "secretstore_net", "{}: removing connection to {} at {}", self.self_node_id, entry.get().node_id(), entry.get().node_address()); + entry.remove(); + } + data.nodes.remove(&obsolete_node); - data.connections.remove(&obsolete_node); + num_removed_nodes += 1; } } + for (new_node_public, new_node_addr) in new_nodes { - data.nodes.insert(new_node_public, new_node_addr); + match data.nodes.insert(new_node_public, new_node_addr) { + None => num_added_nodes += 1, + Some(old_node_addr) => if new_node_addr != old_node_addr { + if let Entry::Occupied(entry) = data.connections.entry(new_node_public) { + trace!(target: "secretstore_net", "{}: removing connection to {} at {}", self.self_node_id, entry.get().node_id(), entry.get().node_address()); + entry.remove(); + } + num_changed_nodes += 1; + }, + } + } + + if num_added_nodes != 0 || num_removed_nodes != 0 || num_changed_nodes != 0 { + trace!(target: "secretstore_net", "{}: updated nodes set: removed {}, added {}, changed {}", self.self_node_id, num_removed_nodes, num_added_nodes, num_changed_nodes); } } } diff --git a/secret_store/src/key_server_cluster/io/handshake.rs b/secret_store/src/key_server_cluster/io/handshake.rs index 38d8a6ac1..90f4d04cc 100644 --- a/secret_store/src/key_server_cluster/io/handshake.rs +++ b/secret_store/src/key_server_cluster/io/handshake.rs @@ -45,7 +45,7 @@ pub fn handshake_with_plain_confirmation(a: A, self_confirmation_plain: Resul state: state, self_key_pair: self_key_pair, self_confirmation_plain: self_confirmation_plain.unwrap_or(Default::default()), - trusted_nodes: trusted_nodes, + trusted_nodes: Some(trusted_nodes), other_node_id: None, other_confirmation_plain: None, shared_key: None, @@ -53,7 +53,7 @@ pub fn handshake_with_plain_confirmation(a: A, self_confirmation_plain: Resul } /// Wait for handshake procedure to be started by another node from the cluster. -pub fn accept_handshake(a: A, self_key_pair: KeyPair, trusted_nodes: BTreeSet) -> Handshake where A: AsyncWrite + AsyncRead { +pub fn accept_handshake(a: A, self_key_pair: KeyPair) -> Handshake where A: AsyncWrite + AsyncRead { let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into); let (error, state) = match self_confirmation_plain.clone() { Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))), @@ -66,7 +66,7 @@ pub fn accept_handshake(a: A, self_key_pair: KeyPair, trusted_nodes: BTreeSet state: state, self_key_pair: self_key_pair, self_confirmation_plain: self_confirmation_plain.unwrap_or(Default::default()), - trusted_nodes: trusted_nodes, + trusted_nodes: None, other_node_id: None, other_confirmation_plain: None, shared_key: None, @@ -89,7 +89,7 @@ pub struct Handshake { state: HandshakeState, self_key_pair: KeyPair, self_confirmation_plain: H256, - trusted_nodes: BTreeSet, + trusted_nodes: Option>, other_node_id: Option, other_confirmation_plain: Option, shared_key: Option, @@ -172,7 +172,8 @@ impl Future for Handshake where A: AsyncRead + AsyncWrite { Err(err) => return Ok((stream, Err(err.into())).into()), }; - if !self.trusted_nodes.contains(&*message.node_id) { + if !self.trusted_nodes.as_ref().map(|tn| tn.contains(&*message.node_id)).unwrap_or(true) { +println!("=== HANDSHAKE - INVALID NODE: self.trusted_nodes = {:?}, message.node_id = {:?}", self.trusted_nodes, message.node_id); return Ok((stream, Err(Error::InvalidNodeId)).into()); } @@ -300,7 +301,7 @@ mod tests { let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect(); let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap(); - let mut handshake = accept_handshake(io, self_key_pair, trusted_nodes); + let mut handshake = accept_handshake(io, self_key_pair); handshake.set_self_confirmation_plain(self_confirmation_plain); let handshake_result = handshake.wait().unwrap(); diff --git a/secret_store/src/key_server_cluster/net/accept_connection.rs b/secret_store/src/key_server_cluster/net/accept_connection.rs index 0daa8b2da..339625f3f 100644 --- a/secret_store/src/key_server_cluster/net/accept_connection.rs +++ b/secret_store/src/key_server_cluster/net/accept_connection.rs @@ -17,19 +17,18 @@ use std::io; use std::net::SocketAddr; use std::time::Duration; -use std::collections::BTreeSet; use futures::{Future, Poll}; use tokio_core::reactor::Handle; use tokio_core::net::TcpStream; use ethkey::KeyPair; -use key_server_cluster::{Error, NodeId}; +use key_server_cluster::Error; use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline}; use key_server_cluster::net::Connection; /// Create future for accepting incoming connection. -pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: KeyPair, trusted_nodes: BTreeSet) -> Deadline { +pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: KeyPair) -> Deadline { let accept = AcceptConnection { - handshake: accept_handshake(stream, self_key_pair, trusted_nodes), + handshake: accept_handshake(stream, self_key_pair), address: address, }; diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index f9ec120fd..7b0bd5c9f 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -28,8 +28,8 @@ use types::all::Public; const KEY_SERVER_SET_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_server_set"; // TODO: ethabi should be able to generate this. -const ADDED_EVENT_NAME: &'static [u8] = &*b"KeyServerAdded()"; -const REMOVED_EVENT_NAME: &'static [u8] = &*b"KeyServerRemoved()"; +const ADDED_EVENT_NAME: &'static [u8] = &*b"KeyServerAdded(address)"; +const REMOVED_EVENT_NAME: &'static [u8] = &*b"KeyServerRemoved(address)"; lazy_static! { static ref ADDED_EVENT_NAME_HASH: H256 = ADDED_EVENT_NAME.sha3(); @@ -83,7 +83,6 @@ impl KeyServerSet for OnChainKeyServerSet { impl ChainNotify for OnChainKeyServerSet { fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { -println!("=== new_blocks: imported {}, invalid: {}, enactd: {}, retracted: {}, sealed: {}, proposed: {}", _imported.len(), _invalid.len(), enacted.len(), retracted.len(), _sealed.len(), _proposed.len()); self.contract.lock().update(enacted, retracted) } } @@ -97,26 +96,33 @@ impl CachedContract { } } - pub fn update(&mut self, enacted: Vec, _retracted: Vec) { + pub fn update(&mut self, enacted: Vec, retracted: Vec) { if let Some(client) = self.client.upgrade() { let new_contract_addr = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned()); -println!("=== Registry address = {:?}", new_contract_addr); + // new contract installed if self.contract_addr.as_ref() != new_contract_addr.as_ref() { self.read_from_registry(&*client, new_contract_addr); return; } - // check for events - for enacted_hash in enacted { - let filter = Filter { - from_block: BlockId::Hash(enacted_hash.clone()), - to_block: BlockId::Hash(enacted_hash.clone()), + // check for contract events + let is_set_changed = self.contract_addr.is_some() && enacted.iter() + .chain(retracted.iter()) + .any(|block_hash| !client.logs(Filter { + from_block: BlockId::Hash(block_hash.clone()), + to_block: BlockId::Hash(block_hash.clone()), address: self.contract_addr.clone().map(|a| vec![a]), - topics: vec![Some(vec![*ADDED_EVENT_NAME_HASH]), Some(vec![*REMOVED_EVENT_NAME_HASH])], - limit: None, - }; - println!("=== Number of filtered log entries: {}", client.logs(filter).len()); + topics: vec![ + Some(vec![*ADDED_EVENT_NAME_HASH, *REMOVED_EVENT_NAME_HASH]), + None, + None, + None, + ], + limit: Some(1), + }).is_empty()); + if is_set_changed { + self.read_from_registry(&*client, new_contract_addr); } } } @@ -126,7 +132,6 @@ println!("=== Registry address = {:?}", new_contract_addr); } fn read_from_registry(&mut self, client: &Client, new_contract_address: Option
) { -println!("=== Installing contract from address: {:?}", new_contract_address); self.key_servers = new_contract_address.map(|contract_addr| { trace!(target: "secretstore", "Configuring for key server set contract from {}", contract_addr); @@ -146,10 +151,8 @@ println!("=== Installing contract from address: {:?}", new_contract_address); |a, d| future::done(client.call_contract(BlockId::Latest, a, d)), key_server).wait() .and_then(|a| a.parse().map_err(|e| format!("Invalid ip address: {}", e))); if let (Ok(key_server_public), Ok(key_server_ip)) = (key_server_public, key_server_ip) { -println!("=== PARSED {:?} {:?}", key_server_public, key_server_ip); key_servers.insert(key_server_public, key_server_ip); } -else { println!("=== ERROR parsing"); } } key_servers }) From 9a9c4f6ad6ee6e6beda9820ade823191987b98f9 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 20 Jul 2017 12:25:41 +0300 Subject: [PATCH 007/119] removed println --- secret_store/src/key_server_cluster/io/handshake.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/secret_store/src/key_server_cluster/io/handshake.rs b/secret_store/src/key_server_cluster/io/handshake.rs index 90f4d04cc..df8f6cbf7 100644 --- a/secret_store/src/key_server_cluster/io/handshake.rs +++ b/secret_store/src/key_server_cluster/io/handshake.rs @@ -173,7 +173,6 @@ impl Future for Handshake where A: AsyncRead + AsyncWrite { }; if !self.trusted_nodes.as_ref().map(|tn| tn.contains(&*message.node_id)).unwrap_or(true) { -println!("=== HANDSHAKE - INVALID NODE: self.trusted_nodes = {:?}, message.node_id = {:?}", self.trusted_nodes, message.node_id); return Ok((stream, Err(Error::InvalidNodeId)).into()); } From a35db9f45476d44d77870f5cd1e52764a7676d07 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 20 Jul 2017 12:55:52 +0300 Subject: [PATCH 008/119] improved KeyServerSet tracing --- secret_store/src/key_server_set.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 7b0bd5c9f..6b58e54de 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -27,8 +27,9 @@ use types::all::Public; const KEY_SERVER_SET_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_server_set"; -// TODO: ethabi should be able to generate this. +/// Key server has been added to the set. const ADDED_EVENT_NAME: &'static [u8] = &*b"KeyServerAdded(address)"; +/// Key server has been removed from the set. const REMOVED_EVENT_NAME: &'static [u8] = &*b"KeyServerRemoved(address)"; lazy_static! { @@ -63,6 +64,7 @@ impl OnChainKeyServerSet { let mut cached_contract = CachedContract::new(client, key_servers); let key_server_contract_address = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned()); // only initialize from contract if it is installed. otherwise - use default nodes + // once the contract is installed, all default nodes are lost (if not in the contract' set) if key_server_contract_address.is_some() { cached_contract.read_from_registry(&*client, key_server_contract_address); } @@ -100,7 +102,7 @@ impl CachedContract { if let Some(client) = self.client.upgrade() { let new_contract_addr = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned()); - // new contract installed + // new contract installed => read nodes set from the contract if self.contract_addr.as_ref() != new_contract_addr.as_ref() { self.read_from_registry(&*client, new_contract_addr); return; @@ -121,6 +123,7 @@ impl CachedContract { ], limit: Some(1), }).is_empty()); + // to simplify processing - just re-read the whole nodes set from the contract if is_set_changed { self.read_from_registry(&*client, new_contract_addr); } @@ -150,8 +153,12 @@ impl CachedContract { let key_server_ip = contract.get_key_server_address( |a, d| future::done(client.call_contract(BlockId::Latest, a, d)), key_server).wait() .and_then(|a| a.parse().map_err(|e| format!("Invalid ip address: {}", e))); - if let (Ok(key_server_public), Ok(key_server_ip)) = (key_server_public, key_server_ip) { - key_servers.insert(key_server_public, key_server_ip); + + // only add successfully parsed nodes + match (key_server_public, key_server_ip) { + (Ok(key_server_public), Ok(key_server_ip)) => { key_servers.insert(key_server_public, key_server_ip); }, + (Err(public_err), _) => warn!(target: "secretstore_net", "received invalid public from key server set contract: {}", public_err), + (_, Err(ip_err)) => warn!(target: "secretstore_net", "received invalid IP from key server set contract: {}", ip_err), } } key_servers From b9ad093d06fc11f1dba8d30d5986a4aa8dd93cbe Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 20 Jul 2017 13:15:16 +0300 Subject: [PATCH 009/119] moved parsing to KeyServerSet --- secret_store/src/key_server_set.rs | 22 ++++++++++++++-------- secret_store/src/lib.rs | 4 +--- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 6b58e54de..302f76196 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -23,7 +23,7 @@ use ethcore::filter::Filter; use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify}; use native_contracts::KeyServerSet as KeyServerSetContract; use util::{H256, Address, Bytes, Hashable}; -use types::all::Public; +use types::all::{Error, Public, NodeAddress}; const KEY_SERVER_SET_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_server_set"; @@ -60,8 +60,8 @@ struct CachedContract { } impl OnChainKeyServerSet { - pub fn new(client: &Arc, key_servers: BTreeMap) -> Arc { - let mut cached_contract = CachedContract::new(client, key_servers); + pub fn new(client: &Arc, key_servers: BTreeMap) -> Result, Error> { + let mut cached_contract = CachedContract::new(client, key_servers)?; let key_server_contract_address = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned()); // only initialize from contract if it is installed. otherwise - use default nodes // once the contract is installed, all default nodes are lost (if not in the contract' set) @@ -73,7 +73,7 @@ impl OnChainKeyServerSet { contract: Mutex::new(cached_contract), }); client.add_notify(key_server_set.clone()); - key_server_set + Ok(key_server_set) } } @@ -90,12 +90,18 @@ impl ChainNotify for OnChainKeyServerSet { } impl CachedContract { - pub fn new(client: &Arc, key_servers: BTreeMap) -> Self { - CachedContract { + pub fn new(client: &Arc, key_servers: BTreeMap) -> Result { + Ok(CachedContract { client: Arc::downgrade(client), contract_addr: None, - key_servers: key_servers, - } + key_servers: key_servers.into_iter() + .map(|(p, addr)| { + let addr = format!("{}:{}", addr.address, addr.port).parse() + .map_err(|err| Error::Internal(format!("error parsing node address: {}", err)))?; + Ok((p, addr)) + }) + .collect::, Error>>()?, + }) } pub fn update(&mut self, enacted: Vec, retracted: Vec) { diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index 235d0edd9..9750f7223 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -72,9 +72,7 @@ pub fn start(client: Arc, config: ServiceConfiguration) -> Result Date: Thu, 20 Jul 2017 13:28:31 +0300 Subject: [PATCH 010/119] re-read only when blockchain is changed --- secret_store/src/acl_storage.rs | 6 ++++-- secret_store/src/key_server_set.rs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index 7ae72cbfc..37d5bcd25 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -64,8 +64,10 @@ impl AclStorage for OnChainAclStorage { } impl ChainNotify for OnChainAclStorage { - fn new_blocks(&self, _imported: Vec, _invalid: Vec, _enacted: Vec, _retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { - self.contract.lock().update() + fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { + if !enacted.is_empty() || !retracted.is_empty() { + self.contract.lock().update() + } } } diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 302f76196..47f033db1 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -85,7 +85,9 @@ impl KeyServerSet for OnChainKeyServerSet { impl ChainNotify for OnChainKeyServerSet { fn new_blocks(&self, _imported: Vec, _invalid: Vec, enacted: Vec, retracted: Vec, _sealed: Vec, _proposed: Vec, _duration: u64) { - self.contract.lock().update(enacted, retracted) + if !enacted.is_empty() || !retracted.is_empty() { + self.contract.lock().update(enacted, retracted) + } } } From 023e5b4b9086c85405746dc38b95fcd8c9786746 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 21 Jul 2017 10:49:10 +0300 Subject: [PATCH 011/119] do not try to connect if not a part of cluster --- secret_store/src/key_server_cluster/cluster.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index ff9ff9b22..831867029 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -751,7 +751,11 @@ impl ClusterConnections { pub fn update_nodes_set(&self) { let mut data = self.data.write(); let mut new_nodes = self.key_server_set.get(); - new_nodes.remove(&self.self_node_id); + // we do not need to connect to self + // + we do not need to try to connect to any other node if we are not the part of a cluster + if new_nodes.remove(&self.self_node_id).is_none() { + new_nodes.clear(); + } let mut num_added_nodes = 0; let mut num_removed_nodes = 0; From 5fb9652af56410a805da24e4f2177578f062be53 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 21 Jul 2017 11:25:26 +0300 Subject: [PATCH 012/119] improved logging --- secret_store/src/key_server_cluster/cluster.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index 831867029..649ad4bc9 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -715,7 +715,8 @@ impl ClusterConnections { } } - trace!(target: "secretstore_net", "{}: inserting connection to {} at {}", self.self_node_id, connection.node_id(), connection.node_address()); + trace!(target: "secretstore_net", "{}: inserting connection to {} at {}. Connected to {} of {} nodes", + self.self_node_id, connection.node_id(), connection.node_address(), data.connections.len() + 1, data.nodes.len()); data.connections.insert(connection.node_id().clone(), connection); true } @@ -787,7 +788,8 @@ impl ClusterConnections { } if num_added_nodes != 0 || num_removed_nodes != 0 || num_changed_nodes != 0 { - trace!(target: "secretstore_net", "{}: updated nodes set: removed {}, added {}, changed {}", self.self_node_id, num_removed_nodes, num_added_nodes, num_changed_nodes); + trace!(target: "secretstore_net", "{}: updated nodes set: removed {}, added {}, changed {}. Connected to {} of {} nodes", + self.self_node_id, num_removed_nodes, num_added_nodes, num_changed_nodes, data.connections.len(), data.nodes.len()); } } } From b31b067743a62068425a9e87eee6edd9864c83f5 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 24 Jul 2017 12:36:31 +0300 Subject: [PATCH 013/119] fixed tests --- secret_store/src/key_server.rs | 8 +++++- .../src/key_server_cluster/cluster.rs | 10 +++---- secret_store/src/key_server_cluster/mod.rs | 2 ++ secret_store/src/key_server_set.rs | 27 +++++++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index 969782ca2..c83e460f3 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -192,10 +192,13 @@ impl Drop for KeyServerCore { pub mod tests { use std::time; use std::sync::Arc; + use std::net::SocketAddr; + use std::collections::BTreeMap; use ethcrypto; use ethkey::{self, Secret, Random, Generator}; use acl_storage::tests::DummyAclStorage; use key_storage::tests::DummyKeyStorage; + use key_server_set::tests::MapKeyServerSet; use key_server_cluster::math; use util::H256; use types::all::{Error, Public, ClusterConfiguration, NodeAddress, RequestSignature, ServerKeyId, @@ -253,8 +256,11 @@ pub mod tests { })).collect(), allow_connecting_to_higher_nodes: false, }).collect(); + let key_servers_set: BTreeMap = configs[0].nodes.iter() + .map(|(k, a)| (k.clone(), format!("{}:{}", a.address, a.port).parse().unwrap())) + .collect(); let key_servers: Vec<_> = configs.into_iter().map(|cfg| - KeyServerImpl::new(&cfg, Arc::new(DummyAclStorage::default()), Arc::new(DummyKeyStorage::default())).unwrap() + KeyServerImpl::new(&cfg, Arc::new(MapKeyServerSet::new(key_servers_set.clone())), Arc::new(DummyAclStorage::default()), Arc::new(DummyKeyStorage::default())).unwrap() ).collect(); // wait until connections are established. It is fast => do not bother with events here diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index 649ad4bc9..d77a82431 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -989,7 +989,7 @@ pub mod tests { use parking_lot::Mutex; use tokio_core::reactor::Core; use ethkey::{Random, Generator, Public}; - use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage}; + use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet}; use key_server_cluster::message::Message; use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration}; use key_server_cluster::generation_session::{Session as GenerationSession, SessionState as GenerationSessionState}; @@ -1059,7 +1059,7 @@ pub mod tests { } pub fn all_connections_established(cluster: &Arc) -> bool { - cluster.config().nodes.keys() + cluster.config().key_server_set.get().keys() .filter(|p| *p != cluster.config().self_key_pair.public()) .all(|p| cluster.connection(p).is_some()) } @@ -1070,9 +1070,9 @@ pub mod tests { threads: 1, self_key_pair: key_pairs[i].clone(), listen_address: ("127.0.0.1".to_owned(), ports_begin + i as u16), - nodes: key_pairs.iter().enumerate() - .map(|(j, kp)| (kp.public().clone(), ("127.0.0.1".into(), ports_begin + j as u16))) - .collect(), + key_server_set: Arc::new(MapKeyServerSet::new(key_pairs.iter().enumerate() + .map(|(j, kp)| (kp.public().clone(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap())) + .collect())), allow_connecting_to_higher_nodes: false, key_storage: Arc::new(DummyKeyStorage::default()), acl_storage: Arc::new(DummyAclStorage::default()), diff --git a/secret_store/src/key_server_cluster/mod.rs b/secret_store/src/key_server_cluster/mod.rs index 11c32d528..8f6ae4add 100644 --- a/secret_store/src/key_server_cluster/mod.rs +++ b/secret_store/src/key_server_cluster/mod.rs @@ -34,6 +34,8 @@ pub use self::decryption_session::Session as DecryptionSession; pub use super::key_storage::tests::DummyKeyStorage; #[cfg(test)] pub use super::acl_storage::tests::DummyAclStorage; +#[cfg(test)] +pub use super::key_server_set::tests::MapKeyServerSet; pub type SessionId = ServerKeyId; diff --git a/secret_store/src/key_server_set.rs b/secret_store/src/key_server_set.rs index 47f033db1..e17dceed5 100644 --- a/secret_store/src/key_server_set.rs +++ b/secret_store/src/key_server_set.rs @@ -175,3 +175,30 @@ impl CachedContract { self.contract_addr = new_contract_address; } } + +#[cfg(test)] +pub mod tests { + use std::collections::BTreeMap; + use std::net::SocketAddr; + use ethkey::Public; + use super::KeyServerSet; + + #[derive(Default)] + pub struct MapKeyServerSet { + nodes: BTreeMap, + } + + impl MapKeyServerSet { + pub fn new(nodes: BTreeMap) -> Self { + MapKeyServerSet { + nodes: nodes, + } + } + } + + impl KeyServerSet for MapKeyServerSet { + fn get(&self) -> BTreeMap { + self.nodes.clone() + } + } +} From 5180919e52d9d06b9772935d22504ba601088bd9 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 24 Jul 2017 17:45:15 +0300 Subject: [PATCH 014/119] wasm mvp continued --- Cargo.lock | 1 + ethcore/evm/Cargo.toml | 2 + ethcore/evm/src/lib.rs | 1 + ethcore/evm/src/wasm/env.rs | 55 ++++------- ethcore/evm/src/wasm/mod.rs | 3 +- ethcore/evm/src/wasm/runtime.rs | 158 +++++++++++++++++++++++++++++++- ethcore/evm/src/wasm/tests.rs | 108 ++++++++++++++++++++-- ethcore/res/wasm-tests | 2 +- 8 files changed, 281 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c7046b759..16d378150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -878,6 +878,7 @@ dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", + "ethcore-logger 1.8.0", "ethcore-util 1.8.0", "ethjson 0.1.0", "evmjit 1.8.0", diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index b48dd2346..bd95e0587 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -14,8 +14,10 @@ lazy_static = "0.2" log = "0.3" rlp = { path = "../../util/rlp" } parity-wasm = "0.12" +ethcore-logger = { path = "../../logger" } wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } + [dev-dependencies] rustc-hex = "1.0" diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index fa4d12315..55f7c5090 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -24,6 +24,7 @@ extern crate ethjson; extern crate rlp; extern crate parity_wasm; extern crate wasm_utils; +extern crate ethcore_logger; #[macro_use] extern crate lazy_static; diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/evm/src/wasm/env.rs index cabd38bd9..e68e50432 100644 --- a/ethcore/evm/src/wasm/env.rs +++ b/ethcore/evm/src/wasm/env.rs @@ -61,6 +61,21 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ &[I32; 4], Some(I32), ), + Static( + "_ccall", + &[I32; 6], + Some(I32), + ), + Static( + "_dcall", + &[I32; 5], + Some(I32), + ), + Static( + "_scall", + &[I32; 5], + Some(I32), + ), Static( "abort", &[I32], @@ -71,49 +86,19 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ &[], None, ), - Static( - "invoke_vii", - &[I32; 3], - None, - ), - Static( - "invoke_vi", - &[I32; 2], - None, - ), - Static( - "invoke_v", - &[I32], - None, - ), - Static( - "invoke_iii", - &[I32; 3], - Some(I32), - ), - Static( - "___resumeException", - &[I32], - None, - ), Static( "_rust_begin_unwind", &[I32; 4], None, ), - Static( - "___cxa_find_matching_catch_2", - &[], - Some(I32), - ), - Static( - "___gxx_personality_v0", - &[I32; 6], - Some(I32), - ), Static( "_emscripten_memcpy_big", &[I32; 3], Some(I32), + ), + Static( + "___syscall6", + &[I32; 2], + Some(I32), ) ]; diff --git a/ethcore/evm/src/wasm/mod.rs b/ethcore/evm/src/wasm/mod.rs index a7186add5..acad9e5cb 100644 --- a/ethcore/evm/src/wasm/mod.rs +++ b/ethcore/evm/src/wasm/mod.rs @@ -34,7 +34,7 @@ use wasm_utils; use evm::{self, GasLeft, ReturnData}; use action_params::ActionParams; -use self::runtime::Runtime; +use self::runtime::{Runtime, RuntimeContext}; pub use self::runtime::Error as RuntimeError; @@ -82,6 +82,7 @@ impl evm::Evm for WasmInterpreter { env_memory, DEFAULT_STACK_SPACE, params.gas.low_u64(), + RuntimeContext::new(params.address, params.sender), ); let mut cursor = ::std::io::Cursor::new(&*code); diff --git a/ethcore/evm/src/wasm/runtime.rs b/ethcore/evm/src/wasm/runtime.rs index 7beb4c599..adcb14de1 100644 --- a/ethcore/evm/src/wasm/runtime.rs +++ b/ethcore/evm/src/wasm/runtime.rs @@ -25,6 +25,7 @@ use ext; use parity_wasm::interpreter; use util::{Address, H256, U256}; +use call_type::CallType; use super::ptr::{WasmPtr, Error as PtrError}; use super::call_args::CallArgs; @@ -57,6 +58,20 @@ impl From for Error { } } +pub struct RuntimeContext { + address: Address, + sender: Address, +} + +impl RuntimeContext { + pub fn new(address: Address, sender: Address) -> Self { + RuntimeContext { + address: address, + sender: sender, + } + } +} + /// Runtime enviroment data for wasm contract execution pub struct Runtime<'a> { gas_counter: u64, @@ -64,6 +79,7 @@ pub struct Runtime<'a> { dynamic_top: u32, ext: &'a mut ext::Ext, memory: Arc, + context: RuntimeContext, } impl<'a> Runtime<'a> { @@ -73,6 +89,7 @@ impl<'a> Runtime<'a> { memory: Arc, stack_space: u32, gas_limit: u64, + context: RuntimeContext, ) -> Runtime<'b> { Runtime { gas_counter: 0, @@ -80,6 +97,7 @@ impl<'a> Runtime<'a> { dynamic_top: stack_space, memory: memory, ext: ext, + context: context, } } @@ -139,13 +157,13 @@ impl<'a> Runtime<'a> { trace!(target: "wasm", "runtime: create contract"); let mut context = context; let result_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " result_ptr: {:?}", result_ptr); + trace!(target: "wasm", "result_ptr: {:?}", result_ptr); let code_len = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_len: {:?}", code_len); + trace!(target: "wasm", " code_len: {:?}", code_len); let code_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_ptr: {:?}", code_ptr); + trace!(target: "wasm", " code_ptr: {:?}", code_ptr); let endowment = self.pop_u256(&mut context)?; - trace!(target: "wasm", " val: {:?}", endowment); + trace!(target: "wasm", " val: {:?}", endowment); let code = self.memory.get(code_ptr, code_len as usize)?; @@ -167,6 +185,127 @@ impl<'a> Runtime<'a> { } } + pub fn call(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // + // method signature: + // fn ( + // address: *const u8, + // val_ptr: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(true, CallType::Call, context) + } + + + fn call_code(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // + // signature (same as static call): + // fn ( + // address: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(false, CallType::CallCode, context) + } + + fn do_call( + &mut self, + use_val: bool, + call_type: CallType, + context: interpreter::CallerContext, + ) + -> Result, interpreter::Error> + { + + trace!(target: "wasm", "runtime: call code"); + let mut context = context; + let result_alloc_len = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " result_len: {:?}", result_alloc_len); + + let result_ptr = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " result_ptr: {:?}", result_ptr); + + let input_len = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " input_len: {:?}", input_len); + + let input_ptr = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " input_ptr: {:?}", input_ptr); + + let val = if use_val { Some(self.pop_u256(&mut context)?) } + else { None }; + trace!(target: "wasm", " val: {:?}", val); + + let address = self.pop_address(&mut context)?; + trace!(target: "wasm", " address: {:?}", address); + + if let Some(ref val) = val { + let address_balance = self.ext.balance(&self.context.address) + .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))?; + + if &address_balance < val { + trace!(target: "wasm", "runtime: call failed due to balance check"); + return Ok(Some((-1i32).into())); + } + } + + let mut result = Vec::with_capacity(result_alloc_len as usize); + result.resize(result_alloc_len as usize, 0); + let gas = self.gas_left() + .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? + .into(); + // todo: optimize to use memory views once it's in + let payload = self.memory.get(input_ptr, input_len as usize)?; + + let call_result = self.ext.call( + &gas, + &self.context.sender, + &self.context.address, + val, + &payload, + &address, + &mut result[..], + call_type, + ); + + match call_result { + ext::MessageCallResult::Success(gas_left, _) => { + self.gas_counter = self.gas_limit - gas_left.low_u64(); + self.memory.set(result_ptr, &result)?; + Ok(Some(0i32.into())) + }, + ext::MessageCallResult::Failed => { + Ok(Some((-1i32).into())) + } + } + } + + pub fn static_call(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // signature (same as code call): + // fn ( + // address: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(false, CallType::StaticCall, context) + } + + /// Allocate memory using the wasm stack params pub fn malloc(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> @@ -338,6 +477,15 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { "_create" => { self.create(context) }, + "_ccall" => { + self.call(context) + }, + "_dcall" => { + self.call_code(context) + }, + "_scall" => { + self.static_call(context) + }, "_debug" => { self.debug_log(context) }, @@ -348,7 +496,7 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { self.mem_copy(context) }, _ => { - trace!("Unknown env func: '{}'", name); + trace!(target: "wasm", "Trapped due to unhandled function: '{}'", name); self.user_trap(context) } } diff --git a/ethcore/evm/src/wasm/tests.rs b/ethcore/evm/src/wasm/tests.rs index 8ae13daae..c9d02a4ad 100644 --- a/ethcore/evm/src/wasm/tests.rs +++ b/ethcore/evm/src/wasm/tests.rs @@ -21,6 +21,7 @@ use super::WasmInterpreter; use evm::{self, Evm, GasLeft}; use action_params::{ActionParams, ActionValue}; use util::{U256, H256, Address}; +use byteorder::{LittleEndian, ByteOrder}; macro_rules! load_sample { ($name: expr) => { @@ -85,7 +86,7 @@ fn logger() { }; println!("ext.store: {:?}", ext.store); - assert_eq!(gas_left, U256::from(99581)); + assert_eq!(gas_left, U256::from(99590)); let address_val: H256 = address.into(); assert_eq!( ext.store.get(&"0100000000000000000000000000000000000000000000000000000000000000".parse().unwrap()).expect("storage key to exist"), @@ -136,7 +137,7 @@ fn identity() { } }; - assert_eq!(gas_left, U256::from(99_689)); + assert_eq!(gas_left, U256::from(99_687)); assert_eq!( Address::from_slice(&result), @@ -170,7 +171,7 @@ fn dispersion() { } }; - assert_eq!(gas_left, U256::from(99_402)); + assert_eq!(gas_left, U256::from(99_423)); assert_eq!( result, @@ -199,7 +200,7 @@ fn suicide_not() { } }; - assert_eq!(gas_left, U256::from(99_703)); + assert_eq!(gas_left, U256::from(99_656)); assert_eq!( result, @@ -233,12 +234,14 @@ fn suicide() { } }; - assert_eq!(gas_left, U256::from(99_747)); + assert_eq!(gas_left, U256::from(99_740)); assert!(ext.suicides.contains(&refund)); } #[test] fn create() { + ::ethcore_logger::init_log(); + let mut params = ActionParams::default(); params.gas = U256::from(100_000); params.code = Some(Arc::new(load_sample!("creator.wasm"))); @@ -262,7 +265,7 @@ fn create() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Create, - gas: U256::from(99_778), + gas: U256::from(99_767), sender_address: None, receive_address: None, value: Some(1_000_000_000.into()), @@ -270,5 +273,96 @@ fn create() { code_address: None, } )); - assert_eq!(gas_left, U256::from(99_768)); + assert_eq!(gas_left, U256::from(99_759)); } + + +#[test] +fn call_code() { + ::ethcore_logger::init_log(); + + let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); + let receiver: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); + + let mut params = ActionParams::default(); + params.sender = sender.clone(); + params.address = receiver.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(load_sample!("call_code.wasm"))); + params.data = Some(Vec::new()); + params.value = ActionValue::transfer(1_000_000_000); + + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Call test should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + + trace!(target: "wasm", "fake_calls: {:?}", &ext.calls); + assert!(ext.calls.contains( + &FakeCall { + call_type: FakeCallType::Call, + gas: U256::from(99_061), + sender_address: Some(sender), + receive_address: Some(receiver), + value: None, + data: vec![1u8, 2, 3, 5, 7, 11], + code_address: Some("0d13710000000000000000000000000000000000".parse().unwrap()), + } + )); + assert_eq!(gas_left, U256::from(94196)); + + // siphash result + let res = LittleEndian::read_u32(&result[..]); + assert_eq!(res, 4198595614); +} + +#[test] +fn call_static() { + ::ethcore_logger::init_log(); + + let sender: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); + let receiver: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); + + let mut params = ActionParams::default(); + params.sender = sender.clone(); + params.address = receiver.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(load_sample!("call_static.wasm"))); + params.data = Some(Vec::new()); + params.value = ActionValue::transfer(1_000_000_000); + + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Static call test should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + + trace!(target: "wasm", "fake_calls: {:?}", &ext.calls); + assert!(ext.calls.contains( + &FakeCall { + call_type: FakeCallType::Call, + gas: U256::from(99_061), + sender_address: Some(sender), + receive_address: Some(receiver), + value: None, + data: vec![1u8, 2, 3, 5, 7, 11], + code_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()), + } + )); + assert_eq!(gas_left, U256::from(94196)); + + // siphash result + let res = LittleEndian::read_u32(&result[..]); + assert_eq!(res, 317632590); +} \ No newline at end of file diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index 9ed630431..8361f18c7 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit 9ed6304313fa949ed92aa0570fb2bc759fb6dc58 +Subproject commit 8361f18c7ea133d9b85edf7dea02f05b9feb1938 From 45f2b824110e1f7378217e8d6b73cffd261b6755 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 25 Jul 2017 09:24:54 +0300 Subject: [PATCH 015/119] NodeKeyPAir trait --- secret_store/src/key_server.rs | 20 +++--- .../src/key_server_cluster/cluster.rs | 10 +-- .../src/key_server_cluster/io/handshake.rs | 48 +++++++------ .../src/key_server_cluster/io/message.rs | 15 ++--- secret_store/src/key_server_cluster/io/mod.rs | 2 +- secret_store/src/key_server_cluster/mod.rs | 3 + .../net/accept_connection.rs | 6 +- .../src/key_server_cluster/net/connect.rs | 8 +-- secret_store/src/key_storage.rs | 2 +- secret_store/src/lib.rs | 8 ++- secret_store/src/node_key_pair.rs | 67 +++++++++++++++++++ secret_store/src/traits.rs | 12 ++++ secret_store/src/types/all.rs | 2 - 13 files changed, 146 insertions(+), 57 deletions(-) create mode 100644 secret_store/src/node_key_pair.rs diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index c83e460f3..0944dd37c 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -26,7 +26,7 @@ use super::acl_storage::AclStorage; use super::key_storage::KeyStorage; use super::key_server_set::KeyServerSet; use key_server_cluster::{math, ClusterCore}; -use traits::{ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer}; +use traits::{ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer, NodeKeyPair}; use types::all::{Error, Public, RequestSignature, ServerKeyId, EncryptedDocumentKey, EncryptedDocumentKeyShadow, ClusterConfiguration, MessageHash, EncryptedMessageSignature}; use key_server_cluster::{ClusterClient, ClusterConfiguration as NetClusterConfiguration}; @@ -45,9 +45,9 @@ pub struct KeyServerCore { impl KeyServerImpl { /// Create new key server instance - pub fn new(config: &ClusterConfiguration, key_server_set: Arc, acl_storage: Arc, key_storage: Arc) -> Result { + pub fn new(config: &ClusterConfiguration, key_server_set: Arc, self_key_pair: Arc, acl_storage: Arc, key_storage: Arc) -> Result { Ok(KeyServerImpl { - data: Arc::new(Mutex::new(KeyServerCore::new(config, key_server_set, acl_storage, key_storage)?)), + data: Arc::new(Mutex::new(KeyServerCore::new(config, key_server_set, self_key_pair, acl_storage, key_storage)?)), }) } @@ -144,10 +144,10 @@ impl MessageSigner for KeyServerImpl { } impl KeyServerCore { - pub fn new(config: &ClusterConfiguration, key_server_set: Arc, acl_storage: Arc, key_storage: Arc) -> Result { + pub fn new(config: &ClusterConfiguration, key_server_set: Arc, self_key_pair: Arc, acl_storage: Arc, key_storage: Arc) -> Result { let config = NetClusterConfiguration { threads: config.threads, - self_key_pair: ethkey::KeyPair::from_secret_slice(&config.self_private)?, + self_key_pair: self_key_pair, listen_address: (config.listener_address.address.clone(), config.listener_address.port), key_server_set: key_server_set, allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes, @@ -198,6 +198,7 @@ pub mod tests { use ethkey::{self, Secret, Random, Generator}; use acl_storage::tests::DummyAclStorage; use key_storage::tests::DummyKeyStorage; + use node_key_pair::PlainNodeKeyPair; use key_server_set::tests::MapKeyServerSet; use key_server_cluster::math; use util::H256; @@ -244,7 +245,7 @@ pub mod tests { let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect(); let configs: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration { threads: 1, - self_private: (***key_pairs[i].secret()).into(), +// self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())), listener_address: NodeAddress { address: "127.0.0.1".into(), port: start_port + (i as u16), @@ -259,8 +260,11 @@ pub mod tests { let key_servers_set: BTreeMap = configs[0].nodes.iter() .map(|(k, a)| (k.clone(), format!("{}:{}", a.address, a.port).parse().unwrap())) .collect(); - let key_servers: Vec<_> = configs.into_iter().map(|cfg| - KeyServerImpl::new(&cfg, Arc::new(MapKeyServerSet::new(key_servers_set.clone())), Arc::new(DummyAclStorage::default()), Arc::new(DummyKeyStorage::default())).unwrap() + let key_servers: Vec<_> = configs.into_iter().enumerate().map(|(i, cfg)| + KeyServerImpl::new(&cfg, Arc::new(MapKeyServerSet::new(key_servers_set.clone())), + Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())), + Arc::new(DummyAclStorage::default()), + Arc::new(DummyKeyStorage::default())).unwrap() ).collect(); // wait until connections are established. It is fast => do not bother with events here diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index d77a82431..155dd4a01 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -28,7 +28,7 @@ use tokio_core::reactor::{Handle, Remote, Interval}; use tokio_core::net::{TcpListener, TcpStream}; use ethkey::{Public, KeyPair, Signature, Random, Generator}; use util::H256; -use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet}; +use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet, NodeKeyPair}; use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, GenerationSessionWrapper, EncryptionSessionWrapper, DecryptionSessionWrapper, SigningSessionWrapper}; use key_server_cluster::message::{self, Message, ClusterMessage, GenerationMessage, EncryptionMessage, DecryptionMessage, @@ -99,7 +99,7 @@ pub struct ClusterConfiguration { /// Allow connecting to 'higher' nodes. pub allow_connecting_to_higher_nodes: bool, /// KeyPair this node holds. - pub self_key_pair: KeyPair, + pub self_key_pair: Arc, /// Interface to listen to. pub listen_address: (String, u16), /// Cluster nodes set. @@ -146,7 +146,7 @@ pub struct ClusterData { /// Handle to the cpu thread pool. pool: CpuPool, /// KeyPair this node holds. - self_key_pair: KeyPair, + self_key_pair: Arc, /// Connections data. connections: ClusterConnections, /// Active sessions data. @@ -989,7 +989,7 @@ pub mod tests { use parking_lot::Mutex; use tokio_core::reactor::Core; use ethkey::{Random, Generator, Public}; - use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet}; + use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet, PlainNodeKeyPair}; use key_server_cluster::message::Message; use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration}; use key_server_cluster::generation_session::{Session as GenerationSession, SessionState as GenerationSessionState}; @@ -1068,7 +1068,7 @@ pub mod tests { let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect(); let cluster_params: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration { threads: 1, - self_key_pair: key_pairs[i].clone(), + self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())), listen_address: ("127.0.0.1".to_owned(), ports_begin + i as u16), key_server_set: Arc::new(MapKeyServerSet::new(key_pairs.iter().enumerate() .map(|(j, kp)| (kp.public().clone(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap())) diff --git a/secret_store/src/key_server_cluster/io/handshake.rs b/secret_store/src/key_server_cluster/io/handshake.rs index df8f6cbf7..bf52ab798 100644 --- a/secret_store/src/key_server_cluster/io/handshake.rs +++ b/secret_store/src/key_server_cluster/io/handshake.rs @@ -15,24 +15,25 @@ // along with Parity. If not, see . use std::io; +use std::sync::Arc; use std::collections::BTreeSet; use futures::{Future, Poll, Async}; use tokio_io::{AsyncRead, AsyncWrite}; -use ethkey::{Random, Generator, KeyPair, Secret, sign, verify_public}; +use ethkey::{Random, Generator, KeyPair, verify_public}; use util::H256; -use key_server_cluster::{NodeId, Error}; +use key_server_cluster::{NodeId, Error, NodeKeyPair}; use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature}; use key_server_cluster::io::{write_message, write_encrypted_message, WriteMessage, ReadMessage, - read_message, read_encrypted_message, compute_shared_key}; + read_message, read_encrypted_message, fix_shared_key}; /// Start handshake procedure with another node from the cluster. -pub fn handshake(a: A, self_key_pair: KeyPair, trusted_nodes: BTreeSet) -> Handshake where A: AsyncWrite + AsyncRead { +pub fn handshake(a: A, self_key_pair: Arc, trusted_nodes: BTreeSet) -> Handshake where A: AsyncWrite + AsyncRead { let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into); handshake_with_plain_confirmation(a, self_confirmation_plain, self_key_pair, trusted_nodes) } /// Start handshake procedure with another node from the cluster and given plain confirmation. -pub fn handshake_with_plain_confirmation(a: A, self_confirmation_plain: Result, self_key_pair: KeyPair, trusted_nodes: BTreeSet) -> Handshake where A: AsyncWrite + AsyncRead { +pub fn handshake_with_plain_confirmation(a: A, self_confirmation_plain: Result, self_key_pair: Arc, trusted_nodes: BTreeSet) -> Handshake where A: AsyncWrite + AsyncRead { let (error, state) = match self_confirmation_plain.clone() .and_then(|c| Handshake::::make_public_key_message(self_key_pair.public().clone(), c)) { Ok(message) => (None, HandshakeState::SendPublicKey(write_message(a, message))), @@ -53,7 +54,7 @@ pub fn handshake_with_plain_confirmation(a: A, self_confirmation_plain: Resul } /// Wait for handshake procedure to be started by another node from the cluster. -pub fn accept_handshake(a: A, self_key_pair: KeyPair) -> Handshake where A: AsyncWrite + AsyncRead { +pub fn accept_handshake(a: A, self_key_pair: Arc) -> Handshake where A: AsyncWrite + AsyncRead { let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into); let (error, state) = match self_confirmation_plain.clone() { Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))), @@ -87,7 +88,7 @@ pub struct Handshake { is_active: bool, error: Option<(A, Result)>, state: HandshakeState, - self_key_pair: KeyPair, + self_key_pair: Arc, self_confirmation_plain: H256, trusted_nodes: Option>, other_node_id: Option, @@ -117,9 +118,9 @@ impl Handshake where A: AsyncRead + AsyncWrite { }))) } - fn make_private_key_signature_message(secret: &Secret, confirmation_plain: &H256) -> Result { + fn make_private_key_signature_message(self_key_pair: &NodeKeyPair, confirmation_plain: &H256) -> Result { Ok(Message::Cluster(ClusterMessage::NodePrivateKeySignature(NodePrivateKeySignature { - confirmation_signed: sign(secret, confirmation_plain)?.into(), + confirmation_signed: self_key_pair.sign(confirmation_plain)?.into(), }))) } } @@ -142,15 +143,15 @@ impl Future for Handshake where A: AsyncRead + AsyncWrite { read_message(stream) ), Async::NotReady) } else { - self.shared_key = match compute_shared_key(self.self_key_pair.secret(), + self.shared_key = match self.self_key_pair.compute_shared_key( self.other_node_id.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_node_id is filled in ReceivePublicKey; qed") - ) { + ).map_err(Into::into).and_then(|sk| fix_shared_key(sk.secret())) { Ok(shared_key) => Some(shared_key), - Err(err) => return Ok((stream, Err(err)).into()), + Err(err) => return Ok((stream, Err(err.into())).into()), }; let message = match Handshake::::make_private_key_signature_message( - self.self_key_pair.secret(), + &*self.self_key_pair, self.other_confirmation_plain.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_confirmation_plain is filled in ReceivePublicKey; qed") ) { Ok(message) => message, @@ -179,15 +180,15 @@ impl Future for Handshake where A: AsyncRead + AsyncWrite { self.other_node_id = Some(message.node_id.into()); self.other_confirmation_plain = Some(message.confirmation_plain.into()); if self.is_active { - self.shared_key = match compute_shared_key(self.self_key_pair.secret(), + self.shared_key = match self.self_key_pair.compute_shared_key( self.other_node_id.as_ref().expect("filled couple of lines above; qed") - ) { + ).map_err(Into::into).and_then(|sk| fix_shared_key(sk.secret())) { Ok(shared_key) => Some(shared_key), - Err(err) => return Ok((stream, Err(err)).into()), + Err(err) => return Ok((stream, Err(err.into())).into()), }; let message = match Handshake::::make_private_key_signature_message( - self.self_key_pair.secret(), + &*self.self_key_pair, self.other_confirmation_plain.as_ref().expect("filled couple of lines above; qed") ) { Ok(message) => message, @@ -248,11 +249,14 @@ impl Future for Handshake where A: AsyncRead + AsyncWrite { #[cfg(test)] mod tests { + use std::sync::Arc; use std::collections::BTreeSet; use futures::Future; use ethkey::{Random, Generator, sign}; + use ethcrypto::ecdh::agree; use util::H256; - use key_server_cluster::io::message::compute_shared_key; + use key_server_cluster::PlainNodeKeyPair; + use key_server_cluster::io::message::fix_shared_key; use key_server_cluster::io::message::tests::TestIo; use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature}; use super::{handshake_with_plain_confirmation, accept_handshake, HandshakeResult}; @@ -283,9 +287,9 @@ mod tests { let (self_confirmation_plain, io) = prepare_test_io(); let self_key_pair = io.self_key_pair().clone(); let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect(); - let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap(); + let shared_key = fix_shared_key(&agree(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap()).unwrap(); - let handshake = handshake_with_plain_confirmation(io, Ok(self_confirmation_plain), self_key_pair, trusted_nodes); + let handshake = handshake_with_plain_confirmation(io, Ok(self_confirmation_plain), Arc::new(PlainNodeKeyPair::new(self_key_pair)), trusted_nodes); let handshake_result = handshake.wait().unwrap(); assert_eq!(handshake_result.1, Ok(HandshakeResult { node_id: handshake_result.0.peer_public().clone(), @@ -298,9 +302,9 @@ mod tests { let (self_confirmation_plain, io) = prepare_test_io(); let self_key_pair = io.self_key_pair().clone(); let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect(); - let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap(); + let shared_key = fix_shared_key(&agree(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap()).unwrap(); - let mut handshake = accept_handshake(io, self_key_pair); + let mut handshake = accept_handshake(io, Arc::new(PlainNodeKeyPair::new(self_key_pair))); handshake.set_self_confirmation_plain(self_confirmation_plain); let handshake_result = handshake.wait().unwrap(); diff --git a/secret_store/src/key_server_cluster/io/message.rs b/secret_store/src/key_server_cluster/io/message.rs index 49b71e39d..5a6b50a3e 100644 --- a/secret_store/src/key_server_cluster/io/message.rs +++ b/secret_store/src/key_server_cluster/io/message.rs @@ -19,9 +19,8 @@ use std::u16; use std::ops::Deref; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use serde_json; -use ethcrypto::ecdh::agree; use ethcrypto::ecies::{encrypt_single_message, decrypt_single_message}; -use ethkey::{Public, Secret, KeyPair}; +use ethkey::{Secret, KeyPair}; use ethkey::math::curve_order; use util::{H256, U256}; use key_server_cluster::Error; @@ -154,12 +153,11 @@ pub fn decrypt_message(key: &KeyPair, payload: Vec) -> Result, Error Ok(decrypt_single_message(key.secret(), &payload)?) } -/// Compute shared encryption key. -pub fn compute_shared_key(self_secret: &Secret, other_public: &Public) -> Result { +/// Fix shared encryption key. +pub fn fix_shared_key(shared_secret: &Secret) -> Result { // secret key created in agree function is invalid, as it is not calculated mod EC.field.n // => let's do it manually - let shared_secret = agree(self_secret, other_public)?; - let shared_secret: H256 = (*shared_secret).into(); + let shared_secret: H256 = (**shared_secret).into(); let shared_secret: U256 = shared_secret.into(); let shared_secret: H256 = (shared_secret % curve_order()).into(); let shared_key_pair = KeyPair::from_secret_slice(&*shared_secret)?; @@ -204,8 +202,9 @@ pub mod tests { use futures::Poll; use tokio_io::{AsyncRead, AsyncWrite}; use ethkey::{KeyPair, Public}; + use ethcrypto::ecdh::agree; use key_server_cluster::message::Message; - use super::{MESSAGE_HEADER_SIZE, MessageHeader, compute_shared_key, encrypt_message, serialize_message, + use super::{MESSAGE_HEADER_SIZE, MessageHeader, fix_shared_key, encrypt_message, serialize_message, serialize_header, deserialize_header}; pub struct TestIo { @@ -217,7 +216,7 @@ pub mod tests { impl TestIo { pub fn new(self_key_pair: KeyPair, peer_public: Public) -> Self { - let shared_key_pair = compute_shared_key(self_key_pair.secret(), &peer_public).unwrap(); + let shared_key_pair = fix_shared_key(&agree(self_key_pair.secret(), &peer_public).unwrap()).unwrap(); TestIo { self_key_pair: self_key_pair, peer_public: peer_public, diff --git a/secret_store/src/key_server_cluster/io/mod.rs b/secret_store/src/key_server_cluster/io/mod.rs index 57071038e..dfea33683 100644 --- a/secret_store/src/key_server_cluster/io/mod.rs +++ b/secret_store/src/key_server_cluster/io/mod.rs @@ -26,7 +26,7 @@ mod write_message; pub use self::deadline::{deadline, Deadline, DeadlineStatus}; pub use self::handshake::{handshake, accept_handshake, Handshake, HandshakeResult}; pub use self::message::{MessageHeader, SerializedMessage, serialize_message, deserialize_message, - encrypt_message, compute_shared_key}; + encrypt_message, fix_shared_key}; pub use self::read_header::{read_header, ReadHeader}; pub use self::read_payload::{read_payload, read_encrypted_payload, ReadPayload}; pub use self::read_message::{read_message, read_encrypted_message, ReadMessage}; diff --git a/secret_store/src/key_server_cluster/mod.rs b/secret_store/src/key_server_cluster/mod.rs index 8f6ae4add..102c3672f 100644 --- a/secret_store/src/key_server_cluster/mod.rs +++ b/secret_store/src/key_server_cluster/mod.rs @@ -20,6 +20,7 @@ use ethkey; use ethcrypto; use super::types::all::ServerKeyId; +pub use super::traits::NodeKeyPair; pub use super::types::all::{NodeId, EncryptedDocumentKeyShadow}; pub use super::acl_storage::AclStorage; pub use super::key_storage::{KeyStorage, DocumentKeyShare}; @@ -30,6 +31,8 @@ pub use self::generation_session::Session as GenerationSession; pub use self::encryption_session::Session as EncryptionSession; pub use self::decryption_session::Session as DecryptionSession; +#[cfg(test)] +pub use super::node_key_pair::PlainNodeKeyPair; #[cfg(test)] pub use super::key_storage::tests::DummyKeyStorage; #[cfg(test)] diff --git a/secret_store/src/key_server_cluster/net/accept_connection.rs b/secret_store/src/key_server_cluster/net/accept_connection.rs index 339625f3f..d85e492dd 100644 --- a/secret_store/src/key_server_cluster/net/accept_connection.rs +++ b/secret_store/src/key_server_cluster/net/accept_connection.rs @@ -15,18 +15,18 @@ // along with Parity. If not, see . use std::io; +use std::sync::Arc; use std::net::SocketAddr; use std::time::Duration; use futures::{Future, Poll}; use tokio_core::reactor::Handle; use tokio_core::net::TcpStream; -use ethkey::KeyPair; -use key_server_cluster::Error; +use key_server_cluster::{Error, NodeKeyPair}; use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline}; use key_server_cluster::net::Connection; /// Create future for accepting incoming connection. -pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: KeyPair) -> Deadline { +pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: Arc) -> Deadline { let accept = AcceptConnection { handshake: accept_handshake(stream, self_key_pair), address: address, diff --git a/secret_store/src/key_server_cluster/net/connect.rs b/secret_store/src/key_server_cluster/net/connect.rs index 449168ab2..7515494e4 100644 --- a/secret_store/src/key_server_cluster/net/connect.rs +++ b/secret_store/src/key_server_cluster/net/connect.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Arc; use std::collections::BTreeSet; use std::io; use std::time::Duration; @@ -21,13 +22,12 @@ use std::net::SocketAddr; use futures::{Future, Poll, Async}; use tokio_core::reactor::Handle; use tokio_core::net::{TcpStream, TcpStreamNew}; -use ethkey::KeyPair; -use key_server_cluster::{Error, NodeId}; +use key_server_cluster::{Error, NodeId, NodeKeyPair}; use key_server_cluster::io::{handshake, Handshake, Deadline, deadline}; use key_server_cluster::net::Connection; /// Create future for connecting to other node. -pub fn connect(address: &SocketAddr, handle: &Handle, self_key_pair: KeyPair, trusted_nodes: BTreeSet) -> Deadline { +pub fn connect(address: &SocketAddr, handle: &Handle, self_key_pair: Arc, trusted_nodes: BTreeSet) -> Deadline { let connect = Connect { state: ConnectState::TcpConnect(TcpStream::connect(address, handle)), address: address.clone(), @@ -48,7 +48,7 @@ enum ConnectState { pub struct Connect { state: ConnectState, address: SocketAddr, - self_key_pair: KeyPair, + self_key_pair: Arc, trusted_nodes: BTreeSet, } diff --git a/secret_store/src/key_storage.rs b/secret_store/src/key_storage.rs index d5af7a5fa..18c61c1bf 100644 --- a/secret_store/src/key_storage.rs +++ b/secret_store/src/key_storage.rs @@ -241,7 +241,7 @@ pub mod tests { data_path: path.as_str().to_owned(), cluster_config: ClusterConfiguration { threads: 1, - self_private: (**Random.generate().unwrap().secret().clone()).into(), + //self_private: (**Random.generate().unwrap().secret().clone()).into(), listener_address: NodeAddress { address: "0.0.0.0".to_owned(), port: 8083, diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index 9750f7223..7e9897e60 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -59,22 +59,24 @@ mod key_server; mod key_storage; mod serialization; mod key_server_set; +mod node_key_pair; use std::sync::Arc; use ethcore::client::Client; pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public, Error, NodeAddress, ServiceConfiguration, ClusterConfiguration}; -pub use traits::{KeyServer}; +pub use traits::{NodeKeyPair, KeyServer}; +pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair}; /// Start new key server instance -pub fn start(client: Arc, config: ServiceConfiguration) -> Result, Error> { +pub fn start(client: Arc, self_key_pair: Arc, config: ServiceConfiguration) -> Result, Error> { use std::sync::Arc; let acl_storage = acl_storage::OnChainAclStorage::new(&client); let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?; let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?); - let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, acl_storage, key_storage)?; + let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, self_key_pair, acl_storage, key_storage)?; let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?; Ok(Box::new(listener)) } diff --git a/secret_store/src/node_key_pair.rs b/secret_store/src/node_key_pair.rs new file mode 100644 index 000000000..8676dd16d --- /dev/null +++ b/secret_store/src/node_key_pair.rs @@ -0,0 +1,67 @@ +// Copyright 2015-2017 Parity Technologies (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 . + +use std::sync::Arc; +use ethcrypto::ecdh::agree; +use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign}; +use ethcore::account_provider::AccountProvider; +use util::H256; +use traits::NodeKeyPair; + +pub struct PlainNodeKeyPair { + key_pair: KeyPair, +} + +pub struct KeyStoreNodeKeyPair { + _account_provider: Arc, +} + +impl PlainNodeKeyPair { + pub fn new(key_pair: KeyPair) -> Self { + PlainNodeKeyPair { + key_pair: key_pair, + } + } +} + +impl NodeKeyPair for PlainNodeKeyPair { + fn public(&self) -> &Public { + self.key_pair.public() + } + + fn sign(&self, data: &H256) -> Result { + sign(self.key_pair.secret(), data) + } + + fn compute_shared_key(&self, peer_public: &Public) -> Result { + agree(self.key_pair.secret(), peer_public).map_err(|e| EthKeyError::Custom(e.into())) + .and_then(KeyPair::from_secret) + } +} + +impl NodeKeyPair for KeyStoreNodeKeyPair { + fn public(&self) -> &Public { + unimplemented!() + } + + fn sign(&self, _data: &H256) -> Result { + unimplemented!() + } + + fn compute_shared_key(&self, _peer_public: &Public) -> Result { + unimplemented!() + } +} diff --git a/secret_store/src/traits.rs b/secret_store/src/traits.rs index 33a4eff3c..31da748e0 100644 --- a/secret_store/src/traits.rs +++ b/secret_store/src/traits.rs @@ -14,9 +14,21 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use ethkey::{KeyPair, Signature, Error as EthKeyError}; +use util::H256; use types::all::{Error, Public, ServerKeyId, MessageHash, EncryptedMessageSignature, RequestSignature, EncryptedDocumentKey, EncryptedDocumentKeyShadow}; +/// Node key pair. +pub trait NodeKeyPair: Send + Sync { + /// Public portion of key. + fn public(&self) -> &Public; + /// Sign data with node key. + fn sign(&self, data: &H256) -> Result; + /// Compute shared key to encrypt channel between two nodes. + fn compute_shared_key(&self, peer_public: &Public) -> Result; +} + /// Server key (SK) generator. pub trait ServerKeyGenerator { /// Generate new SK. diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index 54fc8acae..8dc92f175 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -83,8 +83,6 @@ pub struct ServiceConfiguration { pub struct ClusterConfiguration { /// Number of threads reserved by cluster. pub threads: usize, - /// Private key this node holds. - pub self_private: Vec, // holds ethkey::Secret /// This node address. pub listener_address: NodeAddress, /// All cluster nodes addresses. From fb68b0924ab7902f301d697643a10d27f50fb739 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 25 Jul 2017 09:56:23 +0300 Subject: [PATCH 016/119] fixed parity to use new trait --- parity/secretstore.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/parity/secretstore.rs b/parity/secretstore.rs index f215c937c..b29f43479 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -65,6 +65,7 @@ mod server { #[cfg(feature="secretstore")] mod server { + use std::sync::Arc; use ethcore_secretstore; use ethkey::KeyPair; use super::{Configuration, Dependencies}; @@ -86,7 +87,6 @@ mod server { data_path: conf.data_path.clone(), cluster_config: ethcore_secretstore::ClusterConfiguration { threads: 4, - self_private: (**self_secret).into(), listener_address: ethcore_secretstore::NodeAddress { address: conf.interface.clone(), port: conf.port, @@ -103,7 +103,8 @@ mod server { .map_err(|e| format!("valid secret is required when using secretstore. Error: {}", e))?; conf.cluster_config.nodes.insert(self_key_pair.public().clone(), conf.cluster_config.listener_address.clone()); - let key_server = ethcore_secretstore::start(deps.client, conf) + let node_key_pair = Arc::new(ethcore_secretstore::PlainNodeKeyPair::new(self_key_pair)); + let key_server = ethcore_secretstore::start(deps.client, node_key_pair, conf) .map_err(Into::::into)?; Ok(KeyServer { From 9e30d85fdc4c2c76d7fc0bada8302cff9b66a383 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 25 Jul 2017 10:19:48 +0300 Subject: [PATCH 017/119] continue integrating with parity --- parity/configuration.rs | 8 ++++---- parity/secretstore.rs | 29 +++++++++++++++++++---------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index fe397dff5..e037defa2 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -41,7 +41,7 @@ use ethcore_logger::Config as LogConfig; use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path}; use dapps::Configuration as DappsConfiguration; use ipfs::Configuration as IpfsConfiguration; -use secretstore::Configuration as SecretStoreConfiguration; +use secretstore::{Configuration as SecretStoreConfiguration, NodeSecretKey}; use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack}; use run::RunCmd; use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat}; @@ -995,10 +995,10 @@ impl Configuration { self.interface(&self.args.flag_secretstore_http_interface) } - fn secretstore_self_secret(&self) -> Result, String> { + fn secretstore_self_secret(&self) -> Result, String> { match self.args.flag_secretstore_secret { - Some(ref s) => Ok(Some(s.parse() - .map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?)), + Some(ref s) => Ok(Some(NodeSecretKey::Plain(s.parse() + .map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))), None => Ok(None), } } diff --git a/parity/secretstore.rs b/parity/secretstore.rs index b29f43479..7cdd26377 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -21,13 +21,20 @@ use ethcore::client::Client; use ethkey::{Secret, Public}; use helpers::replace_home; +#[derive(Debug, PartialEq, Clone)] +/// This node secret key. +pub enum NodeSecretKey { + /// Stored as plain text in configuration file. + Plain(Secret), +} + #[derive(Debug, PartialEq, Clone)] /// Secret store configuration pub struct Configuration { /// Is secret store functionality enabled? pub enabled: bool, /// This node secret. - pub self_secret: Option, + pub self_secret: Option, /// Other nodes IDs + addresses. pub nodes: BTreeMap, /// Interface to listen to @@ -66,9 +73,9 @@ mod server { #[cfg(feature="secretstore")] mod server { use std::sync::Arc; - use ethcore_secretstore; + use ethcore_secretstore::{self, NodeKeyPair}; use ethkey::KeyPair; - use super::{Configuration, Dependencies}; + use super::{Configuration, Dependencies, NodeSecretKey}; /// Key server pub struct KeyServer { @@ -77,8 +84,13 @@ mod server { impl KeyServer { /// Create new key server - pub fn new(conf: Configuration, deps: Dependencies) -> Result { - let self_secret = conf.self_secret.ok_or("self secret is required when using secretstore")?; + pub fn new(mut conf: Configuration, deps: Dependencies) -> Result { + let self_secret = match conf.self_secret.take() { + Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new( + KeyPair::from_secret(secret).map_err(|e| format!("invalid secret: {}", e))?)), + None => return Err("self secret is required when using secretstore".into()), + }; + let mut conf = ethcore_secretstore::ServiceConfiguration { listener_address: ethcore_secretstore::NodeAddress { address: conf.http_interface.clone(), @@ -99,12 +111,9 @@ mod server { }, }; - let self_key_pair = KeyPair::from_secret(self_secret.clone()) - .map_err(|e| format!("valid secret is required when using secretstore. Error: {}", e))?; - conf.cluster_config.nodes.insert(self_key_pair.public().clone(), conf.cluster_config.listener_address.clone()); + conf.cluster_config.nodes.insert(self_secret.public().clone(), conf.cluster_config.listener_address.clone()); - let node_key_pair = Arc::new(ethcore_secretstore::PlainNodeKeyPair::new(self_key_pair)); - let key_server = ethcore_secretstore::start(deps.client, node_key_pair, conf) + let key_server = ethcore_secretstore::start(deps.client, self_secret, conf) .map_err(Into::::into)?; Ok(KeyServer { From 2e9df2c39dbb6790d6c43befcf5214bcf650eeb7 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 25 Jul 2017 16:30:24 +0300 Subject: [PATCH 018/119] updated parity for NodeKeyPair --- ethcore/src/account_provider/mod.rs | 5 +++++ parity/configuration.rs | 5 ++++- parity/run.rs | 4 +++- parity/secretstore.rs | 32 ++++++++++++++++++++++++++--- secret_store/src/node_key_pair.rs | 26 ++++++++++++++++++----- 5 files changed, 62 insertions(+), 10 deletions(-) diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 249ca40af..769db692c 100755 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -519,6 +519,11 @@ impl AccountProvider { } } + /// Returns account public key. + pub fn account_public(&self, address: Address, password: &str) -> Result { + self.sstore.public(&self.sstore.account_ref(&address)?, password) + } + /// Returns each account along with name and meta. pub fn set_account_name(&self, address: Address, name: String) -> Result<(), Error> { self.sstore.set_name(&self.sstore.account_ref(&address)?, name)?; diff --git a/parity/configuration.rs b/parity/configuration.rs index e037defa2..09dbfeedf 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -997,8 +997,11 @@ impl Configuration { fn secretstore_self_secret(&self) -> Result, String> { match self.args.flag_secretstore_secret { - Some(ref s) => Ok(Some(NodeSecretKey::Plain(s.parse() + Some(ref s) if s.len() == 64 => Ok(Some(NodeSecretKey::Plain(s.parse() .map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))), + Some(ref s) if s.len() == 40 => Ok(Some(NodeSecretKey::KeyStore(s.parse() + .map_err(|e| format!("Invalid secret store secret address: {}. Error: {:?}", s, e))?))), + Some(_) => Err(format!("Invalid secret store secret. Must be either existing account address, or hex-encoded private key")), None => Ok(None), } } diff --git a/parity/run.rs b/parity/run.rs index 30f4c8759..8fc5da405 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -489,7 +489,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R } // Attempt to sign in the engine signer. - if !passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { + if !passwords.iter().any(|p| miner.set_engine_signer(engine_signer, (*p).clone()).is_ok()) { return Err(format!("No valid password for the consensus signer {}. {}", engine_signer, VERIFY_PASSWORD_HINT)); } } @@ -705,6 +705,8 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // secret store key server let secretstore_deps = secretstore::Dependencies { client: client.clone(), + account_provider: account_provider, + accounts_passwords: &passwords, }; let secretstore_key_server = secretstore::start(cmd.secretstore_conf.clone(), secretstore_deps)?; diff --git a/parity/secretstore.rs b/parity/secretstore.rs index 7cdd26377..def2cd1a6 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -17,15 +17,19 @@ use std::collections::BTreeMap; use std::sync::Arc; use dir::default_data_path; +use ethcore::account_provider::AccountProvider; use ethcore::client::Client; use ethkey::{Secret, Public}; use helpers::replace_home; +use util::Address; #[derive(Debug, PartialEq, Clone)] /// This node secret key. pub enum NodeSecretKey { /// Stored as plain text in configuration file. Plain(Secret), + /// Stored as account in key store. + KeyStore(Address), } #[derive(Debug, PartialEq, Clone)] @@ -50,9 +54,13 @@ pub struct Configuration { } /// Secret store dependencies -pub struct Dependencies { +pub struct Dependencies<'a> { /// Blockchain client. pub client: Arc, + /// Account provider. + pub account_provider: Arc, + /// Passed accounts passwords. + pub accounts_passwords: &'a [String], } #[cfg(not(feature = "secretstore"))] @@ -73,7 +81,7 @@ mod server { #[cfg(feature="secretstore")] mod server { use std::sync::Arc; - use ethcore_secretstore::{self, NodeKeyPair}; + use ethcore_secretstore; use ethkey::KeyPair; use super::{Configuration, Dependencies, NodeSecretKey}; @@ -85,9 +93,27 @@ mod server { impl KeyServer { /// Create new key server pub fn new(mut conf: Configuration, deps: Dependencies) -> Result { - let self_secret = match conf.self_secret.take() { + let self_secret: Arc = match conf.self_secret.take() { Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new( KeyPair::from_secret(secret).map_err(|e| format!("invalid secret: {}", e))?)), + Some(NodeSecretKey::KeyStore(account)) => { + // Check if account exists + if !deps.account_provider.has_account(account.clone()).unwrap_or(false) { + return Err(format!("Account {} passed as secret store node key is not found", account)); + } + + // Check if any passwords have been read from the password file(s) + if deps.accounts_passwords.is_empty() { + return Err(format!("No password found for the secret store node account {}", account)); + } + + // Attempt to sign in the engine signer. + let password = deps.accounts_passwords.iter() + .find(|p| deps.account_provider.sign(account.clone(), Some((*p).clone()), Default::default()).is_ok()) + .ok_or(format!("No valid password for the secret store node account {}", account))?; + Arc::new(ethcore_secretstore::KeyStoreNodeKeyPair::new(deps.account_provider, account, password.clone()) + .map_err(|e| format!("{}", e))?) + }, None => return Err("self secret is required when using secretstore".into()), }; diff --git a/secret_store/src/node_key_pair.rs b/secret_store/src/node_key_pair.rs index 8676dd16d..556625079 100644 --- a/secret_store/src/node_key_pair.rs +++ b/secret_store/src/node_key_pair.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use ethcrypto::ecdh::agree; use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign}; use ethcore::account_provider::AccountProvider; -use util::H256; +use util::{Address, H256}; use traits::NodeKeyPair; pub struct PlainNodeKeyPair { @@ -26,7 +26,10 @@ pub struct PlainNodeKeyPair { } pub struct KeyStoreNodeKeyPair { - _account_provider: Arc, + account_provider: Arc, + address: Address, + public: Public, + password: String, } impl PlainNodeKeyPair { @@ -52,13 +55,26 @@ impl NodeKeyPair for PlainNodeKeyPair { } } +impl KeyStoreNodeKeyPair { + pub fn new(account_provider: Arc, address: Address, password: String) -> Result { + let public = account_provider.account_public(address.clone(), &password).map_err(|e| EthKeyError::Custom(format!("{}", e)))?; + Ok(KeyStoreNodeKeyPair { + account_provider: account_provider, + address: address, + public: public, + password: password, + }) + } +} + impl NodeKeyPair for KeyStoreNodeKeyPair { fn public(&self) -> &Public { - unimplemented!() + &self.public } - fn sign(&self, _data: &H256) -> Result { - unimplemented!() + fn sign(&self, data: &H256) -> Result { + self.account_provider.sign(self.address.clone(), Some(self.password.clone()), data.clone()) + .map_err(|e| EthKeyError::Custom(format!("{}", e))) } fn compute_shared_key(&self, _peer_public: &Public) -> Result { From eb895fbb3199cd81c887c3048ba2c2090f927ac6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 25 Jul 2017 17:54:32 +0300 Subject: [PATCH 019/119] completed KeyStoreNodeKeyPair --- Cargo.lock | 1 + ethcore/src/account_provider/mod.rs | 7 +++++++ ethstore/Cargo.toml | 1 + ethstore/src/account/safe_account.rs | 9 ++++++++- ethstore/src/ethstore.rs | 12 ++++++++++++ ethstore/src/lib.rs | 1 + ethstore/src/secret_store.rs | 2 ++ secret_store/src/key_server.rs | 1 - secret_store/src/node_key_pair.rs | 5 +++-- 9 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae33d7590..0c049c948 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,6 +794,7 @@ name = "ethstore" version = "0.1.0" dependencies = [ "ethcore-bigint 0.1.3", + "ethcore-util 1.8.0", "ethcrypto 0.1.0", "ethkey 0.2.0", "itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 769db692c..752cec964 100755 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -702,6 +702,13 @@ impl AccountProvider { Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?) } + /// Agree on shared key. + pub fn agree(&self, address: Address, password: Option, other_public: &Public) -> Result { + let account = self.sstore.account_ref(&address)?; + let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?; + Ok(self.sstore.agree(&account, &password, other_public)?) + } + /// Returns the underlying `SecretStore` reference if one exists. pub fn list_geth_accounts(&self, testnet: bool) -> Vec
{ self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect() diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index 117332022..9d8d2fce5 100755 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -19,6 +19,7 @@ itertools = "0.5" parking_lot = "0.4" ethcrypto = { path = "../ethcrypto" } ethcore-bigint = { path = "../util/bigint" } +ethcore-util = { path = "../util" } smallvec = "0.4" parity-wordlist = "1.0" tempdir = "0.3" diff --git a/ethstore/src/account/safe_account.rs b/ethstore/src/account/safe_account.rs index e0512fe8d..478b796e6 100755 --- a/ethstore/src/account/safe_account.rs +++ b/ethstore/src/account/safe_account.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ethkey::{KeyPair, sign, Address, Signature, Message, Public}; +use ethkey::{KeyPair, sign, Address, Signature, Message, Public, Secret}; +use crypto::ecdh::agree; use {json, Error, crypto}; use account::Version; use super::crypto::Crypto; @@ -135,6 +136,12 @@ impl SafeAccount { crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from) } + /// Agree on shared key. + pub fn agree(&self, password: &str, other: &Public) -> Result { + let secret = self.crypto.secret(password)?; + agree(&secret, other).map_err(From::from) + } + /// Derive public key. pub fn public(&self, password: &str) -> Result { let secret = self.crypto.secret(password)?; diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index 246671990..d32fa9f62 100755 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -97,6 +97,10 @@ impl SimpleSecretStore for EthStore { self.store.sign_derived(account_ref, password, derivation, message) } + fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result { + self.store.agree(account, password, other) + } + fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result, Error> { let account = self.get(account)?; account.decrypt(password, shared_mac, message) @@ -509,6 +513,14 @@ impl SimpleSecretStore for EthMultiStore { Err(Error::InvalidPassword) } + fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result { + let accounts = self.get_matching(account, password)?; + for account in accounts { + return account.agree(password, other); + } + Err(Error::InvalidPassword) + } + fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> { let is_vault_created = { // lock border let mut vaults = self.vaults.lock(); diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index 65935f89c..311e9e73a 100755 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -35,6 +35,7 @@ extern crate ethcore_bigint as bigint; extern crate ethcrypto as crypto; extern crate ethkey as _ethkey; extern crate parity_wordlist; +extern crate ethcore_util as util; #[macro_use] extern crate log; diff --git a/ethstore/src/secret_store.rs b/ethstore/src/secret_store.rs index 2deae023e..e364245b7 100755 --- a/ethstore/src/secret_store.rs +++ b/ethstore/src/secret_store.rs @@ -60,6 +60,8 @@ pub trait SimpleSecretStore: Send + Sync { fn sign_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation, message: &Message) -> Result; /// Decrypt a messages with given account. fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result, Error>; + /// Agree on shared key. + fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result; /// Returns all accounts in this secret store. fn accounts(&self) -> Result, Error>; diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index 0944dd37c..6526bff68 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -245,7 +245,6 @@ pub mod tests { let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect(); let configs: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration { threads: 1, -// self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())), listener_address: NodeAddress { address: "127.0.0.1".into(), port: start_port + (i as u16), diff --git a/secret_store/src/node_key_pair.rs b/secret_store/src/node_key_pair.rs index 556625079..ce6c88a07 100644 --- a/secret_store/src/node_key_pair.rs +++ b/secret_store/src/node_key_pair.rs @@ -77,7 +77,8 @@ impl NodeKeyPair for KeyStoreNodeKeyPair { .map_err(|e| EthKeyError::Custom(format!("{}", e))) } - fn compute_shared_key(&self, _peer_public: &Public) -> Result { - unimplemented!() + fn compute_shared_key(&self, peer_public: &Public) -> Result { + KeyPair::from_secret(self.account_provider.agree(self.address.clone(), Some(self.password.clone()), peer_public) + .map_err(|e| EthKeyError::Custom(format!("{}", e)))?) } } From 4938dfd971a6524310611fbb0da0f0fdd02e1a72 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 25 Jul 2017 17:57:27 +0300 Subject: [PATCH 020/119] removed comment --- secret_store/src/key_storage.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/secret_store/src/key_storage.rs b/secret_store/src/key_storage.rs index 18c61c1bf..08ebe6e1c 100644 --- a/secret_store/src/key_storage.rs +++ b/secret_store/src/key_storage.rs @@ -241,7 +241,6 @@ pub mod tests { data_path: path.as_str().to_owned(), cluster_config: ClusterConfiguration { threads: 1, - //self_private: (**Random.generate().unwrap().secret().clone()).into(), listener_address: NodeAddress { address: "0.0.0.0".to_owned(), port: 8083, From 689993a592418f0654f39e4df3ecebd66862fd22 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Tue, 25 Jul 2017 17:58:52 +0200 Subject: [PATCH 021/119] whisper parity.js api --- js/src/api/rpc/shh/shh.js | 62 ++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/js/src/api/rpc/shh/shh.js b/js/src/api/rpc/shh/shh.js index 9312df6c1..8bba37caa 100644 --- a/js/src/api/rpc/shh/shh.js +++ b/js/src/api/rpc/shh/shh.js @@ -14,58 +14,78 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -export default class Personal { +export default class Shh { constructor (transport) { this._transport = transport; } - addToGroup (identity) { + info () { return this._transport - .execute('shh_addToGroup', identity); + .execute('shh_info'); } - getFilterChanges (filterId) { + newKeyPair () { return this._transport - .execute('shh_getFilterChanges', filterId); + .execute('shh_newKeyPair'); } - getMessages (filterId) { + addPrivateKey (privKey) { return this._transport - .execute('shh_getMessages', filterId); + .execute('shh_addPrivateKey', privKey); } - hasIdentity (identity) { + newSymKey () { return this._transport - .execute('shh_hasIdentity', identity); + .execute('shh_newSymKey'); } - newFilter (options) { + getPublicKey (identity) { return this._transport - .execute('shh_newFilter', options); + .execute('shh_getPublicKey', identity); } - newGroup () { + getPrivateKey (identity) { return this._transport - .execute('shh_newGroup'); + .execute('shh_getPrivateKey', identity); } - newIdentity () { + getSymKey (identity) { return this._transport - .execute('shh_newIdentity'); + .execute('shh_getSymKey', identity); } - post (options) { + deleteKey (identity) { return this._transport - .execute('shh_post', options); + .execute('shh_deleteKey', identity); } - uninstallFilter (filterId) { + post (messageObj) { return this._transport - .execute('shh_uninstallFilter', filterId); + .execute('shh_post', messageObj); } - version () { + newMessageFilter (filterObj) { return this._transport - .execute('shh_version'); + .execute('shh_newMessageFilter', filterObj); + } + + getFilterChanges (identity) { + return this._transport + .execute('shh_getFilterChanges', identity); + } + + deleteMessageFilter (filterId) { + return this._transport + .execute('shh_deleteMessageFilter', filterId); + } + + subscribe (filterObj) { + return this._transport + .execute('shh_subscribe', filterObj); + } + + unsubscribe (subscriptionId) { + return this._transport + .execute('shh_unsubscribe', subscriptionId); } } From 417a037ac517d1e783f6c42c4fbc9e475a7ffffc Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 26 Jul 2017 14:09:41 +0300 Subject: [PATCH 022/119] improved logging --- .../src/key_server_cluster/cluster.rs | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index 155dd4a01..c267d1259 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -262,7 +262,7 @@ impl ClusterCore { fn connect_future(handle: &Handle, data: Arc, node_address: SocketAddr) -> BoxedEmptyFuture { let disconnected_nodes = data.connections.disconnected_nodes().keys().cloned().collect(); net_connect(&node_address, handle, data.self_key_pair.clone(), disconnected_nodes) - .then(move |result| ClusterCore::process_connection_result(data, false, result)) + .then(move |result| ClusterCore::process_connection_result(data, Some(node_address), result)) .then(|_| finished(())) .boxed() } @@ -290,7 +290,7 @@ impl ClusterCore { /// Accept connection future. fn accept_connection_future(handle: &Handle, data: Arc, stream: TcpStream, node_address: SocketAddr) -> BoxedEmptyFuture { net_accept_connection(node_address, stream, handle, data.self_key_pair.clone()) - .then(move |result| ClusterCore::process_connection_result(data, true, result)) + .then(move |result| ClusterCore::process_connection_result(data, None, result)) .then(|_| finished(())) .boxed() } @@ -370,10 +370,10 @@ impl ClusterCore { } /// Process connection future result. - fn process_connection_result(data: Arc, is_inbound: bool, result: Result>, io::Error>) -> IoFuture> { + fn process_connection_result(data: Arc, outbound_addr: Option, result: Result>, io::Error>) -> IoFuture> { match result { Ok(DeadlineStatus::Meet(Ok(connection))) => { - let connection = Connection::new(is_inbound, connection); + let connection = Connection::new(outbound_addr.is_none(), connection); if data.connections.insert(connection.clone()) { ClusterCore::process_connection_messages(data.clone(), connection) } else { @@ -381,15 +381,21 @@ impl ClusterCore { } }, Ok(DeadlineStatus::Meet(Err(err))) => { - warn!(target: "secretstore_net", "{}: protocol error {} when establishind connection", data.self_key_pair.public(), err); + warn!(target: "secretstore_net", "{}: protocol error {} when establishing {} connection{}", + data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); finished(Ok(())).boxed() }, Ok(DeadlineStatus::Timeout) => { - warn!(target: "secretstore_net", "{}: timeout when establishind connection", data.self_key_pair.public()); + warn!(target: "secretstore_net", "{}: timeout when establishing {} connection{}", + data.self_key_pair.public(), if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); finished(Ok(())).boxed() }, Err(err) => { - warn!(target: "secretstore_net", "{}: network error {} when establishind connection", data.self_key_pair.public(), err); + warn!(target: "secretstore_net", "{}: network error {} when establishing {} connection{}", + data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" }, + outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default()); finished(Ok(())).boxed() }, } From dcfb8c1a10f6590c5b565e71ec491fb9fba038dc Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 26 Jul 2017 14:09:52 +0300 Subject: [PATCH 023/119] fixed generation session lags --- secret_store/src/key_server_cluster/generation_session.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/secret_store/src/key_server_cluster/generation_session.rs b/secret_store/src/key_server_cluster/generation_session.rs index e94d5bd35..0ba82524e 100644 --- a/secret_store/src/key_server_cluster/generation_session.rs +++ b/secret_store/src/key_server_cluster/generation_session.rs @@ -399,7 +399,7 @@ impl SessionImpl { // check state if data.state != SessionState::WaitingForKeysDissemination { match data.state { - SessionState::WaitingForInitializationComplete => return Err(Error::TooEarlyForRequest), + SessionState::WaitingForInitializationComplete | SessionState::WaitingForInitializationConfirm(_) => return Err(Error::TooEarlyForRequest), _ => return Err(Error::InvalidStateForRequest), } } From c466def1e8bc2e9a25c1cf5434cd18134200be68 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 27 Jul 2017 11:33:09 +0300 Subject: [PATCH 024/119] improved logging --- parity/secretstore.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/parity/secretstore.rs b/parity/secretstore.rs index def2cd1a6..0f23ffdf5 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -117,7 +117,8 @@ mod server { None => return Err("self secret is required when using secretstore".into()), }; - let mut conf = ethcore_secretstore::ServiceConfiguration { + let key_server_name = format!("{}:{}", conf.interface, conf.port); + let mut cconf = ethcore_secretstore::ServiceConfiguration { listener_address: ethcore_secretstore::NodeAddress { address: conf.http_interface.clone(), port: conf.http_port, @@ -137,10 +138,10 @@ mod server { }, }; - conf.cluster_config.nodes.insert(self_secret.public().clone(), conf.cluster_config.listener_address.clone()); + cconf.cluster_config.nodes.insert(self_secret.public().clone(), cconf.cluster_config.listener_address.clone()); - let key_server = ethcore_secretstore::start(deps.client, self_secret, conf) - .map_err(Into::::into)?; + let key_server = ethcore_secretstore::start(deps.client, self_secret, cconf) + .map_err(|e| format!("Error starting KeyServer {}: {}", key_server_name, e))?; Ok(KeyServer { _key_server: key_server, From b13cd0d484a95a9ce368de5d6d749bafeb602f29 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Thu, 27 Jul 2017 12:18:07 +0200 Subject: [PATCH 025/119] getFilterChanges -> getFilterMessages , subscribe & unsubscribe subscription is currently not working (method not found) --- js/src/api/rpc/shh/shh.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/src/api/rpc/shh/shh.js b/js/src/api/rpc/shh/shh.js index 8bba37caa..c58754abf 100644 --- a/js/src/api/rpc/shh/shh.js +++ b/js/src/api/rpc/shh/shh.js @@ -69,9 +69,9 @@ export default class Shh { .execute('shh_newMessageFilter', filterObj); } - getFilterChanges (identity) { + getFilterMessages (filterId) { return this._transport - .execute('shh_getFilterChanges', identity); + .execute('shh_getFilterMessages', filterId); } deleteMessageFilter (filterId) { @@ -79,13 +79,13 @@ export default class Shh { .execute('shh_deleteMessageFilter', filterId); } - subscribe (filterObj) { + subscribe (filterObj, callback) { return this._transport - .execute('shh_subscribe', filterObj); + .subscribe('shh', callback, filterObj); } unsubscribe (subscriptionId) { return this._transport - .execute('shh_unsubscribe', subscriptionId); + .unsubscribe(subscriptionId); } } From 7c05a906d095a0e1c0f6cac16eec88247612856c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 27 Jul 2017 13:29:09 +0300 Subject: [PATCH 026/119] cli option to disable SS HTTP API --- parity/cli/config.full.toml | 3 ++- parity/cli/mod.rs | 5 ++++ parity/cli/usage.txt | 1 + parity/configuration.rs | 6 +++++ parity/secretstore.rs | 7 ++++-- secret_store/src/http_listener.rs | 25 ++++++++++++------- .../key_server_cluster/generation_session.rs | 2 +- secret_store/src/key_storage.rs | 5 +--- secret_store/src/lib.rs | 2 +- secret_store/src/types/all.rs | 4 +-- 10 files changed, 40 insertions(+), 20 deletions(-) diff --git a/parity/cli/config.full.toml b/parity/cli/config.full.toml index 581871997..47ca9ffd8 100644 --- a/parity/cli/config.full.toml +++ b/parity/cli/config.full.toml @@ -76,8 +76,9 @@ path = "$HOME/.parity/dapps" user = "test_user" pass = "test_pass" -[secretstore] +[secretstore] disable = false +disable_http = false nodes = [] http_interface = "local" http_port = 8082 diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 262e054a2..27c5c40ff 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -216,6 +216,8 @@ usage! { // Secret Store flag_no_secretstore: bool = false, or |c: &Config| otry!(c.secretstore).disable.clone(), + flag_no_secretstore_http: bool = false, + or |c: &Config| otry!(c.secretstore).disable_http.clone(), flag_secretstore_secret: Option = None, or |c: &Config| otry!(c.secretstore).self_secret.clone().map(Some), flag_secretstore_nodes: String = "", @@ -510,6 +512,7 @@ struct Dapps { #[derive(Default, Debug, PartialEq, Deserialize)] struct SecretStore { disable: Option, + disable_http: Option, self_secret: Option, nodes: Option>, interface: Option, @@ -779,6 +782,7 @@ mod tests { flag_no_dapps: false, flag_no_secretstore: false, + flag_no_secretstore_http: false, flag_secretstore_secret: None, flag_secretstore_nodes: "".into(), flag_secretstore_interface: "local".into(), @@ -1009,6 +1013,7 @@ mod tests { }), secretstore: Some(SecretStore { disable: None, + disable_http: None, self_secret: None, nodes: None, interface: None, diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index dc4796e05..38c76b71f 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -228,6 +228,7 @@ API and Console Options: Secret Store Options: --no-secretstore Disable Secret Store functionality. (default: {flag_no_secretstore}) + --no-secretstore-http Disable Secret Store HTTP API. (default: {flag_no_secretstore_http}) --secretstore-secret SECRET Hex-encoded secret key of this node. (required, default: {flag_secretstore_secret:?}). --secretstore-nodes NODES Comma-separated list of other secret store cluster nodes in form diff --git a/parity/configuration.rs b/parity/configuration.rs index 09dbfeedf..b17eeadef 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -586,6 +586,7 @@ impl Configuration { fn secretstore_config(&self) -> Result { Ok(SecretStoreConfiguration { enabled: self.secretstore_enabled(), + http_enabled: self.secretstore_http_enabled(), self_secret: self.secretstore_self_secret()?, nodes: self.secretstore_nodes()?, interface: self.secretstore_interface(), @@ -1050,6 +1051,10 @@ impl Configuration { !self.args.flag_no_secretstore && cfg!(feature = "secretstore") } + fn secretstore_http_enabled(&self) -> bool { + !self.args.flag_no_secretstore_http && cfg!(feature = "secretstore") + } + fn ui_enabled(&self) -> bool { if self.args.flag_force_ui { return true; @@ -1331,6 +1336,7 @@ mod tests { no_persistent_txqueue: false, }; expected.secretstore_conf.enabled = cfg!(feature = "secretstore"); + expected.secretstore_conf.http_enabled = cfg!(feature = "secretstore"); assert_eq!(conf.into_command().unwrap().cmd, Cmd::Run(expected)); } diff --git a/parity/secretstore.rs b/parity/secretstore.rs index 0f23ffdf5..ef577c988 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -37,6 +37,8 @@ pub enum NodeSecretKey { pub struct Configuration { /// Is secret store functionality enabled? pub enabled: bool, + /// Is HTTP API enabled? + pub http_enabled: bool, /// This node secret. pub self_secret: Option, /// Other nodes IDs + addresses. @@ -119,10 +121,10 @@ mod server { let key_server_name = format!("{}:{}", conf.interface, conf.port); let mut cconf = ethcore_secretstore::ServiceConfiguration { - listener_address: ethcore_secretstore::NodeAddress { + listener_address: if conf.http_enabled { Some(ethcore_secretstore::NodeAddress { address: conf.http_interface.clone(), port: conf.http_port, - }, + }) } else { None }, data_path: conf.data_path.clone(), cluster_config: ethcore_secretstore::ClusterConfiguration { threads: 4, @@ -157,6 +159,7 @@ impl Default for Configuration { let data_dir = default_data_path(); Configuration { enabled: true, + http_enabled: true, self_secret: None, nodes: BTreeMap::new(), interface: "127.0.0.1".to_owned(), diff --git a/secret_store/src/http_listener.rs b/secret_store/src/http_listener.rs index 1f7f14ede..86688618a 100644 --- a/secret_store/src/http_listener.rs +++ b/secret_store/src/http_listener.rs @@ -39,7 +39,7 @@ use types::all::{Error, Public, MessageHash, EncryptedMessageSignature, NodeAddr /// To sign message with server key: GET /{server_key_id}/{signature}/{message_hash} pub struct KeyServerHttpListener { - _http_server: HttpListening, + http_server: Option, handler: Arc>, } @@ -74,19 +74,26 @@ struct KeyServerSharedHttpHandler { impl KeyServerHttpListener where T: KeyServer + 'static { /// Start KeyServer http listener - pub fn start(listener_address: &NodeAddress, key_server: T) -> Result { + pub fn start(listener_address: Option, key_server: T) -> Result { let shared_handler = Arc::new(KeyServerSharedHttpHandler { key_server: key_server, }); - let handler = KeyServerHttpHandler { + /*let handler = KeyServerHttpHandler { handler: shared_handler.clone(), - }; + };*/ - let listener_addr: &str = &format!("{}:{}", listener_address.address, listener_address.port); + let http_server = listener_address + .map(|listener_address| format!("{}:{}", listener_address.address, listener_address.port)) + .map(|listener_address| HttpServer::http(&listener_address).expect("cannot start HttpServer")) + .map(|http_server| http_server.handle(KeyServerHttpHandler { + handler: shared_handler.clone(), + }).expect("cannot start HttpServer")); + + /*let listener_addr: &str = &format!("{}:{}", listener_address.address, listener_address.port); let http_server = HttpServer::http(&listener_addr).expect("cannot start HttpServer"); - let http_server = http_server.handle(handler).expect("cannot start HttpServer"); + let http_server = http_server.handle(handler).expect("cannot start HttpServer");*/ let listener = KeyServerHttpListener { - _http_server: http_server, + http_server: http_server, handler: shared_handler, }; Ok(listener) @@ -128,7 +135,7 @@ impl MessageSigner for KeyServerHttpListener where T: KeyServer + 'static impl Drop for KeyServerHttpListener where T: KeyServer + 'static { fn drop(&mut self) { // ignore error as we are dropping anyway - let _ = self._http_server.close(); + self.http_server.take().map(|mut s| { let _ = s.close(); }); } } @@ -318,7 +325,7 @@ mod tests { fn http_listener_successfully_drops() { let key_server = DummyKeyServer; let address = NodeAddress { address: "127.0.0.1".into(), port: 9000 }; - let listener = KeyServerHttpListener::start(&address, key_server).unwrap(); + let listener = KeyServerHttpListener::start(Some(address), key_server).unwrap(); drop(listener); } diff --git a/secret_store/src/key_server_cluster/generation_session.rs b/secret_store/src/key_server_cluster/generation_session.rs index 0ba82524e..ade78bc57 100644 --- a/secret_store/src/key_server_cluster/generation_session.rs +++ b/secret_store/src/key_server_cluster/generation_session.rs @@ -1104,7 +1104,7 @@ pub mod tests { secret1: math::generate_random_scalar().unwrap().into(), secret2: math::generate_random_scalar().unwrap().into(), publics: vec![math::generate_random_point().unwrap().into()], - }).unwrap_err(), Error::InvalidStateForRequest); + }).unwrap_err(), Error::TooEarlyForRequest); } #[test] diff --git a/secret_store/src/key_storage.rs b/secret_store/src/key_storage.rs index 08ebe6e1c..20b5eaf6c 100644 --- a/secret_store/src/key_storage.rs +++ b/secret_store/src/key_storage.rs @@ -234,10 +234,7 @@ pub mod tests { fn persistent_key_storage() { let path = RandomTempPath::create_dir(); let config = ServiceConfiguration { - listener_address: NodeAddress { - address: "0.0.0.0".to_owned(), - port: 8082, - }, + listener_address: None, data_path: path.as_str().to_owned(), cluster_config: ClusterConfiguration { threads: 1, diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index 7e9897e60..6ead7c657 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -77,6 +77,6 @@ pub fn start(client: Arc, self_key_pair: Arc, config: Servi let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?; let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?); let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, self_key_pair, acl_storage, key_storage)?; - let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?; + let listener = http_listener::KeyServerHttpListener::start(config.listener_address, key_server)?; Ok(Box::new(listener)) } diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index 8dc92f175..6bc0d9c87 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -69,8 +69,8 @@ pub struct NodeAddress { #[binary] /// Secret store configuration pub struct ServiceConfiguration { - /// HTTP listener address. - pub listener_address: NodeAddress, + /// HTTP listener address. If None, HTTP API is disabled. + pub listener_address: Option, /// Data directory path for secret store pub data_path: String, /// Cluster configuration. From 8238fb37f3bb651b3b519928439defe24ff4893b Mon Sep 17 00:00:00 2001 From: fro Date: Thu, 27 Jul 2017 15:36:55 +0300 Subject: [PATCH 027/119] new env exports added ___syscall140 ___syscall146 ___syscall54 _llvm_trap --- ethcore/evm/src/wasm/env.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/evm/src/wasm/env.rs index e68e50432..19cffad7e 100644 --- a/ethcore/evm/src/wasm/env.rs +++ b/ethcore/evm/src/wasm/env.rs @@ -100,5 +100,25 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ "___syscall6", &[I32; 2], Some(I32), - ) + ), + Static( + "___syscall140", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall146", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall54", + &[I32; 2], + Some(I32) + ), + Static( + "_llvm_trap", + &[I32; 0], + None + ), ]; From c345bc3d856e48c3c37f0a56bbea7cc1eabc74dc Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 27 Jul 2017 15:48:07 +0300 Subject: [PATCH 028/119] cli option to disable SS ACL check --- parity/cli/config.full.toml | 1 + parity/cli/mod.rs | 5 ++ parity/cli/usage.txt | 1 + parity/configuration.rs | 5 ++ parity/secretstore.rs | 4 ++ secret_store/src/acl_storage.rs | 57 ++++++++----------- secret_store/src/key_server.rs | 2 +- .../key_server_cluster/decryption_session.rs | 2 +- secret_store/src/key_server_cluster/mod.rs | 2 +- .../src/key_server_cluster/signing_session.rs | 2 +- secret_store/src/key_storage.rs | 1 + secret_store/src/lib.rs | 6 +- secret_store/src/types/all.rs | 2 + 13 files changed, 53 insertions(+), 37 deletions(-) diff --git a/parity/cli/config.full.toml b/parity/cli/config.full.toml index 47ca9ffd8..75677ed6c 100644 --- a/parity/cli/config.full.toml +++ b/parity/cli/config.full.toml @@ -79,6 +79,7 @@ pass = "test_pass" [secretstore] disable = false disable_http = false +disable_acl_check = false nodes = [] http_interface = "local" http_port = 8082 diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 27c5c40ff..50032767a 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -218,6 +218,8 @@ usage! { or |c: &Config| otry!(c.secretstore).disable.clone(), flag_no_secretstore_http: bool = false, or |c: &Config| otry!(c.secretstore).disable_http.clone(), + flag_no_secretstore_acl_check: bool = false, + or |c: &Config| otry!(c.secretstore).disable_acl_check.clone(), flag_secretstore_secret: Option = None, or |c: &Config| otry!(c.secretstore).self_secret.clone().map(Some), flag_secretstore_nodes: String = "", @@ -513,6 +515,7 @@ struct Dapps { struct SecretStore { disable: Option, disable_http: Option, + disable_acl_check: Option, self_secret: Option, nodes: Option>, interface: Option, @@ -783,6 +786,7 @@ mod tests { flag_no_secretstore: false, flag_no_secretstore_http: false, + flag_no_secretstore_acl_check: false, flag_secretstore_secret: None, flag_secretstore_nodes: "".into(), flag_secretstore_interface: "local".into(), @@ -1014,6 +1018,7 @@ mod tests { secretstore: Some(SecretStore { disable: None, disable_http: None, + disable_acl_check: None, self_secret: None, nodes: None, interface: None, diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index 38c76b71f..da36c4a2b 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -229,6 +229,7 @@ API and Console Options: Secret Store Options: --no-secretstore Disable Secret Store functionality. (default: {flag_no_secretstore}) --no-secretstore-http Disable Secret Store HTTP API. (default: {flag_no_secretstore_http}) + --no-acl-check Disable ACL check (useful for test environments). (default: {flag_no_secretstore_acl_check}) --secretstore-secret SECRET Hex-encoded secret key of this node. (required, default: {flag_secretstore_secret:?}). --secretstore-nodes NODES Comma-separated list of other secret store cluster nodes in form diff --git a/parity/configuration.rs b/parity/configuration.rs index b17eeadef..0583bdb81 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -587,6 +587,7 @@ impl Configuration { Ok(SecretStoreConfiguration { enabled: self.secretstore_enabled(), http_enabled: self.secretstore_http_enabled(), + acl_check_enabled: self.secretstore_acl_check_enabled(), self_secret: self.secretstore_self_secret()?, nodes: self.secretstore_nodes()?, interface: self.secretstore_interface(), @@ -1055,6 +1056,10 @@ impl Configuration { !self.args.flag_no_secretstore_http && cfg!(feature = "secretstore") } + fn secretstore_acl_check_enabled(&self) -> bool { + !self.args.flag_no_secretstore_acl_check + } + fn ui_enabled(&self) -> bool { if self.args.flag_force_ui { return true; diff --git a/parity/secretstore.rs b/parity/secretstore.rs index ef577c988..8094ef323 100644 --- a/parity/secretstore.rs +++ b/parity/secretstore.rs @@ -39,6 +39,8 @@ pub struct Configuration { pub enabled: bool, /// Is HTTP API enabled? pub http_enabled: bool, + /// Is ACL check enabled. + pub acl_check_enabled: bool, /// This node secret. pub self_secret: Option, /// Other nodes IDs + addresses. @@ -126,6 +128,7 @@ mod server { port: conf.http_port, }) } else { None }, data_path: conf.data_path.clone(), + acl_check_enabled: conf.acl_check_enabled, cluster_config: ethcore_secretstore::ClusterConfiguration { threads: 4, listener_address: ethcore_secretstore::NodeAddress { @@ -160,6 +163,7 @@ impl Default for Configuration { Configuration { enabled: true, http_enabled: true, + acl_check_enabled: true, self_secret: None, nodes: BTreeMap::new(), interface: "127.0.0.1".to_owned(), diff --git a/secret_store/src/acl_storage.rs b/secret_store/src/acl_storage.rs index 37d5bcd25..0a3ee9276 100644 --- a/secret_store/src/acl_storage.rs +++ b/secret_store/src/acl_storage.rs @@ -15,8 +15,9 @@ // along with Parity. If not, see . use std::sync::{Arc, Weak}; +use std::collections::{HashMap, HashSet}; use futures::{future, Future}; -use parking_lot::Mutex; +use parking_lot::{Mutex, RwLock}; use ethkey::public_to_address; use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify}; use native_contracts::SecretStoreAclStorage; @@ -47,6 +48,12 @@ struct CachedContract { contract: Option, } +#[derive(Default, Debug)] +/// Dummy ACL storage implementation (check always passed). +pub struct DummyAclStorage { + prohibited: RwLock>>, +} + impl OnChainAclStorage { pub fn new(client: &Arc) -> Arc { let acl_storage = Arc::new(OnChainAclStorage { @@ -113,36 +120,22 @@ impl CachedContract { } } -#[cfg(test)] -pub mod tests { - use std::collections::{HashMap, HashSet}; - use parking_lot::RwLock; - use types::all::{Error, ServerKeyId, Public}; - use super::AclStorage; - - #[derive(Default, Debug)] - /// Dummy ACL storage implementation - pub struct DummyAclStorage { - prohibited: RwLock>>, - } - - impl DummyAclStorage { - #[cfg(test)] - /// Prohibit given requestor access to given document - pub fn prohibit(&self, public: Public, document: ServerKeyId) { - self.prohibited.write() - .entry(public) - .or_insert_with(Default::default) - .insert(document); - } - } - - impl AclStorage for DummyAclStorage { - fn check(&self, public: &Public, document: &ServerKeyId) -> Result { - Ok(self.prohibited.read() - .get(public) - .map(|docs| !docs.contains(document)) - .unwrap_or(true)) - } +impl DummyAclStorage { + #[cfg(test)] + /// Prohibit given requestor access to given document + pub fn prohibit(&self, public: Public, document: ServerKeyId) { + self.prohibited.write() + .entry(public) + .or_insert_with(Default::default) + .insert(document); + } +} + +impl AclStorage for DummyAclStorage { + fn check(&self, public: &Public, document: &ServerKeyId) -> Result { + Ok(self.prohibited.read() + .get(public) + .map(|docs| !docs.contains(document)) + .unwrap_or(true)) } } diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index 6526bff68..f9fad19df 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -196,7 +196,7 @@ pub mod tests { use std::collections::BTreeMap; use ethcrypto; use ethkey::{self, Secret, Random, Generator}; - use acl_storage::tests::DummyAclStorage; + use acl_storage::DummyAclStorage; use key_storage::tests::DummyKeyStorage; use node_key_pair::PlainNodeKeyPair; use key_server_set::tests::MapKeyServerSet; diff --git a/secret_store/src/key_server_cluster/decryption_session.rs b/secret_store/src/key_server_cluster/decryption_session.rs index 6a806bb92..afc73f858 100644 --- a/secret_store/src/key_server_cluster/decryption_session.rs +++ b/secret_store/src/key_server_cluster/decryption_session.rs @@ -467,7 +467,7 @@ impl Ord for DecryptionSessionId { mod tests { use std::sync::Arc; use std::collections::BTreeMap; - use super::super::super::acl_storage::tests::DummyAclStorage; + use super::super::super::acl_storage::DummyAclStorage; use ethkey::{self, KeyPair, Random, Generator, Public, Secret}; use key_server_cluster::{NodeId, DocumentKeyShare, SessionId, Error, EncryptedDocumentKeyShadow, SessionMeta}; use key_server_cluster::cluster::tests::DummyCluster; diff --git a/secret_store/src/key_server_cluster/mod.rs b/secret_store/src/key_server_cluster/mod.rs index 102c3672f..4fcda1539 100644 --- a/secret_store/src/key_server_cluster/mod.rs +++ b/secret_store/src/key_server_cluster/mod.rs @@ -36,7 +36,7 @@ pub use super::node_key_pair::PlainNodeKeyPair; #[cfg(test)] pub use super::key_storage::tests::DummyKeyStorage; #[cfg(test)] -pub use super::acl_storage::tests::DummyAclStorage; +pub use super::acl_storage::DummyAclStorage; #[cfg(test)] pub use super::key_server_set::tests::MapKeyServerSet; diff --git a/secret_store/src/key_server_cluster/signing_session.rs b/secret_store/src/key_server_cluster/signing_session.rs index 00246ae64..e647c8b14 100644 --- a/secret_store/src/key_server_cluster/signing_session.rs +++ b/secret_store/src/key_server_cluster/signing_session.rs @@ -572,7 +572,7 @@ mod tests { use std::collections::{BTreeMap, VecDeque}; use ethkey::{self, Random, Generator, Public}; use util::H256; - use super::super::super::acl_storage::tests::DummyAclStorage; + use super::super::super::acl_storage::DummyAclStorage; use key_server_cluster::{NodeId, SessionId, SessionMeta, Error, KeyStorage}; use key_server_cluster::cluster::tests::DummyCluster; use key_server_cluster::generation_session::{Session as GenerationSession}; diff --git a/secret_store/src/key_storage.rs b/secret_store/src/key_storage.rs index 20b5eaf6c..2fad4cdf7 100644 --- a/secret_store/src/key_storage.rs +++ b/secret_store/src/key_storage.rs @@ -235,6 +235,7 @@ pub mod tests { let path = RandomTempPath::create_dir(); let config = ServiceConfiguration { listener_address: None, + acl_check_enabled: true, data_path: path.as_str().to_owned(), cluster_config: ClusterConfiguration { threads: 1, diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index 6ead7c657..d7f35a55a 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -73,7 +73,11 @@ pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair}; pub fn start(client: Arc, self_key_pair: Arc, config: ServiceConfiguration) -> Result, Error> { use std::sync::Arc; - let acl_storage = acl_storage::OnChainAclStorage::new(&client); + let acl_storage: Arc = if config.acl_check_enabled { + acl_storage::OnChainAclStorage::new(&client) + } else { + Arc::new(acl_storage::DummyAclStorage::default()) + }; let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?; let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?); let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, self_key_pair, acl_storage, key_storage)?; diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index 6bc0d9c87..6867c82f3 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -71,6 +71,8 @@ pub struct NodeAddress { pub struct ServiceConfiguration { /// HTTP listener address. If None, HTTP API is disabled. pub listener_address: Option, + /// Is ACL check enabled. If false, everyone has access to all keys. Useful for tests only. + pub acl_check_enabled: bool, /// Data directory path for secret store pub data_path: String, /// Cluster configuration. From f245d66c8a8ecd34af0a3ffb437bc795ab95abf7 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Thu, 27 Jul 2017 15:48:49 +0200 Subject: [PATCH 029/119] shh_subscription added --- js/src/api/transport/ws/ws.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/api/transport/ws/ws.js b/js/src/api/transport/ws/ws.js index 3c642d5f8..9c276772d 100644 --- a/js/src/api/transport/ws/ws.js +++ b/js/src/api/transport/ws/ws.js @@ -29,7 +29,7 @@ export default class Ws extends JsonRpcBase { this._url = url; this._token = token; this._messages = {}; - this._subscriptions = { 'eth_subscription': [], 'parity_subscription': [] }; + this._subscriptions = { 'eth_subscription': [], 'parity_subscription': [], 'shh_subscription': [] }; this._sessionHash = null; this._connecting = false; From 7a810def2836584a104b711da06c69bb1cdf4f31 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Thu, 27 Jul 2017 18:07:25 +0200 Subject: [PATCH 030/119] Shh documentation (jsonrpc interface) --- js/src/jsonrpc/interfaces/shh.js | 201 ++++++++++++++++++++++++------- js/src/jsonrpc/types.js | 2 + 2 files changed, 157 insertions(+), 46 deletions(-) diff --git a/js/src/jsonrpc/interfaces/shh.js b/js/src/jsonrpc/interfaces/shh.js index 801c965d0..87af117fe 100644 --- a/js/src/jsonrpc/interfaces/shh.js +++ b/js/src/jsonrpc/interfaces/shh.js @@ -14,21 +14,37 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { Data, Quantity } from '../types'; +import { Data, Quantity, Float } from '../types'; export default { - version: { - nodoc: 'Not present in Rust code', + info: { desc: 'Returns the current whisper protocol version.', params: [], returns: { - type: String, - desc: 'The current whisper protocol version' + type: Object, + desc: 'The current whisper protocol version', + details: { + minPow: { + type: Float, + desc: 'required PoW threshold for a message to be accepted into the local pool, or null if there is empty space in the pool.' + }, + messages: { + type: Quantity, + desc: 'Number of messages in the pool.' + }, + memory: { + type: Quantity, + desc: 'Amount of memory used by messages in the pool.' + }, + targetMemory: { + type: Quantity, + desc: 'Target amount of memory for the pool.' + } + } } }, post: { - nodoc: 'Not present in Rust code', desc: 'Sends a whisper message.', params: [ { @@ -63,79 +79,122 @@ export default { } }, - newIdentity: { - nodoc: 'Not present in Rust code', - desc: 'Creates new whisper identity in the client.', + newKeyPair: { + desc: 'Generate a new key pair (identity) for asymmetric encryption.', params: [], returns: { type: Data, - desc: '60 Bytes - the address of the new identiy' + desc: '32 Bytes - the address of the new identiy' } }, - hasIdentity: { - nodoc: 'Not present in Rust code', - desc: 'Checks if the client hold the private keys for a given identity.', + addPrivateKey: { + desc: 'Import a private key to use for asymmetric decryption.', params: [ { type: Data, - desc: '60 Bytes - The identity address to check' + desc: '32 Bytes - The private key to import' } ], returns: { - type: Boolean, - desc: '`true` if the client holds the privatekey for that identity, otherwise `false`' + type: Data, + desc: '`32 Bytes` A unique identity to refer to this keypair by.' } }, - newGroup: { - nodoc: 'Not present in Rust code', - desc: '(?)', + newSymKey: { + desc: 'Generate a key pair(identity) for symmetric encryption.', params: [], returns: { - type: Data, desc: '60 Bytes - the address of the new group. (?)' + type: Data, + desc: '32 Bytes - the address of the new identiy' } }, - addToGroup: { - nodoc: 'Not present in Rust code', - desc: '(?)', + getPublicKey: { + desc: 'Get the public key associated with an asymmetric identity.', params: [ { type: Data, - desc: '60 Bytes - The identity address to add to a group (?)' + desc: '32 Bytes - The identity to fetch the public key for.' } ], returns: { - type: Boolean, - desc: '`true` if the identity was successfully added to the group, otherwise `false` (?)' + type: Data, + desc: '`64 Bytes` - The public key of the asymmetric identity.' } }, - newFilter: { - nodoc: 'Not present in Rust code', - desc: 'Creates filter to notify, when client receives whisper message matching the filter options.', + getPrivateKey: { + desc: 'Get the private key associated with an asymmetric identity.', + params: [ + { + type: Data, + desc: '32 Bytes - The identity to fetch the private key for.' + } + ], + returns: { + type: Data, + desc: '`32 Bytes` - The private key of the asymmetric identity.' + } + }, + + getSymKey: { + desc: 'Get the key associated with a symmetric identity.', + params: [ + { + type: Data, + desc: '`32 Bytes` - The identity to fetch the key for.' + } + ], + returns: { + type: Data, + desc: '`64 Bytes` - The key of the asymmetric identity.' + } + }, + + deleteKey: { + desc: 'Delete the key or key pair denoted by the given identity.', + params: [ + { + type: Data, + desc: '`32 Bytes` - The identity to remove.' + } + ], + returns: { + type: Data, + desc: '`true` on successful removal, `false` on unkown identity' + } + }, + + newMessageFilter: { + desc: 'Create a new polled filter for messages.', params: [ { type: Object, desc: 'The filter options:', details: { - to: { - type: Data, desc: '60 Bytes - Identity of the receiver. *When present it will try to decrypt any incoming message if the client holds the private key to this identity.*', + decryptWith: { + type: Data, + desc: '`32 bytes` - Identity of key used for description. null if listening for broadcasts.' + }, + from: { + type: Data, desc: '`32 Bytes` - if present, only accept messages signed by this key.', optional: true }, topics: { - type: Array, desc: 'Array of `Data` topics which the incoming message\'s topics should match. You can use the following combinations' + type: Array, + desc: 'Array of `Data`. Only accept messages matching these topics. Should be non-empty.' } } } ], returns: { - type: Quantity, - desc: 'The newly created filter' + type: Data, + desc: '`32 bytes` - Unique identity for this filter.' } }, - uninstallFilter: { + getFilterMesssages: { nodoc: 'Not present in Rust code', desc: 'Uninstalls a filter with given id. Should always be called when watch is no longer needed.\nAdditonally Filters timeout when they aren\'t requested with [shh_getFilterChanges](#shh_getfilterchanges) for a period of time.', params: [ @@ -150,30 +209,80 @@ export default { } }, - getFilterChanges: { - nodoc: 'Not present in Rust code', + getFilterMessages: { desc: 'Polling method for whisper filters. Returns new messages since the last call of this method.\n**Note** calling the [shh_getMessages](#shh_getmessages) method, will reset the buffer for this method, so that you won\'t receive duplicate messages.', params: [ { - type: Quantity, - desc: 'The filter id' + type: Data, + desc: '`32 bytes` - Unique identity to fetch changes for.' } ], returns: { type: Array, - desc: 'Array of messages received since last poll' + desc: 'Array of `messages` received since last poll', + details: { + from: { + type: Data, + desc: '`64 bytes` - Public key that signed this message or null' + }, + recipient: { + type: Data, + desc: '`32 bytes` - local identity which decrypted this message, or null if broadcast.' + }, + ttl: { + type: Quantity, + desc: 'time to live of the message in seconds.' + }, + topics: { + type: Array, + desc: 'Array of `Data` - Topics which matched the filter' + }, + timestamp: { + type: Quantity, + desc: 'Unix timestamp of the message' + }, + payload: { + type: Data, + desc: 'The message body' + }, + padding: { + type: Data, + desc: 'Optional padding which was decoded.' + } + } } }, - getMessages: { - nodoc: 'Not present in Rust code', - desc: 'Get all messages matching a filter. Unlike `shh_getFilterChanges` this returns all messages.', + deleteMessageFilter: { + desc: 'Delete a message filter by identifier', params: [ { - type: Quantity, - desc: 'The filter id' + type: Data, + desc: '`32 bytes` - The identity of the filter to delete.' } ], - returns: 'See [shh_getFilterChanges](#shh_getfilterchanges)' + returns: { + type: Boolean, + desc: '`true` on deletion, `false` on unrecognized ID.' + } + }, + subscribe: { + desc: 'Open a subscription to a filter.', + params: 'See [shh_newMessageFilter](#shh_newmessagefilter)', + returns: { + type: Quantity, + desc: 'Unique subscription identifier' + } + }, + unsubscribe: { + desc: 'Close a subscribed filter', + params: [{ + type: Quantity, + desc: 'Unique subscription identifier' + }], + returns: { + type: Boolean, + desc: '`true` on success, `false` on unkown subscription ID.' + } } }; diff --git a/js/src/jsonrpc/types.js b/js/src/jsonrpc/types.js index 52e79019e..c750932c9 100644 --- a/js/src/jsonrpc/types.js +++ b/js/src/jsonrpc/types.js @@ -22,6 +22,8 @@ export class Hash {} export class Integer {} +export class Float {} + export class Quantity {} export class BlockNumber { From e234b7fdbf2c9ab30044073579fd1bd8488f51b6 Mon Sep 17 00:00:00 2001 From: fro Date: Fri, 28 Jul 2017 16:38:03 +0300 Subject: [PATCH 031/119] realloc test added --- ethcore/evm/src/wasm/env.rs | 37 ++++++++++++++++++++++++++++++++++- ethcore/evm/src/wasm/tests.rs | 24 +++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/evm/src/wasm/env.rs index cabd38bd9..00770bb4a 100644 --- a/ethcore/evm/src/wasm/env.rs +++ b/ethcore/evm/src/wasm/env.rs @@ -115,5 +115,40 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ "_emscripten_memcpy_big", &[I32; 3], Some(I32), - ) + ), + Static( + "___syscall140", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall146", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall54", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall6", + &[I32; 2], + Some(I32) + ), + Static( + "_llvm_trap", + &[I32; 0], + None + ), + Static( + "abortOnCannotGrowMemory", + &[I32; 0], + Some(I32) + ), + Static( + "___setErrNo", + &[I32; 1], + None + ), ]; diff --git a/ethcore/evm/src/wasm/tests.rs b/ethcore/evm/src/wasm/tests.rs index 8ae13daae..8c2ec0b3f 100644 --- a/ethcore/evm/src/wasm/tests.rs +++ b/ethcore/evm/src/wasm/tests.rs @@ -272,3 +272,27 @@ fn create() { )); assert_eq!(gas_left, U256::from(99_768)); } + +// Realloc test +#[test] +fn realloc() { + let code = load_sample!("realloc.wasm"); + + let mut params = ActionParams::default(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.data = Some(vec![0u8]); + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Realloc should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + assert_eq!(gas_left, U256::from(98326)); + assert_eq!(result, vec![0u8; 2]); + +} From ad30a6899b4306d447b6aeefed08c2b27296b0a9 Mon Sep 17 00:00:00 2001 From: Afri Date: Fri, 28 Jul 2017 18:15:04 +0200 Subject: [PATCH 032/119] Update Changelog for 1.6.10 and 1.7.0 (#6183) * Update changelog for 1.6.10 * Update changelog for 1.7.0 * Move 1.7.0 to top * Rephrase contract warp * Update final 1.7.0 changelog * Update beta backports in Changelog --- CHANGELOG.md | 59 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59eb1d0b4..78bf895ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,41 +1,45 @@ -## Parity [v1.6.10](https://github.com/paritytech/parity/releases/tag/v1.6.10) (2017-07-23) - -This is a hotfix release for the stable channel addressing the recent [multi-signature wallet vulnerability](https://blog.parity.io/security-alert-high-2/). Note, upgrading is not mandatory, and all future multi-sig wallets created by any version of Parity are secure. - -All Changes: - -- Backports for stable [#6116](https://github.com/paritytech/parity/pull/6116) - - Remove chunk to restore from pending set only upon successful import [#6112](https://github.com/paritytech/parity/pull/6112) - - Blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874) - - Bump snap version and tweak importing detection logic [#6079](https://github.com/paritytech/parity/pull/6079) (modified to work) -- Fix docker build for stable [#6118](https://github.com/paritytech/parity/pull/6118) -- Backported wallet fix [#6104](https://github.com/paritytech/parity/pull/6104) - - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) - - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) -- Bump to v1.6.10 - -## Parity [v1.7.0](https://github.com/paritytech/parity/releases/tag/v1.7.0) (2017-07-23) +## Parity [v1.7.0](https://github.com/paritytech/parity/releases/tag/v1.7.0) (2017-07-28) Parity 1.7.0 is a major release introducing several important features: -- **Experimental [Light client](https://github.com/paritytech/parity/wiki/The-Parity-Light-Protocol-(PIP)) support**. Start Parity with `--light` to enable light mode. +- **Experimental [Light client](https://github.com/paritytech/parity/wiki/The-Parity-Light-Protocol-(PIP)) support**. Start Parity with `--light` to enable light mode. Please, note: The wallet UI integration for the light client is not included, yet. - **Experimental web wallet**. A hosted version of Parity that keeps the keys and signs transactions using your browser storage. Try it at https://wallet.parity.io or run your own with `--public-node`. - **WASM contract support**. Private networks can run contracts compiled into WASM bytecode. _More information and documentation to follow_. - **DApps and RPC server merge**. DApp and RPC are now available through a single API endpoint. DApp server related settings are deprecated. - **Export accounts from the wallet**. Backing up your keys can now simply be managed through the wallet interface. -- **PoA/Kovan validator set contract**. The PoA network validator-set management via smart contract is now supported by warp and light sync. +- **PoA/Kovan validator set contract**. The PoA network validator-set management via smart contract is now supported by warp and, in the near future, light sync. - **PubSub API**. https://github.com/paritytech/parity/wiki/JSONRPC-Parity-Pub-Sub-module - **Signer apps for IOS and Android**. Full list of included changes: +- Backports [#6163](https://github.com/paritytech/parity/pull/6163) + - Light client improvements ([#6156](https://github.com/paritytech/parity/pull/6156)) + - No seal checking + - Import command and --no-seal-check for light client + - Fix eth_call + - Tweak registry dapps lookup + - Ignore failed requests to non-server peers + - Fix connecting to wildcard addresses. ([#6167](https://github.com/paritytech/parity/pull/6167)) + - Don't display an overlay in case the time sync check fails. ([#6164](https://github.com/paritytech/parity/pull/6164)) + - Small improvements to time estimation. + - Temporarily disable NTP time check by default. +- Light client fixes ([#6148](https://github.com/paritytech/parity/pull/6148)) [#6151](https://github.com/paritytech/parity/pull/6151) + - Light client fixes + - Fix memory-lru-cache + - Clear pending reqs on disconnect +- Filter tokens logs from current block, not genesis ([#6128](https://github.com/paritytech/parity/pull/6128)) [#6141](https://github.com/paritytech/parity/pull/6141) +- Fix QR scanner returning null on confirm [#6122](https://github.com/paritytech/parity/pull/6122) - Check QR before lowercase ([#6119](https://github.com/paritytech/parity/pull/6119)) [#6120](https://github.com/paritytech/parity/pull/6120) - Remove chunk to restore from pending set only upon successful import [#6117](https://github.com/paritytech/parity/pull/6117) - Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094) - Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095) +- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108) - Backported wallet fix [#6105](https://github.com/paritytech/parity/pull/6105) - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) +- Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095) +- Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094) - Bump snap version and tweak importing detection logic ([#6079](https://github.com/paritytech/parity/pull/6079)) [#6081](https://github.com/paritytech/parity/pull/6081) - bump last tick just before printing info and restore sync detection - bump kovan snapshot version @@ -439,6 +443,23 @@ Full list of included changes: - Update the Wallet Library Registry key [#4817](https://github.com/paritytech/parity/pull/4817) - Update Wallet to new Wallet Code [#4805](https://github.com/paritytech/parity/pull/4805) +## Parity [v1.6.10](https://github.com/paritytech/parity/releases/tag/v1.6.10) (2017-07-25) + +This is a hotfix release for the stable channel addressing the recent [multi-signature wallet vulnerability](https://blog.parity.io/security-alert-high-2/). Note, upgrading is not mandatory, and all future multi-sig wallets created by any version of Parity are secure. + +All Changes: + +- Backports for stable [#6116](https://github.com/paritytech/parity/pull/6116) + - Remove chunk to restore from pending set only upon successful import [#6112](https://github.com/paritytech/parity/pull/6112) + - Blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874) + - Bump snap version and tweak importing detection logic [#6079](https://github.com/paritytech/parity/pull/6079) (modified to work) +- Fix docker build for stable [#6118](https://github.com/paritytech/parity/pull/6118) +- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108) +- Backported wallet fix [#6104](https://github.com/paritytech/parity/pull/6104) + - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) + - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) +- Bump to v1.6.10 + ## Parity [v1.6.9](https://github.com/paritytech/parity/releases/tag/v1.6.9) (2017-07-16) This is a first stable release of 1.6 series. It contains a number of minor fixes and introduces the `--reseal-on-uncles` option for miners. From b5f1524e787235774b033f03851f9123c1b7b019 Mon Sep 17 00:00:00 2001 From: Joseph Mark Date: Sat, 29 Jul 2017 00:06:39 +0700 Subject: [PATCH 033/119] Refactor --allow-ips to handle custom ip-ranges (#6144) * Add checks for additional reserved ip addresses 100.64.0.0/10 and 240.0.0.0/4 are both reserved but not currently filtered. * Add check for special purpose addresses 192.0.0.0/24 - Used for the IANA IPv4 Special Purpose Address Registry * Refactor ip_utils (#5872) * Add checks for all ipv4 special use addresses * Add comprehensive ipv4 test cases * Refactor Ipv6 address checks (#5872) * Refactor AllowIP (#5872) * Add IpFilter struct to wrap predefined filter (AllowIP) with custom allow/block filters. * Refactor parsing of --allow-ips to handle custom filters. * Move AllowIP/IpFilter from ethsync to ethcore-network where they are used. * Revert Cargo.lock * Tests for custom ip filters (#5872) * Add "none" as a valid argument for --allow-ips to allow narrow custom ranges, eg.: --allow-ips="none 10.0.0.0/8" * Add tests for parsing filter arguments and node endpoints. * Add ipnetwork crate to dev dependencies for testing. * Add ipv6 filter tests (#5872) * Revert parity-ui-precompiled to master * Fix minor detail in usage.txt (#5872) * Spaces to tabs * Rename IpFilter::new() to ::default() * Small readability improvements * Test (#5872) * Revert "Test (#5872)" This reverts commit 7a8906430a6dad633fe29df3dca57f1630851fa9. --- Cargo.lock | 10 ++ Cargo.toml | 2 + parity/cli/usage.txt | 10 +- parity/configuration.rs | 68 ++++++- parity/helpers.rs | 5 +- parity/main.rs | 1 + sync/Cargo.toml | 1 + sync/src/api.rs | 42 +---- sync/src/lib.rs | 1 + util/network/Cargo.toml | 1 + util/network/src/discovery.rs | 19 +- util/network/src/host.rs | 10 +- util/network/src/ip_utils.rs | 319 +++++++++++++++++++++++++++++---- util/network/src/lib.rs | 48 ++++- util/network/src/node_table.rs | 82 +++++++-- 15 files changed, 508 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 359b2d2f9..52d0434a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,6 +656,7 @@ dependencies = [ "ethcrypto 0.1.0", "ethkey 0.2.0", "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -862,6 +863,7 @@ dependencies = [ "ethcore-util 1.8.0", "ethkey 0.2.0", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1149,6 +1151,11 @@ dependencies = [ "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ipnetwork" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "isatty" version = "0.1.1" @@ -1763,6 +1770,7 @@ dependencies = [ "ethcore-ipc-tests 0.1.0", "ethcore-light 1.8.0", "ethcore-logger 1.8.0", + "ethcore-network 1.8.0", "ethcore-secretstore 1.0.0", "ethcore-stratum 1.8.0", "ethcore-util 1.8.0", @@ -1771,6 +1779,7 @@ dependencies = [ "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3226,6 +3235,7 @@ dependencies = [ "checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76" "checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb" "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" +"checksum ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "232e76922883005380e831068f731ef0305541c9f77b30df3a1635047b16f370" "checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c" "checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a" "checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5" diff --git a/Cargo.toml b/Cargo.toml index 21961776e..97746c082 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ ethcore-ipc-hypervisor = { path = "ipc/hypervisor" } ethcore-light = { path = "ethcore/light" } ethcore-logger = { path = "logger" } ethcore-stratum = { path = "stratum" } +ethcore-network = { path = "util/network" } ethkey = { path = "ethkey" } rlp = { path = "util/rlp" } rpc-cli = { path = "rpc_cli" } @@ -65,6 +66,7 @@ rustc_version = "0.2" [dev-dependencies] ethcore-ipc-tests = { path = "ipc/tests" } pretty_assertions = "0.1" +ipnetwork = "0.12.6" [target.'cfg(windows)'.dependencies] winapi = "0.2" diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index 1c9e1e22c..c1d1ab9de 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -148,11 +148,15 @@ Networking Options: These nodes will always have a reserved slot on top of the normal maximum peers. (default: {flag_reserved_peers:?}) --reserved-only Connect only to reserved nodes. (default: {flag_reserved_only}) - --allow-ips FILTER Filter outbound connections. Must be one of: + --allow-ips FILTER Filter outbound connections. FILTER can be one of: private - connect to private network IP addresses only; public - connect to public network IP addresses only; - all - connect to any IP address. - (default: {flag_allow_ips}) + all - connect to any IP address; + none - block all (for use with a custom filter as below); + a custom filter list in the format: "private ip_range1 -ip_range2 ...". + Where ip_range1 would be allowed and ip_range2 blocked; + Custom blocks ("-ip_range") override custom allows ("ip_range"); + (default: {flag_allow_ips}). --max-pending-peers NUM Allow up to NUM pending connections. (default: {flag_max_pending_peers}) --no-ancient-blocks Disable downloading old blocks after snapshot restoration or warp sync. (default: {flag_no_ancient_blocks}) diff --git a/parity/configuration.rs b/parity/configuration.rs index 40726eeca..f1399e47c 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -24,7 +24,7 @@ use cli::{Args, ArgsError}; use util::{Hashable, H256, U256, Bytes, version_data, Address}; use util::journaldb::Algorithm; use util::Colour; -use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP}; +use ethsync::{NetworkConfiguration, is_valid_node_url}; use ethcore::ethstore::ethkey::{Secret, Public}; use ethcore::client::{VMType}; use ethcore::miner::{MinerOptions, Banning, StratumOptions}; @@ -48,6 +48,7 @@ use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockcha use presale::ImportWallet; use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts}; use snapshot::{self, SnapshotCommand}; +use network::{IpFilter}; #[derive(Debug, PartialEq)] pub enum Cmd { @@ -461,12 +462,10 @@ impl Configuration { max(self.min_peers(), peers) } - fn allow_ips(&self) -> Result { - match self.args.flag_allow_ips.as_str() { - "all" => Ok(AllowIP::All), - "public" => Ok(AllowIP::Public), - "private" => Ok(AllowIP::Private), - _ => Err("Invalid IP filter value".to_owned()), + fn ip_filter(&self) -> Result { + match IpFilter::parse(self.args.flag_allow_ips.as_str()) { + Ok(allow_ip) => Ok(allow_ip), + Err(_) => Err("Invalid IP filter value".to_owned()), } } @@ -712,7 +711,7 @@ impl Configuration { ret.max_peers = self.max_peers(); ret.min_peers = self.min_peers(); ret.snapshot_peers = self.snapshot_peers(); - ret.allow_ips = self.allow_ips()?; + ret.ip_filter = self.ip_filter()?; ret.max_pending_peers = self.max_pending_peers(); let mut net_path = PathBuf::from(self.directories().base); net_path.push("network"); @@ -968,7 +967,6 @@ impl Configuration { }.into() } - fn ui_interface(&self) -> String { self.interface(&self.args.flag_ui_interface) } @@ -1080,6 +1078,7 @@ impl Configuration { mod tests { use std::io::Write; use std::fs::{File, create_dir}; + use std::str::FromStr; use devtools::{RandomTempPath}; use ethcore::client::{VMType, BlockId}; @@ -1097,6 +1096,11 @@ mod tests { use rpc::{WsConfiguration, UiConfiguration}; use run::RunCmd; + use network::{AllowIP, IpFilter}; + + extern crate ipnetwork; + use self::ipnetwork::IpNetwork; + use super::*; #[derive(Debug, PartialEq)] @@ -1752,4 +1756,50 @@ mod tests { assert_eq!(&conf0.ipfs_config().interface, "0.0.0.0"); assert_eq!(conf0.ipfs_config().hosts, None); } + + #[test] + fn allow_ips() { + let all = parse(&["parity", "--allow-ips", "all"]); + let private = parse(&["parity", "--allow-ips", "private"]); + let block_custom = parse(&["parity", "--allow-ips", "-10.0.0.0/8"]); + let combo = parse(&["parity", "--allow-ips", "public 10.0.0.0/8 -1.0.0.0/8"]); + let ipv6_custom_public = parse(&["parity", "--allow-ips", "public fc00::/7"]); + let ipv6_custom_private = parse(&["parity", "--allow-ips", "private -fc00::/7"]); + + assert_eq!(all.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![], + }); + + assert_eq!(private.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Private, + custom_allow: vec![], + custom_block: vec![], + }); + + assert_eq!(block_custom.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()], + }); + + assert_eq!(combo.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Public, + custom_allow: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()], + custom_block: vec![IpNetwork::from_str("1.0.0.0/8").unwrap()], + }); + + assert_eq!(ipv6_custom_public.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Public, + custom_allow: vec![IpNetwork::from_str("fc00::/7").unwrap()], + custom_block: vec![], + }); + + assert_eq!(ipv6_custom_private.ip_filter().unwrap(), IpFilter { + predefined: AllowIP::Private, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str("fc00::/7").unwrap()], + }); + } } diff --git a/parity/helpers.rs b/parity/helpers.rs index 7d28f44fd..2a1b3156d 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -191,7 +191,8 @@ pub fn to_bootnodes(bootnodes: &Option) -> Result, String> { #[cfg(test)] pub fn default_network_config() -> ::ethsync::NetworkConfiguration { - use ethsync::{NetworkConfiguration, AllowIP}; + use ethsync::{NetworkConfiguration}; + use super::network::IpFilter; NetworkConfiguration { config_path: Some(replace_home(&::dir::default_data_path(), "$BASE/network")), net_config_path: None, @@ -206,7 +207,7 @@ pub fn default_network_config() -> ::ethsync::NetworkConfiguration { min_peers: 25, snapshot_peers: 0, max_pending_peers: 64, - allow_ips: AllowIP::All, + ip_filter: IpFilter::default(), reserved_nodes: Vec::new(), allow_non_reserved: true, } diff --git a/parity/main.rs b/parity/main.rs index 8bd6bf53f..311ce8b35 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -55,6 +55,7 @@ extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_light as light; extern crate ethcore_logger; extern crate ethcore_util as util; +extern crate ethcore_network as network; extern crate ethkey; extern crate ethsync; extern crate panic_hook; diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 8e9a2a3eb..b9a411879 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -31,6 +31,7 @@ ethcore-ipc-nano = { path = "../ipc/nano" } ethcore-devtools = { path = "../devtools" } ethkey = { path = "../ethkey" } parking_lot = "0.4" +ipnetwork = "0.12.6" [features] default = [] diff --git a/sync/src/api.rs b/sync/src/api.rs index b8f495f9b..acbc26867 100644 --- a/sync/src/api.rs +++ b/sync/src/api.rs @@ -19,8 +19,7 @@ use std::collections::{HashMap, BTreeMap}; use std::io; use util::Bytes; use network::{NetworkProtocolHandler, NetworkService, NetworkContext, HostInfo, PeerId, ProtocolId, - NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError, - AllowIP as NetworkAllowIP}; + NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError}; use util::{U256, H256, H512}; use io::{TimerToken}; use ethcore::ethstore::ethkey::Secret; @@ -37,6 +36,7 @@ use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT}; use light::client::AsLightClient; use light::Provider; use light::net::{self as light_net, LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext}; +use network::IpFilter; /// Parity sync protocol pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par"; @@ -539,30 +539,6 @@ impl ManageNetwork for EthSync { } } -/// IP fiter -#[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] -pub enum AllowIP { - /// Connect to any address - All, - /// Connect to private network only - Private, - /// Connect to public network only - Public, -} - -impl AllowIP { - /// Attempt to parse the peer mode from a string. - pub fn parse(s: &str) -> Option { - match s { - "all" => Some(AllowIP::All), - "private" => Some(AllowIP::Private), - "public" => Some(AllowIP::Public), - _ => None, - } - } -} - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "ipc", binary)] /// Network service configuration @@ -598,7 +574,7 @@ pub struct NetworkConfiguration { /// The non-reserved peer mode. pub allow_non_reserved: bool, /// IP Filtering - pub allow_ips: AllowIP, + pub ip_filter: IpFilter, } impl NetworkConfiguration { @@ -629,11 +605,7 @@ impl NetworkConfiguration { max_handshakes: self.max_pending_peers, reserved_protocols: hash_map![WARP_SYNC_PROTOCOL_ID => self.snapshot_peers], reserved_nodes: self.reserved_nodes, - allow_ips: match self.allow_ips { - AllowIP::All => NetworkAllowIP::All, - AllowIP::Private => NetworkAllowIP::Private, - AllowIP::Public => NetworkAllowIP::Public, - }, + ip_filter: self.ip_filter, non_reserved_mode: if self.allow_non_reserved { NonReservedPeerMode::Accept } else { NonReservedPeerMode::Deny }, }) } @@ -656,11 +628,7 @@ impl From for NetworkConfiguration { max_pending_peers: other.max_handshakes, snapshot_peers: *other.reserved_protocols.get(&WARP_SYNC_PROTOCOL_ID).unwrap_or(&0), reserved_nodes: other.reserved_nodes, - allow_ips: match other.allow_ips { - NetworkAllowIP::All => AllowIP::All, - NetworkAllowIP::Private => AllowIP::Private, - NetworkAllowIP::Public => AllowIP::Public, - }, + ip_filter: other.ip_filter, allow_non_reserved: match other.non_reserved_mode { NonReservedPeerMode::Accept => true, _ => false } , } } diff --git a/sync/src/lib.rs b/sync/src/lib.rs index b51c157be..e131bf901 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -37,6 +37,7 @@ extern crate semver; extern crate parking_lot; extern crate smallvec; extern crate rlp; +extern crate ipnetwork; extern crate ethcore_light as light; diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml index 8abda59c5..7c44aff7f 100644 --- a/util/network/Cargo.toml +++ b/util/network/Cargo.toml @@ -30,6 +30,7 @@ ethcrypto = { path = "../../ethcrypto" } rlp = { path = "../rlp" } path = { path = "../path" } ethcore-logger = { path ="../../logger" } +ipnetwork = "0.12.6" [features] default = [] diff --git a/util/network/src/discovery.rs b/util/network/src/discovery.rs index 138ba23ba..3dcd8548d 100644 --- a/util/network/src/discovery.rs +++ b/util/network/src/discovery.rs @@ -30,7 +30,7 @@ use node_table::*; use error::NetworkError; use io::{StreamToken, IoContext}; use ethkey::{Secret, KeyPair, sign, recover}; -use AllowIP; +use IpFilter; use PROTOCOL_VERSION; @@ -99,7 +99,7 @@ pub struct Discovery { send_queue: VecDeque, check_timestamps: bool, adding_nodes: Vec, - allow_ips: AllowIP, + ip_filter: IpFilter, } pub struct TableUpdates { @@ -108,7 +108,7 @@ pub struct TableUpdates { } impl Discovery { - pub fn new(key: &KeyPair, listen: SocketAddr, public: NodeEndpoint, token: StreamToken, allow_ips: AllowIP) -> Discovery { + pub fn new(key: &KeyPair, listen: SocketAddr, public: NodeEndpoint, token: StreamToken, ip_filter: IpFilter) -> Discovery { let socket = UdpSocket::bind(&listen).expect("Error binding UDP socket"); Discovery { id: key.public().clone(), @@ -124,7 +124,7 @@ impl Discovery { send_queue: VecDeque::new(), check_timestamps: true, adding_nodes: Vec::new(), - allow_ips: allow_ips, + ip_filter: ip_filter, } } @@ -400,7 +400,7 @@ impl Discovery { } fn is_allowed(&self, entry: &NodeEntry) -> bool { - entry.endpoint.is_allowed(self.allow_ips) && entry.id != self.id + entry.endpoint.is_allowed(&self.ip_filter) && entry.id != self.id } fn on_ping(&mut self, rlp: &UntrustedRlp, node: &NodeId, from: &SocketAddr) -> Result, NetworkError> { @@ -561,7 +561,6 @@ mod tests { use std::str::FromStr; use rustc_hex::FromHex; use ethkey::{Random, Generator}; - use AllowIP; #[test] fn find_node() { @@ -586,8 +585,8 @@ mod tests { let key2 = Random.generate().unwrap(); let ep1 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40444").unwrap(), udp_port: 40444 }; let ep2 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40445").unwrap(), udp_port: 40445 }; - let mut discovery1 = Discovery::new(&key1, ep1.address.clone(), ep1.clone(), 0, AllowIP::All); - let mut discovery2 = Discovery::new(&key2, ep2.address.clone(), ep2.clone(), 0, AllowIP::All); + let mut discovery1 = Discovery::new(&key1, ep1.address.clone(), ep1.clone(), 0, IpFilter::default()); + let mut discovery2 = Discovery::new(&key2, ep2.address.clone(), ep2.clone(), 0, IpFilter::default()); let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@127.0.0.1:7770").unwrap(); let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@127.0.0.1:7771").unwrap(); @@ -619,7 +618,7 @@ mod tests { fn removes_expired() { let key = Random.generate().unwrap(); let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40446").unwrap(), udp_port: 40447 }; - let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, AllowIP::All); + let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, IpFilter::default()); for _ in 0..1200 { discovery.add_node(NodeEntry { id: NodeId::random(), endpoint: ep.clone() }); } @@ -648,7 +647,7 @@ mod tests { fn packets() { let key = Random.generate().unwrap(); let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40447").unwrap(), udp_port: 40447 }; - let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, AllowIP::All); + let mut discovery = Discovery::new(&key, ep.address.clone(), ep.clone(), 0, IpFilter::default()); discovery.check_timestamps = false; let from = SocketAddr::from_str("99.99.99.99:40445").unwrap(); diff --git a/util/network/src/host.rs b/util/network/src/host.rs index b0de67499..8aea9184f 100644 --- a/util/network/src/host.rs +++ b/util/network/src/host.rs @@ -35,7 +35,7 @@ use rlp::*; use session::{Session, SessionInfo, SessionData}; use error::*; use io::*; -use {NetworkProtocolHandler, NonReservedPeerMode, AllowIP, PROTOCOL_VERSION}; +use {NetworkProtocolHandler, NonReservedPeerMode, PROTOCOL_VERSION, IpFilter}; use node_table::*; use stats::NetworkStats; use discovery::{Discovery, TableUpdates, NodeEntry}; @@ -106,7 +106,7 @@ pub struct NetworkConfiguration { /// The non-reserved peer mode. pub non_reserved_mode: NonReservedPeerMode, /// IP filter - pub allow_ips: AllowIP, + pub ip_filter: IpFilter, } impl Default for NetworkConfiguration { @@ -132,7 +132,7 @@ impl NetworkConfiguration { max_peers: 50, max_handshakes: 64, reserved_protocols: HashMap::new(), - allow_ips: AllowIP::All, + ip_filter: IpFilter::default(), reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, } @@ -566,7 +566,7 @@ impl Host { } let local_endpoint = self.info.read().local_endpoint.clone(); let public_address = self.info.read().config.public_address.clone(); - let allow_ips = self.info.read().config.allow_ips; + let allow_ips = self.info.read().config.ip_filter.clone(); let public_endpoint = match public_address { None => { let public_address = select_public_address(local_endpoint.address.port()); @@ -660,7 +660,7 @@ impl Host { } let config = &info.config; - (config.min_peers, config.non_reserved_mode == NonReservedPeerMode::Deny, config.max_handshakes as usize, config.allow_ips, info.id().clone()) + (config.min_peers, config.non_reserved_mode == NonReservedPeerMode::Deny, config.max_handshakes as usize, config.ip_filter.clone(), info.id().clone()) }; let session_count = self.session_count(); diff --git a/util/network/src/ip_utils.rs b/util/network/src/ip_utils.rs index a98cf1f88..d637dbee8 100644 --- a/util/network/src/ip_utils.rs +++ b/util/network/src/ip_utils.rs @@ -21,55 +21,193 @@ use std::io; use igd::{PortMappingProtocol, search_gateway_from_timeout}; use std::time::Duration; use node_table::{NodeEndpoint}; +use ipnetwork::{IpNetwork}; /// Socket address extension for rustc beta. To be replaces with now unstable API pub trait SocketAddrExt { - /// Returns true for the special 'unspecified' address 0.0.0.0. - fn is_unspecified_s(&self) -> bool; /// Returns true if the address appears to be globally routable. fn is_global_s(&self) -> bool; + + // Ipv4 specific + fn is_shared_space(&self) -> bool { false } + fn is_special_purpose(&self) -> bool { false } + fn is_benchmarking(&self) -> bool { false } + fn is_future_use(&self) -> bool { false } + + // Ipv6 specific + fn is_unique_local_s(&self) -> bool { false } + fn is_unicast_link_local_s(&self) -> bool { false } + fn is_documentation_s(&self) -> bool { false } + fn is_global_multicast(&self) -> bool { false } + fn is_other_multicast(&self) -> bool { false } + + fn is_reserved(&self) -> bool; + fn is_usable_public(&self) -> bool; + fn is_usable_private(&self) -> bool; + + fn is_within(&self, ipnet: &IpNetwork) -> bool; } impl SocketAddrExt for Ipv4Addr { - fn is_unspecified_s(&self) -> bool { - self.octets() == [0, 0, 0, 0] + fn is_global_s(&self) -> bool { + !self.is_private() && + !self.is_loopback() && + !self.is_link_local() && + !self.is_broadcast() && + !self.is_documentation() } - fn is_global_s(&self) -> bool { - !self.is_private() && !self.is_loopback() && !self.is_link_local() && - !self.is_broadcast() && !self.is_documentation() + // Used for communications between a service provider and its subscribers when using a carrier-grade NAT + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_shared_space(&self) -> bool { + *self >= Ipv4Addr::new(100, 64, 0, 0) && + *self <= Ipv4Addr::new(100, 127, 255, 255) + } + + // Used for the IANA IPv4 Special Purpose Address Registry + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_special_purpose(&self) -> bool { + *self >= Ipv4Addr::new(192, 0, 0, 0) && + *self <= Ipv4Addr::new(192, 0, 0, 255) + } + + // Used for testing of inter-network communications between two separate subnets + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_benchmarking(&self) -> bool { + *self >= Ipv4Addr::new(198, 18, 0, 0) && + *self <= Ipv4Addr::new(198, 19, 255, 255) + } + + // Reserved for future use + // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses + fn is_future_use(&self) -> bool { + *self >= Ipv4Addr::new(240, 0, 0, 0) && + *self <= Ipv4Addr::new(255, 255, 255, 254) + } + + fn is_reserved(&self) -> bool { + self.is_unspecified() || + self.is_loopback() || + self.is_link_local() || + self.is_broadcast() || + self.is_documentation() || + self.is_multicast() || + self.is_shared_space() || + self.is_special_purpose() || + self.is_benchmarking() || + self.is_future_use() + } + + fn is_usable_public(&self) -> bool { + !self.is_reserved() && + !self.is_private() + } + + fn is_usable_private(&self) -> bool { + self.is_private() + } + + fn is_within(&self, ipnet: &IpNetwork) -> bool { + match ipnet { + &IpNetwork::V4(ipnet) => ipnet.contains(*self), + _ => false + } } } impl SocketAddrExt for Ipv6Addr { - fn is_unspecified_s(&self) -> bool { - self.segments() == [0, 0, 0, 0, 0, 0, 0, 0] + fn is_global_s(&self) -> bool { + self.is_global_multicast() || + (!self.is_loopback() && + !self.is_unique_local_s() && + !self.is_unicast_link_local_s() && + !self.is_documentation_s() && + !self.is_other_multicast()) } - fn is_global_s(&self) -> bool { - if self.is_multicast() { - self.segments()[0] & 0x000f == 14 - } else { - !self.is_loopback() && !((self.segments()[0] & 0xffc0) == 0xfe80) && - !((self.segments()[0] & 0xffc0) == 0xfec0) && !((self.segments()[0] & 0xfe00) == 0xfc00) + // unique local address (fc00::/7). + fn is_unique_local_s(&self) -> bool { + (self.segments()[0] & 0xfe00) == 0xfc00 + } + + // unicast and link-local (fe80::/10). + fn is_unicast_link_local_s(&self) -> bool { + (self.segments()[0] & 0xffc0) == 0xfe80 + } + + // reserved for documentation (2001:db8::/32). + fn is_documentation_s(&self) -> bool { + (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) + } + + fn is_global_multicast(&self) -> bool { + self.segments()[0] & 0x000f == 14 + } + + fn is_other_multicast(&self) -> bool { + self.is_multicast() && !self.is_global_multicast() + } + + fn is_reserved(&self) -> bool { + self.is_unspecified() || + self.is_loopback() || + self.is_unicast_link_local_s() || + self.is_documentation_s() || + self.is_other_multicast() + } + + fn is_usable_public(&self) -> bool { + !self.is_reserved() && + !self.is_unique_local_s() + } + + fn is_usable_private(&self) -> bool { + self.is_unique_local_s() + } + + fn is_within(&self, ipnet: &IpNetwork) -> bool { + match ipnet { + &IpNetwork::V6(ipnet) => ipnet.contains(*self), + _ => false } } } impl SocketAddrExt for IpAddr { - fn is_unspecified_s(&self) -> bool { - match *self { - IpAddr::V4(ref ip) => ip.is_unspecified_s(), - IpAddr::V6(ref ip) => ip.is_unspecified_s(), - } - } - fn is_global_s(&self) -> bool { match *self { IpAddr::V4(ref ip) => ip.is_global_s(), IpAddr::V6(ref ip) => ip.is_global_s(), } } + + fn is_reserved(&self) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_reserved(), + IpAddr::V6(ref ip) => ip.is_reserved(), + } + } + + fn is_usable_public(&self) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_usable_public(), + IpAddr::V6(ref ip) => ip.is_usable_public(), + } + } + + fn is_usable_private(&self) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_usable_private(), + IpAddr::V6(ref ip) => ip.is_usable_private(), + } + } + + fn is_within(&self, ipnet: &IpNetwork) -> bool { + match *self { + IpAddr::V4(ref ip) => ip.is_within(ipnet), + IpAddr::V6(ref ip) => ip.is_within(ipnet) + } + } } #[cfg(not(windows))] @@ -79,7 +217,7 @@ mod getinterfaces { use libc::{getifaddrs, freeifaddrs, ifaddrs, sockaddr, sockaddr_in, sockaddr_in6}; use std::net::{Ipv4Addr, Ipv6Addr, IpAddr}; - fn convert_sockaddr (sa: *mut sockaddr) -> Option { + fn convert_sockaddr(sa: *mut sockaddr) -> Option { if sa == ptr::null_mut() { return None; } let (addr, _) = match unsafe { *sa }.sa_family as i32 { @@ -115,7 +253,7 @@ mod getinterfaces { Some(addr) } - fn convert_ifaddrs (ifa: *mut ifaddrs) -> Option { + fn convert_ifaddrs(ifa: *mut ifaddrs) -> Option { let ifa = unsafe { &mut *ifa }; convert_sockaddr(ifa.ifa_addr) } @@ -158,16 +296,16 @@ pub fn select_public_address(port: u16) -> SocketAddr { Ok(list) => { //prefer IPV4 bindings for addr in &list { //TODO: use better criteria than just the first in the list - match *addr { - IpAddr::V4(a) if !a.is_unspecified_s() && !a.is_loopback() && !a.is_link_local() => { + match addr { + &IpAddr::V4(a) if !a.is_reserved() => { return SocketAddr::V4(SocketAddrV4::new(a, port)); }, _ => {}, } } - for addr in list { + for addr in &list { match addr { - IpAddr::V6(a) if !a.is_unspecified_s() && !a.is_loopback() => { + &IpAddr::V6(a) if !a.is_reserved() => { return SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)); }, _ => {}, @@ -227,7 +365,6 @@ fn can_map_external_address_or_fail() { #[test] fn ipv4_properties() { - #![cfg_attr(feature="dev", allow(too_many_arguments))] fn check(octets: &[u8; 4], unspec: bool, loopback: bool, private: bool, link_local: bool, global: bool, @@ -235,7 +372,7 @@ fn ipv4_properties() { let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]); assert_eq!(octets, &ip.octets()); - assert_eq!(ip.is_unspecified_s(), unspec); + assert_eq!(ip.is_unspecified(), unspec); assert_eq!(ip.is_loopback(), loopback); assert_eq!(ip.is_private(), private); assert_eq!(ip.is_link_local(), link_local); @@ -264,13 +401,131 @@ fn ipv4_properties() { check(&[255, 255, 255, 255], false, false, false, false, false, false, true, false); } +#[test] +fn ipv4_shared_space() { + assert!(!Ipv4Addr::new(100, 63, 255, 255).is_shared_space()); + assert!(Ipv4Addr::new(100, 64, 0, 0).is_shared_space()); + assert!(Ipv4Addr::new(100, 127, 255, 255).is_shared_space()); + assert!(!Ipv4Addr::new(100, 128, 0, 0).is_shared_space()); +} + +#[test] +fn ipv4_special_purpose() { + assert!(!Ipv4Addr::new(191, 255, 255, 255).is_special_purpose()); + assert!(Ipv4Addr::new(192, 0, 0, 0).is_special_purpose()); + assert!(Ipv4Addr::new(192, 0, 0, 255).is_special_purpose()); + assert!(!Ipv4Addr::new(192, 0, 1, 255).is_special_purpose()); +} + +#[test] +fn ipv4_benchmarking() { + assert!(!Ipv4Addr::new(198, 17, 255, 255).is_benchmarking()); + assert!(Ipv4Addr::new(198, 18, 0, 0).is_benchmarking()); + assert!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking()); + assert!(!Ipv4Addr::new(198, 20, 0, 0).is_benchmarking()); +} + +#[test] +fn ipv4_future_use() { + assert!(!Ipv4Addr::new(239, 255, 255, 255).is_future_use()); + assert!(Ipv4Addr::new(240, 0, 0, 0).is_future_use()); + assert!(Ipv4Addr::new(255, 255, 255, 254).is_future_use()); + assert!(!Ipv4Addr::new(255, 255, 255, 255).is_future_use()); +} + +#[test] +fn ipv4_usable_public() { + assert!(!Ipv4Addr::new(0,0,0,0).is_usable_public()); // unspecified + assert!(Ipv4Addr::new(0,0,0,1).is_usable_public()); + + assert!(Ipv4Addr::new(9,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(10,0,0,0).is_usable_public()); // private intra-network + assert!(!Ipv4Addr::new(10,255,255,255).is_usable_public()); // private intra-network + assert!(Ipv4Addr::new(11,0,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(100, 63, 255, 255).is_usable_public()); + assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space + assert!(!Ipv4Addr::new(100, 127, 255, 255).is_usable_public()); // shared space + assert!(Ipv4Addr::new(100, 128, 0, 0).is_usable_public()); + + assert!(Ipv4Addr::new(126,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(127,0,0,0).is_usable_public()); // loopback + assert!(!Ipv4Addr::new(127,255,255,255).is_usable_public()); // loopback + assert!(Ipv4Addr::new(128,0,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(169,253,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(169,254,0,0).is_usable_public()); // link-local + assert!(!Ipv4Addr::new(169,254,255,255).is_usable_public()); // link-local + assert!(Ipv4Addr::new(169,255,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(172,15,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(172,16,0,0).is_usable_public()); // private intra-network + assert!(!Ipv4Addr::new(172,31,255,255).is_usable_public()); // private intra-network + assert!(Ipv4Addr::new(172,32,255,255).is_usable_public()); + + assert!(Ipv4Addr::new(191,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(192,0,0,0).is_usable_public()); // special purpose + assert!(!Ipv4Addr::new(192,0,0,255).is_usable_public()); // special purpose + assert!(Ipv4Addr::new(192,0,1,0).is_usable_public()); + + assert!(Ipv4Addr::new(192,0,1,255).is_usable_public()); + assert!(!Ipv4Addr::new(192,0,2,0).is_usable_public()); // documentation + assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation + assert!(Ipv4Addr::new(192,0,3,0).is_usable_public()); + + assert!(Ipv4Addr::new(192,167,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(192,168,0,0).is_usable_public()); // private intra-network + assert!(!Ipv4Addr::new(192,168,255,255).is_usable_public()); // private intra-network + assert!(Ipv4Addr::new(192,169,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(198,17,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(198,18,0,0).is_usable_public()); // benchmarking + assert!(!Ipv4Addr::new(198,19,255,255).is_usable_public()); // benchmarking + assert!(Ipv4Addr::new(198,20,0,0).is_usable_public()); + + assert!(Ipv4Addr::new(198,51,99,255).is_usable_public()); + assert!(!Ipv4Addr::new(198,51,100,0).is_usable_public()); // documentation + assert!(!Ipv4Addr::new(198,51,100,255).is_usable_public()); // documentation + assert!(Ipv4Addr::new(198,51,101,0).is_usable_public()); + + assert!(Ipv4Addr::new(203,0,112,255).is_usable_public()); + assert!(!Ipv4Addr::new(203,0,113,0).is_usable_public()); // documentation + assert!(!Ipv4Addr::new(203,0,113,255).is_usable_public()); // documentation + assert!(Ipv4Addr::new(203,0,114,0).is_usable_public()); + + assert!(Ipv4Addr::new(223,255,255,255).is_usable_public()); + assert!(!Ipv4Addr::new(224,0,0,0).is_usable_public()); // multicast + assert!(!Ipv4Addr::new(239, 255, 255, 255).is_usable_public()); // multicast + assert!(!Ipv4Addr::new(240, 0, 0, 0).is_usable_public()); // future use + assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use + assert!(!Ipv4Addr::new(255, 255, 255, 255).is_usable_public()); // limited broadcast +} + +#[test] +fn ipv4_usable_private() { + assert!(!Ipv4Addr::new(9,255,255,255).is_usable_private()); + assert!(Ipv4Addr::new(10,0,0,0).is_usable_private()); // private intra-network + assert!(Ipv4Addr::new(10,255,255,255).is_usable_private()); // private intra-network + assert!(!Ipv4Addr::new(11,0,0,0).is_usable_private()); + + assert!(!Ipv4Addr::new(172,15,255,255).is_usable_private()); + assert!(Ipv4Addr::new(172,16,0,0).is_usable_private()); // private intra-network + assert!(Ipv4Addr::new(172,31,255,255).is_usable_private()); // private intra-network + assert!(!Ipv4Addr::new(172,32,255,255).is_usable_private()); + + assert!(!Ipv4Addr::new(192,167,255,255).is_usable_private()); + assert!(Ipv4Addr::new(192,168,0,0).is_usable_private()); // private intra-network + assert!(Ipv4Addr::new(192,168,255,255).is_usable_private()); // private intra-network + assert!(!Ipv4Addr::new(192,169,0,0).is_usable_private()); +} + #[test] fn ipv6_properties() { fn check(str_addr: &str, unspec: bool, loopback: bool, global: bool) { let ip: Ipv6Addr = str_addr.parse().unwrap(); assert_eq!(str_addr, ip.to_string()); - assert_eq!(ip.is_unspecified_s(), unspec); + assert_eq!(ip.is_unspecified(), unspec); assert_eq!(ip.is_loopback(), loopback); assert_eq!(ip.is_global_s(), global); } @@ -279,3 +534,5 @@ fn ipv6_properties() { check("::", true, false, true); check("::1", false, true, false); } + + diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 5a3fdc1e6..74e30a750 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -77,6 +77,7 @@ extern crate rlp; extern crate bytes; extern crate path; extern crate ethcore_logger; +extern crate ipnetwork; #[macro_use] extern crate log; @@ -106,6 +107,8 @@ pub use session::SessionInfo; pub use io::TimerToken; pub use node_table::{is_valid_node_url, NodeId}; +use ipnetwork::{IpNetwork, IpNetworkError}; +use std::str::FromStr; const PROTOCOL_VERSION: u32 = 4; @@ -145,8 +148,49 @@ impl NonReservedPeerMode { } } +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", binary)] +pub struct IpFilter { + pub predefined: AllowIP, + pub custom_allow: Vec, + pub custom_block: Vec, +} + +impl Default for IpFilter { + fn default() -> Self { + IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![], + } + } +} + +impl IpFilter { + /// Attempt to parse the peer mode from a string. + pub fn parse(s: &str) -> Result { + let mut filter = IpFilter::default(); + for f in s.split_whitespace() { + match f { + "all" => filter.predefined = AllowIP::All, + "private" => filter.predefined = AllowIP::Private, + "public" => filter.predefined = AllowIP::Public, + "none" => filter.predefined = AllowIP::None, + custom => { + if custom.starts_with("-") { + filter.custom_block.push(IpNetwork::from_str(&custom.to_owned().split_off(1))?) + } else { + filter.custom_allow.push(IpNetwork::from_str(custom)?) + } + } + } + } + Ok(filter) + } +} + /// IP fiter -#[derive(Clone, Debug, PartialEq, Eq, Copy)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum AllowIP { /// Connect to any address All, @@ -154,5 +198,7 @@ pub enum AllowIP { Private, /// Connect to public network only Public, + /// Block all addresses + None, } diff --git a/util/network/src/node_table.rs b/util/network/src/node_table.rs index 1481187d4..f9d4e9589 100644 --- a/util/network/src/node_table.rs +++ b/util/network/src/node_table.rs @@ -30,7 +30,7 @@ use util::UtilError; use rlp::*; use time::Tm; use error::NetworkError; -use AllowIP; +use {AllowIP, IpFilter}; use discovery::{TableUpdates, NodeEntry}; use ip_utils::*; pub use rustc_serialize::json::Json; @@ -55,11 +55,21 @@ impl NodeEndpoint { } } - pub fn is_allowed(&self, filter: AllowIP) -> bool { + pub fn is_allowed(&self, filter: &IpFilter) -> bool { + (self.is_allowed_by_predefined(&filter.predefined) || filter.custom_allow.iter().any(|ipnet| { + self.address.ip().is_within(ipnet) + })) + && !filter.custom_block.iter().any(|ipnet| { + self.address.ip().is_within(ipnet) + }) + } + + pub fn is_allowed_by_predefined(&self, filter: &AllowIP) -> bool { match filter { - AllowIP::All => true, - AllowIP::Private => !self.address.ip().is_global_s(), - AllowIP::Public => self.address.ip().is_global_s(), + &AllowIP::All => true, + &AllowIP::Private => self.address.ip().is_usable_private(), + &AllowIP::Public => self.address.ip().is_usable_public(), + &AllowIP::None => false, } } @@ -101,8 +111,8 @@ impl NodeEndpoint { pub fn is_valid(&self) -> bool { self.udp_port != 0 && self.address.port() != 0 && match self.address { - SocketAddr::V4(a) => !a.ip().is_unspecified_s(), - SocketAddr::V6(a) => !a.ip().is_unspecified_s() + SocketAddr::V4(a) => !a.ip().is_unspecified(), + SocketAddr::V6(a) => !a.ip().is_unspecified() } } } @@ -219,8 +229,8 @@ impl NodeTable { } /// Returns node ids sorted by number of failures - pub fn nodes(&self, filter: AllowIP) -> Vec { - let mut refs: Vec<&Node> = self.nodes.values().filter(|n| !self.useless_nodes.contains(&n.id) && n.endpoint.is_allowed(filter)).collect(); + pub fn nodes(&self, filter: IpFilter) -> Vec { + let mut refs: Vec<&Node> = self.nodes.values().filter(|n| !self.useless_nodes.contains(&n.id) && n.endpoint.is_allowed(&filter)).collect(); refs.sort_by(|a, b| a.failures.cmp(&b.failures)); refs.iter().map(|n| n.id.clone()).collect() } @@ -283,7 +293,7 @@ impl NodeTable { let mut json = String::new(); json.push_str("{\n"); json.push_str("\"nodes\": [\n"); - let node_ids = self.nodes(AllowIP::All); + let node_ids = self.nodes(IpFilter::default()); for i in 0 .. node_ids.len() { let node = self.nodes.get(&node_ids[i]).expect("self.nodes() only returns node IDs from self.nodes"); json.push_str(&format!("\t{{ \"url\": \"{}\", \"failures\": {} }}{}\n", node, node.failures, if i == node_ids.len() - 1 {""} else {","})) @@ -366,7 +376,7 @@ mod tests { use util::H512; use std::str::FromStr; use devtools::*; - use AllowIP; + use ipnetwork::IpNetwork; #[test] fn endpoint_parse() { @@ -412,7 +422,7 @@ mod tests { table.note_failure(&id1); table.note_failure(&id2); - let r = table.nodes(AllowIP::All); + let r = table.nodes(IpFilter::default()); assert_eq!(r[0][..], id3[..]); assert_eq!(r[1][..], id2[..]); assert_eq!(r[2][..], id1[..]); @@ -434,9 +444,55 @@ mod tests { { let table = NodeTable::new(Some(temp_path.as_path().to_str().unwrap().to_owned())); - let r = table.nodes(AllowIP::All); + let r = table.nodes(IpFilter::default()); assert_eq!(r[0][..], id1[..]); assert_eq!(r[1][..], id2[..]); } } + + #[test] + fn custom_allow() { + let filter = IpFilter { + predefined: AllowIP::None, + custom_allow: vec![IpNetwork::from_str(&"10.0.0.0/8").unwrap(), IpNetwork::from_str(&"1.0.0.0/8").unwrap()], + custom_block: vec![], + }; + assert!(!NodeEndpoint::from_str("123.99.55.44:7770").unwrap().is_allowed(&filter)); + assert!(NodeEndpoint::from_str("10.0.0.1:7770").unwrap().is_allowed(&filter)); + assert!(NodeEndpoint::from_str("1.0.0.55:5550").unwrap().is_allowed(&filter)); + } + + #[test] + fn custom_block() { + let filter = IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str(&"10.0.0.0/8").unwrap(), IpNetwork::from_str(&"1.0.0.0/8").unwrap()], + }; + assert!(NodeEndpoint::from_str("123.99.55.44:7770").unwrap().is_allowed(&filter)); + assert!(!NodeEndpoint::from_str("10.0.0.1:7770").unwrap().is_allowed(&filter)); + assert!(!NodeEndpoint::from_str("1.0.0.55:5550").unwrap().is_allowed(&filter)); + } + + #[test] + fn custom_allow_ipv6() { + let filter = IpFilter { + predefined: AllowIP::None, + custom_allow: vec![IpNetwork::from_str(&"fc00::/8").unwrap()], + custom_block: vec![], + }; + assert!(NodeEndpoint::from_str("[fc00::]:5550").unwrap().is_allowed(&filter)); + assert!(!NodeEndpoint::from_str("[fd00::]:5550").unwrap().is_allowed(&filter)); + } + + #[test] + fn custom_block_ipv6() { + let filter = IpFilter { + predefined: AllowIP::All, + custom_allow: vec![], + custom_block: vec![IpNetwork::from_str(&"fc00::/8").unwrap()], + }; + assert!(!NodeEndpoint::from_str("[fc00::]:5550").unwrap().is_allowed(&filter)); + assert!(NodeEndpoint::from_str("[fd00::]:5550").unwrap().is_allowed(&filter)); + } } From f212ae6322ce7e6742f3df02de46414b9fb88cc9 Mon Sep 17 00:00:00 2001 From: Nicolas Ochem Date: Fri, 28 Jul 2017 10:07:38 -0700 Subject: [PATCH 034/119] fix #6052. honor --no-color for signer command (#6100) * fix #6052. honor --no-color for signer command * replace call to paint closure with the body, apply to generate_new_token too --- parity/configuration.rs | 10 +++++++--- parity/main.rs | 2 +- parity/run.rs | 12 ++++++------ parity/signer.rs | 30 +++++++++++++++++++----------- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index f1399e47c..d05f26f53 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -57,7 +57,7 @@ pub enum Cmd { Account(AccountCmd), ImportPresaleWallet(ImportWallet), Blockchain(BlockchainCmd), - SignerToken(WsConfiguration, UiConfiguration), + SignerToken(WsConfiguration, UiConfiguration, LogConfig), SignerSign { id: Option, pwfile: Option, @@ -149,7 +149,7 @@ impl Configuration { let authfile = ::signer::codes_path(&ws_conf.signer_path); if self.args.cmd_new_token { - Cmd::SignerToken(ws_conf, ui_conf) + Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone()) } else if self.args.cmd_sign { let pwfile = self.args.flag_password.get(0).map(|pwfile| { PathBuf::from(pwfile) @@ -1285,7 +1285,11 @@ mod tests { interface: "127.0.0.1".into(), port: 8180, hosts: Some(vec![]), - })); + }, LogConfig { + color: true, + mode: None, + file: None, + } )); } #[test] diff --git a/parity/main.rs b/parity/main.rs index 311ce8b35..48e752bf2 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -164,7 +164,7 @@ fn execute(command: Execute, can_restart: bool) -> Result account::execute(account_cmd).map(|s| PostExecutionAction::Print(s)), Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd).map(|s| PostExecutionAction::Print(s)), Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd).map(|_| PostExecutionAction::Quit), - Cmd::SignerToken(ws_conf, ui_conf) => signer::execute(ws_conf, ui_conf).map(|s| PostExecutionAction::Print(s)), + Cmd::SignerToken(ws_conf, ui_conf, logger_config) => signer::execute(ws_conf, ui_conf, logger_config).map(|s| PostExecutionAction::Print(s)), Cmd::SignerSign { id, pwfile, port, authfile } => rpc_cli::signer_sign(id, pwfile, port, authfile).map(|s| PostExecutionAction::Print(s)), Cmd::SignerList { port, authfile } => rpc_cli::signer_list(port, authfile).map(|s| PostExecutionAction::Print(s)), Cmd::SignerReject { id, port, authfile } => rpc_cli::signer_reject(id, port, authfile).map(|s| PostExecutionAction::Print(s)), diff --git a/parity/run.rs b/parity/run.rs index 7c835aa3f..c08294a42 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -118,12 +118,12 @@ pub struct RunCmd { pub whisper: ::whisper::Config } -pub fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> Result<(), String> { +pub fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result<(), String> { if !ui_conf.enabled { return Err("Cannot use UI command with UI turned off.".into()) } - let token = signer::generate_token_and_url(ws_conf, ui_conf)?; + let token = signer::generate_token_and_url(ws_conf, ui_conf, logger_config)?; // Open a browser url::open(&token.url); // Print a message @@ -282,7 +282,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc) -> let rpc_stats = Arc::new(informant::RpcStats::default()); // the dapps server - let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf)); + let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)); let dapps_deps = { let contract_client = Arc::new(::dapps::LightRegistrar { client: service.client().clone(), @@ -378,7 +378,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // Check if Parity is already running let addr = format!("{}:{}", cmd.ui_conf.interface, cmd.ui_conf.port); if !TcpListener::bind(&addr as &str).is_ok() { - return open_ui(&cmd.ws_conf, &cmd.ui_conf).map(|_| (false, None)); + return open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config).map(|_| (false, None)); } } @@ -658,7 +658,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R false => Some(account_provider.clone()) }; - let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf)); + let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)); // the dapps server let dapps_deps = { @@ -791,7 +791,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // start ui if cmd.ui { - open_ui(&cmd.ws_conf, &cmd.ui_conf)?; + open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)?; } if let Some(dapp) = cmd.dapp { diff --git a/parity/signer.rs b/parity/signer.rs index 7a5e90341..8bdf18bd0 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -17,13 +17,13 @@ use std::io; use std::path::{Path, PathBuf}; -use ansi_term::Colour; +use ansi_term::Colour::White; +use ethcore_logger::Config as LogConfig; use rpc; use rpc_apis; use parity_rpc; use path::restrict_permissions_owner; - pub const CODES_FILENAME: &'static str = "authcodes"; pub struct NewToken { @@ -32,12 +32,13 @@ pub struct NewToken { pub message: String, } -pub fn new_service(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> rpc_apis::SignerService { +pub fn new_service(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> rpc_apis::SignerService { let signer_path = ws_conf.signer_path.clone(); + let logger_config_color = logger_config.color; let signer_enabled = ui_conf.enabled; rpc_apis::SignerService::new(move || { - generate_new_token(&signer_path).map_err(|e| format!("{:?}", e)) + generate_new_token(&signer_path, logger_config_color).map_err(|e| format!("{:?}", e)) }, signer_enabled) } @@ -48,13 +49,14 @@ pub fn codes_path(path: &Path) -> PathBuf { p } -pub fn execute(ws_conf: rpc::WsConfiguration, ui_conf: rpc::UiConfiguration) -> Result { - Ok(generate_token_and_url(&ws_conf, &ui_conf)?.message) +pub fn execute(ws_conf: rpc::WsConfiguration, ui_conf: rpc::UiConfiguration, logger_config: LogConfig) -> Result { + Ok(generate_token_and_url(&ws_conf, &ui_conf, &logger_config)?.message) } -pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> Result { - let code = generate_new_token(&ws_conf.signer_path).map_err(|err| format!("Error generating token: {:?}", err))?; +pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result { + let code = generate_new_token(&ws_conf.signer_path, logger_config.color).map_err(|err| format!("Error generating token: {:?}", err))?; let auth_url = format!("http://{}:{}/#/auth?token={}", ui_conf.interface, ui_conf.port, code); + // And print in to the console Ok(NewToken { token: code.clone(), @@ -65,18 +67,24 @@ Open: {} to authorize your browser. Or use the generated token: {}"#, - Colour::White.bold().paint(auth_url), + match logger_config.color { + true => format!("{}", White.bold().paint(auth_url)), + false => auth_url + }, code ) }) } -fn generate_new_token(path: &Path) -> io::Result { +fn generate_new_token(path: &Path, logger_config_color: bool) -> io::Result { let path = codes_path(path); let mut codes = parity_rpc::AuthCodes::from_file(&path)?; codes.clear_garbage(); let code = codes.generate_new()?; codes.to_file(&path)?; - trace!("New key code created: {}", Colour::White.bold().paint(&code[..])); + trace!("New key code created: {}", match logger_config_color { + true => format!("{}", White.bold().paint(&code[..])), + false => format!("{}", &code[..]) + }); Ok(code) } From 9f0bfa01ca9769153b4f0c5579a7f853397e6708 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Fri, 28 Jul 2017 23:18:02 +0200 Subject: [PATCH 035/119] typo in uninstaller --- nsis/installer.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nsis/installer.nsi b/nsis/installer.nsi index 564fbfce8..7173beccc 100644 --- a/nsis/installer.nsi +++ b/nsis/installer.nsi @@ -149,7 +149,7 @@ function un.onInit SetShellVarContext all #Verify the uninstaller - last chance to back out - MessageBox MB_OKCANCEL "Permanantly remove ${APPNAME}?" IDOK next + MessageBox MB_OKCANCEL "Permanently remove ${APPNAME}?" IDOK next Abort next: From eecd823d32b3f4d88f64a6c41acec9c2b0b78994 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 17:12:07 +0200 Subject: [PATCH 036/119] util reexports less std --- Cargo.lock | 14 ++++++-- ethcore/Cargo.toml | 3 ++ ethcore/evm/src/interpreter/gasometer.rs | 3 +- ethcore/evm/src/interpreter/mod.rs | 3 +- ethcore/evm/src/tests.rs | 2 ++ ethcore/src/account_db.rs | 1 + ethcore/src/blockchain/blockchain.rs | 2 ++ ethcore/src/blockchain/extras.rs | 9 ++++-- ethcore/src/client/test_client.rs | 2 ++ ethcore/src/engines/authority_round/mod.rs | 9 ++++-- ethcore/src/engines/basic_authority.rs | 12 ++++--- ethcore/src/engines/instant_seal.rs | 4 +-- ethcore/src/engines/mod.rs | 2 ++ ethcore/src/engines/tendermint/message.rs | 5 +-- ethcore/src/engines/tendermint/mod.rs | 7 ++-- ethcore/src/engines/validator_set/contract.rs | 8 ++--- ethcore/src/engines/validator_set/multi.rs | 1 + .../engines/validator_set/safe_contract.rs | 10 +++--- ethcore/src/engines/vote_collector.rs | 1 + ethcore/src/error.rs | 1 + ethcore/src/ethereum/ethash.rs | 32 +++++++++++-------- ethcore/src/executive.rs | 6 ++-- ethcore/src/externalities.rs | 9 +++--- ethcore/src/header.rs | 8 ++--- ethcore/src/lib.rs | 3 ++ ethcore/src/miner/miner.rs | 3 +- ethcore/src/miner/transaction_queue.rs | 4 +-- ethcore/src/miner/work_notify.rs | 1 + ethcore/src/pod_account.rs | 4 ++- ethcore/src/pod_state.rs | 4 ++- ethcore/src/spec/spec.rs | 3 ++ ethcore/src/state/account.rs | 2 ++ ethcore/src/state/mod.rs | 2 ++ ethcore/src/tests/client.rs | 1 + ethcore/src/tests/helpers.rs | 3 +- ethcore/src/trace/types/filter.rs | 4 +-- ethcore/src/trace/types/trace.rs | 2 +- ethcore/src/verification/queue/mod.rs | 17 +++++----- ethcore/src/verification/verification.rs | 2 ++ ethcore/types/Cargo.toml | 1 + ethcore/types/src/filter.rs | 2 +- ethcore/types/src/lib.rs | 1 + ethcore/types/src/log_entry.rs | 6 ++-- ethkey/cli/src/main.rs | 16 +++++----- ethkey/src/secret.rs | 7 ++++ hash-fetch/src/client.rs | 3 +- ipc/hypervisor/src/lib.rs | 2 +- ipfs/src/lib.rs | 4 +-- ipfs/src/route.rs | 3 +- js/src/lib.rs.in | 2 +- rpc/src/v1/tests/helpers/miner_service.rs | 1 + stratum/src/lib.rs | 8 ++--- sync/src/block_sync.rs | 4 ++- sync/src/blocks.rs | 1 + sync/src/chain.rs | 28 ++++++++-------- sync/src/tests/helpers.rs | 1 + sync/src/tests/snapshot.rs | 1 + util/Cargo.toml | 2 -- util/bloomable/Cargo.toml | 10 ++++++ util/{src/bloom.rs => bloomable/src/lib.rs} | 32 ++----------------- util/bloomable/tests/test.rs | 31 ++++++++++++++++++ util/src/common.rs | 5 +-- util/src/journaldb/archivedb.rs | 1 + util/src/journaldb/earlymergedb.rs | 2 ++ util/src/journaldb/mod.rs | 3 +- util/src/journaldb/overlayrecentdb.rs | 1 + util/src/journaldb/refcounteddb.rs | 1 + util/src/kvdb.rs | 2 ++ util/src/lib.rs | 5 --- util/src/migration/tests.rs | 1 + util/src/misc.rs | 6 ++-- util/src/nibblevec.rs | 2 +- util/src/standard.rs | 18 ----------- util/src/trie/triedb.rs | 1 + 74 files changed, 255 insertions(+), 168 deletions(-) create mode 100644 util/bloomable/Cargo.toml rename util/{src/bloom.rs => bloomable/src/lib.rs} (70%) create mode 100644 util/bloomable/tests/test.rs diff --git a/Cargo.lock b/Cargo.lock index 359b2d2f9..2f9cb3f6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,6 +181,14 @@ name = "blastfig" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bloomable" +version = "0.1.0" +dependencies = [ + "ethcore-bigint 0.1.3", + "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bloomchain" version = "0.1.0" @@ -271,6 +279,7 @@ dependencies = [ name = "common-types" version = "0.1.0" dependencies = [ + "bloomable 0.1.0", "ethcore-util 1.8.0", "ethjson 0.1.0", "rlp 0.2.0", @@ -462,6 +471,7 @@ name = "ethcore" version = "1.8.0" dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bloomable 0.1.0", "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bn 0.4.4 (git+https://github.com/paritytech/bn)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -502,8 +512,10 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", + "table 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "using_queue 0.1.0", ] [[package]] @@ -751,11 +763,9 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.1.0", - "table 0.1.0", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "using_queue 0.1.0", "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 71e329201..7ac147cd0 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -53,6 +53,9 @@ semver = "0.6" stats = { path = "../util/stats" } time = "0.1" transient-hashmap = "0.4" +using_queue = { path = "../util/using_queue" } +table = { path = "../util/table" } +bloomable = { path = "../util/bloomable" } [dev-dependencies] native-contracts = { path = "native_contracts", features = ["test_contracts"] } diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index c2dcf5412..5f4ef80a1 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::cmp; use util::*; use super::u256_to_address; @@ -82,7 +83,7 @@ impl Gasometer { }; if let Some(Ok(r)) = requested { - Ok(min(r, max_gas_provided)) + Ok(cmp::min(r, max_gas_provided)) } else { Ok(max_gas_provided) } diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 30b431912..621febffd 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -23,12 +23,13 @@ mod stack; mod memory; mod shared_cache; +use std::marker::PhantomData; +use std::{cmp, mem}; use self::gasometer::Gasometer; use self::stack::{Stack, VecStack}; use self::memory::Memory; pub use self::shared_cache::SharedCache; -use std::marker::PhantomData; use action_params::{ActionParams, ActionValue}; use call_type::CallType; use instructions::{self, Instruction, InstructionInfo}; diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index d0502f79a..c19a575f3 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . use std::fmt::Debug; +use std::str::FromStr; +use std::collections::{HashMap, HashSet}; use rustc_hex::FromHex; use util::*; use action_params::{ActionParams, ActionValue}; diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs index 10e63dba3..5ce555aef 100644 --- a/ethcore/src/account_db.rs +++ b/ethcore/src/account_db.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! DB backend wrapper for Account trie +use std::collections::HashMap; use util::*; use rlp::NULL_RLP; diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 4412df567..59b4fb7c3 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -16,6 +16,8 @@ //! Blockchain database. +use std::collections::{HashMap, HashSet}; +use std::mem; use bloomchain as bc; use util::*; use rlp::*; diff --git a/ethcore/src/blockchain/extras.rs b/ethcore/src/blockchain/extras.rs index 04c12d53a..ed3a5009b 100644 --- a/ethcore/src/blockchain/extras.rs +++ b/ethcore/src/blockchain/extras.rs @@ -16,6 +16,8 @@ //! Blockchain DB extras. +use std::ops; +use std::io::Write; use bloomchain; use blooms::{GroupPosition, BloomGroup}; use db::Key; @@ -56,7 +58,7 @@ fn with_index(hash: &H256, i: ExtrasIndex) -> H264 { pub struct BlockNumberKey([u8; 5]); -impl Deref for BlockNumberKey { +impl ops::Deref for BlockNumberKey { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -88,7 +90,7 @@ impl Key for H256 { pub struct LogGroupKey([u8; 6]); -impl Deref for LogGroupKey { +impl ops::Deref for LogGroupKey { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -160,7 +162,8 @@ pub const EPOCH_KEY_PREFIX: &'static [u8; DB_PREFIX_LEN] = &[ ]; pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]); -impl Deref for EpochTransitionsKey { + +impl ops::Deref for EpochTransitionsKey { type Target = [u8]; fn deref(&self) -> &[u8] { &self.0[..] } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 5dfdf5c25..e33888e72 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -17,6 +17,8 @@ //! Test client. use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; +use std::collections::{HashMap, BTreeMap}; +use std::mem; use rustc_hex::FromHex; use util::*; use rlp::*; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 3210368db..a72091e5e 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -19,6 +19,8 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::Weak; use std::time::{UNIX_EPOCH, Duration}; +use std::collections::{BTreeMap, HashSet, HashMap}; +use std::cmp; use account_provider::AccountProvider; use block::*; @@ -463,9 +465,9 @@ impl Engine for AuthorityRound { let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -815,7 +817,7 @@ impl Engine for AuthorityRound { } } - fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> { t.check_low_s()?; if let Some(n) = t.network_id() { @@ -852,6 +854,7 @@ impl Engine for AuthorityRound { #[cfg(test)] mod tests { use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; + use std::str::FromStr; use util::*; use header::Header; use error::{Error, BlockError}; diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 68759131d..a3f4b9114 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -17,6 +17,8 @@ //! A blockchain engine that supports a basic, non-BFT proof-of-authority. use std::sync::Weak; +use std::collections::BTreeMap; +use std::cmp; use util::*; use ethkey::{recover, public_to_address, Signature}; use account_provider::AccountProvider; @@ -121,9 +123,9 @@ impl Engine for BasicAuthority { let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -147,7 +149,7 @@ impl Engine for BasicAuthority { Seal::None } - fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // check the seal fields. // TODO: pull this out into common code. if header.seal().len() != self.seal_fields() { @@ -158,11 +160,11 @@ impl Engine for BasicAuthority { Ok(()) } - fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) } - fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // Do not calculate difficulty for genesis blocks. if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 38834622c..4d297dc3f 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::collections::BTreeMap; -use util::{Address, HashMap}; +use std::collections::{BTreeMap, HashMap}; +use util::Address; use builtin::Builtin; use engines::{Engine, Seal}; use spec::CommonParams; diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index c5fa4818e..77b89e59c 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -36,6 +36,8 @@ pub use self::null_engine::NullEngine; pub use self::tendermint::Tendermint; use std::sync::Weak; +use std::collections::{BTreeMap, HashMap}; +use std::fmt; use self::epoch::PendingTransition; diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index b9465f429..623284839 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -16,6 +16,7 @@ //! Tendermint message handling. +use std::cmp; use util::*; use super::{Height, View, BlockHash, Step}; use error::Error; @@ -110,13 +111,13 @@ impl Default for VoteStep { } impl PartialOrd for VoteStep { - fn partial_cmp(&self, m: &VoteStep) -> Option { + fn partial_cmp(&self, m: &VoteStep) -> Option { Some(self.cmp(m)) } } impl Ord for VoteStep { - fn cmp(&self, m: &VoteStep) -> Ordering { + fn cmp(&self, m: &VoteStep) -> cmp::Ordering { if self.height != m.height { self.height.cmp(&m.height) } else if self.view != m.view { diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 453e8f9fb..5d334a610 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -27,6 +27,8 @@ mod params; use std::sync::Weak; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; +use std::collections::{HashSet, BTreeMap, HashMap}; +use std::cmp; use util::*; use client::{Client, EngineClient}; use error::{Error, BlockError}; @@ -473,9 +475,9 @@ impl Engine for Tendermint { let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -771,6 +773,7 @@ impl Engine for Tendermint { #[cfg(test)] mod tests { + use std::str::FromStr; use rustc_hex::FromHex; use util::*; use block::*; diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 46f5c8512..e93d06a27 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -142,11 +142,11 @@ mod tests { #[test] fn fetches_validators() { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None); - let vc = Arc::new(ValidatorContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); + let vc = Arc::new(ValidatorContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_contract(Arc::downgrade(&client)); let last_hash = client.best_block_header().hash(); - assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); - assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); + assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::
().unwrap())); + assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::
().unwrap())); } #[test] @@ -155,7 +155,7 @@ mod tests { let v1 = tap.insert_account("1".sha3().into(), "").unwrap(); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone())); client.engine().register_client(Arc::downgrade(&client)); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); // Make sure reporting can be done. client.miner().set_gas_floor_target(1_000_000.into()); diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 5835dbcdb..79a5a7d26 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -142,6 +142,7 @@ impl ValidatorSet for Multi { #[cfg(test)] mod tests { + use std::collections::BTreeMap; use account_provider::AccountProvider; use client::{BlockChainClient, EngineClient}; use engines::EpochChange; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 2c42323be..172ec53b7 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -438,11 +438,11 @@ mod tests { #[test] fn fetches_validators() { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); - let vc = Arc::new(ValidatorSafeContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); + let vc = Arc::new(ValidatorSafeContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_contract(Arc::downgrade(&client)); let last_hash = client.best_block_header().hash(); - assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); - assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); + assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::
().unwrap())); + assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::
().unwrap())); } #[test] @@ -454,7 +454,7 @@ mod tests { let network_id = Spec::new_validator_safe_contract().network_id(); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap)); client.engine().register_client(Arc::downgrade(&client)); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); client.miner().set_engine_signer(v1, "".into()).unwrap(); // Remove "1" validator. @@ -520,7 +520,7 @@ mod tests { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); let engine = client.engine().clone(); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); let last_hash = client.best_block_header().hash(); let mut new_header = Header::default(); diff --git a/ethcore/src/engines/vote_collector.rs b/ethcore/src/engines/vote_collector.rs index d01d07f15..de9188e74 100644 --- a/ethcore/src/engines/vote_collector.rs +++ b/ethcore/src/engines/vote_collector.rs @@ -17,6 +17,7 @@ //! Collects votes on hashes at each Message::Round. use std::fmt::Debug; +use std::collections::{BTreeMap, HashSet, HashMap}; use util::*; use rlp::{Encodable, RlpStream}; diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 2d908cdb6..194cbcb38 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -16,6 +16,7 @@ //! General error types for use in ethcore. +use std::fmt; use util::*; use io::*; use header::BlockNumber; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 1fbd711c9..06a4ad0d8 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . use std::path::Path; +use std::cmp; +use std::collections::{BTreeMap, HashMap}; use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use util::*; use block::*; @@ -235,15 +237,15 @@ impl Engine for Arc { let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into(); let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into(); let gas_limit = if gas_limit < gas_floor_target { - let gas_limit = min(gas_floor_target, upper_limit); + let gas_limit = cmp::min(gas_floor_target, upper_limit); round_block_gas_limit(gas_limit, lower_limit, upper_limit) } else if gas_limit > gas_ceil_target { - let gas_limit = max(gas_ceil_target, lower_limit); + let gas_limit = cmp::max(gas_ceil_target, lower_limit); round_block_gas_limit(gas_limit, lower_limit, upper_limit) } else { - let total_lower_limit = max(lower_limit, gas_floor_target); - let total_upper_limit = min(upper_limit, gas_ceil_target); - let gas_limit = max(gas_floor_target, min(total_upper_limit, + let total_lower_limit = cmp::max(lower_limit, gas_floor_target); + let total_upper_limit = cmp::min(upper_limit, gas_ceil_target); + let gas_limit = cmp::max(gas_floor_target, cmp::min(total_upper_limit, lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor)); round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit) }; @@ -319,7 +321,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // check the seal fields. if header.seal().len() != self.seal_fields() { return Err(From::from(BlockError::InvalidSealArity( @@ -357,7 +359,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { if header.seal().len() != self.seal_fields() { return Err(From::from(BlockError::InvalidSealArity( Mismatch { expected: self.seal_fields(), found: header.seal().len() } @@ -376,7 +378,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // we should not calculate difficulty for genesis blocks if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); @@ -400,7 +402,7 @@ impl Engine for Arc { Ok(()) } - fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> { if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price { return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into()); } @@ -493,28 +495,28 @@ impl Ethash { if diff_inc <= threshold { *parent.difficulty() + *parent.difficulty() / difficulty_bound_divisor * (threshold - diff_inc).into() } else { - let multiplier = min(diff_inc - threshold, 99).into(); + let multiplier = cmp::min(diff_inc - threshold, 99).into(); parent.difficulty().saturating_sub( *parent.difficulty() / difficulty_bound_divisor * multiplier ) } }; - target = max(min_difficulty, target); + target = cmp::max(min_difficulty, target); if header.number() < self.ethash_params.bomb_defuse_transition { if header.number() < self.ethash_params.ecip1010_pause_transition { let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; if period > 1 { - target = max(min_difficulty, target + (U256::from(1) << (period - 2))); + target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2))); } } else if header.number() < self.ethash_params.ecip1010_continue_transition { let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize; - target = max(min_difficulty, target + (U256::from(1) << fixed_difficulty)); + target = cmp::max(min_difficulty, target + (U256::from(1) << fixed_difficulty)); } else { let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize; - target = max(min_difficulty, target + (U256::from(1) << (period - delay - 2))); + target = cmp::max(min_difficulty, target + (U256::from(1) << (period - delay - 2))); } } target @@ -559,6 +561,8 @@ impl Header { #[cfg(test)] mod tests { + use std::str::FromStr; + use std::collections::BTreeMap; use util::*; use block::*; use tests::helpers::*; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 9e25b6671..9845d4575 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! Transaction Execution environment. +use std::cmp; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; @@ -74,7 +75,7 @@ pub struct TransactOptions { pub check_nonce: bool, } -pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) +pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) -> Box where E: Engine + ?Sized { if engine.supports_wasm() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) { @@ -597,10 +598,11 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { #[allow(dead_code)] mod tests { use std::sync::Arc; + use std::str::FromStr; use rustc_hex::FromHex; use ethkey::{Generator, Random}; use super::*; - use util::{H256, U256, U512, Address, FromStr}; + use util::{H256, U256, U512, Address}; use util::bytes::BytesRef; use evm::action_params::{ActionParams, ActionValue}; use evm::env_info::EnvInfo; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 39c8673a9..d718fd256 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! Transaction Execution environment. +use std::cmp; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; @@ -470,7 +471,7 @@ mod tests { let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); - let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); assert_eq!(hash, H256::zero()); } @@ -494,7 +495,7 @@ mod tests { let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); - let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); assert_eq!(test_hash, hash); } @@ -513,10 +514,10 @@ mod tests { // this should panic because we have no balance on any account ext.call( - &U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap(), + &"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap(), &Address::new(), &Address::new(), - Some(U256::from_str("0000000000000000000000000000000000000000000000000000000000150000").unwrap()), + Some("0000000000000000000000000000000000000000000000000000000000150000".parse::().unwrap()), &[], &Address::new(), &mut output, diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 83c69e97d..a9a4f948d 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -16,13 +16,13 @@ //! Block header. +use std::cmp; +use std::cell::RefCell; use util::*; use basic_types::{LogBloom, ZERO_LOGBLOOM}; use time::get_time; use rlp::*; -use std::cell::RefCell; - pub use basic_types::Seal; pub use types::BlockNumber; @@ -175,7 +175,7 @@ impl Header { /// Set the timestamp field of the header. pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); } /// Set the timestamp field of the header to the current time. - pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); } + pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = cmp::max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); } /// Set the number field of the header. pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); } /// Set the author field of the header. @@ -275,7 +275,7 @@ impl Decodable for Header { number: r.val_at(8)?, gas_limit: r.val_at(9)?, gas_used: r.val_at(10)?, - timestamp: min(r.val_at::(11)?, u64::max_value().into()).as_u64(), + timestamp: cmp::min(r.val_at::(11)?, u64::max_value().into()).as_u64(), extra_data: r.val_at(12)?, seal: vec![], hash: RefCell::new(Some(r.as_raw().sha3())), diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 89f9d2e57..0805fc7a0 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -106,6 +106,9 @@ extern crate semver; extern crate stats; extern crate time; extern crate transient_hashmap; +extern crate using_queue; +extern crate table; +extern crate bloomable; #[macro_use] extern crate log; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 80971355b..cc5c8b6f3 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -15,9 +15,10 @@ // along with Parity. If not, see . use std::time::{Instant, Duration}; +use std::collections::{BTreeMap, HashSet}; use util::*; -use util::using_queue::{UsingQueue, GetAction}; +use using_queue::{UsingQueue, GetAction}; use account_provider::{AccountProvider, SignError as AccountError}; use state::{State, CleanupMode}; use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockId, CallAnalytics, TransactionId}; diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index 542b42b93..263143ee8 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -106,7 +106,7 @@ use std::cmp; use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap}; use linked_hash_map::LinkedHashMap; use util::{Address, H256, U256, HeapSizeOf}; -use util::table::Table; +use table::Table; use transaction::*; use error::{Error, TransactionError}; use client::TransactionImportResult; @@ -1447,7 +1447,7 @@ fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option. +use std::fmt; +use std::collections::BTreeMap; use util::*; use state::Account; use ethjson; @@ -166,7 +168,7 @@ pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option StateDiff { #[cfg(test)] mod test { - use util::*; + use std::collections::BTreeMap; use types::state_diff::*; use types::account_diff::*; use pod_account::PodAccount; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 7d3900f2c..c4afc93d7 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -16,6 +16,8 @@ //! Parameters for a block chain. +use std::io::Read; +use std::collections::BTreeMap; use rustc_hex::FromHex; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; @@ -484,6 +486,7 @@ impl Spec { #[cfg(test)] mod tests { + use std::str::FromStr; use util::*; use views::*; use tests::helpers::get_temp_state_db; diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 9e58f2ec0..8f528b9d8 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -16,6 +16,8 @@ //! Single account in the system. +use std::fmt; +use std::collections::HashMap; use util::*; use pod_account::*; use rlp::*; diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 354da2cc3..25c019dc0 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -21,6 +21,8 @@ use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry; +use std::collections::{HashMap, BTreeMap, HashSet}; +use std::fmt; use receipt::Receipt; use engines::Engine; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 3b32f9094..54256b285 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::str::FromStr; use io::IoChannel; use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockId}; use state::{self, State, CleanupMode}; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index f8e412073..2c50f0fc2 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::BTreeMap; use ethkey::KeyPair; use io::*; use client::{BlockChainClient, Client, ClientConfig}; @@ -347,7 +348,7 @@ pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_h for i in start_number .. start_number + count + 1 { let mut block_header = Header::new(); block_header.set_gas_limit(test_engine.params().min_gas_limit); - block_header.set_difficulty(U256::from(i).mul(U256([0, 1, 0, 0]))); + block_header.set_difficulty(U256::from(i) * U256([0, 1, 0, 0])); block_header.set_timestamp(rolling_timestamp); block_header.set_number(i as u64); block_header.set_parent_hash(parent); diff --git a/ethcore/src/trace/types/filter.rs b/ethcore/src/trace/types/filter.rs index 2dc810442..1b2e2077a 100644 --- a/ethcore/src/trace/types/filter.rs +++ b/ethcore/src/trace/types/filter.rs @@ -20,7 +20,7 @@ use std::ops::Range; use bloomchain::{Filter as BloomFilter, Bloom, Number}; use util::Address; use util::sha3::Hashable; -use util::bloom::Bloomable; +use bloomable::Bloomable; use basic_types::LogBloom; use trace::flat::FlatTrace; use super::trace::{Action, Res}; @@ -137,7 +137,7 @@ impl Filter { mod tests { use util::Address; use util::sha3::Hashable; - use util::bloom::Bloomable; + use bloomable::Bloomable; use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide}; use trace::flat::FlatTrace; use trace::{Filter, AddressesFilter, TraceError}; diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index 24250935f..9a22f31a9 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -18,7 +18,7 @@ use util::{U256, Bytes, Address}; use util::sha3::Hashable; -use util::bloom::Bloomable; +use bloomable::Bloomable; use rlp::*; use evm::action_params::ActionParams; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 7e9a70f7c..192a0dc77 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -20,6 +20,8 @@ use std::thread::{self, JoinHandle}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}; use std::sync::{Condvar as SCondvar, Mutex as SMutex}; +use std::cmp; +use std::collections::{VecDeque, HashSet, HashMap}; use util::*; use io::*; use error::*; @@ -234,8 +236,8 @@ impl VerificationQueue { let scale_verifiers = config.verifier_settings.scale_verifiers; let num_cpus = ::num_cpus::get(); - let max_verifiers = min(num_cpus, MAX_VERIFIERS); - let default_amount = max(1, min(max_verifiers, config.verifier_settings.num_verifiers)); + let max_verifiers = cmp::min(num_cpus, MAX_VERIFIERS); + let default_amount = cmp::max(1, cmp::min(max_verifiers, config.verifier_settings.num_verifiers)); let state = Arc::new((Mutex::new(State::Work(default_amount)), Condvar::new())); let mut verifier_handles = Vec::with_capacity(max_verifiers); @@ -278,8 +280,8 @@ impl VerificationQueue { processing: RwLock::new(HashMap::new()), empty: empty, ticks_since_adjustment: AtomicUsize::new(0), - max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT), - max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT), + max_queue_size: cmp::max(config.max_queue_size, MIN_QUEUE_LIMIT), + max_mem_use: cmp::max(config.max_mem_use, MIN_MEM_LIMIT), scale_verifiers: scale_verifiers, verifier_handles: verifier_handles, state: state, @@ -567,7 +569,7 @@ impl VerificationQueue { /// Removes up to `max` verified items from the queue pub fn drain(&self, max: usize) -> Vec { let mut verified = self.verification.verified.lock(); - let count = min(max, verified.len()); + let count = cmp::min(max, verified.len()); let result = verified.drain(..count).collect::>(); let drained_size = result.iter().map(HeapSizeOf::heap_size_of_children).fold(0, |a, c| a + c); @@ -687,8 +689,8 @@ impl VerificationQueue { // or below 1. fn scale_verifiers(&self, target: usize) { let current = self.num_verifiers(); - let target = min(self.verifier_handles.len(), target); - let target = max(1, target); + let target = cmp::min(self.verifier_handles.len(), target); + let target = cmp::max(1, target); debug!(target: "verification", "Scaling from {} to {} verifiers", current, target); @@ -725,7 +727,6 @@ impl Drop for VerificationQueue { #[cfg(test)] mod tests { - use util::*; use io::*; use spec::*; use super::{BlockQueue, Config, State}; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 823d2ef70..00976dca7 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -21,6 +21,7 @@ //! 2. Signatures verification done in the queue. //! 3. Final verification against the blockchain done before enactment. +use std::collections::HashSet; use util::*; use engines::Engine; use error::{BlockError, Error}; @@ -264,6 +265,7 @@ fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: & #[cfg(test)] mod tests { + use std::collections::{BTreeMap, HashMap}; use util::*; use ethkey::{Random, Generator}; use header::*; diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index 2a3ac6a80..77f392bf6 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Parity Technologies "] rlp = { path = "../../util/rlp" } ethcore-util = { path = "../../util" } ethjson = { path = "../../json" } +bloomable = { path = "../../util/bloomable" } [dev-dependencies] rustc-hex= "1.0" diff --git a/ethcore/types/src/filter.rs b/ethcore/types/src/filter.rs index 6ab53b536..6e344b4ef 100644 --- a/ethcore/types/src/filter.rs +++ b/ethcore/types/src/filter.rs @@ -17,7 +17,7 @@ //! Blockchain filter use util::{Address, H256, Hashable, H2048}; -use util::bloom::Bloomable; +use bloomable::Bloomable; use ids::BlockId; use log_entry::LogEntry; diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 589034066..7650cf651 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -19,6 +19,7 @@ extern crate ethcore_util as util; extern crate ethjson; extern crate rlp; +extern crate bloomable; #[cfg(test)] extern crate rustc_hex; diff --git a/ethcore/types/src/log_entry.rs b/ethcore/types/src/log_entry.rs index 724e6a7dc..f917a4dab 100644 --- a/ethcore/types/src/log_entry.rs +++ b/ethcore/types/src/log_entry.rs @@ -18,7 +18,7 @@ use std::ops::Deref; use util::{H256, Address, Bytes, HeapSizeOf, Hashable}; -use util::bloom::Bloomable; +use bloomable::Bloomable; use rlp::*; use {BlockNumber}; @@ -114,8 +114,8 @@ mod tests { #[test] fn test_empty_log_bloom() { - let bloom = H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); - let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let bloom = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap(); + let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse::
().unwrap(); let log = LogEntry { address: address, topics: vec![], diff --git a/ethkey/cli/src/main.rs b/ethkey/cli/src/main.rs index 7ad07e295..e60b4583a 100644 --- a/ethkey/cli/src/main.rs +++ b/ethkey/cli/src/main.rs @@ -25,7 +25,7 @@ extern crate panic_hook; use std::{env, fmt, process}; use std::num::ParseIntError; use docopt::Docopt; -use rustc_hex::{FromHex, FromHexError}; +use rustc_hex::{ToHex, FromHex, FromHexError}; use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, sign, verify_public, verify_address}; use std::io; @@ -170,7 +170,7 @@ fn main() { fn display(keypair: KeyPair, mode: DisplayMode) -> String { match mode { DisplayMode::KeyPair => format!("{}", keypair), - DisplayMode::Secret => format!("{:?}", keypair.secret()), + DisplayMode::Secret => format!("{}", keypair.secret().to_hex()), DisplayMode::Public => format!("{:?}", keypair.public()), DisplayMode::Address => format!("{:?}", keypair.address()), } @@ -248,9 +248,9 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .collect::>(); let expected = -"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 -public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 -address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); +"secret: aa22b54c0cb43ee30a014afe5ef3664b1cde299feabca46cd3167a85a57c39f2 +public: c4c5398da6843632c123f543d714d2d2277716c11ff612b2a2f23c6bda4d6f0327c31cd58c55a9572c3cc141dade0c32747a13b7ef34c241b26c84adbb28fcf4 +address: 006e27b6a72e1f34c626762f3c4761547aff1421".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -261,7 +261,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55".to_owned(); + let expected = "aa22b54c0cb43ee30a014afe5ef3664b1cde299feabca46cd3167a85a57c39f2".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -272,7 +272,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124".to_owned(); + let expected = "c4c5398da6843632c123f543d714d2d2277716c11ff612b2a2f23c6bda4d6f0327c31cd58c55a9572c3cc141dade0c32747a13b7ef34c241b26c84adbb28fcf4".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -283,7 +283,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); + let expected = "006e27b6a72e1f34c626762f3c4761547aff1421".to_owned(); assert_eq!(execute(command).unwrap(), expected); } diff --git a/ethkey/src/secret.rs b/ethkey/src/secret.rs index 982962684..433d8c68e 100644 --- a/ethkey/src/secret.rs +++ b/ethkey/src/secret.rs @@ -17,6 +17,7 @@ use std::fmt; use std::ops::Deref; use std::str::FromStr; +use rustc_hex::ToHex; use secp256k1::key; use bigint::hash::H256; use {Error, SECP256K1}; @@ -26,6 +27,12 @@ pub struct Secret { inner: H256, } +impl ToHex for Secret { + fn to_hex(&self) -> String { + self.inner.to_hex() + } +} + impl fmt::Debug for Secret { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "Secret: 0x{:x}{:x}..{:x}{:x}", self.inner[0], self.inner[1], self.inner[30], self.inner[31]) diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index d52bda7d9..bd773e9b3 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -188,8 +188,9 @@ fn random_temp_path() -> PathBuf { #[cfg(test)] mod tests { + use rustc_hex::FromHex; use std::sync::{Arc, mpsc}; - use util::{Mutex, FromHex}; + use util::Mutex; use futures::future; use fetch::{self, Fetch}; use parity_reactor::Remote; diff --git a/ipc/hypervisor/src/lib.rs b/ipc/hypervisor/src/lib.rs index 1031905d4..b522122b5 100644 --- a/ipc/hypervisor/src/lib.rs +++ b/ipc/hypervisor/src/lib.rs @@ -260,7 +260,7 @@ mod tests { let client = nanoipc::fast_client::>(url).unwrap(); client.handshake().unwrap(); - client.module_ready(test_module_id); + client.module_ready(test_module_id, url.to_owned()); }); let hypervisor = Hypervisor::with_url(url).local_module(test_module_id); diff --git a/ipfs/src/lib.rs b/ipfs/src/lib.rs index 4821ef59d..104c7db19 100644 --- a/ipfs/src/lib.rs +++ b/ipfs/src/lib.rs @@ -233,7 +233,7 @@ mod tests { let _ = write_chunk(&mut transport, &mut progress, b"foobar"); - assert_eq!(b"foobar".into_vec(), transport); + assert_eq!(b"foobar".to_vec(), transport); assert_eq!(6, progress); } @@ -244,7 +244,7 @@ mod tests { let _ = write_chunk(&mut transport, &mut progress, b"foobar"); - assert_eq!(b"bar".into_vec(), transport); + assert_eq!(b"bar".to_vec(), transport); assert_eq!(6, progress); } diff --git a/ipfs/src/route.rs b/ipfs/src/route.rs index b034c2d4c..40edc8de0 100644 --- a/ipfs/src/route.rs +++ b/ipfs/src/route.rs @@ -119,7 +119,8 @@ mod tests { use ethcore::client::TestBlockChainClient; fn get_mocked_handler() -> IpfsHandler { - IpfsHandler::new(None, None, Arc::new(TestBlockChainClient::new())) + //IpfsHandler::new(None, None, Arc::new(TestBlockChainClient::new())) + unimplemented!(); } #[test] diff --git a/js/src/lib.rs.in b/js/src/lib.rs.in index 220811656..b811c1066 100644 --- a/js/src/lib.rs.in +++ b/js/src/lib.rs.in @@ -51,5 +51,5 @@ impl WebApp for App { #[test] fn test_js() { - parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR")); + parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR"), "build"); } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index c5bc0a259..ecc453622 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -16,6 +16,7 @@ //! Test implementation of miner service. +use std::collections::{BTreeMap, HashMap}; use std::collections::hash_map::Entry; use util::{Address, H256, Bytes, U256}; use util::standard::*; diff --git a/stratum/src/lib.rs b/stratum/src/lib.rs index d87bf59a8..0042ab1e9 100644 --- a/stratum/src/lib.rs +++ b/stratum/src/lib.rs @@ -342,7 +342,7 @@ mod tests { let mut core = Core::new().expect("Tokio Core should be created with no errors"); let mut buffer = vec![0u8; 2048]; - let mut data_vec = data.as_bytes().into_vec(); + let mut data_vec = data.as_bytes().to_vec(); data_vec.extend(b"\n"); let stream = TcpStream::connect(addr, &core.handle()) @@ -353,7 +353,7 @@ mod tests { io::read(stream, &mut buffer) }) .and_then(|(_, read_buf, len)| { - future::ok(read_buf[0..len].into_vec()) + future::ok(read_buf[0..len].to_vec()) }); let result = core.run(stream).expect("Core should run with no errors"); @@ -454,7 +454,7 @@ mod tests { let mut auth_request = r#"{"jsonrpc": "2.0", "method": "mining.authorize", "params": ["miner1", ""], "id": 1}"# .as_bytes() - .into_vec(); + .to_vec(); auth_request.extend(b"\n"); let mut core = Core::new().expect("Tokio Core should be created with no errors"); @@ -487,7 +487,7 @@ mod tests { }) .and_then(|(_, read_buf, len)| { trace!(target: "stratum", "Received work from server"); - future::ok(read_buf[0..len].into_vec()) + future::ok(read_buf[0..len].to_vec()) }); let response = String::from_utf8( core.run(stream).expect("Core should run with no errors") diff --git a/sync/src/block_sync.rs b/sync/src/block_sync.rs index e7192d525..8215b775b 100644 --- a/sync/src/block_sync.rs +++ b/sync/src/block_sync.rs @@ -18,6 +18,8 @@ /// Blockchain downloader /// +use std::collections::{HashSet, VecDeque}; +use std::cmp; use util::*; use rlp::*; use ethcore::views::{BlockView}; @@ -386,7 +388,7 @@ impl BlockDownloader { debug!(target: "sync", "Could not revert to previous ancient block, last: {} ({})", start, start_hash); self.reset(); } else { - let n = start - min(self.retract_step, start); + let n = start - cmp::min(self.retract_step, start); self.retract_step *= 2; match io.chain().block_hash(BlockId::Number(n)) { Some(h) => { diff --git a/sync/src/blocks.rs b/sync/src/blocks.rs index 3dcc912a7..dbd797007 100644 --- a/sync/src/blocks.rs +++ b/sync/src/blocks.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::{HashSet, HashMap}; use std::collections::hash_map::Entry; use smallvec::SmallVec; use util::*; diff --git a/sync/src/chain.rs b/sync/src/chain.rs index b3ca25328..38872b24f 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -89,6 +89,8 @@ /// All other messages are ignored. /// +use std::collections::{HashSet, HashMap}; +use std::cmp; use util::*; use rlp::*; use network::*; @@ -421,7 +423,7 @@ impl ChainSync { start_block_number: self.starting_block, last_imported_block_number: Some(last_imported_number), last_imported_old_block_number: self.old_blocks.as_ref().map(|d| d.last_imported_block_number()), - highest_block_number: self.highest_block.map(|n| max(n, last_imported_number)), + highest_block_number: self.highest_block.map(|n| cmp::max(n, last_imported_number)), blocks_received: if last_imported_number > self.starting_block { last_imported_number - self.starting_block } else { 0 }, blocks_total: match self.highest_block { Some(x) if x > self.starting_block => x - self.starting_block, _ => 0 }, num_peers: self.peers.values().filter(|p| p.is_allowed()).count(), @@ -961,7 +963,7 @@ impl ChainSync { } if self.state != SyncState::Idle { trace!(target: "sync", "Ignoring new hashes since we're already downloading."); - let max = r.iter().take(MAX_NEW_HASHES).map(|item| item.val_at::(1).unwrap_or(0)).fold(0u64, max); + let max = r.iter().take(MAX_NEW_HASHES).map(|item| item.val_at::(1).unwrap_or(0)).fold(0u64, cmp::max); if max > self.highest_block.unwrap_or(0) { self.highest_block = Some(max); } @@ -1473,7 +1475,7 @@ impl ChainSync { let mut item_count = r.item_count()?; trace!(target: "sync", "{:02} -> Transactions ({} entries)", peer_id, item_count); - item_count = min(item_count, MAX_TX_TO_IMPORT); + item_count = cmp::min(item_count, MAX_TX_TO_IMPORT); let mut transactions = Vec::with_capacity(item_count); for i in 0 .. item_count { let rlp = r.at(i)?; @@ -1549,11 +1551,11 @@ impl ChainSync { }; let mut number = if reverse { - min(last, number) + cmp::min(last, number) } else { - max(0, number) + cmp::max(0, number) }; - let max_count = min(MAX_HEADERS_TO_SEND, max_headers); + let max_count = cmp::min(MAX_HEADERS_TO_SEND, max_headers); let mut count = 0; let mut data = Bytes::new(); let inc = (skip + 1) as BlockNumber; @@ -1594,7 +1596,7 @@ impl ChainSync { debug!(target: "sync", "Empty GetBlockBodies request, ignoring."); return Ok(None); } - count = min(count, MAX_BODIES_TO_SEND); + count = cmp::min(count, MAX_BODIES_TO_SEND); let mut added = 0usize; let mut data = Bytes::new(); for i in 0..count { @@ -1617,7 +1619,7 @@ impl ChainSync { debug!(target: "sync", "Empty GetNodeData request, ignoring."); return Ok(None); } - count = min(count, MAX_NODE_DATA_TO_SEND); + count = cmp::min(count, MAX_NODE_DATA_TO_SEND); let mut added = 0usize; let mut data = Vec::new(); for i in 0..count { @@ -1641,7 +1643,7 @@ impl ChainSync { debug!(target: "sync", "Empty GetReceipts request, ignoring."); return Ok(None); } - count = min(count, MAX_RECEIPTS_HEADERS_TO_SEND); + count = cmp::min(count, MAX_RECEIPTS_HEADERS_TO_SEND); let mut added_headers = 0usize; let mut added_receipts = 0usize; let mut data = Bytes::new(); @@ -1915,8 +1917,8 @@ impl ChainSync { // take sqrt(x) peers let mut peers = peers.to_vec(); let mut count = (peers.len() as f64).powf(0.5).round() as usize; - count = min(count, MAX_PEERS_PROPAGATION); - count = max(count, MIN_PEERS_PROPAGATION); + count = cmp::min(count, MAX_PEERS_PROPAGATION); + count = cmp::max(count, MIN_PEERS_PROPAGATION); random::new().shuffle(&mut peers); peers.truncate(count); peers @@ -2006,7 +2008,7 @@ impl ChainSync { fn select_peers_for_transactions(&self, filter: F) -> Vec where F: Fn(&PeerId) -> bool { // sqrt(x)/x scaled to max u32 - let fraction = (self.peers.len() as f64).powf(-0.5).mul(u32::max_value() as f64).round() as u32; + let fraction = ((self.peers.len() as f64).powf(-0.5) * (u32::max_value() as f64).round()) as u32; let small = self.peers.len() < MIN_PEERS_PROPAGATION; let mut random = random::new(); @@ -2112,7 +2114,7 @@ impl ChainSync { peers.insert(peer_id); self.send_packet(io, peer_id, TRANSACTIONS_PACKET, rlp); trace!(target: "sync", "{:02} <- Transactions ({} entries)", peer_id, sent); - max_sent = max(max_sent, sent); + max_sent = cmp::max(max_sent, sent); } debug!(target: "sync", "Sent up to {} transactions to {} peers.", max_sent, lucky_peers_len); } diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index 9d32d1951..fa3039b63 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::{VecDeque, HashSet, HashMap}; use util::*; use network::*; use tests::snapshot::*; diff --git a/sync/src/tests/snapshot.rs b/sync/src/tests/snapshot.rs index f52cdb39a..0a3b31fb0 100644 --- a/sync/src/tests/snapshot.rs +++ b/sync/src/tests/snapshot.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::HashMap; use util::*; use ethcore::snapshot::{SnapshotService, ManifestData, RestorationStatus}; use ethcore::header::BlockNumber; diff --git a/util/Cargo.toml b/util/Cargo.toml index aa846898f..5306e3c57 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -28,8 +28,6 @@ vergen = "0.1" target_info = "0.1" ethcore-bigint = { path = "bigint", features = ["heapsizeof"] } parking_lot = "0.4" -using_queue = { path = "using_queue" } -table = { path = "table" } ansi_term = "0.9" tiny-keccak= "1.0" ethcore-bloom-journal = { path = "bloom" } diff --git a/util/bloomable/Cargo.toml b/util/bloomable/Cargo.toml new file mode 100644 index 000000000..46009d381 --- /dev/null +++ b/util/bloomable/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "bloomable" +version = "0.1.0" +authors = ["debris "] + +[dependencies] +ethcore-bigint = { path = "../bigint" } + +[dev-dependencies] +tiny-keccak = "1.2.1" diff --git a/util/src/bloom.rs b/util/bloomable/src/lib.rs similarity index 70% rename from util/src/bloom.rs rename to util/bloomable/src/lib.rs index c39921f5d..29a9abde5 100644 --- a/util/src/bloom.rs +++ b/util/bloomable/src/lib.rs @@ -16,9 +16,11 @@ //! Bloom operations. +extern crate ethcore_bigint; + use std::mem; use std::ops::DerefMut; -use {H64, H160, H256, H512, H520, H2048}; +use ethcore_bigint::hash::{H64, H160, H256, H512, H520, H2048}; /// Returns log2. pub fn log2(x: usize) -> u32 { @@ -115,31 +117,3 @@ impl_bloomable_for_hash!(H256, 32); impl_bloomable_for_hash!(H512, 64); impl_bloomable_for_hash!(H520, 65); impl_bloomable_for_hash!(H2048, 256); - -#[cfg(test)] -mod tests { - use {H160, H256, H2048}; - use sha3::Hashable; - use super::Bloomable; - - #[test] - fn shift_bloomed() { - let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(); - let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into(); - let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".into(); - - let mut my_bloom = H2048::default(); - assert!(!my_bloom.contains_bloomed(&address.sha3())); - assert!(!my_bloom.contains_bloomed(&topic.sha3())); - - my_bloom.shift_bloomed(&address.sha3()); - assert!(my_bloom.contains_bloomed(&address.sha3())); - assert!(!my_bloom.contains_bloomed(&topic.sha3())); - - my_bloom.shift_bloomed(&topic.sha3()); - assert_eq!(my_bloom, bloom); - assert!(my_bloom.contains_bloomed(&address.sha3())); - assert!(my_bloom.contains_bloomed(&topic.sha3())); - } -} - diff --git a/util/bloomable/tests/test.rs b/util/bloomable/tests/test.rs new file mode 100644 index 000000000..85ced83e6 --- /dev/null +++ b/util/bloomable/tests/test.rs @@ -0,0 +1,31 @@ +extern crate tiny_keccak; +extern crate ethcore_bigint; +extern crate bloomable; + +use ethcore_bigint::hash::{H160, H256, H2048}; +use bloomable::Bloomable; +use tiny_keccak::keccak256; + +fn sha3(input: &[u8]) -> H256 { + keccak256(input).into() +} + +#[test] +fn shift_bloomed() { + let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(); + let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into(); + let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".into(); + + let mut my_bloom = H2048::default(); + assert!(!my_bloom.contains_bloomed(&sha3(&address))); + assert!(!my_bloom.contains_bloomed(&sha3(&topic))); + + my_bloom.shift_bloomed(&sha3(&address)); + assert!(my_bloom.contains_bloomed(&sha3(&address))); + assert!(!my_bloom.contains_bloomed(&sha3(&topic))); + + my_bloom.shift_bloomed(&sha3(&topic)); + assert_eq!(my_bloom, bloom); + assert!(my_bloom.contains_bloomed(&sha3(&address))); + assert!(my_bloom.contains_bloomed(&sha3(&topic))); +} diff --git a/util/src/common.rs b/util/src/common.rs index eff697bc2..89ce9d95f 100644 --- a/util/src/common.rs +++ b/util/src/common.rs @@ -16,6 +16,7 @@ //! Utils common types and macros global reexport. +use std::io; pub use standard::*; pub use error::*; pub use bytes::*; @@ -100,8 +101,8 @@ macro_rules! flushln { #[doc(hidden)] pub fn flush(s: String) { - let _ = ::std::io::stdout().write(s.as_bytes()); - let _ = ::std::io::stdout().flush(); + let _ = io::Write::write(&mut io::stdout(), s.as_bytes()); + let _ = io::Write::flush(&mut io::stdout()); } #[test] diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index cf21fbd9f..e882f3f18 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -16,6 +16,7 @@ //! Disk-backed `HashDB` implementation. +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index 7eb3f3259..de0e19d6e 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -16,6 +16,8 @@ //! Disk-backed `HashDB` implementation. +use std::fmt; +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/journaldb/mod.rs b/util/src/journaldb/mod.rs index 84a71339a..80ddbf7a1 100644 --- a/util/src/journaldb/mod.rs +++ b/util/src/journaldb/mod.rs @@ -16,6 +16,7 @@ //! `JournalDB` interface and implementation. +use std::{fmt, str}; use common::*; /// Export the journaldb module. @@ -59,7 +60,7 @@ impl Default for Algorithm { fn default() -> Algorithm { Algorithm::OverlayRecent } } -impl FromStr for Algorithm { +impl str::FromStr for Algorithm { type Err = String; fn from_str(s: &str) -> Result { diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index 915e64d05..73a63bd4b 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -16,6 +16,7 @@ //! `JournalDB` over in-memory overlay +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index 4f8600bde..772281abd 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -16,6 +16,7 @@ //! Disk-backed, ref-counted `JournalDB` implementation. +use std::collections::HashMap; use common::*; use rlp::*; use hashdb::*; diff --git a/util/src/kvdb.rs b/util/src/kvdb.rs index d1cf67218..6692064ed 100644 --- a/util/src/kvdb.rs +++ b/util/src/kvdb.rs @@ -16,6 +16,8 @@ //! Key-Value store abstraction with `RocksDB` backend. +use std::{mem, fs}; +use std::collections::{HashMap, BTreeMap}; use std::io::ErrorKind; use std::marker::PhantomData; use std::path::PathBuf; diff --git a/util/src/lib.rs b/util/src/lib.rs index c6a50f58b..c2d9c59d3 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -112,10 +112,6 @@ extern crate ethcore_logger; #[macro_use] extern crate log as rlog; -pub extern crate using_queue; -pub extern crate table; - -pub mod bloom; pub mod standard; #[macro_use] pub mod common; @@ -147,7 +143,6 @@ pub use overlaydb::*; pub use journaldb::JournalDB; pub use triehash::*; pub use trie::{Trie, TrieMut, TrieDB, TrieDBMut, TrieFactory, TrieError, SecTrieDB, SecTrieDBMut}; -pub use nibbleslice::*; pub use semantic_version::*; pub use kvdb::*; pub use timer::*; diff --git a/util/src/migration/tests.rs b/util/src/migration/tests.rs index 585bb5f36..7cd19009a 100644 --- a/util/src/migration/tests.rs +++ b/util/src/migration/tests.rs @@ -18,6 +18,7 @@ //! A random temp directory is created. A database is created within it, and migrations //! are performed in temp sub-directories. +use std::collections::BTreeMap; use common::*; use migration::{Batch, Config, Error, SimpleMigration, Migration, Manager}; use kvdb::Database; diff --git a/util/src/misc.rs b/util/src/misc.rs index 6dc2fba12..120805f0c 100644 --- a/util/src/misc.rs +++ b/util/src/misc.rs @@ -60,9 +60,9 @@ pub fn version() -> String { pub fn version_data() -> Bytes { let mut s = RlpStream::new_list(4); let v = - (u32::from_str(env!("CARGO_PKG_VERSION_MAJOR")).expect("Environment variables are known to be valid; qed") << 16) + - (u32::from_str(env!("CARGO_PKG_VERSION_MINOR")).expect("Environment variables are known to be valid; qed") << 8) + - u32::from_str(env!("CARGO_PKG_VERSION_PATCH")).expect("Environment variables are known to be valid; qed"); + (env!("CARGO_PKG_VERSION_MAJOR").parse::().expect("Environment variables are known to be valid; qed") << 16) + + (env!("CARGO_PKG_VERSION_MINOR").parse::().expect("Environment variables are known to be valid; qed") << 8) + + env!("CARGO_PKG_VERSION_PATCH").parse::().expect("Environment variables are known to be valid; qed"); s.append(&v); s.append(&"Parity"); s.append(&rustc_version()); diff --git a/util/src/nibblevec.rs b/util/src/nibblevec.rs index 718ff8e9e..b38198593 100644 --- a/util/src/nibblevec.rs +++ b/util/src/nibblevec.rs @@ -17,7 +17,7 @@ //! An owning, nibble-oriented byte vector. -use ::NibbleSlice; +use nibbleslice::NibbleSlice; use elastic_array::ElasticArray36; /// Owning, nibble-oriented byte vector. Counterpart to `NibbleSlice`. diff --git a/util/src/standard.rs b/util/src/standard.rs index 19521a5d5..cc67b0de5 100644 --- a/util/src/standard.rs +++ b/util/src/standard.rs @@ -16,28 +16,10 @@ //! Std lib global reexports. -pub use std::io; -pub use std::fs; -pub use std::str; -pub use std::fmt; -pub use std::cmp; -pub use std::ptr; -pub use std::mem; -pub use std::ops; -pub use std::slice; -pub use std::result; -pub use std::option; - pub use std::path::Path; -pub use std::str::{FromStr}; -pub use std::io::{Read,Write}; pub use std::hash::{Hash, Hasher}; -pub use std::error::Error as StdError; -pub use std::ops::*; -pub use std::cmp::*; pub use std::sync::Arc; -pub use std::collections::*; pub use heapsize::HeapSizeOf; pub use itertools::Itertools; diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index 5da304167..a8600914c 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::fmt; use common::*; use hashdb::*; use nibbleslice::*; From c4989ddc442df2d8a09a7a28057a640f8898894b Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 21:56:42 +0200 Subject: [PATCH 037/119] removed util::common --- dapps/src/api/time.rs | 5 ++-- ethcore/evm/src/ext.rs | 1 + ethcore/evm/src/interpreter/mod.rs | 1 + ethcore/evm/src/tests.rs | 2 ++ ethcore/src/blockchain/blockchain.rs | 1 + ethcore/src/client/test_client.rs | 1 + ethcore/src/engines/authority_round/mod.rs | 22 +++++++-------- ethcore/src/engines/basic_authority.rs | 3 ++- ethcore/src/engines/instant_seal.rs | 1 + ethcore/src/engines/mod.rs | 3 ++- ethcore/src/engines/signer.rs | 3 ++- ethcore/src/engines/tendermint/message.rs | 1 + ethcore/src/engines/tendermint/mod.rs | 2 +- ethcore/src/engines/validator_set/contract.rs | 1 + ethcore/src/engines/validator_set/multi.rs | 1 + .../engines/validator_set/safe_contract.rs | 3 ++- ethcore/src/engines/validator_set/test.rs | 3 ++- ethcore/src/engines/vote_collector.rs | 1 + ethcore/src/ethereum/ethash.rs | 2 ++ ethcore/src/executive.rs | 1 + ethcore/src/externalities.rs | 1 + ethcore/src/miner/miner.rs | 1 + ethcore/src/service.rs | 2 ++ ethcore/src/spec/spec.rs | 2 ++ ethcore/src/state/account.rs | 1 + ethcore/src/state/mod.rs | 1 + ethcore/src/state_db.rs | 3 ++- ethcore/src/tests/client.rs | 1 + ethcore/src/tests/evm.rs | 1 + ethcore/src/tests/helpers.rs | 1 + ethcore/src/verification/queue/mod.rs | 2 +- json/src/spec/authority_round.rs | 5 ++-- rpc/src/v1/tests/helpers/miner_service.rs | 3 +-- sync/src/tests/chain.rs | 2 +- sync/src/tests/consensus.rs | 1 + sync/src/tests/helpers.rs | 1 + sync/src/tests/snapshot.rs | 1 + util/network/src/tests.rs | 3 ++- util/src/common.rs | 11 ++------ util/src/error.rs | 2 +- util/src/journaldb/archivedb.rs | 6 +++-- util/src/journaldb/earlymergedb.rs | 9 +++++-- util/src/journaldb/mod.rs | 2 +- util/src/journaldb/overlayrecentdb.rs | 8 ++++-- util/src/journaldb/refcounteddb.rs | 6 +++-- util/src/journaldb/traits.rs | 3 ++- util/src/kvdb.rs | 7 +++-- util/src/lib.rs | 12 +++++++-- util/src/migration/tests.rs | 5 ++-- util/src/misc.rs | 2 +- util/src/standard.rs | 27 ------------------- util/src/trie/triedb.rs | 3 ++- 52 files changed, 109 insertions(+), 84 deletions(-) delete mode 100644 util/src/standard.rs diff --git a/dapps/src/api/time.rs b/dapps/src/api/time.rs index b81b4a844..3117f4cc9 100644 --- a/dapps/src/api/time.rs +++ b/dapps/src/api/time.rs @@ -33,13 +33,14 @@ use std::io; use std::{fmt, mem, time}; - +use std::sync::Arc; use std::collections::VecDeque; + use futures::{self, Future, BoxFuture}; use futures_cpupool::CpuPool; use ntp; use time::{Duration, Timespec}; -use util::{Arc, RwLock}; +use util::RwLock; /// Time checker error. #[derive(Debug, Clone, PartialEq)] diff --git a/ethcore/evm/src/ext.rs b/ethcore/evm/src/ext.rs index 1c3ddb317..2861b1ca5 100644 --- a/ethcore/evm/src/ext.rs +++ b/ethcore/evm/src/ext.rs @@ -16,6 +16,7 @@ //! Interface for Evm externalities. +use std::sync::Arc; use util::*; use call_type::CallType; use env_info::EnvInfo; diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 621febffd..36e652ab2 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -25,6 +25,7 @@ mod shared_cache; use std::marker::PhantomData; use std::{cmp, mem}; +use std::sync::Arc; use self::gasometer::Gasometer; use self::stack::{Stack, VecStack}; use self::memory::Memory; diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index c19a575f3..7679ab980 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -16,6 +16,8 @@ use std::fmt::Debug; use std::str::FromStr; +use std::hash::Hash; +use std::sync::Arc; use std::collections::{HashMap, HashSet}; use rustc_hex::FromHex; use util::*; diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 59b4fb7c3..bd0defa47 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -17,6 +17,7 @@ //! Blockchain database. use std::collections::{HashMap, HashSet}; +use std::sync::Arc; use std::mem; use bloomchain as bc; use util::*; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index e33888e72..aa49e6abc 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -17,6 +17,7 @@ //! Test client. use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; +use std::sync::Arc; use std::collections::{HashMap, BTreeMap}; use std::mem; use rustc_hex::FromHex; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index a72091e5e..d260c9ac8 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -17,7 +17,7 @@ //! A blockchain engine that supports a non-instant BFT proof-of-authority. use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::time::{UNIX_EPOCH, Duration}; use std::collections::{BTreeMap, HashSet, HashMap}; use std::cmp; @@ -853,8 +853,8 @@ impl Engine for AuthorityRound { #[cfg(test)] mod tests { + use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; - use std::str::FromStr; use util::*; use header::Header; use error::{Error, BlockError}; @@ -944,10 +944,10 @@ mod tests { let addr = tap.insert_account("0".sha3().into(), "0").unwrap(); let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&0usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -970,10 +970,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&0usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -996,10 +996,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&4usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -1017,7 +1017,7 @@ mod tests { fn reports_skipped() { let last_benign = Arc::new(AtomicUsize::new(0)); let params = AuthorityRoundParams { - gas_limit_bound_divisor: U256::from_str("400").unwrap(), + gas_limit_bound_divisor: "400".parse::().unwrap(), step_duration: Default::default(), block_reward: Default::default(), registrar: Default::default(), @@ -1032,10 +1032,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&1usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_seal(vec![encode(&3usize).into_vec()]); // Do not report when signer not present. diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index a3f4b9114..38db41c53 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -16,7 +16,7 @@ //! A blockchain engine that supports a basic, non-BFT proof-of-authority. -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::collections::BTreeMap; use std::cmp; use util::*; @@ -256,6 +256,7 @@ impl Engine for BasicAuthority { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use block::*; use error::{BlockError, Error}; diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 4d297dc3f..94e3184ef 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -65,6 +65,7 @@ impl Engine for InstantSeal { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use tests::helpers::*; use spec::Spec; diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 77b89e59c..b5a0d934f 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -35,7 +35,7 @@ pub use self::instant_seal::InstantSeal; pub use self::null_engine::NullEngine; pub use self::tendermint::Tendermint; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::collections::{BTreeMap, HashMap}; use std::fmt; @@ -395,6 +395,7 @@ pub trait Engine : Sync + Send { /// Common engine utilities pub mod common { + use std::sync::Arc; use block::ExecutedBlock; use evm::env_info::{EnvInfo, LastHashes}; use error::Error; diff --git a/ethcore/src/engines/signer.rs b/ethcore/src/engines/signer.rs index 4ec4318c9..4069488ab 100644 --- a/ethcore/src/engines/signer.rs +++ b/ethcore/src/engines/signer.rs @@ -16,7 +16,8 @@ //! A signer used by Engines which need to sign messages. -use util::{Arc, H256, Address}; +use std::sync::Arc; +use util::{H256, Address}; use ethkey::Signature; use account_provider::{self, AccountProvider}; diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index 623284839..68bdcb0f7 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -199,6 +199,7 @@ pub fn message_hash(vote_step: VoteStep, block_hash: H256) -> H256 { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use rlp::*; use account_provider::AccountProvider; diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 5d334a610..a340db5d4 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -25,7 +25,7 @@ mod message; mod params; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use std::collections::{HashSet, BTreeMap, HashMap}; use std::cmp; diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index e93d06a27..7c1890379 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -126,6 +126,7 @@ impl ValidatorSet for ValidatorContract { #[cfg(test)] mod tests { + use std::sync::Arc; use rustc_hex::FromHex; use util::*; use rlp::encode; diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 79a5a7d26..9acf6050b 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -142,6 +142,7 @@ impl ValidatorSet for Multi { #[cfg(test)] mod tests { + use std::sync::Arc; use std::collections::BTreeMap; use account_provider::AccountProvider; use client::{BlockChainClient, EngineClient}; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 172ec53b7..8148846e7 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -16,7 +16,7 @@ /// Validator set maintained in a contract, updated using `getValidators` method. -use std::sync::Weak; +use std::sync::{Weak, Arc}; use futures::Future; use native_contracts::ValidatorSet as Provider; @@ -422,6 +422,7 @@ impl ValidatorSet for ValidatorSafeContract { #[cfg(test)] mod tests { + use std::sync::Arc; use rustc_hex::FromHex; use util::*; use types::ids::BlockId; diff --git a/ethcore/src/engines/validator_set/test.rs b/ethcore/src/engines/validator_set/test.rs index 4960ee7be..25eeff66e 100644 --- a/ethcore/src/engines/validator_set/test.rs +++ b/ethcore/src/engines/validator_set/test.rs @@ -17,8 +17,9 @@ /// Used for Engine testing. use std::str::FromStr; +use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; -use util::{Arc, Bytes, H256, Address, HeapSizeOf}; +use util::{Bytes, H256, Address, HeapSizeOf}; use engines::{Call, Engine}; use header::{Header, BlockNumber}; diff --git a/ethcore/src/engines/vote_collector.rs b/ethcore/src/engines/vote_collector.rs index de9188e74..b934fdb2e 100644 --- a/ethcore/src/engines/vote_collector.rs +++ b/ethcore/src/engines/vote_collector.rs @@ -18,6 +18,7 @@ use std::fmt::Debug; use std::collections::{BTreeMap, HashSet, HashMap}; +use std::hash::Hash; use util::*; use rlp::{Encodable, RlpStream}; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 06a4ad0d8..0f984517c 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -17,6 +17,7 @@ use std::path::Path; use std::cmp; use std::collections::{BTreeMap, HashMap}; +use std::sync::Arc; use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use util::*; use block::*; @@ -563,6 +564,7 @@ impl Header { mod tests { use std::str::FromStr; use std::collections::BTreeMap; + use std::sync::Arc; use util::*; use block::*; use tests::helpers::*; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 9845d4575..a63605a81 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -16,6 +16,7 @@ //! Transaction Execution environment. use std::cmp; +use std::sync::Arc; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index d718fd256..5baca496d 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -16,6 +16,7 @@ //! Transaction Execution environment. use std::cmp; +use std::sync::Arc; use util::*; use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index cc5c8b6f3..241d90c32 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -16,6 +16,7 @@ use std::time::{Instant, Duration}; use std::collections::{BTreeMap, HashSet}; +use std::sync::Arc; use util::*; use using_queue::{UsingQueue, GetAction}; diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index e4c3d7519..5e65a4de8 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -16,6 +16,8 @@ //! Creates and registers client and network services. +use std::sync::Arc; +use std::path::Path; use util::*; use io::*; use spec::Spec; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index c4afc93d7..a5426faa8 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -18,6 +18,8 @@ use std::io::Read; use std::collections::BTreeMap; +use std::path::Path; +use std::sync::Arc; use rustc_hex::FromHex; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 8f528b9d8..1235fd289 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -17,6 +17,7 @@ //! Single account in the system. use std::fmt; +use std::sync::Arc; use std::collections::HashMap; use util::*; use pod_account::*; diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 25c019dc0..1dd6204c3 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -23,6 +23,7 @@ use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry; use std::collections::{HashMap, BTreeMap, HashSet}; use std::fmt; +use std::sync::Arc; use receipt::Receipt; use engines::Engine; diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index de5a3f75b..e2f6fdaf0 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::{VecDeque, HashSet}; +use std::sync::Arc; use lru_cache::LruCache; use util::cache::MemoryLruCache; use util::journaldb::JournalDB; @@ -23,7 +24,7 @@ use util::hash::{H256}; use util::hashdb::HashDB; use state::{self, Account}; use header::BlockNumber; -use util::{Arc, Address, DBTransaction, UtilError, Mutex, Hashable}; +use util::{Address, DBTransaction, UtilError, Mutex, Hashable}; use bloom_journal::{Bloom, BloomJournal}; use db::COL_ACCOUNT_BLOOM; use byteorder::{LittleEndian, ByteOrder}; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 54256b285..639fce3ab 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::str::FromStr; +use std::sync::Arc; use io::IoChannel; use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockId}; use state::{self, State, CleanupMode}; diff --git a/ethcore/src/tests/evm.rs b/ethcore/src/tests/evm.rs index c97fd4ac0..50cf4deb7 100644 --- a/ethcore/src/tests/evm.rs +++ b/ethcore/src/tests/evm.rs @@ -1,5 +1,6 @@ //! Tests of EVM integration with transaction execution. +use std::sync::Arc; use evm::action_params::{ActionParams, ActionValue}; use evm::env_info::EnvInfo; use evm::{Factory, VMType}; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 2c50f0fc2..2d48e470b 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::BTreeMap; +use std::sync::Arc; use ethkey::KeyPair; use io::*; use client::{BlockChainClient, Client, ClientConfig}; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 192a0dc77..ce0cb4179 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -19,7 +19,7 @@ use std::thread::{self, JoinHandle}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}; -use std::sync::{Condvar as SCondvar, Mutex as SMutex}; +use std::sync::{Condvar as SCondvar, Mutex as SMutex, Arc}; use std::cmp; use std::collections::{VecDeque, HashSet, HashMap}; use util::*; diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 0fdbfbfb3..91a5fd828 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -63,11 +63,10 @@ pub struct AuthorityRound { #[cfg(test)] mod tests { + use util::{H160, U256}; use uint::Uint; - use util::U256; - use util::H160; - use serde_json; use hash::Address; + use serde_json; use spec::validator_set::ValidatorSet; use spec::authority_round::AuthorityRound; diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index ecc453622..ef9b5724b 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -18,8 +18,7 @@ use std::collections::{BTreeMap, HashMap}; use std::collections::hash_map::Entry; -use util::{Address, H256, Bytes, U256}; -use util::standard::*; +use util::{Address, H256, Bytes, U256, RwLock, Mutex}; use ethcore::error::{Error, CallError}; use ethcore::client::{MiningBlockChainClient, Executed, CallAnalytics}; use ethcore::block::{ClosedBlock, IsBlock}; diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index 23ed4b7ea..f9ce17b5b 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use util::*; +use std::sync::Arc; use ethcore::client::{TestBlockChainClient, BlockChainClient, BlockId, EachBlockWith}; use chain::{SyncState}; use super::helpers::*; diff --git a/sync/src/tests/consensus.rs b/sync/src/tests/consensus.rs index 6b91b11c6..499b7de17 100644 --- a/sync/src/tests/consensus.rs +++ b/sync/src/tests/consensus.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Arc; use util::*; use io::{IoHandler, IoContext, IoChannel}; use ethcore::client::{BlockChainClient, Client}; diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index fa3039b63..3ac68b0fb 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::{VecDeque, HashSet, HashMap}; +use std::sync::Arc; use util::*; use network::*; use tests::snapshot::*; diff --git a/sync/src/tests/snapshot.rs b/sync/src/tests/snapshot.rs index 0a3b31fb0..9303aa9f7 100644 --- a/sync/src/tests/snapshot.rs +++ b/sync/src/tests/snapshot.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::HashMap; +use std::sync::Arc; use util::*; use ethcore::snapshot::{SnapshotService, ManifestData, RestorationStatus}; use ethcore::header::BlockNumber; diff --git a/util/network/src/tests.rs b/util/network/src/tests.rs index 52184061c..81325f57b 100644 --- a/util/network/src/tests.rs +++ b/util/network/src/tests.rs @@ -16,9 +16,10 @@ use super::*; use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; +use std::sync::Arc; use std::thread; use std::time::*; -use util::common::*; +use util::{Bytes, Mutex}; use io::TimerToken; use ethkey::{Random, Generator}; diff --git a/util/src/common.rs b/util/src/common.rs index 89ce9d95f..4bf3a06ed 100644 --- a/util/src/common.rs +++ b/util/src/common.rs @@ -17,13 +17,6 @@ //! Utils common types and macros global reexport. use std::io; -pub use standard::*; -pub use error::*; -pub use bytes::*; -pub use vector::*; -pub use sha3::*; -pub use bigint::prelude::*; -pub use bigint::hash; #[macro_export] macro_rules! vec_into { @@ -89,8 +82,8 @@ macro_rules! map_into { #[macro_export] macro_rules! flush { - ($arg:expr) => ($crate::flush($arg.into())); - ($($arg:tt)*) => ($crate::flush(format!("{}", format_args!($($arg)*)))); + ($arg:expr) => ($crate::common::flush($arg.into())); + ($($arg:tt)*) => ($crate::common::flush(format!("{}", format_args!($($arg)*)))); } #[macro_export] diff --git a/util/src/error.rs b/util/src/error.rs index 4ed2fc9bd..b0e887434 100644 --- a/util/src/error.rs +++ b/util/src/error.rs @@ -19,7 +19,7 @@ use rustc_hex::FromHexError; use rlp::DecoderError; use std::fmt; -use hash::H256; +use bigint::hash::H256; #[derive(Debug)] /// Error in database subsystem. diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index e882f3f18..fc893654a 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -17,13 +17,14 @@ //! Disk-backed `HashDB` implementation. use std::collections::HashMap; -use common::*; +use std::sync::Arc; use rlp::*; use hashdb::*; use memorydb::*; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; +use {Bytes, H256, BaseDataError, UtilError}; /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay /// and latent-removal semantics. @@ -197,11 +198,12 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; + use std::path::Path; use hashdb::{HashDB, DBValue}; use super::*; use journaldb::traits::JournalDB; use kvdb::Database; + use {Hashable, H32}; #[test] fn insert_same_in_fork() { diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index de0e19d6e..5f409d327 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -18,13 +18,17 @@ use std::fmt; use std::collections::HashMap; -use common::*; +use std::sync::Arc; +use parking_lot::RwLock; +use heapsize::HeapSizeOf; +use itertools::Itertools; use rlp::*; use hashdb::*; use memorydb::*; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; +use {H256, BaseDataError, UtilError, Bytes}; #[derive(Clone, PartialEq, Eq)] struct RefInfo { @@ -551,12 +555,13 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; + use std::path::Path; use hashdb::{HashDB, DBValue}; use super::*; use super::super::traits::JournalDB; use ethcore_logger::init_log; use kvdb::{DatabaseConfig}; + use {Hashable, H32}; #[test] fn insert_same_in_fork() { diff --git a/util/src/journaldb/mod.rs b/util/src/journaldb/mod.rs index 80ddbf7a1..4f0f2fb1b 100644 --- a/util/src/journaldb/mod.rs +++ b/util/src/journaldb/mod.rs @@ -17,7 +17,7 @@ //! `JournalDB` interface and implementation. use std::{fmt, str}; -use common::*; +use std::sync::Arc; /// Export the journaldb module. pub mod traits; diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index 73a63bd4b..e96430e06 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -17,13 +17,16 @@ //! `JournalDB` over in-memory overlay use std::collections::HashMap; -use common::*; +use std::sync::Arc; +use parking_lot::RwLock; +use heapsize::HeapSizeOf; use rlp::*; use hashdb::*; use memorydb::*; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use kvdb::{KeyValueDB, DBTransaction}; use super::JournalDB; +use {H256, BaseDataError, UtilError, Bytes, H256FastMap}; /// Implementation of the `JournalDB` trait for a disk-backed database with a memory overlay /// and, possibly, latent-removal semantics. @@ -451,12 +454,13 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; + use std::path::Path; use super::*; use hashdb::{HashDB, DBValue}; use ethcore_logger::init_log; use journaldb::JournalDB; use kvdb::Database; + use {H32, Hashable}; fn new_db(path: &Path) -> OverlayRecentDB { let backing = Arc::new(Database::open_default(path.to_str().unwrap()).unwrap()); diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index 772281abd..e38994700 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -17,7 +17,8 @@ //! Disk-backed, ref-counted `JournalDB` implementation. use std::collections::HashMap; -use common::*; +use std::sync::Arc; +use heapsize::HeapSizeOf; use rlp::*; use hashdb::*; use overlaydb::OverlayDB; @@ -25,6 +26,7 @@ use memorydb::MemoryDB; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; +use {UtilError, H256, Bytes}; /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay /// and latent-removal semantics. @@ -211,10 +213,10 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use common::*; use hashdb::{HashDB, DBValue}; use super::*; use super::super::traits::JournalDB; + use {Hashable}; #[test] fn long_history() { diff --git a/util/src/journaldb/traits.rs b/util/src/journaldb/traits.rs index 8a89f1368..1f14e9765 100644 --- a/util/src/journaldb/traits.rs +++ b/util/src/journaldb/traits.rs @@ -16,9 +16,10 @@ //! Disk-backed `HashDB` implementation. -use common::*; +use std::sync::Arc; use hashdb::*; use kvdb::{self, DBTransaction}; +use {Bytes, H256, UtilError}; /// A `HashDB` which can manage a short-term journal potentially containing many forks of mutually /// exclusive actions. diff --git a/util/src/kvdb.rs b/util/src/kvdb.rs index 6692064ed..c231e682d 100644 --- a/util/src/kvdb.rs +++ b/util/src/kvdb.rs @@ -20,14 +20,17 @@ use std::{mem, fs}; use std::collections::{HashMap, BTreeMap}; use std::io::ErrorKind; use std::marker::PhantomData; -use std::path::PathBuf; +use std::path::{PathBuf, Path}; +use parking_lot::{Mutex, MutexGuard, RwLock}; -use common::*; use elastic_array::*; use hashdb::DBValue; use rlp::{UntrustedRlp, RlpType, Compressible}; use rocksdb::{DB, Writable, WriteBatch, WriteOptions, IteratorMode, DBIterator, Options, DBCompactionStyle, BlockBasedOptions, Direction, Cache, Column, ReadOptions}; +use {UtilError, Bytes}; + + #[cfg(target_os = "linux")] use regex::Regex; #[cfg(target_os = "linux")] diff --git a/util/src/lib.rs b/util/src/lib.rs index c2d9c59d3..544f60d39 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -112,7 +112,6 @@ extern crate ethcore_logger; #[macro_use] extern crate log as rlog; -pub mod standard; #[macro_use] pub mod common; pub mod error; @@ -135,7 +134,6 @@ pub mod snappy; pub mod cache; mod timer; -pub use common::*; pub use misc::*; pub use hashdb::*; pub use memorydb::MemoryDB; @@ -146,7 +144,17 @@ pub use trie::{Trie, TrieMut, TrieDB, TrieDBMut, TrieFactory, TrieError, SecTrie pub use semantic_version::*; pub use kvdb::*; pub use timer::*; +pub use error::*; +pub use bytes::*; +pub use vector::*; +pub use sha3::*; +pub use bigint::prelude::*; +pub use bigint::hash; + pub use ansi_term::{Colour, Style}; +pub use heapsize::HeapSizeOf; +pub use itertools::Itertools; +pub use parking_lot::{Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; /// 160-bit integer representing account address pub type Address = H160; diff --git a/util/src/migration/tests.rs b/util/src/migration/tests.rs index 7cd19009a..64f2d976a 100644 --- a/util/src/migration/tests.rs +++ b/util/src/migration/tests.rs @@ -19,12 +19,11 @@ //! are performed in temp sub-directories. use std::collections::BTreeMap; -use common::*; +use std::sync::Arc; +use std::path::{Path, PathBuf}; use migration::{Batch, Config, Error, SimpleMigration, Migration, Manager}; use kvdb::Database; - use devtools::RandomTempPath; -use std::path::PathBuf; fn db_path(path: &Path) -> PathBuf { let mut p = path.to_owned(); diff --git a/util/src/misc.rs b/util/src/misc.rs index 120805f0c..e33b5e857 100644 --- a/util/src/misc.rs +++ b/util/src/misc.rs @@ -16,9 +16,9 @@ //! Diff misc. -use common::*; use rlp::RlpStream; use target_info::Target; +use Bytes; include!(concat!(env!("OUT_DIR"), "/version.rs")); include!(concat!(env!("OUT_DIR"), "/rustc_version.rs")); diff --git a/util/src/standard.rs b/util/src/standard.rs deleted file mode 100644 index cc67b0de5..000000000 --- a/util/src/standard.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (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 . - -//! Std lib global reexports. - -pub use std::path::Path; -pub use std::hash::{Hash, Hasher}; - -pub use std::sync::Arc; - -pub use heapsize::HeapSizeOf; -pub use itertools::Itertools; - -pub use parking_lot::{Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index a8600914c..262a874ea 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -15,13 +15,14 @@ // along with Parity. If not, see . use std::fmt; -use common::*; +use itertools::Itertools; use hashdb::*; use nibbleslice::*; use rlp::*; use super::node::{Node, OwnedNode}; use super::lookup::Lookup; use super::{Trie, TrieItem, TrieError, TrieIterator, Query}; +use {ToPretty, Bytes, H256}; /// A `Trie` implementation using a generic `HashDB` backing database. /// From 2b02651bbfef634c157d06534d3de80d3c93c9c4 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 22:53:52 +0200 Subject: [PATCH 038/119] alway test --all (temporary exclude ipfs and evmjit) --- scripts/cov.sh | 3 +-- scripts/doc.sh | 4 +--- scripts/hook.sh | 4 +--- scripts/targets.sh | 22 ---------------------- test.sh | 3 +-- 5 files changed, 4 insertions(+), 32 deletions(-) delete mode 100755 scripts/targets.sh diff --git a/scripts/cov.sh b/scripts/cov.sh index eae6a4f72..8d618e2c3 100755 --- a/scripts/cov.sh +++ b/scripts/cov.sh @@ -20,8 +20,7 @@ if ! type $KCOV > /dev/null; then exit 1 fi -. ./scripts/targets.sh -RUSTFLAGS="-C link-dead-code" cargo test $TARGETS --no-run || exit $? +RUSTFLAGS="-C link-dead-code" cargo test --all --exclude ipfs --exclude evmjit --no-run || exit $? KCOV_TARGET="target/cov" diff --git a/scripts/doc.sh b/scripts/doc.sh index 657f47567..8174ed5d6 100755 --- a/scripts/doc.sh +++ b/scripts/doc.sh @@ -1,7 +1,5 @@ #!/bin/sh # generate documentation only for partiy and ethcore libraries -. ./scripts/targets.sh - -cargo doc --no-deps --verbose $TARGETS && +cargo doc --no-deps --verbose --all --exclude ipfs --exclude evmjit && echo '' > target/doc/index.html diff --git a/scripts/hook.sh b/scripts/hook.sh index 9b5512ac0..c8977aacf 100755 --- a/scripts/hook.sh +++ b/scripts/hook.sh @@ -1,6 +1,5 @@ #!/bin/sh FILE=./.git/hooks/pre-push -. ./scripts/targets.sh echo "#!/bin/sh\n" > $FILE # Exit on any error @@ -8,7 +7,6 @@ echo "set -e" >> $FILE # Run release build echo "cargo build --features dev" >> $FILE # Build tests -echo "cargo test --no-run --features dev \\" >> $FILE -echo $TARGETS >> $FILE +echo "cargo test --no-run --features dev --all --exclude ipfs --exclude evmjit" >> $FILE echo "" >> $FILE chmod +x $FILE diff --git a/scripts/targets.sh b/scripts/targets.sh deleted file mode 100755 index fb10c43f2..000000000 --- a/scripts/targets.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -export TARGETS=" - -p rlp\ - -p ethash \ - -p ethcore \ - -p ethcore-bigint\ - -p parity-dapps \ - -p parity-rpc \ - -p parity-rpc-client \ - -p rpc-cli \ - -p ethcore-util \ - -p ethcore-network \ - -p ethcore-io \ - -p ethkey \ - -p ethstore \ - -p ethsync \ - -p ethcore-ipc \ - -p ethcore-ipc-tests \ - -p ethcore-ipc-nano \ - -p ethcore-light \ - -p parity" diff --git a/test.sh b/test.sh index 2d0cc2e5f..6eb447970 100755 --- a/test.sh +++ b/test.sh @@ -22,5 +22,4 @@ case $1 in ;; esac -. ./scripts/targets.sh -cargo test -j 8 $OPTIONS --features "$FEATURES" $TARGETS $1 \ +cargo test -j 8 $OPTIONS --features "$FEATURES" --all --exclude ipfs --exclude evmjit $1 \ From 48f28fe29c180a8fe634bd0695650f0b9dc90fe9 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 29 Jul 2017 23:19:33 +0200 Subject: [PATCH 039/119] fixed json_tests --- ethcore/src/json_tests/chain.rs | 2 +- ethcore/src/json_tests/executive.rs | 1 + ethcore/src/json_tests/test_common.rs | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index ccdd7d499..7047c9882 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use super::test_common::*; +use std::sync::Arc; use client::{BlockChainClient, Client, ClientConfig}; use block::Block; use ethereum; diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 0c5a6a90d..495ff3cdb 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Arc; use super::test_common::*; use evm::action_params::ActionParams; use state::{Backend as StateBackend, State, Substate}; diff --git a/ethcore/src/json_tests/test_common.rs b/ethcore/src/json_tests/test_common.rs index f9716d221..fa1078776 100644 --- a/ethcore/src/json_tests/test_common.rs +++ b/ethcore/src/json_tests/test_common.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . pub use util::*; +use std::collections::HashSet; +use std::io::Read; use std::fs::{File, read_dir}; use std::path::Path; use std::ffi::OsString; From 32fafd7a24ad3f0e38b469c11358385517fb6477 Mon Sep 17 00:00:00 2001 From: kaikun213 Date: Mon, 31 Jul 2017 10:58:49 +0200 Subject: [PATCH 040/119] CI fix: Interface shh subscribe params --- js/src/jsonrpc/interfaces/shh.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/src/jsonrpc/interfaces/shh.js b/js/src/jsonrpc/interfaces/shh.js index 87af117fe..7084aa3bf 100644 --- a/js/src/jsonrpc/interfaces/shh.js +++ b/js/src/jsonrpc/interfaces/shh.js @@ -268,7 +268,10 @@ export default { }, subscribe: { desc: 'Open a subscription to a filter.', - params: 'See [shh_newMessageFilter](#shh_newmessagefilter)', + params: [{ + type: Data, + desc: 'See [shh_newMessageFilter](#shh_newmessagefilter)' + }], returns: { type: Quantity, desc: 'Unique subscription identifier' From 003eef982bf1194ee4096f5ce5eee5545529819c Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 31 Jul 2017 12:34:29 +0200 Subject: [PATCH 041/119] Move more params to the common section. (#6134) * move common forks and parameters to common params * port specs over to new format * fix RPC tests --- Cargo.lock | 2 +- ethcore/res/authority_round.json | 2 +- ethcore/res/basic_authority.json | 2 +- ethcore/res/constructor.json | 2 + ethcore/res/ethereum/classic.json | 9 ++-- ethcore/res/ethereum/eip150_test.json | 10 ++-- ethcore/res/ethereum/eip161_test.json | 10 ++-- ethcore/res/ethereum/expanse.json | 10 ++-- ethcore/res/ethereum/foundation.json | 9 ++-- ethcore/res/ethereum/frontier_like_test.json | 10 ++-- ethcore/res/ethereum/frontier_test.json | 10 ++-- ethcore/res/ethereum/homestead_test.json | 10 ++-- ethcore/res/ethereum/kovan.json | 12 ++--- ethcore/res/ethereum/metropolis_test.json | 11 ++-- ethcore/res/ethereum/morden.json | 9 ++-- ethcore/res/ethereum/olympic.json | 10 ++-- ethcore/res/ethereum/ropsten.json | 9 ++-- ethcore/res/ethereum/transition_test.json | 10 ++-- ethcore/res/instant_seal.json | 7 +-- ethcore/res/null.json | 1 + ethcore/res/null_morden.json | 1 + ethcore/res/tendermint.json | 2 +- ethcore/res/validator_contract.json | 2 +- ethcore/res/validator_multi.json | 2 +- ethcore/res/validator_safe_contract.json | 1 + ethcore/src/engines/authority_round/mod.rs | 44 +++++---------- ethcore/src/engines/basic_authority.rs | 9 +--- ethcore/src/engines/instant_seal.rs | 6 +-- ethcore/src/engines/tendermint/mod.rs | 17 +++--- ethcore/src/engines/tendermint/params.rs | 10 ---- ethcore/src/ethereum/ethash.rs | 54 +++++++------------ ethcore/src/miner/miner.rs | 12 ++++- .../tests/test_validator_contract.json | 2 +- ethcore/src/spec/spec.rs | 36 +++++++++++-- ethcore/src/tests/helpers.rs | 6 +-- json/Cargo.toml | 2 +- json/src/hash.rs | 4 +- json/src/lib.rs | 2 +- json/src/maybe.rs | 2 +- json/src/spec/account.rs | 2 +- json/src/spec/authority_round.rs | 22 +------- json/src/spec/basic_authority.rs | 8 +-- json/src/spec/engine.rs | 18 ++----- json/src/spec/ethash.rs | 37 ++----------- json/src/spec/genesis.rs | 4 +- json/src/spec/instant_seal.rs | 53 ------------------ json/src/spec/mod.rs | 2 - json/src/spec/params.rs | 17 +++++- json/src/spec/seal.rs | 3 +- json/src/spec/spec.rs | 6 +-- json/src/spec/tendermint.rs | 20 +------ json/src/spec/validator_set.rs | 3 +- json/src/uint.rs | 4 +- json/src/vm/call.rs | 2 +- rpc/src/v1/tests/eth.rs | 12 ++--- 55 files changed, 224 insertions(+), 358 deletions(-) delete mode 100644 json/src/spec/instant_seal.rs diff --git a/Cargo.lock b/Cargo.lock index 52d0434a5..4b787a656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -777,7 +777,7 @@ name = "ethjson" version = "0.1.0" dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.8.0", + "ethcore-bigint 0.1.3", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/res/authority_round.json b/ethcore/res/authority_round.json index d8014ff25..a56618d1c 100644 --- a/ethcore/res/authority_round.json +++ b/ethcore/res/authority_round.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 2, "validators": { @@ -17,6 +16,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/basic_authority.json b/ethcore/res/basic_authority.json index 6b9f4c0ed..192b48cad 100644 --- a/ethcore/res/basic_authority.json +++ b/ethcore/res/basic_authority.json @@ -3,7 +3,6 @@ "engine": { "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators": { "list": ["0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6"] @@ -12,6 +11,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0100000", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/constructor.json b/ethcore/res/constructor.json index 0be5b3be4..2932ce164 100644 --- a/ethcore/res/constructor.json +++ b/ethcore/res/constructor.json @@ -4,12 +4,14 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2" }, "genesis": { + "gasLimitBoundDivisor": "0x0400", "seal": { "generic": "0x" }, diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 6edfef460..bfd64248e 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": 1150000, "eip150Transition": 2500000, - "eip155Transition": 3000000, "eip160Transition": 3000000, "ecip1010PauseTransition": 3000000, "ecip1010ContinueTransition": 5000000, @@ -24,6 +20,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -31,6 +30,8 @@ "chainID": "0x3d", "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", + "eip155Transition": 3000000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/eip150_test.json b/ethcore/res/ethereum/eip150_test.json index 3091ee27b..22ebf5500 100644 --- a/ethcore/res/ethereum/eip150_test.json +++ b/ethcore/res/ethereum/eip150_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff", @@ -20,12 +16,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffffff", - "eip86Transition": "0x7fffffffffffffff" + "eip86Transition": "0x7fffffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/eip161_test.json b/ethcore/res/ethereum/eip161_test.json index e6e8bf3bb..50d28570b 100644 --- a/ethcore/res/ethereum/eip161_test.json +++ b/ethcore/res/ethereum/eip161_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x0", "eip161abcTransition": "0x0", "eip161dTransition": "0x0", @@ -20,12 +16,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffffff", - "eip86Transition": "0x7fffffffffffffff" + "eip86Transition": "0x7fffffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/ethereum/expanse.json index b7d22ac3e..d79ab6b3c 100644 --- a/ethcore/res/ethereum/expanse.json +++ b/ethcore/res/ethereum/expanse.json @@ -4,19 +4,15 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "difficultyIncrementDivisor": "60", "durationLimit": "0x3C", - "blockReward": "0x6f05b59d3b200000", - "registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21", "homesteadTransition": "0x30d40", "difficultyHardforkTransition": "0x59d9", "difficultyHardforkBoundDivisor": "0x0200", "bombDefuseTransition": "0x30d40", "eip150Transition": "0x927C0", - "eip155Transition": "0x927C0", "eip160Transition": "0x927C0", "eip161abcTransition": "0x927C0", "eip161dTransition": "0x927C0" @@ -24,6 +20,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x6f05b59d3b200000", + "registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -31,7 +30,8 @@ "chainID": "0x2", "subprotocolName": "exp", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x927C0" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index a77b39934..b30453082 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -4,12 +4,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142", "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -132,7 +129,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0x259518", - "eip155Transition": 2675000, "eip160Transition": 2675000, "eip161abcTransition": 2675000, "eip161dTransition": 2675000, @@ -141,12 +137,17 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "forkBlock": "0x1d4c00", "forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb", + "eip155Transition": 2675000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index fde04f6b5..0f4b8850f 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -3,12 +3,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -131,7 +128,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -139,12 +135,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index 6761c79f3..802a77f8d 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index 25b061857..557a48a64 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 7cdb79e16..ca7638e33 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -4,10 +4,7 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x400", - "registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3", "stepDuration": "4", - "blockReward": "0x4563918244F40000", "validators" : { "list": [ "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", @@ -25,16 +22,19 @@ ] }, "validateScoreTransition": 1000000, - "eip155Transition": 1000000, "validateStepTransition": 1500000 } } }, "params": { - "maximumExtraDataSize": "0x20", + "gasLimitBoundDivisor": "0x400", + "registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3", + "blockReward": "0x4563918244F40000", + "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2A", - "validateReceiptsTransition" : 1000000 + "validateReceiptsTransition" : 1000000, + "eip155Transition": 1000000 }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/metropolis_test.json b/ethcore/res/ethereum/metropolis_test.json index 76189e731..a452e5a80 100644 --- a/ethcore/res/ethereum/metropolis_test.json +++ b/ethcore/res/ethereum/metropolis_test.json @@ -3,15 +3,12 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x0", "eip160Transition": "0x0", "eip161abcTransition": "0x0", "eip161dTransition": "0x0", @@ -20,6 +17,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -27,7 +27,8 @@ "eip98Transition": "0x0", "eip86Transition": "0x0", "eip140Transition": "0x0", - "eip210Transition": "0x0" + "eip210Transition": "0x0", + "eip155Transition": "0x0" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index 495849daf..f316fdf5f 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d", "homesteadTransition": 494000, "eip150Transition": 1783000, - "eip155Transition": 1915000, "eip160Transition": 1915000, "ecip1010PauseTransition": 1915000, "ecip1010ContinueTransition": 3415000, @@ -23,6 +19,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d", "accountStartNonce": "0x0100000", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -30,6 +29,8 @@ "chainID": "0x3e", "forkBlock": "0x1b34d8", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", + "eip155Transition": 1915000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index 3d2e7baf9..c73dcb815 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x08", - "blockReward": "0x14D1120D7B160000", - "registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050", "homesteadTransition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x14D1120D7B160000", + "registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x0400", "minGasLimit": "125000", "networkID" : "0x0", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 1e350d636..1706c433b 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2", "homesteadTransition": 0, "eip150Transition": 0, - "eip155Transition": 10, "eip160Transition": 10, "eip161abcTransition": 10, "eip161dTransition": 10, @@ -21,12 +17,17 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x3", "forkBlock": 641350, "forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb", + "eip155Transition": 10, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/transition_test.json b/ethcore/res/ethereum/transition_test.json index 7709ba015..409210a76 100644 --- a/ethcore/res/ethereum/transition_test.json +++ b/ethcore/res/ethereum/transition_test.json @@ -3,12 +3,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x5", "daoHardforkTransition": "0x8", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -131,7 +128,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0xa", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -139,12 +135,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index c791b9a2d..f59feb0bd 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -1,13 +1,10 @@ { "name": "DevelopmentChain", "engine": { - "instantSeal": { - "params": { - "registrar": "0x0000000000000000000000000000000000000005" - } - } + "instantSeal": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/null.json b/ethcore/res/null.json index ffb0ea061..97ce1afc5 100644 --- a/ethcore/res/null.json +++ b/ethcore/res/null.json @@ -4,6 +4,7 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/null_morden.json b/ethcore/res/null_morden.json index 96d804b5b..b615cdc29 100644 --- a/ethcore/res/null_morden.json +++ b/ethcore/res/null_morden.json @@ -4,6 +4,7 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/tendermint.json b/ethcore/res/tendermint.json index 642f5b385..e7fa69ea0 100644 --- a/ethcore/res/tendermint.json +++ b/ethcore/res/tendermint.json @@ -3,7 +3,6 @@ "engine": { "tendermint": { "params": { - "gasLimitBoundDivisor": "0x0400", "validators" : { "list": [ "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1", @@ -18,6 +17,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_contract.json b/ethcore/res/validator_contract.json index 3faec7665..9d007ac23 100644 --- a/ethcore/res/validator_contract.json +++ b/ethcore/res/validator_contract.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 2, "validators": { @@ -14,6 +13,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_multi.json b/ethcore/res/validator_multi.json index 5d51b73da..9eba2d5ba 100644 --- a/ethcore/res/validator_multi.json +++ b/ethcore/res/validator_multi.json @@ -3,7 +3,6 @@ "engine": { "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators": { "multi": { @@ -15,6 +14,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_safe_contract.json b/ethcore/res/validator_safe_contract.json index 3f5241c96..7845c898d 100644 --- a/ethcore/res/validator_safe_contract.json +++ b/ethcore/res/validator_safe_contract.json @@ -12,6 +12,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 3210368db..ebe7cacea 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -47,22 +47,14 @@ mod finality; /// `AuthorityRound` params. pub struct AuthorityRoundParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Time to wait before next block or authority switching. pub step_duration: Duration, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, /// Starting step, pub start_step: Option, /// Valid validators. pub validators: Box, /// Chain score validation transition block. pub validate_score_transition: u64, - /// Number of first block where EIP-155 rules are validated. - pub eip155_transition: u64, /// Monotonic step validation transition block. pub validate_step_transition: u64, /// Immediate transitions. @@ -72,14 +64,10 @@ pub struct AuthorityRoundParams { impl From for AuthorityRoundParams { fn from(p: ethjson::spec::AuthorityRoundParams) -> Self { AuthorityRoundParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), step_duration: Duration::from_secs(p.step_duration.into()), validators: new_validator_set(p.validators), - block_reward: p.block_reward.map_or_else(U256::zero, Into::into), - registrar: p.registrar.map_or_else(Address::new, Into::into), start_step: p.start_step.map(Into::into), validate_score_transition: p.validate_score_transition.map_or(0, Into::into), - eip155_transition: p.eip155_transition.map_or(0, Into::into), validate_step_transition: p.validate_step_transition.map_or(0, Into::into), immediate_transitions: p.immediate_transitions.unwrap_or(false), } @@ -214,9 +202,6 @@ impl EpochManager { /// Engine using `AuthorityRound` proof-of-authority BFT consensus. pub struct AuthorityRound { params: CommonParams, - gas_limit_bound_divisor: U256, - block_reward: U256, - registrar: Address, builtins: BTreeMap, transition_service: IoService<()>, step: Arc, @@ -225,7 +210,6 @@ pub struct AuthorityRound { signer: RwLock, validators: Box, validate_score_transition: u64, - eip155_transition: u64, validate_step_transition: u64, epoch_manager: Mutex, immediate_transitions: bool, @@ -362,9 +346,6 @@ impl AuthorityRound { let engine = Arc::new( AuthorityRound { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, - block_reward: our_params.block_reward, - registrar: our_params.registrar, builtins: builtins, transition_service: IoService::<()>::start()?, step: Arc::new(Step { @@ -377,7 +358,6 @@ impl AuthorityRound { signer: Default::default(), validators: our_params.validators, validate_score_transition: our_params.validate_score_transition, - eip155_transition: our_params.eip155_transition, validate_step_transition: our_params.validate_step_transition, epoch_manager: Mutex::new(EpochManager::blank()), immediate_transitions: our_params.immediate_transitions, @@ -433,7 +413,9 @@ impl Engine for AuthorityRound { fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.registrar.hex()] } + fn additional_params(&self) -> HashMap { + hash_map!["registrar".to_owned() => self.params().registrar.hex()] + } fn builtins(&self) -> &BTreeMap { &self.builtins } @@ -461,7 +443,7 @@ impl Engine for AuthorityRound { header.set_difficulty(new_difficulty); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { @@ -564,7 +546,8 @@ impl Engine for AuthorityRound { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { let fields = block.fields_mut(); // Bestow block reward - let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) + let reward = self.params().block_reward; + let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty) .map_err(::error::Error::from) .and_then(|_| fields.state.commit()); // Commit state so that we can actually figure out the state root. @@ -629,7 +612,7 @@ impl Engine for AuthorityRound { } } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { @@ -819,7 +802,7 @@ impl Engine for AuthorityRound { t.check_low_s()?; if let Some(n) = t.network_id() { - if header.number() >= self.eip155_transition && n != self.params().chain_id { + if header.number() >= self.params().eip155_transition && n != self.params().chain_id { return Err(TransactionError::InvalidNetworkId.into()); } } @@ -1014,18 +997,19 @@ mod tests { fn reports_skipped() { let last_benign = Arc::new(AtomicUsize::new(0)); let params = AuthorityRoundParams { - gas_limit_bound_divisor: U256::from_str("400").unwrap(), step_duration: Default::default(), - block_reward: Default::default(), - registrar: Default::default(), start_step: Some(1), validators: Box::new(TestSet::new(Default::default(), last_benign.clone())), validate_score_transition: 0, validate_step_transition: 0, - eip155_transition: 0, immediate_transitions: true, }; - let aura = AuthorityRound::new(Default::default(), params, Default::default()).unwrap(); + + let aura = { + let mut c_params = ::spec::CommonParams::default(); + c_params.gas_limit_bound_divisor = 5.into(); + AuthorityRound::new(c_params, params, Default::default()).unwrap() + }; let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&1usize).into_vec()]); diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 68759131d..360a32ddd 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -35,8 +35,6 @@ use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; /// `BasicAuthority` params. #[derive(Debug, PartialEq)] pub struct BasicAuthorityParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Valid signatories. pub validators: ethjson::spec::ValidatorSet, } @@ -44,7 +42,6 @@ pub struct BasicAuthorityParams { impl From for BasicAuthorityParams { fn from(p: ethjson::spec::BasicAuthorityParams) -> Self { BasicAuthorityParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), validators: p.validators, } } @@ -80,7 +77,6 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err /// Engine using `BasicAuthority`, trivial proof-of-authority consensus. pub struct BasicAuthority { params: CommonParams, - gas_limit_bound_divisor: U256, builtins: BTreeMap, signer: RwLock, validators: Box, @@ -91,7 +87,6 @@ impl BasicAuthority { pub fn new(params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap) -> Self { BasicAuthority { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, builtins: builtins, validators: new_validator_set(our_params.validators), signer: Default::default(), @@ -119,7 +114,7 @@ impl Engine for BasicAuthority { header.set_difficulty(parent.difficulty().clone()); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { @@ -172,7 +167,7 @@ impl Engine for BasicAuthority { if header.difficulty() != parent.difficulty() { return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() }))) } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 38834622c..6e9988521 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -24,16 +24,14 @@ use block::ExecutedBlock; /// An engine which does not provide any consensus mechanism, just seals blocks internally. pub struct InstantSeal { params: CommonParams, - registrar: Address, builtins: BTreeMap, } impl InstantSeal { /// Returns new instance of InstantSeal with default VM Factory - pub fn new(params: CommonParams, registrar: Address, builtins: BTreeMap) -> Self { + pub fn new(params: CommonParams, builtins: BTreeMap) -> Self { InstantSeal { params: params, - registrar: registrar, builtins: builtins, } } @@ -49,7 +47,7 @@ impl Engine for InstantSeal { } fn additional_params(&self) -> HashMap { - hash_map!["registrar".to_owned() => self.registrar.hex()] + hash_map!["registrar".to_owned() => self.params().registrar.hex()] } fn builtins(&self) -> &BTreeMap { diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 453e8f9fb..1f3dbeb4e 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -71,12 +71,9 @@ pub type BlockHash = H256; /// Engine using `Tendermint` consensus algorithm, suitable for EVM chain. pub struct Tendermint { params: CommonParams, - gas_limit_bound_divisor: U256, builtins: BTreeMap, step_service: IoService, client: RwLock>>, - block_reward: U256, - registrar: Address, /// Blockchain height. height: AtomicUsize, /// Consensus view. @@ -166,12 +163,9 @@ impl Tendermint { let engine = Arc::new( Tendermint { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, builtins: builtins, client: RwLock::new(None), step_service: IoService::::start()?, - block_reward: our_params.block_reward, - registrar: our_params.registrar, height: AtomicUsize::new(1), view: AtomicUsize::new(0), step: RwLock::new(Step::Propose), @@ -446,7 +440,9 @@ impl Engine for Tendermint { fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.registrar.hex()] } + fn additional_params(&self) -> HashMap { + hash_map!["registrar".to_owned() => self.params().registrar.hex()] + } fn builtins(&self) -> &BTreeMap { &self.builtins } @@ -471,7 +467,7 @@ impl Engine for Tendermint { header.set_difficulty(new_difficulty); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { @@ -545,7 +541,8 @@ impl Engine for Tendermint { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{ let fields = block.fields_mut(); // Bestow block reward - let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) + let reward = self.params().block_reward; + let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty) .map_err(::error::Error::from) .and_then(|_| fields.state.commit()); // Commit state so that we can actually figure out the state root. @@ -617,7 +614,7 @@ impl Engine for Tendermint { self.check_above_threshold(origins.len())? } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { diff --git a/ethcore/src/engines/tendermint/params.rs b/ethcore/src/engines/tendermint/params.rs index 16b47a0fb..7ff3d697f 100644 --- a/ethcore/src/engines/tendermint/params.rs +++ b/ethcore/src/engines/tendermint/params.rs @@ -17,7 +17,6 @@ //! Tendermint specific parameters. use ethjson; -use util::{U256, Address}; use time::Duration; use super::super::validator_set::{ValidatorSet, new_validator_set}; use super::super::transition::Timeouts; @@ -25,16 +24,10 @@ use super::Step; /// `Tendermint` params. pub struct TendermintParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// List of validators. pub validators: Box, /// Timeout durations for different steps. pub timeouts: TendermintTimeouts, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, } /// Base timeout of each step in ms. @@ -81,7 +74,6 @@ impl From for TendermintParams { fn from(p: ethjson::spec::TendermintParams) -> Self { let dt = TendermintTimeouts::default(); TendermintParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), validators: new_validator_set(p.validators), timeouts: TendermintTimeouts { propose: p.timeout_propose.map_or(dt.propose, to_duration), @@ -89,8 +81,6 @@ impl From for TendermintParams { precommit: p.timeout_precommit.map_or(dt.precommit, to_duration), commit: p.timeout_commit.map_or(dt.commit, to_duration), }, - block_reward: p.block_reward.map_or_else(U256::zero, Into::into), - registrar: p.registrar.map_or_else(Address::new, Into::into), } } } diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 1fbd711c9..ef6bb64cd 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -41,8 +41,6 @@ const SNAPSHOT_BLOCKS: u64 = 30000; /// Ethash params. #[derive(Debug, PartialEq)] pub struct EthashParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Minimum difficulty. pub minimum_difficulty: U256, /// Difficulty bound divisor. @@ -53,10 +51,6 @@ pub struct EthashParams { pub metropolis_difficulty_increment_divisor: u64, /// Block duration. pub duration_limit: u64, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, /// Homestead transition block number. pub homestead_transition: u64, /// DAO hard-fork transition block (X). @@ -75,8 +69,6 @@ pub struct EthashParams { pub eip100b_transition: u64, /// Number of first block where EIP-150 rules begin. pub eip150_transition: u64, - /// Number of first block where EIP-155 rules begin. - pub eip155_transition: u64, /// Number of first block where EIP-160 rules begin. pub eip160_transition: u64, /// Number of first block where EIP-161.abc begin. @@ -104,14 +96,11 @@ pub struct EthashParams { impl From for EthashParams { fn from(p: ethjson::spec::EthashParams) -> Self { EthashParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), minimum_difficulty: p.minimum_difficulty.into(), difficulty_bound_divisor: p.difficulty_bound_divisor.into(), difficulty_increment_divisor: p.difficulty_increment_divisor.map_or(10, Into::into), metropolis_difficulty_increment_divisor: p.metropolis_difficulty_increment_divisor.map_or(9, Into::into), duration_limit: p.duration_limit.map_or(0, Into::into), - block_reward: p.block_reward.into(), - registrar: p.registrar.map_or_else(Address::new, Into::into), homestead_transition: p.homestead_transition.map_or(0, Into::into), dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into), dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::new, Into::into), @@ -121,7 +110,6 @@ impl From for EthashParams { bomb_defuse_transition: p.bomb_defuse_transition.map_or(u64::max_value(), Into::into), eip100b_transition: p.eip100b_transition.map_or(u64::max_value(), Into::into), eip150_transition: p.eip150_transition.map_or(0, Into::into), - eip155_transition: p.eip155_transition.map_or(0, Into::into), eip160_transition: p.eip160_transition.map_or(0, Into::into), eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into), eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into), @@ -185,7 +173,7 @@ impl Engine for Arc { fn seal_fields(&self) -> usize { 2 } fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.ethash_params.registrar.hex()] } + fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.params().registrar.hex()] } fn builtins(&self) -> &BTreeMap { &self.builtins @@ -216,7 +204,7 @@ impl Engine for Arc { } fn signing_network_id(&self, env_info: &EnvInfo) -> Option { - if env_info.number >= self.ethash_params.eip155_transition { + if env_info.number >= self.params().eip155_transition { Some(self.params().chain_id) } else { None @@ -231,7 +219,7 @@ impl Engine for Arc { } let gas_limit = { let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.ethash_params.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into(); let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into(); let gas_limit = if gas_limit < gas_floor_target { @@ -284,7 +272,7 @@ impl Engine for Arc { /// Apply the block reward on finalisation of the block. /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { - let reward = self.ethash_params.block_reward; + let reward = self.params().block_reward; let fields = block.fields_mut(); let eras_rounds = self.ethash_params.ecip1017_era_rounds; let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number()); @@ -387,7 +375,7 @@ impl Engine for Arc { if header.difficulty() != &expected_difficulty { return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() }))) } - let gas_limit_divisor = self.ethash_params.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let parent_gas_limit = *parent.gas_limit(); let min_gas = parent_gas_limit - parent_gas_limit / gas_limit_divisor; let max_gas = parent_gas_limit + parent_gas_limit / gas_limit_divisor; @@ -406,7 +394,7 @@ impl Engine for Arc { } let check_low_s = header.number() >= self.ethash_params.homestead_transition; - let network_id = if header.number() >= self.ethash_params.eip155_transition { Some(self.params().chain_id) } else { None }; + let network_id = if header.number() >= self.params().eip155_transition { Some(self.params().chain_id) } else { None }; t.verify_basic(check_low_s, network_id, false)?; Ok(()) } @@ -809,36 +797,32 @@ mod tests { #[test] fn has_valid_ecip1017_eras_block_reward() { - let ethparams = EthashParams { - // see ethcore/res/ethereum/classic.json - ecip1017_era_rounds: 5000000, - block_reward: U256::from_str("4563918244F40000").unwrap(), - ..get_default_ethash_params() - }; - let eras_rounds = ethparams.ecip1017_era_rounds; - let reward = ethparams.block_reward; + let eras_rounds = 5000000; + + let start_reward: U256 = "4563918244F40000".parse().unwrap(); + let block_number = 0; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(0, eras); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 5000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(0, eras); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 10000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(1, eras); assert_eq!(U256::from_str("3782DACE9D900000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 20000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(3, eras); assert_eq!(U256::from_str("2386F26FC1000000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 80000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(15, eras); assert_eq!(U256::from_str("271000000000000").unwrap(), reward); } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 80971355b..f193c4cf9 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1112,6 +1112,8 @@ impl MinerService for Miner { /// Prepare the block and work if the Engine does not seal internally. fn update_sealing(&self, chain: &MiningBlockChainClient) { trace!(target: "miner", "update_sealing"); + const NO_NEW_CHAIN_WITH_FORKS: &str = "Your chain specification contains one or more hard forks which are required to be \ + on by default. Please remove these forks and start your chain again."; if self.requires_reseal(chain.chain_info().best_block_number) { // -------------------------------------------------------------------------- @@ -1120,6 +1122,14 @@ impl MinerService for Miner { // -------------------------------------------------------------------------- trace!(target: "miner", "update_sealing: preparing a block"); let (block, original_work_hash) = self.prepare_block(chain); + + // refuse to seal the first block of the chain if it contains hard forks + // which should be on by default. + if block.block().fields().header.number() == 1 && self.engine.params().contains_bugfix_hard_fork() { + warn!("{}", NO_NEW_CHAIN_WITH_FORKS); + return; + } + match self.engine.seals_internally() { Some(true) => { trace!(target: "miner", "update_sealing: engine indicates internal sealing"); @@ -1127,11 +1137,11 @@ impl MinerService for Miner { trace!(target: "miner", "update_sealing: imported internally sealed block"); } }, + Some(false) => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now"), None => { trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work"); self.prepare_work(block, original_work_hash) }, - _ => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now") } } } diff --git a/ethcore/src/snapshot/tests/test_validator_contract.json b/ethcore/src/snapshot/tests/test_validator_contract.json index e2485fe82..b0aeb8785 100644 --- a/ethcore/src/snapshot/tests/test_validator_contract.json +++ b/ethcore/src/snapshot/tests/test_validator_contract.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 0, "validators": { @@ -17,6 +16,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 7d3900f2c..959793e4c 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -39,7 +39,12 @@ use trace::{NoopTracer, NoopVMTracer}; use evm::CallType; use util::*; -/// Parameters common to all engines. +/// Parameters common to ethereum-like blockchains. +/// NOTE: when adding bugfix hard-fork parameters, +/// add to `contains_bugfix_hard_fork` +/// +/// we define a "bugfix" hard fork as any hard fork which +/// you would put on-by-default in a new chain. #[derive(Debug, PartialEq, Default)] #[cfg_attr(test, derive(Clone))] pub struct CommonParams { @@ -59,8 +64,10 @@ pub struct CommonParams { pub fork_block: Option<(BlockNumber, H256)>, /// Number of first block where EIP-98 rules begin. pub eip98_transition: BlockNumber, + /// Number of first block where EIP-155 rules begin. + pub eip155_transition: BlockNumber, /// Validate block receipts root. - pub validate_receipts_transition: u64, + pub validate_receipts_transition: BlockNumber, /// Number of first block where EIP-86 (Metropolis) rules begin. pub eip86_transition: BlockNumber, /// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin. @@ -85,6 +92,12 @@ pub struct CommonParams { pub remove_dust_contracts: bool, /// Wasm support pub wasm: bool, + /// Gas limit bound divisor (how much gas limit can change per block) + pub gas_limit_bound_divisor: U256, + /// Block reward in wei. + pub block_reward: U256, + /// Registrar contract address. + pub registrar: Address, } impl CommonParams { @@ -111,6 +124,19 @@ impl CommonParams { }; } } + + /// Whether these params contain any bug-fix hard forks. + pub fn contains_bugfix_hard_fork(&self) -> bool { + self.eip98_transition != 0 && + self.eip155_transition != 0 && + self.validate_receipts_transition != 0 && + self.eip86_transition != 0 && + self.eip140_transition != 0 && + self.eip210_transition != 0 && + self.eip211_transition != 0 && + self.eip214_transition != 0 && + self.dust_protection_transition != 0 + } } impl From for CommonParams { @@ -124,6 +150,7 @@ impl From for CommonParams { min_gas_limit: p.min_gas_limit.into(), fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None }, eip98_transition: p.eip98_transition.map_or(0, Into::into), + eip155_transition: p.eip155_transition.map_or(0, Into::into), validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), eip86_transition: p.eip86_transition.map_or(BlockNumber::max_value(), Into::into), eip140_transition: p.eip140_transition.map_or(BlockNumber::max_value(), Into::into), @@ -139,6 +166,9 @@ impl From for CommonParams { nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false), wasm: p.wasm.unwrap_or(false), + gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), + block_reward: p.block_reward.map_or_else(U256::zero, Into::into), + registrar: p.registrar.map_or_else(Address::new, Into::into), } } } @@ -242,7 +272,7 @@ impl Spec { ) -> Arc { match engine_spec { ethjson::spec::Engine::Null => Arc::new(NullEngine::new(params, builtins)), - ethjson::spec::Engine::InstantSeal(instant) => Arc::new(InstantSeal::new(params, instant.params.registrar.map_or_else(Address::new, Into::into), builtins)), + ethjson::spec::Engine::InstantSeal => Arc::new(InstantSeal::new(params, builtins)), ethjson::spec::Engine::Ethash(ethash) => Arc::new(ethereum::Ethash::new(cache_dir, params, From::from(ethash.params), builtins)), ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(params, From::from(basic_authority.params), builtins)), ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(params, From::from(authority_round.params), builtins).expect("Failed to start AuthorityRound consensus engine."), diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index f8e412073..21dc16fa8 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -394,16 +394,13 @@ pub fn get_bad_state_dummy_block() -> Bytes { create_test_block(&block_header) } -pub fn get_default_ethash_params() -> EthashParams{ +pub fn get_default_ethash_params() -> EthashParams { EthashParams { - gas_limit_bound_divisor: U256::from(1024), minimum_difficulty: U256::from(131072), difficulty_bound_divisor: U256::from(2048), difficulty_increment_divisor: 10, metropolis_difficulty_increment_divisor: 9, duration_limit: 13, - block_reward: U256::from(0), - registrar: "0000000000000000000000000000000000000001".into(), homestead_transition: 1150000, dao_hardfork_transition: u64::max_value(), dao_hardfork_beneficiary: "0000000000000000000000000000000000000001".into(), @@ -413,7 +410,6 @@ pub fn get_default_ethash_params() -> EthashParams{ bomb_defuse_transition: u64::max_value(), eip100b_transition: u64::max_value(), eip150_transition: u64::max_value(), - eip155_transition: u64::max_value(), eip160_transition: u64::max_value(), eip161abc_transition: u64::max_value(), eip161d_transition: u64::max_value(), diff --git a/json/Cargo.toml b/json/Cargo.toml index 81af58ac7..dbc365a1d 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -ethcore-util = { path = "../util" } +ethcore-bigint = { path = "../util/bigint" } rustc-hex = "1.0" serde = "1.0" serde_json = "1.0" diff --git a/json/src/hash.rs b/json/src/hash.rs index 64da93e1c..32c707d5b 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -21,7 +21,7 @@ use std::fmt; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::de::{Error, Visitor}; use rustc_hex::ToHex; -use util::hash::{H64 as Hash64, H160 as Hash160, H256 as Hash256, H520 as Hash520, H2048 as Hash2048}; +use bigint::hash::{H64 as Hash64, H160 as Hash160, H256 as Hash256, H520 as Hash520, H2048 as Hash2048}; macro_rules! impl_hash { @@ -99,7 +99,7 @@ impl_hash!(Bloom, Hash2048); mod test { use std::str::FromStr; use serde_json; - use util::hash; + use bigint::hash; use hash::H256; #[test] diff --git a/json/src/lib.rs b/json/src/lib.rs index c03b9f439..4af7384a0 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -17,7 +17,7 @@ extern crate rustc_hex; extern crate serde; extern crate serde_json; -extern crate ethcore_util as util; +extern crate ethcore_bigint as bigint; #[macro_use] extern crate serde_derive; pub mod hash; diff --git a/json/src/maybe.rs b/json/src/maybe.rs index 075aaefbd..b799b7ef6 100644 --- a/json/src/maybe.rs +++ b/json/src/maybe.rs @@ -68,7 +68,7 @@ impl Into> for MaybeEmpty { mod tests { use std::str::FromStr; use serde_json; - use util::hash; + use bigint::hash; use hash::H256; use maybe::MaybeEmpty; diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs index 2c98fd3f1..32d5ec42d 100644 --- a/json/src/spec/account.rs +++ b/json/src/spec/account.rs @@ -50,7 +50,7 @@ mod tests { use std::collections::BTreeMap; use serde_json; use spec::account::Account; - use util::U256; + use bigint::prelude::U256; use uint::Uint; use bytes::Bytes; diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 0fdbfbfb3..2d7d64086 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -17,25 +17,16 @@ //! Authority params deserialization. use uint::Uint; -use hash::Address; use super::ValidatorSet; /// Authority params deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct AuthorityRoundParams { - /// Gas limit divisor. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// Block duration. #[serde(rename="stepDuration")] pub step_duration: Uint, /// Valid authorities pub validators: ValidatorSet, - /// Block reward. - #[serde(rename="blockReward")] - pub block_reward: Option, - /// Address of the registrar contract. - pub registrar: Option
, /// Starting step. Determined automatically if not specified. /// To be used for testing only. #[serde(rename="startStep")] @@ -43,9 +34,6 @@ pub struct AuthorityRoundParams { /// Block at which score validation should start. #[serde(rename="validateScoreTransition")] pub validate_score_transition: Option, - /// See main AuthorityRoundParams docs. - #[serde(rename="eip155Transition")] - pub eip155_transition: Option, /// Block from which monotonic steps start. #[serde(rename="validateStepTransition")] pub validate_step_transition: Option, @@ -63,9 +51,8 @@ pub struct AuthorityRound { #[cfg(test)] mod tests { + use bigint::prelude::{U256, H160}; use uint::Uint; - use util::U256; - use util::H160; use serde_json; use hash::Address; use spec::validator_set::ValidatorSet; @@ -75,26 +62,19 @@ mod tests { fn authority_round_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": "0x02", "validators": { "list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] }, - "blockReward": "0x50", "startStep" : 24, - "eip155Transition": "0x42", "validateStepTransition": 150 } }"#; let deserialized: AuthorityRound = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.gas_limit_bound_divisor, Uint(U256::from(0x0400))); assert_eq!(deserialized.params.step_duration, Uint(U256::from(0x02))); assert_eq!(deserialized.params.validators, ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))])); - assert_eq!(deserialized.params.block_reward, Some(Uint(U256::from(0x50)))); - assert!(deserialized.params.registrar.is_none()); assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24)))); - assert_eq!(deserialized.params.eip155_transition, Some(Uint(U256::from(0x42)))); assert_eq!(deserialized.params.immediate_transitions, None); } } diff --git a/json/src/spec/basic_authority.rs b/json/src/spec/basic_authority.rs index 01fe8f088..d8182a990 100644 --- a/json/src/spec/basic_authority.rs +++ b/json/src/spec/basic_authority.rs @@ -22,9 +22,6 @@ use super::ValidatorSet; /// Authority params deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct BasicAuthorityParams { - /// Gas limit divisor. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// Block duration. #[serde(rename="durationLimit")] pub duration_limit: Uint, @@ -43,9 +40,8 @@ pub struct BasicAuthority { mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::{U256, H160}; use hash::Address; - use util::hash::H160; use spec::basic_authority::BasicAuthority; use spec::validator_set::ValidatorSet; @@ -53,7 +49,6 @@ mod tests { fn basic_authority_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators" : { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] @@ -63,7 +58,6 @@ mod tests { let deserialized: BasicAuthority = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.gas_limit_bound_divisor, Uint(U256::from(0x0400))); assert_eq!(deserialized.params.duration_limit, Uint(U256::from(0x0d))); let vs = ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]); assert_eq!(deserialized.params.validators, vs); diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index 5706b0680..8b487041e 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -16,7 +16,7 @@ //! Engine deserialization. -use super::{Ethash, InstantSeal, BasicAuthority, AuthorityRound, Tendermint}; +use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint}; /// Engine deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -26,7 +26,7 @@ pub enum Engine { Null, /// Instantly sealing engine. #[serde(rename="instantSeal")] - InstantSeal(InstantSeal), + InstantSeal, /// Ethash engine. Ethash(Ethash), /// BasicAuthority engine. @@ -55,23 +55,21 @@ mod tests { assert_eq!(Engine::Null, deserialized); let s = r#"{ - "instantSeal": { "params": {} } + "instantSeal": null }"#; let deserialized: Engine = serde_json::from_str(s).unwrap(); match deserialized { - Engine::InstantSeal(_) => {}, // instant seal is unit tested in its own file. + Engine::InstantSeal => {}, // instant seal is unit tested in its own file. _ => assert!(false), }; let s = r#"{ "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition" : "0x", "daoHardforkTransition": "0xffffffffffffffff", @@ -90,7 +88,6 @@ mod tests { let s = r#"{ "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators" : { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] @@ -107,14 +104,11 @@ mod tests { let s = r#"{ "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": "0x02", "validators": { "list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] }, - "blockReward": "0x50", "startStep" : 24, - "eip155Transition": "0x42", "validateStepTransition": 150 } } @@ -128,11 +122,9 @@ mod tests { let s = r#"{ "tendermint": { "params": { - "gasLimitBoundDivisor": "0x0400", "validators": { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] - }, - "blockReward": "0x50" + } } } }"#; diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index f3391e067..784a9d477 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -22,9 +22,6 @@ use hash::Address; /// Deserializable doppelganger of EthashParams. #[derive(Debug, PartialEq, Deserialize)] pub struct EthashParams { - /// See main EthashParams docs. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// See main EthashParams docs. #[serde(rename="minimumDifficulty")] pub minimum_difficulty: Uint, @@ -40,11 +37,6 @@ pub struct EthashParams { /// See main EthashParams docs. #[serde(rename="durationLimit")] pub duration_limit: Option, - /// See main EthashParams docs. - #[serde(rename="blockReward")] - pub block_reward: Uint, - /// See main EthashParams docs. - pub registrar: Option
, /// See main EthashParams docs. #[serde(rename="homesteadTransition")] @@ -78,10 +70,6 @@ pub struct EthashParams { #[serde(rename="eip150Transition")] pub eip150_transition: Option, - /// See main EthashParams docs. - #[serde(rename="eip155Transition")] - pub eip155_transition: Option, - /// See main EthashParams docs. #[serde(rename="eip160Transition")] pub eip160_transition: Option, @@ -136,21 +124,17 @@ pub struct Ethash { mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::{H160, U256}; use hash::Address; - use util::hash::H160; use spec::ethash::{Ethash, EthashParams}; #[test] fn ethash_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x42", "daoHardforkTransition": "0x08", "daoHardforkBeneficiary": "0xabcabcabcabcabcabcabcabcabcabcabcabcabca", @@ -181,7 +165,6 @@ mod tests { "bombDefuseTransition": "0x41", "eip100bTransition": "0x42", "eip150Transition": "0x43", - "eip155Transition": "0x44", "eip160Transition": "0x45", "eip161abcTransition": "0x46", "eip161dTransition": "0x47" @@ -190,16 +173,13 @@ mod tests { let deserialized: Ethash = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized, Ethash{ + assert_eq!(deserialized, Ethash { params: EthashParams{ - gas_limit_bound_divisor: Uint(U256::from(0x0400)), minimum_difficulty: Uint(U256::from(0x020000)), difficulty_bound_divisor: Uint(U256::from(0x0800)), difficulty_increment_divisor: None, metropolis_difficulty_increment_divisor: None, duration_limit: Some(Uint(U256::from(0x0d))), - block_reward: Uint(U256::from(0x4563918244F40000u64)), - registrar: Some(Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))), homestead_transition: Some(Uint(U256::from(0x42))), dao_hardfork_transition: Some(Uint(U256::from(0x08))), dao_hardfork_beneficiary: Some(Address(H160::from("0xabcabcabcabcabcabcabcabcabcabcabcabcabca"))), @@ -230,7 +210,6 @@ mod tests { bomb_defuse_transition: Some(Uint(U256::from(0x41))), eip100b_transition: Some(Uint(U256::from(0x42))), eip150_transition: Some(Uint(U256::from(0x43))), - eip155_transition: Some(Uint(U256::from(0x44))), eip160_transition: Some(Uint(U256::from(0x45))), eip161abc_transition: Some(Uint(U256::from(0x46))), eip161d_transition: Some(Uint(U256::from(0x47))), @@ -250,24 +229,19 @@ mod tests { fn ethash_deserialization_missing_optionals() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", - "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", - "blockReward": "0x4563918244F40000" + "minimumDifficulty": "0x020000" } }"#; let deserialized: Ethash = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized, Ethash{ - params: EthashParams{ - gas_limit_bound_divisor: Uint(U256::from(0x0400)), + assert_eq!(deserialized, Ethash { + params: EthashParams { minimum_difficulty: Uint(U256::from(0x020000)), difficulty_bound_divisor: Uint(U256::from(0x0800)), difficulty_increment_divisor: None, metropolis_difficulty_increment_divisor: None, duration_limit: None, - block_reward: Uint(U256::from(0x4563918244F40000u64)), - registrar: None, homestead_transition: None, dao_hardfork_transition: None, dao_hardfork_beneficiary: None, @@ -277,7 +251,6 @@ mod tests { bomb_defuse_transition: None, eip100b_transition: None, eip150_transition: None, - eip155_transition: None, eip160_transition: None, eip161abc_transition: None, eip161d_transition: None, diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs index 120df4fc1..98bc75c69 100644 --- a/json/src/spec/genesis.rs +++ b/json/src/spec/genesis.rs @@ -60,10 +60,8 @@ mod tests { use serde_json; use bytes::Bytes; use uint::Uint; - use util::U256; + use bigint::prelude::{U256, H160, H64 as Eth64, H256 as Eth256}; use hash::{H64, H256, Address}; - use util::hash::H160; - use util::{H64 as Eth64, H256 as Eth256}; use spec::genesis::Genesis; use spec::{Ethereum, Seal}; use std::str::FromStr; diff --git a/json/src/spec/instant_seal.rs b/json/src/spec/instant_seal.rs deleted file mode 100644 index ebf167d28..000000000 --- a/json/src/spec/instant_seal.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (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 . - -//! Instant params deserialization. - -use hash::Address; - -/// Instant params deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct InstantSealParams { - /// Address of the registrar contract. - pub registrar: Option
, -} - -/// Instant engine deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct InstantSeal { - /// Instant Seal params. - pub params: InstantSealParams, -} - -#[cfg(test)] -mod tests { - use serde_json; - use hash::Address; - use util::hash::H160; - use spec::instant_seal::InstantSeal; - - #[test] - fn instant_seal_deserialization() { - let s = r#"{ - "params": { - "registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b" - } - }"#; - - let deserialized: InstantSeal = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.registrar, Some(Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b")))); - } -} diff --git a/json/src/spec/mod.rs b/json/src/spec/mod.rs index 63c26a010..bc7e751af 100644 --- a/json/src/spec/mod.rs +++ b/json/src/spec/mod.rs @@ -26,7 +26,6 @@ pub mod engine; pub mod state; pub mod ethash; pub mod validator_set; -pub mod instant_seal; pub mod basic_authority; pub mod authority_round; pub mod tendermint; @@ -41,7 +40,6 @@ pub use self::engine::Engine; pub use self::state::State; pub use self::ethash::{Ethash, EthashParams}; pub use self::validator_set::ValidatorSet; -pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams}; pub use self::authority_round::{AuthorityRound, AuthorityRoundParams}; pub use self::tendermint::{Tendermint, TendermintParams}; diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 0c0b1b01e..d72ead89a 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -55,6 +55,9 @@ pub struct Params { #[serde(rename="eip98Transition")] pub eip98_transition: Option, /// See `CommonParams` docs. + #[serde(rename="eip155Transition")] + pub eip155_transition: Option, + /// See `CommonParams` docs. #[serde(rename="validateReceiptsTransition")] pub validate_receipts_transition: Option, /// See `CommonParams` docs. @@ -91,13 +94,21 @@ pub struct Params { pub remove_dust_contracts : Option, /// Wasm support flag pub wasm: Option, + /// See `CommonParams` docs. + #[serde(rename="gasLimitBoundDivisor")] + pub gas_limit_bound_divisor: Uint, + /// See `CommonParams` docs. + #[serde(rename="blockReward")] + pub block_reward: Option, + /// See `CommonParams` docs. + pub registrar: Option
, } #[cfg(test)] mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::U256; use spec::params::Params; #[test] @@ -108,7 +119,8 @@ mod tests { "chainID" : "0x15", "subprotocolName" : "exp", "minGasLimit": "0x1388", - "accountStartNonce": "0x01" + "accountStartNonce": "0x01", + "gasLimitBoundDivisor": "0x20" }"#; let deserialized: Params = serde_json::from_str(s).unwrap(); @@ -118,5 +130,6 @@ mod tests { assert_eq!(deserialized.subprotocol_name, Some("exp".to_owned())); assert_eq!(deserialized.min_gas_limit, Uint(U256::from(0x1388))); assert_eq!(deserialized.account_start_nonce, Some(Uint(U256::from(0x01)))); + assert_eq!(deserialized.gas_limit_bound_divisor, Uint(U256::from(0x20))); } } diff --git a/json/src/spec/seal.rs b/json/src/spec/seal.rs index 7345a623d..a428a0957 100644 --- a/json/src/spec/seal.rs +++ b/json/src/spec/seal.rs @@ -73,8 +73,7 @@ mod tests { use hash::*; use bytes::Bytes; use uint::Uint; - use util::U256; - use util::{H64 as Eth64, H256 as Eth256, H520 as Eth520}; + use bigint::prelude::{U256, H64 as Eth64, H256 as Eth256, H520 as Eth520}; use spec::{Ethereum, AuthorityRoundSeal, TendermintSeal, Seal}; #[test] diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index b4b73d9d0..6aa419b18 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -61,12 +61,9 @@ mod tests { "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition" : "0x", "daoHardforkTransition": "0xffffffffffffffff", "daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000", @@ -81,7 +78,8 @@ mod tests { "minGasLimit": "0x1388", "networkID" : "0x2", "forkBlock": "0xffffffffffffffff", - "forkCanonHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + "forkCanonHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasLimitBoundDivisor": "0x20" }, "genesis": { "seal": { diff --git a/json/src/spec/tendermint.rs b/json/src/spec/tendermint.rs index 5a15a0841..f5a178d50 100644 --- a/json/src/spec/tendermint.rs +++ b/json/src/spec/tendermint.rs @@ -17,15 +17,11 @@ //! Tendermint params deserialization. use uint::Uint; -use hash::Address; use super::ValidatorSet; /// Tendermint params deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct TendermintParams { - /// Gas limit divisor. - #[serde(rename="gasLimitBoundDivisor")] - pub gas_limit_bound_divisor: Uint, /// Valid validators. pub validators: ValidatorSet, /// Propose step timeout in milliseconds. @@ -40,11 +36,6 @@ pub struct TendermintParams { /// Commit step timeout in milliseconds. #[serde(rename="timeoutCommit")] pub timeout_commit: Option, - /// Block reward. - #[serde(rename="blockReward")] - pub block_reward: Option, - /// Address of the registrar contract. - pub registrar: Option
, } /// Tendermint engine deserialization. @@ -57,10 +48,7 @@ pub struct Tendermint { #[cfg(test)] mod tests { use serde_json; - use uint::Uint; - use util::U256; - use hash::Address; - use util::hash::H160; + use bigint::prelude::H160; use spec::tendermint::Tendermint; use spec::validator_set::ValidatorSet; @@ -68,18 +56,14 @@ mod tests { fn tendermint_deserialization() { let s = r#"{ "params": { - "gasLimitBoundDivisor": "0x0400", "validators": { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] - }, - "blockReward": "0x50" + } } }"#; let deserialized: Tendermint = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.gas_limit_bound_divisor, Uint(U256::from(0x0400))); let vs = ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]); assert_eq!(deserialized.params.validators, vs); - assert_eq!(deserialized.params.block_reward, Some(Uint(U256::from(0x50)))); } } diff --git a/json/src/spec/validator_set.rs b/json/src/spec/validator_set.rs index abcb35848..3526bed93 100644 --- a/json/src/spec/validator_set.rs +++ b/json/src/spec/validator_set.rs @@ -41,9 +41,8 @@ pub enum ValidatorSet { mod tests { use serde_json; use uint::Uint; - use util::U256; + use bigint::prelude::{H160, U256}; use hash::Address; - use util::hash::H160; use spec::validator_set::ValidatorSet; #[test] diff --git a/json/src/uint.rs b/json/src/uint.rs index 5e98a9dca..b6962c762 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -20,7 +20,7 @@ use std::fmt; use std::str::FromStr; use serde::{Deserialize, Deserializer}; use serde::de::{Error, Visitor}; -use util::U256; +use bigint::prelude::U256; /// Lenient uint json deserialization for test json files. #[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] @@ -93,7 +93,7 @@ impl<'a> Visitor<'a> for UintVisitor { #[cfg(test)] mod test { use serde_json; - use util::U256; + use bigint::prelude::U256; use uint::Uint; #[test] diff --git a/json/src/vm/call.rs b/json/src/vm/call.rs index 711d7b538..14e067f5f 100644 --- a/json/src/vm/call.rs +++ b/json/src/vm/call.rs @@ -39,7 +39,7 @@ pub struct Call { mod tests { use serde_json; use vm::Call; - use util::{U256, H160 as Hash160}; + use bigint::prelude::{U256, H160 as Hash160}; use uint::Uint; use hash::Address; use maybe::MaybeEmpty; diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 7cd146082..cbbfa8dc0 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -227,12 +227,9 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0xffffffffffffffff", "daoHardforkTransition": "0xffffffffffffffff", "daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000", @@ -241,6 +238,9 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x50000", @@ -275,12 +275,9 @@ const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0xffffffffffffffff", "daoHardforkTransition": "0xffffffffffffffff", "daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000", @@ -289,6 +286,9 @@ const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x0100", "maximumExtraDataSize": "0x20", "minGasLimit": "0x50000", From fe6bdc870c150a708253a2338d29e8605c1514be Mon Sep 17 00:00:00 2001 From: fro Date: Mon, 31 Jul 2017 16:54:26 +0300 Subject: [PATCH 042/119] realloc test contract submodule update --- ethcore/res/wasm-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index 9ed630431..04c9d84c5 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit 9ed6304313fa949ed92aa0570fb2bc759fb6dc58 +Subproject commit 04c9d84c5fe5c3ad707be58664c7e72b97cc9996 From 2ca4adb62cf605830f35ee89c0b42205bd98a3b5 Mon Sep 17 00:00:00 2001 From: maciejhirsz Date: Mon, 31 Jul 2017 17:51:23 +0200 Subject: [PATCH 043/119] Re-enable wallets, fixed forgetting accounts --- js/src/api/local/accounts/account.js | 4 ++++ js/src/api/local/accounts/accounts.js | 6 ++++++ js/src/api/local/localAccountsMiddleware.js | 4 ++++ js/src/views/Accounts/accounts.js | 4 ---- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/js/src/api/local/accounts/account.js b/js/src/api/local/accounts/account.js index 0bb069c8b..224a05cd9 100644 --- a/js/src/api/local/accounts/account.js +++ b/js/src/api/local/accounts/account.js @@ -31,6 +31,10 @@ export default class Account { } isValidPassword (password) { + if (!this._keyObject) { + return false; + } + return decryptPrivateKey(this._keyObject, password) .then((privateKey) => { if (!privateKey) { diff --git a/js/src/api/local/accounts/accounts.js b/js/src/api/local/accounts/accounts.js index 823ab3624..d11ea2bad 100644 --- a/js/src/api/local/accounts/accounts.js +++ b/js/src/api/local/accounts/accounts.js @@ -168,6 +168,12 @@ export default class Accounts { return false; } + if (!account.uuid) { + this.removeUnsafe(address); + + return true; + } + return account .isValidPassword(password) .then((isValid) => { diff --git a/js/src/api/local/localAccountsMiddleware.js b/js/src/api/local/localAccountsMiddleware.js index c8e767f89..c452f541a 100644 --- a/js/src/api/local/localAccountsMiddleware.js +++ b/js/src/api/local/localAccountsMiddleware.js @@ -206,6 +206,10 @@ export default class LocalAccountsMiddleware extends Middleware { return accounts.remove(address, password); }); + register('parity_removeAddress', ([address]) => { + return accounts.remove(address, null); + }); + register('parity_testPassword', ([address, password]) => { const account = accounts.get(address); diff --git a/js/src/views/Accounts/accounts.js b/js/src/views/Accounts/accounts.js index 2d37b7a4b..c8828cff6 100644 --- a/js/src/views/Accounts/accounts.js +++ b/js/src/views/Accounts/accounts.js @@ -373,10 +373,6 @@ class Accounts extends Component { } renderNewWalletButton () { - if (this.props.availability !== 'personal') { - return null; - } - return (