34 KiB
Run an AERE node, operator runbook
This is the runbook for standing up an independent Hyperledger Besu node on the AERE Network, chain ID 2800, and applying to become one of the first non-Foundation validators.
Read it end to end before you start. It is written for someone who has run a node before and is comfortable with Docker and a Linux server.
Corrected 2026-10-20. Until this date this runbook said that a validator's post-quantum keys are "issued at admission", listed a property (
aere.falcon.genesis) that no running validator carries, and did not name the SLH-DSA key at all. All three were wrong. Every key of a validator is generated by its operator, on the operator's own machine, with the tools in thevalidator/directory of theaere-noderepository; nothing private ever leaves that machine. Section 6 describes admission as it now works, step by step, and section 3b the clock requirement.
What AERE actually is today (read this first)
AERE runs Hyperledger Besu with QBFT consensus and sub-second blocks (0.60 s on average over the 100,000 blocks to 2026-11-03). Consensus is a permissioned proof-of-authority BFT set, not proof-of-work and not on-chain proof-of-stake.
- The active validator set is 10 validators as read from the chain at 2026-09-29 07:55 UTC, all Foundation-operated; f = 3, quorum 7-of-10 (as read from the chain at 2026-09-29 07:55 UTC). Read the live set with
qbft_getValidatorsByBlockNumberand believe the chain over this line. - QBFT tolerates
f = floor((n - 1) / 3)faulty validators. At n = 10, f = 3: the network tolerates three simultaneous Byzantine faults (commit quorum 7 of 10). It is honest to say the set is small and single-operator today. - The public path is 10 to 21 validators. This program exists specifically to admit the first independent (non-Foundation) operators.
- Admission is a governance vote of the existing validator set, not an automatic or permissionless process. There is no staking, no bond, and no slashing. A validator that misbehaves or goes down for a prolonged period is removed by the same governance vote that admitted it. Accountability is social and on-chain, not economic.
If you are looking for a stake-and-earn validator with slashing and unbonding, that is not how AERE works. Do not trust older pages that describe self-staking, slashing, unbonding periods, or APY tiers; they predate the current QBFT design.
What running this gives you
A full, syncing node on chain 2800, built from the same published patch series the validators run. A validator differs from a following node in four things, all of them yours to hold and none of them issued by anyone else:
- its node key (
data/key), which is also its consensus key: the address voted into the set; - a Falcon-512 key and an SLH-DSA-SHA2-128s key, generated on your machine (section 3);
- a row in a post-quantum registry epoch that carries those public keys, signed by them (section 6);
- the validator-only properties: the paths of the two key files and the heights from which the node emits post-quantum seals (section 7b).
So the sequence is:
- Stand up a following node with this runbook (or with
run-node.shinaere-node), and keep it healthy. The Foundation observes it from outside for fourteen days before a vote is proposed. - Generate your keys and write your candidacy file on your own machine (sections 3 and 6).
- The Foundation verifies the candidacy independently and puts your row into a new registry epoch, which every node, yours included, loads before your admission.
- Your node restarts as a validator and connects to every validator; then the existing validators vote. After the vote your node proposes and seals blocks. No reinstall, no migration.
1. Prerequisites
Software
- A Linux host (the live nodes run Docker on Linux).
- Docker and the Docker Compose plugin, or a build from source (
run-node.shinaere-nodeneeds git and a JDK 21). The key tools of section 3 need the same JDK 21 and a build from the published patch series, which./run-node.sh --no-startproduces.
Hardware
There is no published minimum-hardware spec sheet for AERE, so treat the following as guidance, not a documented requirement. The Foundation confirms final sizing on application.
- The node is configured with a 4 GB JVM heap (
-Xmx4g), matching the live validators. Give the host meaningful headroom above that. A reasonable starting point is 4 vCPU, 8 GB RAM, NVMe SSD, but confirm on application. - A CPU with SHA hardware instructions (x86 SHA-NI, or the ARMv8 SHA2 extension). A validator signs an SLH-DSA-SHA2-128s seal on the consensus thread at the parent of every anchor block; measured on chain 2800 that costs 0.3 to 0.7 s per signature with the JDK digest, which uses those instructions (AIP-22, table of constants). A slower signature delays the anchor round.
- Local NVMe, not network-attached block storage. The node writes its post-quantum seal store on the consensus thread; on a network volume every such write adds milliseconds to each slot.
- Storage uses Besu Bonsai format. At sub-second blocks the trie-log data grows faster than on a slow chain, so provision generous, growable NVMe disk and monitor free space over time. Block headers are most of what a node stores.
Network / firewall
- 30303/tcp and 30303/udp: open to the internet. This is P2P. Peers must be able to reach you.
- 8545 (JSON-RPC): keep private. The compose binds it to
127.0.0.1on the host. Do not expose it to the public internet without an authenticating proxy in front. - 9545 (metrics): keep private, localhost only.
RPC policy for a validator. A validator's JSON-RPC stays on localhost, always: it serves the
qbft_* methods, including qbft_proposeValidatorVote, and a public endpoint on a consensus node is a
denial-of-service surface on the very node that has to answer within a slot. If you want to offer
public reads, run a separate following node for them and keep the validator private.
2. Get the config bundle
Everything you need to start is in this directory
(https://aere.network/validator/):
| File | What it is | Source |
|---|---|---|
docker-compose.yml |
The node service, real QBFT flags | Published here |
config.toml |
Same config for bare-metal / from-source runs | Published here |
genesis.json |
Chain 2800 genesis (no private keys) | Published here |
static-nodes.json |
Current peer / bootnode enode list | Provided by the Foundation on application |
| Bootnode enode string | For --bootnodes |
Provided by the Foundation on application |
| Canonical genesis hash | To verify your genesis | Provided by the Foundation on application |
Download the published files into a working directory, for example
/opt/aere:
mkdir -p /opt/aere && cd /opt/aere
curl -fSLO https://aere.network/validator/docker-compose.yml
curl -fSLO https://aere.network/validator/config.toml
curl -fSLO https://aere.network/validator/genesis.json
The post-quantum registry files (added 2026-09-12)
docker-compose.yml mounts two directories that the steps above did not create, and a node
started without them cannot judge an anchor certificate at all. Fetch them:
mkdir -p /opt/aere/aere-pqc /opt/aere/pq && cd /opt/aere/aere-pqc
curl -fSLO https://aere.network/pq/manifests/manifest-13014000.json
curl -fSLO https://aere.network/pq/manifests/manifest-18082816.json
curl -fSLO https://aere.network/pq/manifests/registru-2800-v2-13600000.properties
cd /opt/aere/pq
curl -fSLO https://aere.network/pq/manifests/hibrid-10.properties
Check what you downloaded, because a 200 is not proof of a file. Until 2026-09-12 two of
these paths were not published, and the site answered every one of them with HTTP 200 and the
51 KB HTML page of the web app. curl -fSLO succeeds on that: exit code 0, a file on disk, the
wrong bytes. So look at the first character of each file, and refuse anything that starts with
<:
for f in /opt/aere/aere-pqc/* /opt/aere/pq/*; do
head -c 1 "$f" | grep -q '<' && echo "NOT A REGISTRY FILE: $f" || echo "ok: $f"
done
The same four files ship inside the aere-node package, with a SHA256SUMS beside them, if you
prefer to take them from there and compare.
Added 2026-10-07: a fifth file, the stage-3 registry epoch. Since block 20,836,228 (AIP-22 stage 3,
active on chain 2800 since 2026-09-30) the header carries post-quantum validator identities, and
docker-compose.yml now passes aere.pq.identityBlock=20836228 with aere.pq.registryV3=/opt/aere-pqc/epoca-v3-2800-20836228.json.
Until 2026-10-07 this file did not list that option at all: a validator started from it would have stopped at
block 20,836,228. The epoch file is the one published as registry-v3-20836228.json; save it under the name
the option expects:
cd /opt/aere/aere-pqc
curl -fSL -o epoca-v3-2800-20836228.json https://aere.network/pq/manifests/registry-v3-20836228.json
sha256sum epoca-v3-2800-20836228.json
Expected: 0212d8ff9e857f1c756b0004929e9ad4c7988341af4837d947e7b5263fb8c581 (194,122 bytes; measured on a
running validator of the fleet and on the served file on 2026-10-07). The option aere.pq.registryV3.hashes
pins the epoch's identity hash, so a node given the wrong file refuses to start rather than following the
chain with a wrong registry; the first-character check above applies to this file too.
Every later epoch is added, never swapped. When an epoch that admits a new validator is announced, the
index at https://aere.network/pq/manifests/index.json lists it (registry-v3-<height>.json, with its
sha256 and registry hash), and every node appends the file to aere.pq.registryV3 and its
<height>:<hash> pin to aere.pq.registryV3.hashes, keeping the earlier ones. The announcement gives the
exact values and the height by which every node must carry them.
Verify the genesis
The genesis.json published here is the chain-2800 genesis. It contains no
private keys. The comment fields inside alloc are human labels that Besu
ignores, so they do not affect the genesis block hash.
After your node's first start, confirm your node computed the same genesis hash the Foundation gives you on application:
curl -s -X POST http://127.0.0.1:8545 \
-H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x0",false],"id":1}' \
| grep -o '"hash":"0x[0-9a-f]*"'
The value must equal the canonical chain-2800 genesis hash provided by the Foundation on application. If it does not match, stop and contact the Foundation; do not keep running against a divergent genesis.
3. Your keys: generated on your machine, never sent anywhere
A validator holds three private keys. You generate all three; the Foundation never sees, holds or issues any of them.
The node key, data/key (secp256k1). Besu creates it the first time the node starts. It is your
node's P2P identity and your consensus key: the address derived from it is the one voted into the
set, and Besu sends consensus messages only to peers whose node-key address is in the set. A validator
whose node key is not its validator key receives no consensus message at all. So never start the node
with a node key from another place than the data directory you register.
Create the data directory, then start the node once so Besu writes the key:
cd /opt/aere
mkdir -p data
docker compose up -d
Read your node's public info (enode and address) once it is up:
curl -s -X POST http://127.0.0.1:8545 \
-H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"net_enode","params":[],"id":1}'
The post-quantum keys (Falcon-512 and SLH-DSA-SHA2-128s). They are generated by
PqRegistryV3Tool keygen, a tool inside your own build of the published patch series (patch 0008),
through the kit in the aere-node repository:
git clone https://git.aere.network/aere-network/aere-node && cd aere-node
./run-node.sh --no-start # builds the Aere fork from the published patches (JDK 21)
validator/validator-keys.sh --params admission-params.json --data-path <your node's data directory>
admission-params.json is a small public file the Foundation sends you (the chain id, the height and
size of the registry epoch that will carry your row, and your row index). The script refuses unless the
build comes from the bundle's patch series, writes the two key files owner-only (mode 600) into an
owner-only directory (default ~/.aere-validator/keys, outside the repository on purpose), never
overwrites an existing key, prints only public keys and your post-quantum id, and checks its own output
for any private value before it ends.
Protect your keys
-
data/keyand the two post-quantum key files are your validator identity. Back them up together, somewhere secret and offline. Anyone with them can sign as your validator; losing them means a new admission. -
Never
rm -rf data/. That destroys the node key and, if you were already a validator, forces re-admission. To wipe chain data while keeping the key:find /opt/aere/data -mindepth 1 ! -name key -exec rm -rf {} +
3b. The clock (added 2026-10-20)
Chain 2800 rejects a block header whose timestamp is more than one second ahead of the node's own
clock (QBFT's TimestampBoundedByFutureParameter(1)), and at about 0.60 s per block that rule bites at every
head:
- a node whose clock is behind rejects the head blocks it is sent and disconnects the peer with
BREACH_OF_PROTOCOL, which reads like an attack and is a clock; - a validator whose clock is ahead proposes blocks the others reject, and loses its slot.
What to do: run NTP or chrony against good sources, and measure against the chain head, not against a
flag: a host that reports NTPSynchronized=yes was measured one full second behind on 2026-09-12.
The kit measures it for you, in the same terms the Foundation measures its own fleet (head timestamp
minus local clock, at most 1 s behind and at most 2 s ahead):
validator/validator-candidacy.sh --clock-only --params admission-params.json --enode-host <your host>
On the day of the vote the Foundation asks for exactly this report, fresh (at most six hours old). It is signed by your node key and holds nothing private.
4. Add peers and finish syncing
Until you have the Foundation's peer list, the node has nothing to connect to. On application you receive:
- a bootnode enode string, and
- a
static-nodes.jsonfile (belt-and-braces; Besu reads it from inside the data directory).
Wire them in:
-
Put
static-nodes.jsonnext to the compose file. It is bind-mounted todata/static-nodes.jsonby the compose (uncomment that volume line if you commented it out). -
Replace
BOOTNODE_ENODE_PROVIDED_ON_APPLICATIONindocker-compose.yml(orconfig.toml) with the real enode string. -
Restart:
docker compose up -d
Watch it find peers and import blocks:
docker compose logs -f aere-node
The two traps that stop a fresh node cold
- The 5-peer wait. Besu will not begin BFT block import until it has enough
peers, and it defaults to needing 5. A small network never reaches 5 and
the node waits forever, never importing block 1. The compose already sets
--sync-min-peers=1to fix this. Keep it. - Gas price. AERE nodes run
--min-gas-price=0: the protocol's base-fee floor (from block 10,141,734) sets the price of a transaction, not the node. Do not set a nonzero min gas price of your own; you would drop normal AERE transactions. The compose already sets it to 0.
You do not need the public RPC fee-shim proxy. That proxy exists only for the public wallet-facing RPC endpoint; a syncing full node talks to the chain directly.
5. Confirm the node is healthy
# Current block height (should be climbing, then tracking the public head):
curl -s -X POST http://127.0.0.1:8545 -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# Peer count (should be >= 1, ideally several):
curl -s -X POST http://127.0.0.1:8545 -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}'
# The current QBFT validator set (you will NOT be in it yet):
curl -s -X POST http://127.0.0.1:8545 -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"qbft_getValidatorsByBlockNumber","params":["latest"],"id":1}'
Compare your height against the public head at https://aere.network/validators
(the live validator-state dashboard). When your eth_blockNumber is tracking the
public head and you have steady peers, your node is ready to apply.
6. Admission (the governance vote)
This is the honest part: admission is a decision of the existing validators, not a transaction you can send yourself. Here is the whole path, in order.
-
Observation. Your following node runs for fourteen days while the Foundation measures it from outside (that it follows the head, with the same block hashes as the fleet). You tell the Foundation the read endpoint it may use for that.
-
Admission parameters. The Foundation sends
admission-params.json: chain id 2800, the height of the registry epoch that will carry your row, its size, and your row index. Public data. -
Your keys and your candidacy, on your machine.
validator/validator-keys.sh(section 3), then:validator/validator-candidacy.sh --params admission-params.json --enode-host <your public P2P host or IP> \ --data-path <your node's data directory>With your node running, the script checks that the node runs with exactly the key in your data directory (the enode it reports must match), measures your clock against the chain head (section 3b), writes your registry row with
PqRegistryV3Tool rowfrom your build (your post-quantum id, both public keys, a proof of possession by each, the link signed by your node key, and your node key's address as the transport address), signs the candidacy message with all three keys, verifies its own signatures, and checks that no private value appears in anything it wrote. Send the resultingaere-candidacy.json. It holds public data only. -
Independent verification. The Foundation verifies the candidacy with an implementation that shares no code with the client (every signature, the proofs of possession, that your id is derived from your Falcon key, that the enode's key is the row's address, that the date and the clock are fresh and in margin), and refuses it otherwise, with the reason.
-
The new registry epoch. The existing validators re-sign their own rows for the new epoch (the same keys; a proof of possession is bound to the epoch's height and size), your row is added as the last one, and the epoch is checked by two independent loaders. The epoch is published at
https://aere.network/pq/manifests/in the same hour it takes effect, and every node, yours included, appends its file and pin (section 2). -
Your node becomes a validator. You restart it with the validator properties of section 7b and the new epoch, connected to every validator (with the peer list the Foundation gives you, as in section 4), and you send a fresh clock report (section 3b).
-
The vote. A majority of the current validators propose your post-quantum id with
qbft_proposeValidatorVote(<your id>, true). Since block 20,836,228 (AIP-22 stage 3) the set and the votes are on post-quantum ids, and a vote for an id that has no row in the registry in force is invalid: that is why the epoch comes first. The vote is proposed only after every check of the steps above passes, including that your node is connected to all validators. -
After the vote. Your already-running, already-synced node detects that it is now in the set and begins proposing and sealing blocks. The Foundation checks, from the chain and from its own nodes, that you propose in turn, that your post-quantum commit seal is heard and verified by every node, that your index appears in the anchor certificates, and that the chain's rhythm did not change.
The Foundation decides whether an admission grows the set or whether a Foundation validator steps out after you are in; for you the steps are the same.
Removal is the same mechanism in reverse:
qbft_proposeValidatorVote(<id>, false) by a majority. This is how a
misbehaving or long-offline validator is dropped. There is no slashing and no
stake to lose; the consequence is removal from the set.
You can always read the live set yourself with
qbft_getValidatorsByBlockNumber (see step 5), so admission and removal are
publicly verifiable on-chain.
The candidacy file
aere-candidacy.json (format aere-validator-candidacy/1) carries: chainId, bindHeight, count,
index, issued (UTC date), enode, address, id, row (the registry v3 row, AIP-22 section 3.2),
rowHash, proof and clock. The two signed messages, so that anyone can verify a candidacy without
our tools (integers big-endian, i32 two's complement, || concatenation):
candidacy = keccak256("AERE-CANDIDACY-1" || u64 chainId || u64 bindHeight || u32 count || u32 index
|| u32 len(issued) || issued || id (20 bytes) || rowHash (32 bytes))
clock = keccak256("AERE-CLOCK-1" || u64 chainId || u64 measuredAt || u64 headNumber || u32 samples
|| i32 dMin || i32 dMax)
proof.secp256k1 (65 bytes, r || s || v) must recover to the row's ecdsa.addr, which must equal its
transport address and the address of the enode's public key; proof.falcon-512 and
proof.slh-dsa-sha2-128s must verify under the row's two keys; clock.secp256k1 must recover to the
same address. dMin and dMax are the smallest and largest "head timestamp minus local clock" over the
samples; the margin is dMax <= 1 and dMin >= -2.
7. How validators are paid
Rewards are transparent and on-chain. Measured 2026-10-15: the beneficiary of
every block in a 40-block sample is the proposing validator's own identity address
(ten addresses, none with code), and blocks carry almost no transactions. The split
below is the design of the AereCoinbaseSplitterV2 contract
(0x8C1A48eFA57b66fEE743A00E3899c29ad3Fd27b4); block fees do not pass through it
today (its balance was 0 that day), so read it as a deployed mechanism, not a
present-tense flow. It does a fixed basis-points split:
- Burn: 3750 bps (37.5%) to the fee-burn vault.
- Sink: 1500 bps (15.0%) routed through AereSink (the sAERE flywheel).
- Rebate to the validator: the remainder, 47.5% at the defaults.
These are the current default splits. They are owner-adjustable within hard caps written into the contract (burn at most 5000 bps, sink at most 3000 bps), and any change to the sink destination is time-locked for 7 days. If the sink is unset, its share is added to the validator rebate instead. Everything is readable on-chain; nothing here is off-book.
There is no staking yield, because there is no staking. A delegation UI tied to the sAERE flywheel is on the roadmap but is not live today; do not assume any delegation mechanics until the Foundation announces them.
7b. If you are being admitted as a validator: the validator properties
Everything above gets you a following node, and that is the normal case until the vote. A
validator passes, through BESU_OPTS, the whole line of docker-compose.yml (it is derived from a
running validator of the fleet and carries the validators' own seal cap) plus the properties below.
The Foundation confirms the exact values when your admission is scheduled.
| property | what it is |
|---|---|
aere.falcon.key |
the path of YOUR Falcon-512 key file, written by validator-keys.sh |
aere.pq.hybrid.key.slh-dsa-sha2-128s |
the path of YOUR SLH-DSA-SHA2-128s key file, written by validator-keys.sh |
aere.pq.registryV3, aere.pq.registryV3.hashes |
every registry epoch and its pin, including the one that carries your row (section 2) |
aere.pq.hybrid.attachBlock, aere.pq.proposalPq.attachBlock, aere.pq.preparePq.attachBlock, aere.pq.roundChangePq.attachBlock |
the heights from which the node EMITS post-quantum seals; already in docker-compose.yml |
Two things a validator must NOT carry: aere.pq.anchor.minSealsCeiling (a node syncing from genesis
with run-node.sh sets it to 1 to start inside the small genesis set; a validator starts into the full
set and must judge anchors at the scheduled threshold), and a node key from anywhere else than its data
directory (section 3). From block 20,836,228 the key a node signs with, and the index it signs under, are
looked up in the registry epoch in force by the PUBLIC key, and the client refuses to start a validator
registered in an epoch whose row does not match the key it holds (AERE-PQC-KEY-NEXT-02).
One path not yet measured, stated so you do not lose an evening to it. A node that synced as a
follower and restarts as a validator passes the client's attach-height guard when it finds a recent
Falcon-sealed header; otherwise it refuses to start with AERE-PQC-CFG-UNSAFE-05, and the recovery
is aere.falcon.attachBlockAcknowledgePast=<attachBlock> for one restart. Both behaviours were measured
on 2026-08-12 on the fleet of that time; for a node joining after block 20,836,228 they have not been
measured yet (the Foundation measures them on its rehearsal network before the first admission). If you
hit that refusal, send the log line; do not work around it alone: an attachment height that disagrees
with the fleet is a liveness incident, not a local setting.
One more measured fact, because it decides how you schedule your upgrades. If your node is a validator and it is still on a build without a rule the fleet has armed, it does not fork and it does not accept anything wrong. But every time it is proposer at an anchor height, the upgraded majority rejects its block and the round is lost. Measured with two of seven nodes un-upgraded (2026-08): the chain head paused for about twenty seconds across a hundred blocks. Being behind costs the network rhythm, not safety.
7c. Post-quantum seals on consensus messages (live since September 2026)
Every 32nd block carries a post-quantum certificate under its hash. The blocks between anchors carry no certificate of their own; below block 25,080,000 their validity at import rested on the ECDSA commit quorum, and from it (AIP-22 stage 5) on the Falcon-512 seal of their proposer, so a fabricated segment stops at the next anchor: the depth measured below block 25,080,000 with classical keys was 31 consecutive blocks, and the bound derived from the anchor rule, for a node that requires a quorum of seals in the certificate, was 33 blocks below block 24,148,752 (32 plus the sealed-sibling exception) and is 32 from it, where that quorum must be of one round: the latest anchor and the 31 after it (SPEC.md 3.1; from block 25,080,000 such a segment takes the post-quantum key of one validator, not measured); for the published follower, with its ceiling at 1, the bound stays 33 against an adversary without a post-quantum key, and one leaked or misused post-quantum key of a validator makes the depth unbounded (SPEC.md 6.4).
Beyond the anchors, each of the four QBFT messages (proposal, prepare, commit, round-change) carries a Falcon-512 seal of its author, each under its own domain. On chain 2800 the nine Besu-derived validators refuse a message without a valid seal: COMMIT from block 17,250,000, PROPOSAL from 17,400,000, ROUND-CHANGE from 17,550,000 and PREPARE from 17,700,000. The tenth validator, which runs the second client, refuses a COMMIT without one from block 18,131,633 and applies the other three types since block 24,300,000 (AIP-22 stage 4, 2026-10-25). Each message has two switches, passed like the anchor properties:
| property | what it does |
|---|---|
aere.pq.<message>Pq.attachBlock |
height from which this node emits a seal on that message |
aere.pq.<message>Pq.forkBlock |
height from which this node refuses that message without a valid seal |
where <message> is one of prepare, proposal, roundChange (commit uses
aere.pq.commitPq.forkBlock).
Two things worth knowing, both measured:
- Emission and enforcement are separate on purpose. The fleet emitted for a while before anything refused. If they were one switch, the first node to start emitting would also start refusing, and that is a flag day.
- A mistyped value refuses to start, it does not quietly disarm. If you set one of these to something that is not a plain block height, the client stops with a configuration error: a node that boots disarmed because of a stray character looks exactly like a correctly configured one, right up to the day it matters.
What this asks of you as a validator: your post-quantum keys (Falcon-512, and SLH-DSA for the hybrid anchor certificate), generated by you on your machine and carried in the registry epoch that admits you, and the same emission and enforcement heights as the fleet, which the Foundation gives you. A validator whose seals are refused does not fork and does not accept anything wrong: it loses its turn as proposer, and the chain continues without it as long as a quorum of the others can seal.
What we claim, and what we do not. Since block 25,080,000 (AIP-22 stage 5) headers no longer carry ECDSA commit seals and, since block 24,300,000 (AIP-22 stage 4), every vote counts only with the verified post-quantum seal of its author, and a commit still carries the ECDSA commit seal of its validator as an additional check, which we call post-quantum consensus. We do not claim a post-quantum transport (the peer-to-peer transport is still authenticated by secp256k1), the ten validators are run by one operator, and no third party has audited it yet. What you can verify yourself, without taking our word for it, is the anchor certificate at every 32nd block, with the public verifier.
8. Day-two operations
- Updates: the live network runs a pinned build of the Aere fork of Besu,
not stock upstream. Every new fleet build is published as a patch in
aere-nodebefore it is required, with the height from which it is needed; rebuild with./run-node.sh --no-start --rebuildand restart before that height. Do not move to:lateston your own. As of 2026-10-28, the published patch series (0001 to 0010) does not yet include the decision journal that the Foundation's validators run together with the decided-head rule. - Restarts: tell the Foundation before a planned restart. A restarted validator starts with an empty
post-quantum seal store, and two validator restarts within minutes of each other can stall an anchor
round. A node restarting with its
data/intact keeps its identity and does not re-hit the 5-peer trap. - Emergencies: the emergency settings of the anchor rules are applied uniformly to every node, never to one; when the Foundation announces one, it applies to your node too, at the same time.
- Backups: back up
data/keyand the two post-quantum key files. Those are the irreplaceable files. - Monitoring: scrape Prometheus metrics on
127.0.0.1:9545. Track block height versus the public head, peer count, disk free space (Bonsai growth) and the clock against the chain head (section 3b). - Disk: watch free space. At sub-second blocks storage grows steadily; plan for a growable NVMe volume.
Quick reference
| Item | Value |
|---|---|
| Network name | AERE Network |
| Chain ID / network ID | 2800 |
| Consensus | Hyperledger Besu, QBFT |
| Block time | sub-second since block 2,137,652 (0.60 s average over the 100,000 blocks to 2026-11-03) |
| Gas price | min-gas-price 0 on the node; the protocol base-fee floor sets the price |
| Storage format | Bonsai |
| Client | Aere fork of Besu, built from the public patch series of the aere-node bundle (0001 to 0010 as of 2026-10-14) on the named upstream commit. Stock upstream cannot follow chain 2800 past block 9,189,161. See RUN-A-NODE.md in aere-node. |
| Required JVM flags | the full BESU_OPTS line in docker-compose.yml (base-fee floor, post-quantum anchor, registry epochs, post-quantum identities, post-quantum transactions); a node missing one stops at the first height that needs it |
| Validator keys | node key data/key (also the consensus key), Falcon-512 and SLH-DSA-SHA2-128s; all generated by the operator (validator/validator-keys.sh in aere-node) |
| Candidacy | validator/validator-candidacy.sh in aere-node: registry row, enode, proof of possession, signed clock report |
| Clock | at most 1 s behind and 2 s ahead of the chain head, measured against the head |
| JVM heap | -Xmx4g |
| P2P port | 30303 tcp + udp (public) |
| RPC port | 8545 (keep private; on a validator, localhost only) |
| Metrics port | 9545 (keep private) |
| Active validators today | 10 (Foundation), as read from the chain on 2026-10-15 |
| Fault tolerance | f = 3, quorum 7-of-10 (as read from the chain at 2026-09-29 07:55 UTC) |
| Public path | 10 to 21 |
| Staking / bond / slashing | None |
| Admission | Governance vote of existing validators, after the registry epoch that carries your row |
| Reward contract | AereCoinbaseSplitterV2 0x8C1A48eFA57b66fEE743A00E3899c29ad3Fd27b4 |
| Genesis hash | Provided by the Foundation on application |
| Bootnode enode | Provided by the Foundation on application |
static-nodes.json |
Provided by the Foundation on application |
Live consensus explainer: https://aere.network/consensus
Live validator state: https://aere.network/validators