Skip to content

Commit

Permalink
make tests work again
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse committed Sep 2, 2022
1 parent eeab142 commit 78d7ec5
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 32 deletions.
47 changes: 22 additions & 25 deletions evm/src/executor/backend/in_memory_db.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! The in memory DB
use crate::executor::backend::{error::DatabaseError, DatabaseResult};
use crate::executor::backend::error::DatabaseError;
use ethers::{
prelude::{H256, U256},
types::Address,
Expand All @@ -12,31 +12,18 @@ use revm::{

use crate::executor::snapshot::Snapshots;

pub type InMemoryDB = CacheDB<EmptyDBWrapper>;
/// Type alias for an in memory database
///
/// See `EmptyDBWrapper`
pub type FoundryEvmInMemoryDB = CacheDB<EmptyDBWrapper>;

/// In memory Database for anvil
///
/// This acts like a wrapper type for [InMemoryDB] but is capable of applying snapshots
#[derive(Debug)]
pub struct MemDb {
pub inner: InMemoryDB,
pub snapshots: Snapshots<InMemoryDB>,
}

impl MemDb {
/// the [`Database`](revm::Database) implementation for `CacheDB` manages an `AccountState` for the `DbAccount`, this will be set to `AccountState::NotExisting` if the account does not exist yet. This is because there's a distinction between "non-existing" and "empty", See <https://github.com/bluealloy/revm/blob/8f4348dc93022cffb3730d9db5d3ab1aad77676a/crates/revm/src/db/in_memory_db.rs#L81-L83>
/// If an account is `NotExisting`, `Database(Ref)::basic` will always return `None` for the
/// requested `AccountInfo`. To prevent
///
/// This will ensure that a missing account is never marked as `NotExisting`
fn ensure_loaded(&mut self, address: Address) -> DatabaseResult<AccountInfo> {
if let Some(acc) = DatabaseRef::basic(self, address)? {
Ok(acc)
} else {
self.inner.insert_account_info(address, Default::default());
Ok(Default::default())
}
}
pub inner: FoundryEvmInMemoryDB,
pub snapshots: Snapshots<FoundryEvmInMemoryDB>,
}

impl Default for MemDb {
Expand Down Expand Up @@ -68,15 +55,15 @@ impl Database for MemDb {
type Error = DatabaseError;

fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
self.ensure_loaded(address).map(Some)
// Note: this will always return `Some(AccountInfo)`, See `EmptyDBWrapper`
Database::basic(&mut self.inner, address)
}

fn code_by_hash(&mut self, code_hash: H256) -> Result<Bytecode, Self::Error> {
Database::code_by_hash(&mut self.inner, code_hash)
}

fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
self.ensure_loaded(address)?;
Database::storage(&mut self.inner, address, index)
}

Expand All @@ -95,13 +82,23 @@ impl DatabaseCommit for MemDb {
///
/// This is just a simple wrapper for `revm::EmptyDB` but implements `DatabaseError` instead, this
/// way we can unify all different `Database` impls
///
/// This will also _always_ return `Some(AccountInfo)`:
///
/// The [`Database`](revm::Database) implementation for `CacheDB` manages an `AccountState` for the `DbAccount`, this will be set to `AccountState::NotExisting` if the account does not exist yet. This is because there's a distinction between "non-existing" and "empty", See <https://github.com/bluealloy/revm/blob/8f4348dc93022cffb3730d9db5d3ab1aad77676a/crates/revm/src/db/in_memory_db.rs#L81-L83>
/// If an account is `NotExisting`, `Database(Ref)::basic` will always return `None` for the
/// requested `AccountInfo`. To prevent
///
/// This will ensure that a missing account is never marked as `NotExisting`
#[derive(Debug, Default, Clone)]
pub struct EmptyDBWrapper(EmptyDB);

impl DatabaseRef for EmptyDBWrapper {
type Error = DatabaseError;

fn basic(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
Ok(self.0.basic(address)?)
// Note: this will always return `Some(AccountInfo)`, for the reason explained above
Ok(Some(self.0.basic(address)?.unwrap_or_default()))
}
fn code_by_hash(&self, code_hash: H256) -> Result<Bytecode, Self::Error> {
Ok(self.0.code_by_hash(code_hash)?)
Expand All @@ -124,7 +121,7 @@ mod tests {
/// Demonstrates how calling `Database::basic` works if an account does not exist
#[test]
fn cache_db_insert_basic_non_existing() {
let mut db = CacheDB::new(EmptyDBWrapper::default());
let mut db = CacheDB::new(EmptyDB::default());
let address = Address::random();

// call `basic` on a non-existing account
Expand All @@ -144,7 +141,7 @@ mod tests {
/// Demonstrates how to insert a new account but not mark it as non-existing
#[test]
fn cache_db_insert_basic_default() {
let mut db = CacheDB::new(EmptyDBWrapper::default());
let mut db = CacheDB::new(EmptyDB::default());
let address = Address::random();

let info = DatabaseRef::basic(&db, address).unwrap();
Expand Down
15 changes: 8 additions & 7 deletions evm/src/executor/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub use in_memory_db::MemDb;
use revm::{
db::{CacheDB, DatabaseRef},
precompiles::Precompiles,
Account, AccountInfo, Bytecode, Database, DatabaseCommit, Env, ExecutionResult, InMemoryDB,
Inspector, JournaledState, Log, SpecId, TransactTo, KECCAK_EMPTY,
Account, AccountInfo, Bytecode, Database, DatabaseCommit, Env, ExecutionResult, Inspector,
JournaledState, Log, SpecId, TransactTo, KECCAK_EMPTY,
};
use std::collections::{HashMap, HashSet};
use tracing::{trace, warn};
Expand All @@ -30,6 +30,7 @@ use crate::executor::inspector::cheatcodes::util::with_journaled_account;
pub use diagnostic::RevertDiagnostic;

pub mod error;
use crate::executor::backend::in_memory_db::FoundryEvmInMemoryDB;
pub use error::{DatabaseError, DatabaseResult};

mod in_memory_db;
Expand Down Expand Up @@ -263,7 +264,7 @@ pub struct Backend {
/// The access point for managing forks
forks: MultiFork,
// The default in memory db
mem_db: InMemoryDB,
mem_db: FoundryEvmInMemoryDB,
/// The journaled_state to use to initialize new forks with
///
/// The way [`revm::JournaledState`] works is, that it holds the "hot" accounts loaded from the
Expand Down Expand Up @@ -310,7 +311,7 @@ impl Backend {

let mut backend = Self {
forks,
mem_db: InMemoryDB::default(),
mem_db: CacheDB::new(Default::default()),
fork_init_journaled_state: inner.new_journaled_state(),
active_fork_ids: None,
inner,
Expand All @@ -336,7 +337,7 @@ impl Backend {
pub fn clone_empty(&self) -> Self {
Self {
forks: self.forks.clone(),
mem_db: InMemoryDB::default(),
mem_db: CacheDB::new(Default::default()),
fork_init_journaled_state: self.inner.new_journaled_state(),
active_fork_ids: None,
inner: Default::default(),
Expand Down Expand Up @@ -459,7 +460,7 @@ impl Backend {
}

/// Returns the memory db used if not in forking mode
pub fn mem_db(&self) -> &InMemoryDB {
pub fn mem_db(&self) -> &FoundryEvmInMemoryDB {
&self.mem_db
}

Expand Down Expand Up @@ -987,7 +988,7 @@ impl Database for Backend {
#[derive(Debug, Clone)]
pub enum BackendDatabaseSnapshot {
/// Simple in-memory [revm::Database]
InMemory(InMemoryDB),
InMemory(FoundryEvmInMemoryDB),
/// Contains the entire forking mode database
Forked(LocalForkId, ForkId, ForkLookupIndex, Box<Fork>),
}
Expand Down

0 comments on commit 78d7ec5

Please sign in to comment.