* 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,
|
BloomGroups = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Key<BlockTraces> for H256 {
|
impl Key<FlatBlockTraces> for H256 {
|
||||||
type Target = H264;
|
type Target = H264;
|
||||||
|
|
||||||
fn key(&self) -> H264 {
|
fn key(&self) -> H264 {
|
||||||
@ -91,7 +91,7 @@ impl Key<blooms::BloomGroup> for TraceGroupPosition {
|
|||||||
/// Trace database.
|
/// Trace database.
|
||||||
pub struct TraceDB<T> where T: DatabaseExtras {
|
pub struct TraceDB<T> where T: DatabaseExtras {
|
||||||
// cache
|
// cache
|
||||||
traces: RwLock<HashMap<H256, BlockTraces>>,
|
traces: RwLock<HashMap<H256, FlatBlockTraces>>,
|
||||||
blooms: RwLock<HashMap<TraceGroupPosition, blooms::BloomGroup>>,
|
blooms: RwLock<HashMap<TraceGroupPosition, blooms::BloomGroup>>,
|
||||||
// db
|
// db
|
||||||
tracesdb: Database,
|
tracesdb: Database,
|
||||||
@ -153,15 +153,13 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns traces for block with hash.
|
/// 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)
|
self.tracesdb.read_with_cache(&self.traces, block_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns vector of transaction traces for given block.
|
/// Returns vector of transaction traces for given block.
|
||||||
fn transactions_traces(&self, block_hash: &H256) -> Option<Vec<FlatTransactionTraces>> {
|
fn transactions_traces(&self, block_hash: &H256) -> Option<Vec<FlatTransactionTraces>> {
|
||||||
self.traces(block_hash)
|
self.traces(block_hash).map(Into::into)
|
||||||
.map(FlatBlockTraces::from)
|
|
||||||
.map(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matching_block_traces(
|
fn matching_block_traces(
|
||||||
@ -232,7 +230,7 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
|
|||||||
let mut traces = self.traces.write();
|
let mut traces = self.traces.write();
|
||||||
// it's important to use overwrite here,
|
// it's important to use overwrite here,
|
||||||
// cause this value might be queried by hash later
|
// 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
|
// 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");
|
.expect("Expected to find block hash. Extras db is probably corrupted");
|
||||||
let traces = self.traces(&hash)
|
let traces = self.traces(&hash)
|
||||||
.expect("Expected to find a trace. Db is probably corrupted.");
|
.expect("Expected to find a trace. Db is probably corrupted.");
|
||||||
let flat_block = FlatBlockTraces::from(traces);
|
self.matching_block_traces(filter, traces, hash, number)
|
||||||
self.matching_block_traces(filter, flat_block, hash, number)
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,15 @@
|
|||||||
|
|
||||||
//! Flat trace module
|
//! Flat trace module
|
||||||
|
|
||||||
|
use util::rlp::*;
|
||||||
use trace::BlockTraces;
|
use trace::BlockTraces;
|
||||||
|
use basic_types::LogBloom;
|
||||||
use super::trace::{Trace, Action, Res};
|
use super::trace::{Trace, Action, Res};
|
||||||
|
|
||||||
/// Trace localized in vector of traces produced by a single transaction.
|
/// Trace localized in vector of traces produced by a single transaction.
|
||||||
///
|
///
|
||||||
/// Parent and children indexes refer to positions in this vector.
|
/// Parent and children indexes refer to positions in this vector.
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct FlatTrace {
|
pub struct FlatTrace {
|
||||||
/// Type of action performed by a transaction.
|
/// Type of action performed by a transaction.
|
||||||
pub action: Action,
|
pub action: Action,
|
||||||
@ -35,9 +38,59 @@ pub struct FlatTrace {
|
|||||||
pub trace_address: Vec<usize>,
|
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.
|
/// Represents all traces produced by a single transaction.
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct FlatTransactionTraces(Vec<FlatTrace>);
|
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 {
|
impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||||
fn into(self) -> Vec<FlatTrace> {
|
fn into(self) -> Vec<FlatTrace> {
|
||||||
self.0
|
self.0
|
||||||
@ -45,8 +98,27 @@ impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents all traces produced by transactions in a single block.
|
/// Represents all traces produced by transactions in a single block.
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct FlatBlockTraces(Vec<FlatTransactionTraces>);
|
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 {
|
impl From<BlockTraces> for FlatBlockTraces {
|
||||||
fn from(block_traces: BlockTraces) -> Self {
|
fn from(block_traces: BlockTraces) -> Self {
|
||||||
let traces: Vec<Trace> = block_traces.into();
|
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].trace_address, vec![1]);
|
||||||
assert_eq!(ordered_traces[4].subtraces, 0);
|
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 from_matches = self.from_address.matches(&create.from);
|
||||||
let to_matches = self.to_address.matches_all();
|
let to_matches = self.to_address.matches_all();
|
||||||
from_matches && to_matches
|
from_matches && to_matches
|
||||||
}
|
},
|
||||||
Action::Suicide(ref suicide) => {
|
Action::Suicide(ref suicide) => {
|
||||||
let from_matches = self.from_address.matches(&suicide.address);
|
let from_matches = self.from_address.matches(&suicide.address);
|
||||||
let to_matches = self.to_address.matches(&suicide.refund_address);
|
let to_matches = self.to_address.matches(&suicide.refund_address);
|
||||||
|
Loading…
Reference in New Issue
Block a user