The public history carried kat/__pycache__/mlkem768_reference.cpython-314.pyc, a compiled Python artifact embedding the operator's absolute local path. Text secret scanners do not read compiled binaries, which is exactly how it slipped through, and removing it from the tip would have left it reachable through the old root commits. So this repository is republished from a single clean root. This root also carries, from the previously unpublished line of work: - corrected LICENSE year, LICENSING.md, VERIFY-POLICY.md, and CITATIONS-UNRESOLVED.md remeasured 2026-08-11 (101 paths, README aligned) - O-018: run_consensus_verification.py ran 19 of 29 models and reported PASS; it now runs all 29, and computemarket_smt.py gains resolveByTimeout / reclaimUnsettled cases plus a negative control - O-006: the word 'audited' removed from next to Bouncy Castle, twice, after a concurrent edit resurrected it - O-014: prior art named and dated - Algorand's native falcon_verify shipped about ten months before AERE's precompiles; the primacy claim is withdrawn where it was implied - bench/ scripts parametrized so they actually run for an outsider (the earlier textual sanitization left $STAGING unexpanded inside Python strings) - AIP-2/AIP-3 errata with measured figures, spec remeasurements at 2026-08-01, and the spec-zk-stack retractions (owner is an operational key, not the Foundation; 'maximally sound' withdrawn; aggregator V1 deprecated) The redacted bench-host environment files from the sanitized line are kept exactly as published; the unredacted local variants are not carried.
30 KiB
AERE Network: Full-EVM Validity Rollup (revm-in-SP1)
Chain: AERE Network mainnet, chain ID 2800 (Hyperledger Besu QBFT). Measured mean block interval 0.5175 s over the 2,000 blocks to head 11,810,041 on 2026-08-01; seven validators, f=2, one operator.
Status date: 2026-08-01. Every on-chain figure (code size, owner, counters, route targets, balances, the EIP-2935 window) was re-read from https://rpc.aere.network at head block 11,810,041 on that date. Corrections found in that pass are stated inline, next to the sentence they correct, rather than applied silently.
Source of truth for addresses: sdk-js/src/addresses.ts. Contract source: contracts/contracts/. Guest/host prover: rollup-evm-validity/.
Scope: the REAL full-EVM validity path: a live chain-2800 block re-executed with revm inside the SP1 zkVM, its post-state root proven, and that proof verified on-chain through the SP1 gateway into the AereEVMValidity anchor. This document also states, honestly, what is and is not proven, and how this work supersedes the earlier bounded-VM proof of concept.
0. Honesty preamble (read this first)
Four points frame everything that follows.
-
This is a proof-of-approach, not a production rollup. What has been proven is that a REAL AERE mainnet block, executed with a real EVM (
revm) inside a zkVM, reproduces the canonical post-state root, and that the resulting proof verifies on chain 2800. The proven block is small (one EIP-1559 transaction). It is not a large batch, and the anchor records isolated proven blocks rather than a continuous sequenced chain. No claim built on this should imply a full-throughput validity rollup exists today. -
The realism is the point. The guest runs the actual
revmexecution stack (SP1-patchedreth1.9.3 /revm), not a hand-written subset. Full opcode set, call frames,SLOAD/SSTORE,LOG, EIP-1559 base-fee burn plus priority-to-coinbase, and the Cancun/Prague/Osaka system calls all execute and all affect the proven state root. This is the difference from the prior bounded-VM PoC (section 9). -
The anchors are now in the canonical registry.
AereEVMValidity(single block) at0x1f2CB0ebDBb21500e99868DbF1dB3abCcDd7DF26and its multi-block siblingAereEVMValidityBatchat0x49D30a5999eA5b7f6eFf12196AB006316683Ff3Care both live on chain 2800, have real proofs recorded, and are now promoted intosdk-js/src/addresses.ts(verbatim there). Both are immutable, admin-free, and permissionless to record. -
The crypto is classical, a known hedge. SP1 Groth16 proves over BN254 and QBFT signs with classical keys, so this validity path is not itself post-quantum. AERE's post-quantum work (the verifier suite and the
AerePQChard-fork that also carries the native EIP-2935 lookback of section 8) is tracked separately.
1. What is proven (the theorem)
For a target chain-2800 block B with parent P, the SP1 Groth16 proof establishes:
Executing block
B's transactions withrevm(Cancun/Prague/Osaka rules per the chain-2800 genesis schedule) against the account and storage state committed byP.stateRoot, then re-rooting the resulting sparse Merkle-Patricia trie, yields a post-state root exactly equal toB.header.stateRoot.
The public values committed by the guest are exactly 224 bytes (7 x 32), ABI-encode compatible:
abi.encode(
uint256 chainId, // == block.chainid (2800)
uint256 blockNumber, // proven block height
bytes32 prevStateRoot, // parent block state root (pre-state anchor)
bytes32 postStateRoot, // proven post-execution state root == header.stateRoot
bytes32 txRoot, // header.transactionsRoot (binds the executed txs)
uint256 gasUsed, // total gas used by the block
uint256 numTxns // number of transactions executed
)
txRoot binds the proof to the canonical header's exact transaction set, prevStateRoot and postStateRoot bind it to the concrete pre-state and the post-state the real chain published, and chainId prevents cross-chain replay.
2. Architecture: host witness, guest re-execution, on-chain anchor
The pipeline has three stages, each with a distinct trust role.
chain-2800 node SP1 zkVM (guest) chain 2800 (on-chain)
--------------- ---------------- ---------------------
eth_getProof / block / code revm re-execute block SP1VerifierGateway
-> EthClientExecutorInput -> re-root sparse MPT -> 0x9ca479...70628
(host pre-flight revm) commit 224-byte pv -> AereEVMValidity anchor
- Host (
rollup-evm-validity/host). Gathers the pre-state witness for blockBfrom the live node usingrsp'sEthHostExecutor, which driveseth_getProofplus block and code RPC. It runsrevmonce, off chain, against a proof-recording database and asserts the recomputed post-state root equalsheader.stateRoot. This pre-flight produces no proof, only the serialized witness (EthClientExecutorInput). - Guest (
rollup-evm-validity/guest, ELFaere-client). Re-executes the block withrevminside the zkVM viarsp_client_executor::EthClientExecutor, re-roots the trie, and commits the 224-byte public values. Execution only succeeds when the computed post-state root matchesheader.stateRoot; a mismatch panics and no valid proof exists. - Anchor (
AereEVMValidity). Verifies the Groth16 proof through the SP1 gateway and, on success, records the block. Verification is delegated entirely to the gateway; the anchor adds no trust of its own beyond binding the exact program.
The gateway SP1VerifierGateway at 0x9ca479C8c52C0EbB4599319a36a5a017BCC70628 is the same canonical SP1 verifier gateway used by the rest of AERE's zk stack, routed by the leading 4-byte selector 0x4388a21c (SP1 v6 Groth16).
3. The guest: revm inside the zkVM (rsp / sp1-reth)
The guest is a thin driver around the rsp (sp1-reth) client executor. Its whole body is: read the bincode witness, capture the parent state root, transaction count and block number, build the chain-2800 ChainSpec from the embedded genesis, then:
let executor = EthClientExecutor::eth(chain_spec, input.custom_beneficiary);
let header = executor.execute(input).expect("EVM execution / state-root check failed");
EthClientExecutor::execute is real revm. It applies each transaction against the witnessed pre-state, charges gas, splits EIP-1559 fees (base fee burned, priority tip to the beneficiary), runs the pre/post-execution system calls, and folds the modified accounts and storage back into the sparse trie to recompute the root. The guest then commits chainId, blockNumber, prevStateRoot, postStateRoot, txRoot, gasUsed, numTxns.
Version pinning. The guest builds against reth tag v1.9.3 and sp1-zkvm =6.1.0 (this is the rsp / sp1-reth line tagged reth-1.9.3-sp1-6.1.0, not the old bounded toy VM). The precompile patches match rsp's reference client so that in-guest hashing and signature recovery are zk-accelerated: sha2, sha3 (Keccak for trie and keccak256), k256 (ecrecover), p256, and substrate-bn, all from the sp1-patches forks. This is what keeps a full block's Keccak-heavy trie walk inside a tractable cycle budget.
Program binding. The anchor's immutable PROGRAM_VKEY is the SP1 verification key of exactly this guest ELF: 0x00d79882d2f72013ede3b1be9d44edcad08107858e00dded883fe3b02dbbb808. Binding the vkey binds the exact revm-in-zkVM program; a proof from any other program is rejected by the gateway.
4. The witness path (eth_getProof, sparse MPT, re-root)
The guest never sees full chain state. It sees a witness: only the accounts and storage slots the block touches, each with the Merkle proof that ties it to P.stateRoot. The witness type ClientExecutorInput (patched in rollup-evm-validity/rsp-patches/io.rs) carries:
current_block(the blockBto execute),ancestor_headers(at least the parent, to supplyP.stateRootand theBLOCKHASHmap),parent_state(anEthereumState: the state trie plus the per-account storage tries, populated frometh_getProof),bytecodes(the contract code the block executes),genesis,custom_beneficiary,opcode_tracking.
witness_db verifies the witness before execution: the provided parent_state must hash to P.stateRoot (state_anchor() == state.state_root()), and each account's storage_root in the state trie must equal the hash of its supplied storage trie. Reads during execution go through a TrieDB DatabaseRef that resolves accounts and storage by walking these witnessed tries (state_trie.get_rlp, storage_tries[...].get_rlp), so any slot the block reads must have been included in the witness with a valid proof, or execution fails. After execution the same trie machinery folds the writes back and recomputes the root. This is what makes the proof a validity statement over the real MPT rather than over an opaque snapshot.
eth_getProof is therefore the sole bridge between the live node and the proven computation. The witness is trustless in the sense that a wrong or incomplete witness cannot produce a passing proof: the pre-state root check, the per-account storage-root check, and the final post-state root equality each independently reject it.
5. QBFT header adaptations
AERE runs Besu QBFT, not proof-of-work or a beacon-chain layer, and this required exactly one honest adaptation to the stock rsp witness logic, isolated in is_qbft_relaxed().
Under QBFT, the canonical block hash is not keccak256(rlp(header)), because the validator commit seals are excluded from the hashed header. Stock rsp links ancestor headers by asserting keccak(rlp(parent)) == child.parent_hash, which never holds on chain 2800. The patch relaxes only that ancestor parent-hash linkage assertion, and only for chain 2800:
fn is_qbft_relaxed(&self) -> bool {
matches!(&self.genesis, Genesis::Custom(c) if c.chain_id == 2800)
}
Everything that actually secures the state transition stays enforced:
- the
BLOCKHASHmap is still built from the canonicalchild.parent_hash()values, so theBLOCKHASHopcode returns real hashes; - the parent state root is still checked against
parent_header.state_root(); - the post-state root is still asserted equal to
header.stateRoot.
The relaxation removes a hash-shape assumption that is false under QBFT; it does not remove any check on the proven state transition. Other L1 fields QBFT lacks (parent beacon block root and blob base fee, both zero on chain 2800) are handled by the chain-2800 ChainSpec built from genesis, consistent with the live node.
6. The on-chain anchor: AereEVMValidity
AereEVMValidity (source contracts/contracts/parallel/AereEVMValidity.sol) is deployed at 0x1f2CB0ebDBb21500e99868DbF1dB3abCcDd7DF26 (canonical in sdk-js/src/addresses.ts; recorded in contracts/deployments/evm-validity.json, deploy tx 0x22284d1d...15e51b, deploy block 9074452, an operational deployment account). A multi-block sibling, AereEVMValidityBatch at 0x49D30a5999eA5b7f6eFf12196AB006316683Ff3C (also canonical), records a contiguous batch of real blocks in one Groth16 and is documented in Section 7.1.
Design:
- Two immutables, no admin.
SP1_VERIFIER(the gateway) andPROGRAM_VKEYare fixed at construction. There is no owner and no upgrade path. Recording is permissionless. Soundness rests entirely on the Groth16 proof plus the vkey binding. - Verify-then-record.
recordBlock(publicValues, proof)requirespublicValues.length == 224, calls the gateway'sverifyProof(PROGRAM_VKEY, publicValues, proof)inside atry/catchthat translates a revert into a typedInvalidProof(), decodes the seven fields, checkschainId == block.chainid, enforces one record per block number, then stores theProvenBlockand updateslatestPostRoot. Averify(...)view offers the same gateway check statelessly for callers who only want to validate without recording. - What it does not do. It does not chain records (there is no
prevRoot == latestRootcontinuity check, unlike the bounded-VM anchor of section 9), and it does not settle withdrawals or sequence a rollup. It is an attestation log of individually proven real blocks.
The trust boundary is stated in the contract's own header comment: this proves REAL EVM execution of a small live block as a proof-of-approach, and records isolated proven blocks rather than a continuous sequencer chain.
7. Measured results
Two real chain-2800 blocks were proven end-to-end with the server's SP1 v6.1.0 CPU prover (SP1_PROVER=cpu, RAYON_NUM_THREADS=16, native gnark Groth16). Both blocks carry one real EIP-1559 transaction performing an SSTORE plus LOG contract call at roughly 33.6k gas, roughly 1.18M RISC-V cycles in the guest, a fresh Groth16 produced in about 533s of CPU time, with peak resident memory about 27.7GB and no out-of-memory.
The block committed on-chain and captured in the repo artifact (contracts/deployments/evm-validity-proof.json) is block 9073073:
| Field | Value |
|---|---|
| chainId | 2800 |
| blockNumber | 9073073 |
| prevStateRoot | 0x31921701d25cb1791d47c0af23b0d84e6f6cdfdd3234a8643638854e588ae5eb |
| postStateRoot | 0x0403c73b02f82a4e25ddde929995995b624ceb9384a50e0c31755099b5346636 |
| txRoot | 0x00e9301708e05258def41ed6a8ec9523ba98b6ffc5945316e9180c841f5b4864 |
| gasUsed | 33601 |
| numTxns | 1 |
| guest cycles | 1,181,363 |
| proof selector | 0x4388a21c |
| proof bytes | 356 |
| public values bytes | 224 |
It was recorded on-chain by recordBlock in tx 0xb28a39507f8c03e6ffcfed307f9848814dd9d35268f01983825b658cbc56415c (submit block 9074454, status 1), gas used 460,015 against an estimate of 464,833, comfortably under the EIP-7825 per-transaction cap of 16,777,216. That record cost is dominated by the fixed Groth16 pairing check in the gateway and is essentially independent of the block's own gas or transaction count. A second, freshly produced block, 9075035, was proven with the identical profile during the same session, demonstrating repeatability on a block mined after the anchor was deployed. Every proof is also tamper-tested: flipping one byte inside postStateRoot in the public values makes the on-chain-equivalent sp1_verifier::Groth16Verifier reject it, confirming the proof binds the committed root.
7.1 Batch proofs and the dense-workload result (density caveat removed at demonstrated scale)
Two extensions build directly on Section 7 and are documented here rather than left implicit.
The multi-block batch anchor, AereEVMValidityBatch (0x49D30a5999eA5b7f6eFf12196AB006316683Ff3C, canonical). A sibling anchor records a contiguous batch of real chain-2800 blocks in one Groth16 proof. The batch guest threads each block's recomputed post-state root into the next block's pre-state and re-roots the sparse trie, so the proof verifies only when the final recomputed post-state root equals the canonical header.stateRoot of the last block. Its PROGRAM_VKEY binds the exact batch guest ELF (0x00418c4f40178103cc75ae57b63703f6075cabdce23582fed6043ceae819192e) and differs from the single-block vkey; the 256-byte public values carry (chainId, firstBlock, lastBlock, numBlocks, prevStateRoot, postStateRoot, totalGas, numTxns). A real 16-block batch, chain-2800 blocks 9111008..9111023, was recorded on-chain via recordBatch in tx 0x074a4e6c17855b78db4c56808e253d4c00a7b392cf0d141e4aa0e6e299ded9ec (submit block 9114536, status 1), gasUsed 460,817, under the cap. Like the single-block anchor it is immutable and admin-free.
The dense-workload proof (removes the "low tx density" caveat at demonstrated scale). Historical mainnet blocks are low-density and the live node prunes state (Bonsai), which capped earlier witnessable batches at a handful of transactions (the prior batch was 2 txs across 16 blocks). To show that a genuinely dense real-EVM block is provable and gateway-acceptable, a dense workload was generated on a throwaway single-validator node running the AERE fork profile (chain-config 2800) in archive mode so all touched state is witnessable via eth_getProof, and proven with the same real revm-in-SP1 batch prover against the same batch-program vkey:
- A single ultra-dense block of 155 real transactions and 460 SSTOREs (52 freshly created EOAs, 52 fresh ERC-20 holder slots), 29,572,987 guest cycles. Local SP1 Groth16 verify PASS, tampered
postStateRootREJECTED. Verified read-only against the live mainnet SP1 gateway0x9ca479C8c52C0EbB4599319a36a5a017BCC70628: the real proof was accepted and both a tampered-public-values and a tampered-proof call reverted. - A 2-block contiguous, state-continuity-chained dense batch (310 txs, 920 SSTOREs, 27,050,310 gas, 61,366,308 cycles; the guest enforces
post_root(N) == header.stateRootandpre_root(N+1) == post_root(N)), same live-gateway acceptance read-only with both tampers reverted.
Honest label: this dense chain is an isolated, engineered workload, NOT a replay of historical mainnet blocks; verification against the live gateway was eth_call only, no mainnet transaction was sent. Compatibility was confirmed by the guest reproducing Besu 26.4.0's exact header.stateRoot for every dense block, the same agreement already established on real chain-2800 blocks (Section 7). What it establishes is that the approach scales to dense, fully-witnessable blocks; the practical ceiling on the box used was about two full-density blocks (~61M cycles) before proving went swap-bound, so a longer dense batch is a prover-resource matter, not an approach question.
Canonical-binding V2 is DEPLOYED and has recorded nothing. Correction of 2026-08-02. An earlier revision of this paragraph said the V2 layer "is STAGED, not deployed" and "MUST NOT be deployed yet". That is measurably wrong at head: AereEVMValidityV2 0x4884ad6617e320735b65D31915d1aBC884768D9B carries 2,852 bytes of live code and AereEVMValidityBatchV2 0xe154B8993FB54dB4418e03ef4a04894f29E690aE carries 3,425 bytes, both in the canonical registry, read from https://rpc.aere.network. What the V2 layer does is unchanged: an updated guest commits blockHash + parentHash and enforces prevStateRoot == parent.stateRoot inside the circuit, closing the canonicity gap of Section 8 by requiring the committed blockHash to equal the on-chain canonical hash of that block number. The honest status is therefore the opposite shape of the old one: the contracts exist and the proving side has not caught up. provenCount() reads 0 on both V2 anchors and 1 on each V1 anchor, so every real recorded proof today still sits on V1. The changed public-values layout changes the SP1 vkey, so the guest must be re-proved end to end against the deployed V2 vkey before anything can be recorded there. Until that happens, the strongest thing actually proven on chain remains the V1 record, and V1 never claims a record is the canonical chain-2800 block. See rollup-evm-validity/NOTE.md and dense-batch-2026-07-11/NOTE.md.
8. Canonicity of the pre-state root (honest gap and the fix)
The proof establishes postStateRoot given prevStateRoot. It does not, by itself, establish that prevStateRoot is the canonical parent state root of the real chain. For the two blocks above, both roots were cross-checked by the host against the live node's headers, so the records are genuine, but a permissionless caller could in principle record a proof over a self-chosen pre-state. Closing that gap trustlessly is the job of the anchoring layer, which has two live-adjacent pieces:
-
AereStorageProofVerifierV2at0x487021f9aE018657B7335ADC6Fc254717751a1Dd(3,160 bytes live) proves a value at an account slot against a given state root, with the same caveat that canonicity of that root is the caller's responsibility. ItsCANONICAL_ANCHOR()returns0x0b959402283c0D2B9db4FfD7823f99782462e488, read at head. Do not use V10xF9a1A183bEb3147D88dA5927301683fEbFb9362E. An earlier revision of this bullet named that address with no qualification. The canonical registry calls itAereStorageProofVerifier_DEPRECATED_POISONABLEand says literally "DO NOT readgetProven()as canonical; repoint to V2": becauseblockNumberis only metadata to the verifier, a genuine proof against a non-canonical root can overwrite a record key with a value that was never in the canonical chain. V2 binds to the anchor above and closes that. -
AereHistoryStateRootAnchorV2at0x4C1F9daD515c7990b65F9833960CA4315216330C(2,915 bytes live,addresses.tsline 391) recovers a canonical block hash from the native EIP-2935 history-storage system contract at0x0000F90827F1C53a10cb7A02335B175320002935viaSTATICCALL, re-derives the header state root from the RLP header, and anchors it. ItsHISTORY_STORAGE_ADDRESS()returns that same system-contract address, read from chain at head. On the AERE Besu fork the ring buffer is written by QBFT consensus itself at the start of every block (a system call, no keeper, no Foundation key), so the value is produced by consensus exactly likeBLOCKHASHbut with an 8,191-block reach instead of 256, roughly 71 minutes of trustless lookback at the measured 0.5175 s block interval.Correction of 2026-08-01: this anchor is no longer scratch-only, and the fork it was waiting for has landed. An earlier revision described it as "scratch-only so far, bundles into the
AerePQChard-fork for mainnet", and proven only on scratch chain 28099. The AerePQC fork activated on mainnet 2800 at block 9,189,161 (timestamp 2026-07-12T01:37:52Z), the EIP-2935 system contract carries 83 bytes of code at head, and the window was measured end to end on mainnet: reads at 1, 255, 256 and 8,190 blocks behind head each returned exactly the canonical hasheth_getBlockByNumberreports for that height, and 8,191 and beyond revert.One loose end, stated because it is ours.
AereHistoryStateRootAnchorV2.VERIFIER()returns0xF9a1A183…, the deprecated storage-proof verifier named above. Until that is repointed at0x487021f9…, the extended-lookback path terminates in a record we ourselves call poisonable, and should not be treated as a canonical record path.
The two are complementary: the validity proof says "this pre-state deterministically yields this post-state," the anchor says "this state root is canonical for this height." A production system would require the recorded prevStateRoot to be an anchored canonical root before accepting the transition. That wiring is future work, called out here rather than hidden.
9. How it supersedes the bounded-VM proof of concept
The prior anchor, AereRollupValidity at 0x38772063572DF94E90351e44ccbBEefD5F497fbd (source contracts/contracts/parallel/AereRollupValidity.sol), is a real validity proof, but of a bounded virtual machine. Its guest implements only four transaction kinds (Transfer, Sweep, Increment, AmmSwap) over a balance-and-storage map, with a hand-ported execute_txn and Keccak state-root folding taken verbatim from AERE's parallel-executor. It commits 160-byte public values (chainId, prevRoot, postRoot, batchHash, numTxns) and, notably, it does chain: it enforces prevRoot == latestRoot and advances a canonical tip, recording epochs. Epoch 0 is on record from a real proof.
AereEVMValidity supersedes it on the axis that matters most, execution fidelity:
| Dimension | AereRollupValidity (bounded PoC) |
AereEVMValidity (full-EVM) |
|---|---|---|
| VM | 4 fixed tx kinds over a map | real revm, full opcode set |
| Input | synthetic batch encoding | REAL chain-2800 block + header |
| State model | custom balance/storage map | real account and storage MPT via eth_getProof |
| Fees / system calls | none | EIP-1559 split, Cancun/Prague/Osaka system calls |
| Public values | 160 bytes | 224 bytes (adds blockNumber, txRoot, gasUsed) |
| Continuity | chains via latestRoot |
isolated records (deliberately, for now) |
The bounded VM could never prove that real EVM bytecode on the real chain reproduces the canonical root, because it does not run the EVM. The full-EVM anchor does exactly that. The trade made along the way is that the full-EVM anchor currently drops the continuity chaining the bounded anchor had, because at proof-of-approach stage you prove individual real blocks, not a sequenced batch chain. The continuity and finalization machinery in AereRollupValidity is the template to re-add when moving to a production sequencer, this time over real EVM blocks.
10. Honest scope versus a production sequencer or rollup
What exists today: a real revm-in-zkVM guest that re-executes a real chain-2800 block and proves the canonical post-state root; a host that gathers the eth_getProof witness and pre-flights execution; an immutable, admin-free on-chain anchor that verifies the Groth16 proof through the canonical SP1 gateway and records the block; and two real blocks proven end-to-end (9073073 recorded on-chain, 9075035 proven fresh) with measured cycles, gas, proving time and memory, plus a passing tamper test.
What does not exist yet, stated plainly:
- Batch scale. The low-tx-density caveat is now removed at demonstrated scale: dense blocks of 155 txs / 460 SSTOREs each are provable and live-gateway-acceptable, single and 2-block-chained (Section 7.1), and a real 16-block batch is recorded on-chain via
AereEVMValidityBatch. What still does not exist is a continuous production cadence: proving is single-box CPU and swap-bound past about two full-density blocks (~61M cycles), so a long dense batch or blocks packed to the gas limit motivates GPU proving and proof partitioning, and the anchors still record isolated proven blocks and ranges rather than a sequenced rollup chain. - A sequencer. There is no mempool, ordering service, or forced-inclusion path. The system proves blocks the QBFT chain already produced; it does not sequence a separate rollup.
- Continuity and settlement. The anchor records isolated blocks with no
prevRoot == latestRootchaining and no withdrawal or bridge settlement. There is no fraud/validity dispute lifecycle beyond "the proof verified." - Canonical pre-state binding. As in section 8, the recorded
prevStateRootis not yet required to be an anchored canonical root on-chain. - Data availability. The witness is gathered from a trusted node; there is no DA commitment or sampling for third-party reconstruction.
- Audit and decentralization. The contracts are unaudited by an external party, and chain 2800 runs seven QBFT validators under a single operator. The prover is a single CPU box.
None of these gaps is hidden in the contract, the artifacts, or this spec. The correct one-line summary is: AERE can prove a real EVM block of its own mainnet in zero knowledge and verify that proof on-chain, as a proof-of-approach; it is not yet a throughput-grade validity rollup.
11. Path to production
The credible sequence from here, each step building on a demonstrated capability:
- Fuller blocks. Prove blocks with many transactions and near-limit gas, measuring the cycle and memory curve. This is the first honest scaling test.
- Continuity. Re-introduce the
prevRoot == latestRootchaining fromAereRollupValidity, over real EVM blocks, so records form a verified chain rather than a set. - Canonical pre-state binding. Require the recorded
prevStateRootto be an anchored canonical root, by wiringAereEVMValiditytoAereHistoryStateRootAnchorV2at0x4C1F9daD515c7990b65F9833960CA4315216330C. The blocker an earlier revision named for this step is gone: it said the work waited on that anchor "once that anchor ships in theAerePQCfork on mainnet", and the fork shipped at block 9,189,161 with EIP-2935 live. The anchor is deployed and registered. What remains is the wiring itself, plus repointing that anchor'sVERIFIER()off the deprecated0xF9a1A183…and ontoAereStorageProofVerifierV2 0x487021f9…. - Aggregation. Fold many per-block validity proofs into one Groth16 via
AereProofAggregatorV2at0x944dE720D6C9696Bdf10b6E2F00dd21ABB1A2b4C(4,663 bytes live,addresses.tsline 396). Not via0x6a260238890E740dB12b371E0C5d17a2470F84C5, which an earlier revision named here without qualification: the canonical registry calls that oneAereProofAggregator_DEPRECATED_UNENFORCED_INNER_VKEYS, because it counted recognized inner programs without requiring them to be registered. The n=10 demonstration cited below was recorded on V1 and is real as a demonstration of recursion (record tx0xd1fd4d60...9344d978, recorded gas roughly 394k, essentially flat in N); the contract to build on is V2, which rejects an unregistered inner program. Measured at head: V1aggregationCount= 2, V2aggregationCount= 1. - DA and sequencing. Add a data-availability commitment and, only if a distinct rollup is warranted, a sequencer with forced inclusion.
- Proving cost. Move from single-box CPU proving toward GPU and partitioned proving as block size grows.
The engineering already on chain (the SP1 gateway, the aggregator at scale, the EIP-2935 native lookback, the storage-proof verifier) makes these integration steps over demonstrated parts, not research from zero. The honest limit is that the integration has not been done yet.
Every address here is printed verbatim from sdk-js/src/addresses.ts. Copying the hex is not the same as copying the status, and an earlier revision of this line claimed more than it delivered: it said every address was printed verbatim from the registry, which was true, while leaving two of them (0xF9a1A183…, 0x6a260238…) presented as current when the registry marks both deprecated. Every deprecated address in this document is now printed with its label and its replacement. The EIP-2935 system-contract address is a protocol constant. Figures from the repo artifacts and the session prover run are marked as such; code sizes, counters and the EIP-2935 window were re-read from https://rpc.aere.network on 2026-08-01 at head block 11,810,041. None are invented.