feat: trustless block verification (verifyPrecomputedBlock / checkBlockClaims)#10
Open
dkijania wants to merge 4 commits into
Open
feat: trustless block verification (verifyPrecomputedBlock / checkBlockClaims)#10dkijania wants to merge 4 commits into
dkijania wants to merge 4 commits into
Conversation
…ckClaims)
Add an in-process block-proof verifier to the SDK. A block whose Pickles/kimchi
SNARK proof verifies attests its entire chain history by recursion, so a JS client
can check chain validity against an untrusted source (node, indexer, GCS archive)
without trusting the bytes.
New API (src/verify.ts):
- verifyPrecomputedBlock(precomputed, { network }) -> VerifiedBlock
{ height, stateHash, previousStateHash, stagedLedgerHash } (all proof-backed)
- checkBlockClaims(precomputed, claimed) -> { honest, facts, mismatches }
endpoint-honesty primitive: does an untrusted source's claim match the proof?
- compareToClaims(facts, claimed) -> HonestyResult (pure, no I/O)
- VerificationError (proof failed) / VerificationBackendError (backend missing)
The proof verifier is a WebAssembly module (mina-verify-wasm) that is NOT bundled
(it is several MB) and is loaded lazily via a runtime dynamic import, so the SDK
stays lightweight and installs without it; a clear error tells users to
`npm install mina-verify-wasm`. Bundle size unchanged (~26 KB).
Note: a daemon's GraphQL `protocolState` is a lossy projection and cannot be
re-hashed to verify a proof — the verifiable input is a precomputed block (the
full-protocol-state JSON daemons publish to GCS / the archive).
Verified end-to-end: a real devnet precomputed block verifies through the SDK and
returns facts identical to the native verifier; checkBlockClaims flags a lying
endpoint. Unit tests cover the comparison logic and the backend-missing path
(mocked, deterministic). Verification is single-threaded today (~tens of seconds
per block); a threaded backend is a planned follow-up.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The proof check is a synchronous, CPU-bound wasm call (tens of seconds), so the async wrapper bought nothing — it held the event loop during the verify either way; the only async part was loading the backend. Load the backend synchronously (createRequire(import.meta.url); the nodejs-target wasm pkg instantiates on require) and return values directly. - verifyPrecomputedBlock(...) -> VerifiedBlock (was Promise<VerifiedBlock>) - checkBlockClaims(...) -> HonestyResult (was Promise<HonestyResult>) Simpler call sites (no await); blocking is documented. Verified: both ESM and CJS builds compile (esbuild shims import.meta.url in CJS), real devnet block verifies synchronously through the SDK, all 32 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
createRequire(import.meta.url) only finds mina-verify-wasm if it is hoisted next to the SDK. Also try the host process cwd, so a backend installed at the app root (or an SDK that is symlinked / pnpm-isolated) resolves. Needed for consumers like the MCP server that install the backend at their own root. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an in-process block-proof verifier to the SDK. A block whose Pickles/kimchi SNARK proof verifies attests its entire chain history by recursion — so a JS client can check chain validity against an untrusted source (a node, an indexer, a GCS archive) without trusting the bytes.
API (
src/verify.ts)verifyPrecomputedBlock(precomputed, { network }) → VerifiedBlockcheckBlockClaims(precomputed, claimed) → { honest, facts, mismatches }compareToClaims(facts, claimed) → HonestyResult— pure, no I/OVerificationError(proof failed → do not ingest) /VerificationBackendError(backend missing)Design
mina-verify-wasm, not bundled (several MB) and loaded lazily via a runtime dynamic import. SDK stays lightweight and installs without it; a clear error directs users tonpm install mina-verify-wasm. Bundle size unchanged (~26 KB).protocolStateis a lossy projection and can't be re-hashed to verify a proof. The verifiable input is a precomputed block (the full-protocol-state JSON daemons publish to GCS / the archive).Verification
mina-verify;checkBlockClaimsflags a lying endpoint.Caveat / follow-up
Single-threaded today (~tens of seconds/block) — fine for periodic/background checks. A threaded wasm backend (worker pool) is the planned perf follow-up.
🤖 Generated with Claude Code