Skip to content

docs: Heima EVM level is Cancun, not London (correct the rationale; keep the foundry pin)#168

Open
Kailai-Wang wants to merge 1 commit into
mainfrom
fix/heima-evm-level-is-cancun-not-london
Open

docs: Heima EVM level is Cancun, not London (correct the rationale; keep the foundry pin)#168
Kailai-Wang wants to merge 1 commit into
mainfrom
fix/heima-evm-level-is-cancun-not-london

Conversation

@Kailai-Wang
Copy link
Copy Markdown

What & why

Our docs assert "Heima is London EVM level" and pin evm_version = \"london\" in crates/agentkeys-chain/foundry.toml on that basis. The EVM-level claim is wrong, and the reason for the pin is mis-stated. This PR corrects the rationale across the canonical CLAUDE.md section + foundry.toml comment + 5 docs that repeated it. The london pin itself is unchanged — it's still needed, just for a different reason.

Root cause of the error

The "London" conclusion came from block-header introspection (baseFeePerGas present; mixHash/withdrawalsRoot/blobGasUsed absent → inferred < Shanghai). But Heima is a Substrate/Aura parachain via Frontier — those missing fields are Ethereum PoS-consensus header fields, not opcode-capability signals. The EVM's opcode level is set independently by Frontier's pallet_evm::config().

Verified on-chain (local heima-node --dev, 2026-06-01)

Probe Opcode Introduced Result on Heima
set(42) (Shanghai-compiled) PUSH0 (0x5f) Shanghai ✅ deployed + executed; x() == 42
rt(99) TSTORE/TLOAD (EIP-1153) Cancun ✅ returned 99

Source confirms it: Frontier stable2412 frame/evm/src/lib.rs config() returns &CANCUN_CONFIG (the // London doc-comment one line up is stale upstream).

➡️ Heima's EVM execution level is Cancun. It does not reject PUSH0 or other ≤Cancun opcodes — the old foundry.toml note ("london avoids PUSH0 which Heima would reject") was false.

Why the london pin still stays (the real reason)

forge script ... --broadcast runs a local simulation that validates the fetched block header against the target EVM revision before broadcasting. Heima's header has no prevrandao, so a paris+ target errors:

EVM error; header validation error: `prevrandao` not set

Verified: running the real DeployAgentKeysV1.s.sol against the dev chain with FOUNDRY_EVM_VERSION=cancun reproduces this; with london it deploys. (Note: forge create --broadcast with cancun does not hit this — it's specific to forge script's simulator, which is our deploy path. So the pin stays.)

So: opcode level = Cancun; the london pin = a forge script header-validation workaround, not an EVM-capability ceiling. These are two independent facts the docs had conflated.

Files changed (docs/config only — no code, no pin value change)

  • CLAUDE.md — rewrote "Heima EVM compatibility level" to separate the two facts + note that header-introspection is the wrong way to read opcode level.
  • crates/agentkeys-chain/foundry.toml — corrected the comment above evm_version = \"london\" (value unchanged).
  • docs/chain-setup.md, docs/v2-stage2-heima-deploy-and-test.md, docs/wiki/heima-setup-faq.md, docs/spec/deployed-contracts.md, docs/research/ai-hardware-companion-office-hours.md — corrected the repeated "Heima is London" framing.

Note

The P-256 precompile absence mentioned in stage-2 docs is true and unaffected — Heima has no RIP-7212 0x100 precompile regardless of EVM version; that's why we ship the pure-Solidity P256Verifier. This PR just stops tying that fact to a wrong "London" claim. (Broader P-256/4337 feasibility findings are in the comment on #163.)

How to re-verify

heima-node --dev --rpc-port 9944 --rpc-methods=unsafe -- --dev-block-time 1000
# fund an EVM acct (transfer //Alice -> blake2_256("evm:"++H160)), then:
# deploy a TSTORE/TLOAD (Cancun-only) contract, call it -> returns its input  => EVM >= Cancun
# run DeployAgentKeysV1.s.sol with FOUNDRY_EVM_VERSION=cancun -> 'prevrandao not set' (forge script only)

…don foundry pin, fix the rationale)

The "Heima is London EVM level" claim was derived from block-header
introspection (baseFeePerGas present; mixHash/withdrawalsRoot/blobGasUsed
absent). That reflects the Substrate/Aura consensus header FORMAT, not the
EVM opcode-execution level — which Frontier sets independently via
pallet_evm::config().

Verified on a local heima-node --dev chain (2026-06-01):
- Frontier stable2412 config() returns &CANCUN_CONFIG.
- PUSH0 (Shanghai): a Shanghai-compiled set(42) executed; x() == 42.
- TSTORE/TLOAD (EIP-1153, Cancun-only): rt(99) == 99.
So Heima does NOT reject PUSH0 / post-London opcodes (the old note was wrong).

The evm_version = "london" pin in foundry.toml is RETAINED, but its reason is
corrected: it is a 'forge script' simulator header-validation workaround
(forge script validates the prevrandao-less Heima header against the target
revision and rejects paris+), NOT an EVM-capability ceiling. Verified:
DeployAgentKeysV1.s.sol with FOUNDRY_EVM_VERSION=cancun reproduces
"header validation error: prevrandao not set"; london deploys. (forge create
--broadcast with cancun does NOT hit this.)

Updates the canonical CLAUDE.md section + foundry.toml comment + 5 docs that
repeated the "Heima is London" framing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant