A client for a consensus network must give the same answer as the reference, bit for bit. One wrong gas value gives a different state root. A gate in xOne closes on recorded evidence for an exact build.

This post explains the checks in xOneRS and how the TypeScript, Python and C++ clients reuse them. It also states what the evidence does not cover.

One pinned reference

The reference is geth-XDC at one commit. The pin is one line in conformance/PIN: 6fc8e8c2088b7f18264f5663036669d04fa7becf.

ADR-003 sets the rules:

  • A change of the pin is its own pull request. It runs every vector again.
  • Go programs under conformance/ write the vectors. The Rust tests read them.
  • The Rust client does not link geth. A mismatch is a defect on one side, found by a diff.

The ADR status is still "Proposed". The code already follows it. The geth-XDC fork is private, so conformance/fetch-geth.sh needs read access to it.

Each consensus rule has a page under spec/ with the geth file:line at the pin. The rule register is generated from those pages. A page with 0 geth references is a defect.

Golden vectors and negative vectors

The consensus vectors hold whole blocks from two geth-XDC archive nodes. The export date is 2026-11-11.

  • 300 Apothem blocks (head at export: 85,230,907).
  • 100 net2040 blocks (head at export: 733,484).

The block list includes V1 checkpoints, V2 epoch switches, the V1 to V2 switch, sign-transaction blocks, and the blocks around each fork row (row-1, row, row+1). The exporter stops if geth's own hash or root differs from the archive's. Nobody edits a vector by hand.

Negative vectors start from a valid block. A recipe changes it, and the test expects an exact typed error. The expected error is written next to the recipe. It is never computed by running the verifier. The negative/ folder has one file per rule, such as body_bloom_bad and v2_not_its_turn.

A limit: the corpus tests the comparison of a header with the masternode list, not the derivation of the list from contract state. Replay covers that.

The replay harness

xone-replay re-executes recorded chain history. In gate mode, each block runs on the state that the previous block left. Nothing is taken from the reference's state.

Per block, the harness compares gasUsed, receiptsRoot, logsBloom, transactionsRoot and stateRoot with the header. It also compares the archive block hash (every 100th block and the last). At V1 checkpoints it compares the masternode list. The first difference stops the run and writes a divergence record. The full list is in RUNS.md.

The run command from the docs:

xone-replay run --network net2040 --to 20000

Other documented flags are --resume (continue from the newest checkpoint at or below --to) and --checkpoint-every. Blocks come from a cache that xone-replay fetch --network net2040 fills from a read-only archive. The replay itself runs offline.

Replay finds real faults. The first net2040 run stopped at block 9,917: between London and Eip1559Block the header has no base fee, and geth checks the fee cap against none. The fix went into xone-evm.

What "0 mismatches" covers

Every row below is copied from the RUNS.md files.

REFERENCE TABLEScroll to explore all columns →
Client Network Range Result
xOneRS Apothem 0..=432,000 (2026-11-11) 0 mismatches, 4,320 archive hash checks, 480 checkpoint lists
xOneRS net2040 0..=21,599 (2026-11-12) 0 mismatches, 13 V2 epoch switches, fork rows from tipSigning 1,800 to Osaka 19,800
xOneRS net2040 30,001..=754,336 (2026-11-12) 0 mismatches, 809 V2 epoch switches, 7,244 archive hash checks

Apothem also has three diagnostic windows. They start from the archive's state at a pivot block, not from genesis. They cross the V2 switch (56,828,700) and the tiered and proportional reward forks. They prove execution and consensus rules, not bootstrap trust.

Mutants test the gate. With the tiered reward switched off, the run diverges at block 83,600,502, the first tiered reward switch.

Limits:

  • The Apothem genesis run stops at 432,000. It does not reach TIPSigning at 3,000,000. The fetch rate of the block cache is the limit.
  • The 0 mismatches apply to the ranges in the table, not to the whole chain.

RPC parity sweep

xone-rpc-parity replays recorded geth-XDC requests against the xOne handlers. It diffs each answer with the recorded one. A row is equal, differ, not-backed or allowlisted. A not-backed row means the data does not exist in the replayed chain. The report names the reason.

REFERENCE TABLEScroll to explore all columns →
Network equal differ not-backed allowlisted
Apothem (replayed tip 1,800) 820 0 1,774 16
net2040 (replayed tip 747,006) 1,038 0 1,577 4

Both reports have 0 differ rows. That is not full coverage: most rows are not backed yet. Reports are in conformance/rpc-parity/report.

The other clients

xOneTS, xOnePy and xOneC use the same gate DAG and the same vectors, vendored from xOneRS. These three repositories are private.

  • xOneTS has a port of the harness. Its RUNS.md records net2040 1..21600 (4,205,493 transactions, 13 V2 switches) and Apothem 1..432000, both at 0 mismatches. Its RPC parity folder is still a placeholder.
  • xOnePy records net2040 1..21600 and Apothem 1801..432000 at 0 mismatches. A later row covers net2040 21601..60000 (42 V2 switches, 2026-11-13). See RUNS.md.
  • xOneC records net2040 1..21,600 and Apothem 1..432,000 at 0 mismatches in its gate B record. It also keeps a bench fixture, net2040-21970.json.gz: block 21,970 with 5,032 transfers. Each run must reproduce the archive's gasUsed, receiptsRoot, bloom, transactionsRoot, access-list hash and state-diff digest.

xOnePy and xOneC also check in CI that their vendor/xone copy equals its pin.

Sources