Hostile-read repairs across the kernel artifacts: 17 confirmed over-claims fixed to honest
A 6-lens hostile panel with adversarial verification confirmed 17 attacks that would hold in a public takedown. All repaired: the MI contract now carries the two base-fee floor-lapse windows (12,978,617-13,087,959 and 13,596,033-13,596,141) as explicit ruleset validation exceptions, so a stranger implementing the written rules no longer halts where our own follower did; the honesty boundary now states the full record of reject-on-disagreement including the windows, and why the fact stays load-bearing; the independence claim is bounded (upstream skeletons yes, AERE ruleset has one author in both forks, so a common-author bug passes any differential gate by construction); the harness verdict claims only what it measures, records engine identity via web3_clientVersion on every run, refuses same-URL endpoint pairs, and prints its NOT MEASURED block on every run; stage 4 names the live engine (upstream parallel processing enabled by default, idling on empty blocks) and its oracle's model limits; 'governed registry' became 'owner-controlled' with the single-key fact stated. The panel also confirmed the import-proof doc claimed a two-month validation history where six days is the truth; fixed.
This commit is contained in:
parent
46c42164de
commit
f2ab368c36
@ -150,10 +150,19 @@ input or output. Only the commitments above are.
|
||||
|
||||
**Determinism is measured across implementations, not asserted from one.** A single client
|
||||
agreeing with itself proves nothing about determinism. The measurement that means something is
|
||||
two independent engines, built by different teams in different languages, deriving the same
|
||||
commitments from the same input. Today that is Besu (serial, live producer) versus Nethermind
|
||||
(independent second client, live at `client2.aere.network`). Tomorrow it is Block-STM through
|
||||
the same seam (treapta 4), measured by the same harness.
|
||||
two engines built by different teams in different languages deriving the same commitments from
|
||||
the same input. Today that is Besu (live producer; note that upstream Besu ships with parallel
|
||||
transaction processing enabled by default and the fleet does not disable it, so the live engine
|
||||
is the parallel-capable one, idling on empty blocks) versus Nethermind (second client, live at
|
||||
`client2.aere.network`). **The independence claim has a boundary, stated here rather than found
|
||||
by a hostile reader:** it holds for the upstream engine skeletons (different teams, different
|
||||
languages, different codebases), and it does NOT hold for the AERE-specific ruleset. The floor
|
||||
fork, the lapse windows and the PQ precompiles have a single author, this project, ported into
|
||||
both forks. A rule bug with a common author passes any differential gate by construction,
|
||||
because both sides inherit it. Cross-client agreement therefore catches implementation
|
||||
divergence, not specification error; specification error is what the formal models and hostile
|
||||
reads are for. Tomorrow Block-STM enters through the same seam (treapta 4), measured by the
|
||||
same harness.
|
||||
|
||||
**Honesty boundary, carried from `cross-client-determinism/`.** A matching header root served
|
||||
over RPC proves, on its own, only that both endpoints **serve the same bytes** for a block that
|
||||
@ -164,6 +173,19 @@ that sits in the follower's canonical chain below its processed head is therefor
|
||||
`post_state` the follower's own engine reproduced. The harness states this boundary on every run
|
||||
and never claims more than it.
|
||||
|
||||
The full record of that mechanism, stated before a hostile reader states it for us: every time
|
||||
reject-on-disagreement fired on the live chain, the resolution was to change the rejecting
|
||||
follower until it accepted the producer's chain. The two rejections cited above were resolved by
|
||||
patching the follower (missing predeploys, missing chainspec keys), and the largest episode is
|
||||
the floor-lapse window of section 6: the follower refused ~109,000 canonical blocks and was
|
||||
given a hardcoded acceptance window (`AereFloorLapse.cs`). Two things keep the fact
|
||||
load-bearing anyway. First, the acceptance windows live in header-fee derivation only; state
|
||||
root, receipts root and gas used stay fully validated inside the windows, so the post-state
|
||||
inference above survives. Second, the mechanism demonstrably still fires: after the first
|
||||
window was encoded, the follower stopped again at 13,596,032, which is exactly how the second
|
||||
lapse window was discovered. A rejection mechanism whose firings keep finding real producer
|
||||
defects is doing its job; a contract that cited only its flattering firings was not.
|
||||
|
||||
---
|
||||
|
||||
## 6. Admissible inputs
|
||||
@ -186,8 +208,22 @@ and never claims more than it.
|
||||
the live AERE fork. It is a **rule keyed on block number**, not an ambient input: every node
|
||||
computes the same base-fee floor for the same height. An engine that lacks it computes a
|
||||
different fee, therefore a different state root, and is a different MI, not the same one with
|
||||
a different environment. This is exactly the D-150 lesson: a binary missing the floor fork
|
||||
froze a real node at a state-root mismatch while every shape check stayed green.
|
||||
a different environment. A binary missing the floor fork froze a real node at a state-root
|
||||
mismatch while every shape check stayed green.
|
||||
- **The two floor-lapse windows, and they are part of the ruleset, not a footnote.** The live
|
||||
chain contains two dated windows in which the floor was NOT applied by the block producer:
|
||||
blocks **12,978,617 to 13,087,959** (109,343 blocks; the floor property had been silently
|
||||
lost from every validator's options and the base fee decayed to single-digit wei), and
|
||||
blocks **13,596,033 to 13,596,141** (a second, smaller lapse, found when the follower
|
||||
stopped again exactly at its edge). Inside these windows the base fee of a block is **not a
|
||||
function of the parent header**; it depends on which validator won the round. The rule an
|
||||
implementation must carry is therefore: **within these two windows, `baseFeePerGas` is
|
||||
accepted as given in the header** (validation exception), and outside them the floor rule
|
||||
applies strictly. An implementer who takes the floor rule without the windows will halt at
|
||||
block 12,978,617, which is precisely what this project's own second client did until the
|
||||
exception was encoded (`AereFloorLapse.cs` in the published follower source). A contract
|
||||
that omits the windows sends every stranger into the same wall, so they are stated here, in
|
||||
the ruleset, with their exact bounds.
|
||||
|
||||
Everything not in this list is inadmissible as an input. In particular: no OS clock, no RNG, no
|
||||
environment read at execution time, no network, no cross-block mutable cache.
|
||||
@ -276,7 +312,9 @@ fork build.
|
||||
|
||||
## 10. What this contract does NOT claim
|
||||
|
||||
Printed as NOT MEASURED by the harness, never as a pass:
|
||||
The harness prints a NOT MEASURED block naming these on every run, and its JSON report carries
|
||||
them in the `honesty` field, so the non-claims travel with every result rather than living only
|
||||
in this document:
|
||||
|
||||
- **That consensus is post-quantum.** It is not. Consensus finality is classical secp256k1 ECDSA
|
||||
QBFT plus a Falcon certificate. MI is an execution seam and says nothing about consensus.
|
||||
|
||||
@ -31,11 +31,16 @@ planted collision.
|
||||
state by (address, slot). Any collapse of two distinct logical locations onto one key is a
|
||||
correctness bug, not a performance detail, and is named in the contract while it costs nothing,
|
||||
not when it bites.
|
||||
- **One visible consensus change per activation (house rule from the panel).** Turning parallel
|
||||
execution on for mainnet, if it ever changes an observable, is one coordinated activation with a
|
||||
runbook, exactly the discipline proven at block 14,050,000. Today it is gated off
|
||||
(`AERE_BLOCKSTM` unset reproduces the default builder byte for byte), so it changes nothing
|
||||
observable and needs no activation.
|
||||
- **One visible consensus change per activation (house rule from the panel).** Turning the
|
||||
AERE Block-STM engine on for mainnet, if it ever changes an observable, is one coordinated
|
||||
activation with a runbook, exactly the discipline proven at block 14,050,000.
|
||||
- **The live engine, stated plainly (measured):** upstream Besu ships
|
||||
`DEFAULT_PARALLEL_TX_PROCESSING = true`, the fleet's start script does not disable it, and
|
||||
`AERE_BLOCKSTM` is unset on all nine validators. So the fleet already runs Besu's own
|
||||
parallel-capable block processor; on today's empty blocks it executes nothing in parallel, so
|
||||
no contention path is exercised in production. Setting `AERE_BLOCKSTM=1` would REPLACE that
|
||||
engine with ours, which is exactly why the determinism oracle and a real-block proof (which
|
||||
does not exist yet, and this document says so instead of implying it) must come first.
|
||||
|
||||
## The proof (Stage 4 gate)
|
||||
|
||||
@ -43,12 +48,21 @@ The reference executor `aere-research/parallel-executor` already carries both pa
|
||||
(`execute_block_sequential` as the oracle, `execute_block_parallel` as Block-STM) and a
|
||||
from-scratch keccak256 state root. The Stage 4 gate is its A/B mode run as a determinism oracle:
|
||||
|
||||
1. **Positive:** for a batch of transactions with real contention, serial and parallel produce the
|
||||
1. **Positive:** for SYNTHETIC batches with designed contention (not real chain-2800 blocks,
|
||||
which are empty today), serial and parallel produce the
|
||||
IDENTICAL state root, across repetitions and thread counts. Same root, or the gate is red.
|
||||
2. **Negative control (mandatory):** plant a divergence, a parallel path that drops one write, or
|
||||
a key-aliasing bug, and require the A/B gate to go red. A determinism oracle that has never
|
||||
disagreed is applause, not measurement.
|
||||
|
||||
## What the oracle's model does and does not cover
|
||||
|
||||
The reference executor models accounts, storage writes and a keccak state root. It does NOT
|
||||
model gas accounting, receipts, or the full EVM; those live in the real engines and are covered
|
||||
by the cross-client checks, not by this oracle. And the oracle runs on synthetic batches: the
|
||||
proof that parallel execution reproduces REAL chain-2800 blocks does not exist yet and is held
|
||||
open as a CRITIC finding in the registry (D-184) rather than implied here.
|
||||
|
||||
## What Stage 4 does NOT claim
|
||||
|
||||
- It does not claim a throughput number. 8-10x is proven CAPACITY on synthetic contended
|
||||
@ -65,3 +79,15 @@ Contract written 2026-08-15. The determinism oracle runs from the existing Rust
|
||||
run and its negative control are recorded in `stage4-determinism-run.md` beside this file once the
|
||||
toolchain build completes. Until that run is recorded, Stage 4 is specified and NOT yet proven,
|
||||
and this sentence says so rather than implying otherwise.
|
||||
|
||||
---
|
||||
|
||||
## Stage 5 note (window narrowing): specified, blocked on a live prover
|
||||
|
||||
Stage 5 narrows the proof window as the cost curve from Stage 2 allows. Measured 2026-08-15:
|
||||
the claim-chain detector's lag is dominated by the safety margin behind the tip (about 8 blocks),
|
||||
not by proving cost, because there is no SP1 prover producing timed proofs on this machine, and
|
||||
running MODE=prove is never done on aere-infra. So the cost curve that Stage 5 would narrow
|
||||
against does not exist yet to be measured. Stage 5 is specified and honestly NOT measurable until
|
||||
a prover produces windowed proofs with recorded wall-time. Stating this rather than publishing a
|
||||
lag number that measures the ruler and not the proving cost, which is the D-150 mistake.
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
*
|
||||
* "Post-quantum" is not one algorithm frozen into the protocol. A chain that means to outlast the
|
||||
* cryptography it ships must be able to add a scheme and retire another without a hard fork. AERE
|
||||
* puts that in a governed on-chain registry, AereCryptoRegistry at
|
||||
* puts that in an owner-controlled on-chain registry (the owner is a single-key account today, stated plainly rather than dressed as governance), AereCryptoRegistry at
|
||||
* 0xaE6fC596bb3eCcbf5c5D02D67B0Ef065b3Afbaa5
|
||||
* which maps each registered algorithm to the precompile that verifies it, its parameters, and a
|
||||
* status. This tool asks the live chain to prove three things:
|
||||
|
||||
@ -103,7 +103,7 @@ const FIELD_BY_NAME = new Map(MI_FIELDS.map((f) => [f.name, f]));
|
||||
|
||||
// ---- read-only JSON-RPC over the Node built-ins, no dependencies -------------------------------
|
||||
|
||||
const ALLOWED_METHODS = new Set(['eth_chainId', 'eth_blockNumber', 'eth_getBlockByNumber']);
|
||||
const ALLOWED_METHODS = new Set(['eth_chainId', 'eth_blockNumber', 'eth_getBlockByNumber', 'web3_clientVersion']);
|
||||
|
||||
function rpc(endpoint, method, params, tries = 4) {
|
||||
if (!ALLOWED_METHODS.has(method)) {
|
||||
@ -335,7 +335,11 @@ async function main() {
|
||||
honesty: 'A matching header root served over RPC proves both endpoints serve the same bytes; '
|
||||
+ 'the load-bearing fact is that Nethermind validates on processing and rejects on '
|
||||
+ 'disagreement. Consensus is classical secp256k1 ECDSA QBFT plus Falcon; MI is execution '
|
||||
+ 'only and this is not a post-quantum-consensus claim. Not a benchmark.',
|
||||
+ 'only and this is not a post-quantum-consensus claim. Not a benchmark. Both endpoints are '
|
||||
+ 'operated by the same party (the trust root does not move; what is removed is the class '
|
||||
+ 'of lies needing only one client implementation). State older than the ~512-block RPC '
|
||||
+ 'state window is not probed. Engine identity of each endpoint is recorded below.',
|
||||
engines: null,
|
||||
verdict: null,
|
||||
};
|
||||
|
||||
@ -345,6 +349,30 @@ async function main() {
|
||||
console.log(` Nethermind: ${NETH_RPC}`);
|
||||
console.log(` mode: ${report.mode}${INJECT ? ` (AERE_MI_INJECT=${INJECT})` : ''}`);
|
||||
|
||||
// endpoint-identity gate: one endpoint agreeing with itself measures nothing
|
||||
if (BESU_RPC.replace(/\/+$/, '') === NETH_RPC.replace(/\/+$/, '')) {
|
||||
report.verdict = 'NOT MEASURED: both endpoints are the same URL; agreement of an endpoint with itself is not a measurement';
|
||||
console.log('RESULT: ' + report.verdict);
|
||||
return finish(report, 2);
|
||||
}
|
||||
|
||||
// engine identity, recorded so "who answered" travels with every report
|
||||
try {
|
||||
const [ebesu, eneth] = await Promise.all([
|
||||
rpc(BESU_RPC, 'web3_clientVersion', []), rpc(NETH_RPC, 'web3_clientVersion', [])]);
|
||||
report.engines = { besu: ebesu, nethermind: eneth };
|
||||
console.log(' engines: ' + ebesu + ' | ' + eneth);
|
||||
if (String(ebesu).toLowerCase().split('/')[0] === String(eneth).toLowerCase().split('/')[0]) {
|
||||
console.log(' WARNING: both endpoints report the SAME engine family; the cross-client claim does not hold for this run');
|
||||
}
|
||||
} catch (e) { report.engines = { error: String(e.message) }; }
|
||||
|
||||
// NOT MEASURED, printed on every run (the contract's non-claims, stated by the tool itself):
|
||||
console.log(' NOT MEASURED by this harness: post-quantum consensus; independent derivation');
|
||||
console.log(' (proven only via the follower validate-on-processing behavior); throughput or');
|
||||
console.log(' latency; who operates the endpoints (same party today); state older than the');
|
||||
console.log(' ~512-block RPC window; gas accounting beyond the gasUsed commitment.');
|
||||
|
||||
// chain-id gate on both endpoints
|
||||
const [besuChain, nethChain] = await Promise.all([chainIdOf(BESU_RPC), chainIdOf(NETH_RPC)]);
|
||||
report.chainId = { besu: besuChain, nethermind: nethChain };
|
||||
@ -458,7 +486,10 @@ async function main() {
|
||||
report.verdict = `AGREE: Besu and Nethermind committed identical MI fields ` +
|
||||
`(stateRoot, receiptsRoot, transactionsRoot, logsBloom, gasUsed, hash, parentHash) in BOTH ` +
|
||||
`directions for all ${report.blocksCovered} covered blocks, and the pre-state chain links on ` +
|
||||
`both clients. Two independent execution paths derived the same post-state.`;
|
||||
`both clients. What this proves: both endpoints serve identical canonical MI commitments ` +
|
||||
`(the same bytes) for every covered block. Independent derivation is NOT proven by this ` +
|
||||
`run alone; it rests on the follower's validate-on-processing behavior, stated in the ` +
|
||||
`honesty field, and on the recorded engine identities.`;
|
||||
console.log('RESULT: AGREE across ' + report.blocksCovered + ' blocks (both directions, 0 divergences).');
|
||||
finish(report, 0);
|
||||
} else {
|
||||
|
||||
@ -14,7 +14,9 @@ oracle. Both runs below were executed on this machine (WSL, Rust release build o
|
||||
|
||||
Across the harness profiles (mixed-moderate and others), seeds, and thread counts (4, 8, 16),
|
||||
the state root produced by optimistic parallel Block-STM is byte-identical to the state root the
|
||||
sequential oracle produces for the same block and pre-state. Zero mismatches.
|
||||
sequential oracle produces for the same synthetic batch and pre-state. Zero mismatches. The
|
||||
batches are synthetic with designed contention; chain-2800 blocks are empty today, so a
|
||||
real-block replay under contention does not exist yet for any engine, and that is stated, not hidden.
|
||||
|
||||
## Negative control: disable validation, and the oracle goes red
|
||||
|
||||
@ -39,7 +41,7 @@ the harness catches it on every profile. The source was restored immediately aft
|
||||
|
||||
PROVES: the determinism oracle is load-bearing. A green from it means parallel and serial agree,
|
||||
because the same oracle demonstrably goes red the moment the safety mechanism that guarantees
|
||||
agreement is removed. This is the D-150 discipline applied to parallel execution: the failure
|
||||
agreement is removed. This is the negative-control discipline (a gate that has never failed cannot be believed) applied to parallel execution: the failure
|
||||
mode of concern (silent state divergence under contention) is exactly the one the negative control
|
||||
plants and the oracle catches.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user