Skip to content

feat: baked pubkey→index map (mapgen + release bake) — no cold sweep#9

Merged
dkijania merged 1 commit into
mainfrom
feat/baked-index-map
Jun 19, 2026
Merged

feat: baked pubkey→index map (mapgen + release bake) — no cold sweep#9
dkijania merged 1 commit into
mainfrom
feat/baked-index-map

Conversation

@dkijania

Copy link
Copy Markdown
Collaborator

Removes the multi-minute cold-start sweep: /account?pubkey= resolves instantly from a baked pubkey → leaf-index map.

What

  • index_map — compact [u64 covered][16-byte blake2b(addr)][u32 index] blob, binary-searchable, format-compatible with the mina-verify-mobile embedded map. Unit-tested (build/lookup/load roundtrip).
  • mina-light-node-mapgen — release-time generator: fetch + verify the tip → staking-epoch-ledger root → sweep → write <network>_index_map.bin.
  • server — loads LIGHT_NODE_INDEX_MAP at startup → by-pubkey is instant; the background sweep then only fills the appended tail. Empty placeholder ⇒ runtime sweep (unchanged behaviour).
  • deploy — the image bakes deploy/index_map.bin (an empty in-tree placeholder) at /opt and sets the env; release.yml runs mapgen per network, bakes the real map into each image, and attaches the .bin to the GitHub Release. A flaky sweep falls back to the placeholder, so it never blocks the image.
  • Factored the chunked sweep into mina_light_node::sweep_index_map (shared by the server + mapgen).

On the S3 tarball

The map is generated by an RPC sweep, not the s3://snark-keys-ro.o1test.net/epoch_ledger_<hash>.tar.gz tarball. That tarball is a RocksDB database — the public key is readable in the key, but the leaf index lives in the value as Mina's internal Location encoding, which is unproven to decode in Rust (the mobile app swept rather than decode it). Decoding the tarball is kept as a follow-up ([ ] in the README); the RPC sweep achieves the same baked artifact today, reusing validated code.

Validated live (devnet)

mapgen → 91585 pairs → /tmp/devnet_index_map.bin (1.6 MB)
server: "loaded baked index map: 81611 keys, covered 91585"
GET /account?pubkey=B62qiy32… → balance 320482501000, nonce 0, h529032  (instant, no sweep)

fmt + clippy -D warnings clean; cargo test green (3 index_map + 8 relay unit, 2 gated e2e).

🤖 Generated with Claude Code

Adds the baked account-index map so /account?pubkey= resolves instantly,
without the multi-minute cold-start epoch-ledger sweep.

- index_map: compact [covered][16-byte blake2b key][u32 index] format
  (binary-searchable; mina-verify-mobile-compatible), with unit tests.
- lib: factor the chunked sweep into mina_light_node::sweep_index_map
  (shared by the server's tail-sweep and the generator).
- mina-light-node-mapgen: release-time generator — fetch+verify tip,
  derive the staking-epoch-ledger root, sweep, write <network>.bin.
- server: load LIGHT_NODE_INDEX_MAP at startup (empty placeholder => sweep
  fallback); index keyed by addr-hash so baked + swept entries unify.
- deploy: image bakes deploy/index_map.bin (empty in-tree placeholder)
  at /opt and sets LIGHT_NODE_INDEX_MAP.
- release.yml: index-map job runs mapgen per network, bakes the map into
  each image, and attaches the .bin to the release (placeholder fallback
  if a sweep is flaky, so it never blocks the image).

Generation is an RPC sweep, not the S3 RocksDB tarball: the tarball stores
the leaf index in Mina's internal RocksDB Location encoding (unproven to
decode; the mobile app swept too) — kept as a follow-up.

Validated live on devnet: mapgen wrote a 91585-pair / 1.6 MB map; the
server loaded it (81611 keys) and answered /account?pubkey= instantly on
the first verified tip (h529032), no cold sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117RNu925HJ97mFHLbQG4Y9
@dkijania dkijania merged commit 8307b0a into main Jun 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant