Skip to content

rpc: return error for eth_call on unexecuted blocks instead of stale data#18929

Open
madumas wants to merge 1 commit intoerigontech:mainfrom
ellipfra:fix/eth-call-unexecuted-block-error-clean
Open

rpc: return error for eth_call on unexecuted blocks instead of stale data#18929
madumas wants to merge 1 commit intoerigontech:mainfrom
ellipfra:fix/eth-call-unexecuted-block-error-clean

Conversation

@madumas
Copy link
Contributor

@madumas madumas commented Feb 2, 2026

Summary

Fixes #18912

When a node is syncing, eth_call and related RPC methods were returning stale/incorrect data from the Execution stage for blocks that have headers but haven't been executed yet. This fix adds validation to return a clear error message instead.

Key Changes

  • Added ShouldValidateExecutionProgress() helper in rpc/rpchelper/helper.go to determine if a block reference requires validation (explicit block number/hash vs semantic tags)
  • Modified CreateStateReader() to validate execution progress for explicit block requests
  • Added validation in methods that bypass CreateStateReader (EstimateGas, GetBalance, GetTransactionCount, GetCode, GetStorageAt)

Behavior

Request Type During Sync (forkchoiceHead > Execution) Behavior
latest tag Yes ✅ Success - uses forkchoiceHead state
pending tag Yes ✅ Success - uses pending/latest state
safe/finalized tag N/A ✅ Success - always executed
Explicit block # > exec Yes ❌ Error - state not available
Block hash > exec Yes ❌ Error - state not available

Methods Fixed

  • eth_call
  • eth_getBalance
  • eth_getTransactionCount
  • eth_getCode
  • eth_getStorageAt
  • eth_estimateGas

Error Response

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "state for block 24356887 not available (execution at block 24356849)"
  }
}

This is consistent with other clients (Geth, Reth) which return -32000 for similar scenarios.

Test Plan

  • Added 7 new unit tests for unexecuted block scenarios
  • All existing tests pass without modification
  • Build succeeds

…data

When a node is syncing, eth_call and related RPC methods were returning
stale/incorrect data from the Execution stage for blocks that have headers
but haven't been executed yet. This fix adds validation to return a clear
error message instead.

The fix validates execution progress only for explicit block numbers or
hashes, while semantic tags (latest, pending, safe, finalized, earliest)
continue to work normally during sync.

Methods fixed:
- eth_call
- eth_getBalance
- eth_getTransactionCount
- eth_getCode
- eth_getStorageAt
- eth_estimateGas

Fixes erigontech#18912
@madumas madumas marked this pull request as ready for review February 2, 2026 15:17
@yperbasis yperbasis added the RPC label Feb 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

eth_call returns stale/incorrect data instead of error for blocks beyond Execution stage

2 participants