Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: replace tracers with reth tracers #6428

Merged
merged 14 commits into from
Dec 11, 2023
921 changes: 730 additions & 191 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ foundry-evm-traces = { path = "crates/evm/traces" }
foundry-macros = { path = "crates/macros" }
foundry-test-utils = { path = "crates/test-utils" }

# block explorer & verification bindings
foundry-block-explorers = { version = "0.1.1", default-features = false }
# solc & compilation utilities
foundry-compilers = { version = "0.1.1", default-features = false }

## revm
Expand Down Expand Up @@ -216,6 +218,6 @@ alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy/", branch = "onbje
alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy/", branch = "onbjerg/alloy-temp-provider-trait" }

revm = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" }
revm-interpreter = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" }
revm-precompile = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" }
revm-primitives = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" }
revm-interpreter = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" }
revm-precompile = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" }
2 changes: 2 additions & 0 deletions crates/anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ alloy-primitives = { workspace = true, features = ["serde"] }
alloy-rpc-types.workspace = true
alloy-providers.workspace = true
alloy-transport.workspace = true
reth-rpc-types = { git = "https://github.com/paradigmxyz/reth/", branch = "main" }


# axum related
axum.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/anvil/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ serde = { workspace = true, optional = true }
serde_json.workspace = true
bytes = { version = "1.4" }
open-fastrlp = { version = "0.1.4", optional = true }
reth-rpc-types = { git = "https://github.com/paradigmxyz/reth/", branch = "main" }

# trie
hash-db = { version = "0.15", default-features = false }
Expand Down
7 changes: 4 additions & 3 deletions crates/anvil/core/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use alloy_rpc_types::{
state::StateOverride,
BlockId, BlockNumberOrTag as BlockNumber, CallRequest, Filter,
};
use ethers_core::types::{transaction::eip712::TypedData, GethDebugTracingOptions};
use ethers_core::types::transaction::eip712::TypedData;
use reth_rpc_types::trace::geth::GethDefaultTracingOptions;

pub mod block;
pub mod proof;
Expand Down Expand Up @@ -261,15 +262,15 @@ pub enum EthRequest {
#[cfg_attr(feature = "serde", serde(rename = "debug_traceTransaction"))]
DebugTraceTransaction(
B256,
#[cfg_attr(feature = "serde", serde(default))] GethDebugTracingOptions,
#[cfg_attr(feature = "serde", serde(default))] GethDefaultTracingOptions,
),

/// geth's `debug_traceCall` endpoint
#[cfg_attr(feature = "serde", serde(rename = "debug_traceCall"))]
DebugTraceCall(
CallRequest,
#[cfg_attr(feature = "serde", serde(default))] Option<BlockId>,
#[cfg_attr(feature = "serde", serde(default))] GethDebugTracingOptions,
#[cfg_attr(feature = "serde", serde(default))] GethDefaultTracingOptions,
),

/// Trace transaction endpoint for parity's `trace_transaction`
Expand Down
39 changes: 2 additions & 37 deletions crates/anvil/core/src/eth/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use ethers_core::{
},
};
use foundry_common::types::ToAlloy;
use foundry_evm::traces::CallTraceArena;
use foundry_evm::traces::CallTraceNode;
use revm::{
interpreter::InstructionResult,
primitives::{CreateScheme, OptimismFields, TransactTo, TxEnv},
Expand Down Expand Up @@ -1513,47 +1513,12 @@ pub struct TransactionInfo {
pub contract_address: Option<Address>,
pub logs: Vec<Log>,
pub logs_bloom: Bloom,
pub traces: CallTraceArena,
pub traces: Vec<CallTraceNode>,
pub exit: InstructionResult,
pub out: Option<Bytes>,
pub nonce: u64,
}

// === impl TransactionInfo ===

impl TransactionInfo {
/// Returns the `traceAddress` of the node in the arena
///
/// The `traceAddress` field of all returned traces, gives the exact location in the call trace
/// [index in root, index in first CALL, index in second CALL, …].
///
/// # Panics
///
/// if the `idx` does not belong to a node
pub fn trace_address(&self, idx: usize) -> Vec<usize> {
if idx == 0 {
// root call has empty traceAddress
return vec![]
}
let mut graph = vec![];
let mut node = &self.traces.arena[idx];
while let Some(parent) = node.parent {
// the index of the child call in the arena
let child_idx = node.idx;
node = &self.traces.arena[parent];
// find the index of the child call in the parent node
let call_idx = node
.children
.iter()
.position(|child| *child == child_idx)
.expect("child exists in parent");
graph.push(call_idx);
}
graph.reverse();
graph
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
27 changes: 10 additions & 17 deletions crates/anvil/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use alloy_rpc_types::{
TransactionReceipt,
TxpoolContent,
TxpoolInspect,
// trace::{geth::{DefaultFrame, GethDebugTracingOptions, GethTrace},
// trace::{geth::{DefaultFrame, GethDefaultTracingOptions, GethTrace},
// parity::LocalizedTransactionTrace},
TxpoolInspectSummary,
TxpoolStatus,
Expand All @@ -69,11 +69,7 @@ use anvil_core::{
},
};
use anvil_rpc::{error::RpcError, response::ResponseResult};
use ethers::{
prelude::DefaultFrame,
types::{transaction::eip712::TypedData, GethDebugTracingOptions, GethTrace, Trace},
utils::rlp,
};
use ethers::{types::transaction::eip712::TypedData, utils::rlp};
use foundry_common::{
provider::alloy::ProviderBuilder,
types::{ToAlloy, ToEthers},
Expand All @@ -88,6 +84,10 @@ use foundry_evm::{
};
use futures::channel::{mpsc::Receiver, oneshot};
use parking_lot::RwLock;
use reth_rpc_types::trace::{
geth::{DefaultFrame, GethDefaultTracingOptions, GethTrace},
parity::LocalizedTransactionTrace,
};
use std::{collections::HashSet, future::Future, sync::Arc, time::Duration};

/// The client version: `anvil/v{major}.{minor}.{patch}`
Expand Down Expand Up @@ -1456,13 +1456,9 @@ impl EthApi {
pub async fn debug_trace_transaction(
&self,
tx_hash: B256,
opts: GethDebugTracingOptions,
opts: GethDefaultTracingOptions,
) -> Result<GethTrace> {
node_info!("debug_traceTransaction");
if opts.tracer.is_some() {
return Err(RpcError::invalid_params("non-default tracer not supported yet").into());
}

self.backend.debug_trace_transaction(tx_hash, opts).await
}

Expand All @@ -1473,12 +1469,9 @@ impl EthApi {
&self,
request: CallRequest,
block_number: Option<BlockId>,
opts: GethDebugTracingOptions,
opts: GethDefaultTracingOptions,
) -> Result<DefaultFrame> {
node_info!("debug_traceCall");
if opts.tracer.is_some() {
return Err(RpcError::invalid_params("non-default tracer not supported yet").into());
}
let block_request = self.block_request(block_number).await?;
let fees = FeeDetails::new(
request.gas_price.map(|g| g.to_ethers()),
Expand All @@ -1495,15 +1488,15 @@ impl EthApi {
/// Returns traces for the transaction hash via parity's tracing endpoint
///
/// Handler for RPC call: `trace_transaction`
pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<Trace>> {
pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
node_info!("trace_transaction");
self.backend.trace_transaction(tx_hash).await
}

/// Returns traces for the transaction hash via parity's tracing endpoint
///
/// Handler for RPC call: `trace_block`
pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<Trace>> {
pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
node_info!("trace_block");
self.backend.trace_block(block).await
}
Expand Down
12 changes: 9 additions & 3 deletions crates/anvil/src/eth/backend/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ use ethers::{
use foundry_common::types::{ToAlloy, ToEthers};
use foundry_evm::{
backend::DatabaseError,
inspectors::{TracingInspector, TracingInspectorConfig},
revm,
revm::{
interpreter::InstructionResult,
primitives::{BlockEnv, CfgEnv, EVMError, Env, ExecutionResult, Output, SpecId},
},
traces::{CallTraceArena, CallTraceNode},
traces::CallTraceNode,
utils::{eval_to_instruction_result, halt_to_instruction_result},
};
use std::sync::Arc;
Expand Down Expand Up @@ -171,7 +172,7 @@ impl<'a, DB: Db + ?Sized, Validator: TransactionValidator> TransactionExecutor<'
contract_address: contract_address.map(|c| c.to_ethers()),
logs,
logs_bloom: *receipt.logs_bloom(),
traces: CallTraceArena { arena: traces },
traces,
exit,
out: match out {
Some(Output::Call(b)) => Some(ethers::types::Bytes(b.0)),
Expand Down Expand Up @@ -321,7 +322,12 @@ impl<'a, 'b, DB: Db + ?Sized, Validator: TransactionValidator> Iterator
out,
gas_used,
logs: logs.unwrap_or_default().into_iter().map(Into::into).collect(),
traces: inspector.tracer.unwrap_or_default().traces.arena,
traces: inspector
.tracer
.unwrap_or(TracingInspector::new(TracingInspectorConfig::all()))
.get_traces()
.clone()
.into_nodes(),
nonce,
};

Expand Down
14 changes: 7 additions & 7 deletions crates/anvil/src/eth/backend/mem/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ use ethers::types::Log;
use foundry_evm::{
call_inspectors,
decode::decode_console_logs,
inspectors::{LogCollector, Tracer},
inspectors::{LogCollector, TracingInspector},
revm,
revm::{
interpreter::{CallInputs, CreateInputs, Gas, InstructionResult, Interpreter},
primitives::{Address, Bytes, B256},
EVMData,
},
traces::TracingInspectorConfig,
};

/// The [`revm::Inspector`] used when transacting in the evm
#[derive(Debug, Clone, Default)]
pub struct Inspector {
pub tracer: Option<Tracer>,
pub tracer: Option<TracingInspector>,
/// collects all `console.sol` logs
pub log_collector: LogCollector,
}
Expand All @@ -34,15 +35,14 @@ impl Inspector {

/// Configures the `Tracer` [`revm::Inspector`]
pub fn with_tracing(mut self) -> Self {
self.tracer = Some(Default::default());
self.tracer = Some(TracingInspector::new(TracingInspectorConfig::all()));
self
}

/// Enables steps recording for `Tracer`.
pub fn with_steps_tracing(mut self) -> Self {
let tracer = self.tracer.get_or_insert_with(Default::default);
tracer.record_steps();
self
pub fn with_steps_tracing(self) -> Self {
// todo deprecate?
self.with_tracing()
}
}

Expand Down
Loading
Loading