From 1fba9df623033f6b3f3d8b6c118529018beb29bd Mon Sep 17 00:00:00 2001 From: Aere Network Date: Sat, 12 Sep 2026 01:51:12 +0300 Subject: [PATCH] anchor/README: the six-of-nine quorum sentence is dated now that the set is ten; RUN-A-NODE: what the emergency-ceiling ERROR stream is and what a real refusal looks like --- RUN-A-NODE.md | 28 ++++++++++++++++++++++++++-- anchor/README.md | 25 ++++++++++++++++--------- run-node.sh | 5 ++++- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/RUN-A-NODE.md b/RUN-A-NODE.md index 9e2707b..faef9fd 100644 --- a/RUN-A-NODE.md +++ b/RUN-A-NODE.md @@ -267,8 +267,32 @@ instructs (`--Xaere-pq-anchor-min-seals-max`). It does not weaken the post-quant follower checks: every anchor must still carry a valid validator Falcon seal that verifies against the registry, and its digest must still bind the certificate under the block hash; only the seal-COUNT floor, which is a proposer-liveness property relative to the current set and not a -history-verification property, is relaxed to one. Real anchor blocks carry three to nine seals, so -all import cleanly. A validator, which starts into the full set and proposes, does not set this. +history-verification property, is relaxed to one. Real anchor blocks carry far more than one seal, so +all import cleanly: measured 2026-09-12 by our own second implementation walking the live chain, the +certificates carried 14, 16, 18 or 20 seals in total, which is seven to ten per half since the +certificate became hybrid on 2026-09-03. A validator, which starts into the full set and proposes, +does not set this. + +**What you will see in the log, and why it is not an incident.** With this ceiling set, the node +prints a red startup banner (`AERE-PQC-EMG-BANNER-01`, "starting with 1 POST-QUANTUM SAFETY +CONTROL lowered") and then one ERROR line **per anchor block**: + +``` +ERROR | PqEmergencyShoutRule | AERE PQC EMERGENCY [AERE-PQC-EMG-CEILING-01]: height N validated +WITH A LOWERED SEAL THRESHOLD. The schedule in force asks for K=... +``` + +That is the binary doing what we asked it to do: a safety control that has been lowered must be +impossible to forget, so it shouts on every use rather than once at startup. On a from-genesis sync +it is loud - measured on our own import run, 2,786 such lines in three megabytes of log. It is not a +chain fault and not a failed verification. + +What WOULD be a fault, and what you should watch for instead: an anchor **refused**. Those read +`IneligibleSeal`, `SealCountBelowThreshold`, or `AnchorDigestMismatch` and stop the import. If you +prefer a quiet log once you are past the early heights, restart the node without +`aere.pq.anchor.minSealsCeiling` after it is synced beyond block 13,034,000: by then the live +validator set is large enough for the scheduled threshold to arm, and the shouting stops because the +control is no longer lowered. This is the FOLLOWER subset, and the distinction is in the code under `anchor/`, not guessed. A validator additionally passes `aere.falcon.key` (the signing key), the `aere.falcon.attach*` and diff --git a/anchor/README.md b/anchor/README.md index 2b5939d..47e4ea7 100644 --- a/anchor/README.md +++ b/anchor/README.md @@ -20,9 +20,11 @@ should not be confused: 2. **The enforced minimum.** Since 2026-08-14 a node does not finalize an anchor block unless its certificate holds at least three valid Falcon-512 seals (f+1 of nine, the guarantee that at least one honest validator signed; eight or nine are carried in practice). Raised at block - 14,961,456 (August 21, 2026): the enforced minimum is now **six of nine, a full 2f+1 quorum**, - the same count of validators QBFT itself requires to agree on the block. The schedule step is - `aere.pq.anchorMinSeals=13014000:0,13034000:3,14961456:6`, uniform on all nine validators; the + 14,961,456 (August 21, 2026): the enforced minimum became **six**, which at that time was a full + 2f+1 quorum of the nine-validator set, the same count QBFT itself required to agree on the block. + **Since 2026-09-11 the set is ten and QBFT's quorum is seven, so the same six is above f+1 and + below the quorum.** The threshold did not move; the set did. The schedule step is + `aere.pq.anchorMinSeals=13014000:0,13034000:3,14961456:6`, uniform on all ten validators; the startup guard refuses any threshold above N - f = 7, the highest count reachable with the fault budget down. Blocks between anchors carry no Falcon seals and are finalized by ECDSA alone, so the post-quantum guarantee is a checkpoint about every 16 seconds, not a per-block quorum. @@ -282,18 +284,23 @@ sentence. Someone else has to do the verifying, which is why it is here. ## Terminology, used precisely -**A certificate at an anchor height is signed by a quorum of six of nine validators, since block -14,961,456 (August 21, 2026). It was f+1 before that, and this paragraph said so.** The distinction +**A certificate at an anchor height is signed by at least six validators, since block 14,961,456 +(August 21, 2026). It was f+1 before that, and this paragraph said so. Between that date and +2026-09-11 six WAS the 2f+1 quorum of a nine-validator set; since the tenth validator joined, the +quorum is seven and six is not one, so we do not call it a quorum.** The distinction is worth keeping in view rather than deleting, because it is the difference between two genuinely different claims. f+1 signatures guarantee only that at least one honest validator signed. A quorum -of 2f+1 is the same count QBFT itself requires to agree on the block, so from 14,961,456 the -post-quantum certificate at an anchor height is backed by as many validators as the block itself. +of 2f+1 is the same count QBFT itself requires to agree on the block. Between 14,961,456 and +2026-09-11 the post-quantum certificate at an anchor height was backed by as many validators as the +block itself; with ten validators it is backed by six of the seven the block needs, which is more +than f+1 and less than the block's own quorum. Raising it to seven is a deliberate decision with a +liveness cost, and it has not been taken. Two things follow, and both should be said rather than left to be discovered. The word "quorum" applies **only at anchor heights** - about every 32nd block; the blocks between them carry no Falcon seals at all and are finalized by ECDSA alone, so "a post-quantum quorum on every block" would be -false. And the higher threshold costs liveness margin: at K=6 of nine, three late validators are -enough to stall an anchor block, where K=3 tolerated six. That trade was made deliberately, and it +false. And the higher threshold costs liveness margin: at K=6 of ten, four late validators are +enough to stall an anchor block, where K=3 tolerated seven. That trade was made deliberately, and it is the reason the threshold is a configured schedule rather than a constant. Anyone counting will notice which of the two regimes a given height falls in, and they should. The diff --git a/run-node.sh b/run-node.sh index 5cb7a6b..0a34e2d 100644 --- a/run-node.sh +++ b/run-node.sh @@ -240,7 +240,10 @@ mkdir -p "$DATA_PATH" # valid validator Falcon seal that verifies against the registry, and its digest must still bind the # certificate under the block hash; only the seal-COUNT floor (a proposer-liveness property relative # to the current set, not a history-verification property) is relaxed to one. Real anchor blocks -# carry three to nine seals, so all import cleanly. A validator, which starts into the full set and +# carry far more than one seal (measured 2026-09-12 on the live chain: 14 to 20 in total, seven to ten +# per half since the certificate became hybrid), so all import cleanly. With the ceiling set the node +# shouts one ERROR per anchor by design (AERE-PQC-EMG-CEILING-01); RUN-A-NODE.md says what that is and +# what a real refusal looks like instead. A validator, which starts into the full set and # proposes, does not set this. ANCHOR_MIN_SEALS_CEILING="${AERE_ANCHOR_MIN_SEALS_CEILING:-1}" REG="$REG_DIR"