Remove calls to heapsize (#10432)
* update memorydb trait * use malloc_size_of instead of heapsize_of * use jemalloc as default allocator for parity client.
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
//! DB backend wrapper for Account trie
|
||||
use ethereum_types::H256;
|
||||
use hash::{KECCAK_NULL_RLP, keccak};
|
||||
use hash_db::{HashDB, AsHashDB};
|
||||
use hash_db::{HashDB, AsHashDB, Prefix};
|
||||
use keccak_hasher::KeccakHasher;
|
||||
use kvdb::DBValue;
|
||||
use rlp::NULL_RLP;
|
||||
@@ -103,29 +103,29 @@ impl<'db> AsHashDB<KeccakHasher, DBValue> for AccountDB<'db> {
|
||||
}
|
||||
|
||||
impl<'db> HashDB<KeccakHasher, DBValue> for AccountDB<'db> {
|
||||
fn get(&self, key: &H256) -> Option<DBValue> {
|
||||
fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return Some(DBValue::from_slice(&NULL_RLP));
|
||||
}
|
||||
self.db.get(&combine_key(&self.address_hash, key))
|
||||
self.db.get(&combine_key(&self.address_hash, key), prefix)
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
fn contains(&self, key: &H256, prefix: Prefix) -> bool {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return true;
|
||||
}
|
||||
self.db.contains(&combine_key(&self.address_hash, key))
|
||||
self.db.contains(&combine_key(&self.address_hash, key), prefix)
|
||||
}
|
||||
|
||||
fn insert(&mut self, _value: &[u8]) -> H256 {
|
||||
fn insert(&mut self, _prefix: Prefix, _value: &[u8]) -> H256 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn emplace(&mut self, _key: H256, _value: DBValue) {
|
||||
fn emplace(&mut self, _key: H256, _prefix: Prefix, _value: DBValue) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn remove(&mut self, _key: &H256) {
|
||||
fn remove(&mut self, _key: &H256, _prefix: Prefix) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
@@ -158,44 +158,44 @@ impl<'db> AccountDBMut<'db> {
|
||||
}
|
||||
|
||||
impl<'db> HashDB<KeccakHasher, DBValue> for AccountDBMut<'db>{
|
||||
fn get(&self, key: &H256) -> Option<DBValue> {
|
||||
fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return Some(DBValue::from_slice(&NULL_RLP));
|
||||
}
|
||||
self.db.get(&combine_key(&self.address_hash, key))
|
||||
self.db.get(&combine_key(&self.address_hash, key), prefix)
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
fn contains(&self, key: &H256, prefix: Prefix) -> bool {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return true;
|
||||
}
|
||||
self.db.contains(&combine_key(&self.address_hash, key))
|
||||
self.db.contains(&combine_key(&self.address_hash, key), prefix)
|
||||
}
|
||||
|
||||
fn insert(&mut self, value: &[u8]) -> H256 {
|
||||
fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H256 {
|
||||
if value == &NULL_RLP {
|
||||
return KECCAK_NULL_RLP.clone();
|
||||
}
|
||||
let k = keccak(value);
|
||||
let ak = combine_key(&self.address_hash, &k);
|
||||
self.db.emplace(ak, DBValue::from_slice(value));
|
||||
self.db.emplace(ak, prefix, DBValue::from_slice(value));
|
||||
k
|
||||
}
|
||||
|
||||
fn emplace(&mut self, key: H256, value: DBValue) {
|
||||
fn emplace(&mut self, key: H256, prefix: Prefix, value: DBValue) {
|
||||
if key == KECCAK_NULL_RLP {
|
||||
return;
|
||||
}
|
||||
let key = combine_key(&self.address_hash, &key);
|
||||
self.db.emplace(key, value)
|
||||
self.db.emplace(key, prefix, value)
|
||||
}
|
||||
|
||||
fn remove(&mut self, key: &H256) {
|
||||
fn remove(&mut self, key: &H256, prefix: Prefix) {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return;
|
||||
}
|
||||
let key = combine_key(&self.address_hash, key);
|
||||
self.db.remove(&key)
|
||||
self.db.remove(&key, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,29 +212,29 @@ impl<'db> AsHashDB<KeccakHasher, DBValue> for Wrapping<'db> {
|
||||
}
|
||||
|
||||
impl<'db> HashDB<KeccakHasher, DBValue> for Wrapping<'db> {
|
||||
fn get(&self, key: &H256) -> Option<DBValue> {
|
||||
fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return Some(DBValue::from_slice(&NULL_RLP));
|
||||
}
|
||||
self.0.get(key)
|
||||
self.0.get(key, prefix)
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
fn contains(&self, key: &H256, prefix: Prefix) -> bool {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return true;
|
||||
}
|
||||
self.0.contains(key)
|
||||
self.0.contains(key, prefix)
|
||||
}
|
||||
|
||||
fn insert(&mut self, _value: &[u8]) -> H256 {
|
||||
fn insert(&mut self, _prefix: Prefix, _value: &[u8]) -> H256 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn emplace(&mut self, _key: H256, _value: DBValue) {
|
||||
fn emplace(&mut self, _key: H256, _prefix: Prefix, _value: DBValue) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn remove(&mut self, _key: &H256) {
|
||||
fn remove(&mut self, _key: &H256, _prefix: Prefix) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
@@ -246,38 +246,38 @@ impl<'db> AsHashDB<KeccakHasher, DBValue> for WrappingMut<'db> {
|
||||
}
|
||||
|
||||
impl<'db> HashDB<KeccakHasher, DBValue> for WrappingMut<'db>{
|
||||
fn get(&self, key: &H256) -> Option<DBValue> {
|
||||
fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return Some(DBValue::from_slice(&NULL_RLP));
|
||||
}
|
||||
self.0.get(key)
|
||||
self.0.get(key, prefix)
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
fn contains(&self, key: &H256, prefix: Prefix) -> bool {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return true;
|
||||
}
|
||||
self.0.contains(key)
|
||||
self.0.contains(key, prefix)
|
||||
}
|
||||
|
||||
fn insert(&mut self, value: &[u8]) -> H256 {
|
||||
fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H256 {
|
||||
if value == &NULL_RLP {
|
||||
return KECCAK_NULL_RLP.clone();
|
||||
}
|
||||
self.0.insert(value)
|
||||
self.0.insert(prefix, value)
|
||||
}
|
||||
|
||||
fn emplace(&mut self, key: H256, value: DBValue) {
|
||||
fn emplace(&mut self, key: H256, prefix: Prefix, value: DBValue) {
|
||||
if key == KECCAK_NULL_RLP {
|
||||
return;
|
||||
}
|
||||
self.0.emplace(key, value)
|
||||
self.0.emplace(key, prefix, value)
|
||||
}
|
||||
|
||||
fn remove(&mut self, key: &H256) {
|
||||
fn remove(&mut self, key: &H256, prefix: Prefix) {
|
||||
if key == &KECCAK_NULL_RLP {
|
||||
return;
|
||||
}
|
||||
self.0.remove(key)
|
||||
self.0.remove(key, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,6 +566,7 @@ mod tests {
|
||||
use types::header::Header;
|
||||
use types::view;
|
||||
use types::views::BlockView;
|
||||
use hash_db::EMPTY_PREFIX;
|
||||
|
||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||
fn enact_bytes(
|
||||
@@ -668,7 +669,8 @@ mod tests {
|
||||
|
||||
let db = e.drain().state.drop().1;
|
||||
assert_eq!(orig_db.journal_db().keys(), db.journal_db().keys());
|
||||
assert!(orig_db.journal_db().keys().iter().filter(|k| orig_db.journal_db().get(k.0) != db.journal_db().get(k.0)).next() == None);
|
||||
assert!(orig_db.journal_db().keys().iter().filter(|k| orig_db.journal_db().get(k.0, EMPTY_PREFIX)
|
||||
!= db.journal_db().get(k.0, EMPTY_PREFIX)).next() == None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -702,6 +704,7 @@ mod tests {
|
||||
|
||||
let db = e.drain().state.drop().1;
|
||||
assert_eq!(orig_db.journal_db().keys(), db.journal_db().keys());
|
||||
assert!(orig_db.journal_db().keys().iter().filter(|k| orig_db.journal_db().get(k.0) != db.journal_db().get(k.0)).next() == None);
|
||||
assert!(orig_db.journal_db().keys().iter().filter(|k| orig_db.journal_db().get(k.0, EMPTY_PREFIX)
|
||||
!= db.journal_db().get(k.0, EMPTY_PREFIX)).next() == None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ use types::log_entry::LocalizedLogEntry;
|
||||
use types::receipt::{Receipt, LocalizedReceipt};
|
||||
use types::{BlockNumber, header::{Header, ExtendedHeader}};
|
||||
use vm::{EnvInfo, LastHashes};
|
||||
|
||||
use hash_db::EMPTY_PREFIX;
|
||||
use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
|
||||
use client::ancient_import::AncientVerifier;
|
||||
use client::{
|
||||
@@ -743,7 +743,7 @@ impl Client {
|
||||
config.history
|
||||
};
|
||||
|
||||
if !chain.block_header_data(&chain.best_block_hash()).map_or(true, |h| state_db.journal_db().contains(&h.state_root())) {
|
||||
if !chain.block_header_data(&chain.best_block_hash()).map_or(true, |h| state_db.journal_db().contains(&h.state_root(), EMPTY_PREFIX)) {
|
||||
warn!("State root not found for block #{} ({:x})", chain.best_block_number(), chain.best_block_hash());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/// Preconfigured validator list.
|
||||
|
||||
use heapsize::HeapSizeOf;
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
use ethereum_types::{H256, Address};
|
||||
|
||||
use machine::{AuxiliaryData, Call, EthereumMachine};
|
||||
@@ -25,7 +25,7 @@ use types::header::Header;
|
||||
use super::ValidatorSet;
|
||||
|
||||
/// Validator set containing a known set of addresses.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Default)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Default, MallocSizeOf)]
|
||||
pub struct SimpleList {
|
||||
validators: Vec<Address>,
|
||||
}
|
||||
@@ -58,12 +58,6 @@ impl From<Vec<Address>> for SimpleList {
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for SimpleList {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.validators.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl ValidatorSet for SimpleList {
|
||||
fn default_caller(&self, _block_id: ::types::ids::BlockId) -> Box<Call> {
|
||||
Box::new(|_, _| Err("Simple list doesn't require calls.".into()))
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::{H256, Address};
|
||||
use heapsize::HeapSizeOf;
|
||||
use types::BlockNumber;
|
||||
use types::header::Header;
|
||||
|
||||
@@ -30,9 +30,12 @@ use machine::{AuxiliaryData, Call, EthereumMachine};
|
||||
use super::{ValidatorSet, SimpleList};
|
||||
|
||||
/// Set used for testing with a single validator.
|
||||
#[derive(MallocSizeOf)]
|
||||
pub struct TestSet {
|
||||
validator: SimpleList,
|
||||
#[ignore_malloc_size_of = "zero sized"]
|
||||
last_malicious: Arc<AtomicUsize>,
|
||||
#[ignore_malloc_size_of = "zero sized"]
|
||||
last_benign: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
@@ -52,12 +55,6 @@ impl TestSet {
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for TestSet {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.validator.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl ValidatorSet for TestSet {
|
||||
fn default_caller(&self, _block_id: ::types::ids::BlockId) -> Box<Call> {
|
||||
Box::new(|_, _| Err("Test set doesn't require calls.".into()))
|
||||
|
||||
@@ -72,7 +72,6 @@ extern crate ethjson;
|
||||
extern crate ethkey;
|
||||
extern crate futures;
|
||||
extern crate hash_db;
|
||||
extern crate heapsize;
|
||||
extern crate itertools;
|
||||
extern crate journaldb;
|
||||
extern crate keccak_hash as hash;
|
||||
@@ -98,6 +97,9 @@ extern crate patricia_trie_ethereum as ethtrie;
|
||||
extern crate rand;
|
||||
extern crate rayon;
|
||||
extern crate rlp;
|
||||
extern crate parity_util_mem;
|
||||
extern crate parity_util_mem as mem;
|
||||
extern crate parity_util_mem as malloc_size_of;
|
||||
extern crate rustc_hex;
|
||||
extern crate serde;
|
||||
extern crate stats;
|
||||
|
||||
@@ -81,7 +81,7 @@ impl PodAccount {
|
||||
/// Place additional data into given hash DB.
|
||||
pub fn insert_additional(&self, db: &mut dyn HashDB<KeccakHasher, DBValue>, factory: &TrieFactory<KeccakHasher, RlpCodec>) {
|
||||
match self.code {
|
||||
Some(ref c) if !c.is_empty() => { db.insert(c); }
|
||||
Some(ref c) if !c.is_empty() => { db.insert(hash_db::EMPTY_PREFIX, c); }
|
||||
_ => {}
|
||||
}
|
||||
let mut r = H256::zero();
|
||||
|
||||
@@ -95,7 +95,7 @@ pub fn to_fat_rlps(
|
||||
} else if used_code.contains(&acc.code_hash) {
|
||||
account_stream.append(&CodeState::Hash.raw()).append(&acc.code_hash);
|
||||
} else {
|
||||
match acct_db.get(&acc.code_hash) {
|
||||
match acct_db.get(&acc.code_hash, hash_db::EMPTY_PREFIX) {
|
||||
Some(c) => {
|
||||
used_code.insert(acc.code_hash.clone());
|
||||
account_stream.append(&CodeState::Inline.raw()).append(&&*c);
|
||||
@@ -182,7 +182,7 @@ pub fn from_fat_rlp(
|
||||
CodeState::Empty => (KECCAK_EMPTY, None),
|
||||
CodeState::Inline => {
|
||||
let code: Bytes = rlp.val_at(3)?;
|
||||
let code_hash = acct_db.insert(&code);
|
||||
let code_hash = acct_db.insert(hash_db::EMPTY_PREFIX, &code);
|
||||
|
||||
(code_hash, Some(code))
|
||||
}
|
||||
@@ -228,7 +228,7 @@ mod tests {
|
||||
|
||||
use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak};
|
||||
use ethereum_types::{H256, Address};
|
||||
use hash_db::HashDB;
|
||||
use hash_db::{HashDB, EMPTY_PREFIX};
|
||||
use kvdb::DBValue;
|
||||
use rlp::Rlp;
|
||||
|
||||
@@ -324,12 +324,12 @@ mod tests {
|
||||
|
||||
let code_hash = {
|
||||
let mut acct_db = AccountDBMut::new(db.as_hash_db_mut(), &addr1);
|
||||
acct_db.insert(b"this is definitely code")
|
||||
acct_db.insert(EMPTY_PREFIX, b"this is definitely code")
|
||||
};
|
||||
|
||||
{
|
||||
let mut acct_db = AccountDBMut::new(db.as_hash_db_mut(), &addr2);
|
||||
acct_db.emplace(code_hash.clone(), DBValue::from_slice(b"this is definitely code"));
|
||||
acct_db.emplace(code_hash.clone(), EMPTY_PREFIX, DBValue::from_slice(b"this is definitely code"));
|
||||
}
|
||||
|
||||
let account1 = BasicAccount {
|
||||
|
||||
@@ -448,7 +448,7 @@ impl StateRebuilder {
|
||||
for (code_hash, code, first_with) in status.new_code {
|
||||
for addr_hash in self.missing_code.remove(&code_hash).unwrap_or_else(Vec::new) {
|
||||
let mut db = AccountDBMut::from_hash(self.db.as_hash_db_mut(), addr_hash);
|
||||
db.emplace(code_hash, DBValue::from_slice(&code));
|
||||
db.emplace(code_hash, hash_db::EMPTY_PREFIX, DBValue::from_slice(&code));
|
||||
}
|
||||
|
||||
self.known_code.insert(code_hash, first_with);
|
||||
@@ -545,11 +545,11 @@ fn rebuild_accounts(
|
||||
Some(&first_with) => {
|
||||
// if so, load it from the database.
|
||||
let code = AccountDB::from_hash(db, first_with)
|
||||
.get(&code_hash)
|
||||
.get(&code_hash, hash_db::EMPTY_PREFIX)
|
||||
.ok_or_else(|| Error::MissingCode(vec![first_with]))?;
|
||||
|
||||
// and write it again under a different mangled key
|
||||
AccountDBMut::from_hash(db, hash).emplace(code_hash, code);
|
||||
AccountDBMut::from_hash(db, hash).emplace(code_hash, hash_db::EMPTY_PREFIX, code);
|
||||
}
|
||||
// if not, queue it up to be filled later
|
||||
None => status.missing_code.push((hash, code_hash)),
|
||||
|
||||
@@ -40,7 +40,7 @@ const RNG_SEED: [u8; 16] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
|
||||
|
||||
#[test]
|
||||
fn snap_and_restore() {
|
||||
use hash_db::HashDB;
|
||||
use hash_db::{HashDB, EMPTY_PREFIX};
|
||||
let mut producer = StateProducer::new();
|
||||
let mut rng = XorShiftRng::from_seed(RNG_SEED);
|
||||
let mut old_db = journaldb::new_memory_db();
|
||||
@@ -97,7 +97,7 @@ fn snap_and_restore() {
|
||||
let keys = old_db.keys();
|
||||
|
||||
for key in keys.keys() {
|
||||
assert_eq!(old_db.get(&key).unwrap(), new_db.as_hash_db().get(&key).unwrap());
|
||||
assert_eq!(old_db.get(&key, EMPTY_PREFIX).unwrap(), new_db.as_hash_db().get(&key, EMPTY_PREFIX).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ fn get_code_from_prev_chunk() {
|
||||
use std::collections::HashSet;
|
||||
use rlp::RlpStream;
|
||||
use ethereum_types::{H256, U256};
|
||||
use hash_db::HashDB;
|
||||
use hash_db::{HashDB, EMPTY_PREFIX};
|
||||
|
||||
use account_db::{AccountDBMut, AccountDB};
|
||||
|
||||
@@ -128,7 +128,7 @@ fn get_code_from_prev_chunk() {
|
||||
|
||||
let mut make_chunk = |acc, hash| {
|
||||
let mut db = journaldb::new_memory_db();
|
||||
AccountDBMut::from_hash(&mut db, hash).insert(&code[..]);
|
||||
AccountDBMut::from_hash(&mut db, hash).insert(EMPTY_PREFIX, &code[..]);
|
||||
let p = Progress::default();
|
||||
let fat_rlp = account::to_fat_rlps(&hash, &acc, &AccountDB::from_hash(&db, hash), &mut used_code, usize::max_value(), usize::max_value(), &p).unwrap();
|
||||
let mut stream = RlpStream::new_list(1);
|
||||
|
||||
@@ -813,7 +813,7 @@ impl Spec {
|
||||
|
||||
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
||||
pub fn ensure_db_good<T: Backend>(&self, db: T, factories: &Factories) -> Result<T, Error> {
|
||||
if db.as_hash_db().contains(&self.state_root()) {
|
||||
if db.as_hash_db().contains(&self.state_root(), hash_db::EMPTY_PREFIX) {
|
||||
return Ok(db);
|
||||
}
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ impl Account {
|
||||
|
||||
if self.is_cached() { return Some(self.code_cache.clone()); }
|
||||
|
||||
match db.get(&self.code_hash) {
|
||||
match db.get(&self.code_hash, hash_db::EMPTY_PREFIX) {
|
||||
Some(x) => {
|
||||
self.code_size = Some(x.len());
|
||||
self.code_cache = Arc::new(x.into_vec());
|
||||
@@ -393,7 +393,7 @@ impl Account {
|
||||
trace!("Account::cache_code_size: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty());
|
||||
self.code_size.is_some() ||
|
||||
if self.code_hash != KECCAK_EMPTY {
|
||||
match db.get(&self.code_hash) {
|
||||
match db.get(&self.code_hash, hash_db::EMPTY_PREFIX) {
|
||||
Some(x) => {
|
||||
self.code_size = Some(x.len());
|
||||
true
|
||||
@@ -507,7 +507,7 @@ impl Account {
|
||||
self.code_filth = Filth::Clean;
|
||||
},
|
||||
(true, false) => {
|
||||
db.emplace(self.code_hash.clone(), DBValue::from_slice(&*self.code_cache));
|
||||
db.emplace(self.code_hash.clone(), hash_db::EMPTY_PREFIX, DBValue::from_slice(&*self.code_cache));
|
||||
self.code_size = Some(self.code_cache.len());
|
||||
self.code_filth = Filth::Clean;
|
||||
},
|
||||
|
||||
@@ -27,8 +27,8 @@ use std::sync::Arc;
|
||||
use state::Account;
|
||||
use parking_lot::Mutex;
|
||||
use ethereum_types::{Address, H256};
|
||||
use memory_db::MemoryDB;
|
||||
use hash_db::{AsHashDB, HashDB};
|
||||
use memory_db::{MemoryDB, HashKey};
|
||||
use hash_db::{AsHashDB, HashDB, Prefix, EMPTY_PREFIX};
|
||||
use kvdb::DBValue;
|
||||
use keccak_hasher::KeccakHasher;
|
||||
use journaldb::AsKeyedHashDB;
|
||||
@@ -78,13 +78,13 @@ pub trait Backend: Send {
|
||||
// TODO: when account lookup moved into backends, this won't rely as tenuously on intended
|
||||
// usage.
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct ProofCheck(MemoryDB<KeccakHasher, DBValue>);
|
||||
pub struct ProofCheck(MemoryDB<KeccakHasher, HashKey<KeccakHasher>, DBValue>);
|
||||
|
||||
impl ProofCheck {
|
||||
/// Create a new `ProofCheck` backend from the given state items.
|
||||
pub fn new(proof: &[DBValue]) -> Self {
|
||||
let mut db = journaldb::new_memory_db();
|
||||
for item in proof { db.insert(item); }
|
||||
for item in proof { db.insert(EMPTY_PREFIX, item); }
|
||||
ProofCheck(db)
|
||||
}
|
||||
}
|
||||
@@ -94,23 +94,23 @@ impl journaldb::KeyedHashDB for ProofCheck {
|
||||
}
|
||||
|
||||
impl HashDB<KeccakHasher, DBValue> for ProofCheck {
|
||||
fn get(&self, key: &H256) -> Option<DBValue> {
|
||||
self.0.get(key)
|
||||
fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
|
||||
self.0.get(key, prefix)
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
self.0.contains(key)
|
||||
fn contains(&self, key: &H256, prefix: Prefix) -> bool {
|
||||
self.0.contains(key, prefix)
|
||||
}
|
||||
|
||||
fn insert(&mut self, value: &[u8]) -> H256 {
|
||||
self.0.insert(value)
|
||||
fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H256 {
|
||||
self.0.insert(prefix, value)
|
||||
}
|
||||
|
||||
fn emplace(&mut self, key: H256, value: DBValue) {
|
||||
self.0.emplace(key, value)
|
||||
fn emplace(&mut self, key: H256, prefix: Prefix, value: DBValue) {
|
||||
self.0.emplace(key, prefix, value)
|
||||
}
|
||||
|
||||
fn remove(&mut self, _key: &H256) { }
|
||||
fn remove(&mut self, _key: &H256, _prefix: Prefix) { }
|
||||
}
|
||||
|
||||
impl AsHashDB<KeccakHasher, DBValue> for ProofCheck {
|
||||
@@ -141,7 +141,7 @@ impl Backend for ProofCheck {
|
||||
/// This doesn't cache anything or rely on the canonical state caches.
|
||||
pub struct Proving<H> {
|
||||
base: H, // state we're proving values from.
|
||||
changed: MemoryDB<KeccakHasher, DBValue>, // changed state via insertions.
|
||||
changed: MemoryDB<KeccakHasher, HashKey<KeccakHasher>, DBValue>, // changed state via insertions.
|
||||
proof: Mutex<HashSet<DBValue>>,
|
||||
}
|
||||
|
||||
@@ -163,32 +163,32 @@ impl<H: AsKeyedHashDB + Send + Sync> journaldb::KeyedHashDB for Proving<H> {
|
||||
}
|
||||
|
||||
impl<H: AsHashDB<KeccakHasher, DBValue> + Send + Sync> HashDB<KeccakHasher, DBValue> for Proving<H> {
|
||||
fn get(&self, key: &H256) -> Option<DBValue> {
|
||||
match self.base.as_hash_db().get(key) {
|
||||
fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
|
||||
match self.base.as_hash_db().get(key, prefix) {
|
||||
Some(val) => {
|
||||
self.proof.lock().insert(val.clone());
|
||||
Some(val)
|
||||
}
|
||||
None => self.changed.get(key)
|
||||
None => self.changed.get(key, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
self.get(key).is_some()
|
||||
fn contains(&self, key: &H256, prefix: Prefix) -> bool {
|
||||
self.get(key, prefix).is_some()
|
||||
}
|
||||
|
||||
fn insert(&mut self, value: &[u8]) -> H256 {
|
||||
self.changed.insert(value)
|
||||
fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H256 {
|
||||
self.changed.insert(prefix, value)
|
||||
}
|
||||
|
||||
fn emplace(&mut self, key: H256, value: DBValue) {
|
||||
self.changed.emplace(key, value)
|
||||
fn emplace(&mut self, key: H256, prefix: Prefix, value: DBValue) {
|
||||
self.changed.emplace(key, prefix, value)
|
||||
}
|
||||
|
||||
fn remove(&mut self, key: &H256) {
|
||||
fn remove(&mut self, key: &H256, prefix: Prefix) {
|
||||
// only remove from `changed`
|
||||
if self.changed.contains(key) {
|
||||
self.changed.remove(key)
|
||||
if self.changed.contains(key, prefix) {
|
||||
self.changed.remove(key, prefix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ impl<B: Backend> State<B> {
|
||||
|
||||
/// Creates new state with existing state root
|
||||
pub fn from_existing(db: B, root: H256, account_start_nonce: U256, factories: Factories) -> TrieResult<State<B>> {
|
||||
if !db.as_hash_db().contains(&root) {
|
||||
if !db.as_hash_db().contains(&root, hash_db::EMPTY_PREFIX) {
|
||||
return Err(Box::new(TrieError::InvalidStateRoot(root)));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
//! Trace database.
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use parity_util_mem::MallocSizeOfExt;
|
||||
|
||||
use blockchain::BlockChainDB;
|
||||
use db::cache_manager::CacheManager;
|
||||
use db::{self, Key, Writable, Readable, CacheUpdatePolicy};
|
||||
use ethereum_types::{H256, H264};
|
||||
use heapsize::HeapSizeOf;
|
||||
use kvdb::{DBTransaction};
|
||||
use parking_lot::RwLock;
|
||||
use types::BlockNumber;
|
||||
@@ -91,7 +91,7 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
||||
}
|
||||
|
||||
fn cache_size(&self) -> usize {
|
||||
self.traces.read().heap_size_of_children()
|
||||
self.traces.read().malloc_size_of()
|
||||
}
|
||||
|
||||
/// Let the cache system know that a cacheable item has been used.
|
||||
@@ -113,7 +113,7 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
||||
}
|
||||
traces.shrink_to_fit();
|
||||
|
||||
traces.heap_size_of_children()
|
||||
traces.malloc_size_of()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -17,17 +17,19 @@
|
||||
//! Flat trace module
|
||||
|
||||
use rlp::{Rlp, RlpStream, Decodable, Encodable, DecoderError};
|
||||
use heapsize::HeapSizeOf;
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
use ethereum_types::Bloom;
|
||||
use super::trace::{Action, Res};
|
||||
|
||||
/// Trace localized in vector of traces produced by a single transaction.
|
||||
///
|
||||
/// Parent and children indexes refer to positions in this vector.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone, MallocSizeOf)]
|
||||
pub struct FlatTrace {
|
||||
#[ignore_malloc_size_of = "ignored for performance reason"]
|
||||
/// Type of action performed by a transaction.
|
||||
pub action: Action,
|
||||
#[ignore_malloc_size_of = "ignored for performance reason"]
|
||||
/// Result of this action.
|
||||
pub result: Res,
|
||||
/// Number of subtraces.
|
||||
@@ -45,12 +47,6 @@ impl FlatTrace {
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for FlatTrace {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.trace_address.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for FlatTrace {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.begin_list(4);
|
||||
@@ -76,7 +72,7 @@ impl Decodable for FlatTrace {
|
||||
}
|
||||
|
||||
/// Represents all traces produced by a single transaction.
|
||||
#[derive(Debug, PartialEq, Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||
#[derive(Debug, PartialEq, Clone, RlpEncodableWrapper, RlpDecodableWrapper, MallocSizeOf)]
|
||||
pub struct FlatTransactionTraces(Vec<FlatTrace>);
|
||||
|
||||
impl From<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||
@@ -85,12 +81,6 @@ impl From<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for FlatTransactionTraces {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.0.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl FlatTransactionTraces {
|
||||
/// Returns bloom of all traces in the collection.
|
||||
pub fn bloom(&self) -> Bloom {
|
||||
@@ -105,15 +95,9 @@ impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||
}
|
||||
|
||||
/// Represents all traces produced by transactions in a single block.
|
||||
#[derive(Debug, PartialEq, Clone, Default, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||
#[derive(Debug, PartialEq, Clone, Default, RlpEncodableWrapper, RlpDecodableWrapper, MallocSizeOf)]
|
||||
pub struct FlatBlockTraces(Vec<FlatTransactionTraces>);
|
||||
|
||||
impl HeapSizeOf for FlatBlockTraces {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.0.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<FlatTransactionTraces>> for FlatBlockTraces {
|
||||
fn from(v: Vec<FlatTransactionTraces>) -> Self {
|
||||
FlatBlockTraces(v)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use engines::EthEngine;
|
||||
use error::Error;
|
||||
|
||||
use heapsize::HeapSizeOf;
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
use ethereum_types::{H256, U256};
|
||||
|
||||
pub use self::blocks::Blocks;
|
||||
@@ -49,13 +49,13 @@ pub trait BlockLike {
|
||||
/// consistent.
|
||||
pub trait Kind: 'static + Sized + Send + Sync {
|
||||
/// The first stage: completely unverified.
|
||||
type Input: Sized + Send + BlockLike + HeapSizeOf;
|
||||
type Input: Sized + Send + BlockLike + MallocSizeOf;
|
||||
|
||||
/// The second stage: partially verified.
|
||||
type Unverified: Sized + Send + BlockLike + HeapSizeOf;
|
||||
type Unverified: Sized + Send + BlockLike + MallocSizeOf;
|
||||
|
||||
/// The third stage: completely verified.
|
||||
type Verified: Sized + Send + BlockLike + HeapSizeOf;
|
||||
type Verified: Sized + Send + BlockLike + MallocSizeOf;
|
||||
|
||||
/// Attempt to create the `Unverified` item from the input.
|
||||
fn create(input: Self::Input, engine: &dyn EthEngine, check_seal: bool) -> Result<Self::Unverified, (Self::Input, Error)>;
|
||||
@@ -74,7 +74,7 @@ pub mod blocks {
|
||||
use verification::{PreverifiedBlock, verify_block_basic, verify_block_unordered};
|
||||
use types::transaction::UnverifiedTransaction;
|
||||
|
||||
use heapsize::HeapSizeOf;
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
use ethereum_types::{H256, U256};
|
||||
use bytes::Bytes;
|
||||
|
||||
@@ -113,7 +113,7 @@ pub mod blocks {
|
||||
}
|
||||
|
||||
/// An unverified block.
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Debug, MallocSizeOf)]
|
||||
pub struct Unverified {
|
||||
/// Unverified block header.
|
||||
pub header: Header,
|
||||
@@ -146,15 +146,6 @@ pub mod blocks {
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for Unverified {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.header.heap_size_of_children()
|
||||
+ self.transactions.heap_size_of_children()
|
||||
+ self.uncles.heap_size_of_children()
|
||||
+ self.bytes.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockLike for Unverified {
|
||||
fn hash(&self) -> H256 {
|
||||
self.header.hash()
|
||||
|
||||
@@ -22,7 +22,7 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering};
|
||||
use std::sync::Arc;
|
||||
use std::cmp;
|
||||
use std::collections::{VecDeque, HashSet, HashMap};
|
||||
use heapsize::HeapSizeOf;
|
||||
use parity_util_mem::{MallocSizeOf, MallocSizeOfExt};
|
||||
use ethereum_types::{H256, U256};
|
||||
use parking_lot::{Condvar, Mutex, RwLock};
|
||||
use io::*;
|
||||
@@ -96,17 +96,12 @@ enum State {
|
||||
}
|
||||
|
||||
/// An item which is in the process of being verified.
|
||||
#[derive(MallocSizeOf)]
|
||||
pub struct Verifying<K: Kind> {
|
||||
hash: H256,
|
||||
output: Option<K::Verified>,
|
||||
}
|
||||
|
||||
impl<K: Kind> HeapSizeOf for Verifying<K> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.output.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
/// Status of items in the queue.
|
||||
pub enum Status {
|
||||
/// Currently queued.
|
||||
@@ -353,7 +348,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
None => continue,
|
||||
};
|
||||
|
||||
verification.sizes.unverified.fetch_sub(item.heap_size_of_children(), AtomicOrdering::SeqCst);
|
||||
verification.sizes.unverified.fetch_sub(item.malloc_size_of(), AtomicOrdering::SeqCst);
|
||||
verifying.push_back(Verifying { hash: item.hash(), output: None });
|
||||
item
|
||||
};
|
||||
@@ -367,7 +362,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
if e.hash == hash {
|
||||
idx = Some(i);
|
||||
|
||||
verification.sizes.verifying.fetch_add(verified.heap_size_of_children(), AtomicOrdering::SeqCst);
|
||||
verification.sizes.verifying.fetch_add(verified.malloc_size_of(), AtomicOrdering::SeqCst);
|
||||
e.output = Some(verified);
|
||||
break;
|
||||
}
|
||||
@@ -417,7 +412,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
|
||||
while let Some(output) = verifying.front_mut().and_then(|x| x.output.take()) {
|
||||
assert!(verifying.pop_front().is_some());
|
||||
let size = output.heap_size_of_children();
|
||||
let size = output.malloc_size_of();
|
||||
removed_size += size;
|
||||
|
||||
if bad.contains(&output.parent_hash()) {
|
||||
@@ -490,7 +485,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
|
||||
match K::create(input, &*self.engine, self.verification.check_seal) {
|
||||
Ok(item) => {
|
||||
self.verification.sizes.unverified.fetch_add(item.heap_size_of_children(), AtomicOrdering::SeqCst);
|
||||
self.verification.sizes.unverified.fetch_add(item.malloc_size_of(), AtomicOrdering::SeqCst);
|
||||
|
||||
self.processing.write().insert(hash, item.difficulty());
|
||||
{
|
||||
@@ -537,7 +532,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
let mut removed_size = 0;
|
||||
for output in verified.drain(..) {
|
||||
if bad.contains(&output.parent_hash()) {
|
||||
removed_size += output.heap_size_of_children();
|
||||
removed_size += output.malloc_size_of();
|
||||
bad.insert(output.hash());
|
||||
if let Some(difficulty) = processing.remove(&output.hash()) {
|
||||
let mut td = self.total_difficulty.write();
|
||||
@@ -574,7 +569,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
let count = cmp::min(max, verified.len());
|
||||
let result = verified.drain(..count).collect::<Vec<_>>();
|
||||
|
||||
let drained_size = result.iter().map(HeapSizeOf::heap_size_of_children).fold(0, |a, c| a + c);
|
||||
let drained_size = result.iter().map(MallocSizeOfExt::malloc_size_of).fold(0, |a, c| a + c);
|
||||
self.verification.sizes.verified.fetch_sub(drained_size, AtomicOrdering::SeqCst);
|
||||
|
||||
self.ready_signal.reset();
|
||||
|
||||
@@ -26,7 +26,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use bytes::Bytes;
|
||||
use hash::keccak;
|
||||
use heapsize::HeapSizeOf;
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
use rlp::Rlp;
|
||||
use triehash::ordered_trie_root;
|
||||
use unexpected::{Mismatch, OutOfBounds};
|
||||
@@ -44,6 +44,7 @@ use verification::queue::kind::blocks::Unverified;
|
||||
use time_utils::CheckedSystemTime;
|
||||
|
||||
/// Preprocessed block data gathered in `verify_block_unordered` call
|
||||
#[derive(MallocSizeOf)]
|
||||
pub struct PreverifiedBlock {
|
||||
/// Populated block header
|
||||
pub header: Header,
|
||||
@@ -55,14 +56,6 @@ pub struct PreverifiedBlock {
|
||||
pub bytes: Bytes,
|
||||
}
|
||||
|
||||
impl HeapSizeOf for PreverifiedBlock {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.header.heap_size_of_children()
|
||||
+ self.transactions.heap_size_of_children()
|
||||
+ self.bytes.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
/// Phase 1 quick block verification. Only does checks that are cheap. Operates on a single block
|
||||
pub fn verify_block_basic(block: &Unverified, engine: &dyn EthEngine, check_seal: bool) -> Result<(), Error> {
|
||||
verify_header_params(&block.header, engine, true, check_seal)?;
|
||||
|
||||
Reference in New Issue
Block a user