# Test snapshot fixture (at scale) This package builds the eligibility snapshot for a vending-machine instance, and it holds the **canonical at-scale test fixture** the recovery-contract tests run against: a deterministic, realistic, full-capacity snapshot of **16,384 wallets** (the full depth-14 Merkle capacity, `1 << drv.MerkleDepth`). ## What's committed (`testdata/`) - **`snapshot-16384.json`** — the full eligibility `Snapshot`: the Merkle `root`, `version`, `script_hash_tag`, and 16,384 `Entry` records, each carrying a credential `C` (28 B), the canonical 553-byte `entitlement`, and the depth-14 inclusion path (siblings + direction bits). **No key material.** ~29 MB; marked `-text` in `.gitattributes` so it stays byte-stable across platforms. - **`manifest.json`** — the reproducibility anchor: `count`, `root` (`348e02ee…cacc`), the seeds (`refgen_seed`, `ada_seed`, `asset_seed`), `snapshot_sha256`, `assets_fraction`, and ADA quantiles. - **`golden-claims.json`** — a few designated claim wallets (`first`, `multiasset`, `whale`) with full witness inputs (`master_xprv`, `C`, `entitlement`, `role`, depth-14 inclusion path, destination `D`). These are deterministic **Preview-only, zero-value** test keys, consistent with the repo's committed-testnet-key boundary — they exist to drive end-to-end prover/validator tests against the real scale root. ## The fixture in numbers - **16,384 wallets** — the full depth-14 Merkle tree, root `348e02ee…cacc`. - **Long-tail ADA**: 2 ADA floor (min-UTxO) → p50 ≈ 357 ADA → p90 ≈ 49.7k ADA → p99 ≈ 989k ADA → max ≈ 20M ADA (a ~1% whale tail). - **~19.9%** of wallets carry **1–8 native assets**, exercising the multi-asset 553-byte entitlement encoding (ascending `(policy, name)` sort, `MaxAssets`, per-asset min-UTxO). ## How holdings are assigned (`holdings.go`) Deterministic and **integer-only**: every draw is `sha256(seed ‖ C ‖ label ‖ LE32(i))` keyed by the wallet's credential `C` — no `math/rand`, no floating-point — so the fixture regenerates **byte-identically on any machine**. ADA is drawn from 70/20/9/1 long-tail buckets; ~20% of wallets get native assets; every entitlement is clamped to a min-UTxO floor (`2 ADA + 0.4 ADA per asset`) so it is always a payable UTxO. ## Regenerating (deterministic) ```sh cd proto/vending go run ./snapshot/cmd/gen-testsnapshot \ --count 16384 \ --refgen-bin ../circuit/refgen/target/release/e2-refgen \ --refgen-seed 00 --ada-seed ada-seed-v1 --asset-seed asset-seed-v1 \ --out-dir snapshot/testdata ``` Wallets come from the `e2-refgen` oracle (deterministic from `--refgen-seed`); holdings are layered on; `BuildSnapshot` folds the depth-14 tree. A fresh run reproduces the committed files byte-for-byte (same `root` and `snapshot_sha256`). ## How it's verified - **`reproduce_test.go`** (fast, no Rust toolchain): regenerates holdings + the Merkle tree from the committed credentials and asserts the recomputed `root` == committed == `manifest.root` with every one of the 16,384 entitlements byte-matched; plus integrity (exactly 16,384 entries, no duplicate credentials, sampled inclusion paths fold to the root), realism (distribution shape, ~20% assets, min-UTxO floor), and golden-claim consistency. - **`fullpipeline_test.go`** (`//go:build perf`): runs the whole generator from the manifest's seeds (including `e2-refgen`) and asserts the regenerated `root` + `snapshot_sha256` match the committed manifest — guards the entire chain. Run with `REFGEN_BIN=<…/e2-refgen> go test -tags perf ./ -run TestFullPipelineRegen`. ## Consuming the fixture Validator and Merkle tests read `snapshot-16384.json` for the root and inclusion paths. End-to-end prover/validator tests target a `golden-claims.json` wallet (its master key + depth-14 path) against the real root. Generating an actual Groth16 proof for a golden wallet, and wiring `realprove`/the validator to consume the scale snapshot, are tracked follow-ups.