erigontech / erigontech/erigon
rpc: validate eth_callMany and debug_traceCallMany state contexts
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 455
Description
## Problem
`eth_callMany` and `debug_traceCallMany` share `StateContext`, whose `BlockNumber` field is a non-pointer `rpc.BlockNumberOrHash`. If JSON omits `blockNumber`, the field keeps its zero value with neither a number nor a hash. The block resolvers assume one is present and dereference the nil number, so the RPC handler crashes instead of returning a normal parameter error.
`eth_callMany` also accepts `pending`. During a background-commit window, overlay execution progress can pass the execution gate while the pending block hash is absent from the database and block overlay. The block lookup then returns nil and the handler dereferences it while reading transactions.
At genesis, `eth_callMany` computes the parent state block as `blockNum - 1`. The unsigned subtraction wraps to `math.MaxUint64`, which becomes the `latest` tag when converted to `rpc.BlockNumber`. The method then executes with the genesis block environment over latest state.
## Proposed direction
- Validate the shared state context once at each endpoint boundary, before block resolution.
- Treat an omitted `blockNumber` as a deterministic invalid-parameters error unless compatibility research establishes a documented default.
- Define the `pending` policy explicitly. Reject it when no matching block and state view can be provided.
- Resolve the genesis state boundary without unsigned underflow; reject genesis if the method cannot represent the required state.
- Check missing blocks and bodies before transaction access.
- Reuse one validator for both methods while preserving their endpoint-specific error contracts.
- Keep transaction-index range validation in #23431.
## Acceptance criteria
- [ ] Omitting `stateContext.blockNumber` cannot panic either method.
- [ ] `eth_callMany` cannot dereference a missing pending block.
- [ ] A genesis selector cannot read state through the `latest` tag.
- [ ] Invalid selectors return stable JSON-RPC errors.
- [ ] Tests reproduce all three failures before the fix and pass afterward.
- [ ] Valid number and hash selectors retain their current behavior.
## Related
- #22533
- #23416
- #23428
- #23431
Contributor guide
Assessment
This issue has not been assessed yet.