Skip to content

Release v0.19.0 - xchain-encoder - #15

Merged
jdogresorg merged 148 commits into
masterfrom
release/v0.19.0
Sep 16, 2026
Merged

jdogresorg merged 148 commits into
masterfrom
release/v0.19.0

Conversation

@jdogresorg

Copy link
Copy Markdown
Contributor

Bumps the package and lockfile to 0.19.0 and folds the Unreleased block into a dated 0.19.0 entry. The train carries the XBRIDGE cross-chain bridge, armed on testnet by the ladder and on mainnet at the sentinel, with the token bridge and policy code dark behind their sentinels, the rollcall and tracker fixes, the code-structure passes with the consensus identity pinned, and the activation registry.

Platform notes ride xchain-node's Release.

Re-vendors the shared coin bundles with the bridge escrow addresses and the XBRIDGE gas entry.
Refreshes the lockfile so every package the security audit flags resolves to its patched release inside the existing version ranges. No source change.
…oles

The envelope-cancel path used one expiry stamp per outpoint as its ownership
token, the concurrency gate released its slot on a response event Express
never awaits, and the single-instance guard published ownership in two steps
so a crash between them left an unowned lock. On the coin-node contract, the
no-fee-estimate condition was handled in only one of its two shapes, mempool
entries were coerced before type validation so malformed rows priced as free,
and ancestor packages committed a root on the first of two round trips. From
the 2026-09-12 review round.
…ilently

A direct library caller whose payload led with an unrecognized action name
previously had it compiled and paid for with no signal that it would be
dropped. createTransaction now reports it as a warning, covering both
string and Buffer inputs.
Ports the suite-title and reachability tooling into this repo's bin/ (with a fix so it recognizes mocha invoked via npx), plus a script that pins the vendored coin files and the canonical fixture by sha256. Records the current suite titles and unit-suite wall time as a baseline.
Checks reachability of every tracked src/*.js file and falsifies each of the four candidates by hand: the browserify entry point and three pre-work adapter-interface stubs are all still live. Records the sweep and its falsification for reference.
Vendors the shared eslint preset inline and adds eslint plus a lint script; scopes the existing ajv override so eslint's own ajv6 dependency still resolves alongside the same ajv8 security pin every repo carries. Running lint surfaces existing style debt this commit does not address.
Renames 15 top-level src/ files (plus the adapters/ trio) to snake_case, updating every require, __dirname join and literal path across src, test and package.json in the same commit; the vendored coins/ and observability/ trees are untouched. Restores two files a codemod rewrite incorrectly touched: a cross-repo twin-guard test's reference to xchain-sdk's own (not-yet-renamed) copy, and two dead-code-sweep evidence files that quote pre-rename names on purpose.
Replaces direct console.log/warn/error calls outside the vendored trees with the shared logger, following the same argument-folding rule the vendored console patch already uses. Fixes a test that spied on console.error directly, which stopped seeing anything once the logger's real shipper installed; it now spies on the logger method instead.
Adds src/config.js as the single place that reads process.env, converting call sites (including several that need per-call, not load-time, evaluation) to config getters instead of raw environment reads; src/api.js keeps its own direct reads as the entry point. Preserves the existing dependency-injection seam in single_instance_guard.js by defaulting to the config object instead of process.env.
Renames 19 underscore-prefixed methods to their plain form across src/ and every call site and comment that names them, leaving the vendored observability methods untouched.
Renames 97 test files to snake_case (or into their kind-specific helper directory) and repoints package.json's two literal test paths and every comment naming an old test file by its prior basename. The remaining 17 files are genuine e2e suites and standalone scripts whose naming stays as-is for now.
Reviews the two sweep commits that touched this repo's own src/ files and restores two genuine losses (a dropped JSDoc tag and a dropped design-doc attribution) while leaving legitimate cuts (ticket numbers, internal references, decorative banners) out per the comment style guide. The remaining coverage shortfall in files the sweep touched outside src/ is not addressed in this commit.
The previous commit's restoration was one line short of the file's comment-coverage floor.
The sibling repo renamed its copy of the shared patch file independently while this repo's own restructuring was in progress; repoints the test's hardcoded sibling path to match. Neither repo's rename was wrong, they just landed concurrently.
Moves every remaining top-level src/ file into a feature directory keyed by which file requires it (a build/ home for XChainEncoder's own dependencies, a server/ home for api.js's, a common/ home for files two or more callers share); src/index.js stays put as the bundler entry point. Reverts one over-eager rewrite that touched a frozen cross-repo fixture's prose.
Renames the real e2e suites and the load-test/benchmark scripts left out earlier, updating package.json's globs and every require path the new depth requires, and adds all 17 to the committed test rename map alongside the earlier 97. Reverts one accidental regeneration of a frozen cross-repo fixture, caught by re-requiring each moved file.
One test file was still short of the comment-coverage floor after its rename, because an earlier sweep commit touched it directly; restores its dropped header summary and declares the remaining shortfall (decorative dividers) as an exemption.
Restores pure-deletion hunks from the same sweep commit across the remaining short test files, skipping anything the comment style guide already bans (ticket numbers, internal references, decorative banners) and declaring the leftover shortfall as an exemption instead. A handful of lines could not be placed unambiguously and are handled in the next commit.
Places the comment lines the previous commit's anchor search could not uniquely locate, using each hunk's original top-to-bottom order instead. Drops one restored line that contradicted the unconditional rejection described immediately above it.
Each finding block regains the one-line summary a comment sweep removed, reworded without the decorative rule characters.
xchain-encoder names xchain-decoder's BlockchainConnector.js and several renamed test files, xchain-sdk's applyBufferutilsPatch.js, compression.js and its own sibling-coverage test, and xchain-node's EncoderMaintenanceWindow.js, in comments and computed sibling-path literals; repoints all of them to those repos' new paths. The hub-vendored src/coins/index.js comment and the utxo-tracker-vendored utxo-record-conformance.json fixture are left untouched, since both must stay byte-identical to their unedited canonical or twin copy until that repo fixes its own self-reference.
The oversized OP_RETURN rationale regains its full wording, with the stale per-coin policy sentence corrected to the unconditional rejection; the finalizer's skipped shape check is described again.
The two body-level requires become one module binding dereferenced per call, which keeps a swapped verifyConsensusPin reachable from the constructor.
Hoisting the per-test requires folded five differently-sourced bindings into one, so two checks went red and two passed against the wrong module.
The canonical coin registry repointed a consensus note at the decoder's
renamed crypto networks module. This re-vendors that byte change so the
copy stays identical to canonical.
validateAll had no doc comment describing its contract, and the first
two checks in validateUtxoEntry had no plain-language line above them
explaining what they guard, both against COMMENT-STYLE's rule that
every validation check gets one. Comments only, no behavior change.
src/index.js only exists to hang XChainEncoder on window for the browserify
build, so it is not cross-cutting infrastructure and does not belong at the
top of src/. The move carries the one require it forces and repoints the
build and build:dev scripts at the new path. No runtime change: the API
process and every Node consumer load src/XChainEncoder.js directly.
bin/pins/identity.json was written by bin/pin-identity.js but read by
nothing, so a stale pin failed no gate. The new tier re-hashes the tree
against the pin and turns ci-full.sh red on any moved or missing file.
The tool compares only the entries a pin names, so the tier also refuses a
pin with no coin or conformance entries instead of reading it as holding.
…ifier and the gate slot wiring into named steps
…hods.js as per-method-group builders

The serve-readiness probe and the eight JSON-RPC methods leave src/api.js
for a part beside it, built by createJsonRpcController({ encoder, NETWORK })
from seven small per-group builders composed in dispatch order. The six
error lines the methods emit go through the service logger like every other
module, same level and message text. GET /status reads the readiness fields
from the controller's health() so the two endpoints cannot drift apart, and
the openrpc drift guard extracts method names from the builder literals.
…o same-title blocks by behaviour

(cherry picked from commit 3186d2896aa7e42d78a6696e2bf4d77b81fc3db2)
…policy, request resolution, reservations, payload preparation, sizing and envelope cancel into src/XChainEncoder/
…rc/XChainEncoder/build_transaction/

The method keeps its signature and runs the steps in the same order over one per-call state object; every moved line is the original text.
…every step

Awaiting each build step as an async function added a suspension at every
step boundary and after every selected input. Concurrent builds over one
address then split its outpoints between them, and both could fail with
insufficient funds where one of them should succeed. The steps are now
generators that yield each node, tracker and payload promise to one loop in
_buildTransaction, so a build suspends exactly where it waits and runs
without a break in between. A unit test pins the first-come outcome for two
builds racing for the same two outpoints.
…de fee rate

The cancel's fee-rate step became an async function in the
buildEnvelopeCancelTransaction split, and awaiting it added one suspension
after the commit-outpoint claim that the inline code never had. It is now a
generator driven by one loop in buildEnvelopeCancelTransaction, the same
pattern _buildTransaction uses, so each node fee-rate promise is awaited
once, where the inline code awaited it. A call with a node that answers at
once settles in three microtask turns again on both fee-rate paths and on
the below-dust refusal, and a new test pins that count.
test/unit held 46 files directly, past the 20-file readability limit.
Group the non-held unit tests into feature subdirectories (api, build,
common/validator, coins, server, adapters, repo, xchain_encoder) by the
src area each test covers. Pure git mv, no content changes; the three
Hub D-OBS-2 held files (blockchain_connector, crash_handlers,
observability) stay in test/unit.
Companion commit to the pure test/unit directory-split move: fix every
relative require()/require.resolve()/path.join(__dirname, ...) call in
the moved files so each still resolves to its original target, update
bin/pins/test-rename-map.json so the 43 moved top-level test files
retarget straight to their new location (single-hop, matching the
pin's own recorded path), update bin/pins/suite-title-splits.json so
the 8 split-parent entries carry their new old-key and part paths, and
repoint five stray comment references (docs/openrpc.build.js, src/api.js,
src/build/apply_bufferutils_patch.js, src/common/validator/constants.js,
bin/coverage-thresholds.json) that named a test file by its old path.
Also fixes the relative require in
xchain_encoder_taproot_envelope.test/05_key_path_cancel_suspension_count.test.js,
which origin/develop added under the split directory after this branch
was first built and picked up the same one-level-deeper move on rebase.
The bare test/unit/**/*.test.js mocha invocation on the "ci" script
omitted --require ./test/setup/index.js, unlike "test". Without it
XCHAIN_LOG_PATCH is unset, so the first file that requires src/api.js
(observability install runs at module load) leaves the global console
patched for the rest of the process. Directory placement, not test
content, decides whether a later file that asserts on raw console.warn
calls runs before some other file's cleanup resets it, and mocha's
default file order is unsorted glob order, not alphabetical across
directories, so any reshuffle can flip which side of that reset line a
file lands on. This split moved test/unit/api/cors_preflight.test.js
(the file that leaves the patch installed) earlier and test/unit's
three held observability/crash/blockchain-connector files later
relative to it, so test/unit/build/package_fee_sizing.test's two
console.warn assertions started failing under "npm run ci" (which does
not sort) while "npm test" (which sets the guard) stayed green. Rather
than pick directory names to keep the accidental ordering that used to
protect it, give "ci" the same guard "test" already has.
…coder

The drift-guards job never checked out the decoder, so the test that
byte-compares ENVELOPE_RECOGNITION_ACTIVATION against the decoder copy
skipped on every GitHub run. The job now checks out the (public) decoder
beside the encoder and runs the test with XCHAIN_REQUIRE_SIBLINGS=1, so a
missing sibling fails instead of skipping (activation-registry row 29,
section 6.4 guard 3).
Version 0.19.0, the 0.19.0 changelog section and the README badges and script-table counts measured on Linux.
@jdogresorg jdogresorg closed this Sep 16, 2026
@jdogresorg jdogresorg reopened this Sep 16, 2026
@jdogresorg
jdogresorg merged commit 8616f3d into master Sep 16, 2026
13 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