feat(prover): persist the derived Lagrange SRS so it isn't re-derived on every start - #3733
Open
coeniebeyers wants to merge 31 commits into
Open
feat(prover): persist the derived Lagrange SRS so it isn't re-derived on every start#3733coeniebeyers wants to merge 31 commits into
coeniebeyers wants to merge 31 commits into
Conversation
Signed-off-by: Marelize <marelize.kriel@adhara.io> Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…test Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
… on every start Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…ename Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…mment Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Marelize <marelize.kriel@adhara.io>
…eremony material Signed-off-by: Marelize <marelize.kriel@adhara.io>
Signed-off-by: Marelize <marelize.kriel@adhara.io>
…ault off Signed-off-by: Marelize <marelize.kriel@adhara.io>
…g even when circuits are current Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…emory derivation Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
… when unwritable, and quiet at dummy sizes Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
… setup section Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…r at prove time Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…ling setup Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…of trusting it Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…after it Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…ence after setup Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…ation, not after Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…ts cleanup Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…rveFileNames Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
…ap over-limit lines Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
… not-found Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Signed-off-by: Coenie Beyers <coenie.beyers@adhara.io>
Author
|
Review notes — observations we deliberately did not act on in this PR:
|
This was referenced Aug 6, 2026
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.
This PR implements issue(s) #3584.
Stacked on #3732: the first two commits are that PR's
WriterstoEqualfix, which the new verifying-key check here depends on; this branch will be rebased once #3732 lands.When no Lagrange-form SRS dump is on disk,
SRSStorederives it from the canonical SRS in memory and discards it on exit — a multi-hour derivation repeated on every prover start, with a single debug-level log line as the only indication. This PR makes the derivation happen at most once per store directory, by separating reading from provisioning:GetSRS(prove time) remains a pure read. A miss still derives in memory, but at real circuit sizes it now warns before the derivation and names the command that resolves it. It never writes: the SRS directory can be mounted read-only.prover setupprovisions. It derives, validates and atomically publishes the dump under the provenance tagderived— locally computed material never claims a ceremony's name — and backfills a missing dump even when circuit assets are current.persist_derived_srsdefaults to on; set it tofalseif the SRS directory must never be written to (for example, a read-only or shared asset store).--forcere-validates an existing dump in full and replaces it if it does not load.Failure modes, each pinned by a test:
ReadDumperror → re-deriveprover setuprun, once its last write is more than an hour oldBehaviour changes:
GetSRS; it is now logged and re-derived. Canonical (ceremony) load failures remain fatal.kzg_srs_canonical_<n>_<curve>_derived.memdump— a name the code never produces — was previously accepted as trusted ceremony material; it is now warned about and ignored.prover setuprather than at store construction; reads never modify the directory.copy-prover-assetsMakefile target now excludes*_derived*, keeping derived dumps machine-local rather than syncing them into the shared asset bucket. If distributing them through the bucket is preferred, remove the exclusion — we left that as an explicit decision for the maintainers.Numbers: loading a Lagrange dump from disk is the pre-existing fast path — deployments that ship pre-derived dumps already pay it on every start (~14 s at 2^27 on a real 13 GiB bls12-377 dump, 8 cores: 9.3 s read, 4.8 s parse). What this PR changes is who can take that path: deployments without shipped dumps previously re-derived in memory for hours on every start; now
prover setupwrites the dump once and later starts load it like any other. The one added cost is ~1.3 s of load-time validation (point count, verifying-key equality, on-curve scan), since the store may now be loading locally-written rather than only ceremony-shipped material. Disk grows by one dump per Lagrange size, the same order of magnitude as the canonical files already present. The feature was also exercised end-to-end through the built CLI: every operator flow (persist, no-op re-run, backfill,--forcerepair, orphan cleanup, opt-out, read-only directory) behaves as documented, and at 2^21 a fresh process loads the persisted dump in 0.1 s against the 93 s derivation it replaces.Substitution of validly-encoded points is out of scope, as it is for every file in the store. gofmt, golangci-lint and the test suite (
-race,-tags nocorset,fuzzlight) all pass.Checklist
No breaking API changes.
Potential follow-up issues
Found while implementing this change and exploring the codebase; none are addressed in this PR, and we are happy to file each as its own issue:
protocol/serde/decoder.go— an integer overflow can bypass the deserializer's length bounds check, so a corrupted or crafted asset can be accepted (the same pattern appears at two more sites in the file).cmd/controller/controller.go— a crashed large-mode job is recovered under a file name no input pattern matches, silently dropping it from the queue.lib/compressor/blob/v2/test_utils— buffer aliasing causes the multi-blob test to run on duplicated data rather than two distinct blobs.symbolic/constructor_ext_test.go— the parent-structure assertion compares the expected value to itself, so its fourteen fixtures verify nothing.circuits/aggregation/circuit_test.go— a memoized test SRS makes every "different" verifying key byte-identical, so per-key selection is never exercised.Thanks
Thanks @mkrielza for your help shaping this PR and for finding the
WriterstoEqualissue.