1- use crate :: debug:: handle_traces;
1+ use crate :: { debug:: handle_traces, utils :: apply_chain_and_block_specific_env_changes } ;
22use alloy_consensus:: Transaction ;
33use alloy_network:: { AnyNetwork , TransactionResponse } ;
44use alloy_primitives:: {
55 Address , Bytes , U256 ,
6- map:: { HashMap , HashSet } ,
6+ map:: { AddressSet , HashMap } ,
77} ;
8- use alloy_provider:: { Provider , RootProvider } ;
8+ use alloy_provider:: Provider ;
99use alloy_rpc_types:: BlockTransactions ;
1010use clap:: Parser ;
1111use eyre:: { Result , WrapErr } ;
@@ -25,13 +25,13 @@ use foundry_config::{
2525use foundry_evm:: {
2626 Env ,
2727 core:: env:: AsEnvMut ,
28- executors:: { EvmError , TracingExecutor } ,
28+ executors:: { EvmError , Executor , TracingExecutor } ,
2929 opts:: EvmOpts ,
3030 traces:: { InternalTraceMode , TraceMode , Traces } ,
3131 utils:: configure_tx_env,
3232} ;
33-
34- use crate :: utils :: apply_chain_and_block_specific_env_changes ;
33+ use futures :: TryFutureExt ;
34+ use revm :: DatabaseRef ;
3535
3636/// CLI arguments for `cast run`.
3737#[ derive( Clone , Debug , Parser ) ]
@@ -151,15 +151,16 @@ impl RunArgs {
151151 let tx_block_number =
152152 tx. block_number . ok_or_else ( || eyre:: eyre!( "tx may still be pending: {:?}" , tx_hash) ) ?;
153153
154- // fetch the block the transaction was mined in
155- let block = provider. get_block ( tx_block_number. into ( ) ) . full ( ) . await ?;
156-
157154 // we need to fork off the parent block
158155 config. fork_block_number = Some ( tx_block_number - 1 ) ;
159156
160157 let create2_deployer = evm_opts. create2_deployer ;
161- let ( mut env, fork, chain, networks) =
162- TracingExecutor :: get_fork_material ( & mut config, evm_opts) . await ?;
158+ let ( block, ( mut env, fork, chain, networks) ) = tokio:: try_join!(
159+ // fetch the block the transaction was mined in
160+ provider. get_block( tx_block_number. into( ) ) . full( ) . into_future( ) . map_err( Into :: into) ,
161+ TracingExecutor :: get_fork_material( & mut config, evm_opts)
162+ ) ?;
163+
163164 let mut evm_version = self . evm_version ;
164165
165166 env. evm_env . cfg_env . disable_block_gas_limit = self . disable_block_gas_limit ;
@@ -303,7 +304,7 @@ impl RunArgs {
303304 }
304305 } ;
305306
306- let contracts_bytecode = fetch_contracts_bytecode_from_trace ( & provider , & result) . await ?;
307+ let contracts_bytecode = fetch_contracts_bytecode_from_trace ( & executor , & result) ?;
307308 handle_traces (
308309 result,
309310 & config,
@@ -321,34 +322,32 @@ impl RunArgs {
321322 }
322323}
323324
324- pub async fn fetch_contracts_bytecode_from_trace (
325- provider : & RootProvider < AnyNetwork > ,
325+ pub fn fetch_contracts_bytecode_from_trace (
326+ executor : & Executor ,
326327 result : & TraceResult ,
327328) -> Result < HashMap < Address , Bytes > > {
328329 let mut contracts_bytecode = HashMap :: default ( ) ;
329330 if let Some ( ref traces) = result. traces {
330- let addresses = gather_trace_addresses ( traces) ;
331- let results = futures:: future:: join_all ( addresses. into_iter ( ) . map ( async |a| {
332- (
333- a,
334- provider. get_code_at ( a) . await . unwrap_or_else ( |e| {
335- sh_warn ! ( "Failed to fetch code for {a:?}: {e:?}" ) . ok ( ) ;
336- Bytes :: new ( )
337- } ) ,
338- )
339- } ) )
340- . await ;
341- for ( address, code) in results {
342- if !code. is_empty ( ) {
343- contracts_bytecode. insert ( address, code) ;
331+ contracts_bytecode. extend ( gather_trace_addresses ( traces) . filter_map ( |addr| {
332+ // All relevant bytecodes should already be cached in the executor.
333+ let code = executor
334+ . backend ( )
335+ . basic_ref ( addr)
336+ . inspect_err ( |e| _ = sh_warn ! ( "Failed to fetch code for {addr}: {e}" ) )
337+ . ok ( ) ??
338+ . code ?
339+ . bytes ( ) ;
340+ if code. is_empty ( ) {
341+ return None ;
344342 }
345- }
343+ Some ( ( addr, code) )
344+ } ) ) ;
346345 }
347346 Ok ( contracts_bytecode)
348347}
349348
350- fn gather_trace_addresses ( traces : & Traces ) -> HashSet < Address > {
351- let mut addresses = HashSet :: default ( ) ;
349+ fn gather_trace_addresses ( traces : & Traces ) -> impl Iterator < Item = Address > {
350+ let mut addresses = AddressSet :: default ( ) ;
352351 for ( _, trace) in traces {
353352 for node in trace. arena . nodes ( ) {
354353 if !node. trace . address . is_zero ( ) {
@@ -359,7 +358,7 @@ fn gather_trace_addresses(traces: &Traces) -> HashSet<Address> {
359358 }
360359 }
361360 }
362- addresses
361+ addresses. into_iter ( )
363362}
364363
365364impl figment:: Provider for RunArgs {
0 commit comments