mirror of
https://github.com/vacp2p/linea-monorepo.git
synced 2026-01-09 04:08:01 -05:00
Prover(fix): setup execution-large (#844)
* fix execution large circuitID and add sanity-check for traces limits checksum between setup and config * fix: add sync.once fullZkEvmSetup and fullZkEvmSetupLarge for setup * fix: prover large cbor Unmarshal error "exceeded max number of elements" - use default value (131072) x 1024 for MaxArrayElements and MaxMapPairs
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package execution
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/linea-monorepo/prover/circuits"
|
||||
"github.com/consensys/linea-monorepo/prover/circuits/dummy"
|
||||
@@ -23,11 +26,6 @@ func Prove(cfg *config.Config, req *Request, large bool) (*Response, error) {
|
||||
// Set MonitorParams before any proving happens
|
||||
profiling.SetMonitorParams(cfg)
|
||||
|
||||
traces := &cfg.TracesLimits
|
||||
if large {
|
||||
traces = &cfg.TracesLimitsLarge
|
||||
}
|
||||
|
||||
var resp Response
|
||||
|
||||
// TODO @gbotrel wrap profiling in the caller; so that we can properly return errors
|
||||
@@ -48,8 +46,8 @@ func Prove(cfg *config.Config, req *Request, large bool) (*Response, error) {
|
||||
// - NewFromString can panic
|
||||
out.Proof, out.VerifyingKeyShaSum = mustProveAndPass(
|
||||
cfg,
|
||||
traces,
|
||||
NewWitness(cfg, req, &out),
|
||||
large,
|
||||
)
|
||||
|
||||
out.Version = cfg.Version
|
||||
@@ -75,10 +73,15 @@ func Prove(cfg *config.Config, req *Request, large bool) (*Response, error) {
|
||||
// when calling it twice.
|
||||
func mustProveAndPass(
|
||||
cfg *config.Config,
|
||||
traces *config.TracesLimits,
|
||||
w *Witness,
|
||||
large bool,
|
||||
) (proofHexString string, vkeyShaSum string) {
|
||||
|
||||
traces := &cfg.TracesLimits
|
||||
if large {
|
||||
traces = &cfg.TracesLimitsLarge
|
||||
}
|
||||
|
||||
switch cfg.Execution.ProverMode {
|
||||
case config.ProverModeDev, config.ProverModePartial:
|
||||
if cfg.Execution.ProverMode == config.ProverModePartial {
|
||||
@@ -119,8 +122,21 @@ func mustProveAndPass(
|
||||
errSetup error
|
||||
chSetupDone = make(chan struct{})
|
||||
)
|
||||
|
||||
circuitID := circuits.ExecutionCircuitID
|
||||
if large {
|
||||
circuitID = circuits.ExecutionLargeCircuitID
|
||||
}
|
||||
|
||||
// Sanity-check trace limits checksum between setup and config
|
||||
if err := SanityCheckTracesChecksum(circuitID, traces, cfg); err != nil {
|
||||
utils.Panic("traces checksum in the setup manifest does not match the one in the config: %v", err)
|
||||
}
|
||||
|
||||
// Start loading the setup
|
||||
go func() {
|
||||
setup, errSetup = circuits.LoadSetup(cfg, circuits.ExecutionCircuitID)
|
||||
logrus.Infof("Loading setup - circuitID: %s", circuitID)
|
||||
setup, errSetup = circuits.LoadSetup(cfg, circuitID)
|
||||
close(chSetupDone)
|
||||
}()
|
||||
|
||||
@@ -139,21 +155,6 @@ func mustProveAndPass(
|
||||
utils.Panic("could not load setup: %v", errSetup)
|
||||
}
|
||||
|
||||
// ensure the checksum for the traces in the setup matches the one in the config
|
||||
setupCfgChecksum, err := setup.Manifest.GetString("cfg_checksum")
|
||||
if err != nil {
|
||||
utils.Panic("could not get the traces checksum from the setup manifest: %v", err)
|
||||
}
|
||||
|
||||
if setupCfgChecksum != traces.Checksum() {
|
||||
// This check is failing on prod but works locally.
|
||||
// @alex: since this is a setup-related constraint, it would likely be
|
||||
// more interesting to directly include that information in the setup
|
||||
// instead of the config. That way we are guaranteed to not pass the
|
||||
// wrong value at runtime.
|
||||
utils.Panic("traces checksum in the setup manifest does not match the one in the config")
|
||||
}
|
||||
|
||||
// TODO: implements the collection of the functional inputs from the prover response
|
||||
return execution.MakeProof(traces, setup, fullZkEvm.WizardIOP, proof, *w.FuncInp), setup.VerifyingKeyDigest()
|
||||
|
||||
@@ -187,3 +188,31 @@ func mustProveAndPass(
|
||||
panic("not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
// SanityCheckTraceChecksum ensures the checksum for the traces in the setup matches the one in the config
|
||||
func SanityCheckTracesChecksum(circuitID circuits.CircuitID, traces *config.TracesLimits, cfg *config.Config) error {
|
||||
|
||||
// read setup manifest
|
||||
manifestPath := filepath.Join(cfg.PathForSetup(string(circuitID)), config.ManifestFileName)
|
||||
manifest, err := circuits.ReadSetupManifest(manifestPath)
|
||||
if err != nil {
|
||||
utils.Panic("could not read the setup manifest: %v", err)
|
||||
}
|
||||
|
||||
// read manifest traces checksum
|
||||
setupCfgChecksum, err := manifest.GetString("cfg_checksum")
|
||||
if err != nil {
|
||||
utils.Panic("could not get the traces checksum from the setup manifest: %v", err)
|
||||
}
|
||||
|
||||
if setupCfgChecksum != traces.Checksum() {
|
||||
// This check is failing on prod but works locally.
|
||||
// @alex: since this is a setup-related constraint, it would likely be
|
||||
// more interesting to directly include that information in the setup
|
||||
// instead of the config. That way we are guaranteed to not pass the
|
||||
// wrong value at runtime.
|
||||
return fmt.Errorf("setup (%s): '%s' vs config: '%s'", circuitID, setupCfgChecksum, traces.Checksum())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -99,20 +99,23 @@ func Setup(context context.Context, args SetupArgs) error {
|
||||
// we skip aggregation in this first loop since the setup is more complex
|
||||
continue
|
||||
}
|
||||
logrus.Infof("setting up %s", c)
|
||||
logrus.Infof("Setting up %s", c)
|
||||
|
||||
var builder circuits.Builder
|
||||
extraFlags := make(map[string]any)
|
||||
|
||||
// let's compile the circuit.
|
||||
switch c {
|
||||
case circuits.ExecutionCircuitID, circuits.ExecutionLargeCircuitID:
|
||||
case circuits.ExecutionCircuitID:
|
||||
limits := cfg.TracesLimits
|
||||
if c == circuits.ExecutionLargeCircuitID {
|
||||
limits = cfg.TracesLimitsLarge
|
||||
}
|
||||
extraFlags["cfg_checksum"] = limits.Checksum()
|
||||
zkEvm := zkevm.FullZkEvm(&limits, cfg)
|
||||
zkEvm := zkevm.FullZkEvmSetup(&limits, cfg)
|
||||
builder = execution.NewBuilder(zkEvm)
|
||||
|
||||
case circuits.ExecutionLargeCircuitID:
|
||||
limits := cfg.TracesLimitsLarge
|
||||
extraFlags["cfg_checksum"] = limits.Checksum()
|
||||
zkEvm := zkevm.FullZkEvmSetupLarge(&limits, cfg)
|
||||
builder = execution.NewBuilder(zkEvm)
|
||||
|
||||
case circuits.BlobDecompressionV0CircuitID:
|
||||
@@ -270,7 +273,7 @@ func updateSetup(ctx context.Context, cfg *config.Config, force bool, srsProvide
|
||||
}
|
||||
|
||||
// compile the circuit
|
||||
logrus.Infof("compiling %s", circuit)
|
||||
logrus.Infof("Compiling %s", circuit)
|
||||
ccs, err := builder.Compile()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compile circuit %s: %w", circuit, err)
|
||||
@@ -279,33 +282,38 @@ func updateSetup(ctx context.Context, cfg *config.Config, force bool, srsProvide
|
||||
// derive the asset paths
|
||||
setupPath := cfg.PathForSetup(string(circuit))
|
||||
manifestPath := filepath.Join(setupPath, config.ManifestFileName)
|
||||
logrus.Infof("Manifest path: %s", manifestPath)
|
||||
|
||||
// check if setup can be skipped
|
||||
if !force {
|
||||
// we may want to skip setup if the files already exist
|
||||
// and the checksums match
|
||||
// read manifest if already exists
|
||||
if manifest, err := circuits.ReadSetupManifest(manifestPath); err == nil {
|
||||
circuitDigest, err := circuits.CircuitDigest(ccs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compute circuit digest for circuit %s: %w", circuit, err)
|
||||
}
|
||||
|
||||
logrus.Infof("Manifest checksum: %s, Computed circuit digest: %s", manifest.Checksums.Circuit, circuitDigest)
|
||||
if manifest.Checksums.Circuit == circuitDigest {
|
||||
logrus.Infof("skipping %s (already setup)", circuit)
|
||||
logrus.Infof("Skipping %s (already setup)", circuit)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// run the actual setup
|
||||
logrus.Infof("plonk setup for %s", circuit)
|
||||
logrus.Infof("Plonk setup for %s", circuit)
|
||||
setup, err := circuits.MakeSetup(ctx, circuit, ccs, srsProvider, extraFlags)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to setup circuit %s: %w", circuit, err)
|
||||
}
|
||||
|
||||
logrus.Infof("writing assets for %s", circuit)
|
||||
return setup.WriteTo(setupPath)
|
||||
// write the assets
|
||||
err = setup.WriteTo(setupPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write assets for circuit %s: %w", circuit, err)
|
||||
}
|
||||
logrus.Infof("Successfully wrote circuit %s to %s", circuit, setupPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listOfChecksums Computes a list of SHA256 checksums for a list of assets, the result is given
|
||||
|
||||
@@ -29,7 +29,16 @@ func serializeAnyWithCborPkg(x any) json.RawMessage {
|
||||
|
||||
// deserializeAnyWithCborPkg calls [json.Unmarshal] and wraps the error if any.
|
||||
func deserializeAnyWithCborPkg(data json.RawMessage, x any) error {
|
||||
if err := cbor.Unmarshal(data, x); err != nil {
|
||||
opts := cbor.DecOptions{
|
||||
MaxArrayElements: 134217728, // MaxArrayElements specifies the max number of elements for CBOR arrays.
|
||||
MaxMapPairs: 134217728, // MaxMapPairs specifies the max number of key-value pairs for CBOR maps.
|
||||
}
|
||||
decMode, err := opts.DecMode()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create CBOR decoder mode: %w", err)
|
||||
}
|
||||
|
||||
if err := decMode.Unmarshal(data, x); err != nil {
|
||||
return fmt.Errorf("cbor.Unmarshal failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -26,10 +26,14 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
fullZkEvm *ZkEvm
|
||||
fullZkEvmCheckOnly *ZkEvm
|
||||
onceFullZkEvm = sync.Once{}
|
||||
onceFullZkEvmCheckOnly = sync.Once{}
|
||||
fullZkEvm *ZkEvm
|
||||
fullZkEvmCheckOnly *ZkEvm
|
||||
fullZkEvmSetup *ZkEvm
|
||||
fullZkEvmSetupLarge *ZkEvm
|
||||
onceFullZkEvm = sync.Once{}
|
||||
onceFullZkEvmCheckOnly = sync.Once{}
|
||||
onceFullZkEvmSetup = sync.Once{}
|
||||
onceFullZkEvmSetupLarge = sync.Once{}
|
||||
|
||||
// This is the SIS instance, that has been found to minimize the overhead of
|
||||
// recursion. It is changed w.r.t to the estimated because the estimated one
|
||||
@@ -121,6 +125,20 @@ func FullZkEVMCheckOnly(tl *config.TracesLimits, cfg *config.Config) *ZkEvm {
|
||||
return fullZkEvmCheckOnly
|
||||
}
|
||||
|
||||
func FullZkEvmSetup(tl *config.TracesLimits, cfg *config.Config) *ZkEvm {
|
||||
onceFullZkEvmSetup.Do(func() {
|
||||
fullZkEvmSetup = FullZKEVMWithSuite(tl, fullCompilationSuite, cfg)
|
||||
})
|
||||
return fullZkEvmSetup
|
||||
}
|
||||
|
||||
func FullZkEvmSetupLarge(tl *config.TracesLimits, cfg *config.Config) *ZkEvm {
|
||||
onceFullZkEvmSetupLarge.Do(func() {
|
||||
fullZkEvmSetupLarge = FullZKEVMWithSuite(tl, fullCompilationSuite, cfg)
|
||||
})
|
||||
return fullZkEvmSetupLarge
|
||||
}
|
||||
|
||||
// FullZKEVMWithSuite returns a compiled zkEVM with the given compilation suite.
|
||||
// It can be used to benchmark the compilation time of the zkEVM and helps with
|
||||
// performance optimization.
|
||||
|
||||
Reference in New Issue
Block a user