Skip to content

Commit

Permalink
use backend error instead of database error
Browse files Browse the repository at this point in the history
  • Loading branch information
Jrigada committed Jul 29, 2024
1 parent c63a80c commit abe0b00
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 34 deletions.
25 changes: 16 additions & 9 deletions crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ use crate::{
},
inspector::utils::CommonCreateInput,
script::{Broadcast, ScriptWallets},
test::expect::{
self, ExpectedEmit,
ExpectedRevert, ExpectedRevertKind,
},
test::expect::{self, ExpectedEmit, ExpectedRevert, ExpectedRevertKind},
CheatsConfig, CheatsCtxt, DynCheatcode, Error, Result, Vm,
Vm::AccountAccess,
};
use alloy_primitives::{hex, keccak256, Address, Bytes, Log, TxKind, B256, U256};
use alloy_rpc_types::request::{TransactionInput, TransactionRequest};
use alloy_sol_types::{SolCall, SolInterface, SolValue};
use foundry_cheatcodes_common::{expect::{ExpectedCallData, ExpectedCallTracker, ExpectedCallType}, mock::{MockCallDataContext, MockCallReturnData}, record::RecordAccess};
use foundry_cheatcodes_common::{
expect::{ExpectedCallData, ExpectedCallTracker, ExpectedCallType},
mock::{MockCallDataContext, MockCallReturnData},
record::RecordAccess,
};
use foundry_common::{evm::Breakpoints, SELECTOR_LEN};
use foundry_config::Config;
use foundry_evm_core::{
Expand All @@ -37,17 +38,24 @@ use foundry_zksync_core::{
use itertools::Itertools;
use revm::{
interpreter::{
opcode, CallInputs, CallOutcome, CallScheme, CreateInputs, CreateOutcome, EOFCreateInputs, Gas, InstructionResult, Interpreter, InterpreterAction, InterpreterResult
opcode, CallInputs, CallOutcome, CallScheme, CreateInputs, CreateOutcome, EOFCreateInputs,
Gas, InstructionResult, Interpreter, InterpreterAction, InterpreterResult,
},
primitives::{
AccountInfo, BlockEnv, Bytecode, CreateScheme, EVMError, Env, EvmStorageSlot, ExecutionResult, HashMap as rHashMap, Output, TransactTo, KECCAK_EMPTY
AccountInfo, BlockEnv, Bytecode, CreateScheme, EVMError, Env, EvmStorageSlot,
ExecutionResult, HashMap as rHashMap, Output, TransactTo, KECCAK_EMPTY,
},
EvmContext, InnerEvmContext, Inspector,
};
use rustc_hash::FxHashMap;
use serde_json::Value;
use std::{
cell::RefCell, collections::{BTreeMap, HashMap, VecDeque}, fs::File, io::BufReader, ops::Range, path::PathBuf, rc::Rc, sync::Arc
collections::{BTreeMap, HashMap, VecDeque},
fs::File,
io::BufReader,
ops::Range,
path::PathBuf,
sync::Arc,
};
use zksync_types::{
block::{pack_block_info, unpack_block_info},
Expand Down Expand Up @@ -1123,7 +1131,6 @@ impl Cheatcodes {
};
}


if call.target_address == HARDHAT_CONSOLE_ADDRESS {
self.combined_logs.push(None);
}
Expand Down
41 changes: 40 additions & 1 deletion crates/evm/core/src/backend/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloy_primitives::{Address, B256, U256};
use alloy_rpc_types::BlockId;
pub use foundry_fork_db::{DatabaseError, DatabaseResult};
use futures::channel::mpsc::SendError;
use futures::channel::mpsc::{SendError, TrySendError};
use revm::primitives::EVMError;
use std::{
convert::Infallible,
Expand Down Expand Up @@ -65,6 +65,39 @@ impl BackendError {
pub fn display(msg: impl std::fmt::Display) -> Self {
Self::Message(msg.to_string())
}

fn get_rpc_error(&self) -> Option<&eyre::Error> {
match self {
Self::GetAccount(_, err) => Some(err),
Self::Database(_) => None, // TODO: Revisit this case
Self::GetStorage(_, _, err) => Some(err),
Self::GetBlockHash(_, err) => Some(err),
Self::GetFullBlock(_, err) => Some(err),
Self::GetTransaction(_, err) => Some(err),
// Enumerate explicitly to make sure errors are updated if a new one is added.
Self::NoCheats(_) |
Self::MissingAccount(_) |
Self::MissingCode(_) |
Self::Recv(_) |
Self::Send(_) |
Self::Message(_) |
Self::BlockNotFound(_) |
Self::TransactionNotFound(_) |
Self::MissingCreate2Deployer => None,
Self::GetBytecode(_, err) => Some(err),
Self::Other(_) => None,
}
}

/// Whether the error is potentially caused by the user forking from an older block in a
/// non-archive node.
pub fn is_possibly_non_archive_node_error(&self) -> bool {
static GETH_MESSAGE: &str = "missing trie node";

self.get_rpc_error()
.map(|err| err.to_string().to_lowercase().contains(GETH_MESSAGE))
.unwrap_or(false)
}
}

impl From<tokio::task::JoinError> for BackendError {
Expand All @@ -73,6 +106,12 @@ impl From<tokio::task::JoinError> for BackendError {
}
}

impl<T> From<TrySendError<T>> for BackendError {
fn from(value: TrySendError<T>) -> Self {
value.into_send_error().into()
}
}

impl From<Infallible> for BackendError {
fn from(value: Infallible) -> Self {
match value {}
Expand Down
47 changes: 23 additions & 24 deletions crates/evm/core/src/fork/backend.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Smart caching and deduplication of requests when using a forking provider
use crate::backend::{BackendError, DatabaseError, DatabaseResult};
use crate::backend::{BackendError, BackendResult};
use alloy_primitives::{keccak256, Address, Bytes, B256, U256};
use alloy_provider::{network::AnyNetwork, Provider};
use alloy_rpc_types::{Block, BlockId, Transaction};
Expand Down Expand Up @@ -47,12 +47,12 @@ type TransactionFuture<Err> = Pin<
type BytecodeHashFuture<Err> =
Pin<Box<dyn Future<Output = (ByteCodeHashSender, Result<Option<Bytecode>, Err>, B256)> + Send>>;

type AccountInfoSender = OneshotSender<DatabaseResult<AccountInfo>>;
type StorageSender = OneshotSender<DatabaseResult<U256>>;
type BlockHashSender = OneshotSender<DatabaseResult<B256>>;
type FullBlockSender = OneshotSender<DatabaseResult<Block>>;
type TransactionSender = OneshotSender<DatabaseResult<WithOtherFields<Transaction>>>;
type ByteCodeHashSender = OneshotSender<DatabaseResult<Bytecode>>;
type AccountInfoSender = OneshotSender<BackendResult<AccountInfo>>;
type StorageSender = OneshotSender<BackendResult<U256>>;
type BlockHashSender = OneshotSender<BackendResult<B256>>;
type FullBlockSender = OneshotSender<BackendResult<Block>>;
type TransactionSender = OneshotSender<BackendResult<WithOtherFields<Transaction>>>;
type ByteCodeHashSender = OneshotSender<BackendResult<Bytecode>>;

/// Request variants that are executed by the provider
enum ProviderRequest<Err> {
Expand Down Expand Up @@ -372,7 +372,7 @@ where
let err = Arc::new(err);
if let Some(listeners) = pin.account_requests.remove(&addr) {
listeners.into_iter().for_each(|l| {
let _ = l.send(Err(DatabaseError::GetAccount(
let _ = l.send(Err(BackendError::GetAccount(
addr,
Arc::clone(&err),
)));
Expand Down Expand Up @@ -418,7 +418,7 @@ where
pin.storage_requests.remove(&(addr, idx))
{
listeners.into_iter().for_each(|l| {
let _ = l.send(Err(DatabaseError::GetStorage(
let _ = l.send(Err(BackendError::GetStorage(
addr,
idx,
Arc::clone(&err),
Expand Down Expand Up @@ -450,7 +450,7 @@ where
// notify all listeners
if let Some(listeners) = pin.block_requests.remove(&number) {
listeners.into_iter().for_each(|l| {
let _ = l.send(Err(DatabaseError::GetBlockHash(
let _ = l.send(Err(BackendError::GetBlockHash(
number,
Arc::clone(&err),
)));
Expand All @@ -476,10 +476,10 @@ where
if let Poll::Ready((sender, resp, number)) = fut.poll_unpin(cx) {
let msg = match resp {
Ok(Some(block)) => Ok(block),
Ok(None) => Err(DatabaseError::BlockNotFound(number)),
Ok(None) => Err(BackendError::BlockNotFound(number)),
Err(err) => {
let err = Arc::new(err);
Err(DatabaseError::GetFullBlock(number, err))
Err(BackendError::GetFullBlock(number, err))
}
};
let _ = sender.send(msg);
Expand All @@ -492,7 +492,7 @@ where
Ok(tx) => Ok(tx),
Err(err) => {
let err = Arc::new(err);
Err(DatabaseError::GetTransaction(tx_hash, err))
Err(BackendError::GetTransaction(tx_hash, err))
}
};
let _ = sender.send(msg);
Expand All @@ -503,11 +503,10 @@ where
if let Poll::Ready((sender, bytecode, code_hash)) = fut.poll_unpin(cx) {
let msg = match bytecode {
Ok(Some(bytecode)) => Ok(bytecode),
Ok(None) => Err(DatabaseError::MissingCode(code_hash)),
Ok(None) => Err(BackendError::MissingCode(code_hash)),
Err(err) => {
let _err = Arc::new(err);
// TODO: fix this
Err(DatabaseError::MissingCode(code_hash))
let err = Arc::new(err);
Err(BackendError::GetBytecode(code_hash, err))
}
};
let _ = sender.send(msg);
Expand Down Expand Up @@ -645,7 +644,7 @@ impl SharedBackend {
}

/// Returns the full block for the given block identifier
pub fn get_full_block(&self, block: impl Into<BlockId>) -> DatabaseResult<Block> {
pub fn get_full_block(&self, block: impl Into<BlockId>) -> BackendResult<Block> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::FullBlock(block.into(), sender);
Expand All @@ -655,7 +654,7 @@ impl SharedBackend {
}

/// Returns the transaction for the hash
pub fn get_transaction(&self, tx: B256) -> DatabaseResult<WithOtherFields<Transaction>> {
pub fn get_transaction(&self, tx: B256) -> BackendResult<WithOtherFields<Transaction>> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::Transaction(tx, sender);
Expand All @@ -664,7 +663,7 @@ impl SharedBackend {
})
}

fn do_get_basic(&self, address: Address) -> DatabaseResult<Option<AccountInfo>> {
fn do_get_basic(&self, address: Address) -> BackendResult<Option<AccountInfo>> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::Basic(address, sender);
Expand All @@ -673,7 +672,7 @@ impl SharedBackend {
})
}

fn do_get_storage(&self, address: Address, index: U256) -> DatabaseResult<U256> {
fn do_get_storage(&self, address: Address, index: U256) -> BackendResult<U256> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::Storage(address, index, sender);
Expand All @@ -682,7 +681,7 @@ impl SharedBackend {
})
}

fn do_get_block_hash(&self, number: u64) -> DatabaseResult<B256> {
fn do_get_block_hash(&self, number: u64) -> BackendResult<B256> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::BlockHash(number, sender);
Expand All @@ -691,7 +690,7 @@ impl SharedBackend {
})
}

fn do_get_bytecode(&self, hash: B256) -> DatabaseResult<Bytecode> {
fn do_get_bytecode(&self, hash: B256) -> BackendResult<Bytecode> {
tokio::task::block_in_place(|| {
let (sender, rx) = oneshot_channel();
let req = BackendRequest::ByteCodeHash(hash, sender);
Expand All @@ -707,7 +706,7 @@ impl SharedBackend {
}

impl DatabaseRef for SharedBackend {
type Error = DatabaseError;
type Error = BackendError;

fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
trace!(target: "sharedbackend", %address, "request basic");
Expand Down

0 comments on commit abe0b00

Please sign in to comment.