Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions cmd/genesisroot/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"fmt"
"math/big"
"os"
"path/filepath"

"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/core"
"github.com/erigontech/erigon/zk/zk_config"
"github.com/erigontech/erigon/zk/zk_config/cfg_dynamic_genesis"
)

func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: genesisroot <config-dir> [chain-name]\n")
Comment on lines +16 to +17
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage banner hard-codes the program name as genesisroot. If the binary is renamed or invoked via a different path, the message will be inaccurate. Using os.Args[0] (or filepath.Base(os.Args[0])) keeps the usage text correct.

Suggested change
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: genesisroot <config-dir> [chain-name]\n")
prog := filepath.Base(os.Args[0])
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: %s <config-dir> [chain-name]\n", prog)

Copilot uses AI. Check for mistakes.
fmt.Fprintf(os.Stderr, " config-dir: directory containing <chain>-allocs.json, <chain>-chainspec.json, <chain>-conf.json\n")
fmt.Fprintf(os.Stderr, " chain-name: chain name (default: dynamic-hermez-dev)\n")
os.Exit(1)
}

configDir := os.Args[1]
chain := "dynamic-hermez-dev"
if len(os.Args) > 2 {
chain = os.Args[2]
}

absDir, err := filepath.Abs(configDir)
if err != nil {
fmt.Fprintf(os.Stderr, "invalid config dir: %v\n", err)
os.Exit(1)
}

zk_config.ZKDynamicConfigPath = absDir
zk_config.ZkUnionConfigPath = ""

dConf := cfg_dynamic_genesis.NewDynamicGenesisConfig(chain)

genesis := core.DynamicGenesisBlock(chain)
Comment on lines +29 to +40
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command can terminate with a panic + stack trace if the config directory/files are missing or invalid, because NewDynamicGenesisConfig/NewDynamicChainConfig/NewDynamicAllocsConfig panic when they can’t find or parse the expected JSON files. It would be more robust to validate configDir exists (e.g., os.Stat) and/or wrap the main body with a defer/recover that prints a clean error message to stderr and exits non-zero.

Copilot uses AI. Check for mistakes.
genesis.Timestamp = dConf.Timestamp
genesis.GasLimit = dConf.GasLimit
genesis.Difficulty = big.NewInt(dConf.Difficulty)
Comment on lines +38 to +43
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfg_dynamic_genesis.NewDynamicGenesisConfig(chain) and core.DynamicGenesisBlock(chain) both read the dynamic genesis conf from disk (the latter calls NewDynamicGenesisConfig internally). This means the config file is parsed twice for every run, and the explicit genesis.Timestamp = dConf.Timestamp becomes redundant. Consider avoiding the duplicate load (e.g., build the genesis struct directly using the cfg_* packages and reuse the already-loaded conf, or introduce/use a helper that returns both the genesis and the parsed dynamic conf).

Copilot uses AI. Check for mistakes.

tmpDir, err := os.MkdirTemp("", "genesisroot-*")
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create temp dir: %v\n", err)
os.Exit(1)
}
defer os.RemoveAll(tmpDir)

block, _, _, err := core.GenesisToBlock(genesis, tmpDir, log.Root())
if err != nil {
fmt.Fprintf(os.Stderr, "GenesisToBlock failed: %v\n", err)
os.Exit(1)
}

fmt.Println("State Root:", block.Root().Hex())
fmt.Println("Block Hash:", block.Hash().Hex())
}
Loading