Merge branch 'master' into h256

Conflicts:
	ethcore/src/account.rs
This commit is contained in:
Tomasz Drwięga
2016-04-09 11:27:19 +02:00
69 changed files with 1449 additions and 312 deletions

View File

@@ -17,7 +17,7 @@ ethcore-util = { path = "../util" }
evmjit = { path = "../evmjit", optional = true }
ethash = { path = "../ethash" }
num_cpus = "0.2"
clippy = { version = "0.0.54", optional = true }
clippy = { version = "0.0.61", optional = true}
crossbeam = "0.1.5"
lazy_static = "0.1"
ethcore-devtools = { path = "../devtools" }

View File

@@ -154,7 +154,7 @@ impl ExecutedBlock {
}
}
/// Trait for a object that is_a `ExecutedBlock`.
/// Trait for a object that is a `ExecutedBlock`.
pub trait IsBlock {
/// Get the block associated with this object.
fn block(&self) -> &ExecutedBlock;
@@ -192,7 +192,7 @@ pub struct OpenBlock<'x> {
last_hashes: LastHashes,
}
/// Just like OpenBlock, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
/// and collected the uncles.
///
/// There is no function available to push a transaction.
@@ -204,7 +204,7 @@ pub struct ClosedBlock {
unclosed_state: State,
}
/// Just like ClosedBlock except that we can't reopen it and it's faster.
/// Just like `ClosedBlock` except that we can't reopen it and it's faster.
///
/// We actually store the post-`Engine::on_close_block` state, unlike in `ClosedBlock` where it's the pre.
#[derive(Clone)]
@@ -216,14 +216,15 @@ pub struct LockedBlock {
/// A block that has a valid seal.
///
/// The block's header has valid seal arguments. The block cannot be reversed into a ClosedBlock or OpenBlock.
/// The block's header has valid seal arguments. The block cannot be reversed into a `ClosedBlock` or `OpenBlock`.
pub struct SealedBlock {
block: ExecutedBlock,
uncle_bytes: Bytes,
}
impl<'x> OpenBlock<'x> {
/// Create a new OpenBlock ready for transaction pushing.
#[cfg_attr(feature="dev", allow(too_many_arguments))]
/// Create a new `OpenBlock` ready for transaction pushing.
pub fn new(engine: &'x Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, author: Address, gas_floor_target: U256, extra_data: Bytes) -> Self {
let mut r = OpenBlock {
block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()), tracing),
@@ -319,7 +320,7 @@ impl<'x> OpenBlock<'x> {
}
}
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure out the uncles.
/// Turn this into a `ClosedBlock`. A `BlockChain` must be provided in order to figure out the uncles.
pub fn close(self) -> ClosedBlock {
let mut s = self;
@@ -454,6 +455,7 @@ impl IsBlock for SealedBlock {
}
/// Enact the block given by block header, transactions and uncles
#[cfg_attr(feature="dev", allow(too_many_arguments))]
pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<LockedBlock, Error> {
{
if ::log::max_log_level() >= ::log::LogLevel::Trace {

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! A queue of blocks. Sits between network or other I/O and the BlockChain.
//! A queue of blocks. Sits between network or other I/O and the `BlockChain`.
//! Sorts them ready for blockchain insertion.
use std::thread::{JoinHandle, self};
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
@@ -89,7 +89,7 @@ impl BlockQueueInfo {
}
}
/// A queue of blocks. Sits between network or other I/O and the BlockChain.
/// A queue of blocks. Sits between network or other I/O and the `BlockChain`.
/// Sorts them ready for blockchain insertion.
pub struct BlockQueue {
panic_handler: Arc<PanicHandler>,
@@ -116,6 +116,7 @@ struct VerifyingBlock {
}
struct QueueSignal {
deleting: Arc<AtomicBool>,
signalled: AtomicBool,
message_channel: IoChannel<NetSyncMessage>,
}
@@ -123,10 +124,16 @@ struct QueueSignal {
impl QueueSignal {
#[cfg_attr(feature="dev", allow(bool_comparison))]
fn set(&self) {
// Do not signal when we are about to close
if self.deleting.load(AtomicOrdering::Relaxed) {
return;
}
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");
}
}
fn reset(&self) {
self.signalled.store(false, AtomicOrdering::Relaxed);
}
@@ -150,8 +157,12 @@ impl BlockQueue {
bad: Mutex::new(HashSet::new()),
});
let more_to_verify = Arc::new(Condvar::new());
let ready_signal = Arc::new(QueueSignal { signalled: AtomicBool::new(false), message_channel: message_channel });
let deleting = Arc::new(AtomicBool::new(false));
let ready_signal = Arc::new(QueueSignal {
deleting: deleting.clone(),
signalled: AtomicBool::new(false),
message_channel: message_channel
});
let empty = Arc::new(Condvar::new());
let panic_handler = PanicHandler::new_in_arc();
@@ -431,12 +442,14 @@ impl MayPanic for BlockQueue {
impl Drop for BlockQueue {
fn drop(&mut self) {
trace!(target: "shutdown", "[BlockQueue] Closing...");
self.clear();
self.deleting.store(true, AtomicOrdering::Release);
self.more_to_verify.notify_all();
for t in self.verifiers.drain(..) {
t.join().unwrap();
}
trace!(target: "shutdown", "[BlockQueue] Closed.");
}
}

View File

@@ -427,6 +427,7 @@ impl BlockChain {
}
}
#[cfg_attr(feature="dev", allow(similar_names))]
/// Inserts the block into backing cache database.
/// Expects the block to be valid and already verified.
/// If the block is already known, does nothing.
@@ -855,6 +856,7 @@ impl BlockChain {
#[cfg(test)]
mod tests {
#![cfg_attr(feature="dev", allow(similar_names))]
use std::str::FromStr;
use rustc_serialize::hex::FromHex;
use util::hash::*;

View File

@@ -60,7 +60,7 @@ impl Indexer {
}
/// Return bloom which are dependencies for given index.
///
///
/// Bloom indexes are ordered from lowest to highest.
pub fn lower_level_bloom_indexes(&self, index: &BloomIndex) -> Vec<BloomIndex> {
// this is the lowest level
@@ -87,6 +87,7 @@ impl Indexer {
#[cfg(test)]
mod tests {
#![cfg_attr(feature="dev", allow(similar_names))]
use chainfilter::BloomIndex;
use chainfilter::indexer::Indexer;

View File

@@ -23,7 +23,7 @@ use chainfilter::{BloomIndex, FilterDataSource, ChainFilter};
/// In memory cache for blooms.
///
/// Stores all blooms in HashMap, which indexes them by `BloomIndex`.
/// Stores all blooms in `HashMap`, which indexes them by `BloomIndex`.
pub struct MemoryCache {
blooms: HashMap<BloomIndex, H2048>,
}

View File

@@ -38,7 +38,7 @@ use block_queue::{BlockQueue, BlockQueueInfo};
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
use client::{BlockId, TransactionId, UncleId, ClientConfig, BlockChainClient};
use env_info::EnvInfo;
use executive::{Executive, Executed, contract_address};
use executive::{Executive, Executed, TransactOptions, contract_address};
use receipt::LocalizedReceipt;
pub use blockchain::CacheSize as BlockChainCacheSize;
@@ -418,7 +418,8 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
// give the sender max balance
state.sub_balance(&sender, &balance);
state.add_balance(&sender, &U256::max_value());
Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t, false)
let options = TransactOptions { tracing: false, check_nonce: false };
Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t, options)
}
// TODO [todr] Should be moved to miner crate eventually.

View File

@@ -44,7 +44,7 @@ pub enum Error {
/// Invoked instruction
instruction: &'static str,
/// How many stack elements was requested by instruction
wanted: usize,
wanted: usize,
/// How many elements were on stack
on_stack: usize
},
@@ -64,8 +64,8 @@ pub enum Error {
}
/// Evm result.
///
/// Returns gas_left if execution is successful, otherwise error.
///
/// Returns `gas_left` if execution is successful, otherwise error.
pub type Result = result::Result<U256, Error>;
/// Evm interface.

View File

@@ -36,6 +36,14 @@ pub fn contract_address(address: &Address, nonce: &U256) -> Address {
From::from(stream.out().sha3())
}
/// Transaction execution options.
pub struct TransactOptions {
/// Enable call tracing.
pub tracing: bool,
/// Check transaction nonce before execution.
pub check_nonce: bool,
}
/// Transaction execution receipt.
#[derive(Debug, PartialEq, Clone)]
pub struct Executed {
@@ -110,7 +118,7 @@ impl<'a> Executive<'a> {
}
/// This funtion should be used to execute transaction.
pub fn transact(&'a mut self, t: &SignedTransaction, tracing: bool) -> Result<Executed, Error> {
pub fn transact(&'a mut self, t: &SignedTransaction, options: TransactOptions) -> Result<Executed, Error> {
let sender = try!(t.sender());
let nonce = self.state.nonce(&sender);
@@ -124,8 +132,10 @@ impl<'a> Executive<'a> {
let init_gas = t.gas - base_gas_required;
// validate transaction nonce
if t.nonce != nonce {
return Err(From::from(ExecutionError::InvalidNonce { expected: nonce, got: t.nonce }));
if options.check_nonce {
if t.nonce != nonce {
return Err(From::from(ExecutionError::InvalidNonce { expected: nonce, got: t.nonce }));
}
}
// validate if transaction fits into given block
@@ -151,7 +161,7 @@ impl<'a> Executive<'a> {
self.state.inc_nonce(&sender);
self.state.sub_balance(&sender, &U256::from(gas_cost));
let mut substate = Substate::new(tracing);
let mut substate = Substate::new(options.tracing);
let (gas_left, output) = match t.action {
Action::Create => {
@@ -881,7 +891,8 @@ mod tests {
let executed = {
let mut ex = Executive::new(&mut state, &info, &engine);
ex.transact(&t, false).unwrap()
let opts = TransactOptions { check_nonce: true, tracing: false };
ex.transact(&t, opts).unwrap()
};
assert_eq!(executed.gas, U256::from(100_000));
@@ -914,7 +925,8 @@ mod tests {
let res = {
let mut ex = Executive::new(&mut state, &info, &engine);
ex.transact(&t, false)
let opts = TransactOptions { check_nonce: true, tracing: false };
ex.transact(&t, opts)
};
match res {
@@ -945,7 +957,8 @@ mod tests {
let res = {
let mut ex = Executive::new(&mut state, &info, &engine);
ex.transact(&t, false)
let opts = TransactOptions { check_nonce: true, tracing: false };
ex.transact(&t, opts)
};
match res {
@@ -978,7 +991,8 @@ mod tests {
let res = {
let mut ex = Executive::new(&mut state, &info, &engine);
ex.transact(&t, false)
let opts = TransactOptions { check_nonce: true, tracing: false };
ex.transact(&t, opts)
};
match res {
@@ -1011,7 +1025,8 @@ mod tests {
let res = {
let mut ex = Executive::new(&mut state, &info, &engine);
ex.transact(&t, false)
let opts = TransactOptions { check_nonce: true, tracing: false };
ex.transact(&t, opts)
};
match res {

View File

@@ -16,7 +16,7 @@
use common::*;
use engine::Engine;
use executive::Executive;
use executive::{Executive, TransactOptions};
use account_db::*;
#[cfg(test)]
#[cfg(feature = "json-tests")]
@@ -220,7 +220,8 @@ impl State {
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &SignedTransaction, tracing: bool) -> ApplyResult {
// let old = self.to_pod();
let e = try!(Executive::new(self, env_info, engine).transact(t, tracing));
let options = TransactOptions { tracing: tracing, check_nonce: true };
let e = try!(Executive::new(self, env_info, engine).transact(t, options));
// TODO uncomment once to_pod() works correctly.
// trace!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod()));

View File

@@ -55,7 +55,7 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Res
/// Phase 2 verification. Perform costly checks such as transaction signatures and block nonce for ethash.
/// Still operates on a individual block
/// Returns a PreverifiedBlock structure populated with transactions
/// Returns a `PreverifiedBlock` structure populated with transactions
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine) -> Result<PreverifiedBlock, Error> {
try!(engine.verify_block_unordered(&header, Some(&bytes)));
for u in Rlp::new(&bytes).at(2).iter().map(|rlp| rlp.as_val::<Header>()) {
@@ -279,7 +279,7 @@ mod tests {
impl BlockProvider for TestBlockChain {
fn have_tracing(&self) -> bool { false }
fn is_known(&self, hash: &H256) -> bool {
self.blocks.contains_key(hash)
}
@@ -331,6 +331,7 @@ mod tests {
}
#[test]
#[cfg_attr(feature="dev", allow(similar_names))]
fn test_verify_block() {
// Test against morden
let mut good = Header::new();