Skip to content

Commit

Permalink
refactor: split Database trait into sub-traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Wodann committed Jan 13, 2023
1 parent d19e2dc commit b900ea5
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 129 deletions.
25 changes: 25 additions & 0 deletions Cargo.lock

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

9 changes: 6 additions & 3 deletions bins/revm-test/src/bin/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ fn main() {
let bytecode_checked = Bytecode::new_raw(contract_data.clone()).to_checked();
let bytecode_analysed = Bytecode::new_raw(contract_data).to_analysed::<revm::LondonSpec>();

evm.database(BenchmarkDB::new_bytecode(bytecode_raw));
let db = BenchmarkDB::new_bytecode(bytecode_raw);
evm.database(&db);

// just to spead up processor.
for _ in 0..10000 {
Expand All @@ -40,15 +41,17 @@ fn main() {
}
println!("Raw elapsed time: {:?}", timer.elapsed());

evm.database(BenchmarkDB::new_bytecode(bytecode_checked));
let db = BenchmarkDB::new_bytecode(bytecode_checked);
evm.database(&db);

let timer = Instant::now();
for _ in 0..30000 {
let (_, _) = evm.transact();
}
println!("Checked elapsed time: {:?}", timer.elapsed());

evm.database(BenchmarkDB::new_bytecode(bytecode_analysed));
let db = BenchmarkDB::new_bytecode(bytecode_analysed);
evm.database(&db);

let timer = Instant::now();
for _ in 0..30000 {
Expand Down
3 changes: 2 additions & 1 deletion bins/revm-test/src/bin/snailtracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ pub fn simple_example() {
// BenchmarkDB is dummy state that implements Database trait.
let mut evm = revm::new();
let bytecode = Bytecode::new_raw(contract_data).to_analysed::<BerlinSpec>();
evm.database(BenchmarkDB::new_bytecode(bytecode.clone()));
let db = BenchmarkDB::new_bytecode(bytecode.clone());
evm.database(&db);

// execution globals block hash/gas_limit/coinbase/timestamp..
evm.env.tx.caller = "0x1000000000000000000000000000000000000000"
Expand Down
1 change: 1 addition & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ auto_impl = { version = "1.0", default-features = false }
bytes = { version = "1.1", default-features = false }
hashbrown = { version = "0.13" }
hex = { version = "0.4", default-features = false }
impl-tools = { version = "0.6.2", default-features = false }
revm-precompiles = { path = "../precompiles", version = "1.1.2", default-features = false }
revm-interpreter = { path = "../interpreter", default-features = false }

Expand Down
29 changes: 29 additions & 0 deletions crates/revm/src/blockchain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use auto_impl::auto_impl;
use revm_interpreter::{B256, U256};

#[auto_impl(& mut, Box)]
pub trait BlockHash {
type Error;

/// Get block hash by block number
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error>;
}

#[auto_impl(&, Box, Arc)]
pub trait BlockHashRef {
type Error;

/// Get block hash by block number
fn block_hash(&self, number: U256) -> Result<B256, Self::Error>;
}

impl<T> BlockHash for &T
where
T: BlockHashRef,
{
type Error = <T as BlockHashRef>::Error;

fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
BlockHashRef::block_hash(*self, number)
}
}
115 changes: 61 additions & 54 deletions crates/revm/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,84 +2,91 @@ mod in_memory_db;

#[cfg(feature = "ethersdb")]
pub mod ethersdb;
#[cfg(feature = "ethersdb")]
pub use ethersdb::EthersDB;

#[cfg(all(not(feature = "ethersdb"), feature = "web3db"))]
compile_error!(
"`web3db` feature is deprecated, drop-in replacement can be found with feature `ethersdb`"
);

use crate::AccountInfo;
use crate::U256;
use crate::{interpreter::bytecode::Bytecode, Account};
use crate::{B160, B256};
use auto_impl::auto_impl;
#[cfg(feature = "ethersdb")]
pub use ethersdb::EthersDB;
use hashbrown::HashMap as Map;
pub use in_memory_db::{AccountState, BenchmarkDB, CacheDB, DbAccount, EmptyDB, InMemoryDB};

#[auto_impl(& mut, Box)]
pub trait Database {
type Error;
/// Get basic account information.
fn basic(&mut self, address: B160) -> Result<Option<AccountInfo>, Self::Error>;
/// Get account code by its hash
fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>;
/// Get storage value of address at index.
fn storage(&mut self, address: B160, index: U256) -> Result<U256, Self::Error>;

// History related
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error>;
use revm_interpreter::{Account, AccountInfo, Bytecode, B160, B256, U256};

use crate::{
blockchain::{BlockHash, BlockHashRef},
state::{State, StateRef},
StateCommit,
};

pub use self::in_memory_db::{AccountState, BenchmarkDB, CacheDB, DbAccount, EmptyDB, InMemoryDB};

#[impl_tools::autoimpl(for<T: trait> &mut T, Box<T>)]
pub trait Database: BlockHash + State {
type DatabaseError: From<<Self as BlockHash>::Error> + From<<Self as State>::Error>;
}

#[impl_tools::autoimpl(for<T: trait> &T, Box<T>)]
#[cfg_attr(feature = "std", impl_tools::autoimpl(for<T: trait> std::sync::Arc<T>))]
pub trait DatabaseRef: BlockHashRef + StateRef {
type DatabaseError: From<<Self as BlockHashRef>::Error> + From<<Self as StateRef>::Error>;
}

#[auto_impl(& mut, Box)]
pub trait DatabaseCommit {
fn commit(&mut self, changes: Map<B160, Account>);
impl<T> Database for &T
where
T: DatabaseRef,
{
type DatabaseError = <T as DatabaseRef>::DatabaseError;
}

#[auto_impl(&, Box, Arc)]
pub trait DatabaseRef {
type Error;
/// Whether account at address exists.
//fn exists(&self, address: B160) -> Option<AccountInfo>;
/// Get basic account information.
fn basic(&self, address: B160) -> Result<Option<AccountInfo>, Self::Error>;
/// Get account code by its hash
fn code_by_hash(&self, code_hash: B256) -> Result<Bytecode, Self::Error>;
/// Get storage value of address at index.
fn storage(&self, address: B160, index: U256) -> Result<U256, Self::Error>;

// History related
fn block_hash(&self, number: U256) -> Result<B256, Self::Error>;
pub struct DatabaseComponents<BH: BlockHash, S: State> {
block_hash: BH,
state: S,
}

pub struct RefDBWrapper<'a, Error> {
pub db: &'a dyn DatabaseRef<Error = Error>,
pub enum ComponentError<BHE, SE> {
BlockHashError(BHE),
StateError(SE),
}

impl<'a, Error> RefDBWrapper<'a, Error> {
pub fn new(db: &'a dyn DatabaseRef<Error = Error>) -> Self {
Self { db }
impl<BH: BlockHash, S: State> Database for DatabaseComponents<BH, S> {
type DatabaseError = ComponentError<BH::Error, S::Error>;
}

impl<BH: BlockHash, S: State> BlockHash for DatabaseComponents<BH, S> {
type Error = ComponentError<BH::Error, S::Error>;

fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
self.block_hash
.block_hash(number)
.map_err(ComponentError::BlockHashError)
}
}

impl<'a, Error> Database for RefDBWrapper<'a, Error> {
type Error = Error;
/// Get basic account information.
impl<BH: BlockHash, S: State> State for DatabaseComponents<BH, S> {
type Error = ComponentError<BH::Error, S::Error>;

fn basic(&mut self, address: B160) -> Result<Option<AccountInfo>, Self::Error> {
self.db.basic(address)
self.state
.basic(address)
.map_err(ComponentError::StateError)
}
/// Get account code by its hash

fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
self.db.code_by_hash(code_hash)
self.state
.code_by_hash(code_hash)
.map_err(ComponentError::StateError)
}
/// Get storage value of address at index.

fn storage(&mut self, address: B160, index: U256) -> Result<U256, Self::Error> {
self.db.storage(address, index)
self.state
.storage(address, index)
.map_err(ComponentError::StateError)
}
}

// History related
fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
self.db.block_hash(number)
impl<BH: BlockHash, S: State + StateCommit> StateCommit for DatabaseComponents<BH, S> {
fn commit(&mut self, changes: Map<B160, Account>) {
self.state.commit(changes)
}
}
15 changes: 11 additions & 4 deletions crates/revm/src/db/ethersdb.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::sync::Arc;
use std::{convert::Infallible, sync::Arc};

use crate::{
interpreter::bytecode::Bytecode, AccountInfo, Database, B160, B256, KECCAK_EMPTY, U256,
interpreter::bytecode::Bytecode, AccountInfo, BlockHash, State, B160, B256, KECCAK_EMPTY, U256,
};

use ethers_core::types::{BlockId, H160 as eH160, H256, U64 as eU64};
Expand Down Expand Up @@ -53,11 +53,11 @@ where
}
}

impl<M> Database for EthersDB<M>
impl<M> State for EthersDB<M>
where
M: Middleware,
{
type Error = ();
type Error = Infallible;

fn basic(&mut self, address: B160) -> Result<Option<AccountInfo>, Self::Error> {
let add = eH160::from(address.0);
Expand Down Expand Up @@ -104,6 +104,13 @@ where
};
Ok(self.block_on(f))
}
}

impl<M> BlockHash for EthersDB<M>
where
M: Middleware,
{
type Error = Infallible;

fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
// saturate usize
Expand Down
Loading

0 comments on commit b900ea5

Please sign in to comment.