diff --git a/ethcore/src/types/trace_types/filter.rs b/ethcore/src/types/trace_types/filter.rs index 91d1c421d..6dd71a238 100644 --- a/ethcore/src/types/trace_types/filter.rs +++ b/ethcore/src/types/trace_types/filter.rs @@ -22,7 +22,7 @@ use util::{Address, FixedHash}; use util::sha3::Hashable; use basic_types::LogBloom; use trace::flat::FlatTrace; -use types::trace_types::trace::Action; +use types::trace_types::trace::{Action, Res}; use ipc::binary::BinaryConvertError; use std::mem; use std::collections::VecDeque; @@ -58,7 +58,7 @@ impl AddressesFilter { true => vec![LogBloom::new()], false => self.list.iter() .map(|address| LogBloom::from_bloomed(&address.sha3())) - .collect() + .collect(), } } @@ -71,7 +71,7 @@ impl AddressesFilter { .flat_map(|bloom| self.list.iter() .map(|address| bloom.with_bloomed(&address.sha3())) .collect::>()) - .collect() + .collect(), } } } @@ -110,12 +110,12 @@ impl Filter { /// Returns true if given trace matches the filter. pub fn matches(&self, trace: &FlatTrace) -> bool { - match trace.action { + let action = match trace.action { Action::Call(ref call) => { let from_matches = self.from_address.matches(&call.from); let to_matches = self.to_address.matches(&call.to); from_matches && to_matches - }, + } Action::Create(ref create) => { let from_matches = self.from_address.matches(&create.from); let to_matches = self.to_address.matches_all(); @@ -126,6 +126,11 @@ impl Filter { let to_matches = self.to_address.matches(&suicide.refund_address); from_matches && to_matches } + }; + + action || match trace.result { + Res::Create(ref create) => self.to_address.matches(&create.address), + _ => false } } } @@ -134,7 +139,7 @@ impl Filter { mod tests { use util::{FixedHash, Address}; use util::sha3::Hashable; - use trace::trace::{Action, Call, Res, Suicide}; + use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide}; use trace::flat::FlatTrace; use trace::{Filter, AddressesFilter}; use basic_types::LogBloom; @@ -294,6 +299,30 @@ mod tests { assert!(f5.matches(&trace)); assert!(!f6.matches(&trace)); + let trace = FlatTrace { + action: Action::Create(Create { + from: 1.into(), + value: 3.into(), + gas: 4.into(), + init: vec![0x5], + }), + result: Res::Create(CreateResult { + gas_used: 10.into(), + code: vec![], + address: 2.into(), + }), + trace_address: vec![0], + subtraces: 0, + }; + + assert!(f0.matches(&trace)); + assert!(f1.matches(&trace)); + assert!(f2.matches(&trace)); + assert!(f3.matches(&trace)); + assert!(f4.matches(&trace)); + assert!(f5.matches(&trace)); + assert!(!f6.matches(&trace)); + let trace = FlatTrace { action: Action::Suicide(Suicide { address: 1.into(), diff --git a/ethcore/src/types/trace_types/trace.rs b/ethcore/src/types/trace_types/trace.rs index db90e068c..2cff2240c 100644 --- a/ethcore/src/types/trace_types/trace.rs +++ b/ethcore/src/types/trace_types/trace.rs @@ -87,6 +87,13 @@ impl Decodable for CreateResult { } } +impl CreateResult { + /// Returns bloom. + pub fn bloom(&self) -> LogBloom { + LogBloom::from_bloomed(&self.address.sha3()) + } +} + /// Description of a _call_ action, either a `CALL` operation or a message transction. #[derive(Debug, Clone, PartialEq, Binary)] pub struct Call { @@ -361,6 +368,16 @@ impl Decodable for Res { } } +impl Res { + /// Returns result bloom. + pub fn bloom(&self) -> LogBloom { + match *self { + Res::Create(ref create) => create.bloom(), + Res::Call(_) | Res::FailedCall | Res::FailedCreate | Res::None => Default::default(), + } + } +} + #[derive(Debug, Clone, PartialEq, Binary)] /// A trace; includes a description of the action being traced and sub traces of each interior action. pub struct Trace { @@ -402,7 +419,7 @@ impl Decodable for Trace { impl Trace { /// Returns trace bloom. pub fn bloom(&self) -> LogBloom { - self.subs.iter().fold(self.action.bloom(), |b, s| b | s.bloom()) + self.subs.iter().fold(self.action.bloom() | self.result.bloom(), |b, s| b | s.bloom()) } } @@ -575,7 +592,7 @@ mod tests { use util::{Address, U256, FixedHash}; use util::rlp::{encode, decode}; use util::sha3::Hashable; - use trace::trace::{Call, CallResult, Create, Res, Action, Trace, Suicide}; + use trace::trace::{Call, CallResult, Create, Res, Action, Trace, Suicide, CreateResult}; #[test] fn traces_rlp() { @@ -633,7 +650,11 @@ mod tests { init: vec![0x9] }), subs: vec![], - result: Res::FailedCreate + result: Res::Create(CreateResult { + gas_used: 10.into(), + code: vec![], + address: 15.into(), + }), }, Trace { depth: 3, @@ -659,6 +680,7 @@ mod tests { assert!(bloom.contains_bloomed(&Address::from(2).sha3())); assert!(!bloom.contains_bloomed(&Address::from(20).sha3())); assert!(bloom.contains_bloomed(&Address::from(6).sha3())); + assert!(bloom.contains_bloomed(&Address::from(15).sha3())); assert!(bloom.contains_bloomed(&Address::from(101).sha3())); assert!(bloom.contains_bloomed(&Address::from(102).sha3())); assert!(!bloom.contains_bloomed(&Address::from(103).sha3()));