From e66f09736f585e34c6a2c4c59dee5b66286ab9f9 Mon Sep 17 00:00:00 2001 From: Arya Tabaie <15056835+Tabaie@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:49:16 -0600 Subject: [PATCH 1/3] refactor prove/setup args --- prover/cmd/prover/cmd/prove.go | 55 +++++++++++++----------- prover/cmd/prover/cmd/setup.go | 77 +++++++++++++++++++--------------- 2 files changed, 74 insertions(+), 58 deletions(-) diff --git a/prover/cmd/prover/cmd/prove.go b/prover/cmd/prover/cmd/prove.go index c0a64d96339..e25627075ca 100644 --- a/prover/cmd/prover/cmd/prove.go +++ b/prover/cmd/prover/cmd/prove.go @@ -15,11 +15,14 @@ import ( "github.com/spf13/cobra" ) -var ( - fInput string - fOutput string - fLarge bool -) +type proverArgsT struct { + input string + output string + large bool + configFile string +} + +var proverArgs proverArgsT // proveCmd represents the prove command var proveCmd = &cobra.Command{ @@ -31,49 +34,53 @@ var proveCmd = &cobra.Command{ func init() { rootCmd.AddCommand(proveCmd) - proveCmd.Flags().StringVar(&fInput, "in", "", "input file") - proveCmd.Flags().StringVar(&fOutput, "out", "", "output file") - proveCmd.Flags().BoolVar(&fLarge, "large", false, "run the large execution circuit") - + proveCmd.Flags().StringVar(&proverArgs.input, "in", "", "input file") + proveCmd.Flags().StringVar(&proverArgs.output, "out", "", "output file") + proveCmd.Flags().BoolVar(&proverArgs.large, "large", false, "run the large execution circuit") } func cmdProve(cmd *cobra.Command, args []string) error { + proverArgs.configFile = fConfigFile + return Prove(cmd.Name(), proverArgs) +} + +func Prove(cmdName string, args proverArgsT) error { // TODO @gbotrel with a specific flag, we could compile the circuit and compare with the checksum of the // asset we deserialize, to make sure we are using the circuit associated with the compiled binary and the setup. // read config cfg, err := config.NewConfigFromFile(fConfigFile) if err != nil { - return fmt.Errorf("%s failed to read config file: %w", cmd.Name(), err) + return fmt.Errorf("%s failed to read config file: %w", cmdName, err) } // discover the type of the job from the input file name - jobExecution := strings.Contains(fInput, "getZkProof") - jobBlobDecompression := strings.Contains(fInput, "getZkBlobCompressionProof") - jobAggregation := strings.Contains(fInput, "getZkAggregatedProof") + jobExecution := strings.Contains(args.input, "getZkProof") + jobBlobDecompression := strings.Contains(args.input, "getZkBlobCompressionProof") + jobAggregation := strings.Contains(args.input, "getZkAggregatedProof") if jobExecution { req := &execution.Request{} - if err := readRequest(fInput, req); err != nil { - return fmt.Errorf("could not read the input file (%v): %w", fInput, err) + if err := readRequest(args.input, req); err != nil { + return fmt.Errorf("could not read the input file (%v): %w", args.input, err) } // we use the large traces in 2 cases; - // 1. the user explicitly asked for it (fLarge) + // 1. the user explicitly asked for it (args.large) // 2. the job contains the large suffix and we are a large machine (cfg.Execution.CanRunLarge) - large := fLarge || (strings.Contains(fInput, "large") && cfg.Execution.CanRunFullLarge) + large := args.large || (strings.Contains(args.input, "large") && cfg.Execution.CanRunFullLarge) resp, err := execution.Prove(cfg, req, large) if err != nil { return fmt.Errorf("could not prove the execution: %w", err) } - return writeResponse(fOutput, resp) + return writeResponse(args.output, resp) } if jobBlobDecompression { req := &blobdecompression.Request{} - if err := readRequest(fInput, req); err != nil { - return fmt.Errorf("could not read the input file (%v): %w", fInput, err) + if err := readRequest(args.input, req); err != nil { + return fmt.Errorf("could not read the input file (%v): %w", args.input, err) } resp, err := blobdecompression.Prove(cfg, req) @@ -81,13 +88,13 @@ func cmdProve(cmd *cobra.Command, args []string) error { return fmt.Errorf("could not prove the blob decompression: %w", err) } - return writeResponse(fOutput, resp) + return writeResponse(args.output, resp) } if jobAggregation { req := &aggregation.Request{} - if err := readRequest(fInput, req); err != nil { - return fmt.Errorf("could not read the input file (%v): %w", fInput, err) + if err := readRequest(args.input, req); err != nil { + return fmt.Errorf("could not read the input file (%v): %w", args.input, err) } resp, err := aggregation.Prove(cfg, req) @@ -95,7 +102,7 @@ func cmdProve(cmd *cobra.Command, args []string) error { return fmt.Errorf("could not prove the aggregation: %w", err) } - return writeResponse(fOutput, resp) + return writeResponse(args.output, resp) } return errors.New("unknown job type") diff --git a/prover/cmd/prover/cmd/setup.go b/prover/cmd/prover/cmd/setup.go index f7e28de8ab9..ae71c53ee35 100644 --- a/prover/cmd/prover/cmd/setup.go +++ b/prover/cmd/prover/cmd/setup.go @@ -32,12 +32,15 @@ import ( "github.com/consensys/gnark/backend/plonk" ) -var ( - fForce bool - fCircuits string - fDictPath string - fAssetsDir string -) +type setupArgsT struct { + force bool + circuits string + dictPath string + assetsDir string + configFile string +} + +var setupArgs setupArgsT // setupCmd represents the setup command var setupCmd = &cobra.Command{ @@ -59,25 +62,30 @@ var allCircuits = []string{ func init() { rootCmd.AddCommand(setupCmd) - setupCmd.Flags().BoolVar(&fForce, "force", false, "overwrites existing files") - setupCmd.Flags().StringVar(&fCircuits, "circuits", strings.Join(allCircuits, ","), "comma separated list of circuits to setup") - setupCmd.Flags().StringVar(&fDictPath, "dict", "", "path to the dictionary file used in blob (de)compression") - setupCmd.Flags().StringVar(&fAssetsDir, "assets-dir", "", "path to the directory where the assets are stored (override conf)") + setupCmd.Flags().BoolVar(&setupArgs.force, "force", false, "overwrites existing files") + setupCmd.Flags().StringVar(&setupArgs.circuits, "circuits", strings.Join(allCircuits, ","), "comma separated list of circuits to setup") + setupCmd.Flags().StringVar(&setupArgs.dictPath, "dict", "", "path to the dictionary file used in blob (de)compression") + setupCmd.Flags().StringVar(&setupArgs.assetsDir, "assets-dir", "", "path to the directory where the assets are stored (override conf)") viper.BindPFlag("assets_dir", setupCmd.Flags().Lookup("assets-dir")) } func cmdSetup(cmd *cobra.Command, args []string) error { + setupArgs.configFile = fConfigFile + return Setup(cmd.Name(), cmd.Context(), setupArgs) +} + +func Setup(cmdName string, context context.Context, args setupArgsT) error { // read config - cfg, err := config.NewConfigFromFile(fConfigFile) + cfg, err := config.NewConfigFromFile(args.configFile) if err != nil { - return fmt.Errorf("%s failed to read config file: %w", cmd.Name(), err) + return fmt.Errorf("%s failed to read config file: %w", cmdName, err) } - if fDictPath != "" { + if args.dictPath != "" { // fail early if the dictionary file is not found but was specified. - if _, err := os.Stat(fDictPath); err != nil { - return fmt.Errorf("%s dictionary file not found: %w", cmd.Name(), err) + if _, err := os.Stat(args.dictPath); err != nil { + return fmt.Errorf("%s dictionary file not found: %w", cmdName, err) } } @@ -86,10 +94,10 @@ func cmdSetup(cmd *cobra.Command, args []string) error { for _, c := range allCircuits { inCircuits[circuits.CircuitID(c)] = false } - _inCircuits := strings.Split(fCircuits, ",") + _inCircuits := strings.Split(args.circuits, ",") for _, c := range _inCircuits { if _, ok := inCircuits[circuits.CircuitID(c)]; !ok { - return fmt.Errorf("%s unknown circuit: %s", cmd.Name(), c) + return fmt.Errorf("%s unknown circuit: %s", cmdName, c) } inCircuits[circuits.CircuitID(c)] = true } @@ -101,7 +109,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { var srsProvider circuits.SRSProvider srsProvider, err = circuits.NewSRSStore(cfg.PathForSRS()) if err != nil { - return fmt.Errorf("%s failed to create SRS provider: %w", cmd.Name(), err) + return fmt.Errorf("%s failed to create SRS provider: %w", cmdName, err) } // for each circuit, we start by compiling the circuit @@ -128,9 +136,9 @@ func cmdSetup(cmd *cobra.Command, args []string) error { zkEvm := zkevm.FullZkEvm(&limits) builder = execution.NewBuilder(zkEvm) case circuits.BlobDecompressionV0CircuitID, circuits.BlobDecompressionV1CircuitID: - dict, err = os.ReadFile(fDictPath) + dict, err = os.ReadFile(args.dictPath) if err != nil { - return fmt.Errorf("%s failed to read dictionary file: %w", cmd.Name(), err) + return fmt.Errorf("%s failed to read dictionary file: %w", cmdName, err) } if c == circuits.BlobDecompressionV0CircuitID { @@ -151,14 +159,14 @@ func cmdSetup(cmd *cobra.Command, args []string) error { continue // dummy, aggregation, emulation or public input circuits are handled later } - if err := updateSetup(cmd.Context(), cfg, srsProvider, c, builder, extraFlags); err != nil { + if err := updateSetup(context, cfg, args.force, srsProvider, c, builder, extraFlags); err != nil { return err } if dict != nil { // we save the dictionary to disk dictPath := filepath.Join(cfg.PathForSetup(string(c)), config.DictionaryFileName) if err := os.WriteFile(dictPath, dict, 0600); err != nil { - return fmt.Errorf("%s failed to write dictionary file: %w", cmd.Name(), err) + return fmt.Errorf("%s failed to write dictionary file: %w", cmdName, err) } } @@ -172,7 +180,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { // get verifying key for public-input circuit piSetup, err := circuits.LoadSetup(cfg, circuits.PublicInputInterconnectionCircuitID) if err != nil { - return fmt.Errorf("%s failed to load public input interconnection setup: %w", cmd.Name(), err) + return fmt.Errorf("%s failed to load public input interconnection setup: %w", cmdName, err) } // first, we need to collect the verifying keys @@ -196,7 +204,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { return fmt.Errorf("unknown dummy circuit: %s", allowedInput) } - vk, err := getDummyCircuitVK(cmd.Context(), cfg, srsProvider, circuits.CircuitID(allowedInput), dummy.NewBuilder(mockID, curveID.ScalarField())) + vk, err := getDummyCircuitVK(context, cfg, srsProvider, circuits.CircuitID(allowedInput), dummy.NewBuilder(mockID, curveID.ScalarField())) if err != nil { return err } @@ -209,7 +217,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { vkPath := filepath.Join(setupPath, config.VerifyingKeyFileName) vk := plonk.NewVerifyingKey(ecc.BLS12_377) if err := circuits.ReadVerifyingKey(vkPath, vk); err != nil { - return fmt.Errorf("%s failed to read verifying key for circuit %s: %w", cmd.Name(), allowedInput, err) + return fmt.Errorf("%s failed to read verifying key for circuit %s: %w", cmdName, allowedInput, err) } allowedVkForAggregation = append(allowedVkForAggregation, vk) @@ -217,7 +225,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { // we need to compute the digest of the verifying keys & store them in the manifest // for the aggregation circuits to be able to check compatibility at run time with the proofs - allowedVkForAggregationDigests := listOfCheckum(allowedVkForAggregation) + allowedVkForAggregationDigests := listOfChecksums(allowedVkForAggregation) extraFlagsForAggregationCircuit := map[string]any{ "allowedVkForAggregationDigests": allowedVkForAggregationDigests, } @@ -229,7 +237,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { logrus.Infof("setting up %s (numProofs=%d)", c, numProofs) builder := aggregation.NewBuilder(numProofs, cfg.Aggregation.AllowedInputs, piSetup, allowedVkForAggregation) - if err := updateSetup(cmd.Context(), cfg, srsProvider, c, builder, extraFlagsForAggregationCircuit); err != nil { + if err := updateSetup(context, cfg, args.force, srsProvider, c, builder, extraFlagsForAggregationCircuit); err != nil { return err } @@ -238,7 +246,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { vkPath := filepath.Join(setupPath, config.VerifyingKeyFileName) vk := plonk.NewVerifyingKey(ecc.BW6_761) if err := circuits.ReadVerifyingKey(vkPath, vk); err != nil { - return fmt.Errorf("%s failed to read verifying key for circuit %s: %w", cmd.Name(), c, err) + return fmt.Errorf("%s failed to read verifying key for circuit %s: %w", cmdName, c, err) } allowedVkForEmulation = append(allowedVkForEmulation, vk) @@ -248,7 +256,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error { c := circuits.EmulationCircuitID logrus.Infof("setting up %s", c) builder := emulation.NewBuilder(allowedVkForEmulation) - return updateSetup(cmd.Context(), cfg, srsProvider, c, builder, nil) + return updateSetup(context, cfg, args.force, srsProvider, c, builder, nil) } @@ -281,7 +289,7 @@ func getDummyCircuitVK(ctx context.Context, cfg *config.Config, srsProvider circ // and if so, if the checksums match. // if the files already exist and the checksums match, it skips the setup. // else it does the setup and writes the assets to disk. -func updateSetup(ctx context.Context, cfg *config.Config, srsProvider circuits.SRSProvider, circuit circuits.CircuitID, builder circuits.Builder, extraFlags map[string]any) error { +func updateSetup(ctx context.Context, cfg *config.Config, force bool, srsProvider circuits.SRSProvider, circuit circuits.CircuitID, builder circuits.Builder, extraFlags map[string]any) error { if extraFlags == nil { extraFlags = make(map[string]any) } @@ -297,7 +305,7 @@ func updateSetup(ctx context.Context, cfg *config.Config, srsProvider circuits.S setupPath := cfg.PathForSetup(string(circuit)) manifestPath := filepath.Join(setupPath, config.ManifestFileName) - if !fForce { + if !force { // we may want to skip setup if the files already exist // and the checksums match // read manifest if already exists @@ -325,12 +333,13 @@ func updateSetup(ctx context.Context, cfg *config.Config, srsProvider circuits.S return setup.WriteTo(setupPath) } -// listOfCheckum Computes a list of SHA256 checksums for a list of assets, the result is given +// listOfChecksums Computes a list of SHA256 checksums for a list of assets, the result is given // in hexstring. -func listOfCheckum[T io.WriterTo](assets []T) []string { +func listOfChecksums[T io.WriterTo](assets []T) []string { res := make([]string, len(assets)) + h := sha256.New() for i := range assets { - h := sha256.New() + h.Reset() _, err := assets[i].WriteTo(h) if err != nil { // It is unexpected that writing in a hasher could possibly fail. From 8853fa7622af8c8b5f732246315f583be0a496c7 Mon Sep 17 00:00:00 2001 From: Arya Tabaie <15056835+Tabaie@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:10:05 -0600 Subject: [PATCH 2/3] refac contain global variables in the main package --- prover/cmd/prover/cmd/prove.go | 65 ++++++++++------------------- prover/cmd/prover/cmd/root.go | 36 ----------------- prover/cmd/prover/cmd/setup.go | 63 +++++++++-------------------- prover/cmd/prover/main.go | 74 +++++++++++++++++++++++++++++++++- 4 files changed, 111 insertions(+), 127 deletions(-) delete mode 100644 prover/cmd/prover/cmd/root.go diff --git a/prover/cmd/prover/cmd/prove.go b/prover/cmd/prover/cmd/prove.go index e25627075ca..0538cdb1a0e 100644 --- a/prover/cmd/prover/cmd/prove.go +++ b/prover/cmd/prover/cmd/prove.go @@ -12,75 +12,52 @@ import ( "github.com/consensys/linea-monorepo/prover/backend/execution" "github.com/consensys/linea-monorepo/prover/backend/files" "github.com/consensys/linea-monorepo/prover/config" - "github.com/spf13/cobra" ) -type proverArgsT struct { - input string - output string - large bool - configFile string +type ProverArgs struct { + Input string + Output string + Large bool + ConfigFile string } -var proverArgs proverArgsT - -// proveCmd represents the prove command -var proveCmd = &cobra.Command{ - Use: "prove", - Short: "prove process a request, creates a proof with the adequate circuit and writes the proof to a file", - RunE: cmdProve, -} - -func init() { - rootCmd.AddCommand(proveCmd) - - proveCmd.Flags().StringVar(&proverArgs.input, "in", "", "input file") - proveCmd.Flags().StringVar(&proverArgs.output, "out", "", "output file") - proveCmd.Flags().BoolVar(&proverArgs.large, "large", false, "run the large execution circuit") -} - -func cmdProve(cmd *cobra.Command, args []string) error { - proverArgs.configFile = fConfigFile - return Prove(cmd.Name(), proverArgs) -} - -func Prove(cmdName string, args proverArgsT) error { +func Prove(cmdName string, args ProverArgs) error { // TODO @gbotrel with a specific flag, we could compile the circuit and compare with the checksum of the // asset we deserialize, to make sure we are using the circuit associated with the compiled binary and the setup. // read config - cfg, err := config.NewConfigFromFile(fConfigFile) + cfg, err := config.NewConfigFromFile(args.ConfigFile) if err != nil { return fmt.Errorf("%s failed to read config file: %w", cmdName, err) } // discover the type of the job from the input file name - jobExecution := strings.Contains(args.input, "getZkProof") - jobBlobDecompression := strings.Contains(args.input, "getZkBlobCompressionProof") - jobAggregation := strings.Contains(args.input, "getZkAggregatedProof") + jobExecution := strings.Contains(args.Input, "getZkProof") + jobBlobDecompression := strings.Contains(args.Input, "getZkBlobCompressionProof") + jobAggregation := strings.Contains(args.Input, "getZkAggregatedProof") if jobExecution { req := &execution.Request{} - if err := readRequest(args.input, req); err != nil { - return fmt.Errorf("could not read the input file (%v): %w", args.input, err) + if err := readRequest(args.Input, req); err != nil { + return fmt.Errorf("could not read the input file (%v): %w", args.Input, err) } // we use the large traces in 2 cases; - // 1. the user explicitly asked for it (args.large) + // 1. the user explicitly asked for it (args.Large) // 2. the job contains the large suffix and we are a large machine (cfg.Execution.CanRunLarge) - large := args.large || (strings.Contains(args.input, "large") && cfg.Execution.CanRunFullLarge) + large := args.Large || (strings.Contains(args.Input, "large") && cfg.Execution.CanRunFullLarge) resp, err := execution.Prove(cfg, req, large) if err != nil { return fmt.Errorf("could not prove the execution: %w", err) } - return writeResponse(args.output, resp) + return writeResponse(args.Output, resp) } if jobBlobDecompression { req := &blobdecompression.Request{} - if err := readRequest(args.input, req); err != nil { - return fmt.Errorf("could not read the input file (%v): %w", args.input, err) + if err := readRequest(args.Input, req); err != nil { + return fmt.Errorf("could not read the input file (%v): %w", args.Input, err) } resp, err := blobdecompression.Prove(cfg, req) @@ -88,13 +65,13 @@ func Prove(cmdName string, args proverArgsT) error { return fmt.Errorf("could not prove the blob decompression: %w", err) } - return writeResponse(args.output, resp) + return writeResponse(args.Output, resp) } if jobAggregation { req := &aggregation.Request{} - if err := readRequest(args.input, req); err != nil { - return fmt.Errorf("could not read the input file (%v): %w", args.input, err) + if err := readRequest(args.Input, req); err != nil { + return fmt.Errorf("could not read the input file (%v): %w", args.Input, err) } resp, err := aggregation.Prove(cfg, req) @@ -102,7 +79,7 @@ func Prove(cmdName string, args proverArgsT) error { return fmt.Errorf("could not prove the aggregation: %w", err) } - return writeResponse(args.output, resp) + return writeResponse(args.Output, resp) } return errors.New("unknown job type") diff --git a/prover/cmd/prover/cmd/root.go b/prover/cmd/prover/cmd/root.go deleted file mode 100644 index fcb4c2c9b94..00000000000 --- a/prover/cmd/prover/cmd/root.go +++ /dev/null @@ -1,36 +0,0 @@ -package cmd - -import ( - "os" - - "github.com/consensys/gnark/logger" - "github.com/rs/zerolog" - "github.com/spf13/cobra" -) - -var fConfigFile string - -// rootCmd represents the base command when called without any subcommands -var rootCmd = &cobra.Command{ - Use: "prover", - Short: "run pre-compute or compute proofs for Linea circuits", -} - -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { - err := rootCmd.Execute() - if err != nil { - os.Exit(1) - } -} - -func init() { - rootCmd.PersistentFlags().StringVar(&fConfigFile, "config", "", "config file") - - output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "15:04:05", NoColor: true} - l := zerolog.New(output).With().Timestamp().Logger() - - // Set global log level for gnark - logger.Set(l) -} diff --git a/prover/cmd/prover/cmd/setup.go b/prover/cmd/prover/cmd/setup.go index ae71c53ee35..e723addc1a9 100644 --- a/prover/cmd/prover/cmd/setup.go +++ b/prover/cmd/prover/cmd/setup.go @@ -16,6 +16,7 @@ import ( "github.com/sirupsen/logrus" "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark/backend/plonk" "github.com/consensys/linea-monorepo/prover/circuits" "github.com/consensys/linea-monorepo/prover/circuits/aggregation" v0 "github.com/consensys/linea-monorepo/prover/circuits/blobdecompression/v0" @@ -26,30 +27,17 @@ import ( "github.com/consensys/linea-monorepo/prover/config" "github.com/consensys/linea-monorepo/prover/utils" "github.com/consensys/linea-monorepo/prover/zkevm" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/consensys/gnark/backend/plonk" ) -type setupArgsT struct { - force bool - circuits string - dictPath string - assetsDir string - configFile string -} - -var setupArgs setupArgsT - -// setupCmd represents the setup command -var setupCmd = &cobra.Command{ - Use: "setup", - Short: "pre compute assets for Linea circuits", - RunE: cmdSetup, +type SetupArgs struct { + Force bool + Circuits string + DictPath string + AssetsDir string + ConfigFile string } -var allCircuits = []string{ +var AllCircuits = []string{ string(circuits.ExecutionCircuitID), string(circuits.ExecutionLargeCircuitID), string(circuits.BlobDecompressionV0CircuitID), @@ -60,41 +48,26 @@ var allCircuits = []string{ string(circuits.EmulationDummyCircuitID), // we want to generate Verifier.sol for this one } -func init() { - rootCmd.AddCommand(setupCmd) - setupCmd.Flags().BoolVar(&setupArgs.force, "force", false, "overwrites existing files") - setupCmd.Flags().StringVar(&setupArgs.circuits, "circuits", strings.Join(allCircuits, ","), "comma separated list of circuits to setup") - setupCmd.Flags().StringVar(&setupArgs.dictPath, "dict", "", "path to the dictionary file used in blob (de)compression") - setupCmd.Flags().StringVar(&setupArgs.assetsDir, "assets-dir", "", "path to the directory where the assets are stored (override conf)") - - viper.BindPFlag("assets_dir", setupCmd.Flags().Lookup("assets-dir")) -} - -func cmdSetup(cmd *cobra.Command, args []string) error { - setupArgs.configFile = fConfigFile - return Setup(cmd.Name(), cmd.Context(), setupArgs) -} - -func Setup(cmdName string, context context.Context, args setupArgsT) error { +func Setup(cmdName string, context context.Context, args SetupArgs) error { // read config - cfg, err := config.NewConfigFromFile(args.configFile) + cfg, err := config.NewConfigFromFile(args.ConfigFile) if err != nil { return fmt.Errorf("%s failed to read config file: %w", cmdName, err) } - if args.dictPath != "" { + if args.DictPath != "" { // fail early if the dictionary file is not found but was specified. - if _, err := os.Stat(args.dictPath); err != nil { + if _, err := os.Stat(args.DictPath); err != nil { return fmt.Errorf("%s dictionary file not found: %w", cmdName, err) } } // parse inCircuits inCircuits := make(map[circuits.CircuitID]bool) - for _, c := range allCircuits { + for _, c := range AllCircuits { inCircuits[circuits.CircuitID(c)] = false } - _inCircuits := strings.Split(args.circuits, ",") + _inCircuits := strings.Split(args.Circuits, ",") for _, c := range _inCircuits { if _, ok := inCircuits[circuits.CircuitID(c)]; !ok { return fmt.Errorf("%s unknown circuit: %s", cmdName, c) @@ -136,7 +109,7 @@ func Setup(cmdName string, context context.Context, args setupArgsT) error { zkEvm := zkevm.FullZkEvm(&limits) builder = execution.NewBuilder(zkEvm) case circuits.BlobDecompressionV0CircuitID, circuits.BlobDecompressionV1CircuitID: - dict, err = os.ReadFile(args.dictPath) + dict, err = os.ReadFile(args.DictPath) if err != nil { return fmt.Errorf("%s failed to read dictionary file: %w", cmdName, err) } @@ -159,7 +132,7 @@ func Setup(cmdName string, context context.Context, args setupArgsT) error { continue // dummy, aggregation, emulation or public input circuits are handled later } - if err := updateSetup(context, cfg, args.force, srsProvider, c, builder, extraFlags); err != nil { + if err := updateSetup(context, cfg, args.Force, srsProvider, c, builder, extraFlags); err != nil { return err } if dict != nil { @@ -237,7 +210,7 @@ func Setup(cmdName string, context context.Context, args setupArgsT) error { logrus.Infof("setting up %s (numProofs=%d)", c, numProofs) builder := aggregation.NewBuilder(numProofs, cfg.Aggregation.AllowedInputs, piSetup, allowedVkForAggregation) - if err := updateSetup(context, cfg, args.force, srsProvider, c, builder, extraFlagsForAggregationCircuit); err != nil { + if err := updateSetup(context, cfg, args.Force, srsProvider, c, builder, extraFlagsForAggregationCircuit); err != nil { return err } @@ -256,7 +229,7 @@ func Setup(cmdName string, context context.Context, args setupArgsT) error { c := circuits.EmulationCircuitID logrus.Infof("setting up %s", c) builder := emulation.NewBuilder(allowedVkForEmulation) - return updateSetup(context, cfg, args.force, srsProvider, c, builder, nil) + return updateSetup(context, cfg, args.Force, srsProvider, c, builder, nil) } diff --git a/prover/cmd/prover/main.go b/prover/cmd/prover/main.go index f221c083ea2..6169ff47c8a 100644 --- a/prover/cmd/prover/main.go +++ b/prover/cmd/prover/main.go @@ -1,7 +1,77 @@ package main -import "github.com/consensys/linea-monorepo/prover/cmd/prover/cmd" +import ( + "github.com/consensys/gnark/logger" + "github.com/consensys/linea-monorepo/prover/cmd/prover/cmd" + "github.com/rs/zerolog" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "os" + "strings" +) + +var ( + // rootCmd represents the base command when called without any subcommands + rootCmd = &cobra.Command{ + Use: "prover", + Short: "run pre-compute or compute proofs for Linea circuits", + } + fConfigFile string + + // setupCmd represents the setup command + setupCmd = &cobra.Command{ + Use: "setup", + Short: "pre compute assets for Linea circuits", + RunE: cmdSetup, + } + setupArgs cmd.SetupArgs + + // proveCmd represents the prove command + proveCmd = &cobra.Command{ + Use: "prove", + Short: "prove process a request, creates a proof with the adequate circuit and writes the proof to a file", + RunE: cmdProve, + } + proverArgs cmd.ProverArgs +) func main() { - cmd.Execute() + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + rootCmd.PersistentFlags().StringVar(&fConfigFile, "config", "", "config file") + + output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "15:04:05", NoColor: true} + l := zerolog.New(output).With().Timestamp().Logger() + + // Set global log level for gnark + logger.Set(l) + + rootCmd.AddCommand(setupCmd) + setupCmd.Flags().BoolVar(&setupArgs.Force, "force", false, "overwrites existing files") + setupCmd.Flags().StringVar(&setupArgs.Circuits, "circuits", strings.Join(cmd.AllCircuits, ","), "comma separated list of circuits to setup") + setupCmd.Flags().StringVar(&setupArgs.DictPath, "dict", "", "path to the dictionary file used in blob (de)compression") + setupCmd.Flags().StringVar(&setupArgs.AssetsDir, "assets-dir", "", "path to the directory where the assets are stored (override conf)") + + viper.BindPFlag("assets_dir", setupCmd.Flags().Lookup("assets-dir")) + + rootCmd.AddCommand(proveCmd) + + proveCmd.Flags().StringVar(&proverArgs.Input, "in", "", "input file") + proveCmd.Flags().StringVar(&proverArgs.Output, "out", "", "output file") + proveCmd.Flags().BoolVar(&proverArgs.Large, "large", false, "run the large execution circuit") +} + +func cmdSetup(_cmd *cobra.Command, args []string) error { + setupArgs.ConfigFile = fConfigFile + return cmd.Setup(_cmd.Name(), _cmd.Context(), setupArgs) +} + +func cmdProve(_cmd *cobra.Command, args []string) error { + proverArgs.ConfigFile = fConfigFile + return cmd.Prove(_cmd.Name(), proverArgs) } From 566b23ea9c2c141363076bce4d030b3243f82d44 Mon Sep 17 00:00:00 2001 From: Arya Tabaie <15056835+Tabaie@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:18:50 -0600 Subject: [PATCH 3/3] refactor eliminate unnecessary arguments --- prover/cmd/prover/cmd/prove.go | 3 ++- prover/cmd/prover/cmd/setup.go | 3 ++- prover/cmd/prover/main.go | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/prover/cmd/prover/cmd/prove.go b/prover/cmd/prover/cmd/prove.go index 0538cdb1a0e..edfff6c97fe 100644 --- a/prover/cmd/prover/cmd/prove.go +++ b/prover/cmd/prover/cmd/prove.go @@ -21,7 +21,8 @@ type ProverArgs struct { ConfigFile string } -func Prove(cmdName string, args ProverArgs) error { +func Prove(args ProverArgs) error { + const cmdName = "prove" // TODO @gbotrel with a specific flag, we could compile the circuit and compare with the checksum of the // asset we deserialize, to make sure we are using the circuit associated with the compiled binary and the setup. diff --git a/prover/cmd/prover/cmd/setup.go b/prover/cmd/prover/cmd/setup.go index d973c616743..3ad86b16f0f 100644 --- a/prover/cmd/prover/cmd/setup.go +++ b/prover/cmd/prover/cmd/setup.go @@ -48,7 +48,8 @@ var AllCircuits = []string{ string(circuits.EmulationDummyCircuitID), // we want to generate Verifier.sol for this one } -func Setup(cmdName string, context context.Context, args SetupArgs) error { +func Setup(context context.Context, args SetupArgs) error { + const cmdName = "setup" // read config cfg, err := config.NewConfigFromFile(args.ConfigFile) if err != nil { diff --git a/prover/cmd/prover/main.go b/prover/cmd/prover/main.go index 6169ff47c8a..99e067ef4ad 100644 --- a/prover/cmd/prover/main.go +++ b/prover/cmd/prover/main.go @@ -66,12 +66,12 @@ func init() { proveCmd.Flags().BoolVar(&proverArgs.Large, "large", false, "run the large execution circuit") } -func cmdSetup(_cmd *cobra.Command, args []string) error { +func cmdSetup(_cmd *cobra.Command, _ []string) error { setupArgs.ConfigFile = fConfigFile - return cmd.Setup(_cmd.Name(), _cmd.Context(), setupArgs) + return cmd.Setup(_cmd.Context(), setupArgs) } -func cmdProve(_cmd *cobra.Command, args []string) error { +func cmdProve(*cobra.Command, []string) error { proverArgs.ConfigFile = fConfigFile - return cmd.Prove(_cmd.Name(), proverArgs) + return cmd.Prove(proverArgs) }