Merge branch 'master' of github.com:ethcore/parity into thread

This commit is contained in:
arkpar
2016-03-10 18:40:17 +01:00
56 changed files with 1708 additions and 573 deletions

View File

@@ -5,6 +5,10 @@ license = "GPL-3.0"
name = "ethcore"
version = "0.9.99"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"
[build-dependencies]
rustc_version = "0.1"
[dependencies]
log = "0.3"
@@ -27,5 +31,5 @@ jit = ["evmjit"]
evm-debug = []
json-tests = []
test-heavy = []
dev = ["clippy"]
dev = []
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.
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.
pub enum Seal {
/// The seal/signature is included.

View File

@@ -16,7 +16,7 @@
//! 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 engine::*;
@@ -274,7 +274,7 @@ impl<'x> OpenBlock<'x> {
s.block.base.header.note_dirty();
ClosedBlock {
block: s.block,
block: s.block,
uncle_bytes: uncle_bytes,
}
}

View File

@@ -121,7 +121,7 @@ struct QueueSignal {
}
impl QueueSignal {
#[cfg_attr(feature="dev", allow(bool_comparison))]
#[cfg_attr(all(nightly, feature="dev"), allow(bool_comparison))]
fn set(&self) {
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");
@@ -331,6 +331,9 @@ impl BlockQueue {
/// Mark given block and all its children as bad. Stops verification.
pub fn mark_as_bad(&self, block_hashes: &[H256]) {
if block_hashes.is_empty() {
return;
}
let mut verified_lock = self.verification.verified.lock().unwrap();
let mut verified = verified_lock.deref_mut();
let mut bad = self.verification.bad.lock().unwrap();
@@ -355,6 +358,9 @@ impl BlockQueue {
/// Mark given block as processed
pub fn mark_as_good(&self, block_hashes: &[H256]) {
if block_hashes.is_empty() {
return;
}
let mut processing = self.processing.write().unwrap();
for hash in block_hashes {
processing.remove(&hash);
@@ -406,7 +412,7 @@ impl BlockQueue {
}
}
pub fn collect_garbage(&self) {
pub fn collect_garbage(&self) {
{
self.verification.unverified.lock().unwrap().shrink_to_fit();
self.verification.verifying.lock().unwrap().shrink_to_fit();

View File

@@ -18,6 +18,7 @@ use util::numbers::{U256,H256};
use header::BlockNumber;
/// Brief info about inserted block.
#[derive(Clone)]
pub struct BlockInfo {
/// Block hash.
pub hash: H256,
@@ -30,6 +31,7 @@ pub struct BlockInfo {
}
/// Describes location of newly inserted block.
#[derive(Clone)]
pub enum BlockLocation {
/// It's part of the canon chain.
CanonChain,
@@ -42,6 +44,8 @@ pub enum BlockLocation {
/// Hash of the newest common ancestor with old canon chain.
ancestor: H256,
/// Hashes of the blocks between ancestor and this block.
route: Vec<H256>
enacted: Vec<H256>,
/// Hashes of the blocks which were invalidated.
retracted: Vec<H256>,
}
}

View File

@@ -29,7 +29,7 @@ use blockchain::best_block::BestBlock;
use blockchain::bloom_indexer::BloomIndexer;
use blockchain::tree_route::TreeRoute;
use blockchain::update::ExtrasUpdate;
use blockchain::CacheSize;
use blockchain::{CacheSize, ImportRoute};
const BLOOM_INDEX_SIZE: usize = 16;
const BLOOM_LEVELS: u8 = 3;
@@ -419,14 +419,14 @@ impl BlockChain {
/// Inserts the block into backing cache database.
/// Expects the block to be valid and already verified.
/// If the block is already known, does nothing.
pub fn insert_block(&self, bytes: &[u8], receipts: Vec<Receipt>) {
pub fn insert_block(&self, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
// create views onto rlp
let block = BlockView::new(bytes);
let header = block.header_view();
let hash = header.sha3();
if self.is_known(&hash) {
return;
return ImportRoute::none();
}
let _lock = self.insert_lock.lock();
@@ -441,8 +441,10 @@ impl BlockChain {
block_receipts: self.prepare_block_receipts_update(receipts, &info),
transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info),
blocks_blooms: self.prepare_block_blooms_update(bytes, &info),
info: info
info: info.clone(),
});
ImportRoute::from(info)
}
/// Applies extras update.
@@ -565,9 +567,14 @@ impl BlockChain {
match route.blocks.len() {
0 => BlockLocation::CanonChain,
_ => BlockLocation::BranchBecomingCanonChain {
ancestor: route.ancestor,
route: route.blocks.into_iter().skip(route.index).collect()
_ => {
let retracted = route.blocks.iter().take(route.index).cloned().collect::<Vec<H256>>();
BlockLocation::BranchBecomingCanonChain {
ancestor: route.ancestor,
enacted: route.blocks.into_iter().skip(route.index).collect(),
retracted: retracted.into_iter().rev().collect(),
}
}
}
} else {
@@ -588,11 +595,11 @@ impl BlockChain {
BlockLocation::CanonChain => {
block_hashes.insert(number, info.hash.clone());
},
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref route } => {
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
let ancestor_number = self.block_number(ancestor).unwrap();
let start_number = ancestor_number + 1;
for (index, hash) in route.iter().cloned().enumerate() {
for (index, hash) in enacted.iter().cloned().enumerate() {
block_hashes.insert(start_number + index as BlockNumber, hash);
}
@@ -677,11 +684,11 @@ impl BlockChain {
ChainFilter::new(self, self.bloom_indexer.index_size(), self.bloom_indexer.levels())
.add_bloom(&header.log_bloom(), header.number() as usize)
},
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref route } => {
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
let ancestor_number = self.block_number(ancestor).unwrap();
let start_number = ancestor_number + 1;
let mut blooms: Vec<H2048> = route.iter()
let mut blooms: Vec<H2048> = enacted.iter()
.map(|hash| self.block(hash).unwrap())
.map(|bytes| BlockView::new(&bytes).header_view().log_bloom())
.collect();
@@ -841,7 +848,7 @@ mod tests {
use rustc_serialize::hex::FromHex;
use util::hash::*;
use util::sha3::Hashable;
use blockchain::{BlockProvider, BlockChain, BlockChainConfig};
use blockchain::{BlockProvider, BlockChain, BlockChainConfig, ImportRoute};
use tests::helpers::*;
use devtools::*;
use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer};
@@ -900,7 +907,7 @@ mod tests {
}
#[test]
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
#[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn test_find_uncles() {
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
@@ -938,7 +945,7 @@ mod tests {
}
#[test]
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
#[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))]
fn test_small_fork() {
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
@@ -959,10 +966,30 @@ mod tests {
let temp = RandomTempPath::new();
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
bc.insert_block(&b1, vec![]);
bc.insert_block(&b2, vec![]);
bc.insert_block(&b3a, vec![]);
bc.insert_block(&b3b, vec![]);
let ir1 = bc.insert_block(&b1, vec![]);
let ir2 = bc.insert_block(&b2, vec![]);
let ir3b = bc.insert_block(&b3b, vec![]);
let ir3a = bc.insert_block(&b3a, vec![]);
assert_eq!(ir1, ImportRoute {
enacted: vec![b1_hash],
retracted: vec![],
});
assert_eq!(ir2, ImportRoute {
enacted: vec![b2_hash],
retracted: vec![],
});
assert_eq!(ir3b, ImportRoute {
enacted: vec![b3b_hash],
retracted: vec![],
});
assert_eq!(ir3a, ImportRoute {
enacted: vec![b3a_hash],
retracted: vec![b3b_hash],
});
assert_eq!(bc.best_block_hash(), best_block_hash);
assert_eq!(bc.block_number(&genesis_hash).unwrap(), 0);

View File

@@ -29,7 +29,7 @@ pub trait ChainIterator: Iterator + Sized {
/// Blocks generated by fork will have lower difficulty than current chain.
fn fork(&self, fork_number: usize) -> Fork<Self> where Self: Clone;
/// 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.
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self>;
/// 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 {
iter: self,
bloom: bloom

View File

@@ -0,0 +1,119 @@
// 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/>.
//! Import route.
use util::hash::H256;
use blockchain::block_info::{BlockInfo, BlockLocation};
/// Import route for newly inserted block.
#[derive(Debug, PartialEq)]
pub struct ImportRoute {
/// Blocks that were invalidated by new block.
pub retracted: Vec<H256>,
/// Blocks that were validated by new block.
pub enacted: Vec<H256>,
}
impl ImportRoute {
pub fn none() -> Self {
ImportRoute {
retracted: vec![],
enacted: vec![],
}
}
}
impl From<BlockInfo> for ImportRoute {
fn from(info: BlockInfo) -> ImportRoute {
match info.location {
BlockLocation::CanonChain => ImportRoute {
retracted: vec![],
enacted: vec![info.hash],
},
BlockLocation::Branch => ImportRoute::none(),
BlockLocation::BranchBecomingCanonChain { mut enacted, retracted, .. } => {
enacted.push(info.hash);
ImportRoute {
retracted: retracted,
enacted: enacted,
}
}
}
}
}
#[cfg(test)]
mod tests {
use util::hash::H256;
use util::numbers::U256;
use blockchain::block_info::{BlockInfo, BlockLocation};
use blockchain::ImportRoute;
#[test]
fn import_route_none() {
assert_eq!(ImportRoute::none(), ImportRoute {
enacted: vec![],
retracted: vec![],
});
}
#[test]
fn import_route_branch() {
let info = BlockInfo {
hash: H256::from(U256::from(1)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::Branch,
};
assert_eq!(ImportRoute::from(info), ImportRoute::none());
}
#[test]
fn import_route_canon_chain() {
let info = BlockInfo {
hash: H256::from(U256::from(1)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::CanonChain,
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![],
enacted: vec![H256::from(U256::from(1))],
});
}
#[test]
fn import_route_branch_becoming_canon_chain() {
let info = BlockInfo {
hash: H256::from(U256::from(2)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::BranchBecomingCanonChain {
ancestor: H256::from(U256::from(0)),
enacted: vec![H256::from(U256::from(1))],
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
}
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
enacted: vec![H256::from(U256::from(1)), H256::from(U256::from(2))],
});
}
}

View File

@@ -25,7 +25,9 @@ mod tree_route;
mod update;
#[cfg(test)]
mod generator;
mod import_route;
pub use self::blockchain::{BlockProvider, BlockChain, BlockChainConfig};
pub use self::cache::CacheSize;
pub use self::tree_route::TreeRoute;
pub use self::import_route::ImportRoute;

View File

@@ -87,6 +87,8 @@ pub struct ClientConfig {
pub blockchain: BlockChainConfig,
/// Prefer journal rather than archive.
pub prefer_journal: bool,
/// The name of the client instance.
pub name: String,
}
impl Default for ClientConfig {
@@ -95,6 +97,7 @@ impl Default for ClientConfig {
queue: Default::default(),
blockchain: Default::default(),
prefer_journal: false,
name: Default::default(),
}
}
}
@@ -138,6 +141,9 @@ pub trait BlockChainClient : Sync + Send {
/// Get block total difficulty.
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
/// Get address nonce.
fn nonce(&self, address: &Address) -> U256;
/// Get block hash.
fn block_hash(&self, id: BlockId) -> Option<H256>;
@@ -179,6 +185,13 @@ pub trait BlockChainClient : Sync + Send {
/// Returns logs matching given filter.
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry>;
/// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock.
fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>>;
/// Submit `seal` as a valid solution for the header of `pow_hash`.
/// Will check the seal, but not actually insert the block into the chain.
fn submit_seal(&self, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error>;
}
#[derive(Default, Clone, Debug, Eq, PartialEq)]
@@ -190,6 +203,8 @@ pub struct ClientReport {
pub transactions_applied: usize,
/// How much gas has been processed so far.
pub gas_processed: U256,
/// Memory used by state DB
pub state_db_mem: usize,
}
impl ClientReport {
@@ -222,7 +237,7 @@ pub struct Client<V = CanonVerifier> where V: Verifier {
}
const HISTORY: u64 = 1000;
const CLIENT_DB_VER_STR: &'static str = "4.0";
const CLIENT_DB_VER_STR: &'static str = "5.1";
impl Client<CanonVerifier> {
/// Create a new client with given spec and DB path.
@@ -364,18 +379,14 @@ impl<V> Client<V> where V: Verifier {
bad_blocks.insert(header.hash());
continue;
}
let closed_block = self.check_and_close_block(&block);
if let Err(_) = closed_block {
bad_blocks.insert(header.hash());
break;
}
// Insert block
let closed_block = closed_block.unwrap();
self.chain.insert_block(&block.bytes, closed_block.block().receipts().clone());
good_blocks.push(header.hash());
// Are we committing an era?
let ancient = if header.number() >= HISTORY {
let n = header.number() - HISTORY;
Some((n, self.chain.block_hash(n).unwrap()))
@@ -384,10 +395,16 @@ impl<V> Client<V> where V: Verifier {
};
// Commit results
let closed_block = closed_block.unwrap();
let receipts = closed_block.block().receipts().clone();
closed_block.drain()
.commit(header.number(), &header.hash(), ancient)
.expect("State DB commit failed.");
// And update the chain after commit to prevent race conditions
// (when something is in chain but you are not able to fetch details)
self.chain.insert_block(&block.bytes, receipts);
self.report.write().unwrap().accrue_block(&block);
trace!(target: "client", "Imported #{} ({})", header.number(), header.hash());
}
@@ -396,8 +413,12 @@ impl<V> Client<V> where V: Verifier {
let bad_blocks = bad_blocks.into_iter().collect::<Vec<H256>>();
{
self.block_queue.mark_as_bad(&bad_blocks);
self.block_queue.mark_as_good(&good_blocks);
if !bad_blocks.is_empty() {
self.block_queue.mark_as_bad(&bad_blocks);
}
if !good_blocks.is_empty() {
self.block_queue.mark_as_good(&good_blocks);
}
}
{
@@ -405,6 +426,8 @@ impl<V> Client<V> where V: Verifier {
io.send(NetworkIoMessage::User(SyncMessage::NewChainBlocks {
good: good_blocks,
bad: bad_blocks,
// TODO [todr] were to take those from?
retracted: vec![],
})).unwrap();
}
}
@@ -428,7 +451,9 @@ impl<V> Client<V> where V: Verifier {
/// Get the report.
pub fn report(&self) -> ClientReport {
self.report.read().unwrap().clone()
let mut report = self.report.read().unwrap().clone();
report.state_db_mem = self.state_db.lock().unwrap().mem_used();
report
}
/// Tick the client.
@@ -500,39 +525,6 @@ impl<V> Client<V> where V: Verifier {
trace!("Sealing: number={}, hash={}, diff={}", b.hash(), b.block().header().difficulty(), b.block().header().number());
*self.sealing_block.lock().unwrap() = Some(b);
}
/// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock.
pub fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>> {
if self.sealing_block.lock().unwrap().is_none() {
self.sealing_enabled.store(true, atomic::Ordering::Relaxed);
// TODO: Above should be on a timer that resets after two blocks have arrived without being asked for.
self.prepare_sealing();
}
&self.sealing_block
}
/// Submit `seal` as a valid solution for the header of `pow_hash`.
/// Will check the seal, but not actually insert the block into the chain.
pub fn submit_seal(&self, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error> {
let mut maybe_b = self.sealing_block.lock().unwrap();
match *maybe_b {
Some(ref b) if b.hash() == pow_hash => {}
_ => { return Err(Error::PowHashInvalid); }
}
let b = maybe_b.take();
match b.unwrap().try_seal(self.engine.deref().deref(), seal) {
Err(old) => {
*maybe_b = Some(old);
Err(Error::PowInvalid)
}
Ok(sealed) => {
// TODO: commit DB from `sealed.drain` and make a VerifiedBlock to skip running the transactions twice.
try!(self.import_block(sealed.rlp_bytes()));
Ok(())
}
}
}
}
// TODO: need MinerService MinerIoHandler
@@ -572,6 +564,10 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block_details(&hash)).map(|d| d.total_difficulty)
}
fn nonce(&self, address: &Address) -> U256 {
self.state().nonce(address)
}
fn block_hash(&self, id: BlockId) -> Option<H256> {
Self::block_hash(&self.chain, id)
}
@@ -682,6 +678,39 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
})
.collect()
}
/// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock.
fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>> {
if self.sealing_block.lock().unwrap().is_none() {
self.sealing_enabled.store(true, atomic::Ordering::Relaxed);
// TODO: Above should be on a timer that resets after two blocks have arrived without being asked for.
self.prepare_sealing();
}
&self.sealing_block
}
/// Submit `seal` as a valid solution for the header of `pow_hash`.
/// Will check the seal, but not actually insert the block into the chain.
fn submit_seal(&self, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error> {
let mut maybe_b = self.sealing_block.lock().unwrap();
match *maybe_b {
Some(ref b) if b.hash() == pow_hash => {}
_ => { return Err(Error::PowHashInvalid); }
}
let b = maybe_b.take();
match b.unwrap().try_seal(self.engine.deref().deref(), seal) {
Err(old) => {
*maybe_b = Some(old);
Err(Error::PowInvalid)
}
Ok(sealed) => {
// TODO: commit DB from `sealed.drain` and make a VerifiedBlock to skip running the transactions twice.
try!(self.import_block(sealed.rlp_bytes()));
Ok(())
}
}
}
}
impl MayPanic for Client {

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 {
fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 {
const EXP_DIFF_PERIOD: u64 = 100000;

View File

@@ -243,7 +243,7 @@ struct CodeReader<'a> {
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> {
/// Get `no_of_bytes` from code and convert to U256. Move PC
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 {
Gas(U256),
GasMem(U256, U256),
@@ -347,7 +347,7 @@ impl evm::Evm for 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,
ext: &evm::Ext,
instruction: Instruction,

View File

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

View File

@@ -15,16 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)]
#![cfg_attr(feature="dev", feature(plugin))]
#![cfg_attr(feature="dev", plugin(clippy))]
#![cfg_attr(all(nightly, feature="dev"), feature(plugin))]
#![cfg_attr(all(nightly, feature="dev"), plugin(clippy))]
// Clippy config
// 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
#![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.
#![cfg_attr(feature="dev", allow(clone_on_copy))]
#![cfg_attr(all(nightly, feature="dev"), allow(clone_on_copy))]
//! Ethcore library
//!

View File

@@ -31,6 +31,8 @@ pub enum SyncMessage {
good: Vec<H256>,
/// Hashes of blocks not imported to blockchain
bad: Vec<H256>,
/// Hashes of blocks that were removed from canonical chain
retracted: Vec<H256>,
},
/// A block is ready
BlockVerified,
@@ -115,12 +117,11 @@ impl IoHandler<NetSyncMessage> for ClientIoHandler {
}
}
#[cfg_attr(feature="dev", allow(match_ref_pats))]
#[cfg_attr(feature="dev", allow(single_match))]
#[cfg_attr(all(nightly, feature="dev"), allow(single_match))]
fn message(&self, io: &IoContext<NetSyncMessage>, net_message: &NetSyncMessage) {
if let &UserMessage(ref message) = net_message {
match message {
&SyncMessage::BlockVerified => {
if let UserMessage(ref message) = *net_message {
match *message {
SyncMessage::BlockVerified => {
self.client.import_verified_blocks(&io.channel());
},
_ => {}, // ignore other messages

View File

@@ -99,7 +99,7 @@ pub struct Spec {
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 {
/// Convert this object into a boxed Engine of the right underlying type.
// 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(),
extra_data: self.extra_data.clone(),
state_root: self.state_root().clone(),
receipts_root: self.receipts_root.clone(),
receipts_root: self.receipts_root.clone(),
log_bloom: H2048::new().clone(),
gas_used: self.gas_used.clone(),
gas_limit: self.gas_limit.clone(),
@@ -182,7 +182,7 @@ impl Spec {
)
}
};
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.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 {
name: json.find("name").map_or("unknown", |j| j.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.
pub fn ensure_db_good(&self, db: &mut HashDB) -> bool {
if !db.contains(&self.state_root()) {
let mut root = H256::new();
let mut root = H256::new();
{
let mut t = SecTrieDBMut::new(db, &mut root);
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.
/// `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>>) {
// first, commit the sub trees.
// 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 {
#[cfg_attr(feature="dev", allow(single_char_pattern))]
#[cfg_attr(all(nightly, feature="dev"), allow(single_char_pattern))]
fn from_json(json: &Json) -> SignedTransaction {
let t = Transaction {
nonce: xjson!(&json["nonce"]),

View File

@@ -17,9 +17,11 @@
pub mod verification;
pub mod verifier;
mod canon_verifier;
#[cfg(test)]
mod noop_verifier;
pub use self::verification::*;
pub use self::verifier::Verifier;
pub use self::canon_verifier::CanonVerifier;
#[cfg(test)]
pub use self::noop_verifier::NoopVerifier;