Repository navigation
core/vm,core/types,params: implement the Amsterdam EVM version #2730
Description
Summary
XDPoSChain implements Osaka but has no Amsterdam fork of its own, while upstream go-ethereum carries the whole Amsterdam (glamsterdam) set and activates it on mainnet at AmsterdamTime = 1791294816 (2026-10-06 13:53:36 UTC).
Solidity 0.8.36 started exposing Amsterdam and 0.8.37 added block.slotnum / slotnum() (EIP-7843), behind --evm-version amsterdam --experimental. Amsterdam is not the compiler's default target yet (osaka still is), so no artifact needs it by default today, but any user who opts in cannot run their contract here, and the chain falls behind the moment solc flips the default.
The port is small in principle because part of it already landed: EIP-8024 was implemented in #2268 and the instruction set is built, but nothing in the fork selection reached it.
Current state
The fork switch itself is in flight rather than missing:
- feat(core,params): add the amsterdam fork switch #2756 adds the switch:
AmsterdamBlock,IsAmsterdam,Rules.IsAmsterdam, the fork-order entry after Osaka, and the two table selection points incore/vm. No network schedules it. - fix(core,params): move the eip-7954 code size raise to amsterdam #33832 #35217 #2757 fixes the EIP-7954 size limits: the limit moves from
IsOsakatoIsAmsterdamand takes the current upstream values, 65536 of code and 131072 of initcode, which makes Osaka equivalent to upstream Osaka again. - docs(solidity,upgrade): document amsterdam, eip-2935 and block.basefee #2758 carries the documentation:
docs/solidity.md(Amsterdam support status, 0.8.36 / 0.8.37, the EIP-7954 limits) and the gas price notes folded into### block.basefee.
Everything else that Amsterdam carries is unimplemented, and is now tracked as one issue per EIP:
- EIP-2780, resource-based intrinsic transaction gas - core/state_transition,params: implement EIP-2780 resource-based intrinsic transaction gas (amsterdam) #2759
- EIP-7843, SLOTNUM and the slot number header field - core/types,core/vm,miner: implement EIP-7843 SLOTNUM and the slot number header field (amsterdam) #2760
- EIP-7928, block-level access lists - core/types,core,eth: implement EIP-7928 block-level access lists (amsterdam) #2761
- EIP-7976, calldata pricing - core/state_transition,params: implement EIP-7976 calldata pricing (amsterdam) #2762
- EIP-7981, access-list token charging - core/state_transition,params: implement EIP-7981 access-list token charging (amsterdam) #2763
- EIP-8037, multidimensional state-gas metering - core/vm,core,params: implement EIP-8037 multidimensional state-gas metering (amsterdam) #2764
- EIP-8038, state-access repricing - core/vm,params: implement EIP-8038 state-access repricing (amsterdam) #2765
- EIP-8246, SELFDESTRUCT burn removal - core/vm,core/state: implement EIP-8246 SELFDESTRUCT burn removal (amsterdam) #2766
- EIP-7708, transfer and burn system logs - core/types,core/vm: implement EIP-7708 transfer and burn system logs (amsterdam) #2767
- EIP-7997, deterministic deployment factory - core/genesis,params: deploy the EIP-7997 deterministic deployment factory (amsterdam) #2768
- EIP-8282, builder execution requests - core,beacon,params: implement EIP-8282 builder execution requests (amsterdam) #2769
Already implemented, and therefore not split out: EIP-8024 (the instruction table, wired by #2756) and EIP-7954 (the size limits, #2757).
Remaining work
- Upstream test vectors: opcode vectors for SLOTNUM, and gas-table and state-transition vectors from the upstream fixtures.
- The activation decision: every live network leaves
osakaBlockunset, and Amsterdam must not be scheduled before Osaka. Activation waits for the EIPs above and for the SLOTNUM value question below.
Impact
- A contract compiled with
--evm-version amsterdam(the only way to useblock.slotnum, which 0.8.37 introduced) cannot be deployed or executed here: the new target is neither activated nor implemented. - Low immediate severity, since Amsterdam is still an experimental, non-default target. It becomes a hard blocker on the release where solc switches its default target, exactly as Osaka did for 0.8.31.
- No network schedules Amsterdam: every live network still leaves
osakaBlockunset, and Amsterdam must not be scheduled before Osaka.
Upstream
go-ethereum master 466c37e33, checked 2026-10-09:
core/vm/jump_table.go:107-111:newAmsterdamInstructionSetis Osaka plusenable7843,enable8024andenable8037And8038.core/vm/eips.go:578(enable7843),:588(enable8037And8038).core/vm/evm.go:158-160(case evm.chainRules.IsAmsterdam),:520-552(account creation charged from the state-gas ledger).params/config.go:329(AmsterdamTime),:741-743(IsAmsterdam),:1092-1094(ActiveSystemContractsfor EIP-8282).core/types/block.go:103,106(BlockAccessListHashadded by EIP-7928,SlotNumberadded by EIP-7843, both ignored in legacy headers).core/state_transition.go:143-151(EIP-7981),:202-215(EIP-7976),:592-596(EIP-7825 / EIP-8037 caps),core/vm/gascosts.go(GasBudget).- Relevant geth PRs: core/vm: implement eip-7843: SLOTNUM ethereum/go-ethereum#33589 (EIP-7843 SLOTNUM), core/vm: add amsterdam instruction set etc. ethereum/go-ethereum#33643 (Amsterdam instruction set), core: genesis slot number parsing ethereum/go-ethereum#35464 (genesis slot number parsing), miner: supply a slot number when synthesising pending block post-Amsterdam ethereum/go-ethereum#34792 / eth/catalyst: use IsAmsterdam when sealing simulated beacon blocks ethereum/go-ethereum#35392 (miner and catalyst slot supply), core: implement EIP-8038 ethereum/go-ethereum#35216 (EIP-8038), core/vm: implements EIP-8037 spec change ethereum/go-ethereum#35173 / core: implement EIP-2780 and EIP-8037 changes ethereum/go-ethereum#35318 / core: remaining spec fixes for glamsterdam ethereum/go-ethereum#35279 (EIP-8037 and most of the 2D-gas spec changes, core: implement EIP-2780 and EIP-8037 changes ethereum/go-ethereum#35318 also carries EIP-2780), eth/downloader: implement BAL downloading ethereum/go-ethereum#35386 / eth/protocols/snap: verify raw BAL before single decode ethereum/go-ethereum#35890 (BAL).
Open questions
- What SLOTNUM returns. EIP-7843 returns the beacon chain slot and this chain has no beacon chain, so like
block.prevrandaothe value has to be defined deterministically and documented before activation. Tracked in core/types,core/vm,miner: implement EIP-7843 SLOTNUM and the slot number header field (amsterdam) #2760. - Which EIPs are adopted at all. EIP-7928 (core/types,core,eth: implement EIP-7928 block-level access lists (amsterdam) #2761), EIP-7708 (core/types,core/vm: implement EIP-7708 transfer and burn system logs (amsterdam) #2767), EIP-7997 (core/genesis,params: deploy the EIP-7997 deterministic deployment factory (amsterdam) #2768) and EIP-8282 (core,beacon,params: implement EIP-8282 builder execution requests (amsterdam) #2769) are consensus-visible or consensus-layer dependent, and their issues carry an applicability question, so the maintainer call is whether XDC follows upstream Amsterdam as it stands or deviates deliberately.
- Fork switch form. Resolved: XDC forks are block-number based, so Amsterdam is
AmsterdamBlock, added by feat(core,params): add the amsterdam fork switch #2756.
Out of scope
- The blob-side parts of Amsterdam (BPO schedules, cell sidecars,
BlobScheduleConfig): this chain has no blob transactions by design (see PR fix(core/vm,params): fail 0x0a calls instead of faking success #2666 anddocs/solidity.md). - Scheduling Amsterdam on any live network: Osaka is unset everywhere and must come first.
Activity
feat(core,params): add the amsterdam fork switch
feat(core,docs,params): add the amsterdam fork switch
feat(core,docs,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch
feat(core,params): add the amsterdam fork switch