Skip to content

Commit

Permalink
Remove accounts bloom (openethereum#11589)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdplm authored Apr 22, 2020
1 parent b7dd06b commit c85300c
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 462 deletions.
19 changes: 0 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 0 additions & 13 deletions ethcore/account-state/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,6 @@ pub trait Backend: Send {

/// Get cached code based on hash.
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.
Expand Down Expand Up @@ -126,8 +119,6 @@ impl Backend for ProofCheck {
None
}
fn get_cached_code(&self, _hash: &H256) -> Option<Arc<Vec<u8>>> { None }
fn note_non_null_account(&self, _address: &Address) {}
fn is_known_null(&self, _address: &Address) -> bool { false }
}

/// Proving state backend.
Expand Down Expand Up @@ -195,8 +186,6 @@ impl<H: AsHashDB<KeccakHasher, DBValue> + Send + Sync> Backend for Proving<H> {
}

fn get_cached_code(&self, _: &H256) -> Option<Arc<Vec<u8>>> { None }
fn note_non_null_account(&self, _: &Address) { }
fn is_known_null(&self, _: &Address) -> bool { false }
}

impl<H: AsHashDB<KeccakHasher, DBValue>> Proving<H> {
Expand Down Expand Up @@ -253,6 +242,4 @@ impl<H: AsHashDB<KeccakHasher, DBValue> + Send + Sync> Backend for Basic<H> {
}

fn get_cached_code(&self, _: &H256) -> Option<Arc<Vec<u8>>> { None }
fn note_non_null_account(&self, _: &Address) { }
fn is_known_null(&self, _: &Address) -> bool { false }
}
51 changes: 19 additions & 32 deletions ethcore/account-state/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,48 +411,48 @@ impl<B: Backend> State<B> {
pub fn exists(&self, a: &Address) -> TrieResult<bool> {
// 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.
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.
pub fn exists_and_not_null(&self, a: &Address) -> TrieResult<bool> {
self.ensure_cached(a, RequireCache::None, false, |a| a.map_or(false, |a| !a.is_null()))
self.ensure_cached(a, RequireCache::None, |a| a.map_or(false, |a| !a.is_null()))
}

/// 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> {
self.ensure_cached(a, RequireCache::CodeSize, false,
self.ensure_cached(a, RequireCache::CodeSize,
|a| a.map_or(false, |a| a.code_hash() != KECCAK_EMPTY || *a.nonce() != self.account_start_nonce))
}

/// Get the balance of account `a`.
pub fn balance(&self, a: &Address) -> TrieResult<U256> {
self.ensure_cached(a, RequireCache::None, true,
self.ensure_cached(a, RequireCache::None,
|a| a.as_ref().map_or(U256::zero(), |account| *account.balance()))
}

/// Get the nonce of account `a`.
pub fn nonce(&self, a: &Address) -> TrieResult<U256> {
self.ensure_cached(a, RequireCache::None, true,
self.ensure_cached(a, RequireCache::None,
|a| a.map_or(self.account_start_nonce, |account| *account.nonce()))
}

/// Whether the base storage root of an account remains unchanged.
pub fn is_base_storage_root_unchanged(&self, a: &Address) -> TrieResult<bool> {
Ok(self.ensure_cached(a, RequireCache::None, true,
Ok(self.ensure_cached(a, RequireCache::None,
|a| a.as_ref().map(|account| account.is_base_storage_root_unchanged()))?
.unwrap_or(true))
}

/// Get the storage root of account `a`.
pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true,
self.ensure_cached(a, RequireCache::None,
|a| a.as_ref().and_then(|account| account.storage_root()))
}

/// Get the original storage root since last commit of account `a`.
pub fn original_storage_root(&self, a: &Address) -> TrieResult<H256> {
Ok(self.ensure_cached(a, RequireCache::None, true,
Ok(self.ensure_cached(a, RequireCache::None,
|a| a.as_ref().map(|account| account.original_storage_root()))?
.unwrap_or(KECCAK_NULL_RLP))
}
Expand Down Expand Up @@ -579,9 +579,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
let db = &self.db.as_hash_db();
let db = self.factories.trie.readonly(db, &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
Expand Down Expand Up @@ -617,25 +614,25 @@ impl<B: Backend> State<B> {

/// Get accounts' code.
pub fn code(&self, a: &Address) -> TrieResult<Option<Arc<Bytes>>> {
self.ensure_cached(a, RequireCache::Code, true,
self.ensure_cached(a, RequireCache::Code,
|a| a.as_ref().map_or(None, |a| a.code().clone()))
}

/// Get an account's code hash.
pub fn code_hash(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true,
self.ensure_cached(a, RequireCache::None,
|a| a.as_ref().map(|a| a.code_hash()))
}

/// Get an account's code version.
pub fn code_version(&self, a: &Address) -> TrieResult<U256> {
self.ensure_cached(a, RequireCache::None, true,
self.ensure_cached(a, RequireCache::None,
|a| a.as_ref().map(|a| *a.code_version()).unwrap_or(U256::zero()))
}

/// Get accounts' code size.
pub fn code_size(&self, a: &Address) -> TrieResult<Option<usize>> {
self.ensure_cached(a, RequireCache::CodeSize, true,
self.ensure_cached(a, RequireCache::CodeSize,
|a| a.as_ref().and_then(|a| a.code_size()))
}

Expand Down Expand Up @@ -719,9 +716,6 @@ impl<B: Backend> State<B> {
account.commit_storage(&self.factories.trie, 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);
}
}
}

Expand Down Expand Up @@ -877,7 +871,7 @@ impl<B: Backend> State<B> {
Ok(PodState::from(all_addresses.into_iter().fold(Ok(BTreeMap::new()), |m: TrieResult<_>, address| {
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| {
// Merge all modified storage keys.
let all_keys = {
Expand Down Expand Up @@ -966,7 +960,7 @@ impl<B: Backend> State<B> {
/// Check caches for required data
/// First searches for account in the local, then the shared cache.
/// Populates local cache if nothing found.
fn ensure_cached<F, U>(&self, a: &Address, require: RequireCache, check_null: bool, f: F) -> TrieResult<U>
fn ensure_cached<F, U>(&self, a: &Address, require: RequireCache, f: F) -> TrieResult<U>
where F: Fn(Option<&Account>) -> U {
// check local cache first
if let Some(ref mut maybe_acc) = self.cache.borrow_mut().get_mut(a) {
Expand All @@ -993,9 +987,6 @@ impl<B: Backend> State<B> {
match result {
Some(r) => Ok(r?),
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
let db = &self.db.as_hash_db();
let db = self.factories.trie.readonly(db, &self.root)?;
Expand Down Expand Up @@ -1029,15 +1020,11 @@ impl<B: Backend> State<B> {
match self.db.get_cached_account(a) {
Some(acc) => self.insert_cache(a, AccountEntry::new_clean_cached(acc)),
None => {
let maybe_acc = if !self.db.is_known_null(a) {
let db = &self.db.as_hash_db();
let db = self.factories.trie.readonly(db, &self.root)?;
let from_rlp = |b:&[u8]| { Account::from_rlp(b).expect("decoding db value failed") };
AccountEntry::new_clean(db.get_with(a.as_bytes(), from_rlp)?)
} else {
AccountEntry::new_clean(None)
};
self.insert_cache(a, maybe_acc);
let db = &self.db.as_hash_db();
let db = self.factories.trie.readonly(db, &self.root)?;
let from_rlp = |b:&[u8]| { Account::from_rlp(b).expect("decoding db value failed") };
let maybe_account = db.get_with(a.as_bytes(), from_rlp)?;
self.insert_cache(a, AccountEntry::new_clean(maybe_account));
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion ethcore/db/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ pub const COL_BODIES: u32 = 2;
pub const COL_EXTRA: u32 = 3;
/// Column for Traces
pub const COL_TRACE: u32 = 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: u32 = 5;
/// Column for general information from the local node which can persist.
pub const COL_NODE_INFO: u32 = 6;
Expand Down
3 changes: 0 additions & 3 deletions ethcore/snapshot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ harness = false

[dependencies]
account-db = { path = "../account-db" }
account-state = { path = "../account-state" }
blockchain = { package = "ethcore-blockchain", path = "../blockchain" }
bloom-journal = { package = "accounts-bloom", path = "../../util/bloom" }
bytes = { package = "parity-bytes", version = "0.1.0" }
client-traits = { path = "../client-traits" }
common-types = { path = "../types" }
Expand All @@ -39,7 +37,6 @@ rlp = "0.4.5"
rlp-derive = "0.1"
scopeguard = "1.1.0"
snappy = { package = "parity-snappy", version ="0.1.0" }
state-db = { path = "../state-db" }
trie-db = "0.20.0"
triehash = { package = "triehash-ethereum", version = "0.2", path = "../../util/triehash-ethereum" }

Expand Down
19 changes: 1 addition & 18 deletions ethcore/snapshot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use keccak_hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY};

use account_db::{AccountDB, AccountDBMut};
use account_state::Account as StateAccount;
use blockchain::{BlockChain, BlockProvider};
use bloom_journal::Bloom;
use bytes::Bytes;
use common_types::{
ids::BlockId,
Expand All @@ -39,7 +37,7 @@ use common_types::{
};
use crossbeam_utils::thread;
use engine::Engine;
use ethereum_types::{H256, U256};
use ethereum_types::H256;
use ethtrie::{TrieDB, TrieDBMut};
use hash_db::HashDB;
use journaldb::{self, Algorithm, JournalDB};
Expand All @@ -51,7 +49,6 @@ use num_cpus;
use rand::{Rng, rngs::OsRng};
use rlp::{RlpStream, Rlp};
use snappy;
use state_db::StateDB;
use trie_db::{Trie, TrieMut};

pub use self::consensus::*;
Expand Down Expand Up @@ -378,7 +375,6 @@ pub struct StateRebuilder {
state_root: H256,
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.
bloom: Bloom,
known_storage_roots: HashMap<H256, H256>, // maps account hashes to last known storage root. Only filled for last account per chunk.
}

Expand All @@ -390,15 +386,13 @@ impl StateRebuilder {
state_root: KECCAK_NULL_RLP,
known_code: HashMap::new(),
missing_code: HashMap::new(),
bloom: StateDB::load_bloom(&*db),
known_storage_roots: HashMap::new(),
}
}

/// Feed an uncompressed state chunk into the rebuilder.
pub fn feed(&mut self, chunk: &[u8], flag: &AtomicBool) -> Result<(), EthcoreError> {
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()?);

// initialize the pairs vector with empty values so we have slots to write into.
Expand Down Expand Up @@ -427,8 +421,6 @@ impl StateRebuilder {
self.known_code.insert(code_hash, first_with);
}

let backing = self.db.backing().clone();

// batch trie writes
{
let mut account_trie = if self.state_root != KECCAK_NULL_RLP {
Expand All @@ -439,19 +431,10 @@ impl StateRebuilder {

for (hash, thin_rlp) in pairs {
if !flag.load(Ordering::SeqCst) { return Err(Error::RestorationAborted.into()) }

if &thin_rlp[..] != &empty_rlp[..] {
self.bloom.set(hash.as_bytes());
}
account_trie.insert(hash.as_bytes(), &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);
Ok(())
}

Expand Down
1 change: 0 additions & 1 deletion ethcore/spec/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ fn run_constructors<T: Backend>(
}

for (address, account) in genesis_state.get().iter() {
db.note_non_null_account(address);
account.insert_additional(
&mut *factories.accountdb.create(
db.as_hash_db_mut(),
Expand Down
3 changes: 0 additions & 3 deletions ethcore/state-db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ edition = "2018"

[dependencies]
account-state = { path = "../account-state" }
bloom_journal = { package = "accounts-bloom", path = "../../util/bloom" }
common-types = { path = "../types"}
ethcore-db = { path = "../db" }
ethereum-types = "0.9.0"
hash-db = "0.15.0"
keccak-hash = "0.5.0"
keccak-hasher = { path = "../../util/keccak-hasher" }
journaldb = { path = "../../util/journaldb" }
kvdb = "0.5.0"
Expand Down
Loading

0 comments on commit c85300c

Please sign in to comment.