XChain Platform v0.18.0
XChain Platform v0.18.0.
A minor train across thirteen components: every code component except xchain-contracts
moves to 0.18.0, xchain-documentation included. It exists to land the platform-train
consensus activation carrier on the fleet ahead of the first major train, and to carry the
six oracle and ledger rules that took their own per-network activation since v0.17.0. The
mainnet hub stays at v0.16.2 under the standing write hold, so nothing here reaches a
mainnet writer until that hold lifts. src/release-manifest.json at this tag pins the
resolved set; the signed artifact set and SHA256SUMS.asc are attached.
Activation
Nothing in this train changes what any node derives from history it has already
processed at the heights it ships with. Six rules take their own activation. Two of them
share a testnet height per coin that the fleet crosses about three weeks after this roll,
and a third arms on a testnet date inside the same window:
| Rule | Mainnet | Testnet | Regtest |
|---|---|---|---|
Amount representability (AMOUNT_REPRESENTABILITY_ACTIVATION) |
unarmed | unarmed | genesis |
Oracle price range bound (PRICE_ZERO_VALIDITY_ACTIVATION) |
unarmed | 2026-10-01 00:00:00Z | genesis |
Dispenser freshness shape (DISPENSER_FRESHNESS_SHAPE_ACTIVATION) |
unarmed, per coin | genesis | genesis |
Landed-batch fee bound (PRICE_FEE_BATCH_LANDED_ACTIVATION) |
unarmed | unarmed | unarmed |
Stake-key reuse (STAKE_KEY_REUSE_ACTIVATION) |
unarmed | BTC 156000, LTC 4897000, DOGE 67920000 | genesis |
SWEEP zero-amount leg (SWEEP_ZERO_LEG_ACTIVATION) |
unarmed | BTC 156000, LTC 4897000, DOGE 67920000 | genesis |
Pre-batch price floor (PRICE_BATCHING_FLOOR_ACTIVATION, node-local timing) |
no era (0) | no era (0) | no era (0) |
Platform-train gate (TRAIN_ACTIVATION) |
1.0.0 floor at genesis | genesis | genesis |
This train adds no TRAIN_ACTIVATION row and its manifest carries no trainActivation
block: the carrier ships, the fleet keeps resolving the 1.0.0 rule set, and the first
major train is the one that arms a boundary.
The three stake-key-reuse testnet heights were sized on 2026-09-11 at the measured
testnet tips (BTC 151,991, LTC 4,883,971, DOGE 67,887,900) plus 21 days of each chain's
blocks, rounded up. Every testnet indexer must run this release before the earliest of
them crosses, which at nominal cadence is Litecoin and Dogecoin around 2026-10-03 and
Bitcoin around 2026-10-08. The oracle price range bound arms on testnet at
2026-10-01 00:00:00Z, keyed on the action's block time, and is the tightest deadline in
the train. If the roll slips toward either date the heights are re-sized before the
release notes are published; an activation already in the past is not a flag day.
The platform-train activation carrier
TRAIN_ACTIVATION now exists in the canonical constants and is vendored byte-identical
into the indexer and the sync follower, held equal by the activation parity suite. The
indexer evaluates it before it reads every block: a node whose signed release manifest
requires a rule set its build does not carry halts with a durable TRAIN_ACTIVATION_HALT
marker instead of applying the block under the old rules, and its health endpoint
publishes the verdict as train_activation (clear, pending with the height and the
version needed, or halt) while a rolling-upgrade window is still open. The release
tooling writes the manifest's trainActivation block at ceremony time and the
release-completeness gate refuses a major train that carries none, a manifest that
disagrees with the vendored map, or a mainnet height at or below the tip it was cut
against.
Ledger and fee rules
A SWEEP that holds a tick at exactly zero stops writing a zero-amount debit and credit leg for it. Those legs are part of the per-block ledger hash, so the skip is a flag day: below the height the legs are written exactly as the deployed fleet writes them, and it shares the stake-key reuse boundary on testnet so the fleet rehearses one crossing per coin.
An amount must now denote the number the ledger credits. The legacy validator accepted the
whole JavaScript number grammar, so an exponential, hexadecimal, signed or trailing-space
spelling passed while the bignumber ledger math credited a different number. Above the
flag day only a plain decimal bounded by the tick's decimals and the stored column width is
accepted; below it, and on every network as shipped except regtest, history replays byte
for byte. The SDK's preflight mirrors the rule as an advisory check and the indexer stays
the authority.
Native-coin fee pricing gains a landed-batch bound. A hub-connected node holds a price
round the instant oracle consensus finalizes it, a full batch window before the PRICE
batch carrying it is mined, while a chain-only node cannot hold it until the batch lands,
so the two priced the same action against different rounds. Price snapshots now carry the
clock of the block their batch landed in (the hub stamps it on batch ingest, earliest
landing wins, and mirrors it down), and once the bound arms getLatestPrice selects only
rounds the chain could have shown every node. It ships unarmed on every network, so the
selection is byte-identical to today's. Arming it needs the hub half to have been stamping
rounds for longer than the fee staleness bound, so the hub rolls first and the bound is
sized afterwards.
An on-chain PRICE is bounded to the range the hub accepts, strictly inside (0, PRICE_MAX)
under the same expression the hub's ingest points evaluate, so a quorum-signed zero or
at-ceiling price is no longer chain-valid and hub-invalid. Testnet arms at
2026-10-01 00:00:00Z; mainnet stays unarmed.
A DISPENSER freshness check that got a non-null but shapeless first-seen answer from the
UTXO tracker used to read it as "never seen" and grant the fresh-address exception; at or
above the flag day it fails closed. Testnet and regtest arm at genesis because the tracker
path is unreachable there; every mainnet coin is unarmed.
A retired STAKE v1 signing key can stake again once every stake row it ever held is
deactivated and past cooldown, eviction and voluntary unstake alike. Below the gate the
legacy predicate refuses any key that ever held a row. Testnet arms per coin at the
heights above; mainnet is unarmed.
Both price barriers resolve immediately for a block older than the network's price rail
instead of waiting out their timeout, which is what made a chain-only bootstrap across the
pre-rail era cost weeks. The floor is node-local timing, never hashed, and ships at zero
on every network, so the barrier behaviour deploying today is unchanged until an operator
arms a measured floor.
Hub
A refused relay row no longer counts as a materialized request, so the honest relay it
still owes is sent; the exclusion is gated on the relay reject-slot activation through a
copy of the indexer's twin module, armed at genesis on every network. The proposed
snapshot height is bounded against this hub's own BTC tip before the clamp-reference gate,
the snapshot, the leader election and the quorum mode read it, so one drop decision
covers all four. A deferred reward attestation whose still-shallow txid draws a rejected
status verdict retries until its TTL instead of being dropped. The attestation provider
fetch timeout default rises to 20000 ms. An unreachable peer is backed off past a minute,
a spend-guard reservation the store cannot record fails closed, capability snapshots are
derived per capability off signing identity so a mesh-only public hub derives the ones it
does not write, and the price-ingest fence is keyed on network as well as source chain.
Also in this train
- The indexer halts at boot, naming the pending migration, when the live
validator_rewardsunique key omitsround_qualifier; that migration now carries
deploy-precondition=required, so a deploy refuses before recreating the container. - Mirrored
capability_snapshotsrows are fenced behind a BTC re-derivation check, a
rebuilt hub source is detected by content contradiction, undeclared live columns and
indexes are reported at boot (warn-only, never dropped), and sends and destroys carry a
leg ordinal so multi-leg broadcast order survives the schema. - A market between a token and the chain's native coin keeps its row across reorgs and
carries the coin it settles in, in the indexer, the explorer and the sync follower's
reorg sweeps; a manual indexer migration restores rows earlier reorgs removed. xchain-syncescalates a persistent replica row gap once as its own alert and publishes
it on/status, presents a separate outboundSYNC_UPSTREAM_KEYso a source can be
keyed without stopping its readers, and re-fetches a boundary-second hub config row.xchain-nodepointsNODE_URLat the coin node's container name rather than the shared
alias, names a missing gas token duringvalidator stake, clears the price-ingest fence
per network, refuses an unreadable migration count, and refuses to build module images
without Docker BuildKit.- The encoder clamps a raw
estimatesmartfeeresult to a per-chain sanity ceiling,
prefunds a two-phase reveal at a package-aware rate, and unifies UTXO freshness into one
classifier. - The SDK and the e2e suite cross-check the hub-served coin consensus hashes against their
bundled coin files; the SDK ships WebSocket typings and a template drift guard.
@dankest-llc/xchain-sdkandxchain-mcppublish at 0.18.0. - Every service Dockerfile stops trying to bake a
.envfile into the image, so the build
succeeds on the legacy builder and configuration reaches the container as environment.
Verifying this release
gpg --verify SHA256SUMS.asc SHA256SUMS
shasum -a 256 -c SHA256SUMSThe signing key is published at xchain-documentation/operations/release-signing.md and in
tools/release/ in every train repo. Any other key is not an official release.
Installing this exact set
xchain-node install v0.18.0 <service> <coin> <network>What is in this train
| Component | Version |
|---|---|
| xchain-node | 0.18.0 |
| xchain-hub | 0.18.0 |
| xchain-indexer | 0.18.0 |
| xchain-sync | 0.18.0 |
| xchain-explorer | 0.18.0 |
| xchain-decoder | 0.18.0 |
| xchain-encoder | 0.18.0 |
| xchain-utxo-tracker | 0.18.0 |
| xchain-sdk | 0.18.0 |
| xchain-e2e-test | 0.18.0 |
| xchain-vm | 0.18.0 |
| xchain-contracts | 0.17.0 (unchanged) |
| xchain-regtest-miner | 0.18.0 |
| xchain-documentation | 0.18.0 |