aere-research/research/specs/spec-full-evm-validity.md
Aere Network 4a0b48588c Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:02:30 +03:00

241 lines
26 KiB
Markdown

# AERE Network: Full-EVM Validity Rollup (revm-in-SP1)
**Chain:** AERE Network mainnet, chain ID 2800 (Hyperledger Besu QBFT, ~0.5s blocks).
**Status date:** 2026-07-11.
**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.
1. **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.
2. **The realism is the point.** The guest runs the actual `revm` execution stack (SP1-patched `reth` 1.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).
3. **The anchors are now in the canonical registry.** `AereEVMValidity` (single block) at `0x1f2CB0ebDBb21500e99868DbF1dB3abCcDd7DF26` and its multi-block sibling `AereEVMValidityBatch` at `0x49D30a5999eA5b7f6eFf12196AB006316683Ff3C` are both live on chain 2800, have real proofs recorded, and are now promoted into `sdk-js/src/addresses.ts` (verbatim there). Both are immutable, admin-free, and permissionless to record.
4. **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 `AerePQC` hard-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 with `revm` (Cancun/Prague/Osaka rules per the chain-2800 genesis schedule) against the account and storage state committed by `P.stateRoot`, then re-rooting the resulting sparse Merkle-Patricia trie, yields a post-state root exactly equal to `B.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 block `B` from the live node using `rsp`'s `EthHostExecutor`, which drives `eth_getProof` plus block and code RPC. It runs `revm` once, off chain, against a proof-recording database and asserts the recomputed post-state root equals `header.stateRoot`. This pre-flight produces no proof, only the serialized witness (`EthClientExecutorInput`).
- **Guest (`rollup-evm-validity/guest`, ELF `aere-client`).** Re-executes the block with `revm` inside the zkVM via `rsp_client_executor::EthClientExecutor`, re-roots the trie, and commits the 224-byte public values. Execution only succeeds when the computed post-state root matches `header.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:
```rust
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 block `B` to execute),
- `ancestor_headers` (at least the parent, to supply `P.stateRoot` and the `BLOCKHASH` map),
- `parent_state` (an `EthereumState`: the state trie plus the per-account storage tries, populated from `eth_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:
```rust
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 `BLOCKHASH` map is still built from the canonical `child.parent_hash()` values, so the `BLOCKHASH` opcode 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, deployer `0xbeB33D20dFBBD49eC7AC1F617667f1f02dfd6465`). 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) and `PROGRAM_VKEY` are 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)` requires `publicValues.length == 224`, calls the gateway's `verifyProof(PROGRAM_VKEY, publicValues, proof)` inside a `try/catch` that translates a revert into a typed `InvalidProof()`, decodes the seven fields, checks `chainId == block.chainid`, enforces one record per block number, then stores the `ProvenBlock` and updates `latestPostRoot`. A `verify(...)` 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 == latestRoot` continuity 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 `postStateRoot` REJECTED. Verified read-only against the live mainnet SP1 gateway `0x9ca479C8c52C0EbB4599319a36a5a017BCC70628`: 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.stateRoot` and `pre_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 STAGED, not deployed.** A V2 layer (`AereEVMValidityV2`, `AereEVMValidityBatchV2`, and an updated guest that commits `blockHash` + `parentHash` and enforces `prevStateRoot == parent.stateRoot` inside the circuit) closes the canonicity gap of Section 8 by requiring the committed `blockHash` to equal the on-chain canonical hash of that block number. It exists in the tree and is self-consistent but MUST NOT be deployed yet, for one remaining reason: the changed public-values layout changes the SP1 vkey, so the guest must be re-proved end to end and the new vkey wired into the V2 contracts before any deploy. The second dependency has since been satisfied: practical canonical binding needs EIP-2935 history storage live on chain 2800 (the 256-block `blockhash()` window is far shorter than proving time), and EIP-2935 is now live on mainnet since block 9,189,161 (the AerePQC hard fork). V2 still requires its own re-prove and a supervised deploy; until it ships, recording continues against the honestly de-canonicalized V1 anchors, which never claim 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:
- **`AereStorageProofVerifier`** at `0xF9a1A183bEb3147D88dA5927301683fEbFb9362E` 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.
- **`AereHistoryStateRootAnchor`** (source `contracts/contracts/anchor/AereHistoryStateRootAnchor.sol`, scratch-only so far, bundles into the `AerePQC` hard-fork for mainnet) recovers a canonical block hash from the native EIP-2935 history-storage system contract at `0x0000F90827F1C53a10cb7A02335B175320002935` via `STATICCALL`, re-derives the header state root from the RLP header, and anchors it. 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 like `BLOCKHASH` but with an 8191-block reach instead of 256, roughly 68 minutes of trustless lookback at ~0.5s blocks. This was proven on scratch chain 28099 by anchoring a header more than 258 blocks back, beyond the `BLOCKHASH` window, recovering the state root purely from the system contract.
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 == latestRoot` chaining 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 `prevStateRoot` is 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 three 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:
1. **Fuller blocks.** Prove blocks with many transactions and near-limit gas, measuring the cycle and memory curve. This is the first honest scaling test.
2. **Continuity.** Re-introduce the `prevRoot == latestRoot` chaining from `AereRollupValidity`, over real EVM blocks, so records form a verified chain rather than a set.
3. **Canonical pre-state binding.** Require the recorded `prevStateRoot` to be an anchored canonical root, wiring `AereEVMValidity` to `AereHistoryStateRootAnchor` once that anchor ships in the `AerePQC` fork on mainnet.
4. **Aggregation.** Fold many per-block validity proofs into one Groth16 via `AereProofAggregator` at `0x6a260238890E740dB12b371E0C5d17a2470F84C5`, whose recursive aggregation is already demonstrated at n=10 (record tx `0xd1fd4d60...9344d978`, recorded gas roughly 394k, essentially flat in N), letting one on-chain verification stand for many proven blocks.
5. **DA and sequencing.** Add a data-availability commitment and, only if a distinct rollup is warranted, a sequencer with forced inclusion.
6. **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` (the SP1 gateway, `AereStorageProofVerifier`, `AereRollupValidity`, `AereProofAggregator`, `AereEVMValidity`, and `AereEVMValidityBatch`, all now canonical). The EIP-2935 system-contract address is a protocol constant. All measured figures come from the repo artifacts and the session prover run above; none are invented.*