Repository navigation
Release v0.20.1 - #28
Merged
Merged
Conversation
… 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.
Send post-archive anchor stamps on a narrow frame that is not subject to late-finalization refusal. Keep full row admission guarded by the height watermark.
Run both hub unit-suite tiers with strict sibling enforcement so missing guard inputs fail. Preserve the existing parent-shell sibling preflight and leave shared row sources unchanged.
Takes src/consensus/gates/mirror_admission_gate.js from the xchain-indexer canonical through the W5 gate-twin row of the platform twin reconcile script, so the indexer, hub and explorer copies are byte-identical again at sha256 e6a3ee813ddb8385f0fbf43cf1aa788229d37ecf29a44634827d96d2c7067336. Moves the thirteen tests that asserted the removed refusals onto the legacy byte semantics: a seam round is now refused on its signatures rather than at the builder, and it is still never stored, which is the property the ingest owes. Re-pins the carrier logic and the AT1 consensus identity; the bare rules digest ee6476f2 is unmoved on both sides of the twin. Operator ruling R14 (a), 2026-09-19.
…ub twin" This reverts a3bc6a2. The file is one byte twin in three repos and its two counterparts could not land beside it: the xchain-indexer and xchain-explorer gates both refuse on SNAP-2, whose bundled lockfile snapshot of xchain-vm still records 0.19.0 while that sibling's develop now declares 0.20.0. That is the v0.20.x develop levelling still in flight, not this change, and refreshing those lockfiles belongs to the train rather than to a consensus fix. Measured: with this commit on develop and the two counterparts still at their old bytes, the hub suite goes from 1 pre-existing failure to 4, the three new ones being the cross-repo byte-twin canonical tests. Leaving it would red hub develop for every pusher, so the half is withdrawn until all three can land together. The prepared commits are preserved on land/xc2564-twin in each repo. Operator ruling R14 (a), 2026-09-19.
The armed LTC:testnet producer/consumer heights (4891504/4891766) are already behind the live TLTC tip. Ruling dq4 (a), 2026-09-18: LTC:testnet mirror admission ships null on this train and arms on a later train. Sets both heights to null in this repo's shared_rows_2.js twin, with the same replacement comment used across all six carriers, and re-pins the consensus rules digest and the AT1 consensus identity file to match, since those two values move with the arming they hash. The paired hardcoded digest in xchain-indexer's own suite moves in the same edit there.
Propagate the canonical v0.20.1 patch-train reslide into the hub's own copy of the shared consensus registry: BTC train height 153221, BTC mirror producer/consumer 153300/153328 (producer also carries ANCHOR_ATTEST_BARRIER_ACTIVATION), DOGE mirror producer/consumer 67916857/67917706. LTC:testnet stays null under dq4 (a) and is untouched. Re-pin bin/pins/at1-consensus-identity.json (consensus_rules_digest and consensus_rules_gates) to match, and update the two test fixtures that hardcoded the superseded BTC heights (153222/153266) so the regression suite tracks the reslide instead of failing on stale numbers.
L002-95 records the durable coverage floor so an absent marker can be told apart from a publisher that ran without outcome. L002-96 scopes the quarantinedWindows statistic to the catch-up horizon and documents it. One commit rather than two merges: the lane branches' own comments narrated the change and the comment-style gate refuses those added lines wherever they sit in the pushed range.
The publishing-window file passed the 400-line ceiling when the horizon case landed. Same harness, same assertions, new numbered sibling.
L002-95 records the durable coverage floor so an absent marker can be told apart from a publisher that ran without outcome. L002-96 scopes the quarantinedWindows statistic to the catch-up horizon and documents it. One commit rather than two merges: the lane branches' own comments narrated the change and the comment-style gate refuses those added lines wherever they sit in the pushed range.
HUB_RATE_LIMIT_RPM now defaults to 60000 when P2P_VALIDATOR_ADDR is set, matching what every validator compose was overriding by hand, while standalone config-oracle hubs keep the 100 default and an explicit HUB_RATE_LIMIT_RPM still wins on either role.
Every mirror reader polls MAX(reference_block) and MAX(block_timestamp) under status = 'finalized' against the hub's price_snapshots, and the hub's status RPC polls MAX(created_at) the same way. With only idx_status each read was a full scan: 1.17M rows on the regtest rail, 1.2 to 1.4 s per read, four pollers, the hub database pinned at 60 to 80 percent CPU. Add the two frontier indexes the indexer and explorer twins already declare (byte-equal names and column lists) plus (status, created_at) for the hub's own age read, and append the three migrateIndex steps to runMigrations so a deployed hub converges at boot. alterTableForDrift never touches indexes.
… margin Live testnet tips (TBTC 153698, TDOGE 67924122 at 2026-09-23T15:55Z) have passed every height the 2026-09-19 reslide armed, so the freeze preflight refuses them. The operator ruled a second reslide to 40 h of margin to the nearest armed height at the fastest defensible cadence (BTC least-squares bound 383.04 s/block, DOGE median 11 s/block), keeping the prior spacing. Propagate it into the hub's own copy of the shared consensus registry: BTC train height 154074 (tip + 376 blocks, 40 h), BTC mirror producer/consumer 154234/154291 (train + 160, 17 h; producer + 57, 6 h; the consumer also carries ANCHOR_ATTEST_BARRIER_ACTIVATION), DOGE mirror producer/consumer 67942777/67944741 (tip + 18655, 57 h, the same instant as the BTC producer; producer + 1964, 6 h). LTC:testnet stays null under dq4 (a) and is untouched. Re-pin bin/pins/at1-consensus-identity.json (consensus_rules_digest and the three moved consensus_rules_gates entries), regenerated with bin/consensus-identity.js --out, and update the three test fixtures that hardcoded the superseded BTC heights and digest so the regression suite tracks the reslide.
Replace the opaque dq4 (a) decision label with a self-contained explanation of why LTC:testnet mirror admission ships disabled on this train. Comment text only; byte-identical to the other five shared-row carriers.
…limit 08c756e defaulted a validator hub's HUB_RATE_LIMIT_RPM to 60000, the value five testnet validator composes carried by hand after the 2026-09-16 roll wedged every mirror bootstrap at 100 req/min. That lifted the throttle for every caller, a 20-call JSON-RPC batch still cost one token, and each health call read all three admission tips from the indexers, so one keyless client could drive about 1.2M health handlers and 3.6M indexer reads a minute. - Charge a JSON-RPC batch one token per call (batch surcharge over a fixed-window store that charges in bulk). - HUB_RATE_LIMIT_RPM is the public budget again, default 100 on every role. Callers presenting a configured hub key get their own bucket, HUB_AUTH_RATE_LIMIT_RPM, default 60000, which keeps the fleet value for the indexer push and replay traffic it was for. A wrong key is public. - Health's admission-tip probe is single-flight with a 1.5 s cache, so a flood costs at most three indexer reads per window. - Every probe deadline clears its timer on completion, and a timed-out admission read aborts its axios request.
…mission era 98ac256 re-vendored the indexer's unconditional admit_block_btc onto the batch wire, so this hub signed every batch over a canonical no v0.19.0 indexer rebuilds and re-verified pushed historical batches over bytes their signers never signed. Re-vendor the indexer twin (xchain-indexer d139dbd8): the row field set is chosen by the batch's own signed btc_block_height against the BTC mirror admission producer activation, and every wire entry point takes this repo's isAdmissionEra. The leader, the co-signer, the encoder and the pushed-batch re-verify all pass it. normalizeRow now carries the stored admit_block_btc. Without it an admission-era batch would sign null for every row and a chain-rebuilt mirror would bind those rows as legacy; below the activation the wire drops the field, so no pre-era byte changes.
…iling mean Operator ruling D11 (a) 2026-09-23: producer moves from 67942777 to 67936053 and consumer from 67944741 to 67936888, the same-instant rule computed off the 84h trailing block-time mean instead of the earlier median estimate. BTC:testnet heights are unchanged; their comments now also carry the 84h trailing mean cadence bound alongside the existing one. Re-pin bin/pins/at1-consensus-identity.json with the repo tool and update the test that hardcodes the bare consensus rules digest.
…d scope the regtest chain-tip purge to this hub's own network setAttestPublishedBatchByNetwork issued INSERT ... ON DUPLICATE KEY UPDATE window_start = window_start as its durable pre-send claim. Under the hub pool's mariadb foundRows default (unset, which the driver resolves to true), a duplicate's matched-but-unchanged row also reports affectedRows 1, so claimWindowForBroadcast could not tell the sole creator of an intent row from a second overlapping sweep on the same hub, and both could broadcast the same window. Switch the claim to INSERT IGNORE, which reports 0 for a duplicate regardless of foundRows, and correct the window.js comments that called the marker a cross-publisher mutex: each validator runs its own hub against its own DB, so the guard only ever arbitrates between this hub's own overlapping attempts. pushchaintip's regtest capability-snapshot purge triggered on the caller's own network param alone, so a testnet or mainnet hub could be made to wipe its cross-chain and capability_snapshots rows by a caller sending network: 'regtest' twice with different chain_ids. Gate it on this hub's own configured network (hub.network) as well. Worktree verified against origin/develop (e9368e8); full hub unit suite (6662 passing) and the code-structure check are clean.
This was referenced Sep 23, 2026
The floating node:22-bookworm tag can move to a Node patch whose V8/ICU no longer match xchain-vm's consensus runtime pin, so the base image is now pinned by digest to a build that is measured to match it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v0.20.1
Coordinated platform release across the 13-repo v0.20.1 train.
masterrelease/v0.20.1What changes
153221to154074, with BTC producer/consumer activation at154234/154291, DOGE producer/consumer activation at67942777/67944741, andANCHOR_ATTEST_BARRIER_ACTIVATIONat154291;LTC:testnetmirror admission remainsnullunder dq4 (a).mirror_admission_gate.jstwin:admissionCanonicalValue()is non-throwing, and an INERT consumer with a legacy-signature mismatch follows the ordinary invalid-row path.Sibling release PRs
Filled in by open-release-prs.sh --execute once every PR above has a number: