Skip to content

Commit

Permalink
fix more breaking changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse committed Sep 1, 2022
1 parent 61afb08 commit 30cd6ee
Show file tree
Hide file tree
Showing 17 changed files with 80 additions and 72 deletions.
8 changes: 4 additions & 4 deletions anvil/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,7 @@ impl EthApi {
/// Handler for RPC call: `anvil_setBalance`
pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
node_info!("anvil_setBalance");
self.backend.set_balance(address, balance).await;
self.backend.set_balance(address, balance).await?;
Ok(())
}

Expand All @@ -1348,7 +1348,7 @@ impl EthApi {
/// Handler for RPC call: `anvil_setCode`
pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
node_info!("anvil_setCode");
self.backend.set_code(address, code).await;
self.backend.set_code(address, code).await?;
Ok(())
}

Expand All @@ -1357,7 +1357,7 @@ impl EthApi {
/// Handler for RPC call: `anvil_setNonce`
pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
node_info!("anvil_setNonce");
self.backend.set_nonce(address, nonce).await;
self.backend.set_nonce(address, nonce).await?;
Ok(())
}

Expand All @@ -1371,7 +1371,7 @@ impl EthApi {
val: H256,
) -> Result<bool> {
node_info!("anvil_setStorageAt");
self.backend.set_storage_at(address, slot, val).await;
self.backend.set_storage_at(address, slot, val).await?;
Ok(true)
}

Expand Down
10 changes: 6 additions & 4 deletions anvil/src/eth/backend/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use foundry_evm::{
};
use hash_db::HashDB;
use serde::{Deserialize, Serialize};
use std::fmt;

/// Type alias for the `HashDB` representation of the Database
pub type AsHashDB = Box<dyn HashDB<KeccakHasher, Vec<u8>>>;
Expand Down Expand Up @@ -68,6 +69,7 @@ pub trait Db:
+ Database<Error = DatabaseError>
+ DatabaseCommit
+ MaybeHashDatabase
+ fmt::Debug
+ Send
+ Sync
{
Expand All @@ -76,23 +78,23 @@ pub trait Db:

/// Sets the nonce of the given address
fn set_nonce(&mut self, address: Address, nonce: u64) -> DatabaseResult<()> {
let mut info = self.basic(address)?.ok_or(DatabaseError::MissingAccount(address))?;
let mut info = self.basic(address)?.unwrap_or_default();
info.nonce = nonce;
self.insert_account(address, info);
Ok(())
}

/// Sets the balance of the given address
fn set_balance(&mut self, address: Address, balance: U256) -> DatabaseResult<()> {
let mut info = self.basic(address)?.ok_or(DatabaseError::MissingAccount(address))?;
let mut info = self.basic(address)?.unwrap_or_default();
info.balance = balance;
self.insert_account(address, info);
Ok(())
}

/// Sets the balance of the given address
fn set_code(&mut self, address: Address, code: Bytes) -> DatabaseResult<()> {
let mut info = self.basic(address)?.ok_or(DatabaseError::MissingAccount(address))?;
let mut info = self.basic(address)?.unwrap_or_default();
let code_hash = if code.as_ref().is_empty() {
KECCAK_EMPTY
} else {
Expand Down Expand Up @@ -137,7 +139,7 @@ pub trait Db:
/// This is useful to create blocks without actually writing to the `Db`, but rather in the cache of
/// the `CacheDB` see also
/// [Backend::pending_block()](crate::eth::backend::mem::Backend::pending_block())
impl<T: DatabaseRef<Error = DatabaseError> + Send + Sync + Clone> Db for CacheDB<T> {
impl<T: DatabaseRef<Error = DatabaseError> + Send + Sync + Clone + fmt::Debug> Db for CacheDB<T> {
fn insert_account(&mut self, address: Address, account: AccountInfo) {
self.insert_account_info(address, account)
}
Expand Down
12 changes: 4 additions & 8 deletions anvil/src/eth/backend/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,11 @@ impl<'a, 'b, DB: Db + ?Sized, Validator: TransactionValidator> Iterator
fn next(&mut self) -> Option<Self::Item> {
let transaction = self.pending.next()?;
let sender = *transaction.pending_transaction.sender();
let account = match self.db.basic(sender) {
Ok(Some(account)) => account,
Ok(None) => {
return Some(TransactionExecutionOutcome::DatabaseError(
transaction,
DatabaseError::MissingAccount(sender),
))
let account = match self.db.basic(sender).map(|acc| acc.unwrap_or_default()) {
Ok(account) => account,
Err(err) => {
return { Some(TransactionExecutionOutcome::DatabaseError(transaction, err)) }
}
Err(err) => return Some(TransactionExecutionOutcome::DatabaseError(transaction, err)),
};
let env = self.env_for(&transaction.pending_transaction);
// check that we comply with the block's gas limit
Expand Down
10 changes: 7 additions & 3 deletions anvil/src/eth/backend/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ethers::{
types::{Address, U256},
};
use forge::revm::KECCAK_EMPTY;
use foundry_evm::revm::AccountInfo;
use foundry_evm::{executor::backend::DatabaseResult, revm::AccountInfo};
use parking_lot::Mutex;
use std::sync::Arc;
use tokio::sync::RwLockWriteGuard;
Expand Down Expand Up @@ -47,17 +47,21 @@ impl GenesisConfig {
}

/// If an initial `genesis.json` was provided, this applies the account alloc to the db
pub fn apply_genesis_json_alloc(&self, mut db: RwLockWriteGuard<'_, dyn Db>) {
pub fn apply_genesis_json_alloc(
&self,
mut db: RwLockWriteGuard<'_, dyn Db>,
) -> DatabaseResult<()> {
if let Some(ref genesis) = self.genesis_init {
for (addr, mut acc) in genesis.alloc.accounts.clone() {
let storage = std::mem::take(&mut acc.storage);
// insert all accounts
db.insert_account(addr, acc.into());
// insert all storage values
for (k, v) in storage.iter() {
db.set_storage_at(addr, k.into_uint(), v.into_uint());
db.set_storage_at(addr, k.into_uint(), v.into_uint())?;
}
}
}
Ok(())
}
}
4 changes: 2 additions & 2 deletions anvil/src/eth/backend/mem/fork_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ethers::prelude::H256;
use forge::revm::Database;
pub use foundry_evm::executor::fork::database::ForkedDatabase;
use foundry_evm::executor::{
backend::{snapshot::StateSnapshot, DatabaseError, DatabaseResult},
backend::{snapshot::StateSnapshot, DatabaseResult},
fork::database::ForkDbSnapshot,
};

Expand All @@ -19,7 +19,7 @@ impl Db for ForkedDatabase {

fn set_storage_at(&mut self, address: Address, slot: U256, val: U256) -> DatabaseResult<()> {
// this ensures the account is loaded first
let _ = Database::basic(self, address)?.ok_or(DatabaseError::MissingAccount(address))?;
let _ = Database::basic(self, address)?;
self.database_mut().set_storage_at(address, slot, val)
}

Expand Down
2 changes: 1 addition & 1 deletion anvil/src/eth/backend/mem/in_memory_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl Db for MemDb {
}

fn set_storage_at(&mut self, address: Address, slot: U256, val: U256) -> DatabaseResult<()> {
Ok(self.inner.insert_account_storage(address, slot, val)?)
self.inner.insert_account_storage(address, slot, val)
}

fn insert_block_hash(&mut self, number: U256, hash: H256) {
Expand Down
30 changes: 18 additions & 12 deletions anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ impl Backend {
active_snapshots: Arc::new(Mutex::new(Default::default())),
};

backend.apply_genesis().await;
// Note: this can only fail in forking mode, in which case we can't recover
backend.apply_genesis().await.expect("Failed to create genesis");
backend
}

Expand All @@ -196,7 +197,7 @@ impl Backend {
fork_genesis_infos.clear();

for address in self.genesis.accounts.iter().copied() {
let mut info = db.basic(address)?.ok_or(DatabaseError::MissingAccount(address))?;
let mut info = db.basic(address)?.unwrap_or_default();
info.balance = self.genesis.balance;
db.insert_account(address, info.clone());

Expand All @@ -210,7 +211,7 @@ impl Backend {
}

// apply the genesis.json alloc
self.genesis.apply_genesis_json_alloc(db);
self.genesis.apply_genesis_json_alloc(db)?;
Ok(())
}

Expand Down Expand Up @@ -241,7 +242,7 @@ impl Backend {
pub async fn stop_impersonating(&self, addr: Address) -> DatabaseResult<()> {
if let Some((Some(code_hash), code)) = self.cheats.stop_impersonating(&addr) {
let mut db = self.db.write().await;
let mut account = db.basic(addr)?.ok_or(DatabaseError::MissingAccount(addr))?;
let mut account = db.basic(addr)?.unwrap_or_default();
account.code_hash = code_hash;
account.code = code;
db.insert_account(addr, account)
Expand All @@ -261,7 +262,7 @@ impl Backend {

/// Returns the `AccountInfo` from the database
pub async fn get_account(&self, address: Address) -> DatabaseResult<AccountInfo> {
self.db.read().await.basic(address)?.ok_or(DatabaseError::MissingAccount(address))
Ok(self.db.read().await.basic(address)?.unwrap_or_default())
}

/// Whether we're forked off some remote client
Expand Down Expand Up @@ -320,7 +321,7 @@ impl Backend {
}

// reset the genesis.json alloc
self.genesis.apply_genesis_json_alloc(db);
self.genesis.apply_genesis_json_alloc(db)?;

Ok(())
} else {
Expand Down Expand Up @@ -406,8 +407,13 @@ impl Backend {
}

/// Sets the value for the given slot of the given address
pub async fn set_storage_at(&self, address: Address, slot: U256, val: H256) {
self.db.write().await.set_storage_at(address, slot, val.into_uint());
pub async fn set_storage_at(
&self,
address: Address,
slot: U256,
val: H256,
) -> DatabaseResult<()> {
self.db.write().await.set_storage_at(address, slot, val.into_uint())
}

/// Returns true for post London
Expand Down Expand Up @@ -834,7 +840,7 @@ impl Backend {
let to = if let Some(to) = request.to {
to
} else {
let nonce = state.basic(from)?.ok_or(DatabaseError::MissingAccount(from))?.nonce;
let nonce = state.basic(from)?.unwrap_or_default().nonce;
get_contract_address(from, nonce)
};

Expand Down Expand Up @@ -1310,7 +1316,7 @@ impl Backend {
D: DatabaseRef<Error = DatabaseError>,
{
trace!(target: "backend", "get code for {:?}", address);
let account = state.basic(address)?.ok_or(DatabaseError::MissingAccount(address))?;
let account = state.basic(address)?.unwrap_or_default();
if account.code_hash == KECCAK_EMPTY {
// if the code hash is `KECCAK_EMPTY`, we check no further
return Ok(Default::default())
Expand Down Expand Up @@ -1344,7 +1350,7 @@ impl Backend {
D: DatabaseRef<Error = DatabaseError>,
{
trace!(target: "backend", "get balance for {:?}", address);
Ok(state.basic(address)?.ok_or(DatabaseError::MissingAccount(address))?.balance)
Ok(state.basic(address)?.unwrap_or_default().balance)
}

/// Returns the nonce of the address
Expand All @@ -1357,7 +1363,7 @@ impl Backend {
) -> Result<U256, BlockchainError> {
self.with_database_at(block_request, |db, _| {
trace!(target: "backend", "get nonce for {:?}", address);
Ok(db.basic(address)?.ok_or(DatabaseError::MissingAccount(address))?.nonce.into())
Ok(db.basic(address)?.unwrap_or_default().nonce.into())
})
.await?
}
Expand Down
3 changes: 1 addition & 2 deletions anvil/src/eth/backend/mem/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ where
{
let mut cache_db = CacheDB::new(state);
for (account, account_overrides) in overrides.iter() {
let mut account_info =
cache_db.basic(*account)?.ok_or(DatabaseError::MissingAccount(*account))?;
let mut account_info = cache_db.basic(*account)?.unwrap_or_default();

if let Some(nonce) = account_overrides.nonce {
account_info.nonce = nonce;
Expand Down
8 changes: 6 additions & 2 deletions anvil/tests/it/anvil_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,19 @@ async fn can_set_storage() {

#[tokio::test(flavor = "multi_thread")]
async fn can_impersonate_account() {
crate::init_tracing();
let (api, handle) = spawn(NodeConfig::test()).await;
let provider = handle.http_provider();

let impersonate = Address::random();
let to = Address::random();
let val = 1337u64;

let funding = U256::from(1e18 as u64);
// fund the impersonated account
api.anvil_set_balance(impersonate, U256::from(1e18 as u64)).await.unwrap();
api.anvil_set_balance(impersonate, funding).await.unwrap();

let balance = api.balance(impersonate, None).await.unwrap();
assert_eq!(balance, funding);

let tx = TransactionRequest::new().from(impersonate).to(to).value(val);

Expand Down
14 changes: 8 additions & 6 deletions cli/src/cmd/forge/script/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ impl ScriptRunner {
if !is_broadcast {
if self.sender == Config::DEFAULT_SENDER {
// We max out their balance so that they can deploy and make calls.
self.executor.set_balance(self.sender, U256::MAX);
self.executor.set_balance(self.sender, U256::MAX)?;
}

if need_create2_deployer {
self.executor.deploy_create2_deployer()?;
}
}

self.executor.set_nonce(self.sender, sender_nonce.as_u64());
self.executor.set_nonce(self.sender, sender_nonce.as_u64())?;

// We max out their balance so that they can deploy and make calls.
self.executor.set_balance(CALLER, U256::MAX);
self.executor.set_balance(CALLER, U256::MAX)?;

// Deploy libraries
let mut traces: Vec<(TraceKind, CallTraceArena)> = libraries
Expand Down Expand Up @@ -78,7 +78,7 @@ impl ScriptRunner {
.map_err(|err| eyre::eyre!("Failed to deploy script:\n{}", err))?;

traces.extend(constructor_traces.map(|traces| (TraceKind::Deployment, traces)).into_iter());
self.executor.set_balance(address, self.initial_balance);
self.executor.set_balance(address, self.initial_balance)?;

// Optionally call the `setUp` function
let (success, gas_used, labeled_addresses, transactions, debug) = if !setup {
Expand Down Expand Up @@ -113,8 +113,10 @@ impl ScriptRunner {
// any broadcasts, then the EVM cheatcode module hasn't corrected the nonce.
// So we have to
if transactions.is_none() || transactions.as_ref().unwrap().is_empty() {
self.executor
.set_nonce(self.sender, sender_nonce.as_u64() + libraries.len() as u64);
self.executor.set_nonce(
self.sender,
sender_nonce.as_u64() + libraries.len() as u64,
)?;
}

(
Expand Down
14 changes: 9 additions & 5 deletions evm/src/executor/backend/in_memory_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use ethers::{
types::Address,
};
use hashbrown::HashMap as Map;
use revm::{db::DatabaseRef, Account, AccountInfo, Bytecode, Database, DatabaseCommit};
use revm::db::{CacheDB, EmptyDB};
use revm::{
db::{CacheDB, DatabaseRef, EmptyDB},
Account, AccountInfo, Bytecode, Database, DatabaseCommit,
};

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

Expand All @@ -30,6 +32,7 @@ impl Default for MemDb {
impl DatabaseRef for MemDb {
type Error = DatabaseError;
fn basic(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
dbg!("basic");
DatabaseRef::basic(&self.inner, address)
}

Expand All @@ -49,6 +52,7 @@ impl DatabaseRef for MemDb {
impl Database for MemDb {
type Error = DatabaseError;
fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
dbg!("basic mut");
Database::basic(&mut self.inner, address)
}

Expand All @@ -71,10 +75,10 @@ impl DatabaseCommit for MemDb {
}
}


/// An empty database that always returns default values when queried.
///
/// This is just a simple wrapper for `revm::EmptyDB` but implements `DatabaseError` instead, this way we can unify all different `Database` impls
/// This is just a simple wrapper for `revm::EmptyDB` but implements `DatabaseError` instead, this
/// way we can unify all different `Database` impls
#[derive(Debug, Default, Clone)]
pub struct EmptyDBWrapper(EmptyDB);

Expand All @@ -93,4 +97,4 @@ impl DatabaseRef for EmptyDBWrapper {
fn block_hash(&self, number: U256) -> Result<H256, Self::Error> {
Ok(self.0.block_hash(number)?)
}
}
}
Loading

0 comments on commit 30cd6ee

Please sign in to comment.