Core tracedb functionality. (#996)

* fixed encoding 0u8

* simplified if else stmt

* tracedb core

* more comprehensive tracedb tests

* fixed minor review issues

* addresses filter

* fixed typos

* replace malformed with corrupted

* trace switch

* db key is generic and can be made smaller

* smaller tracedb keys

* tracedb version

* fixed ignored tests

* rename Tracedb -> TraceDB

* fixed typos

* proves

* trace only top level calls to builtins to avoid DDoS attacks

* fixed tracedb config switches

* fix comments fat replaced with trace

* vector-addressing scheme for localized traces

* removed comments

* removed first, redundant 0 from trace address

* updated db.trace method

* additional tests for tracedb.trace()
This commit is contained in:
Marek Kotewicz
2016-04-30 17:41:24 +02:00
committed by Gav Wood
parent e942f86bd7
commit 66477a9476
31 changed files with 2090 additions and 239 deletions

View File

@@ -42,6 +42,7 @@ use env_info::EnvInfo;
use executive::{Executive, Executed, TransactOptions, contract_address};
use receipt::LocalizedReceipt;
pub use blockchain::CacheSize as BlockChainCacheSize;
use trace::{TraceDB, Database as TraceDatabase};
/// General block status
#[derive(Debug, Eq, PartialEq)]
@@ -103,6 +104,7 @@ impl ClientReport {
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
pub struct Client<V = CanonVerifier> where V: Verifier {
chain: Arc<BlockChain>,
tracedb: Arc<TraceDB<BlockChain>>,
engine: Arc<Box<Engine>>,
state_db: Mutex<Box<JournalDB>>,
block_queue: BlockQueue,
@@ -150,6 +152,7 @@ impl<V> Client<V> where V: Verifier {
let path = get_db_path(path, config.pruning, spec.genesis_header().hash());
let gb = spec.genesis_block();
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path));
let tracedb = Arc::new(TraceDB::new(config.tracing, &path, chain.clone()));
let mut state_db = journaldb::new(&append_path(&path, "state"), config.pruning);
@@ -165,6 +168,7 @@ impl<V> Client<V> where V: Verifier {
Arc::new(Client {
chain: chain,
tracedb: tracedb,
engine: engine,
state_db: Mutex::new(state_db),
block_queue: block_queue,
@@ -225,7 +229,7 @@ impl<V> Client<V> where V: Verifier {
let last_hashes = self.build_last_hashes(header.parent_hash.clone());
let db = self.state_db.lock().unwrap().boxed_clone();
let enact_result = enact_verified(&block, engine, self.chain.have_tracing(), db, &parent, last_hashes);
let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes);
if let Err(e) = enact_result {
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
return Err(());

View File

@@ -16,6 +16,7 @@
pub use block_queue::BlockQueueConfig;
pub use blockchain::BlockChainConfig;
pub use trace::{Config as TraceConfig, Switch};
use util::journaldb;
/// Client configuration. Includes configs for all sub-systems.
@@ -25,6 +26,8 @@ pub struct ClientConfig {
pub queue: BlockQueueConfig,
/// Blockchain configuration.
pub blockchain: BlockChainConfig,
/// Trace configuration.
pub tracing: TraceConfig,
/// The JournalDB ("pruning") algorithm to use.
pub pruning: journaldb::Algorithm,
/// The name of the client instance.

View File

@@ -20,6 +20,7 @@ mod client;
mod config;
mod ids;
mod test_client;
mod trace;
pub use self::client::*;
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig};

View File

@@ -0,0 +1,38 @@
//! Bridge between Tracedb and Blockchain.
use std::ops::Range;
use util::{Address, H256};
use header::BlockNumber;
use trace::DatabaseExtras as TraceDatabaseExtras;
use blockchain::{BlockChain, BlockProvider};
use extras::TransactionAddress;
use super::BlockId;
impl TraceDatabaseExtras for BlockChain {
fn block_hash(&self, block_number: BlockNumber) -> Option<H256> {
(self as &BlockProvider).block_hash(block_number)
}
fn transaction_hash(&self, block_number: BlockNumber, tx_position: usize) -> Option<H256> {
(self as &BlockProvider).block_hash(block_number)
.and_then(|block_hash| {
let tx_address = TransactionAddress {
block_hash: block_hash,
index: tx_position
};
self.transaction(&tx_address)
})
.map(|tx| tx.hash())
}
}
/// Easy to use trace filter.
pub struct Filter {
/// Range of filtering.
pub range: Range<BlockId>,
/// From address.
pub from_address: Vec<Address>,
/// To address.
pub to_address: Vec<Address>,
}