Skip to content

eth_simulateV1 and the debug/trace namespace #121

Description

@koko1123

Motivation

eth_call answers "what does this return"; it does not answer "what would actually happen". Every serious integrator -- a wallet showing a transaction preview, a searcher validating a bundle, an indexer reconstructing internal transfers -- needs simulation and tracing, and today eth.zig offers neither. This is the largest remaining gap in the RPC surface now that the read methods are complete.

eth_simulateV1 is the modern answer and it subsumes a lot: multiple calls across multiple simulated blocks, state and block overrides, per-call return data, logs, and gas used, all in one round trip. We already have the two hard prerequisites -- state_overrides.zig from #12 and the batching machinery in multicall.zig -- so this is mostly serialization and result parsing.

Scope

eth_simulateV1 on Provider:

  • A SimulatePayload mirroring the spec: blockStateCalls (an array of block objects, each with blockOverrides, stateOverrides, and calls), plus validation and traceTransfers flags
  • A SimulateResult per block with per-call status, returnData, gasUsed, logs, and the error object on failure
  • Reuse the existing state_overrides.StateOverride serialization rather than introducing a parallel type

Trace namespace (separate PR, same module):

  • debug_traceTransaction(hash, tracer) and debug_traceCall(call, block, tracer) with first-class support for callTracer and prestateTracer -- these two cover the overwhelming majority of real use, and returning a typed CallFrame tree for callTracer is worth far more than a generic JSON blob
  • trace_call / trace_transaction (the Erigon/Nethermind flavor) as a thin second surface, since a meaningful share of providers expose only one of the two families
  • A raw escape hatch that returns the tracer JSON unparsed, so a custom JS tracer is still usable

Capability handling: these methods are frequently unavailable on managed RPC plans. A method not found error must surface as a distinct, documented error rather than a generic error.RpcError, so callers can fall back cleanly. The FallbackProvider failover rule (#70) already draws the transport-vs-RPC-error line correctly -- keep it that way; an unsupported method is an answer, not a transport failure.

Testing

All parsing is offline-testable against captured responses, which is how provider.zig already tests its parsers. Add fixtures for a successful multi-call simulation, a reverting call inside an otherwise successful block, and a callTracer tree at least three frames deep. Live coverage goes in the Anvil integration suite -- Anvil supports both eth_simulateV1 and debug_traceTransaction.

Pointers

src/provider.zig (method surface and the existing response parsers), src/state_overrides.zig, src/json_rpc.zig (add the method-name constants), src/multicall.zig for the batching precedent. Spec: the eth_simulateV1 entry in https://github.com/ethereum/execution-apis and the go-ethereum tracer docs for the callTracer / prestateTracer result shapes.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions