Skip to content

feat(mesh): arm MESH_ENVELOPE_V2_HEIGHT at 966_400 (H-11, #604) - #825

Merged
defenwycke merged 1 commit into
mainfrom
feat/604-arm-mesh-envelope-v2-at-966400
Sep 1, 2026
Merged

feat(mesh): arm MESH_ENVELOPE_V2_HEIGHT at 966_400 (H-11, #604)#825
defenwycke merged 1 commit into
mainfrom
feat/604-arm-mesh-envelope-v2-at-966400

Conversation

@defenwycke

Copy link
Copy Markdown
Contributor

Part of #604 (audit H-11). Rides v1.11.34 alongside #824.

The fixed order was completed, not shortened

MESH_ENVELOPE_V2_HEIGHT's docs specify an order that "cannot be shortened". Each step verified:

step evidence
1. Tolerance shipped; every node verifies both formats, emits v1 #740 (d829c32f8) is an ancestor of the deployed commit
2. All eight rolled and confirmed on the new binary v1.11.33 at bf3f822b5, checked per binary via --version (names the commit since #820), not by version string
3. Arming is a separate, observed change this PR. Observation: bad_signature / InvalidSignature = 0 across 6h on the rolled binary

Why 966_400 and not 966_000

Both gates ride v1.11.34. They are deliberately ~400 blocks (~2.7 days) apart so that if the mesh misbehaves in that window, the cause is attributable to one gate rather than two — the same reasoning that placed STRATUM_HANDSHAKE_PROOF_HEIGHT clear of its neighbours.

That matters more here than usual: this gate does not degrade, it partitions. A node left on an older binary rejects every mesh message from every upgraded peer, and the only way back is upgrading it.

The flipped test

v2_emission_gate_ships_dormant asserted u64::MAX. It is flipped, not deleted — it did its job holding the gate closed until the order above was genuinely done, and now pins the armed height so it still cannot move without review.

The mirror, and why it is guarded

ghost-consensus sits below ghost-pool and cannot import ADDRESS_PROOF_HEIGHT, so ADDRESS_PROOF_SEPARATION_REFERENCE mirrors it. A duplicated consensus height is precisely the thing that drifts, so ghost-pool asserts it from the side that owns the original.

Controls

Control Result
Both gates at the same height separation test fails
Gates only 100 blocks apart separation test fails
Drift the mirror to 965_000 the_mirror_in_ghost_consensus_matches fails

The separation assertions read through std::hint::black_box: comparing two consts folds at compile time and clippy flags it as assertions_on_constants — correctly, since a tautology that cannot fail is not a check. CI runs -D warnings, so this would otherwise have gone red.

cargo test -p ghost-consensus --lib: 380 passed. -p ghost-pool --lib: 496 passed. Clippy and fmt clean.

Roll requirement

⛔ All eight must be on v1.11.34 before 966_400. Chain is ~965,081, so roughly 8–9 days — comfortable, but this is the gate where "we'll catch the last node later" is not an option.

https://claude.ai/code/session_01Td1vvfowptTTnu88qG2iym

At and above this height a node SIGNS mesh envelopes with v2, which binds the
timestamp and message type into the signature and lets per-sender replay floors
persist restarts.

The constant's docs set a fixed order that "cannot be shortened". It was
completed, not shortened:

1. The tolerance shipped in #740 (`d829c32f8`), an ancestor of the deployed
   commit — so every node already VERIFIES both formats while EMITTING v1.
2. All eight rolled to v1.11.33 at `bf3f822b5`, confirmed per binary via
   `--version` (which names the commit since #820), not by version string.
3. This is that separate, observed change. Observation before arming:
   `bad_signature` / `InvalidSignature` were 0 across 6 hours on the new
   binary.

966_400 is ~400 blocks (~2.7 days) AFTER ADDRESS_PROOF_HEIGHT's 966_000 rather
than sharing it. Both ride v1.11.34, so separated heights are what let a mesh
problem in that window be attributed to one gate instead of two — the same
reasoning that placed STRATUM_HANDSHAKE_PROOF_HEIGHT clear of its neighbours.
This gate's failure mode is a partition, not degradation, so attribution is not
a nicety.

`v2_emission_gate_ships_dormant` is FLIPPED rather than deleted: it held the
gate closed until the order above was actually done, and it now pins the armed
height so it still cannot move without review.

`ADDRESS_PROOF_SEPARATION_REFERENCE` mirrors ghost-pool's constant because
ghost-consensus sits below it in the dependency graph and cannot import it. A
duplicated consensus height is exactly what drifts, so ghost-pool asserts the
mirror from the side that owns the original
(`the_mirror_in_ghost_consensus_matches`).

Controls: both gates at one height fails the separation test; 100 blocks apart
also fails it; drifting the mirror fails the ghost-pool guard. The separation
assertions read through `std::hint::black_box` — comparing two `const`s folds
at compile time, which clippy flags as `assertions_on_constants`, and it is
right to: a tautology that cannot fail is not a check.

⛔ The roll must reach ALL EIGHT before 966_400. A node left behind rejects
every mesh message from every upgraded peer, and the only way back is to
upgrade it.

Claude-Session: https://claude.ai/code/session_01Td1vvfowptTTnu88qG2iym
@defenwycke
defenwycke merged commit f6c63fa into main Sep 1, 2026
12 checks passed
defenwycke added a commit that referenced this pull request Sep 1, 2026
The arming release. Two consensus-visible gates fire from this build, and both
require every node to be running it beforehand:

  * ADDRESS_PROOF_HEIGHT   966_000  (#824, H-7, #605)
  * MESH_ENVELOPE_V2_HEIGHT 966_400  (#825, H-11, #604)

Deliberately ~400 blocks apart rather than sharing a height, so a mesh problem
in that window is attributable to one gate rather than two. MESH_ENVELOPE_V2 is
the reason that matters: it does not degrade, it PARTITIONS — a node left on an
older binary rejects every mesh message from every upgraded peer, and the only
way back is upgrading it.

⛔ ALL EIGHT must carry this before 966_400. At 965,085 that is ~8 days.

Also carries #826: the deploy now prunes stale `$BINARY.bak.*` to the two most
recent instead of accumulating them forever. Measured before the fix, after the
v1.11.33 roll: vm1 39 files / 1.4 GB, vm4 38 / 765 MB, vm5 33 / 712 MB.

Both lockfiles synced; `tests/integration-sv2`, `crates/stratum-apps` and
`prototypes/ghast-bench` carry no workspace version and still resolve under
`--locked`. Checked with `grep -F`, since an unescaped `1.11.33` matches digits
inside dependency checksums.

Claude-Session: https://claude.ai/code/session_01Td1vvfowptTTnu88qG2iym
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant