Release v0.15.0 - xchain-explorer - #20
Open
jdogresorg wants to merge 57 commits into
Open
Conversation
…cover the page when a coin stops being stale
… and pin async/generator handling
…nd name it in the detail view
…less actions appear in the feed
…f the no-TTL action cache
… answering with block 0
…d of serving a frozen mirror
…ached balance cannot outlive its block
…ge and pin the floor in the dependency gate
…ket and staking modules
…e when a response comes back redacted
… database A non-numeric path segment was bound as NaN and threw inside the driver, so a bad id answered 500 rather than a refusal. It is now rejected with the same shape and code the sibling verify route already used for a malformed height.
Byte-identical to the indexer's definition, as the conformance suite requires. The explorer has no table-creation machinery of its own, so its embedded mirror builds its schema from these vendored files.
The mirror gains an eighth table. The version is compared with strict equality and a mismatch parks the whole mirror, by design, so the three copies flip together in one synchronized window.
Byte-identical to the indexer's copy, as the conformance suite requires.
Above the response-mirror activation height a finalized attestation is applied as a system-synthesized action: it has a real action index and a real block, but no transaction. Two discovery queries joined transactions inside, so such a row did not merely lose a column, it disappeared. The list dropped it, and because the change detector discovers new actions through the same query, the websocket event for it never fired at all. Both queries now join blocks off the action's own block index and leave transactions optional, which is the shape the history query already uses. This widens the action feed beyond attestations: every system-synthesized action was being excluded the same way, and they now ship with a null transaction hash. That is the intended behaviour, and it is visible to existing subscribers. The attestations list also had one column answering two different questions. Status carried the attester's HTTP result, so an attestation the chain rejected read as ok. That column is now Response, and a new Action Status column carries the chain's verdict, which is also what tints the row. Nothing was removed. The list's tail fields are read by position here because the shared parser takes the last two columns as status and action index, which this feed's three extra fields displace. The response panel gains the on-chain batch link, with an empty state that distinguishes a body the chain has not carried yet from a response that was its own transaction.
…ernance routes Also reads the poll winning-option test through the shared content-source helper, so it sees the composed page rather than a raw file.
…-source helper The client is composed from components now, so reading the entry file alone sees only part of it.
… registered routes loadApiData keeps its own action-to-endpoint map beside the list-page one and nothing held the two together, so an irregular name added to one side silently built a URL no route answers. A miss there is quiet: the fetch fails and the detail card never fills in.
…e overview Three composed views over data that already had an API. The gallery classifies tokens from their ISSUE fields as indivisible with a frozen ceiling and applies no curation; the rich list ranks one token's holders alongside its supply stats; the governance page shows token polls and network-parameter proposals side by side without merging two separate systems. Also adds the point reads a cross-chain call's live channel needs.
…hannel A call's terminal transition on the source chain is a direct status write by the callback interlock, so the actions cursor never sees it. A third cursor over the resolved height emits both outcomes, and the channel is keyed by call_id, the only stable name a call carries on both chains.
… the client as composed The roll call block shipped without a row config, so it mounted with no order at all, and the eviction-label test evaluated the client entry file alone, where the helpers it calls no longer live.
Byte twin of the hub's definition, re-vendored so the conformance guard keeps holding once the mirror carries batch_action_index.
…batch link Byte twins of the indexer's client and table definition, so the conformance guard keeps holding now that the attestation response apply can fill a null batch link once while leaving every signed column as first inserted.
… the indexer added
A response applied through the hub mirror has an action but no transaction, so joining blocks through the transaction left its detail page showing a block link with no time beside it. The join now reads the action's own block index, which both delivery paths populate identically, and the conformance suite asserts the timestamp for a tx-less response alongside the transaction-backed control that proves the fixture discriminates.
…ead paths One wave of the review round on the xchain-platform board. Every change was re-derived from the code rather than applied from the finding recommended option, and each carries a control that reproduces the original failure. Review findings: 6422 6468 6470 6532 6557 6564 6565
…header
The review round corrected this shared module's header in the indexer copy
(#6494): it claimed the indexer flips the signed shape on this anchor, when the
indexer has no call site at all. The file is vendored in five repos under a
byte-identity gate that permits only the "live in xchain-{...}" line to differ,
so the correction has to land in all five or the gate reds.
Mechanical sync from the indexer copy, each repo keeping its own live-in line.
…and make the trust-proxy hop a tested seam The app-wide, action-proof and checkpoint-verify limits move to 1080, 90 and 90 per minute per client, derived from a five-address wallet's worst minute with retries and 3x NAT headroom; the other five limiters keep their shipped values. All eight are pinned in a version-controlled unit drop-in for the production host. The trust-proxy hop count now lives in src/trustProxy.js so the security test drives real requests through it, on the HTTP and the WebSocket upgrade paths, instead of grepping source.
…y one host's layout The logrotate stanza, its README and the rate-limit drop-in carried a service account name, measured disk figures and the drop-in inventory of a running host. They now state the reasoning without those specifics, and the trust-proxy comments describe a fronting proxy and a CDN rather than naming a particular stack.
A synthetic UNSTAKE v2 cooldown-completion never displayed its token or contract even though the backend computed both. Review round 7 finding #6858. Also carries review round 6's explorer work.
Review-round fixes. Includes a cross-repo repair: the vendored hub-mirror client had drifted from its canonical source because separate changes landed on each copy, which reddened the byte-identity gate. The canonical copy proved the strict superset, so the vendored copy was re-synced through its own sync script rather than hand-merged. Also: an attestation batch link that targeted the response chain instead of DOGE; PRICE oracle token links that ignored the token's declared chain; and the theme-parity probe now self-checks its capture before persisting it as evidence, so an empty or mis-targeted capture cannot read as a pass. Suite: 4020 passing, 0 failing.
…absent check mode could overwrite a populated vendored tree, so a local edit under the destination was silently replaced instead of reported. The indexer's copy already carried the guarantee; this ports the behaviour rather than the file, keeping the two implementations independent. The single write is now keyed on the destination's src/ being absent, so a populated tree is left alone and the drift is reported instead.
…cannot pin the socket _post cleared its abort timer when the response HEADERS arrived and never released res.body, so a collector that answers 200 and then stalls held the socket open with nothing bounding it. Measured against a stalling collector, the socket was still open at three seconds and the batch was counted as shipped. That is worse than a leak, because the timeout was configured and did nothing: at a 400ms ship timeout the timer cleared at 22ms, so the stall outlived its only bound and the shipper reported success. The body is now cancelled inside the same then, within the abort timer's window, rather than after finally has cleared it. The stream is cancelled and never read, and a cancel on an already-errored body is swallowed. Every existing test injected a transport and bypassed the real fetch path, which is why this survived. The new case drives _post itself. Vendored copy, written by the hub sync script and never hand-edited. Parity is gated in the hub.
… accepts The provider-byte columns of the attestation response mirror sat on a utf8mb3 tail while the on-chain fields they stand in for are utf8mb4, so a 4-byte character failed the mirror INSERT with errno 1366 under STRICT_TRANS_TABLES. A body the on-chain path would have carried never reached the mirror, and the request it answered expired unresolved. Both columns now declare utf8mb4, with a dated migration for deployments that already have the table: a definition edit alone reaches only fresh installs.
The pinned 5.0.4 is affected by a critical ExternalCopy advisory. Moving to 6.2.0 across the vm and both of its consumers, which have to agree because the consensus runtime pins an ABI and a validator fails closed against it. The bump also removes a constraint rather than adding one. 5.0.4 had no prebuilt binding, so every install compiled through node-gyp and the build failed on newer Node for a removed V8 API, which is what bounded these repos to Node 22 and what makes a shared checkout hostile to two platforms at once. 6.2.0 ships prebuilt bindings for both ABIs, so the dependency no longer sets the bound and an install lands the right binding for the host that runs it. Node 22 stays the bound for a different and still-live reason: the consensus runtime pins process.versions.modules and the validator refuses any other ABI. The engines rationale now says that rather than citing the build failure it no longer has. Adds a containment test over the isolate's reference surface, since a major version of the isolation boundary is the wrong thing to take on trust.
…canonical source The canonical table in the indexer gained an index whose time column leads, so the oracle preload's consensus-time bound is a range scan rather than a filter over every finalized row. The vendored mirror is a byte-identical twin and a conformance test asserts it, so it is regenerated here with the indexer's sync script rather than hand-edited.
…leeping Adds the test tree's one poll-until helper. It REJECTS on timeout rather than returning a flag, which is the whole contract: a wait that gives up quietly turns a flaky test into one that passes unconditionally, and that is worse than the flake because the flake at least reported something. Only the site waiting on a condition is converted. Where elapsed time is itself under test, the timer stays, and the helper's docblock says so, so the next author does not sweep one of those by reflex.
…tive_time Vendors the widened mirror twin (one request may hold two honest rows that differ only in the signed stamp) and teaches the mirror migration to rebuild the unique key on an existing mirror the same way it widened the capability snapshot key.
The lockfile's xchain-vm entry still recorded 0.12.0 while the sibling declares 0.15.0, which freezes the nested ranges it pins. The tree cannot be re-staged on a Mac, so the recorded version is corrected, which is the remedy the failing check names.
The bundled sibling snapshot check compares this repository's lockfile record of a vendored sibling against that sibling's own manifest. The shared workflow pins siblings at develop for any pull request, and develop never carries a version bump, so on a train that moves every component the comparison is unsatisfiable: the snapshot has to move for the release and develop must not. Passing the release branch through as the sibling ref makes the train measure itself, which is what a release PR should be proving. Everything outside a release PR is unchanged, and the checkout falls back to a sibling's default branch when it has no branch of that name.
… gate The coverage ratchet re-runs the unit suite, so it needs the same siblings the gate gets, and it was still pinning them at develop after the gate had been made release-aware. The bundled sibling snapshot check then compared this repository's lockfile record against a version develop is never going to carry, and reported it against the ratchet instead of the gate. Both call sites now pass the same expression, which the shared action asks for in as many words.
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.
Cuts xchain-explorer for the v0.15.0 release train. 55 commits from master.
Added
xcallWS channel.attestation_responsestable (schema version 5), its batch link and the mirror status accessor.bin/check-explorer-freshness.sh) for cron that mails the operator when any non-regtest coin is stale-gated or its replica carries an active sync halt.deploy/tbtc-tip-gates.conf) is version-controlled: it widens TBTC's future-skew and age gates so a legally future-stamped tip cannot 503 a healthy chain.deploy/rate-limits.conf) pins all eight origin limits explicitly, so a production host's numbers do not depend on which build is deployed.Changed
src/trustProxy.js, so the address the rate limiters key on is covered by a request-level test instead of a source check.bin/vendor-vm.sh checkkeys its one write on an absent vendoredsrc/tree instead of an unreadable version string, so a drifted copy is reported as drift rather than silently repaired and passed.Fixed
getDataresult cache and the network-totals cache are keyed to the indexed tip, so a cached balance cannot outlive its block.Changed