Release v0.19.0 - xchain-encoder - #15
Merged
Merged
Conversation
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
…uisition 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/
…tor into initReservationMaps
…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.
…ChainEncoder/payload_encodings.js
…claim, fee rate and sizing steps
…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.
…d reset its move maps
…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.
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.
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.