Commit 458afcd2 authored by Marek Kotewicz's avatar Marek Kotewicz Committed by Afri Schoedon
Browse files

new blooms database (#8712)

* new blooms database

* fixed conflict in Cargo.lock

* removed bloomchain

* cleanup in progress

* all tests passing in trace db with new blooms-db

* added trace_blooms to BlockChainDB interface, fixed db flushing

* BlockChainDB no longer exposes RwLock in the interface

* automatically flush blooms-db after every insert

* blooms-db uses io::BufReader to read files, wrap blooms-db into Mutex, cause fs::File is just a shared file handle

* fix json_tests

* blooms-db can filter multiple possibilities at the same time

* removed enum trace/db.rs CacheId

* lint fixes

* fixed tests

* kvdb-rocksdb uses fs-swap crate

* update Cargo.lock

* use fs::rename

* fixed failing test on linux

* fix tests

* use fs_swap

* fixed failing test on linux

* cleanup after swap

* fix tests

* fixed osx permissions

* simplify parity database opening functions

* added migration to blooms-db

* address @niklasad1 grumbles

* fix license and authors field of blooms-db Cargo.toml

* restore blooms-db after snapshot
parent cf5ae81c
......@@ -151,12 +151,14 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bloomchain"
version = "0.2.0"
name = "blooms-db"
version = "0.1.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -512,7 +514,7 @@ name = "ethcore"
version = "1.12.0"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bloomchain 0.2.0",
"blooms-db 0.1.0",
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0",
......@@ -1112,6 +1114,15 @@ name = "fnv"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fs-swap"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
......@@ -1500,6 +1511,7 @@ version = "0.1.0"
dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fs-swap 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb 0.1.0",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -1980,6 +1992,7 @@ version = "1.12.0"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"blooms-db 0.1.0",
"clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
"daemonize 0.2.3 (git+https://github.com/paritytech/daemonize)",
......@@ -3855,6 +3868,7 @@ dependencies = [
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum fs-swap 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "18c72c2e124a7f8cf6966d72143940885a0936f30cabe807001552126a50737d"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
......
......@@ -7,6 +7,7 @@ license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
blooms-db = { path = "util/blooms-db" }
log = "0.3"
env_logger = "0.4"
rustc-hex = "1.0"
......
......@@ -8,7 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ansi_term = "0.10"
bloomchain = { path = "../util/bloomchain" }
blooms-db = { path = "../util/blooms-db" }
bn = { git = "https://github.com/paritytech/bn", default-features = false }
byteorder = "1.0"
common-types = { path = "types" }
......@@ -67,11 +67,11 @@ keccak-hash = { path = "../util/hash" }
triehash = { path = "../util/triehash" }
unexpected = { path = "../util/unexpected" }
journaldb = { path = "../util/journaldb" }
tempdir = "0.3"
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
[dev-dependencies]
tempdir = "0.3"
trie-standardmap = { path = "../util/trie-standardmap" }
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
[features]
# Display EVM debug traces.
......
......@@ -21,11 +21,10 @@ use std::fmt;
use std::sync::Arc;
use ethcore::client::ClientIoMessage;
use ethcore::db;
use ethcore::{db, BlockChainDB};
use ethcore::error::Error as CoreError;
use ethcore::spec::Spec;
use io::{IoContext, IoError, IoHandler, IoService};
use kvdb::KeyValueDB;
use cache::Cache;
use parking_lot::Mutex;
......@@ -65,11 +64,10 @@ pub struct Service<T> {
impl<T: ChainDataFetcher> Service<T> {
/// Start the service: initialize I/O workers and client itself.
pub fn start(config: ClientConfig, spec: &Spec, fetcher: T, db: Arc<KeyValueDB>, cache: Arc<Mutex<Cache>>) -> Result<Self, Error> {
pub fn start(config: ClientConfig, spec: &Spec, fetcher: T, db: Arc<BlockChainDB>, cache: Arc<Mutex<Cache>>) -> Result<Self, Error> {
let io_service = IoService::<ClientIoMessage>::start().map_err(Error::Io)?;
let client = Arc::new(Client::new(config,
db,
db.key_value().clone(),
db::COL_LIGHT_CHAIN,
spec,
fetcher,
......@@ -122,12 +120,11 @@ mod tests {
use client::fetch;
use std::time::Duration;
use parking_lot::Mutex;
use kvdb_memorydb;
use ethcore::db::NUM_COLUMNS;
use ethcore::test_helpers;
#[test]
fn it_works() {
let db = Arc::new(kvdb_memorydb::create(NUM_COLUMNS.unwrap_or(0)));
let db = test_helpers::new_db();
let spec = Spec::new_test();
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::from_secs(6 * 3600))));
......
......@@ -115,6 +115,7 @@ mod test {
use ethcore::spec::Spec;
use ethcore::client::{BlockChainClient, Client, ClientConfig};
use ethcore::miner::Miner;
use ethcore::test_helpers;
use network::{ConnectionDirection, ConnectionFilter, NodeId};
use io::IoChannel;
use super::NodeFilter;
......@@ -127,7 +128,7 @@ mod test {
let data = include_bytes!("../res/node_filter.json");
let tempdir = TempDir::new("").unwrap();
let spec = Spec::load(&tempdir.path(), &data[..]).unwrap();
let client_db = Arc::new(::kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0)));
let client_db = test_helpers::new_db();
let client = Client::new(
ClientConfig::default(),
......
......@@ -22,10 +22,10 @@ use std::time::Duration;
use ansi_term::Colour;
use io::{IoContext, TimerToken, IoHandler, IoService, IoError};
use kvdb::{KeyValueDB, KeyValueDBHandler};
use stop_guard::StopGuard;
use sync::PrivateTxHandler;
use ethcore::{BlockChainDB, BlockChainDBHandler};
use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage};
use ethcore::miner::Miner;
use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams};
......@@ -69,7 +69,7 @@ pub struct ClientService {
client: Arc<Client>,
snapshot: Arc<SnapshotService>,
private_tx: Arc<PrivateTxService>,
database: Arc<KeyValueDB>,
database: Arc<BlockChainDB>,
_stop_guard: StopGuard,
}
......@@ -78,9 +78,9 @@ impl ClientService {
pub fn start(
config: ClientConfig,
spec: &Spec,
client_db: Arc<KeyValueDB>,
blockchain_db: Arc<BlockChainDB>,
snapshot_path: &Path,
restoration_db_handler: Box<KeyValueDBHandler>,
restoration_db_handler: Box<BlockChainDBHandler>,
_ipc_path: &Path,
miner: Arc<Miner>,
account_provider: Arc<AccountProvider>,
......@@ -93,7 +93,7 @@ impl ClientService {
info!("Configured for {} using {} engine", Colour::White.bold().paint(spec.name.clone()), Colour::Yellow.bold().paint(spec.engine.name()));
let pruning = config.pruning;
let client = Client::new(config, &spec, client_db.clone(), miner.clone(), io_service.channel())?;
let client = Client::new(config, &spec, blockchain_db.clone(), miner.clone(), io_service.channel())?;
let snapshot_params = SnapServiceParams {
engine: spec.engine.clone(),
......@@ -131,7 +131,7 @@ impl ClientService {
client: client,
snapshot: snapshot,
private_tx,
database: client_db,
database: blockchain_db,
_stop_guard: stop_guard,
})
}
......@@ -167,7 +167,7 @@ impl ClientService {
}
/// Get a handle to the database.
pub fn db(&self) -> Arc<KeyValueDB> { self.database.clone() }
pub fn db(&self) -> Arc<BlockChainDB> { self.database.clone() }
/// Shutdown the Client Service
pub fn shutdown(&self) {
......@@ -259,8 +259,8 @@ mod tests {
use ethcore::miner::Miner;
use ethcore::spec::Spec;
use ethcore::db::NUM_COLUMNS;
use kvdb::Error;
use kvdb_rocksdb::{Database, DatabaseConfig, CompactionProfile};
use ethcore::test_helpers;
use kvdb_rocksdb::{DatabaseConfig, CompactionProfile};
use super::*;
use ethcore_private_tx;
......@@ -278,24 +278,9 @@ mod tests {
client_db_config.compaction = CompactionProfile::auto(&client_path);
client_db_config.wal = client_config.db_wal;
let client_db = Arc::new(Database::open(
&client_db_config,
&client_path.to_str().expect("DB path could not be converted to string.")
).unwrap());
struct RestorationDBHandler {
config: DatabaseConfig,
}
impl KeyValueDBHandler for RestorationDBHandler {
fn open(&self, db_path: &Path) -> Result<Arc<KeyValueDB>, Error> {
Ok(Arc::new(Database::open(&self.config, &db_path.to_string_lossy())?))
}
}
let restoration_db_handler = Box::new(RestorationDBHandler {
config: client_db_config,
});
let client_db_handler = test_helpers::restoration_db_handler(client_db_config.clone());
let client_db = client_db_handler.open(&client_path).unwrap();
let restoration_db_handler = test_helpers::restoration_db_handler(client_db_config);
let spec = Spec::new_test();
let service = ClientService::start(
......
This diff is collapsed.
......@@ -23,8 +23,6 @@ pub struct CacheSize {
pub block_details: usize,
/// Transaction addresses cache size.
pub transaction_addresses: usize,
/// Blooms cache size.
pub blocks_blooms: usize,
/// Block receipts size.
pub block_receipts: usize,
}
......@@ -32,6 +30,6 @@ pub struct CacheSize {
impl CacheSize {
/// Total amount used by the cache.
pub fn total(&self) -> usize {
self.blocks + self.block_details + self.transaction_addresses + self.blocks_blooms + self.block_receipts
self.blocks + self.block_details + self.transaction_addresses + self.block_receipts
}
}
......@@ -18,7 +18,6 @@
use std::ops;
use std::io::Write;
use blooms::{GroupPosition, BloomGroup};
use db::Key;
use engines::epoch::{Transition as EpochTransition};
use header::BlockNumber;
......@@ -38,8 +37,6 @@ pub enum ExtrasIndex {
BlockHash = 1,
/// Transaction address index
TransactionAddress = 2,
/// Block blooms index
BlocksBlooms = 3,
/// Block receipts index
BlockReceipts = 4,
/// Epoch transition data index.
......@@ -87,31 +84,6 @@ impl Key<BlockDetails> for H256 {
}
}
pub struct LogGroupKey([u8; 6]);
impl ops::Deref for LogGroupKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Key<BloomGroup> for GroupPosition {
type Target = LogGroupKey;
fn key(&self) -> Self::Target {
let mut result = [0u8; 6];
result[0] = ExtrasIndex::BlocksBlooms as u8;
result[1] = self.level;
result[2] = (self.index >> 24) as u8;
result[3] = (self.index >> 16) as u8;
result[4] = (self.index >> 8) as u8;
result[5] = self.index as u8;
LogGroupKey(result)
}
}
impl Key<TransactionAddress> for H256 {
type Target = H264;
......
......@@ -28,7 +28,7 @@ mod update;
#[cfg(test)]
pub mod generator;
pub use self::blockchain::{BlockProvider, BlockChain};
pub use self::blockchain::{BlockProvider, BlockChain, BlockChainDB, BlockChainDBHandler};
pub use self::cache::CacheSize;
pub use self::config::Config;
pub use self::extras::{BlockReceipts, BlockDetails, TransactionAddress};
......
......@@ -15,11 +15,10 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::HashMap;
use ethereum_types::H256;
use ethereum_types::{H256, Bloom};
use header::BlockNumber;
use blockchain::block_info::BlockInfo;
use blockchain::extras::{BlockDetails, BlockReceipts, TransactionAddress};
use blooms::{BloomGroup, GroupPosition};
/// Block extras update info.
pub struct ExtrasUpdate<'a> {
......@@ -34,7 +33,7 @@ pub struct ExtrasUpdate<'a> {
/// Modified block receipts.
pub block_receipts: HashMap<H256, BlockReceipts>,
/// Modified blocks blooms.
pub blocks_blooms: HashMap<GroupPosition, BloomGroup>,
pub blocks_blooms: Option<(u64, Vec<Bloom>)>,
/// Modified transaction addresses (None signifies removed transactions).
pub transactions_addresses: HashMap<H256, Option<TransactionAddress>>,
}
......
// Copyright 2015-2018 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 <http://www.gnu.org/licenses/>.
use bloomchain::group as bc;
use heapsize::HeapSizeOf;
use ethereum_types::Bloom;
/// Represents group of X consecutive blooms.
#[derive(Debug, Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct BloomGroup {
blooms: Vec<Bloom>,
}
impl BloomGroup {
pub fn accrue_bloom_group(&mut self, group: &BloomGroup) {
for (bloom, other) in self.blooms.iter_mut().zip(group.blooms.iter()) {
bloom.accrue_bloom(other);
}
}
}
impl From<bc::BloomGroup> for BloomGroup {
fn from(group: bc::BloomGroup) -> Self {
BloomGroup {
blooms: group.blooms
}
}
}
impl Into<bc::BloomGroup> for BloomGroup {
fn into(self) -> bc::BloomGroup {
bc::BloomGroup {
blooms: self.blooms
}
}
}
impl HeapSizeOf for BloomGroup {
fn heap_size_of_children(&self) -> usize {
self.blooms.heap_size_of_children()
}
}
// Copyright 2015-2018 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 <http://www.gnu.org/licenses/>.
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<bc::GroupPosition> 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
}
}
// Copyright 2015-2018 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 <http://www.gnu.org/licenses/>.
//! Bridge between bloomchain crate types and ethcore.
mod bloom_group;
mod group_position;
pub use self::bloom_group::BloomGroup;
pub use self::group_position::GroupPosition;
......@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::{HashSet, BTreeMap, BTreeSet, VecDeque};
use std::collections::{HashSet, BTreeMap, VecDeque};
use std::fmt;
use std::str::FromStr;
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
......@@ -33,7 +33,7 @@ use util_error::UtilError;
// other
use ethereum_types::{H256, Address, U256};
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
use blockchain::{BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
use client::ancient_import::AncientVerifier;
use client::Error as ClientError;
use client::{
......@@ -191,7 +191,7 @@ pub struct Client {
pruning: journaldb::Algorithm,
/// Client uses this to store blocks, traces, etc.
db: RwLock<Arc<KeyValueDB>>,
db: RwLock<Arc<BlockChainDB>>,
state_db: RwLock<StateDB>,
......@@ -342,7 +342,8 @@ impl Importer {
}
}
client.db.read().flush().expect("DB flush failed.");
let db = client.db.read();
db.key_value().flush().expect("DB flush failed.");
imported
}
......@@ -555,7 +556,7 @@ impl Importer {
let is_canon = route.enacted.last().map_or(false, |h| h == hash);
state.sync_cache(&route.enacted, &route.retracted, is_canon);
// Final commit to the DB
client.db.read().write_buffered(batch);
client.db.read().key_value().write_buffered(batch);
chain.commit();
self.check_epoch_end(&header, &chain, client);
......@@ -683,7 +684,7 @@ impl Importer {
// always write the batch directly since epoch transition proofs are
// fetched from a DB iterator and DB iterators are only available on
// flushed data.
client.db.read().write(batch).expect("DB flush failed");
client.db.read().key_value().write(batch).expect("DB flush failed");
}
}
}
......@@ -694,7 +695,7 @@ impl Client {
pub fn new(
config: ClientConfig,
spec: &Spec,
db: Arc<KeyValueDB>,
db: Arc<BlockChainDB>,
miner: Arc<Miner>,
message_channel: IoChannel<ClientIoMessage>,
) -> Result<Arc<Client>, ::error::Error> {
......@@ -710,14 +711,14 @@ impl Client {
accountdb: Default::default(),
};
let journal_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
let journal_db = journaldb::new(db.key_value().clone(), config.pruning, ::db::COL_STATE);
let mut state_db = StateDB::new(journal_db, config.state_cache_size);
if state_db.journal_db().is_empty() {
// Sets the correct state root.
state_db = spec.ensure_db_good(state_db, &factories)?;
let mut batch = DBTransaction::new();
state_db.journal_under(&mut batch, 0, &spec.genesis_header().hash())?;
db.write(batch).map_err(ClientError::Database)?;
db.key_value().write(batch).map_err(ClientError::Database)?;
}
let gb = spec.genesis_block();
......@@ -760,7 +761,7 @@ impl Client {
engine: engine,
pruning: config.pruning.clone(),
config: config,
db: RwLock::new(db),
db: RwLock::new(db.clone()),
state_db: RwLock::new(state_db),
report: RwLock::new(Default::default()),
io_channel: Mutex::new(message_channel),
......@@ -815,12 +816,12 @@ impl Client {
proof: proof,
});
client.db.read().write_buffered(batch);
client.db.read().key_value().write_buffered(batch);
}
}
// ensure buffered changes are flushed.
client.db.read().flush().map_err(ClientError::Database)?;
client.db.read().key_value().flush().map_err(ClientError::Database)?;
Ok(client)
}
......@@ -964,7 +965,7 @@ impl Client {
Some(ancient_hash) => {
let mut batch = DBTransaction::new();
state_db.mark_canonical(&mut batch, era, &ancient_hash)?;
self.db.read().write_buffered(batch);
self.db.read().key_value().write_buffered(batch);
state_db.journal_db().flush();
}
None =>
......@@ -1294,10 +1295,12 @@ impl snapshot::DatabaseRestore for Client {
let mut tracedb = self.tracedb.write();
self.importer.miner.clear();
let db = self.db.write();
db.restore(new_db)?;
db.key_value().restore(new_db)?;
db.blooms().reopen()?;
db.trace_blooms().reopen()?;
let cache_size = state_db.cache_size();
*state_db = StateDB::new(journaldb::new(db.clone(), self.pruning, ::db::COL_STATE), cache_size);
*state_db = StateDB::new(journaldb::new(db.key_value().clone(), self.pruning, ::db::COL_STATE), cache_size);
*chain = Arc::new(BlockChain::new(self.config.blockchain.clone(), &[], db.clone()));
*tracedb = TraceDB::new(self.config.tracing.clone(), db.clone(), chain.clone());
Ok(())
......@@ -1839,17 +1842,10 @@ impl BlockChainClient for Client {
let from = self.block_number_ref(&filter.from_block)?;
let to = self.block_number_ref(&filter.to_block)?;
filter.bloom_possibilities().iter()
.map(|bloom| {
chain.blocks_with_bloom(bloom, from, to)
})