Merge branch 'master' into ethminer_crate

Conflicts:
	Cargo.lock
	Cargo.toml
	hook.sh
	miner/src/transaction_queue.rs
	rpc/Cargo.toml
	sync/Cargo.toml
	sync/src/chain.rs
This commit is contained in:
Tomasz Drwięga 2016-03-10 11:38:24 +01:00
commit 2e72173620
44 changed files with 384 additions and 196 deletions

4
Cargo.lock generated
View File

@ -18,6 +18,7 @@ dependencies = [
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rpassword 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -219,6 +220,7 @@ dependencies = [
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -243,6 +245,7 @@ dependencies = [
"jsonrpc-http-server 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -310,6 +313,7 @@ dependencies = [
"heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View File

@ -4,6 +4,10 @@ name = "parity"
version = "0.9.99" version = "0.9.99"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"
[build-dependencies]
rustc_version = "0.1"
[dependencies] [dependencies]
log = "0.3" log = "0.3"
@ -12,24 +16,32 @@ rustc-serialize = "0.3"
docopt = "0.6" docopt = "0.6"
time = "0.1" time = "0.1"
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" } ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
clippy = { version = "0.0.44", optional = true }
ethcore-util = { path = "util" }
ethcore = { path = "ethcore" }
ethsync = { path = "sync" }
ethminer = { path = "miner" }
ethcore-rpc = { path = "rpc", optional = true }
fdlimit = { path = "util/fdlimit" } fdlimit = { path = "util/fdlimit" }
daemonize = "0.2" daemonize = "0.2"
ethcore-devtools = { path = "devtools" }
number_prefix = "0.2" number_prefix = "0.2"
rpassword = "0.1" rpassword = "0.1"
ethcore = { path = "ethcore" }
ethcore-util = { path = "util" }
ethsync = { path = "sync" }
ethminer = { path = "miner" }
ethcore-devtools = { path = "devtools" }
ethcore-rpc = { path = "rpc", optional = true }
clippy = { version = "0.0.44", optional = true }
[dev-dependencies]
ethcore = { path = "ethcore", features = ["dev"] }
ethcore-util = { path = "util", features = ["dev"] }
ethsync = { path = "sync", features = ["dev"] }
ethcore-rpc = { path = "rpc", features = ["dev"] }
[features] [features]
default = ["rpc"] default = ["rpc"]
rpc = ["ethcore-rpc"] rpc = ["ethcore-rpc"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethminer/dev"] dev = ["ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethminer/dev"]
dev-clippy = ["clippy", "ethcore/clippy", "ethcore-util/clippy", "ethsync/clippy", "ethcore-rpc/clippy",
"ethminer/clippy"]
travis-beta = ["ethcore/json-tests"] travis-beta = ["ethcore/json-tests"]
travis-nightly = ["ethcore/json-tests", "dev"] travis-nightly = ["ethcore/json-tests", "dev-clippy", "dev"]
[[bin]] [[bin]]
path = "parity/main.rs" path = "parity/main.rs"

25
build.rs Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate rustc_version;
use rustc_version::{version_meta, Channel};
fn main() {
if let Channel::Nightly = version_meta().channel {
println!("cargo:rustc-cfg=nightly");
}
}

2
cargo.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
cargo "$@" --features dev-clippy

View File

@ -5,6 +5,10 @@ license = "GPL-3.0"
name = "ethcore" name = "ethcore"
version = "0.9.99" version = "0.9.99"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"
[build-dependencies]
rustc_version = "0.1"
[dependencies] [dependencies]
log = "0.3" log = "0.3"
@ -27,5 +31,5 @@ jit = ["evmjit"]
evm-debug = [] evm-debug = []
json-tests = [] json-tests = []
test-heavy = [] test-heavy = []
dev = ["clippy"] dev = []
default = [] default = []

25
ethcore/build.rs Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate rustc_version;
use rustc_version::{version_meta, Channel};
fn main() {
if let Channel::Nightly = version_meta().channel {
println!("cargo:rustc-cfg=nightly");
}
}

View File

@ -24,7 +24,7 @@ pub type LogBloom = H2048;
/// Constant 2048-bit datum for 0. Often used as a default. /// Constant 2048-bit datum for 0. Often used as a default.
pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]); pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]);
#[cfg_attr(feature="dev", allow(enum_variant_names))] #[cfg_attr(all(nightly, feature="dev"), allow(enum_variant_names))]
/// Semantic boolean for when a seal/signature is included. /// Semantic boolean for when a seal/signature is included.
pub enum Seal { pub enum Seal {
/// The seal/signature is included. /// The seal/signature is included.

View File

@ -16,7 +16,7 @@
//! Blockchain block. //! Blockchain block.
#![cfg_attr(feature="dev", allow(ptr_arg))] // Because of &LastHashes -> &Vec<_> #![cfg_attr(all(nightly, feature="dev"), allow(ptr_arg))] // Because of &LastHashes -> &Vec<_>
use common::*; use common::*;
use engine::*; use engine::*;

View File

@ -121,7 +121,7 @@ struct QueueSignal {
} }
impl QueueSignal { impl QueueSignal {
#[cfg_attr(feature="dev", allow(bool_comparison))] #[cfg_attr(all(nightly, feature="dev"), allow(bool_comparison))]
fn set(&self) { fn set(&self) {
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false { if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message"); self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");

View File

@ -884,7 +884,7 @@ mod tests {
} }
#[test] #[test]
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn test_find_uncles() { fn test_find_uncles() {
let mut canon_chain = ChainGenerator::default(); let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default(); let mut finalizer = BlockFinalizer::default();
@ -922,7 +922,7 @@ mod tests {
} }
#[test] #[test]
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn test_small_fork() { fn test_small_fork() {
let mut canon_chain = ChainGenerator::default(); let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default(); let mut finalizer = BlockFinalizer::default();

View File

@ -29,7 +29,7 @@ pub trait ChainIterator: Iterator + Sized {
/// Blocks generated by fork will have lower difficulty than current chain. /// Blocks generated by fork will have lower difficulty than current chain.
fn fork(&self, fork_number: usize) -> Fork<Self> where Self: Clone; fn fork(&self, fork_number: usize) -> Fork<Self> where Self: Clone;
/// Should be called to make every consecutive block have given bloom. /// Should be called to make every consecutive block have given bloom.
fn with_bloom<'a>(&'a mut self, bloom: H2048) -> Bloom<'a, Self>; fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self>;
/// Should be called to complete block. Without complete, block may have incorrect hash. /// Should be called to complete block. Without complete, block may have incorrect hash.
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self>; fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self>;
/// Completes and generates block. /// Completes and generates block.
@ -44,7 +44,7 @@ impl<I> ChainIterator for I where I: Iterator + Sized {
} }
} }
fn with_bloom<'a>(&'a mut self, bloom: H2048) -> Bloom<'a, Self> { fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self> {
Bloom { Bloom {
iter: self, iter: self,
bloom: bloom bloom: bloom

View File

@ -63,8 +63,15 @@ pub enum ExecutionError {
} }
#[derive(Debug)] #[derive(Debug)]
/// Errors concerning transaction proessing. /// Errors concerning transaction processing.
pub enum TransactionError { pub enum TransactionError {
/// Transaction's gas price is below threshold.
InsufficientGasPrice {
/// Minimal expected gas price
minimal: U256,
/// Transaction gas price
got: U256
},
/// Transaction's gas limit (aka gas) is invalid. /// Transaction's gas limit (aka gas) is invalid.
InvalidGasLimit(OutOfBounds<U256>), InvalidGasLimit(OutOfBounds<U256>),
} }

View File

@ -202,7 +202,7 @@ impl Engine for Ethash {
} }
} }
#[cfg_attr(feature="dev", allow(wrong_self_convention))] // to_ethash should take self #[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))] // to_ethash should take self
impl Ethash { impl Ethash {
fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 { fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 {
const EXP_DIFF_PERIOD: u64 = 100000; const EXP_DIFF_PERIOD: u64 = 100000;

View File

@ -243,7 +243,7 @@ struct CodeReader<'a> {
code: &'a Bytes code: &'a Bytes
} }
#[cfg_attr(feature="dev", allow(len_without_is_empty))] #[cfg_attr(all(nightly, feature="dev"), allow(len_without_is_empty))]
impl<'a> CodeReader<'a> { impl<'a> CodeReader<'a> {
/// Get `no_of_bytes` from code and convert to U256. Move PC /// Get `no_of_bytes` from code and convert to U256. Move PC
fn read(&mut self, no_of_bytes: usize) -> U256 { fn read(&mut self, no_of_bytes: usize) -> U256 {
@ -258,7 +258,7 @@ impl<'a> CodeReader<'a> {
} }
} }
#[cfg_attr(feature="dev", allow(enum_variant_names))] #[cfg_attr(all(nightly, feature="dev"), allow(enum_variant_names))]
enum InstructionCost { enum InstructionCost {
Gas(U256), Gas(U256),
GasMem(U256, U256), GasMem(U256, U256),
@ -347,7 +347,7 @@ impl evm::Evm for Interpreter {
} }
impl Interpreter { impl Interpreter {
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn get_gas_cost_mem(&self, fn get_gas_cost_mem(&self,
ext: &evm::Ext, ext: &evm::Ext,
instruction: Instruction, instruction: Instruction,

View File

@ -25,9 +25,8 @@ struct FakeLogEntry {
} }
#[derive(PartialEq, Eq, Hash, Debug)] #[derive(PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature="dev", allow(enum_variant_names))] // Common prefix is C ;)
enum FakeCallType { enum FakeCallType {
CALL, CREATE Call, Create
} }
#[derive(PartialEq, Eq, Hash, Debug)] #[derive(PartialEq, Eq, Hash, Debug)]
@ -94,7 +93,7 @@ impl Ext for FakeExt {
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult {
self.calls.insert(FakeCall { self.calls.insert(FakeCall {
call_type: FakeCallType::CREATE, call_type: FakeCallType::Create,
gas: *gas, gas: *gas,
sender_address: None, sender_address: None,
receive_address: None, receive_address: None,
@ -115,7 +114,7 @@ impl Ext for FakeExt {
_output: &mut [u8]) -> MessageCallResult { _output: &mut [u8]) -> MessageCallResult {
self.calls.insert(FakeCall { self.calls.insert(FakeCall {
call_type: FakeCallType::CALL, call_type: FakeCallType::Call,
gas: *gas, gas: *gas,
sender_address: Some(sender_address.clone()), sender_address: Some(sender_address.clone()),
receive_address: Some(receive_address.clone()), receive_address: Some(receive_address.clone()),
@ -909,7 +908,7 @@ fn test_calls(factory: super::Factory) {
}; };
assert_set_contains(&ext.calls, &FakeCall { assert_set_contains(&ext.calls, &FakeCall {
call_type: FakeCallType::CALL, call_type: FakeCallType::Call,
gas: U256::from(2556), gas: U256::from(2556),
sender_address: Some(address.clone()), sender_address: Some(address.clone()),
receive_address: Some(code_address.clone()), receive_address: Some(code_address.clone()),
@ -918,7 +917,7 @@ fn test_calls(factory: super::Factory) {
code_address: Some(code_address.clone()) code_address: Some(code_address.clone())
}); });
assert_set_contains(&ext.calls, &FakeCall { assert_set_contains(&ext.calls, &FakeCall {
call_type: FakeCallType::CALL, call_type: FakeCallType::Call,
gas: U256::from(2556), gas: U256::from(2556),
sender_address: Some(address.clone()), sender_address: Some(address.clone()),
receive_address: Some(address.clone()), receive_address: Some(address.clone()),

View File

@ -188,7 +188,7 @@ impl<'a> Ext for Externalities<'a> {
self.state.code(address).unwrap_or_else(|| vec![]) self.state.code(address).unwrap_or_else(|| vec![])
} }
#[cfg_attr(feature="dev", allow(match_ref_pats))] #[cfg_attr(all(nightly, feature="dev"), allow(match_ref_pats))]
fn ret(&mut self, gas: &U256, data: &[u8]) -> Result<U256, evm::Error> { fn ret(&mut self, gas: &U256, data: &[u8]) -> Result<U256, evm::Error> {
match &mut self.output { match &mut self.output {
&mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe { &mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe {
@ -226,9 +226,9 @@ impl<'a> Ext for Externalities<'a> {
fn log(&mut self, topics: Vec<H256>, data: &[u8]) { fn log(&mut self, topics: Vec<H256>, data: &[u8]) {
let address = self.origin_info.address.clone(); let address = self.origin_info.address.clone();
self.substate.logs.push(LogEntry { self.substate.logs.push(LogEntry {
address: address, address: address,
topics: topics, topics: topics,
data: data.to_vec() data: data.to_vec()
}); });
} }

View File

@ -15,16 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)] #![warn(missing_docs)]
#![cfg_attr(feature="dev", feature(plugin))] #![cfg_attr(all(nightly, feature="dev"), feature(plugin))]
#![cfg_attr(feature="dev", plugin(clippy))] #![cfg_attr(all(nightly, feature="dev"), plugin(clippy))]
// Clippy config // Clippy config
// TODO [todr] not really sure // TODO [todr] not really sure
#![cfg_attr(feature="dev", allow(needless_range_loop))] #![cfg_attr(all(nightly, feature="dev"), allow(needless_range_loop))]
// Shorter than if-else // Shorter than if-else
#![cfg_attr(feature="dev", allow(match_bool))] #![cfg_attr(all(nightly, feature="dev"), allow(match_bool))]
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
#![cfg_attr(feature="dev", allow(clone_on_copy))] #![cfg_attr(all(nightly, feature="dev"), allow(clone_on_copy))]
//! Ethcore library //! Ethcore library
//! //!

View File

@ -119,12 +119,11 @@ impl IoHandler<NetSyncMessage> for ClientIoHandler {
} }
} }
#[cfg_attr(feature="dev", allow(match_ref_pats))] #[cfg_attr(all(nightly, feature="dev"), allow(single_match))]
#[cfg_attr(feature="dev", allow(single_match))]
fn message(&self, io: &IoContext<NetSyncMessage>, net_message: &NetSyncMessage) { fn message(&self, io: &IoContext<NetSyncMessage>, net_message: &NetSyncMessage) {
if let &UserMessage(ref message) = net_message { if let UserMessage(ref message) = *net_message {
match message { match *message {
&SyncMessage::BlockVerified => { SyncMessage::BlockVerified => {
self.client.import_verified_blocks(&io.channel()); self.client.import_verified_blocks(&io.channel());
}, },
_ => {}, // ignore other messages _ => {}, // ignore other messages

View File

@ -99,7 +99,7 @@ pub struct Spec {
genesis_state: PodState, genesis_state: PodState,
} }
#[cfg_attr(feature="dev", allow(wrong_self_convention))] // because to_engine(self) should be to_engine(&self) #[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))] // because to_engine(self) should be to_engine(&self)
impl Spec { impl Spec {
/// Convert this object into a boxed Engine of the right underlying type. /// Convert this object into a boxed Engine of the right underlying type.
// TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead. // TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead.
@ -136,7 +136,7 @@ impl Spec {
uncles_hash: RlpStream::new_list(0).out().sha3(), uncles_hash: RlpStream::new_list(0).out().sha3(),
extra_data: self.extra_data.clone(), extra_data: self.extra_data.clone(),
state_root: self.state_root().clone(), state_root: self.state_root().clone(),
receipts_root: self.receipts_root.clone(), receipts_root: self.receipts_root.clone(),
log_bloom: H2048::new().clone(), log_bloom: H2048::new().clone(),
gas_used: self.gas_used.clone(), gas_used: self.gas_used.clone(),
gas_limit: self.gas_limit.clone(), gas_limit: self.gas_limit.clone(),
@ -182,7 +182,7 @@ impl Spec {
) )
} }
}; };
self.parent_hash = H256::from_json(&genesis["parentHash"]); self.parent_hash = H256::from_json(&genesis["parentHash"]);
self.transactions_root = genesis.find("transactionsTrie").and_then(|_| Some(H256::from_json(&genesis["transactionsTrie"]))).unwrap_or(SHA3_NULL_RLP.clone()); self.transactions_root = genesis.find("transactionsTrie").and_then(|_| Some(H256::from_json(&genesis["transactionsTrie"]))).unwrap_or(SHA3_NULL_RLP.clone());
self.receipts_root = genesis.find("receiptTrie").and_then(|_| Some(H256::from_json(&genesis["receiptTrie"]))).unwrap_or(SHA3_NULL_RLP.clone()); self.receipts_root = genesis.find("receiptTrie").and_then(|_| Some(H256::from_json(&genesis["receiptTrie"]))).unwrap_or(SHA3_NULL_RLP.clone());
@ -249,7 +249,7 @@ impl FromJson for Spec {
) )
} }
}; };
Spec { Spec {
name: json.find("name").map_or("unknown", |j| j.as_string().unwrap()).to_owned(), name: json.find("name").map_or("unknown", |j| j.as_string().unwrap()).to_owned(),
engine_name: json["engineName"].as_string().unwrap().to_owned(), engine_name: json["engineName"].as_string().unwrap().to_owned(),
@ -278,7 +278,7 @@ impl Spec {
/// Ensure that the given state DB has the trie nodes in for the genesis state. /// Ensure that the given state DB has the trie nodes in for the genesis state.
pub fn ensure_db_good(&self, db: &mut HashDB) -> bool { pub fn ensure_db_good(&self, db: &mut HashDB) -> bool {
if !db.contains(&self.state_root()) { if !db.contains(&self.state_root()) {
let mut root = H256::new(); let mut root = H256::new();
{ {
let mut t = SecTrieDBMut::new(db, &mut root); let mut t = SecTrieDBMut::new(db, &mut root);
for (address, account) in self.genesis_state.get().iter() { for (address, account) in self.genesis_state.get().iter() {

View File

@ -224,7 +224,7 @@ impl State {
/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit. /// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
/// `accounts` is mutable because we may need to commit the code or storage and record that. /// `accounts` is mutable because we may need to commit the code or storage and record that.
#[cfg_attr(feature="dev", allow(match_ref_pats))] #[cfg_attr(all(nightly, feature="dev"), allow(match_ref_pats))]
pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) { pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) {
// first, commit the sub trees. // first, commit the sub trees.
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`? // TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?

View File

@ -80,7 +80,7 @@ impl Transaction {
} }
impl FromJson for SignedTransaction { impl FromJson for SignedTransaction {
#[cfg_attr(feature="dev", allow(single_char_pattern))] #[cfg_attr(all(nightly, feature="dev"), allow(single_char_pattern))]
fn from_json(json: &Json) -> SignedTransaction { fn from_json(json: &Json) -> SignedTransaction {
let t = Transaction { let t = Transaction {
nonce: xjson!(&json["nonce"]), nonce: xjson!(&json["nonce"]),

View File

@ -1,3 +1,3 @@
#!/bin/sh #!/bin/sh
echo "#!/bin/sh\ncargo test -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer --features dev" > ./.git/hooks/pre-push echo "#!/bin/sh\ncargo test -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer --features dev-clippy" > ./.git/hooks/pre-push
chmod +x ./.git/hooks/pre-push chmod +x ./.git/hooks/pre-push

View File

@ -16,5 +16,5 @@ rayon = "0.3.1"
clippy = { version = "0.0.44", optional = true } clippy = { version = "0.0.44", optional = true }
[features] [features]
dev = ["clippy"]
default = [] default = []
dev = []

View File

@ -24,6 +24,7 @@ use util::numbers::{Uint, U256};
use util::hash::{Address, H256}; use util::hash::{Address, H256};
use util::table::*; use util::table::*;
use ethcore::transaction::*; use ethcore::transaction::*;
use ethcore::error::{Error, TransactionError};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -82,10 +83,11 @@ struct VerifiedTransaction {
transaction: SignedTransaction transaction: SignedTransaction
} }
impl VerifiedTransaction { impl VerifiedTransaction {
fn new(transaction: SignedTransaction) -> Self { fn new(transaction: SignedTransaction) -> Result<Self, Error> {
VerifiedTransaction { try!(transaction.sender());
Ok(VerifiedTransaction {
transaction: transaction transaction: transaction
} })
} }
fn hash(&self) -> H256 { fn hash(&self) -> H256 {
@ -148,6 +150,8 @@ impl TransactionSet {
} }
} }
// Will be used when rpc merged
#[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
/// Current status of the queue /// Current status of the queue
pub struct TransactionQueueStatus { pub struct TransactionQueueStatus {
@ -205,6 +209,8 @@ impl TransactionQueue {
self.minimal_gas_price = min_gas_price; self.minimal_gas_price = min_gas_price;
} }
// Will be used when rpc merged
#[allow(dead_code)]
/// Returns current status for this queue /// Returns current status for this queue
pub fn status(&self) -> TransactionQueueStatus { pub fn status(&self) -> TransactionQueueStatus {
TransactionQueueStatus { TransactionQueueStatus {
@ -214,15 +220,16 @@ impl TransactionQueue {
} }
/// Adds all signed transactions to queue to be verified and imported /// Adds all signed transactions to queue to be verified and imported
pub fn add_all<T>(&mut self, txs: Vec<SignedTransaction>, fetch_nonce: T) pub fn add_all<T>(&mut self, txs: Vec<SignedTransaction>, fetch_nonce: T) -> Result<(), Error>
where T: Fn(&Address) -> U256 { where T: Fn(&Address) -> U256 {
for tx in txs.into_iter() { for tx in txs.into_iter() {
self.add(tx, &fetch_nonce); try!(self.add(tx, &fetch_nonce));
} }
Ok(())
} }
/// Add signed transaction to queue to be verified and imported /// Add signed transaction to queue to be verified and imported
pub fn add<T>(&mut self, tx: SignedTransaction, fetch_nonce: &T) pub fn add<T>(&mut self, tx: SignedTransaction, fetch_nonce: &T) -> Result<(), Error>
where T: Fn(&Address) -> U256 { where T: Fn(&Address) -> U256 {
if tx.gas_price < self.minimal_gas_price { if tx.gas_price < self.minimal_gas_price {
@ -230,10 +237,15 @@ impl TransactionQueue {
"Dropping transaction below minimal gas price threshold: {:?} (gp: {} < {})", "Dropping transaction below minimal gas price threshold: {:?} (gp: {} < {})",
tx.hash(), tx.gas_price, self.minimal_gas_price tx.hash(), tx.gas_price, self.minimal_gas_price
); );
return;
return Error::Transaction(TransactionError::InsufficientGasPrice{
minimal: self.minimal_gas_price,
got: tx.gas_price
});
} }
// Everything ok - import transaction
self.import_tx(VerifiedTransaction::new(tx), fetch_nonce); self.import_tx(try!(VerifiedTransaction::new(tx)), fetch_nonce);
Ok(())
} }
/// Removes all transactions identified by hashes given in slice /// Removes all transactions identified by hashes given in slice
@ -317,7 +329,8 @@ impl TransactionQueue {
self.future.enforce_limit(&mut self.by_hash); self.future.enforce_limit(&mut self.by_hash);
} }
// Will be used when mining merged
#[allow(dead_code)]
/// Returns top transactions from the queue /// Returns top transactions from the queue
pub fn top_transactions(&self, size: usize) -> Vec<SignedTransaction> { pub fn top_transactions(&self, size: usize) -> Vec<SignedTransaction> {
self.current.by_priority self.current.by_priority
@ -425,13 +438,8 @@ impl TransactionQueue {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
extern crate rustc_serialize; extern crate rustc_serialize;
use self::rustc_serialize::hex::FromHex;
use std::ops::Deref;
use std::collections::{HashMap, BTreeSet};
use util::crypto::KeyPair;
use util::numbers::{U256, Uint};
use util::hash::{Address};
use util::table::*; use util::table::*;
use util::*;
use ethcore::transaction::*; use ethcore::transaction::*;
use super::*; use super::*;
use super::{TransactionSet, TransactionOrder, VerifiedTransaction}; use super::{TransactionSet, TransactionOrder, VerifiedTransaction};
@ -475,12 +483,12 @@ mod test {
limit: 1 limit: 1
}; };
let (tx1, tx2) = new_txs(U256::from(1)); let (tx1, tx2) = new_txs(U256::from(1));
let tx1 = VerifiedTransaction::new(tx1); let tx1 = VerifiedTransaction::new(tx1).unwrap();
let tx2 = VerifiedTransaction::new(tx2); let tx2 = VerifiedTransaction::new(tx2).unwrap();
let mut by_hash = { let mut by_hash = {
let mut x = HashMap::new(); let mut x = HashMap::new();
let tx1 = VerifiedTransaction::new(tx1.transaction.clone()); let tx1 = VerifiedTransaction::new(tx1.transaction.clone()).unwrap();
let tx2 = VerifiedTransaction::new(tx2.transaction.clone()); let tx2 = VerifiedTransaction::new(tx2.transaction.clone()).unwrap();
x.insert(tx1.hash(), tx1); x.insert(tx1.hash(), tx1);
x.insert(tx2.hash(), tx2); x.insert(tx2.hash(), tx2);
x x
@ -514,9 +522,10 @@ mod test {
let tx = new_tx(); let tx = new_tx();
// when // when
txq.add(tx, &default_nonce); let res = txq.add(tx, &default_nonce);
// then // then
assert!(res.is_ok());
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 1); assert_eq!(stats.pending, 1);
} }
@ -537,6 +546,31 @@ mod test {
assert_eq!(stats.future, 0); assert_eq!(stats.future, 0);
} }
#[test]
fn should_reject_incorectly_signed_transaction() {
// given
let mut txq = TransactionQueue::new();
let tx = new_unsigned_tx(U256::from(123));
let stx = {
let mut s = RlpStream::new_list(9);
s.append(&tx.nonce);
s.append(&tx.gas_price);
s.append(&tx.gas);
s.append_empty_data(); // action=create
s.append(&tx.value);
s.append(&tx.data);
s.append(&0u64); // v
s.append(&U256::zero()); // r
s.append(&U256::zero()); // s
decode(s.as_raw())
};
// when
let res = txq.add(stx, &default_nonce);
// then
assert!(res.is_err());
}
#[test] #[test]
fn should_import_txs_from_same_sender() { fn should_import_txs_from_same_sender() {
// given // given
@ -545,8 +579,8 @@ mod test {
let (tx, tx2) = new_txs(U256::from(1)); let (tx, tx2) = new_txs(U256::from(1));
// when // when
txq.add(tx.clone(), &default_nonce); txq.add(tx.clone(), &default_nonce).unwrap();
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
// then // then
let top = txq.top_transactions(5); let top = txq.top_transactions(5);
@ -563,8 +597,8 @@ mod test {
let (tx, tx2) = new_txs(U256::from(2)); let (tx, tx2) = new_txs(U256::from(2));
// when // when
txq.add(tx.clone(), &default_nonce); txq.add(tx.clone(), &default_nonce).unwrap();
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
// then // then
let stats = txq.status(); let stats = txq.status();
@ -585,13 +619,13 @@ mod test {
let tx1 = new_unsigned_tx(U256::from(124)).sign(&secret); let tx1 = new_unsigned_tx(U256::from(124)).sign(&secret);
let tx2 = new_unsigned_tx(U256::from(125)).sign(&secret); let tx2 = new_unsigned_tx(U256::from(125)).sign(&secret);
txq.add(tx, &default_nonce); txq.add(tx, &default_nonce).unwrap();
assert_eq!(txq.status().pending, 1); assert_eq!(txq.status().pending, 1);
txq.add(tx2, &default_nonce); txq.add(tx2, &default_nonce).unwrap();
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
// when // when
txq.add(tx1, &default_nonce); txq.add(tx1, &default_nonce).unwrap();
// then // then
let stats = txq.status(); let stats = txq.status();
@ -604,8 +638,8 @@ mod test {
// given // given
let mut txq2 = TransactionQueue::new(); let mut txq2 = TransactionQueue::new();
let (tx, tx2) = new_txs(U256::from(3)); let (tx, tx2) = new_txs(U256::from(3));
txq2.add(tx.clone(), &default_nonce); txq2.add(tx.clone(), &default_nonce).unwrap();
txq2.add(tx2.clone(), &default_nonce); txq2.add(tx2.clone(), &default_nonce).unwrap();
assert_eq!(txq2.status().pending, 1); assert_eq!(txq2.status().pending, 1);
assert_eq!(txq2.status().future, 1); assert_eq!(txq2.status().future, 1);
@ -626,10 +660,10 @@ mod test {
let mut txq = TransactionQueue::new(); let mut txq = TransactionQueue::new();
let (tx, tx2) = new_txs(U256::from(1)); let (tx, tx2) = new_txs(U256::from(1));
let tx3 = new_tx(); let tx3 = new_tx();
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
txq.add(tx3.clone(), &default_nonce); txq.add(tx3.clone(), &default_nonce).unwrap();
txq.add(tx.clone(), &default_nonce); txq.add(tx.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().pending, 3); assert_eq!(txq.status().pending, 3);
// when // when
@ -648,8 +682,8 @@ mod test {
let (tx, tx2) = new_txs(U256::one()); let (tx, tx2) = new_txs(U256::one());
// add // add
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
txq.add(tx.clone(), &default_nonce); txq.add(tx.clone(), &default_nonce).unwrap();
let stats = txq.status(); let stats = txq.status();
assert_eq!(stats.pending, 2); assert_eq!(stats.pending, 2);
@ -666,11 +700,11 @@ mod test {
// given // given
let mut txq = TransactionQueue::with_limits(1, 1); let mut txq = TransactionQueue::with_limits(1, 1);
let (tx, tx2) = new_txs(U256::one()); let (tx, tx2) = new_txs(U256::one());
txq.add(tx.clone(), &default_nonce); txq.add(tx.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().pending, 1); assert_eq!(txq.status().pending, 1);
// when // when
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
// then // then
let t = txq.top_transactions(2); let t = txq.top_transactions(2);
@ -684,14 +718,14 @@ mod test {
let mut txq = TransactionQueue::with_limits(10, 1); let mut txq = TransactionQueue::with_limits(10, 1);
let (tx1, tx2) = new_txs(U256::from(4)); let (tx1, tx2) = new_txs(U256::from(4));
let (tx3, tx4) = new_txs(U256::from(4)); let (tx3, tx4) = new_txs(U256::from(4));
txq.add(tx1.clone(), &default_nonce); txq.add(tx1.clone(), &default_nonce).unwrap();
txq.add(tx3.clone(), &default_nonce); txq.add(tx3.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().pending, 2); assert_eq!(txq.status().pending, 2);
// when // when
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
txq.add(tx4.clone(), &default_nonce); txq.add(tx4.clone(), &default_nonce).unwrap();
// then // then
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
@ -705,7 +739,7 @@ mod test {
let fetch_last_nonce = |_a: &Address| last_nonce; let fetch_last_nonce = |_a: &Address| last_nonce;
// when // when
txq.add(tx, &fetch_last_nonce); txq.add(tx, &fetch_last_nonce).unwrap();
// then // then
let stats = txq.status(); let stats = txq.status();
@ -719,12 +753,12 @@ mod test {
let nonce = |a: &Address| default_nonce(a) + U256::one(); let nonce = |a: &Address| default_nonce(a) + U256::one();
let mut txq = TransactionQueue::new(); let mut txq = TransactionQueue::new();
let (_tx1, tx2) = new_txs(U256::from(1)); let (_tx1, tx2) = new_txs(U256::from(1));
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
assert_eq!(txq.status().pending, 0); assert_eq!(txq.status().pending, 0);
// when // when
txq.add(tx2.clone(), &nonce); txq.add(tx2.clone(), &nonce).unwrap();
// then // then
let stats = txq.status(); let stats = txq.status();
@ -737,15 +771,15 @@ mod test {
// given // given
let mut txq = TransactionQueue::new(); let mut txq = TransactionQueue::new();
let (tx1, tx2) = new_txs(U256::from(1)); let (tx1, tx2) = new_txs(U256::from(1));
txq.add(tx1.clone(), &default_nonce); txq.add(tx1.clone(), &default_nonce).unwrap();
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().pending, 2); assert_eq!(txq.status().pending, 2);
// when // when
txq.remove(&tx1.hash(), &default_nonce); txq.remove(&tx1.hash(), &default_nonce);
assert_eq!(txq.status().pending, 0); assert_eq!(txq.status().pending, 0);
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
txq.add(tx1.clone(), &default_nonce); txq.add(tx1.clone(), &default_nonce).unwrap();
// then // then
let stats = txq.status(); let stats = txq.status();
@ -760,10 +794,10 @@ mod test {
let mut txq = TransactionQueue::new(); let mut txq = TransactionQueue::new();
let (tx, tx2) = new_txs(U256::from(1)); let (tx, tx2) = new_txs(U256::from(1));
let tx3 = new_tx(); let tx3 = new_tx();
txq.add(tx2.clone(), &default_nonce); txq.add(tx2.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
txq.add(tx3.clone(), &default_nonce); txq.add(tx3.clone(), &default_nonce).unwrap();
txq.add(tx.clone(), &default_nonce); txq.add(tx.clone(), &default_nonce).unwrap();
assert_eq!(txq.status().pending, 3); assert_eq!(txq.status().pending, 3);
// when // when
@ -788,8 +822,8 @@ mod test {
}; };
// when // when
txq.add(tx, &default_nonce); txq.add(tx, &default_nonce).unwrap();
txq.add(tx2, &default_nonce); txq.add(tx2, &default_nonce).unwrap();
// then // then
let stats = txq.status(); let stats = txq.status();
@ -816,10 +850,10 @@ mod test {
}; };
// when // when
txq.add(tx1, &default_nonce); txq.add(tx1, &default_nonce).unwrap();
txq.add(tx2, &default_nonce); txq.add(tx2, &default_nonce).unwrap();
assert_eq!(txq.status().future, 1); assert_eq!(txq.status().future, 1);
txq.add(tx0, &default_nonce); txq.add(tx0, &default_nonce).unwrap();
// then // then
let stats = txq.status(); let stats = txq.status();
@ -835,8 +869,8 @@ mod test {
let next_nonce = |a: &Address| default_nonce(a) + U256::one(); let next_nonce = |a: &Address| default_nonce(a) + U256::one();
let mut txq = TransactionQueue::new(); let mut txq = TransactionQueue::new();
let (tx1, tx2) = new_txs(U256::one()); let (tx1, tx2) = new_txs(U256::one());
txq.add(tx1.clone(), &previous_nonce); txq.add(tx1.clone(), &previous_nonce).unwrap();
txq.add(tx2, &previous_nonce); txq.add(tx2, &previous_nonce).unwrap();
assert_eq!(txq.status().future, 2); assert_eq!(txq.status().future, 2);
// when // when

View File

@ -17,8 +17,8 @@
//! Ethcore client application. //! Ethcore client application.
#![warn(missing_docs)] #![warn(missing_docs)]
#![cfg_attr(feature="dev", feature(plugin))] #![cfg_attr(all(nightly, feature="dev"), feature(plugin))]
#![cfg_attr(feature="dev", plugin(clippy))] #![cfg_attr(all(nightly, feature="dev"), plugin(clippy))]
extern crate docopt; extern crate docopt;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate ethcore_util as util; extern crate ethcore_util as util;
@ -309,7 +309,7 @@ impl Configuration {
} }
} }
#[cfg_attr(feature="dev", allow(useless_format))] #[cfg_attr(all(nightly, feature="dev"), allow(useless_format))]
fn net_addresses(&self) -> (Option<SocketAddr>, Option<SocketAddr>) { fn net_addresses(&self) -> (Option<SocketAddr>, Option<SocketAddr>) {
let mut listen_address = None; let mut listen_address = None;
let mut public_address = None; let mut public_address = None;

View File

@ -27,8 +27,9 @@ serde_macros = { version = "0.7.0", optional = true }
[build-dependencies] [build-dependencies]
serde_codegen = { version = "0.7.0", optional = true } serde_codegen = { version = "0.7.0", optional = true }
syntex = "0.29.0" syntex = "0.29.0"
rustc_version = "0.1"
[features] [features]
default = ["serde_codegen"] default = ["serde_codegen"]
nightly = ["serde_macros"] nightly = ["serde_macros"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethminer/dev"] dev = ["ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethminer/dev"]

View File

@ -1,3 +1,23 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate rustc_version;
use rustc_version::{version_meta, Channel};
#[cfg(not(feature = "serde_macros"))] #[cfg(not(feature = "serde_macros"))]
mod inner { mod inner {
extern crate syntex; extern crate syntex;
@ -26,4 +46,7 @@ mod inner {
fn main() { fn main() {
inner::main(); inner::main();
if let Channel::Nightly = version_meta().channel {
println!("cargo:rustc-cfg=nightly");
}
} }

View File

@ -4,20 +4,24 @@ name = "ethsync"
version = "0.9.99" version = "0.9.99"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io"] authors = ["Ethcore <admin@ethcore.io"]
build = "build.rs"
[lib] [lib]
[build-dependencies]
rustc_version = "0.1"
[dependencies] [dependencies]
ethcore-util = { path = "../util" } ethcore-util = { path = "../util" }
ethcore = { path = "../ethcore" } ethcore = { path = "../ethcore" }
ethminer = { path = "../miner" } ethminer = { path = "../miner" }
clippy = { version = "0.0.44", optional = true }
log = "0.3" log = "0.3"
env_logger = "0.3" env_logger = "0.3"
time = "0.1.34" time = "0.1.34"
rand = "0.3.13" rand = "0.3.13"
heapsize = "0.3" heapsize = "0.3"
clippy = { version = "0.0.44", optional = true }
[features] [features]
default = [] default = []
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethminer/dev"] dev = ["ethcore/dev", "ethcore-util/dev", "ethminer/dev"]

25
sync/build.rs Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate rustc_version;
use rustc_version::{version_meta, Channel};
fn main() {
if let Channel::Nightly = version_meta().channel {
println!("cargo:rustc-cfg=nightly");
}
}

View File

@ -273,7 +273,7 @@ impl ChainSync {
} }
#[cfg_attr(feature="dev", allow(for_kv_map))] // Because it's not possible to get `values_mut()` #[cfg_attr(all(nightly, feature="dev"), allow(for_kv_map))] // Because it's not possible to get `values_mut()`
/// Rest sync. Clear all downloaded data but keep the queue /// Rest sync. Clear all downloaded data but keep the queue
fn reset(&mut self) { fn reset(&mut self) {
self.downloading_headers.clear(); self.downloading_headers.clear();
@ -340,7 +340,7 @@ impl ChainSync {
Ok(()) Ok(())
} }
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
/// Called by peer once it has new block headers during sync /// Called by peer once it has new block headers during sync
fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> {
self.reset_peer_asking(peer_id, PeerAsking::BlockHeaders); self.reset_peer_asking(peer_id, PeerAsking::BlockHeaders);
@ -467,6 +467,7 @@ impl ChainSync {
} }
/// Called by peer once it has new block bodies /// Called by peer once it has new block bodies
#[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> {
let block_rlp = try!(r.at(0)); let block_rlp = try!(r.at(0));
let header_rlp = try!(block_rlp.at(0)); let header_rlp = try!(block_rlp.at(0));
@ -1262,8 +1263,9 @@ impl ChainSync {
self.check_resume(io); self.check_resume(io);
} }
/// called when block is imported to chain, updates transactions queue and propagates the blocks
pub fn chain_new_blocks(&mut self, io: &mut SyncIo, good: &[H256], bad: &[H256], retracted: &[H256]) { pub fn chain_new_blocks(&mut self, io: &mut SyncIo, good: &[H256], bad: &[H256], retracted: &[H256]) {
// notify miner // Notify miner
self.miner.chain_new_blocks(io.chain(), good, bad, retracted); self.miner.chain_new_blocks(io.chain(), good, bad, retracted);
// Propagate latests blocks // Propagate latests blocks
self.propagate_latest_blocks(io); self.propagate_latest_blocks(io);

View File

@ -15,11 +15,11 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)] #![warn(missing_docs)]
#![cfg_attr(feature="dev", feature(plugin))] #![cfg_attr(all(nightly, feature="dev"), feature(plugin))]
#![cfg_attr(feature="dev", plugin(clippy))] #![cfg_attr(all(nightly, feature="dev"), plugin(clippy))]
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
#![cfg_attr(feature="dev", allow(clone_on_copy))] #![cfg_attr(all(nightly, feature="dev"), allow(clone_on_copy))]
//! Blockchain sync module //! Blockchain sync module
//! Implements ethereum protocol version 63 as specified here: //! Implements ethereum protocol version 63 as specified here:

View File

@ -231,7 +231,7 @@ impl<K, V> RangeCollection<K, V> for Vec<(K, Vec<V>)> where K: Ord + PartialEq +
} }
#[test] #[test]
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn test_range() { fn test_range() {
use std::cmp::{Ordering}; use std::cmp::{Ordering};

View File

@ -40,7 +40,7 @@ chrono = "0.2"
[features] [features]
default = [] default = []
dev = ["clippy"] dev = []
[build-dependencies] [build-dependencies]
vergen = "*" vergen = "*"

View File

@ -1103,7 +1103,7 @@ macro_rules! construct_uint {
} }
} }
#[cfg_attr(feature="dev", allow(derive_hash_xor_eq))] // We are pretty sure it's ok. #[cfg_attr(all(nightly, feature="dev"), allow(derive_hash_xor_eq))] // We are pretty sure it's ok.
impl Hash for $name { impl Hash for $name {
fn hash<H>(&self, state: &mut H) where H: Hasher { fn hash<H>(&self, state: &mut H) where H: Hasher {
unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); } unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); }
@ -1485,7 +1485,7 @@ mod tests {
} }
#[test] #[test]
#[cfg_attr(feature="dev", allow(eq_op))] #[cfg_attr(all(nightly, feature="dev"), allow(eq_op))]
pub fn uint256_comp_test() { pub fn uint256_comp_test() {
let small = U256([10u64, 0, 0, 0]); let small = U256([10u64, 0, 0, 0]);
let big = U256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]); let big = U256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]);
@ -2032,7 +2032,7 @@ mod tests {
#[test] #[test]
#[cfg_attr(feature = "dev", allow(cyclomatic_complexity))] #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn u256_multi_full_mul() { fn u256_multi_full_mul() {
let result = U256([0, 0, 0, 0]).full_mul(U256([0, 0, 0, 0])); let result = U256([0, 0, 0, 0]).full_mul(U256([0, 0, 0, 0]));
assert_eq!(U512([0, 0, 0, 0, 0, 0, 0, 0]), result); assert_eq!(U512([0, 0, 0, 0, 0, 0, 0, 0]), result);

View File

@ -1,7 +1,28 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate rustc_version;
extern crate vergen; extern crate vergen;
use vergen::*; use vergen::*;
use rustc_version::{version_meta, Channel};
fn main() { fn main() {
vergen(OutputFns::all()).unwrap(); vergen(OutputFns::all()).unwrap();
if let Channel::Nightly = version_meta().channel {
println!("cargo:rustc-cfg=nightly");
}
} }

View File

@ -305,7 +305,7 @@ macro_rules! impl_hash {
} }
impl Copy for $from {} impl Copy for $from {}
#[cfg_attr(feature="dev", allow(expl_impl_clone_on_copy))] #[cfg_attr(all(nightly, feature="dev"), allow(expl_impl_clone_on_copy))]
impl Clone for $from { impl Clone for $from {
fn clone(&self) -> $from { fn clone(&self) -> $from {
unsafe { unsafe {
@ -637,7 +637,7 @@ mod tests {
use std::str::FromStr; use std::str::FromStr;
#[test] #[test]
#[cfg_attr(feature="dev", allow(eq_op))] #[cfg_attr(all(nightly, feature="dev"), allow(eq_op))]
fn hash() { fn hash() {
let h = H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]); let h = H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
assert_eq!(H64::from_str("0123456789abcdef").unwrap(), h); assert_eq!(H64::from_str("0123456789abcdef").unwrap(), h);

View File

@ -27,7 +27,7 @@ use std::env;
/// Implementation of the HashDB trait for a disk-backed database with a memory overlay /// Implementation of the HashDB trait for a disk-backed database with a memory overlay
/// and latent-removal semantics. /// and latent-removal semantics.
/// ///
/// Like OverlayDB, there is a memory overlay; `commit()` must be called in order to /// Like OverlayDB, there is a memory overlay; `commit()` must be called in order to
/// write operations out to disk. Unlike OverlayDB, `remove()` operations do not take effect /// write operations out to disk. Unlike OverlayDB, `remove()` operations do not take effect
/// immediately. Rather some age (based on a linear but arbitrary metric) must pass before /// immediately. Rather some age (based on a linear but arbitrary metric) must pass before
/// the removals actually take effect. /// the removals actually take effect.
@ -158,7 +158,7 @@ impl JournalDB {
backing.get(&Self::morph_key(key, 0)).expect("Low-level database error. Some issue with your hard disk?").is_some() backing.get(&Self::morph_key(key, 0)).expect("Low-level database error. Some issue with your hard disk?").is_some()
} }
fn insert_keys(inserts: &Vec<(H256, Bytes)>, backing: &Database, counters: &mut HashMap<H256, i32>, batch: &DBTransaction) { fn insert_keys(inserts: &[(H256, Bytes)], backing: &Database, counters: &mut HashMap<H256, i32>, batch: &DBTransaction) {
for &(ref h, ref d) in inserts { for &(ref h, ref d) in inserts {
if let Some(c) = counters.get_mut(h) { if let Some(c) = counters.get_mut(h) {
// already counting. increment. // already counting. increment.
@ -181,7 +181,7 @@ impl JournalDB {
} }
} }
fn replay_keys(inserts: &Vec<H256>, backing: &Database, counters: &mut HashMap<H256, i32>) { fn replay_keys(inserts: &[H256], backing: &Database, counters: &mut HashMap<H256, i32>) {
trace!("replay_keys: inserts={:?}, counters={:?}", inserts, counters); trace!("replay_keys: inserts={:?}, counters={:?}", inserts, counters);
for h in inserts { for h in inserts {
if let Some(c) = counters.get_mut(h) { if let Some(c) = counters.get_mut(h) {
@ -211,12 +211,12 @@ impl JournalDB {
n = Some(*c); n = Some(*c);
} }
} }
match &n { match n {
&Some(i) if i == 1 => { Some(i) if i == 1 => {
counters.remove(&h); counters.remove(&h);
Self::reset_already_in(batch, &h); Self::reset_already_in(batch, &h);
} }
&None => { None => {
// Gets removed when moving from 1 to 0 additional refs. Should never be here at 0 additional refs. // Gets removed when moving from 1 to 0 additional refs. Should never be here at 0 additional refs.
//assert!(!Self::is_already_in(db, &h)); //assert!(!Self::is_already_in(db, &h));
batch.delete(&h.bytes()).expect("Low-level database error. Some issue with your hard disk?"); batch.delete(&h.bytes()).expect("Low-level database error. Some issue with your hard disk?");
@ -229,7 +229,7 @@ impl JournalDB {
/// Commit all recent insert operations and historical removals from the old era /// Commit all recent insert operations and historical removals from the old era
/// to the backing database. /// to the backing database.
fn commit_with_counters(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> { fn commit_with_counters(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
// journal format: // journal format:
// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ] // [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ] // [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ]
// [era, n] => [ ... ] // [era, n] => [ ... ]
@ -242,12 +242,12 @@ impl JournalDB {
// By the time comes to remove a tuple from the queue (i.e. then the era passes from recent history // By the time comes to remove a tuple from the queue (i.e. then the era passes from recent history
// into ancient history) then only one commit from the tuple is considered canonical. This commit // into ancient history) then only one commit from the tuple is considered canonical. This commit
// is kept in the main backing database, whereas any others from the same era are reverted. // is kept in the main backing database, whereas any others from the same era are reverted.
// //
// It is possible that a key, properly available in the backing database be deleted and re-inserted // It is possible that a key, properly available in the backing database be deleted and re-inserted
// in the recent history queue, yet have both operations in commits that are eventually non-canonical. // in the recent history queue, yet have both operations in commits that are eventually non-canonical.
// To avoid the original, and still required, key from being deleted, we maintain a reference count // To avoid the original, and still required, key from being deleted, we maintain a reference count
// which includes an original key, if any. // which includes an original key, if any.
// //
// The semantics of the `counter` are: // The semantics of the `counter` are:
// insert key k: // insert key k:
// counter already contains k: count += 1 // counter already contains k: count += 1
@ -255,7 +255,7 @@ impl JournalDB {
// backing db contains k: count = 1 // backing db contains k: count = 1
// backing db doesn't contain k: insert into backing db, count = 0 // backing db doesn't contain k: insert into backing db, count = 0
// delete key k: // delete key k:
// counter contains k (count is asserted to be non-zero): // counter contains k (count is asserted to be non-zero):
// count > 1: counter -= 1 // count > 1: counter -= 1
// count == 1: remove counter // count == 1: remove counter
// count == 0: remove key from backing db // count == 0: remove key from backing db
@ -274,7 +274,7 @@ impl JournalDB {
// //
// record new commit's details. // record new commit's details.
trace!("commit: #{} ({}), end era: {:?}", now, id, end); trace!("commit: #{} ({}), end era: {:?}", now, id, end);
let mut counters = self.counters.as_ref().unwrap().write().unwrap(); let mut counters = self.counters.as_ref().unwrap().write().unwrap();
let batch = DBTransaction::new(); let batch = DBTransaction::new();
{ {
@ -295,7 +295,7 @@ impl JournalDB {
let drained = self.overlay.drain(); let drained = self.overlay.drain();
let removes: Vec<H256> = drained let removes: Vec<H256> = drained
.iter() .iter()
.filter_map(|(ref k, &(_, ref c))| if *c < 0 {Some(k.clone())} else {None}).cloned() .filter_map(|(k, &(_, c))| if c < 0 {Some(k.clone())} else {None})
.collect(); .collect();
let inserts: Vec<(H256, Bytes)> = drained let inserts: Vec<(H256, Bytes)> = drained
.into_iter() .into_iter()
@ -382,12 +382,15 @@ impl JournalDB {
/// Returns heap memory size used /// Returns heap memory size used
pub fn mem_used(&self) -> usize { pub fn mem_used(&self) -> usize {
self.overlay.mem_used() + match &self.counters { &Some(ref c) => c.read().unwrap().heap_size_of_children(), &None => 0 } self.overlay.mem_used() + match self.counters {
Some(ref c) => c.read().unwrap().heap_size_of_children(),
None => 0
}
} }
} }
impl HashDB for JournalDB { impl HashDB for JournalDB {
fn keys(&self) -> HashMap<H256, i32> { fn keys(&self) -> HashMap<H256, i32> {
let mut ret: HashMap<H256, i32> = HashMap::new(); let mut ret: HashMap<H256, i32> = HashMap::new();
for (key, _) in self.backing.iter() { for (key, _) in self.backing.iter() {
let h = H256::from_slice(key.deref()); let h = H256::from_slice(key.deref());
@ -401,7 +404,7 @@ impl HashDB for JournalDB {
ret ret
} }
fn lookup(&self, key: &H256) -> Option<&[u8]> { fn lookup(&self, key: &H256) -> Option<&[u8]> {
let k = self.overlay.raw(key); let k = self.overlay.raw(key);
match k { match k {
Some(&(ref d, rc)) if rc > 0 => Some(d), Some(&(ref d, rc)) if rc > 0 => Some(d),
@ -416,18 +419,18 @@ impl HashDB for JournalDB {
} }
} }
fn exists(&self, key: &H256) -> bool { fn exists(&self, key: &H256) -> bool {
self.lookup(key).is_some() self.lookup(key).is_some()
} }
fn insert(&mut self, value: &[u8]) -> H256 { fn insert(&mut self, value: &[u8]) -> H256 {
self.overlay.insert(value) self.overlay.insert(value)
} }
fn emplace(&mut self, key: H256, value: Bytes) { fn emplace(&mut self, key: H256, value: Bytes) {
self.overlay.emplace(key, value); self.overlay.emplace(key, value);
} }
fn kill(&mut self, key: &H256) { fn kill(&mut self, key: &H256) {
self.overlay.kill(key); self.overlay.kill(key);
} }
} }
@ -614,7 +617,6 @@ mod tests {
fn reopen_remove() { fn reopen_remove() {
let mut dir = ::std::env::temp_dir(); let mut dir = ::std::env::temp_dir();
dir.push(H32::random().hex()); dir.push(H32::random().hex());
let bar = H256::random();
let foo = { let foo = {
let mut jdb = JournalDB::new(dir.to_str().unwrap()); let mut jdb = JournalDB::new(dir.to_str().unwrap());

View File

@ -55,8 +55,7 @@ pub struct DatabaseIterator<'a> {
impl<'a> Iterator for DatabaseIterator<'a> { impl<'a> Iterator for DatabaseIterator<'a> {
type Item = (Box<[u8]>, Box<[u8]>); type Item = (Box<[u8]>, Box<[u8]>);
#[cfg_attr(feature="dev", allow(type_complexity))] fn next(&mut self) -> Option<Self::Item> {
fn next(&mut self) -> Option<(Box<[u8]>, Box<[u8]>)> {
self.iter.next() self.iter.next()
} }
} }

View File

@ -15,18 +15,18 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)] #![warn(missing_docs)]
#![cfg_attr(feature="dev", feature(plugin))] #![cfg_attr(all(nightly, feature="dev"), feature(plugin))]
#![cfg_attr(feature="dev", plugin(clippy))] #![cfg_attr(all(nightly, feature="dev"), plugin(clippy))]
// Clippy settings // Clippy settings
// TODO [todr] not really sure // TODO [todr] not really sure
#![cfg_attr(feature="dev", allow(needless_range_loop))] #![cfg_attr(all(nightly, feature="dev"), allow(needless_range_loop))]
// Shorter than if-else // Shorter than if-else
#![cfg_attr(feature="dev", allow(match_bool))] #![cfg_attr(all(nightly, feature="dev"), allow(match_bool))]
// We use that to be more explicit about handled cases // We use that to be more explicit about handled cases
#![cfg_attr(feature="dev", allow(match_same_arms))] #![cfg_attr(all(nightly, feature="dev"), allow(match_same_arms))]
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
#![cfg_attr(feature="dev", allow(clone_on_copy))] #![cfg_attr(all(nightly, feature="dev"), allow(clone_on_copy))]
//! Ethcore-util library //! Ethcore-util library
//! //!

View File

@ -113,14 +113,14 @@ impl Discovery {
} }
/// Add a new node to discovery table. Pings the node. /// Add a new node to discovery table. Pings the node.
pub fn add_node(&mut self, e: NodeEntry) { pub fn add_node(&mut self, e: NodeEntry) {
let endpoint = e.endpoint.clone(); let endpoint = e.endpoint.clone();
self.update_node(e); self.update_node(e);
self.ping(&endpoint); self.ping(&endpoint);
} }
/// Add a list of known nodes to the table. /// Add a list of known nodes to the table.
pub fn init_node_list(&mut self, mut nodes: Vec<NodeEntry>) { pub fn init_node_list(&mut self, mut nodes: Vec<NodeEntry>) {
for n in nodes.drain(..) { for n in nodes.drain(..) {
self.update_node(n); self.update_node(n);
} }
@ -243,7 +243,7 @@ impl Discovery {
self.send_to(packet, address.clone()); self.send_to(packet, address.clone());
} }
#[cfg_attr(feature="dev", allow(map_clone))] #[cfg_attr(all(nightly, feature="dev"), allow(map_clone))]
fn nearest_node_entries(target: &NodeId, buckets: &[NodeBucket]) -> Vec<NodeEntry> { fn nearest_node_entries(target: &NodeId, buckets: &[NodeBucket]) -> Vec<NodeEntry> {
let mut found: BTreeMap<u32, Vec<&NodeEntry>> = BTreeMap::new(); let mut found: BTreeMap<u32, Vec<&NodeEntry>> = BTreeMap::new();
let mut count = 0; let mut count = 0;
@ -251,7 +251,7 @@ impl Discovery {
// Sort nodes by distance to target // Sort nodes by distance to target
for bucket in buckets { for bucket in buckets {
for node in &bucket.nodes { for node in &bucket.nodes {
let distance = Discovery::distance(target, &node.address.id); let distance = Discovery::distance(target, &node.address.id);
found.entry(distance).or_insert_with(Vec::new).push(&node.address); found.entry(distance).or_insert_with(Vec::new).push(&node.address);
if count == BUCKET_SIZE { if count == BUCKET_SIZE {
// delete the most distant element // delete the most distant element
@ -310,7 +310,7 @@ impl Discovery {
None None
}), }),
Ok(_) => None, Ok(_) => None,
Err(e) => { Err(e) => {
warn!("Error reading UPD socket: {:?}", e); warn!("Error reading UPD socket: {:?}", e);
None None
} }
@ -339,7 +339,7 @@ impl Discovery {
PACKET_PONG => self.on_pong(&rlp, &node_id, &from), PACKET_PONG => self.on_pong(&rlp, &node_id, &from),
PACKET_FIND_NODE => self.on_find_node(&rlp, &node_id, &from), PACKET_FIND_NODE => self.on_find_node(&rlp, &node_id, &from),
PACKET_NEIGHBOURS => self.on_neighbours(&rlp, &node_id, &from), PACKET_NEIGHBOURS => self.on_neighbours(&rlp, &node_id, &from),
_ => { _ => {
debug!("Unknown UDP packet: {}", packet_id); debug!("Unknown UDP packet: {}", packet_id);
Ok(None) Ok(None)
} }
@ -367,14 +367,14 @@ impl Discovery {
} }
else { else {
self.update_node(entry.clone()); self.update_node(entry.clone());
added_map.insert(node.clone(), entry); added_map.insert(node.clone(), entry);
} }
let hash = rlp.as_raw().sha3(); let hash = rlp.as_raw().sha3();
let mut response = RlpStream::new_list(2); let mut response = RlpStream::new_list(2);
dest.to_rlp_list(&mut response); dest.to_rlp_list(&mut response);
response.append(&hash); response.append(&hash);
self.send_packet(PACKET_PONG, from, &response.drain()); self.send_packet(PACKET_PONG, from, &response.drain());
Ok(Some(TableUpdates { added: added_map, removed: HashSet::new() })) Ok(Some(TableUpdates { added: added_map, removed: HashSet::new() }))
} }
@ -391,7 +391,7 @@ impl Discovery {
} }
self.clear_ping(node); self.clear_ping(node);
let mut added_map = HashMap::new(); let mut added_map = HashMap::new();
added_map.insert(node.clone(), entry); added_map.insert(node.clone(), entry);
Ok(None) Ok(None)
} }
@ -466,8 +466,8 @@ impl Discovery {
pub fn round(&mut self) -> Option<TableUpdates> { pub fn round(&mut self) -> Option<TableUpdates> {
let removed = self.check_expired(false); let removed = self.check_expired(false);
self.discover(); self.discover();
if !removed.is_empty() { if !removed.is_empty() {
Some(TableUpdates { added: HashMap::new(), removed: removed }) Some(TableUpdates { added: HashMap::new(), removed: removed })
} else { None } } else { None }
} }

View File

@ -507,7 +507,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
debug!(target: "network", "Connecting peers: {} sessions, {} pending", self.session_count(), self.handshake_count()); debug!(target: "network", "Connecting peers: {} sessions, {} pending", self.session_count(), self.handshake_count());
} }
#[cfg_attr(feature="dev", allow(single_match))] #[cfg_attr(all(nightly, feature="dev"), allow(single_match))]
fn connect_peer(&self, id: &NodeId, io: &IoContext<NetworkIoMessage<Message>>) { fn connect_peer(&self, id: &NodeId, io: &IoContext<NetworkIoMessage<Message>>) {
if self.have_session(id) if self.have_session(id)
{ {
@ -542,7 +542,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
self.create_connection(socket, Some(id), io); self.create_connection(socket, Some(id), io);
} }
#[cfg_attr(feature="dev", allow(block_in_if_condition_stmt))] #[cfg_attr(all(nightly, feature="dev"), allow(block_in_if_condition_stmt))]
fn create_connection(&self, socket: TcpStream, id: Option<&NodeId>, io: &IoContext<NetworkIoMessage<Message>>) { fn create_connection(&self, socket: TcpStream, id: Option<&NodeId>, io: &IoContext<NetworkIoMessage<Message>>) {
let nonce = self.info.write().unwrap().next_nonce(); let nonce = self.info.write().unwrap().next_nonce();
let mut handshakes = self.handshakes.write().unwrap(); let mut handshakes = self.handshakes.write().unwrap();

View File

@ -71,7 +71,7 @@ impl PanicHandler {
/// Invoke closure and catch any possible panics. /// Invoke closure and catch any possible panics.
/// In case of panic notifies all listeners about it. /// In case of panic notifies all listeners about it.
#[cfg_attr(feature="dev", allow(deprecated))] #[cfg_attr(all(nightly, feature="dev"), allow(deprecated))]
pub fn catch_panic<G, R>(&self, g: G) -> thread::Result<R> where G: FnOnce() -> R + Send + 'static { pub fn catch_panic<G, R>(&self, g: G) -> thread::Result<R> where G: FnOnce() -> R + Send + 'static {
let _guard = PanicGuard { handler: self }; let _guard = PanicGuard { handler: self };
let result = g(); let result = g();

View File

@ -22,7 +22,7 @@ use super::trietraits::*;
use super::node::*; use super::node::*;
/// A `Trie` implementation using a generic `HashDB` backing database. /// A `Trie` implementation using a generic `HashDB` backing database.
/// ///
/// Use it as a `Trie` trait object. You can use `db()` to get the backing database object, `keys` /// Use it as a `Trie` trait object. You can use `db()` to get the backing database object, `keys`
/// to get the keys belonging to the trie in the backing database, and `db_items_remaining()` to get /// to get the keys belonging to the trie in the backing database, and `db_items_remaining()` to get
/// which items in the backing database do not belong to this trie. If this is the only trie in the /// which items in the backing database do not belong to this trie. If this is the only trie in the
@ -54,7 +54,7 @@ pub struct TrieDB<'db> {
pub hash_count: usize, pub hash_count: usize,
} }
#[cfg_attr(feature="dev", allow(wrong_self_convention))] #[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))]
impl<'db> TrieDB<'db> { impl<'db> TrieDB<'db> {
/// Create a new trie with the backing database `db` and `root` /// Create a new trie with the backing database `db` and `root`
/// Panics, if `root` does not exist /// Panics, if `root` does not exist
@ -63,16 +63,16 @@ impl<'db> TrieDB<'db> {
flushln!("TrieDB::new({}): Trie root not found!", root); flushln!("TrieDB::new({}): Trie root not found!", root);
panic!("Trie root not found!"); panic!("Trie root not found!");
} }
TrieDB { TrieDB {
db: db, db: db,
root: root, root: root,
hash_count: 0 hash_count: 0
} }
} }
/// Get the backing database. /// Get the backing database.
pub fn db(&'db self) -> &'db HashDB { pub fn db(&'db self) -> &'db HashDB {
self.db self.db
} }
/// Determine all the keys in the backing database that belong to the trie. /// Determine all the keys in the backing database that belong to the trie.
@ -142,7 +142,7 @@ impl<'db> TrieDB<'db> {
/// Indentation helper for `formal_all`. /// Indentation helper for `formal_all`.
fn fmt_indent(&self, f: &mut fmt::Formatter, size: usize) -> fmt::Result { fn fmt_indent(&self, f: &mut fmt::Formatter, size: usize) -> fmt::Result {
for _ in 0..size { for _ in 0..size {
try!(write!(f, " ")); try!(write!(f, " "));
} }
Ok(()) Ok(())
@ -358,7 +358,7 @@ impl<'db> fmt::Debug for TrieDB<'db> {
fn iterator() { fn iterator() {
use memorydb::*; use memorydb::*;
use super::triedbmut::*; use super::triedbmut::*;
let d = vec![ &b"A"[..], &b"AA"[..], &b"AB"[..], &b"B"[..] ]; let d = vec![ &b"A"[..], &b"AA"[..], &b"AB"[..], &b"B"[..] ];
let mut memdb = MemoryDB::new(); let mut memdb = MemoryDB::new();

View File

@ -23,7 +23,7 @@ use super::journal::*;
use super::trietraits::*; use super::trietraits::*;
/// A `Trie` implementation using a generic `HashDB` backing database. /// A `Trie` implementation using a generic `HashDB` backing database.
/// ///
/// Use it as a `Trie` trait object. You can use `db()` to get the backing database object, `keys` /// Use it as a `Trie` trait object. You can use `db()` to get the backing database object, `keys`
/// to get the keys belonging to the trie in the backing database, and `db_items_remaining()` to get /// to get the keys belonging to the trie in the backing database, and `db_items_remaining()` to get
/// which items in the backing database do not belong to this trie. If this is the only trie in the /// which items in the backing database do not belong to this trie. If this is the only trie in the
@ -66,21 +66,21 @@ enum MaybeChanged<'a> {
Changed(Bytes), Changed(Bytes),
} }
#[cfg_attr(feature="dev", allow(wrong_self_convention))] #[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))]
impl<'db> TrieDBMut<'db> { impl<'db> TrieDBMut<'db> {
/// Create a new trie with the backing database `db` and empty `root` /// Create a new trie with the backing database `db` and empty `root`
/// Initialise to the state entailed by the genesis block. /// Initialise to the state entailed by the genesis block.
/// This guarantees the trie is built correctly. /// This guarantees the trie is built correctly.
pub fn new(db: &'db mut HashDB, root: &'db mut H256) -> Self { pub fn new(db: &'db mut HashDB, root: &'db mut H256) -> Self {
let mut r = TrieDBMut{ let mut r = TrieDBMut{
db: db, db: db,
root: root, root: root,
hash_count: 0 hash_count: 0
}; };
// set root rlp // set root rlp
*r.root = SHA3_NULL_RLP.clone(); *r.root = SHA3_NULL_RLP.clone();
r r
} }
/// Create a new trie with the backing database `db` and `root`. /// Create a new trie with the backing database `db` and `root`.
@ -91,21 +91,21 @@ impl<'db> TrieDBMut<'db> {
flushln!("Trie root not found {}", root); flushln!("Trie root not found {}", root);
panic!("Trie root not found!"); panic!("Trie root not found!");
} }
TrieDBMut { TrieDBMut {
db: db, db: db,
root: root, root: root,
hash_count: 0 hash_count: 0
} }
} }
/// Get the backing database. /// Get the backing database.
pub fn db(&'db self) -> &'db HashDB { pub fn db(&'db self) -> &'db HashDB {
self.db self.db
} }
/// Get the backing database. /// Get the backing database.
pub fn db_mut(&'db mut self) -> &'db mut HashDB { pub fn db_mut(&'db mut self) -> &'db mut HashDB {
self.db self.db
} }
/// Determine all the keys in the backing database that belong to the trie. /// Determine all the keys in the backing database that belong to the trie.
@ -184,7 +184,7 @@ impl<'db> TrieDBMut<'db> {
/// Indentation helper for `formal_all`. /// Indentation helper for `formal_all`.
fn fmt_indent(&self, f: &mut fmt::Formatter, size: usize) -> fmt::Result { fn fmt_indent(&self, f: &mut fmt::Formatter, size: usize) -> fmt::Result {
for _ in 0..size { for _ in 0..size {
try!(write!(f, " ")); try!(write!(f, " "));
} }
Ok(()) Ok(())
@ -350,7 +350,7 @@ impl<'db> TrieDBMut<'db> {
} }
} }
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
/// Determine the RLP of the node, assuming we're inserting `partial` into the /// Determine the RLP of the node, assuming we're inserting `partial` into the
/// node currently of data `old`. This will *not* delete any hash of `old` from the database; /// node currently of data `old`. This will *not* delete any hash of `old` from the database;
/// it will just return the new RLP that includes the new node. /// it will just return the new RLP that includes the new node.
@ -378,7 +378,7 @@ impl<'db> TrieDBMut<'db> {
// original had empty slot - place a leaf there. // original had empty slot - place a leaf there.
true if old_rlp.at(i).is_empty() => journal.new_node(Self::compose_leaf(&partial.mid(1), value), &mut s), true if old_rlp.at(i).is_empty() => journal.new_node(Self::compose_leaf(&partial.mid(1), value), &mut s),
// original has something there already; augment. // original has something there already; augment.
true => { true => {
let new = self.augmented(self.take_node(&old_rlp.at(i), journal), &partial.mid(1), value, journal); let new = self.augmented(self.take_node(&old_rlp.at(i), journal), &partial.mid(1), value, journal);
journal.new_node(new, &mut s); journal.new_node(new, &mut s);
} }