Skip to content

audit: harden the verify sidecar + add tests, benchmark, coverage docs#3

Merged
dkijania merged 4 commits into
mainfrom
verify/sidecar-audit-tests
Jun 17, 2026
Merged

audit: harden the verify sidecar + add tests, benchmark, coverage docs#3
dkijania merged 4 commits into
mainfrom
verify/sidecar-audit-tests

Conversation

@dkijania

Copy link
Copy Markdown
Member

Stacked on #2 (the HTTP verify sidecar). Review/merge #2 first; this branch's base
will retarget to main automatically once #2 merges.

An audit pass over the sidecar plus the test/benchmark coverage the workspace was
missing (it had a single test before this).

Audit → robustness fixes

The sidecar accepts an untrusted POST body, so two hardening fixes:

  • Body-size cap (MAX_BODY_BYTES = 32 MiB). The body was read with an unbounded
    read_to_end into a Vec; a single oversized POST could exhaust memory. Oversized
    bodies now truncate into a clean 400 instead.
  • Per-request panic isolation. Verification runs inside catch_unwind, so a
    malformed-but-decodable block that trips an assertion deep in the verifier fails
    that one request (500) instead of killing a worker thread (which would silently
    shrink the pool over time).
  • Refactored main.rs → lib + thin bin so the router is a pure, unit-testable
    dispatch(method, path, body) -> (status, json).

Non-blocking observation (not changed): header_from_precomputed labels block-decode
failures as VerifierError::InvalidIndexJson (a clearer BlockDecode variant exists);
it maps to 400 correctly, so it's cosmetic.

Tests

  • mina-verify unit tests — decode error paths for header_from_precomputed (bad
    JSON, missing protocol_state/proof, non-base64 proof, bare vs {version,data}
    envelope).
  • mina-verify heavy integration test (#[ignore]) — verifies a real devnet
    block
    end-to-end and rejects a height-tampered one (ProofInvalid).
  • mina-verify-server unit tests (dispatch: health / 404 / 400 mapping) and
    acceptance tests that spawn the real binary and drive it over a dependency-free
    HTTP/1.1 client (fast: health / bad-request / not-found; heavy #[ignore]: a real
    block → valid:true with correct hashes, and a tampered one → valid:false).

Fast suite runs in CI; heavy proof tests via cargo test --workspace --release -- --ignored.

Benchmark

cargo bench -p mina-verify (a harness=false binary, no new deps) times decode +
verify: warm ~0.4 s/block (~2.25 blocks/sec/core), first verify ~2.7 s (SRS
priming), VK build ~5 s.

Fixture

tests/fixtures/devnet-528700.json — a real precomputed devnet block (height 528700)
from the public mina_network_block_data bucket, shared by the heavy tests and the
bench. It is intentionally not strictly UTF-8, so it also exercises the lossy-decode
path.

Docs

Root README gains the missing mina-verify-server / mina-verify-wasm crate rows and a
Testing / Benchmarks / Coverage section; server README documents the hardening, the
network:"custom" health label under MINA_VK_JSON, a Tests section, and the measured
throughput.

🤖 Generated with Claude Code

dkijania and others added 4 commits June 17, 2026 22:40
Move all logic into the library (`mina_verify_server`) behind a thin `main`, so
the router and verify path are unit-testable without spawning a process or running
a proof. `dispatch(method, path, body) -> (status, json)` is now pure.

Two hardening fixes for untrusted input (the POST body):
- cap the buffered body at 32 MiB (MAX_BODY_BYTES); an oversized body is truncated
  into a clean 400 rather than an unbounded allocation.
- run verification inside catch_unwind: a malformed-but-decodable block that trips
  an assertion deep in the verifier now fails that one request (500) instead of
  killing a worker thread (which would silently shrink the pool over time).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Before this the workspace had a single test. Add:
- mina-verify: fast decode tests for `header_from_precomputed` (bad JSON, missing
  protocol_state / proof, non-base64 proof, bare vs {version,data} envelope), and a
  heavy `#[ignore]`d integration test that verifies a real devnet block end-to-end
  and rejects a height-tampered one (ProofInvalid).
- mina-verify-server: pure-router unit tests (dispatch: health/404/400 mapping) and
  acceptance tests that spawn the real binary and drive it over a dependency-free
  HTTP/1.1 client (fast: health/bad-request/not-found; heavy `#[ignore]`d:
  valid:true with correct facts, and a tampered block -> valid:false).
- a `cargo bench -p mina-verify` harness (harness=false, no new deps) timing
  decode+verify: ~0.4 s/block warm (~2.25 blocks/sec/core), first verify ~2.7 s.

Fixture: tests/fixtures/devnet-528700.json — a real precomputed devnet block from
the public mina_network_block_data bucket. It is not strictly UTF-8, so it also
exercises the lossy-decode path. Heavy tests/bench run in release:
  cargo test --workspace --release -- --ignored

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- root README: list mina-verify-server and mina-verify-wasm in the crates table;
  add a Testing & benchmarks section (fast vs heavy `--ignored`, the shared fixture,
  the tarpaulin coverage command).
- server README: document the body cap + per-request panic isolation, the
  `network:"custom"` health label under MINA_VK_JSON, a Tests section, and the
  measured warm throughput (~0.4 s/block) in place of the old ~1-2 s estimate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e for the server)

The plain tarpaulin command measured the vendored `openmina/` tree (7485 lines) and
the ptrace engine can't follow the server acceptance test's spawned child. Document
`--exclude-files 'openmina/*'` and `--engine llvm` for the server, and note that the
verify paths are covered by the heavy `#[ignore]`d tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dkijania dkijania changed the base branch from verify/http-sidecar to main June 17, 2026 21:40
@dkijania dkijania merged commit 9ff9767 into main Jun 17, 2026
8 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