Background
The new `TestLegacyCancunState` (added in #20892) walks `execution/tests/legacy-tests/LegacyTests/Cancun/GeneralStateTests` to catch the d3 RIPEMD-160 touch path that the Hive `legacy-cancun` simulator surfaced. Most of those tests pass; six fixtures consistently fail on the Constantinople subtest only, with post-state-root mismatches.
Failures (all Constantinople fork, all post-state-root mismatches)
| File |
Failing subtest indexes |
| `stSStoreTest/sstoreGas.json` |
0 |
| `stCreateTest/CREATE_HighNonce.json` |
0 |
| `stCreate2/CREATE2_HighNonce.json` |
0 |
| `stCreate2/CREATE2_HighNonceDelegatecall.json` |
0–3, 5, 11–15, 17, 23 |
| `stPreCompiledContracts2/CallEcrecover_Overflow.json` |
0–4 |
| `stPreCompiledContracts2/ecrecoverShortBuff.json` |
0 |
All other forks (Byzantium, ConstantinopleFix, Berlin, Istanbul, London, Paris, Shanghai, Cancun, …) pass. The failures are pre-existing — verified by reverting #20892's STATICCALL change and re-running.
Why this wasn't caught locally before
`TestLegacyCancunState` is the first local runner to walk `LegacyTests/Cancun/GeneralStateTests`. Geth's `tests/state_test.go` walks `LegacyTests/Constantinople/GeneralStateTests` (an older snapshot — see `tests/init_test.go:40` in go-ethereum), which does not include these specific fixtures. The fixtures' `_info.filling-rpc-server` shows they were generated by `evm 1.13.11-unstable-…20240124` (geth itself), so geth passes them by definition — Erigon only notices by walking the Cancun snapshot or running Hive `legacy-cancun`.
Sample divergence
`CREATE_HighNonce/Constantinople/0`:
- pre-state `0xb94f5374…` has `nonce = 0xffffffffffffffff` (max uint64) and 102 bytes of code; the tx invokes it.
- expected post-state root: `0xf5ffa088bcc12fb74a9d1d1ff8dab72e02d0b26d2c834de1504fb48eaaf3ea66`
- Erigon computes: `0xc8e453a40ff2bf75e275958a382d54971d2f8b713ce2c59ca5e0d90b2f2cce03`
Three orthogonal clusters
Group by suspected root cause; each likely its own small consensus fix:
- EIP-1283 SSTORE gas metering (`sstoreGas`) — Constantinople-only; reverted by Petersburg.
- Max-uint64 nonce CREATE/CREATE2 behavior (`_HighNonce`) — pre-EIP-2681 (Berlin), behavior was specified differently across forks.
- ECRecover with malformed/overflow input (`CallEcrecover_Overflow`, `ecrecoverShortBuff`) — likely an input-validation/normalization difference.
Workaround
#20892 `st.SkipLoad`s the six files with a comment pointing at this issue, so the test catches future regressions on the d3 RIPEMD-160 path without gating PRs on this orthogonal cluster.
Notes for whoever picks this up
- Reproduction: `go test -timeout 5m -count=1 -run "TestLegacyCancunState/" ./execution/tests/ -short=false` (after temporarily removing the corresponding `SkipLoad` line in `execution/tests/state_test.go`).
- `-v` on the same command reports the "got vs want" post-state root for each failing index.
- All six are pure state tests (not blockchain tests), so reproducing under `evm statetest` should match the test runner output.
Background
The new `TestLegacyCancunState` (added in #20892) walks `execution/tests/legacy-tests/LegacyTests/Cancun/GeneralStateTests` to catch the d3 RIPEMD-160 touch path that the Hive `legacy-cancun` simulator surfaced. Most of those tests pass; six fixtures consistently fail on the Constantinople subtest only, with post-state-root mismatches.
Failures (all Constantinople fork, all post-state-root mismatches)
All other forks (Byzantium, ConstantinopleFix, Berlin, Istanbul, London, Paris, Shanghai, Cancun, …) pass. The failures are pre-existing — verified by reverting #20892's STATICCALL change and re-running.
Why this wasn't caught locally before
`TestLegacyCancunState` is the first local runner to walk `LegacyTests/Cancun/GeneralStateTests`. Geth's `tests/state_test.go` walks `LegacyTests/Constantinople/GeneralStateTests` (an older snapshot — see `tests/init_test.go:40` in go-ethereum), which does not include these specific fixtures. The fixtures' `_info.filling-rpc-server` shows they were generated by `evm 1.13.11-unstable-…20240124` (geth itself), so geth passes them by definition — Erigon only notices by walking the Cancun snapshot or running Hive `legacy-cancun`.
Sample divergence
`CREATE_HighNonce/Constantinople/0`:
Three orthogonal clusters
Group by suspected root cause; each likely its own small consensus fix:
Workaround
#20892 `st.SkipLoad`s the six files with a comment pointing at this issue, so the test catches future regressions on the d3 RIPEMD-160 path without gating PRs on this orthogonal cluster.
Notes for whoever picks this up