Skip to content

Release v0.20.0 - #27

Merged
jdogresorg merged 22 commits into
masterfrom
release/v0.20.0
Sep 18, 2026
Merged

jdogresorg merged 22 commits into
masterfrom
release/v0.20.0

Conversation

@jdogresorg

@jdogresorg jdogresorg commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Title: Release v0.20.0

Summary

Changed

  • Mirrored rows carry per-chain admission heights so a future-dated block no longer stalls indexer processing.
  • carrier_logic_pin_ops --move can re-pin changed carrier logic and record path and hash transitions atomically.
  • Governance activation reads now use the shared registry.
  • Consensus gates, frozen-set derivation, and identity pins follow the consolidated registry layout.

Fixed

  • BTC-sourced bridge transfers cannot be anchored below the source block that mined their lock.
  • Mirror bootstrap pages carry the same admission-height columns as the live stream.
  • Mirror bootstrap requests use a dedicated per-IP rate-limit bucket.
  • Boot marker scans stop at the catch-up horizon.

Sibling release PRs

Merge order

Merge order: merge after xchain-documentation and before xchain-vm.

CI note

GitHub CI on this branch clones sibling repos at develop, not at this release branch, unless a workflow call passes siblings-ref for release branches. A cross-repo guard failure here can reflect that develop-only comparison rather than a real disagreement with a sibling still on this release branch; check the venue pre-push gate (which ships each companion at its own release branch) before treating a red guard as a defect.

…ensus/gates (activation registry row 21i, the indexer twin's bytes)
…istry rows (activation registry row 28-code)
…retired, 7 logic twins and 3 carriers moved under src/consensus from the indexer's bytes, the hub-owned zero-conf gate under src/attestation (activation registry row 21h)

Callers of the deleted shims read their rows through ./consensus/gate_registry
by literal key and the bridge engine spells its three gate keys literally
(a miss still throws at construction naming the key). Every twin is
byte-identical to the indexer's copy at the same tail (D101); no registry key,
row or value changes and the hub identity holds (digest 26ba9cce,
gates_field_hash f19f21f0, 33 keys). The sibling reference map scanner follows
the digest loader's bound-variable shape, the reachability dynamic edges name
the W5 gate paths, and the identity tool's exit code on an uncomputable digest
is pinned by a test. Four test files whose only assertions were a deleted
shim's table are deleted. Tier 6493 passing; the pin test and the frozen-set
manifest red until row 28-pin re-pins.
… consumers (a W5 comment reword in the canonical copy reverted; activation registry row 21h)
… 3 ids; frozen set, identity digest, suite titles and sibling map re-pinned; the pin membership rule follows moved paths in all three twins (activation registry row 28-pin, D102)
…ion-length limit (activation registry row 23)
…n registry

The governance snapshot-lock table was the one flag-day literal outside the
hub's registry. It becomes a row of a new hub-only part,
consensus/gate_registry/hub_rows.js (no SHARED-GATES markers, twinned
nowhere, queued after the block so the block's order is untouched), keyed
validators/governance/rules.GOV_SNAPSHOT_ACTIVATION with its comment. rules.js
reads the frozen table back by key, so electorate.js indexes it by network
exactly as before and a build without the row throws at load naming the key.
Values unchanged: mainnet 963000, testnet 0, regtest 0. The layout suite
grades the hub-only part apart from the block parts and counts its keys.
The 2026-09-16 fleet roll wedged all three testnet indexers. Recreating the
five validator hubs made every mirror re-drain each table from id 0 over
/hub-db/snapshot, three mirrors behind ONE public address spent the shared
100 req/min budget that ordinary fleet polling was already drawing on, and
the drain 429ed part way, retried every 30s, re-spent the budget and never
finished until HUB_RATE_LIMIT_RPM was raised to 60000 by hand on all five
hubs. Nothing in the train carried that, so a recreate from clean compose or
a sixth validator reproduced the wedge exactly.

The snapshot routes now carry their own per-IP budget,
HUB_SNAPSHOT_RATE_LIMIT_RPM, default 600: about 32 page reads for one
mirror's full ten-table bootstrap, about 96 for three mirrors behind one
address, about 192 req/min while any of them is still retrying. The general
limiter skips that family and stays at 100 req/min, so the public JSON-RPC
surface keeps exactly the throttle it had; raising one shared limit to fit
the drain would have taken that throttle off every open read instead.

Driven at the shipped defaults through the real snapshot routes: 192
authenticated page reads from one public IP all answer 200, the JSON-RPC
surface still 429s at call 101 with the -32029 envelope, the snapshot family
still 429s at request 601 in the REST shape its routes already use, and an
unauthenticated page read is still 401.
…and name each marker's age

hydrateMarkers loaded every intent row this hub had ever written and reported
only a count, so a marker from four days ago read exactly like one from the last
hour. pendingWindows only ever asks about the MAX_CATCHUP_WINDOWS windows below
the current one, so a marker below that floor names a window no sweep can reach:
it is quarantined no longer, reported at info as history rather than as an
operator action item, and the action-item line now carries each window's age in
windows closed and in wall clock.
…rier family

Carries the hub's registry rows for the mirror admission producer/consumer
heights and the anchor-attest barrier, rolls HUB_SCHEMA_VERSION to v7 for the
admission_height column, and re-pins the gate-registry and consensus-identity
guards the new rows move.

Platform buildout row 15 (child rows 7, 8, 9b, 10, 11 and three seam-fix passes).
…gistry P11)

A changed-hash move requires a reason and writes one atomic {from, to, path, date, reason} record. Verified 17/0 byte-identical across indexer, sync and hub.
… block

The hub pinned snapshot_block on its pushed BTC tip, so an escrow proof could read the checkpoint one block before the lock and refuse the mint every block. Proposers now hold until the tip covers the leg; followers refuse a lower snapshot.
…nchor rewards carry the admission-height columns the live stream carries
…ghts from the v0.20.0 train (dq3 (a))

This reverts commit f39437f; the token bridge and policy gates stay dark on v0.20.0 and arm on the next train. The identity pin stays at HEAD's value, because every row f39437f re-pinned (digest, hub_schema_version, the barrier and mirror admission rows) belongs to later barrier work and the hub identity reads no token or policy row.
…ying and the BTC-arms-last dependency"

This reverts commit b06036b.
… the BTC instant

The v0.20.0 family was sized 2026-09-16 20:41Z from last-99-block cadences. LTC
testnet then ran at about 82 s per block against the 146.6 s that sizing assumed,
pulling its producer boundary to 3.2 h out while BTC's stayed 53.0 h out, and
DOGE's drifted 7.5 h early. Two legs of one cross-chain match would have crossed
the flag day about two days apart, which is what the same-wall-clock-instant rule
exists to prevent.

Re-measured 2026-09-17 22:45Z over a trailing window as long as the lead being
sized: TBTC 152,891 at 576.7 s per block, TLTC 4,889,190 at 82.5 s, TDOGE
67,904,912 at 27.7 s. BTC is unchanged, still keyed to epoch close 153,216 plus
6 buried; LTC and DOGE are converted onto that same instant, and each consumer
is its own producer plus six hours at its own measured cadence rather than a
block count carried over from the first sizing.

Arms the TRAIN_ACTIVATION 0.20.0 row at testnet 153,116, 106 blocks and about
17 h below the BTC producer. resolveRuleSet reads only the local map, so with no
row every block above the boundary keeps resolving under 0.19.0, and a manifest
naming 0.20.0 halts a fleet in which no build implements it.

Records the cadence-window rule the re-cut used and makes the re-size rule per
chain instead of BTC-keyed, so an LTC or DOGE drift past the six-hour ordering
margin forces a re-cut the way an overrun BTC height already does.

(cherry picked from commit 82ecaf4382655af714ed27b92573b5b9af18c160)
@jdogresorg
jdogresorg merged commit 0f7c78a into master Sep 18, 2026
13 of 14 checks passed
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