Skip to content

Commit d7af499

Browse files
refactor(cast): generic cast run (#14121)
generic cast run Co-authored-by: figtracer <1gusredo@gmail.com> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
1 parent f4acd5d commit d7af499

2 files changed

Lines changed: 48 additions & 35 deletions

File tree

crates/cast/src/cmd/run.rs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use crate::{
22
debug::handle_traces,
33
utils::{apply_chain_and_block_specific_env_changes, block_env_from_header},
44
};
5-
use alloy_consensus::{BlockHeader, Transaction};
5+
use alloy_consensus::{BlockHeader, Transaction, transaction::SignerRecoverable};
66

77
use alloy_evm::FromRecoveredTx;
8-
use alloy_network::{AnyNetwork, TransactionResponse};
8+
use alloy_network::{BlockResponse, TransactionResponse};
99
use alloy_primitives::{
1010
Address, Bytes, U256,
1111
map::{AddressSet, HashMap},
@@ -18,7 +18,9 @@ use foundry_cli::{
1818
opts::{EtherscanOpts, RpcOpts},
1919
utils::{TraceResult, init_progress},
2020
};
21-
use foundry_common::{SYSTEM_TRANSACTION_TYPE, is_impersonated_tx, is_known_system_sender, shell};
21+
use foundry_common::{
22+
SYSTEM_TRANSACTION_TYPE, is_known_system_sender, provider::ProviderBuilder, shell,
23+
};
2224
use foundry_compilers::artifacts::EvmVersion;
2325
use foundry_config::{
2426
Config,
@@ -28,16 +30,16 @@ use foundry_config::{
2830
},
2931
};
3032
use foundry_evm::{
31-
core::{FoundryBlock, evm::EthEvmNetwork},
33+
core::{
34+
FoundryBlock as _,
35+
evm::{EthEvmNetwork, FoundryEvmNetwork, TempoEvmNetwork, TxEnvFor},
36+
},
3237
executors::{EvmError, Executor, TracingExecutor},
3338
opts::EvmOpts,
3439
traces::{InternalTraceMode, TraceMode, Traces},
3540
};
3641
use futures::TryFutureExt;
37-
use revm::{
38-
DatabaseRef,
39-
context::{Block, TxEnv},
40-
};
42+
use revm::{DatabaseRef, context::Block};
4143

4244
/// CLI arguments for `cast run`.
4345
#[derive(Clone, Debug, Parser)]
@@ -129,6 +131,16 @@ impl RunArgs {
129131
///
130132
/// Note: This executes the transaction(s) as is: Cheatcodes are disabled
131133
pub async fn run(self) -> Result<()> {
134+
let figment = self.rpc.clone().into_figment(self.with_local_artifacts).merge(&self);
135+
let evm_opts = figment.extract::<EvmOpts>()?;
136+
if evm_opts.networks.is_tempo() {
137+
self.run_with_evm::<TempoEvmNetwork>().await
138+
} else {
139+
self.run_with_evm::<EthEvmNetwork>().await
140+
}
141+
}
142+
143+
async fn run_with_evm<FEN: FoundryEvmNetwork>(self) -> Result<()> {
132144
let figment = self.rpc.clone().into_figment(self.with_local_artifacts).merge(&self);
133145
let evm_opts = figment.extract::<EvmOpts>()?;
134146
let mut config = Config::from_provider(figment)?.sanitized();
@@ -141,7 +153,7 @@ impl RunArgs {
141153
let compute_units_per_second =
142154
if self.no_rate_limit { Some(u64::MAX) } else { self.compute_units_per_second };
143155

144-
let provider = foundry_cli::utils::get_provider_builder(&config)?
156+
let provider = ProviderBuilder::<FEN::Network>::from_config(&config)?
145157
.compute_units_per_second_opt(compute_units_per_second)
146158
.build()?;
147159

@@ -163,8 +175,9 @@ impl RunArgs {
163175
));
164176
}
165177

166-
let tx_block_number =
167-
tx.block_number.ok_or_else(|| eyre::eyre!("tx may still be pending: {:?}", tx_hash))?;
178+
let tx_block_number = tx
179+
.block_number()
180+
.ok_or_else(|| eyre::eyre!("tx may still be pending: {:?}", tx_hash))?;
168181

169182
// we need to fork off the parent block
170183
config.fork_block_number = Some(tx_block_number - 1);
@@ -173,7 +186,7 @@ impl RunArgs {
173186
let (block, (mut evm_env, tx_env, fork, chain, networks)) = tokio::try_join!(
174187
// fetch the block the transaction was mined in
175188
provider.get_block(tx_block_number.into()).full().into_future().map_err(Into::into),
176-
TracingExecutor::<EthEvmNetwork>::get_fork_material(&mut config, evm_opts)
189+
TracingExecutor::<FEN>::get_fork_material(&mut config, evm_opts)
177190
)?;
178191

179192
let mut evm_version = self.evm_version;
@@ -190,17 +203,17 @@ impl RunArgs {
190203
evm_env.block_env.set_number(U256::from(tx_block_number));
191204

192205
if let Some(block) = &block {
193-
evm_env.block_env = block_env_from_header(&block.header);
206+
evm_env.block_env = block_env_from_header(block.header());
194207

195208
// TODO: we need a smarter way to map the block to the corresponding evm_version for
196209
// commonly used chains
197210
if evm_version.is_none() {
198211
// if the block has the excess_blob_gas field, we assume it's a Cancun block
199-
if block.header.excess_blob_gas().is_some() {
212+
if block.header().excess_blob_gas().is_some() {
200213
evm_version = Some(EvmVersion::Prague);
201214
}
202215
}
203-
apply_chain_and_block_specific_env_changes::<AnyNetwork, _, _>(
216+
apply_chain_and_block_specific_env_changes::<FEN::Network, _, _>(
204217
&mut evm_env,
205218
block,
206219
config.networks,
@@ -215,7 +228,7 @@ impl RunArgs {
215228
InternalTraceMode::None
216229
})
217230
.with_state_changes(shell::verbosity() > 4);
218-
let mut executor = TracingExecutor::<EthEvmNetwork>::new(
231+
let mut executor = TracingExecutor::<FEN>::new(
219232
(evm_env.clone(), tx_env),
220233
fork,
221234
evm_version,
@@ -234,10 +247,10 @@ impl RunArgs {
234247
}
235248

236249
if let Some(block) = block {
237-
let pb = init_progress(block.transactions.len() as u64, "tx");
250+
let pb = init_progress(block.transactions().len() as u64, "tx");
238251
pb.set_position(0);
239252

240-
let BlockTransactions::Full(ref txs) = block.transactions else {
253+
let BlockTransactions::Full(ref txs) = *block.transactions() else {
241254
return Err(eyre::eyre!("Could not get block txs"));
242255
};
243256

@@ -256,9 +269,7 @@ impl RunArgs {
256269
break;
257270
}
258271

259-
let tx_env = tx.as_envelope().map_or(Default::default(), |tx_envelope| {
260-
TxEnv::from_recovered_tx(tx_envelope, tx.from())
261-
});
272+
let tx_env = TxEnvFor::<FEN>::from_recovered_tx(tx.as_ref(), tx.from());
262273

263274
evm_env.cfg_env.disable_balance_check = true;
264275

@@ -303,11 +314,9 @@ impl RunArgs {
303314
let result = {
304315
executor.set_trace_printer(self.trace_printer);
305316

306-
let tx_env = tx.as_envelope().map_or(Default::default(), |tx_envelope| {
307-
TxEnv::from_recovered_tx(tx_envelope, tx.from())
308-
});
317+
let tx_env = TxEnvFor::<FEN>::from_recovered_tx(tx.as_ref(), tx.from());
309318

310-
if is_impersonated_tx(tx.as_ref()) {
319+
if tx.as_ref().recover_signer().is_ok_and(|signer| signer != tx.from()) {
311320
evm_env.cfg_env.disable_balance_check = true;
312321
}
313322

@@ -339,8 +348,8 @@ impl RunArgs {
339348
}
340349
}
341350

342-
pub fn fetch_contracts_bytecode_from_trace(
343-
executor: &Executor<EthEvmNetwork>,
351+
pub fn fetch_contracts_bytecode_from_trace<FEN: FoundryEvmNetwork>(
352+
executor: &Executor<FEN>,
344353
result: &TraceResult,
345354
) -> Result<HashMap<Address, Bytes>> {
346355
let mut contracts_bytecode = HashMap::default();

crates/cli/src/utils/cmd.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use foundry_compilers::{
66
};
77
use foundry_config::{Chain, Config, NamedChain, error::ExtractConfigError, figment::Figment};
88
use foundry_evm::{
9+
core::evm::FoundryEvmNetwork,
910
executors::{DeployResult, EvmError, RawCallResult},
1011
opts::EvmOpts,
1112
traces::{
@@ -244,22 +245,25 @@ pub struct TraceResult {
244245

245246
impl TraceResult {
246247
/// Create a new [`TraceResult`] from a [`RawCallResult`].
247-
pub fn from_raw(raw: RawCallResult, trace_kind: TraceKind) -> Self {
248+
pub fn from_raw<FEN: FoundryEvmNetwork>(
249+
raw: RawCallResult<FEN>,
250+
trace_kind: TraceKind,
251+
) -> Self {
248252
let RawCallResult { gas_used, traces, reverted, .. } = raw;
249253
Self { success: !reverted, traces: traces.map(|arena| vec![(trace_kind, arena)]), gas_used }
250254
}
251255
}
252256

253-
impl From<DeployResult> for TraceResult {
254-
fn from(result: DeployResult) -> Self {
257+
impl<FEN: FoundryEvmNetwork> From<DeployResult<FEN>> for TraceResult {
258+
fn from(result: DeployResult<FEN>) -> Self {
255259
Self::from_raw(result.raw, TraceKind::Deployment)
256260
}
257261
}
258262

259-
impl TryFrom<Result<DeployResult, EvmError>> for TraceResult {
260-
type Error = EvmError;
263+
impl<FEN: FoundryEvmNetwork> TryFrom<Result<DeployResult<FEN>, EvmError<FEN>>> for TraceResult {
264+
type Error = EvmError<FEN>;
261265

262-
fn try_from(value: Result<DeployResult, EvmError>) -> Result<Self, Self::Error> {
266+
fn try_from(value: Result<DeployResult<FEN>, EvmError<FEN>>) -> Result<Self, Self::Error> {
263267
match value {
264268
Ok(result) => Ok(Self::from(result)),
265269
Err(EvmError::Execution(err)) => Ok(Self::from_raw(err.raw, TraceKind::Deployment)),
@@ -268,8 +272,8 @@ impl TryFrom<Result<DeployResult, EvmError>> for TraceResult {
268272
}
269273
}
270274

271-
impl From<RawCallResult> for TraceResult {
272-
fn from(result: RawCallResult) -> Self {
275+
impl<FEN: FoundryEvmNetwork> From<RawCallResult<FEN>> for TraceResult {
276+
fn from(result: RawCallResult<FEN>) -> Self {
273277
Self::from_raw(result, TraceKind::Execution)
274278
}
275279
}

0 commit comments

Comments
 (0)