Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
74fab99
feat(cast): added custom polling interval args
dipanshuhappy Oct 30, 2025
3b03b3d
feat(cast): added a custom alias for poll interval
dipanshuhappy Oct 30, 2025
6992ffb
feat(cast): updated with clippy suggestion
dipanshuhappy Oct 30, 2025
8f41f4c
feat(cast): added multi fields to cast block
dipanshuhappy Nov 2, 2025
f5863b9
Merge branch 'master' of https://github.com/foundry-rs/foundry
dipanshuhappy Nov 3, 2025
d00864c
feat(cast): num of args needed for fields in block set to 0
dipanshuhappy Nov 3, 2025
ccc98a9
chore: updated with formatting
dipanshuhappy Nov 3, 2025
b34c60f
feat(cast): added long field to cast block
dipanshuhappy Nov 3, 2025
de99dcd
doc(cast): updated docs to match change in fields
dipanshuhappy Nov 3, 2025
e41c2f2
test(cast): Remove trailing whitespace from block output
dipanshuhappy Nov 11, 2025
90dfd30
Merge branch 'master' into master
dipanshuhappy Nov 11, 2025
2d92457
Merge branch 'master' into master
dipanshuhappy Nov 13, 2025
e66d26d
Merge branch 'master' of https://github.com/foundry-rs/foundry
dipanshuhappy Nov 22, 2025
c541623
Merge branch 'master' of https://github.com/dipanshuhappy/foundry
dipanshuhappy Nov 28, 2025
c833407
Merge branch 'master' of https://github.com/foundry-rs/foundry
dipanshuhappy Dec 4, 2025
daaae73
feat(cast): optimistically fetch prestate from debug_transaction api if
dipanshuhappy Dec 5, 2025
98f194f
Enable trace feature for alloy-rpc-types
dipanshuhappy Dec 5, 2025
dd00918
chore(cast): updated test cases
dipanshuhappy Dec 5, 2025
6453e59
chore(cast): updated test cases
dipanshuhappy Dec 5, 2025
7ccf80a
chore(cast): updates testcases
dipanshuhappy Dec 5, 2025
5bb09d3
Merge branch 'master' into feat/prestate-mode
dipanshuhappy Dec 5, 2025
5112af3
feat(cast): add default value for disable_debug_trace_api flag
dipanshuhappy Dec 6, 2025
b528697
Merge branch 'feat/prestate-mode' of https://github.com/dipanshuhappy…
dipanshuhappy Dec 6, 2025
cfccf62
chore(test): updated snapshots in cast test
dipanshuhappy Dec 11, 2025
0921759
Merge branch 'master' into feat/prestate-mode
dipanshuhappy Dec 11, 2025
36b6d0f
chore(test): updated snapshots in cast test
dipanshuhappy Dec 11, 2025
c327562
Merge branch 'feat/prestate-mode' of https://github.com/dipanshuhappy…
dipanshuhappy Dec 11, 2025
4e4daa8
chore(test): reverted back snapshot update
dipanshuhappy Dec 11, 2025
0079bbe
Re-run GitHub Actions
dipanshuhappy Dec 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ alloy-network = { version = "1.1.2", default-features = false }
alloy-provider = { version = "1.1.2", default-features = false }
alloy-pubsub = { version = "1.1.2", default-features = false }
alloy-rpc-client = { version = "1.1.2", default-features = false }
alloy-rpc-types = { version = "1.1.2", default-features = true }
alloy-rpc-types = { version = "1.1.2", default-features = true, features = ["trace"] }
alloy-rpc-types-beacon = { version = "1.1.2", default-features = true }
alloy-rpc-types-eth = { version = "1.1.2", default-features = false }
alloy-serde = { version = "1.1.2", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions crates/cast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ alloy-provider = { workspace = true, features = [
"ipc",
"trace-api",
"txpool-api",
"debug-api"
] }
alloy-rlp.workspace = true
alloy-rpc-types = { workspace = true, features = ["eth", "trace"] }
Expand Down
40 changes: 36 additions & 4 deletions crates/cast/src/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ use alloy_primitives::{
Address, Bytes, U256,
map::{AddressSet, HashMap},
};
use alloy_provider::Provider;
use alloy_rpc_types::BlockTransactions;
use alloy_provider::{Provider, ext::DebugApi};
use alloy_rpc_types::{
BlockTransactions,
trace::geth::{GethDebugTracingOptions, PreStateConfig},
};
use clap::Parser;
use eyre::{Result, WrapErr};
use foundry_cli::{
Expand Down Expand Up @@ -65,6 +68,10 @@ pub struct RunArgs {
#[arg(long, default_value_t = false)]
disable_labels: bool,

/// Disable the debug trace API.
#[arg(long, default_value_t = false)]
disable_debug_trace_api: bool,

/// Label addresses in the trace.
///
/// Example: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045:vitalik.eth
Expand Down Expand Up @@ -224,9 +231,34 @@ impl RunArgs {
env.tx.clone(),
executor.spec_id(),
);

let mut debug_trace_api_succeeded = false;
if !self.disable_debug_trace_api {
trace!(?tx_hash, "attempting to fetch prestate trace");

match provider
.debug_trace_transaction(
tx_hash,
GethDebugTracingOptions::prestate_tracer(PreStateConfig::default()),
)
.await
{
Ok(trace_state) => match trace_state.try_into_pre_state_frame() {
Ok(pre_state_frame) => {
executor.apply_prestate_trace(pre_state_frame.into_pre_state())?;
debug_trace_api_succeeded = true;
trace!("optimistic prestate trace applied successfully");
}
Err(err) => {
trace!(%err, "failed to parse prestate trace response");
}
},
Err(err) => {
trace!(?err, "debug_traceTransaction failed, falling back to block replay");
}
}
}
// Set the state to the moment right before the transaction
if !self.quick {
if !self.quick && !debug_trace_api_succeeded {
if !shell::is_json() {
sh_println!("Executing previous transactions from the block.")?;
}
Expand Down
5 changes: 0 additions & 5 deletions crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2923,7 +2923,6 @@ contract LocalProjectScript is Script {
.args(["run", "--la", format!("{tx_hash}").as_str(), "--rpc-url", &handle.http_endpoint()])
.assert_success()
.stdout_eq(str![[r#"
Executing previous transactions from the block.
Compiling project to generate artifacts
Nothing to compile

Expand All @@ -2937,7 +2936,6 @@ Nothing to compile
.args(["run", format!("{tx_hash}").as_str(), "--rpc-url", &handle.http_endpoint()])
.assert_success()
.stdout_eq(str![[r#"
Executing previous transactions from the block.
Traces:
[..] → new <unknown>@0x5FbDB2315678afecb367f032d93F642f64180aa3
├─ emit topic 0: 0xa7263295d3a687d750d1fd377b5df47de69d7db8decc745aaa4bbee44dc1688d
Expand All @@ -2955,7 +2953,6 @@ Transaction successfully executed.
.args(["run", "--la", format!("{tx_hash}").as_str(), "--rpc-url", &handle.http_endpoint()])
.assert_success()
.stdout_eq(str![[r#"
Executing previous transactions from the block.
Compiling project to generate artifacts
No files changed, compilation skipped
Traces:
Expand Down Expand Up @@ -3020,7 +3017,6 @@ forgetest_async!(show_state_changes_in_traces, |prj, cmd| {
])
.assert_success()
.stdout_eq(str![[r#"
Executing previous transactions from the block.
Traces:
[..] 0x5FbDB2315678afecb367f032d93F642f64180aa3::setNumber(111)
├─ storage changes:
Expand Down Expand Up @@ -4482,7 +4478,6 @@ forgetest_async!(cast_send_with_data, |prj, cmd| {
])
.assert_success()
.stdout_eq(str![[r#"
Executing previous transactions from the block.
Traces:
[..] 0x5FbDB2315678afecb367f032d93F642f64180aa3::setNumber(111)
├─ storage changes:
Expand Down
25 changes: 25 additions & 0 deletions crates/evm/evm/src/executors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use alloy_primitives::{
Address, Bytes, Log, TxKind, U256, keccak256,
map::{AddressHashMap, HashMap},
};
use alloy_rpc_types::trace::geth::AccountState;
use alloy_sol_types::{SolCall, sol};
use foundry_evm_core::{
EvmEnv,
Expand All @@ -44,6 +45,7 @@ use revm::{
};
use std::{
borrow::Cow,
collections::BTreeMap,
sync::{
Arc,
atomic::{AtomicBool, Ordering},
Expand Down Expand Up @@ -530,6 +532,29 @@ impl Executor {
self.commit(&mut result);
Ok(result)
}
pub fn apply_prestate_trace(
&mut self,
trace: BTreeMap<Address, AccountState>,
) -> eyre::Result<()> {
let backend = self.backend_mut();
for (address, account_state) in trace {
let code = account_state.code.map(Bytecode::new_raw).unwrap_or_default();
let info = revm::state::AccountInfo {
nonce: account_state.nonce.unwrap_or_default(),
balance: account_state.balance.unwrap_or_default(),
..Default::default()
}
.with_code(code);
backend.insert_account_info(address, info);

for (key, value) in account_state.storage {
let slot = U256::from_be_bytes(key.0);
let val = U256::from_be_bytes(value.0);
backend.insert_account_storage(address, slot, val)?;
}
}
Ok(())
}

/// Commit the changeset to the database and adjust `self.inspector_config` values according to
/// the executed call result.
Expand Down
Loading