Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Core tracedb functionality. #996

Merged
merged 37 commits into from
Apr 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8e77ac2
fixed encoding 0u8
debris Apr 24, 2016
418d4a4
simplified if else stmt
debris Apr 24, 2016
5e160f0
tracedb core
debris Apr 24, 2016
c4cf503
Merge branch 'encoding-u8' into tracedb
debris Apr 24, 2016
2bd4a87
Merge branch 'ommited' into tracedb
debris Apr 24, 2016
63a98b9
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 25, 2016
39c29cb
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 25, 2016
7e489af
Merge branch 'master' into tracedb
debris Apr 25, 2016
a20a9d8
more comprehensive tracedb tests
debris Apr 25, 2016
7ee4666
fixed minor review issues
debris Apr 26, 2016
a6bff43
addresses filter
debris Apr 26, 2016
77bb2f4
fixed typos
debris Apr 26, 2016
2341839
replace malformed with corrupted
debris Apr 26, 2016
6f034f1
trace switch
debris Apr 26, 2016
eca6233
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 26, 2016
4451110
db key is generic and can be made smaller
debris Apr 27, 2016
9db32f2
Merge pull request #1006 from ethcore/generic_db_key
debris Apr 27, 2016
ec5b4a7
smaller tracedb keys
debris Apr 27, 2016
1f74d75
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 27, 2016
0b2855d
tracedb version
debris Apr 27, 2016
225b3ff
fixed ignored tests
debris Apr 27, 2016
1b4c789
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 28, 2016
89ae48e
Merge branch 'master' into tracedb
debris Apr 28, 2016
c1149a0
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 28, 2016
9b745ee
rename Tracedb -> TraceDB
debris Apr 28, 2016
c7e62d7
fixed typos
debris Apr 28, 2016
f2918a3
proves
debris Apr 28, 2016
baf72f5
trace only top level calls to builtins to avoid DDoS attacks
debris Apr 28, 2016
6b684ed
fixed tracedb config switches
debris Apr 28, 2016
3ce64ee
fix comments fat replaced with trace
debris Apr 28, 2016
fc2a9b1
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 29, 2016
bc8f79b
vector-addressing scheme for localized traces
debris Apr 29, 2016
2262dc9
removed comments
debris Apr 29, 2016
1d96dcd
Merge branch 'master' of github.com:ethcore/parity into tracedb
debris Apr 30, 2016
59f6357
removed first, redundant 0 from trace address
debris Apr 30, 2016
e99de80
updated db.trace method
debris Apr 30, 2016
55c839f
additional tests for tracedb.trace()
debris Apr 30, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ethcore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ crossbeam = "0.1.5"
lazy_static = "0.1"
ethcore-devtools = { path = "../devtools" }
ethjson = { path = "../json" }
bloomchain = "0.1"

[features]
jit = ["evmjit"]
Expand Down
1 change: 1 addition & 0 deletions ethcore/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use common::*;
use engine::*;
use state::*;
use verification::PreverifiedBlock;
use trace::Trace;

/// A block, encoded as it is on the block chain.
#[derive(Default, Debug, Clone)]
Expand Down
11 changes: 3 additions & 8 deletions ethcore/src/blockchain/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ impl Default for BlockChainConfig {

/// Interface for querying blocks by hash and by number.
pub trait BlockProvider {
/// True if we store full tracing information for transactions.
fn have_tracing(&self) -> bool;

/// Returns true if the given block is known
/// (though not necessarily a part of the canon chain).
fn is_known(&self, hash: &H256) -> bool;
Expand Down Expand Up @@ -186,9 +183,6 @@ impl BlockProvider for BlockChain {
self.extras_db.exists_with_cache(&self.block_details, hash)
}

/// We do not store tracing information.
fn have_tracing(&self) -> bool { false }

/// Get raw block data
fn block(&self, hash: &H256) -> Option<Bytes> {
{
Expand Down Expand Up @@ -734,9 +728,10 @@ impl BlockChain {
self.query_extras(hash, &self.blocks_blooms)
}

fn query_extras<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> Option<T> where
fn query_extras<K, T, R>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> Option<T> where
T: ExtrasIndexable + Clone + Decodable,
K: Key<T> + Eq + Hash + Clone,
K: Key<T, Target = R> + Eq + Hash + Clone,
R: Deref<Target = [u8]>,
H256: From<K> {
self.note_used(CacheID::Extras(T::index(), H256::from(hash.clone())));
self.extras_db.read_with_cache(cache, hash)
Expand Down
6 changes: 5 additions & 1 deletion ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand All @@ -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,
Expand Down Expand Up @@ -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(());
Expand Down
3 changes: 3 additions & 0 deletions ethcore/src/client/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
1 change: 1 addition & 0 deletions ethcore/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
38 changes: 38 additions & 0 deletions ethcore/src/client/trace.rs
Original file line number Diff line number Diff line change
@@ -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>,
}
1 change: 0 additions & 1 deletion ethcore/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ pub use transaction::*;
pub use log_entry::*;
pub use receipt::*;
pub use action_params::*;
pub use trace::*;
47 changes: 28 additions & 19 deletions ethcore/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

//! Extras db utils.

use std::ops::Deref;
use std::hash::Hash;
use std::sync::RwLock;
use std::collections::HashMap;
use util::{H264, DBTransaction, Database};
use util::{DBTransaction, Database};
use util::rlp::{encode, Encodable, decode, Decodable};

#[derive(Clone, Copy)]
Expand All @@ -30,19 +31,22 @@ pub enum CacheUpdatePolicy {

/// Should be used to get database key associated with given value.
pub trait Key<T> {
type Target: Deref<Target = [u8]>;

/// Returns db key.
fn key(&self) -> H264;
fn key(&self) -> Self::Target;
}

/// Should be used to write value into database.
pub trait Writable {
/// Writes the value into the database.
fn write<T>(&self, key: &Key<T>, value: &T) where T: Encodable;
fn write<T, R>(&self, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]>;

/// Writes the value into the database and updates the cache.
fn write_with_cache<K, T>(&self, cache: &mut HashMap<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
K: Key<T> + Hash + Eq,
T: Encodable {
fn write_with_cache<K, T, R>(&self, cache: &mut HashMap<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: Encodable,
R: Deref<Target = [u8]> {
self.write(&key, &value);
match policy {
CacheUpdatePolicy::Overwrite => {
Expand All @@ -55,8 +59,10 @@ pub trait Writable {
}

/// Writes the values into the database and updates the cache.
fn extend_with_cache<K, T>(&self, cache: &mut HashMap<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy)
where K: Key<T> + Hash + Eq, T: Encodable {
fn extend_with_cache<K, T, R>(&self, cache: &mut HashMap<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: Encodable,
R: Deref<Target = [u8]> {
match policy {
CacheUpdatePolicy::Overwrite => {
for (key, value) in values.into_iter() {
Expand All @@ -77,7 +83,9 @@ pub trait Writable {
/// Should be used to read values from database.
pub trait Readable {
/// Returns value for given key.
fn read<T>(&self, key: &Key<T>) -> Option<T> where T: Decodable;
fn read<T, R>(&self, key: &Key<T, Target = R>) -> Option<T> where
T: Decodable,
R: Deref<Target = [u8]>;

/// Returns value for given key either in cache or in database.
fn read_with_cache<K, T>(&self, cache: &RwLock<HashMap<K, T>>, key: &K) -> Option<T> where
Expand All @@ -98,50 +106,51 @@ pub trait Readable {
}

/// Returns true if given value exists.
fn exists<T>(&self, key: &Key<T>) -> bool;
fn exists<T, R>(&self, key: &Key<T, Target = R>) -> bool where R: Deref<Target= [u8]>;

/// Returns true if given value exists either in cache or in database.
fn exists_with_cache<K, T>(&self, cache: &RwLock<HashMap<K, T>>, key: &K) -> bool where
K: Eq + Hash + Key<T> {
fn exists_with_cache<K, T, R>(&self, cache: &RwLock<HashMap<K, T>>, key: &K) -> bool where
K: Eq + Hash + Key<T, Target = R>,
R: Deref<Target = [u8]> {
{
let read = cache.read().unwrap();
if read.get(key).is_some() {
return true;
}
}

self.exists::<T>(key)
self.exists::<T, R>(key)
}
}

impl Writable for DBTransaction {
fn write<T>(&self, key: &Key<T>, value: &T) where T: Encodable {
fn write<T, R>(&self, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> {
let result = self.put(&key.key(), &encode(value));
if let Err(err) = result {
panic!("db put failed, key: {:?}, err: {:?}", key.key(), err);
panic!("db put failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}

impl Readable for Database {
fn read<T>(&self, key: &Key<T>) -> Option<T> where T: Decodable {
fn read<T, R>(&self, key: &Key<T, Target = R>) -> Option<T> where T: Decodable, R: Deref<Target = [u8]> {
let result = self.get(&key.key());

match result {
Ok(option) => option.map(|v| decode(&v)),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", key.key(), err);
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}

fn exists<T>(&self, key: &Key<T>) -> bool {
fn exists<T, R>(&self, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {
let result = self.get(&key.key());

match result {
Ok(v) => v.is_some(),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", key.key(), err);
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}
Expand Down
Loading