Remove accounts bloom (#33)

This commit is contained in:
Artem Vorotnikov 2020-09-22 13:41:04 +03:00 committed by GitHub
parent 4fb4ef6d24
commit d17ee979b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 479 additions and 782 deletions

1058
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,6 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
ansi_term = "0.10" ansi_term = "0.10"
blooms-db = { path = "../util/blooms-db", optional = true } blooms-db = { path = "../util/blooms-db", optional = true }
byteorder = "1.0"
common-types = { path = "types" } common-types = { path = "types" }
crossbeam-utils = "0.6" crossbeam-utils = "0.6"
eip-152 = { version = "0.1", path = "../util/EIP-152" } eip-152 = { version = "0.1", path = "../util/EIP-152" }

View File

@ -33,12 +33,13 @@ pub const COL_BODIES: Option<u32> = Some(2);
pub const COL_EXTRA: Option<u32> = Some(3); pub const COL_EXTRA: Option<u32> = Some(3);
/// Column for Traces /// Column for Traces
pub const COL_TRACE: Option<u32> = Some(4); pub const COL_TRACE: Option<u32> = Some(4);
/// Column for the empty accounts bloom filter. /// Column for the accounts existence bloom filter.
#[deprecated(since = "3.0.0", note = "Accounts bloom column is deprecated")]
pub const COL_ACCOUNT_BLOOM: Option<u32> = Some(5); pub const COL_ACCOUNT_BLOOM: Option<u32> = Some(5);
/// Column for general information from the local node which can persist. /// Column for general information from the local node which can persist.
pub const COL_NODE_INFO: Option<u32> = Some(6); pub const COL_NODE_INFO: Option<u32> = Some(6);
/// Number of columns in DB /// Number of columns in DB
pub const NUM_COLUMNS: Option<u32> = Some(8); pub const NUM_COLUMNS: Option<u32> = Some(7);
/// Modes for updating caches. /// Modes for updating caches.
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

View File

@ -59,13 +59,11 @@
#![recursion_limit = "128"] #![recursion_limit = "128"]
extern crate ansi_term; extern crate ansi_term;
extern crate byteorder;
extern crate common_types as types; extern crate common_types as types;
extern crate crossbeam_utils; extern crate crossbeam_utils;
extern crate ethabi; extern crate ethabi;
extern crate ethash; extern crate ethash;
extern crate ethcore_blockchain as blockchain; extern crate ethcore_blockchain as blockchain;
extern crate ethcore_bloom_journal as bloom_journal;
extern crate ethcore_builtin as builtin; extern crate ethcore_builtin as builtin;
extern crate ethcore_call_contract as call_contract; extern crate ethcore_call_contract as call_contract;
extern crate ethcore_db as db; extern crate ethcore_db as db;

View File

@ -34,9 +34,8 @@ use blockchain::{BlockChain, BlockProvider};
use engines::EthEngine; use engines::EthEngine;
use types::{header::Header, ids::BlockId}; use types::{header::Header, ids::BlockId};
use bloom_journal::Bloom;
use bytes::Bytes; use bytes::Bytes;
use ethereum_types::{H256, U256}; use ethereum_types::H256;
use ethtrie::{TrieDB, TrieDBMut}; use ethtrie::{TrieDB, TrieDBMut};
use hash_db::HashDB; use hash_db::HashDB;
use journaldb::{self, Algorithm, JournalDB}; use journaldb::{self, Algorithm, JournalDB};
@ -50,8 +49,6 @@ use trie::{Trie, TrieMut};
use self::io::SnapshotWriter; use self::io::SnapshotWriter;
use super::{state::Account as StateAccount, state_db::StateDB};
use crossbeam_utils::thread; use crossbeam_utils::thread;
use rand::{OsRng, Rng}; use rand::{OsRng, Rng};
@ -433,7 +430,6 @@ pub struct StateRebuilder {
state_root: H256, state_root: H256,
known_code: HashMap<H256, H256>, // code hashes mapped to first account with this code. known_code: HashMap<H256, H256>, // code hashes mapped to first account with this code.
missing_code: HashMap<H256, Vec<H256>>, // maps code hashes to lists of accounts missing that code. missing_code: HashMap<H256, Vec<H256>>, // maps code hashes to lists of accounts missing that code.
bloom: Bloom,
known_storage_roots: HashMap<H256, H256>, // maps account hashes to last known storage root. Only filled for last account per chunk. known_storage_roots: HashMap<H256, H256>, // maps account hashes to last known storage root. Only filled for last account per chunk.
} }
@ -445,7 +441,6 @@ impl StateRebuilder {
state_root: KECCAK_NULL_RLP, state_root: KECCAK_NULL_RLP,
known_code: HashMap::new(), known_code: HashMap::new(),
missing_code: HashMap::new(), missing_code: HashMap::new(),
bloom: StateDB::load_bloom(&*db),
known_storage_roots: HashMap::new(), known_storage_roots: HashMap::new(),
} }
} }
@ -453,7 +448,6 @@ impl StateRebuilder {
/// Feed an uncompressed state chunk into the rebuilder. /// Feed an uncompressed state chunk into the rebuilder.
pub fn feed(&mut self, chunk: &[u8], flag: &AtomicBool) -> Result<(), ::error::Error> { pub fn feed(&mut self, chunk: &[u8], flag: &AtomicBool) -> Result<(), ::error::Error> {
let rlp = Rlp::new(chunk); let rlp = Rlp::new(chunk);
let empty_rlp = StateAccount::new_basic(U256::zero(), U256::zero()).rlp();
let mut pairs = Vec::with_capacity(rlp.item_count()?); let mut pairs = Vec::with_capacity(rlp.item_count()?);
// initialize the pairs vector with empty values so we have slots to write into. // initialize the pairs vector with empty values so we have slots to write into.
@ -489,8 +483,6 @@ impl StateRebuilder {
self.known_code.insert(code_hash, first_with); self.known_code.insert(code_hash, first_with);
} }
let backing = self.db.backing().clone();
// batch trie writes // batch trie writes
{ {
let mut account_trie = if self.state_root != KECCAK_NULL_RLP { let mut account_trie = if self.state_root != KECCAK_NULL_RLP {
@ -504,18 +496,10 @@ impl StateRebuilder {
return Err(Error::RestorationAborted.into()); return Err(Error::RestorationAborted.into());
} }
if &thin_rlp[..] != &empty_rlp[..] {
self.bloom.set(&*hash);
}
account_trie.insert(&hash, &thin_rlp)?; account_trie.insert(&hash, &thin_rlp)?;
} }
} }
let bloom_journal = self.bloom.drain_journal();
let mut batch = backing.transaction();
StateDB::commit_bloom(&mut batch, bloom_journal)?;
self.db.inject(&mut batch)?;
backing.write_buffered(batch);
trace!(target: "snapshot", "current state root: {:?}", self.state_root); trace!(target: "snapshot", "current state root: {:?}", self.state_root);
Ok(()) Ok(())
} }

View File

@ -707,7 +707,6 @@ impl Spec {
} }
for (address, account) in self.genesis_state.get().iter() { for (address, account) in self.genesis_state.get().iter() {
db.note_non_null_account(address);
account.insert_additional( account.insert_additional(
&mut *factories &mut *factories
.accountdb .accountdb

View File

@ -65,13 +65,6 @@ pub trait Backend: Send {
/// Get cached code based on hash. /// Get cached code based on hash.
fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>>; fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>>;
/// Note that an account with the given address is non-null.
fn note_non_null_account(&self, address: &Address);
/// Check whether an account is known to be empty. Returns true if known to be
/// empty, false otherwise.
fn is_known_null(&self, address: &Address) -> bool;
} }
/// A raw backend used to check proofs of execution. /// A raw backend used to check proofs of execution.
@ -150,10 +143,6 @@ impl Backend for ProofCheck {
fn get_cached_code(&self, _hash: &H256) -> Option<Arc<Vec<u8>>> { fn get_cached_code(&self, _hash: &H256) -> Option<Arc<Vec<u8>>> {
None None
} }
fn note_non_null_account(&self, _address: &Address) {}
fn is_known_null(&self, _address: &Address) -> bool {
false
}
} }
/// Proving state backend. /// Proving state backend.
@ -252,10 +241,6 @@ impl<H: AsHashDB<KeccakHasher, DBValue> + Send + Sync> Backend for Proving<H> {
fn get_cached_code(&self, _: &H256) -> Option<Arc<Vec<u8>>> { fn get_cached_code(&self, _: &H256) -> Option<Arc<Vec<u8>>> {
None None
} }
fn note_non_null_account(&self, _: &Address) {}
fn is_known_null(&self, _: &Address) -> bool {
false
}
} }
impl<H: AsHashDB<KeccakHasher, DBValue>> Proving<H> { impl<H: AsHashDB<KeccakHasher, DBValue>> Proving<H> {
@ -317,8 +302,4 @@ impl<H: AsHashDB<KeccakHasher, DBValue> + Send + Sync> Backend for Basic<H> {
fn get_cached_code(&self, _: &H256) -> Option<Arc<Vec<u8>>> { fn get_cached_code(&self, _: &H256) -> Option<Arc<Vec<u8>>> {
None None
} }
fn note_non_null_account(&self, _: &Address) {}
fn is_known_null(&self, _: &Address) -> bool {
false
}
} }

View File

@ -554,19 +554,17 @@ impl<B: Backend> State<B> {
pub fn exists(&self, a: &Address) -> TrieResult<bool> { pub fn exists(&self, a: &Address) -> TrieResult<bool> {
// Bloom filter does not contain empty accounts, so it is important here to // Bloom filter does not contain empty accounts, so it is important here to
// check if account exists in the database directly before EIP-161 is in effect. // check if account exists in the database directly before EIP-161 is in effect.
self.ensure_cached(a, RequireCache::None, false, |a| a.is_some()) self.ensure_cached(a, RequireCache::None, |a| a.is_some())
} }
/// Determine whether an account exists and if not empty. /// Determine whether an account exists and if not empty.
pub fn exists_and_not_null(&self, a: &Address) -> TrieResult<bool> { pub fn exists_and_not_null(&self, a: &Address) -> TrieResult<bool> {
self.ensure_cached(a, RequireCache::None, false, |a| { self.ensure_cached(a, RequireCache::None, |a| a.map_or(false, |a| !a.is_null()))
a.map_or(false, |a| !a.is_null())
})
} }
/// Determine whether an account exists and has code or non-zero nonce. /// Determine whether an account exists and has code or non-zero nonce.
pub fn exists_and_has_code_or_nonce(&self, a: &Address) -> TrieResult<bool> { pub fn exists_and_has_code_or_nonce(&self, a: &Address) -> TrieResult<bool> {
self.ensure_cached(a, RequireCache::CodeSize, false, |a| { self.ensure_cached(a, RequireCache::CodeSize, |a| {
a.map_or(false, |a| { a.map_or(false, |a| {
a.code_hash() != KECCAK_EMPTY || *a.nonce() != self.account_start_nonce a.code_hash() != KECCAK_EMPTY || *a.nonce() != self.account_start_nonce
}) })
@ -575,7 +573,7 @@ impl<B: Backend> State<B> {
/// Get the balance of account `a`. /// Get the balance of account `a`.
pub fn balance(&self, a: &Address) -> TrieResult<U256> { pub fn balance(&self, a: &Address) -> TrieResult<U256> {
self.ensure_cached(a, RequireCache::None, true, |a| { self.ensure_cached(a, RequireCache::None, |a| {
a.as_ref() a.as_ref()
.map_or(U256::zero(), |account| *account.balance()) .map_or(U256::zero(), |account| *account.balance())
}) })
@ -583,7 +581,7 @@ impl<B: Backend> State<B> {
/// Get the nonce of account `a`. /// Get the nonce of account `a`.
pub fn nonce(&self, a: &Address) -> TrieResult<U256> { pub fn nonce(&self, a: &Address) -> TrieResult<U256> {
self.ensure_cached(a, RequireCache::None, true, |a| { self.ensure_cached(a, RequireCache::None, |a| {
a.as_ref() a.as_ref()
.map_or(self.account_start_nonce, |account| *account.nonce()) .map_or(self.account_start_nonce, |account| *account.nonce())
}) })
@ -592,7 +590,7 @@ impl<B: Backend> State<B> {
/// Whether the base storage root of an account remains unchanged. /// Whether the base storage root of an account remains unchanged.
pub fn is_base_storage_root_unchanged(&self, a: &Address) -> TrieResult<bool> { pub fn is_base_storage_root_unchanged(&self, a: &Address) -> TrieResult<bool> {
Ok(self Ok(self
.ensure_cached(a, RequireCache::None, true, |a| { .ensure_cached(a, RequireCache::None, |a| {
a.as_ref() a.as_ref()
.map(|account| account.is_base_storage_root_unchanged()) .map(|account| account.is_base_storage_root_unchanged())
})? })?
@ -601,7 +599,7 @@ impl<B: Backend> State<B> {
/// Get the storage root of account `a`. /// Get the storage root of account `a`.
pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> { pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true, |a| { self.ensure_cached(a, RequireCache::None, |a| {
a.as_ref().and_then(|account| account.storage_root()) a.as_ref().and_then(|account| account.storage_root())
}) })
} }
@ -609,7 +607,7 @@ impl<B: Backend> State<B> {
/// Get the original storage root since last commit of account `a`. /// Get the original storage root since last commit of account `a`.
pub fn original_storage_root(&self, a: &Address) -> TrieResult<H256> { pub fn original_storage_root(&self, a: &Address) -> TrieResult<H256> {
Ok(self Ok(self
.ensure_cached(a, RequireCache::None, true, |a| { .ensure_cached(a, RequireCache::None, |a| {
a.as_ref().map(|account| account.original_storage_root()) a.as_ref().map(|account| account.original_storage_root())
})? })?
.unwrap_or(KECCAK_NULL_RLP)) .unwrap_or(KECCAK_NULL_RLP))
@ -755,11 +753,6 @@ impl<B: Backend> State<B> {
} }
} }
// check if the account could exist before any requests to trie
if self.db.is_known_null(address) {
return Ok(H256::zero());
}
// account is not found in the global cache, get from the DB and insert into local // account is not found in the global cache, get from the DB and insert into local
let db = &self.db.as_hash_db(); let db = &self.db.as_hash_db();
let db = self let db = self
@ -802,21 +795,19 @@ impl<B: Backend> State<B> {
/// Get accounts' code. /// Get accounts' code.
pub fn code(&self, a: &Address) -> TrieResult<Option<Arc<Bytes>>> { pub fn code(&self, a: &Address) -> TrieResult<Option<Arc<Bytes>>> {
self.ensure_cached(a, RequireCache::Code, true, |a| { self.ensure_cached(a, RequireCache::Code, |a| {
a.as_ref().map_or(None, |a| a.code().clone()) a.as_ref().map_or(None, |a| a.code().clone())
}) })
} }
/// Get an account's code hash. /// Get an account's code hash.
pub fn code_hash(&self, a: &Address) -> TrieResult<Option<H256>> { pub fn code_hash(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true, |a| { self.ensure_cached(a, RequireCache::None, |a| a.as_ref().map(|a| a.code_hash()))
a.as_ref().map(|a| a.code_hash())
})
} }
/// Get accounts' code size. /// Get accounts' code size.
pub fn code_size(&self, a: &Address) -> TrieResult<Option<usize>> { pub fn code_size(&self, a: &Address) -> TrieResult<Option<usize>> {
self.ensure_cached(a, RequireCache::CodeSize, true, |a| { self.ensure_cached(a, RequireCache::CodeSize, |a| {
a.as_ref().and_then(|a| a.code_size()) a.as_ref().and_then(|a| a.code_size())
}) })
} }
@ -1021,9 +1012,6 @@ impl<B: Backend> State<B> {
account.commit_storage(&self.factories.trie, account_db.as_hash_db_mut())?; account.commit_storage(&self.factories.trie, account_db.as_hash_db_mut())?;
account.commit_code(account_db.as_hash_db_mut()); account.commit_code(account_db.as_hash_db_mut());
} }
if !account.is_empty() {
self.db.note_non_null_account(address);
}
} }
} }
@ -1208,7 +1196,7 @@ impl<B: Backend> State<B> {
|m: TrieResult<_>, address| { |m: TrieResult<_>, address| {
let mut m = m?; let mut m = m?;
let account = self.ensure_cached(&address, RequireCache::Code, true, |acc| { let account = self.ensure_cached(&address, RequireCache::Code, |acc| {
acc.map(|acc| { acc.map(|acc| {
// Merge all modified storage keys. // Merge all modified storage keys.
let all_keys = { let all_keys = {
@ -1324,13 +1312,7 @@ impl<B: Backend> State<B> {
/// Check caches for required data /// Check caches for required data
/// First searches for account in the local, then the shared cache. /// First searches for account in the local, then the shared cache.
/// Populates local cache if nothing found. /// Populates local cache if nothing found.
fn ensure_cached<F, U>( fn ensure_cached<F, U>(&self, a: &Address, require: RequireCache, f: F) -> TrieResult<U>
&self,
a: &Address,
require: RequireCache,
check_null: bool,
f: F,
) -> TrieResult<U>
where where
F: Fn(Option<&Account>) -> U, F: Fn(Option<&Account>) -> U,
{ {
@ -1365,11 +1347,6 @@ impl<B: Backend> State<B> {
match result { match result {
Some(r) => Ok(r?), Some(r) => Ok(r?),
None => { None => {
// first check if it is not in database for sure
if check_null && self.db.is_known_null(a) {
return Ok(f(None));
}
// not found in the global cache, get from the DB and insert into local // not found in the global cache, get from the DB and insert into local
let db = &self.db.as_hash_db(); let db = &self.db.as_hash_db();
let db = self.factories.trie.readonly(db, &self.root)?; let db = self.factories.trie.readonly(db, &self.root)?;
@ -1424,15 +1401,11 @@ impl<B: Backend> State<B> {
match self.db.get_cached_account(a) { match self.db.get_cached_account(a) {
Some(acc) => self.insert_cache(a, AccountEntry::new_clean_cached(acc)), Some(acc) => self.insert_cache(a, AccountEntry::new_clean_cached(acc)),
None => { None => {
let maybe_acc = if !self.db.is_known_null(a) { let db = &self.db.as_hash_db();
let db = &self.db.as_hash_db(); let db = self.factories.trie.readonly(db, &self.root)?;
let db = self.factories.trie.readonly(db, &self.root)?; let from_rlp =
let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed");
|b: &[u8]| Account::from_rlp(b).expect("decoding db value failed"); let maybe_acc = AccountEntry::new_clean(db.get_with(a, from_rlp)?);
AccountEntry::new_clean(db.get_with(a, from_rlp)?)
} else {
AccountEntry::new_clean(None)
};
self.insert_cache(a, maybe_acc); self.insert_cache(a, maybe_acc);
} }
} }

View File

@ -22,15 +22,11 @@ use std::{
sync::Arc, sync::Arc,
}; };
use bloom_journal::{Bloom, BloomJournal};
use byteorder::{ByteOrder, LittleEndian};
use db::COL_ACCOUNT_BLOOM;
use ethereum_types::{Address, H256}; use ethereum_types::{Address, H256};
use hash::keccak;
use hash_db::HashDB; use hash_db::HashDB;
use journaldb::JournalDB; use journaldb::JournalDB;
use keccak_hasher::KeccakHasher; use keccak_hasher::KeccakHasher;
use kvdb::{DBTransaction, DBValue, KeyValueDB}; use kvdb::{DBTransaction, DBValue};
use lru_cache::LruCache; use lru_cache::LruCache;
use memory_cache::MemoryLruCache; use memory_cache::MemoryLruCache;
use parking_lot::Mutex; use parking_lot::Mutex;
@ -38,19 +34,6 @@ use types::BlockNumber;
use state::{self, Account}; use state::{self, Account};
/// Value used to initialize bloom bitmap size.
///
/// Bitmap size is the size in bytes (not bits) that will be allocated in memory.
pub const ACCOUNT_BLOOM_SPACE: usize = 1048576;
/// Value used to initialize bloom items count.
///
/// Items count is an estimation of the maximum number of items to store.
pub const DEFAULT_ACCOUNT_PRESET: usize = 1000000;
/// Key for a value storing amount of hashes
pub const ACCOUNT_BLOOM_HASHCOUNT_KEY: &'static [u8] = b"account_hash_count";
const STATE_CACHE_BLOCKS: usize = 12; const STATE_CACHE_BLOCKS: usize = 12;
// The percentage of supplied cache size to go to accounts. // The percentage of supplied cache size to go to accounts.
@ -116,8 +99,6 @@ pub struct StateDB {
code_cache: Arc<Mutex<MemoryLruCache<H256, Arc<Vec<u8>>>>>, code_cache: Arc<Mutex<MemoryLruCache<H256, Arc<Vec<u8>>>>>,
/// Local dirty cache. /// Local dirty cache.
local_cache: Vec<CacheQueueItem>, local_cache: Vec<CacheQueueItem>,
/// Shared account bloom. Does not handle chain reorganizations.
account_bloom: Arc<Mutex<Bloom>>,
cache_size: usize, cache_size: usize,
/// Hash of the block on top of which this instance was created or /// Hash of the block on top of which this instance was created or
/// `None` if cache is disabled /// `None` if cache is disabled
@ -134,7 +115,6 @@ impl StateDB {
// TODO: make the cache size actually accurate by moving the account storage cache // TODO: make the cache size actually accurate by moving the account storage cache
// into the `AccountCache` structure as its own `LruCache<(Address, H256), H256>`. // into the `AccountCache` structure as its own `LruCache<(Address, H256), H256>`.
pub fn new(db: Box<dyn JournalDB>, cache_size: usize) -> StateDB { pub fn new(db: Box<dyn JournalDB>, cache_size: usize) -> StateDB {
let bloom = Self::load_bloom(&**db.backing());
let acc_cache_size = cache_size * ACCOUNT_CACHE_RATIO / 100; let acc_cache_size = cache_size * ACCOUNT_CACHE_RATIO / 100;
let code_cache_size = cache_size - acc_cache_size; let code_cache_size = cache_size - acc_cache_size;
let cache_items = acc_cache_size / ::std::mem::size_of::<Option<Account>>(); let cache_items = acc_cache_size / ::std::mem::size_of::<Option<Account>>();
@ -147,7 +127,6 @@ impl StateDB {
})), })),
code_cache: Arc::new(Mutex::new(MemoryLruCache::new(code_cache_size))), code_cache: Arc::new(Mutex::new(MemoryLruCache::new(code_cache_size))),
local_cache: Vec::new(), local_cache: Vec::new(),
account_bloom: Arc::new(Mutex::new(bloom)),
cache_size: cache_size, cache_size: cache_size,
parent_hash: None, parent_hash: None,
commit_hash: None, commit_hash: None,
@ -155,56 +134,6 @@ impl StateDB {
} }
} }
/// Loads accounts bloom from the database
/// This bloom is used to handle request for the non-existant account fast
pub fn load_bloom(db: &dyn KeyValueDB) -> Bloom {
let hash_count_entry = db
.get(COL_ACCOUNT_BLOOM, ACCOUNT_BLOOM_HASHCOUNT_KEY)
.expect("Low-level database error");
let hash_count_bytes = match hash_count_entry {
Some(bytes) => bytes,
None => return Bloom::new(ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET),
};
assert_eq!(hash_count_bytes.len(), 1);
let hash_count = hash_count_bytes[0];
let mut bloom_parts = vec![0u64; ACCOUNT_BLOOM_SPACE / 8];
let mut key = [0u8; 8];
for i in 0..ACCOUNT_BLOOM_SPACE / 8 {
LittleEndian::write_u64(&mut key, i as u64);
bloom_parts[i] = db
.get(COL_ACCOUNT_BLOOM, &key)
.expect("low-level database error")
.and_then(|val| Some(LittleEndian::read_u64(&val[..])))
.unwrap_or(0u64);
}
let bloom = Bloom::from_parts(&bloom_parts, hash_count as u32);
trace!(target: "account_bloom", "Bloom is {:?} full, hash functions count = {:?}", bloom.saturation(), hash_count);
bloom
}
/// Commit blooms journal to the database transaction
pub fn commit_bloom(batch: &mut DBTransaction, journal: BloomJournal) -> io::Result<()> {
assert!(journal.hash_functions <= 255);
batch.put(
COL_ACCOUNT_BLOOM,
ACCOUNT_BLOOM_HASHCOUNT_KEY,
&[journal.hash_functions as u8],
);
let mut key = [0u8; 8];
let mut val = [0u8; 8];
for (bloom_part_index, bloom_part_value) in journal.entries {
LittleEndian::write_u64(&mut key, bloom_part_index as u64);
LittleEndian::write_u64(&mut val, bloom_part_value);
batch.put(COL_ACCOUNT_BLOOM, &key, &val);
}
Ok(())
}
/// Journal all recent operations under the given era and ID. /// Journal all recent operations under the given era and ID.
pub fn journal_under( pub fn journal_under(
&mut self, &mut self,
@ -212,10 +141,6 @@ impl StateDB {
now: u64, now: u64,
id: &H256, id: &H256,
) -> io::Result<u32> { ) -> io::Result<u32> {
{
let mut bloom_lock = self.account_bloom.lock();
Self::commit_bloom(batch, bloom_lock.drain_journal())?;
}
let records = self.db.journal_under(batch, now, id)?; let records = self.db.journal_under(batch, now, id)?;
self.commit_hash = Some(id.clone()); self.commit_hash = Some(id.clone());
self.commit_number = Some(now); self.commit_number = Some(now);
@ -365,7 +290,6 @@ impl StateDB {
account_cache: self.account_cache.clone(), account_cache: self.account_cache.clone(),
code_cache: self.code_cache.clone(), code_cache: self.code_cache.clone(),
local_cache: Vec::new(), local_cache: Vec::new(),
account_bloom: self.account_bloom.clone(),
cache_size: self.cache_size, cache_size: self.cache_size,
parent_hash: None, parent_hash: None,
commit_hash: None, commit_hash: None,
@ -380,7 +304,6 @@ impl StateDB {
account_cache: self.account_cache.clone(), account_cache: self.account_cache.clone(),
code_cache: self.code_cache.clone(), code_cache: self.code_cache.clone(),
local_cache: Vec::new(), local_cache: Vec::new(),
account_bloom: self.account_bloom.clone(),
cache_size: self.cache_size, cache_size: self.cache_size,
parent_hash: Some(parent.clone()), parent_hash: Some(parent.clone()),
commit_hash: None, commit_hash: None,
@ -510,19 +433,6 @@ impl state::Backend for StateDB {
cache.get_mut(hash).map(|code| code.clone()) cache.get_mut(hash).map(|code| code.clone())
} }
fn note_non_null_account(&self, address: &Address) {
trace!(target: "account_bloom", "Note account bloom: {:?}", address);
let mut bloom = self.account_bloom.lock();
bloom.set(&*keccak(address));
}
fn is_known_null(&self, address: &Address) -> bool {
trace!(target: "account_bloom", "Check account bloom: {:?}", address);
let bloom = self.account_bloom.lock();
let is_null = !bloom.check(&*keccak(address));
is_null
}
} }
/// Sync wrapper for the account. /// Sync wrapper for the account.

View File

@ -47,7 +47,7 @@ pub const TO_V12: ChangeColumns = ChangeColumns {
/// Database is assumed to be at default version, when no version file is found. /// Database is assumed to be at default version, when no version file is found.
const DEFAULT_VERSION: u32 = 5; const DEFAULT_VERSION: u32 = 5;
/// Current version of database models. /// Current version of database models.
const CURRENT_VERSION: u32 = 13; const CURRENT_VERSION: u32 = 16;
/// A version of database at which blooms-db was introduced /// A version of database at which blooms-db was introduced
const BLOOMS_DB_VERSION: u32 = 13; const BLOOMS_DB_VERSION: u32 = 13;
/// Defines how many items are migrated to the new version of database at once. /// Defines how many items are migrated to the new version of database at once.