Skip to content

fix(cast): replay HyperEVM read precompiles - #16525

Open
mattsse wants to merge 2 commits into
foundry-rs:masterfrom
mattsse:mattsse/hyperevm-precompiles
Open

mattsse wants to merge 2 commits into
foundry-rs:masterfrom
mattsse:mattsse/hyperevm-precompiles

Conversation

@mattsse

@mattsse mattsse commented Sep 1, 2026

Copy link
Copy Markdown
Member

HyperEVM read precompiles expose HyperCore state, so their results cannot be reconstructed from the EVM database alone. This adds a reusable block-scoped implementation that mirrors Nanoreth's exact (calldata, gas limit) lookup semantics, including the active-address warming range and out-of-gas behavior for missing or failed queries.

On HyperEVM mainnet and testnet, cast run now opportunistically requests eth_blockPrecompileData for the exact transaction block hash. The response remains local to that replay and is injected once into the replay EVM before any prefix or target transaction executes; it is not stored in the executor or backend, and no HyperEVM-specific transaction path is introduced. The RPC extension remains optional, so endpoints that do not expose it retain the existing replay behavior rather than becoming unusable.

This is stacked on #16531, which makes cast run reuse one EVM for block replay. A pinned end-to-end case covers a transaction that calls the BBO precompile at 0x080e four times and reproduces its receipt gas exactly. This advances the HyperEVM portion of #7262.

This contribution was implemented with AI assistance and reviewed and tested by the contributor.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

✅ Changelog found

The deterministic check will validate the changed entry.

figtracer
figtracer previously approved these changes Sep 1, 2026
@mattsse

mattsse commented Sep 1, 2026

Copy link
Copy Markdown
Member Author

this looks a bit sloppy still

@mattsse
mattsse marked this pull request as draft September 1, 2026 12:27
Comment thread crates/evm/core/src/evm/eth.rs Outdated
Comment on lines +65 to +72
fn inject_hyperevm_precompiles<'db, I: FoundryInspectorExt<Self::FoundryContext<'db>>>(
&self,
evm: &mut Self::FoundryEvm<'db, I>,
data: &foundry_evm_networks::hyperevm::HyperEvmBlockPrecompileData,
block_number: u64,
) {
data.inject(evm.precompiles_mut(), block_number);
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this approach, I'd prefer if we could always inject the precompiles by going through evm.precompiles_mut()

Comment thread crates/evm/core/src/backend/mod.rs Outdated
/// RPC block number exposed while executing a historical transaction in a temporary backend.
fork_block_number_override: Option<u64>,
/// Block-scoped HyperEVM read precompile data used for historical replay.
hyperevm_precompile_data: Option<HyperEvmBlockPrecompileData>,

@figtracer figtracer Sep 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep this shouldn't be here i belive

@mattsse
mattsse force-pushed the mattsse/hyperevm-precompiles branch from 0a7fd0e to 19c315a Compare September 1, 2026 13:05
@mattsse
mattsse marked this pull request as ready for review September 1, 2026 14:12
@mattsse
mattsse force-pushed the mattsse/hyperevm-precompiles branch 2 times, most recently from fdde2eb to 7091471 Compare September 1, 2026 15:52
Keep one EVM alive while cast run applies a block prefix and executes its target transaction. This preserves EVM-local configuration across replay while continuing to trace only the target and update network transaction context between transactions.
HyperEVM read calls depend on HyperCore state that is unavailable in the EVM database. Install exact block-scoped call results from archive nodes once before block replay when eth_blockPrecompileData is available, while keeping the RPC capability optional.
@mattsse
mattsse force-pushed the mattsse/hyperevm-precompiles branch from 7091471 to 8e1dde4 Compare September 1, 2026 16:07
Comment on lines +177 to +192
/// Tries to execute a canonical system transaction on a Foundry-wrapped EVM during replay.
///
/// Returning `Ok(None)` means the transaction was not recognized. Implementations must not
/// mutate the EVM, its database, or inspector before returning `Ok(None)`, because callers may
/// fall back to ordinary execution using the same EVM instance.
#[cfg(feature = "monad")]
fn try_transact_foundry_system_replay<'db, I: FoundryInspectorExt<Self::FoundryContext<'db>>>(
&self,
_evm: &mut Self::FoundryEvm<'db, I>,
_tx: &Self::Tx,
) -> eyre::Result<Option<ResultAndState<Self::HaltReason>>>
where
Self: 'db,
{
Ok(None)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not add this to FoundryEvmFactory imo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants