aere-research/aips/AIP-18.md

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 JUMPDEST at 0x42 (revert path) and the JUMPDEST at 0x46 (the SSTORE path taken when caller == 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:

  1. eth_getCode at the history address returns the canonical 83-byte runtime.
  2. eth_call the address with the 32-byte block number of head - 100 returns that block's hash, byte-identical to eth_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.

Released to the public domain (CC0). No rights reserved.