6.5 KiB
AIP-18: EIP-2935 on Chain 2800: Deviation from the Written Activation Schedule
Preamble
| Field | Value |
|---|---|
| AIP | 18 |
| Title | EIP-2935 on Chain 2800: Deviation from the Written Activation Schedule |
| Author | Aere Network Foundation |
| Type | Standards Track |
| Category | Core |
| Status | Final |
| Created | 2026-07-20 |
| Requires | 7 |
| Supersedes | None |
| Superseded-By | None |
| Ratification | Foundation-ratified (pre-decentralization) |
Abstract
Chain 2800 lists EIP-2935 under its Pectra ruleset, but the history-storage system contract was not populated and the write path did not run until the AerePQC fork at block 9,189,161. Any client or integrator that assumed "Pectra is active, therefore EIP-2935 serves history" was wrong for every block between the Pectra ruleset taking effect and block 9,189,161. This AIP records that deviation explicitly so it is discoverable, and states exactly what is true before and after that block. It is a retro-filed record and backfills history.
Motivation
A deviation from a written standard that is not written down is a trap. It does not cause a problem on the day it is created; it causes one months later, when somebody reads the standard, checks that the fork is active, and writes code against a guarantee the chain was not providing.
The deviation was found and confirmed by direct measurement while building the EIP compatibility matrix, not by reading our own configuration, which is exactly the failure mode this record exists to prevent for the next person.
Specification
EIP-2935 as written specifies a history-storage system contract at
0x0000F90827F1C53a10cb7A02335B175320002935, a ring buffer serving the last
HISTORY_SERVE_WINDOW = 8191 block hashes, written by a consensus system call at
the start of each block, activated at the fork that adopts it.
On chain 2800:
- Address:
0x0000F90827F1C53a10cb7A02335B175320002935(canonical, unchanged). - Window: 8191 blocks (
0x1fff), unchanged from the written EIP. - Runtime: 83 bytes, byte-for-byte the canonical EIP-2935 runtime
(measured). Disassembly confirms the two jump targets: the
JUMPDESTat0x42(revert path) and theJUMPDESTat0x46(theSSTOREpath taken whencaller == SYSTEM_ADDRESS). - Deviation: the contract was not populated at the Pectra ruleset. It was
populated, and the consensus write path began running, at the AerePQC milestone
block 9,189,161 (Besu
futureEipsTime = 1783820272), the same fork documented in AIP-7.
Therefore, normatively:
- For
number < 9,189,161: a call to the history address returns empty, because the address was an empty account. EIP-2935 MUST NOT be relied on. - For
number >= 9,189,161: the contract serves the window[number - 8191, number - 1]. A call passes the 32-byte block number as calldata; a query outside the served window reverts.
At the 500 ms target block period, 8191 blocks is roughly 68 minutes of
trustless lookback, against roughly 128 seconds for the 256-block BLOCKHASH
window.
Rationale
The deviation was not a design choice made in advance; it is the honest description of what happened. Pectra parity was configured before the EIP-2935 write path existed in the Aere Besu fork, so the ruleset listed an EIP whose system contract nothing was writing to. When the write path shipped, it was bundled into the AerePQC fork rather than given its own activation, because the fork was already scheduled and a second coordinated activation would have added rollout risk for no benefit (the same bundling rationale as AIP-7).
Alternatives rejected. Silently correcting the compatibility documentation to say EIP-2935 was live from Pectra: false. Backfilling the ring buffer at activation: impossible without rewriting state, and the fail-empty behavior of an unpopulated contract is the safe outcome anyway.
Backwards Compatibility
This is the whole subject of the AIP. Concretely: a contract deployed before block 9,189,161 that called the history address received empty return data, and if it treated empty as "hash zero" it computed a wrong answer rather than reverting. Any such contract should be re-checked. From block 9,189,161 the same call returns real history, so a contract whose behavior depended on the empty return changes behavior at that block.
Note the asymmetry that makes this safe at the consensus layer: the transition is from an empty account to a populated one, so no historical block re-executes differently on an upgraded binary.
Security Considerations
The window is 8191 blocks and queries outside it revert. A consumer that assumes a longer lookback fails closed, which is correct, but a consumer that assumes any lookback before block 9,189,161 silently receives nothing, which is not. That asymmetry is the reason this record exists.
The trustless-lookback guarantee is only as strong as the chain itself: on chain 2800 that is a seven-validator, single-operator QBFT chain (AIP-9). EIP-2935 removes a trust assumption on an oracle; it does not remove the trust assumption on the validator set.
Reference Implementation and On-Chain Deployment
Chain ID 2800, activation block 9,189,161, contract
0x0000F90827F1C53a10cb7A02335B175320002935, runtime 83 bytes.
Verify it yourself against https://rpc.aere.network:
eth_getCodeat the history address returns the canonical 83-byte runtime.eth_callthe address with the 32-byte block number ofhead - 100returns that block's hash, byte-identical toeth_getBlockByNumber. This is the stronger check: the ring buffer is not merely populated, it is serving correct history.
Related: AIP-7 (the fork that activated it),
aerenew/docs/AERE-EIP-COMPATIBILITY-MATRIX.md (deviation 7),
aerenew/docs/AERE-PROTOCOL-SPECIFICATION.md.
Errata
None.
Post-Acceptance Outcome Record
2026-07-20. Both verification paths above were run against the live chain and
both pass (measured). The functional check, returning the correct hash for
head - 100, is recorded as the canonical proof rather than the bytecode check,
because matching bytes prove deployment while a correct answer proves operation.
An adjacent claim remains open and is flagged rather than assumed: whether the EIP-6110 deposit system contract is populated on mainnet 2800 has not been checked directly. Given that EIP-2935's contract was listed as active while unpopulated, that claim must be measured, not inferred from the ruleset.
Copyright
Released to the public domain (CC0). No rights reserved.