Skip to main content
A conformance corpus that’s slightly wrong is worse than none: it trains everyone to agree on the wrong answer. So the first thing Istravex does on every run is prove that each fixture is exactly what the network recorded.

Canonical ledgers

For each fixture, the full LedgerCloseMeta of its ledger is stored in corpus/ledgers/<network>/<seq>.xdr.zst, as a zstd-compressed LedgerCloseMetaBatch. That’s the same layout SDF uses for its public data lake. corpus/ledgers/index.json records each ledger’s sha256 (of the decompressed XDR), its size and its source.
Testnet ledgers are snapshots. Re-fetching testnet ledgers 5,727,196 and 5,727,199 from the same RPC endpoint a few hours apart returned different bytes. A different node behind the load balancer answered, and node-local diagnostic events differ between nodes. So kit/capture/ledgers.mjs never overwrites a stored ledger unless you pass --refresh. See Compare only consensus data.

The verifier

kit/go/cmd/verify checks every fixture, in order:
1

Manifest

manifest.json parses and validates against corpus/manifest.schema.json.
2

Files

Each file decodes, and its sha256 and size match the manifest.
3

Ledger

The stored ledger’s sha256 matches index.json, and its header’s protocol version matches the manifest.
4

Transaction

The fixture’s transaction is found in that ledger by hash, using go-stellar-sdk’s ingestion reader with the network’s passphrase.
5

Byte equality

Every XDR value in the fixture (envelope, result, fee changes, meta) is byte-identical to the ledger’s copy. For ledger-entry fixtures, the entry is found among the transaction’s changes.
It writes corpus/results/provenance.json and exits non-zero on any failure, which fails CI. Today: 62 of 62 checks pass.

Why the fixture is cut from the ledger

Testnet fixtures were first captured from getTransaction, and the verifier caught the problem immediately: one RPC node’s meta and another node’s ledger differed in a single diagnostic value. Rather than special-case that, kit/capture/canonicalize.mjs rewrites each fixture’s meta from the stored ledger. The ledger is the source of truth; the fixture is a slice of it.