Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

[WIP] Add get_with method to KeyValueDB and HashDB #5942

Closed
wants to merge 10 commits into from
44 changes: 32 additions & 12 deletions ethcore/src/account_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,17 @@ impl<'db> HashDB for AccountDB<'db>{
unimplemented!()
}

fn get(&self, key: &H256) -> Option<DBValue> {
fn get_exec(
&self,
key: &H256,
f: &mut FnMut(&[u8]),
) {
if key == &SHA3_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));
f(&NULL_RLP);
return;
}
self.db.get(&combine_key(&self.address_hash, key))

self.db.get_exec(&combine_key(&self.address_hash, key), f);
}

fn contains(&self, key: &H256) -> bool {
Expand Down Expand Up @@ -154,11 +160,17 @@ impl<'db> HashDB for AccountDBMut<'db>{
unimplemented!()
}

fn get(&self, key: &H256) -> Option<DBValue> {
fn get_exec(
&self,
key: &H256,
f: &mut FnMut(&[u8])
) {
if key == &SHA3_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));
f(&NULL_RLP);
return;
}
self.db.get(&combine_key(&self.address_hash, key))

self.db.get_exec(&combine_key(&self.address_hash, key), f);
}

fn contains(&self, key: &H256) -> bool {
Expand Down Expand Up @@ -202,11 +214,17 @@ impl<'db> HashDB for Wrapping<'db> {
unimplemented!()
}

fn get(&self, key: &H256) -> Option<DBValue> {
fn get_exec(
&self,
key: &H256,
f: &mut FnMut(&[u8])
) {
if key == &SHA3_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));
f(&NULL_RLP);
return;
}
self.0.get(key)

self.0.get_exec(key, f);
}

fn contains(&self, key: &H256) -> bool {
Expand Down Expand Up @@ -236,11 +254,13 @@ impl<'db> HashDB for WrappingMut<'db>{
unimplemented!()
}

fn get(&self, key: &H256) -> Option<DBValue> {
fn get_exec(&self, key: &H256, f: &mut FnMut(&[u8])) {
if key == &SHA3_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));
f(&NULL_RLP);
return;
}
self.0.get(key)

self.0.get_exec(key, f);
}

fn contains(&self, key: &H256) -> bool {
Expand Down
17 changes: 7 additions & 10 deletions ethcore/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use std::ops::Deref;
use std::hash::Hash;
use std::collections::HashMap;
use util::{DBTransaction, KeyValueDB, RwLock};
use util::{DBTransaction, KeyValueDBExt, RwLock};

use rlp;

Expand Down Expand Up @@ -216,20 +216,17 @@ impl Writable for DBTransaction {
}
}

impl<KVDB: KeyValueDB + ?Sized> Readable for KVDB {
impl<KVDB: KeyValueDBExt + ?Sized> Readable for KVDB {
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: rlp::Decodable, R: Deref<Target = [u8]> {
let result = self.get(col, &key.key());
let result = self.get_with(col, &key.key(), rlp::decode);

match result {
Ok(option) => option.map(|v| rlp::decode(&v)),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
result.unwrap_or_else(
|err| panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err)
)
}

fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {
let result = self.get(col, &key.key());
let result = self.get_with(col, &key.key(), |_| ());

match result {
Ok(v) => v.is_some(),
Expand Down
26 changes: 12 additions & 14 deletions ethcore/src/evm/benches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ fn simple_loop_log0_u256(b: &mut Bencher) {
}

fn simple_loop_log0(gas: U256, b: &mut Bencher) {
let mut vm = Factory::new(VMType::Interpreter).create(gas);
let mut vm = Factory::new(VMType::Interpreter, None).create(gas);
let mut ext = FakeExt::new();

let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = black_box(
let code: Arc<_> = black_box(
"62ffffff5b600190036000600fa0600357".from_hex().unwrap()
);
).into();

b.iter(|| {
let mut params = ActionParams::default();
Expand All @@ -69,16 +69,15 @@ fn mem_gas_calculation_same_u256(b: &mut Bencher) {
}

fn mem_gas_calculation_same(gas: U256, b: &mut Bencher) {
let mut vm = Factory::new(VMType::Interpreter).create(gas);
let mut vm = Factory::new(VMType::Interpreter, None).create(gas);
let mut ext = FakeExt::new();

let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code: Arc<_> = black_box(
"6110006001556001546000555b610fff805560016000540380600055600c57".from_hex().unwrap()
).into();

b.iter(|| {
let code = black_box(
"6110006001556001546000555b610fff805560016000540380600055600c57".from_hex().unwrap()
);

let mut params = ActionParams::default();
params.address = address.clone();
params.gas = gas;
Expand All @@ -99,16 +98,15 @@ fn mem_gas_calculation_increasing_u256(b: &mut Bencher) {
}

fn mem_gas_calculation_increasing(gas: U256, b: &mut Bencher) {
let mut vm = Factory::new(VMType::Interpreter).create(gas);
let mut vm = Factory::new(VMType::Interpreter, None).create(gas);
let mut ext = FakeExt::new();

let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code: Arc<_> = black_box(
"6110006001556001546000555b610fff60005401805560016000540380600055600c57".from_hex().unwrap()
).into();

b.iter(|| {
let code = black_box(
"6110006001556001546000555b610fff60005401805560016000540380600055600c57".from_hex().unwrap()
);

let mut params = ActionParams::default();
params.address = address.clone();
params.gas = gas;
Expand All @@ -121,7 +119,7 @@ fn mem_gas_calculation_increasing(gas: U256, b: &mut Bencher) {
fn result(r: evm::Result<evm::GasLeft>) -> U256 {
match r {
Ok(evm::GasLeft::Known(v)) => v,
Ok(evm::GasLeft::NeedsReturn(v, _)) => v,
Ok(evm::GasLeft::NeedsReturn { gas_left, .. }) => gas_left,
_ => U256::zero(),
}
}
15 changes: 9 additions & 6 deletions ethcore/src/evm/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ impl Factory {

/// Create new instance of specific `VMType` factory, with a size in bytes
/// for caching jump destinations.
pub fn new(evm: VMType, cache_size: usize) -> Self {
pub fn new<T: Into<Option<usize>>>(evm: VMType, maybe_cache_size: T) -> Self {
const DEFAULT_CACHE_SIZE: usize = 1024 * 32;
let cache_size = maybe_cache_size.into().unwrap_or(DEFAULT_CACHE_SIZE);

Factory {
evm: evm,
evm_cache: Arc::new(SharedCache::new(cache_size)),
Expand Down Expand Up @@ -106,18 +109,18 @@ macro_rules! evm_test(
#[ignore]
#[cfg(feature = "jit")]
fn $name_jit() {
$name_test(Factory::new(VMType::Jit, 1024 * 32));
$name_test(Factory::new(VMType::Jit, None));
}
#[test]
fn $name_int() {
$name_test(Factory::new(VMType::Interpreter, 1024 * 32));
$name_test(Factory::new(VMType::Interpreter, None));
}
};
($name_test: ident: $name_jit: ident, $name_int: ident) => {
#[test]
#[cfg(feature = "jit")]
fn $name_jit() {
$name_test(Factory::new(VMType::Jit, 1024 * 32));
$name_test(Factory::new(VMType::Jit, None));
}
#[test]
fn $name_int() {
Expand All @@ -135,13 +138,13 @@ macro_rules! evm_test_ignore(
#[cfg(feature = "jit")]
#[cfg(feature = "ignored-tests")]
fn $name_jit() {
$name_test(Factory::new(VMType::Jit, 1024 * 32));
$name_test(Factory::new(VMType::Jit, None));
}
#[test]
#[ignore]
#[cfg(feature = "ignored-tests")]
fn $name_int() {
$name_test(Factory::new(VMType::Interpreter, 1024 * 32));
$name_test(Factory::new(VMType::Interpreter, None));
}
}
);
4 changes: 2 additions & 2 deletions ethcore/src/evm/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ fn test_stack_underflow() {

evm_test!{test_add: test_add_jit, test_add_int}
fn test_add(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();

let mut params = ActionParams::default();
Expand Down Expand Up @@ -895,7 +895,7 @@ fn test_signextend(factory: super::Factory) {

#[test] // JIT just returns out of gas
fn test_badinstruction_int() {
let factory = super::Factory::new(VMType::Interpreter, 1024 * 32);
let factory = super::Factory::new(VMType::Interpreter, None);
let code = "af".from_hex().unwrap();

let mut params = ActionParams::default();
Expand Down
8 changes: 3 additions & 5 deletions ethcore/src/migrations/state/v7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,14 @@
//! This migration migrates the state db to use an accountdb which ensures uniqueness
//! using an address' hash as opposed to the address itself.

use rlp::{decode, Rlp, RlpStream};
use std::collections::HashMap;
use std::sync::Arc;

use util::Bytes;
use util::{Address, H256};
use util::{Bytes, Address, H256};
use util::kvdb::Database;
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
use util::sha3::Hashable;
use std::sync::Arc;

use rlp::{decode, Rlp, RlpStream};

// attempt to migrate a key, value pair. None if migration not possible.
fn attempt_migrate(mut key_h: H256, val: &[u8]) -> Option<H256> {
Expand Down
10 changes: 4 additions & 6 deletions ethcore/src/migrations/v10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@

//! Bloom upgrade

use std::sync::Arc;
use bloom_journal::Bloom;
use db::{COL_EXTRA, COL_HEADERS, COL_STATE};
use state_db::{ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET, StateDB};
use std::sync::Arc;
use util::{journaldb, H256, Trie, Database, DBTransaction};
use util::migration::{Error, Migration, Progress, Batch, Config};
use util::trie::TrieDB;
use views::HeaderView;
use bloom_journal::Bloom;
use util::migration::{Error, Migration, Progress, Batch, Config};
use util::journaldb;
use util::{H256, Trie};
use util::{Database, DBTransaction};

/// Account bloom upgrade routine. If bloom already present, does nothing.
/// If database empty (no best block), does nothing.
Expand Down
15 changes: 7 additions & 8 deletions ethcore/src/snapshot/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@

//! Snapshot network service implementation.

use std::collections::HashSet;
use std::io::ErrorKind;
use std::fs;
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService};
use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter};

Expand All @@ -31,9 +24,15 @@ use client::{BlockChainClient, Client};
use engines::Engine;
use error::Error;
use ids::BlockId;
use service::ClientIoMessage;

use io::IoChannel;
use service::ClientIoMessage;
use std::collections::HashSet;
use std::fs;
use std::io::ErrorKind;
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

use util::{Bytes, H256, Mutex, RwLock, RwLockReadGuard, UtilError};
use util::journaldb::Algorithm;
Expand Down
38 changes: 31 additions & 7 deletions ethcore/src/state/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ impl HashDB for ProofCheck {
self.0.get(key)
}

fn get_exec(
&self,
key: &H256,
f: &mut FnMut(&[u8])
) {
self.0.get_exec(key, f);
}

fn contains(&self, key: &H256) -> bool {
self.0.contains(key)
}
Expand Down Expand Up @@ -139,13 +147,29 @@ impl<H: AsHashDB + Send + Sync> HashDB for Proving<H> {
keys
}

fn get(&self, key: &H256) -> Option<DBValue> {
match self.base.as_hashdb().get(key) {
Some(val) => {
self.proof.lock().insert(val.clone());
Some(val)
}
None => self.changed.get(key)
fn get_exec(
&self,
key: &H256,
mut f: &mut FnMut(&[u8])
) {
let mut called = false;

{
let mut optional_f = Some(&mut f);
let mut wrapper = |val: &[u8]| {
called = true;
self.proof.lock().insert(DBValue::from_slice(val));

if let Some(f) = optional_f.take() {
f(val);
}
};

self.base.as_hashdb().get_exec(key, &mut wrapper);
}

if !called {
self.changed.get_exec(key, f);
}
}

Expand Down
Loading