* flat trace serialization * tracing finds transaction which creates contract * flatten traces before inserting them to the db
This commit is contained in:
parent
1fbef3289b
commit
a76981a61d
@ -40,7 +40,7 @@ enum TraceDBIndex {
|
||||
BloomGroups = 1,
|
||||
}
|
||||
|
||||
impl Key<BlockTraces> for H256 {
|
||||
impl Key<FlatBlockTraces> for H256 {
|
||||
type Target = H264;
|
||||
|
||||
fn key(&self) -> H264 {
|
||||
@ -91,7 +91,7 @@ impl Key<blooms::BloomGroup> for TraceGroupPosition {
|
||||
/// Trace database.
|
||||
pub struct TraceDB<T> where T: DatabaseExtras {
|
||||
// cache
|
||||
traces: RwLock<HashMap<H256, BlockTraces>>,
|
||||
traces: RwLock<HashMap<H256, FlatBlockTraces>>,
|
||||
blooms: RwLock<HashMap<TraceGroupPosition, blooms::BloomGroup>>,
|
||||
// db
|
||||
tracesdb: Database,
|
||||
@ -153,15 +153,13 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
||||
}
|
||||
|
||||
/// Returns traces for block with hash.
|
||||
fn traces(&self, block_hash: &H256) -> Option<BlockTraces> {
|
||||
fn traces(&self, block_hash: &H256) -> Option<FlatBlockTraces> {
|
||||
self.tracesdb.read_with_cache(&self.traces, block_hash)
|
||||
}
|
||||
|
||||
/// Returns vector of transaction traces for given block.
|
||||
fn transactions_traces(&self, block_hash: &H256) -> Option<Vec<FlatTransactionTraces>> {
|
||||
self.traces(block_hash)
|
||||
.map(FlatBlockTraces::from)
|
||||
.map(Into::into)
|
||||
self.traces(block_hash).map(Into::into)
|
||||
}
|
||||
|
||||
fn matching_block_traces(
|
||||
@ -232,7 +230,7 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
|
||||
let mut traces = self.traces.write();
|
||||
// it's important to use overwrite here,
|
||||
// cause this value might be queried by hash later
|
||||
batch.write_with_cache(traces.deref_mut(), request.block_hash, request.traces, CacheUpdatePolicy::Overwrite);
|
||||
batch.write_with_cache(traces.deref_mut(), request.block_hash, request.traces.into(), CacheUpdatePolicy::Overwrite);
|
||||
}
|
||||
|
||||
// now let's rebuild the blooms
|
||||
@ -353,8 +351,7 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
|
||||
.expect("Expected to find block hash. Extras db is probably corrupted");
|
||||
let traces = self.traces(&hash)
|
||||
.expect("Expected to find a trace. Db is probably corrupted.");
|
||||
let flat_block = FlatBlockTraces::from(traces);
|
||||
self.matching_block_traces(filter, flat_block, hash, number)
|
||||
self.matching_block_traces(filter, traces, hash, number)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -16,12 +16,15 @@
|
||||
|
||||
//! Flat trace module
|
||||
|
||||
use util::rlp::*;
|
||||
use trace::BlockTraces;
|
||||
use basic_types::LogBloom;
|
||||
use super::trace::{Trace, Action, Res};
|
||||
|
||||
/// Trace localized in vector of traces produced by a single transaction.
|
||||
///
|
||||
/// Parent and children indexes refer to positions in this vector.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct FlatTrace {
|
||||
/// Type of action performed by a transaction.
|
||||
pub action: Action,
|
||||
@ -35,9 +38,59 @@ pub struct FlatTrace {
|
||||
pub trace_address: Vec<usize>,
|
||||
}
|
||||
|
||||
impl FlatTrace {
|
||||
/// Returns bloom of the trace.
|
||||
pub fn bloom(&self) -> LogBloom {
|
||||
self.action.bloom() | self.result.bloom()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for FlatTrace {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.begin_list(4);
|
||||
s.append(&self.action);
|
||||
s.append(&self.result);
|
||||
s.append(&self.subtraces);
|
||||
s.append(&self.trace_address);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for FlatTrace {
|
||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||
let d = decoder.as_rlp();
|
||||
let res = FlatTrace {
|
||||
action: try!(d.val_at(0)),
|
||||
result: try!(d.val_at(1)),
|
||||
subtraces: try!(d.val_at(2)),
|
||||
trace_address: try!(d.val_at(3)),
|
||||
};
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents all traces produced by a single transaction.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct FlatTransactionTraces(Vec<FlatTrace>);
|
||||
|
||||
impl FlatTransactionTraces {
|
||||
pub fn bloom(&self) -> LogBloom {
|
||||
self.0.iter().fold(Default::default(), | bloom, trace | bloom | trace.bloom())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for FlatTransactionTraces {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.append(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for FlatTransactionTraces {
|
||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||
Ok(FlatTransactionTraces(try!(Decodable::decode(decoder))))
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||
fn into(self) -> Vec<FlatTrace> {
|
||||
self.0
|
||||
@ -45,8 +98,27 @@ impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||
}
|
||||
|
||||
/// Represents all traces produced by transactions in a single block.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct FlatBlockTraces(Vec<FlatTransactionTraces>);
|
||||
|
||||
impl FlatBlockTraces {
|
||||
pub fn bloom(&self) -> LogBloom {
|
||||
self.0.iter().fold(Default::default(), | bloom, tx_traces | bloom | tx_traces.bloom())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for FlatBlockTraces {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.append(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for FlatBlockTraces {
|
||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||
Ok(FlatBlockTraces(try!(Decodable::decode(decoder))))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BlockTraces> for FlatBlockTraces {
|
||||
fn from(block_traces: BlockTraces) -> Self {
|
||||
let traces: Vec<Trace> = block_traces.into();
|
||||
@ -180,4 +252,31 @@ mod tests {
|
||||
assert_eq!(ordered_traces[4].trace_address, vec![1]);
|
||||
assert_eq!(ordered_traces[4].subtraces, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trace_serialization() {
|
||||
use util::rlp;
|
||||
|
||||
let flat_trace = FlatTrace {
|
||||
action: Action::Call(Call {
|
||||
from: 1.into(),
|
||||
to: 2.into(),
|
||||
value: 3.into(),
|
||||
gas: 4.into(),
|
||||
input: vec![0x5]
|
||||
}),
|
||||
result: Res::Call(CallResult {
|
||||
gas_used: 10.into(),
|
||||
output: vec![0x11, 0x12]
|
||||
}),
|
||||
trace_address: Vec::new(),
|
||||
subtraces: 0,
|
||||
};
|
||||
|
||||
let block_traces = FlatBlockTraces(vec![FlatTransactionTraces(vec![flat_trace])]);
|
||||
|
||||
let encoded = rlp::encode(&block_traces);
|
||||
let decoded = rlp::decode(&encoded);
|
||||
assert_eq!(block_traces, decoded);
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ impl Filter {
|
||||
let from_matches = self.from_address.matches(&create.from);
|
||||
let to_matches = self.to_address.matches_all();
|
||||
from_matches && to_matches
|
||||
}
|
||||
},
|
||||
Action::Suicide(ref suicide) => {
|
||||
let from_matches = self.from_address.matches(&suicide.address);
|
||||
let to_matches = self.to_address.matches(&suicide.refund_address);
|
||||
|
Loading…
Reference in New Issue
Block a user