diff --git a/Cargo.lock b/Cargo.lock index d86f8fab9d2..345a7fb0614 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,11 +181,6 @@ dependencies = [ "keccak-hash 0.1.0", ] -[[package]] -name = "bloomchain" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bn" version = "0.4.4" @@ -476,7 +471,6 @@ version = "1.9.0" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bloomable 0.1.0", - "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bn 0.4.4 (git+https://github.com/paritytech/bn)", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", @@ -3608,7 +3602,6 @@ dependencies = [ "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d" "checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "" "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" "checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 35b2e9bc705..883fc002093 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -8,7 +8,6 @@ authors = ["Parity Technologies "] [dependencies] ansi_term = "0.9" -bloomchain = "0.1" bn = { git = "https://github.com/paritytech/bn" } byteorder = "1.0" common-types = { path = "types" } diff --git a/ethcore/src/blooms/bloom_group.rs b/ethcore/src/blooms/bloom_group.rs deleted file mode 100644 index 1867b7ecc5b..00000000000 --- a/ethcore/src/blooms/bloom_group.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use bloomchain::group as bc; -use rlp::*; -use heapsize::HeapSizeOf; -use super::Bloom; - -/// Represents group of X consecutive blooms. -#[derive(Debug, Clone)] -pub struct BloomGroup { - blooms: Vec, -} - -impl From for BloomGroup { - fn from(group: bc::BloomGroup) -> Self { - let blooms = group.blooms - .into_iter() - .map(From::from) - .collect(); - - BloomGroup { - blooms: blooms - } - } -} - -impl Into for BloomGroup { - fn into(self) -> bc::BloomGroup { - let blooms = self.blooms - .into_iter() - .map(Into::into) - .collect(); - - bc::BloomGroup { - blooms: blooms - } - } -} - -impl Decodable for BloomGroup { - fn decode(rlp: &UntrustedRlp) -> Result { - let blooms = rlp.as_list()?; - let group = BloomGroup { - blooms: blooms - }; - Ok(group) - } -} - -impl Encodable for BloomGroup { - fn rlp_append(&self, s: &mut RlpStream) { - s.append_list(&self.blooms); - } -} - -impl HeapSizeOf for BloomGroup { - fn heap_size_of_children(&self) -> usize { - self.blooms.heap_size_of_children() - } -} diff --git a/ethcore/src/blooms/group_position.rs b/ethcore/src/blooms/group_position.rs deleted file mode 100644 index b1ea8279261..00000000000 --- a/ethcore/src/blooms/group_position.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use bloomchain::group as bc; -use heapsize::HeapSizeOf; - -/// Represents `BloomGroup` position in database. -#[derive(PartialEq, Eq, Hash, Clone, Debug)] -pub struct GroupPosition { - /// Bloom level. - pub level: u8, - /// Group index. - pub index: u32, -} - -impl From for GroupPosition { - fn from(p: bc::GroupPosition) -> Self { - GroupPosition { - level: p.level as u8, - index: p.index as u32, - } - } -} - -impl HeapSizeOf for GroupPosition { - fn heap_size_of_children(&self) -> usize { - 0 - } -} diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index fdbd35e950d..b4ae063b437 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -54,7 +54,6 @@ //! cargo build --release //! ``` -extern crate bloomchain; extern crate bn; extern crate byteorder; extern crate crossbeam; @@ -155,7 +154,6 @@ pub mod verification; pub mod views; mod cache_manager; -mod blooms; mod basic_types; mod pod_account; mod state_db; diff --git a/ethcore/src/trace/bloom.rs b/ethcore/src/trace/bloom.rs deleted file mode 100644 index ed34d650510..00000000000 --- a/ethcore/src/trace/bloom.rs +++ /dev/null @@ -1,77 +0,0 @@ -use bloomchain::Bloom; -use bloomchain::group::{BloomGroup, GroupPosition}; -use basic_types::LogBloom; - -/// Helper structure representing bloom of the trace. -#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)] -pub struct BlockTracesBloom(LogBloom); - -impl From for BlockTracesBloom { - fn from(bloom: LogBloom) -> BlockTracesBloom { - BlockTracesBloom(bloom) - } -} - -impl From for BlockTracesBloom { - fn from(bloom: Bloom) -> BlockTracesBloom { - let bytes: [u8; 256] = bloom.into(); - BlockTracesBloom(LogBloom::from(bytes)) - } -} - -impl Into for BlockTracesBloom { - fn into(self) -> Bloom { - let log = self.0; - Bloom::from(log.0) - } -} - -/// Represents group of X consecutive blooms. -#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)] -pub struct BlockTracesBloomGroup { - blooms: Vec, -} - -impl From for BlockTracesBloomGroup { - fn from(group: BloomGroup) -> Self { - let blooms = group.blooms - .into_iter() - .map(From::from) - .collect(); - - BlockTracesBloomGroup { - blooms: blooms - } - } -} - -impl Into for BlockTracesBloomGroup { - fn into(self) -> BloomGroup { - let blooms = self.blooms - .into_iter() - .map(Into::into) - .collect(); - - BloomGroup { - blooms: blooms - } - } -} - -/// Represents `BloomGroup` position in database. -#[derive(PartialEq, Eq, Hash, Clone, Debug)] -pub struct TraceGroupPosition { - /// Bloom level. - pub level: u8, - /// Group index. - pub index: u32, -} - -impl From for TraceGroupPosition { - fn from(p: GroupPosition) -> Self { - TraceGroupPosition { - level: p.level as u8, - index: p.index as u32, - } - } -} diff --git a/ethcore/src/trace/config.rs b/ethcore/src/trace/config.rs index dbd8a97affe..59ce099de0b 100644 --- a/ethcore/src/trace/config.rs +++ b/ethcore/src/trace/config.rs @@ -15,7 +15,6 @@ // along with Parity. If not, see . //! Traces config. -use bloomchain::Config as BloomConfig; /// Traces config. #[derive(Debug, PartialEq, Clone)] @@ -23,8 +22,6 @@ pub struct Config { /// Indicates if tracing should be enabled or not. /// If it's None, it will be automatically configured. pub enabled: bool, - /// Traces blooms configuration. - pub blooms: BloomConfig, /// Preferef cache-size. pub pref_cache_size: usize, /// Max cache-size. @@ -35,10 +32,6 @@ impl Default for Config { fn default() -> Self { Config { enabled: false, - blooms: BloomConfig { - levels: 3, - elements_per_index: 16, - }, pref_cache_size: 15 * 1024 * 1024, max_cache_size: 20 * 1024 * 1024, } diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index e90eedc4b73..5ab5d96ccfa 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -15,19 +15,15 @@ // along with Parity. If not, see . //! Trace database. -use std::ops::Deref; use std::collections::{HashMap, VecDeque}; use std::sync::Arc; -use bloomchain::{Number, Config as BloomConfig}; -use bloomchain::group::{BloomGroupDatabase, BloomGroupChain, GroupPosition, BloomGroup}; use heapsize::HeapSizeOf; -use bigint::hash::{H256, H264}; +use bigint::hash::{H256, H264, H2048 as Bloom}; use kvdb::{KeyValueDB, DBTransaction}; use parking_lot::RwLock; use header::BlockNumber; use trace::{LocalizedTrace, Config, Filter, Database as TraceDatabase, ImportRequest, DatabaseExtras}; use db::{self, Key, Writable, Readable, CacheUpdatePolicy}; -use blooms; use super::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces}; use cache_manager::CacheManager; @@ -37,8 +33,8 @@ const TRACE_DB_VER: &'static [u8] = b"1.0"; enum TraceDBIndex { /// Block traces index. BlockTraces = 0, - /// Trace bloom group index. - BloomGroups = 1, + /// Blooms index. + Blooms = 2, } impl Key for H256 { @@ -52,80 +48,37 @@ impl Key for H256 { } } -/// Wrapper around `blooms::GroupPosition` so it could be -/// uniquely identified in the database. -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -struct TraceGroupPosition(blooms::GroupPosition); - -impl From for TraceGroupPosition { - fn from(position: GroupPosition) -> Self { - TraceGroupPosition(From::from(position)) - } -} - -impl HeapSizeOf for TraceGroupPosition { - fn heap_size_of_children(&self) -> usize { - 0 - } -} - -/// Helper data structure created cause [u8; 6] does not implement Deref to &[u8]. -pub struct TraceGroupKey([u8; 6]); - -impl Deref for TraceGroupKey { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} +impl Key for H256 { + type Target = H264; -impl Key for TraceGroupPosition { - type Target = TraceGroupKey; - - fn key(&self) -> Self::Target { - let mut result = [0u8; 6]; - result[0] = TraceDBIndex::BloomGroups as u8; - result[1] = self.0.level; - result[2] = self.0.index as u8; - result[3] = (self.0.index >> 8) as u8; - result[4] = (self.0.index >> 16) as u8; - result[5] = (self.0.index >> 24) as u8; - TraceGroupKey(result) + fn key(&self) -> H264 { + let mut result = H264::default(); + result[0] = TraceDBIndex::Blooms as u8; + result[1..33].copy_from_slice(self); + result } } #[derive(Debug, Hash, Eq, PartialEq)] enum CacheId { Trace(H256), - Bloom(TraceGroupPosition), + Bloom(H256), } /// Trace database. pub struct TraceDB where T: DatabaseExtras { // cache traces: RwLock>, - blooms: RwLock>, + blooms: RwLock>, cache_manager: RwLock>, // db tracesdb: Arc, - // config, - bloom_config: BloomConfig, // tracing enabled enabled: bool, // extras extras: Arc, } -impl BloomGroupDatabase for TraceDB where T: DatabaseExtras { - fn blooms_at(&self, position: &GroupPosition) -> Option { - let position = TraceGroupPosition::from(position.clone()); - let result = self.tracesdb.read_with_cache(db::COL_TRACE, &self.blooms, &position).map(Into::into); - self.note_used(CacheId::Bloom(position)); - result - } -} - impl TraceDB where T: DatabaseExtras { /// Creates new instance of `TraceDB`. pub fn new(config: Config, tracesdb: Arc, extras: Arc) -> Self { @@ -137,13 +90,12 @@ impl TraceDB where T: DatabaseExtras { tracesdb.write(batch).expect("failed to update version"); TraceDB { - traces: RwLock::new(HashMap::new()), - blooms: RwLock::new(HashMap::new()), cache_manager: RwLock::new(CacheManager::new(config.pref_cache_size, config.max_cache_size, 10 * 1024)), - tracesdb: tracesdb, - bloom_config: config.blooms, + tracesdb, enabled: config.enabled, - extras: extras, + extras, + traces: RwLock::default(), + blooms: RwLock::default(), } } @@ -188,6 +140,12 @@ impl TraceDB where T: DatabaseExtras { result } + fn bloom(&self, block_hash: &H256) -> Option { + let result = self.tracesdb.read_with_cache(db::COL_TRACE, &self.blooms, block_hash); + self.note_used(CacheId::Bloom(block_hash.clone())); + result + } + /// Returns vector of transaction traces for given block. fn transactions_traces(&self, block_hash: &H256) -> Option> { self.traces(block_hash).map(Into::into) @@ -264,49 +222,16 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { return; } - // now let's rebuild the blooms - if !request.enacted.is_empty() { - let range_start = request.block_number as Number + 1 - request.enacted.len(); - let range_end = range_start + request.retracted; - let replaced_range = range_start..range_end; - let enacted_blooms = request.enacted - .iter() - // all traces are expected to be found here. That's why `expect` has been used - // instead of `filter_map`. If some traces haven't been found, it meens that - // traces database is corrupted or incomplete. - .map(|block_hash| if block_hash == &request.block_hash { - request.traces.bloom() - } else { - self.traces(block_hash).expect("Traces database is incomplete.").bloom() - }) - .map(blooms::Bloom::from) - .map(Into::into) - .collect(); - - let chain = BloomGroupChain::new(self.bloom_config, self); - let trace_blooms = chain.replace(&replaced_range, enacted_blooms); - let blooms_to_insert = trace_blooms.into_iter() - .map(|p| (From::from(p.0), From::from(p.1))) - .collect::>(); - - let blooms_keys: Vec<_> = blooms_to_insert.keys().cloned().collect(); - let mut blooms = self.blooms.write(); - batch.extend_with_cache(db::COL_TRACE, &mut *blooms, blooms_to_insert, CacheUpdatePolicy::Remove); - // note_used must be called after locking blooms to avoid cache/traces deadlock on garbage collection - for key in blooms_keys { - self.note_used(CacheId::Bloom(key)); - } - } - // insert new block traces into the cache and the database - { - 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(db::COL_TRACE, &mut *traces, request.block_hash, request.traces, CacheUpdatePolicy::Overwrite); - // note_used must be called after locking traces to avoid cache/traces deadlock on garbage collection - self.note_used(CacheId::Trace(request.block_hash.clone())); - } + let mut traces = self.traces.write(); + let mut blooms = self.blooms.write(); + // it's important to use overwrite here, + // cause this value might be queried by hash later + batch.write_with_cache(db::COL_TRACE, &mut *blooms, request.block_hash, request.traces.bloom(), CacheUpdatePolicy::Overwrite); + batch.write_with_cache(db::COL_TRACE, &mut *traces, request.block_hash, request.traces, CacheUpdatePolicy::Overwrite); + // note_used must be called after locking traces to avoid cache/traces deadlock on garbage collection + self.note_used(CacheId::Trace(request.block_hash)); + self.note_used(CacheId::Bloom(request.block_hash)); } fn trace(&self, block_number: BlockNumber, tx_position: usize, trace_position: Vec) -> Option { @@ -393,15 +318,17 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { } fn filter(&self, filter: &Filter) -> Vec { - let chain = BloomGroupChain::new(self.bloom_config, self); - let numbers = chain.filter(filter); - numbers.into_iter() - .flat_map(|n| { - let number = n as BlockNumber; - let hash = self.extras.block_hash(number) - .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 possibilities = filter.bloom_possibilities(); + // + 1, cause filters are inclusive + (filter.range.start..filter.range.end + 1).into_iter() + .map(|n| n as BlockNumber) + .filter_map(|n| self.extras.block_hash(n).map(|hash| (n, hash))) + .filter(|&(_,ref hash)| { + let bloom = self.bloom(hash).expect("hash exists; qed"); + possibilities.iter().any(|p| bloom.contains(p)) + }) + .flat_map(|(number, hash)| { + let traces = self.traces(&hash).expect("hash exists; qed"); self.matching_block_traces(filter, traces, hash, number) }) .collect() diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index 991e434fc29..e427af7d2b3 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -16,7 +16,6 @@ //! Tracing -mod bloom; mod config; mod db; mod executive_tracer; diff --git a/ethcore/src/trace/types/filter.rs b/ethcore/src/trace/types/filter.rs index f7e2d214076..4df362d173f 100644 --- a/ethcore/src/trace/types/filter.rs +++ b/ethcore/src/trace/types/filter.rs @@ -17,10 +17,10 @@ //! Trace filters type definitions use std::ops::Range; -use bloomchain::{Filter as BloomFilter, Bloom, Number}; use hash::keccak; use util::Address; use bloomable::Bloomable; +use bigint::prelude::H2048 as Bloom; use basic_types::LogBloom; use trace::flat::FlatTrace; use super::trace::{Action, Res}; @@ -87,22 +87,9 @@ pub struct Filter { pub to_address: AddressesFilter, } -impl BloomFilter for Filter { - fn bloom_possibilities(&self) -> Vec { - self.bloom_possibilities() - .into_iter() - .map(|b| Bloom::from(b.0)) - .collect() - } - - fn range(&self) -> Range { - self.range.clone() - } -} - impl Filter { /// Returns combinations of each address. - fn bloom_possibilities(&self) -> Vec { + pub fn bloom_possibilities(&self) -> Vec { self.to_address.with_blooms(self.from_address.blooms()) }