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:
cheme
2019-06-19 13:54:05 +02:00
committed by GitHub
parent 859a41308c
commit 6fc5014b4d
84 changed files with 926 additions and 1074 deletions

View File

@@ -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)
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}

View File

@@ -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()))

View File

@@ -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()))

View File

@@ -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;

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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)),

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
},

View File

@@ -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)
}
}
}

View File

@@ -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)));
}

View File

@@ -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()
});
}

View File

@@ -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)

View File

@@ -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()

View File

@@ -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();

View File

@@ -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)?;