Skip to content

Commit 547da23

Browse files
authored
add-chain: add check-genesis subcommand (#354)
* Add check-genesis-config subcommand * Remove unused writeGenesisJSON function * Run tests in parallel * Update test for check-genesis-config * Add testdata/ for zorasep * Rename check-genesis-config to check-genesis * Remove ExcessBlobGas,BlobGasUsed exceptions from check-genesis * Add check-genesis to add-chain.sh * Remove redundant l2-genesis flag * Make SystemConfig BaseFeeScalar and BlobBaseFeeScalar optional * validation go mod tidy * Update op-geth import. Add genesis.json DenominatorCanyon exception * Add link to op-geth issue in code comment * Cleanup e2e_test.go * Give more detailed error message for check-genesis failure
1 parent 67c4105 commit 547da23

File tree

16 files changed

+185
-36
lines changed

16 files changed

+185
-36
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ SCR_STANDARD_CHAIN_CANDIDATE=false
1515
SCR_MONOREPO_DIR=../optimism # path to local "ethereum-optimism/optimism" monorepo
1616
SCR_DEPLOYMENTS_DIR=${SCR_MONOREPO_DIR}/packages/contracts-bedrock/deployments/getting-started
1717
SCR_ROLLUP_CONFIG=${SCR_MONOREPO_DIR}/op-node/rollup.json
18-
SCR_GENESIS_CONFIG=${SCR_MONOREPO_DIR}/op-node/genesis.json
18+
SCR_GENESIS=${SCR_MONOREPO_DIR}/op-node/genesis.json
1919
SCR_PUBLIC_RPC="http://awe.some.rpc" # new OP Stack L2 RPC URL
2020
SCR_SEQUENCER_RPC="http://awe.some.seq.rpc" # new OP Stack L2 sequencer RPC URL
2121
SCR_EXPLORER="https://awesomescan.org" # new OP Stack L2 block explorer URL

add-chain/cmd/check-genesis.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"math/big"
7+
"os"
8+
9+
"github.com/ethereum-optimism/superchain-registry/add-chain/flags"
10+
"github.com/ethereum/go-ethereum/core"
11+
"github.com/google/go-cmp/cmp"
12+
"github.com/google/go-cmp/cmp/cmpopts"
13+
"github.com/urfave/cli/v2"
14+
)
15+
16+
var CheckGenesisCmd = cli.Command{
17+
Name: "check-genesis",
18+
Flags: []cli.Flag{flags.GenesisFlag, flags.ChainIdFlag},
19+
Usage: "Sanity check genesis (genesis.json) is reproducible",
20+
Action: func(ctx *cli.Context) error {
21+
genesisPath := ctx.String(flags.GenesisFlag.Name)
22+
fmt.Printf("Attempting to read from %s\n", genesisPath)
23+
file, err := os.ReadFile(genesisPath)
24+
if err != nil {
25+
return fmt.Errorf("failed to read from local genesis.json config file: %w", err)
26+
}
27+
var localGenesis *core.Genesis
28+
if err = json.Unmarshal(file, &localGenesis); err != nil {
29+
return fmt.Errorf("failed to unmarshal local genesis.json into core.Genesis struct: %w", err)
30+
}
31+
32+
chainId := ctx.Uint64(flags.ChainIdFlag.Name)
33+
gethGenesis, err := core.LoadOPStackGenesis(chainId)
34+
if err != nil {
35+
return fmt.Errorf("failed to load genesis via op-geth: ensure chainId has already been added to registry: %w", err)
36+
}
37+
38+
// Exceptions for testing
39+
if localGenesis.Config.Optimism != nil {
40+
// this value is always hardcoded in op-geth to 250. Need to updated op-geth to
41+
// conditionally set the value (if canyon is activated) to remove the exception
42+
// https://github.com/ethereum-optimism/op-geth/issues/346
43+
twofifty := uint64(250)
44+
localGenesis.Config.Optimism.EIP1559DenominatorCanyon = &twofifty
45+
}
46+
47+
opts := cmp.Options{cmpopts.IgnoreUnexported(big.Int{})}
48+
if diff := cmp.Diff(localGenesis, gethGenesis, opts...); diff != "" {
49+
return fmt.Errorf("local genesis.json (-) does not match config generated by op-geth (+): %s", diff)
50+
}
51+
52+
fmt.Println("Regenerated genesis config matches existing one")
53+
return nil
54+
},
55+
}

add-chain/cmd/check-rollup-config.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,11 @@ var CheckRollupConfigCmd = cli.Command{
3939
if err != nil {
4040
return fmt.Errorf("op-node failed to generate rollup config: %w", err)
4141
}
42-
opts := cmp.Options{
43-
cmpopts.IgnoreUnexported(big.Int{}),
44-
}
45-
4642
// Exclude this field from check since it gets populated by op-node after rollup.json is created
4743
localRollupConfig.ProtocolVersionsAddress = common.Address{}
4844
opNodeRollupConfig.ProtocolVersionsAddress = common.Address{}
4945

46+
opts := cmp.Options{cmpopts.IgnoreUnexported(big.Int{})}
5047
if diff := cmp.Diff(localRollupConfig, opNodeRollupConfig, opts...); diff != "" {
5148
return fmt.Errorf("local rollup.json (-) does not match config generated by op-node (+): %s", diff)
5249
}

add-chain/cmd/compress-genesis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
var CompressGenesisCmd = cli.Command{
2525
Name: "compress-genesis",
2626
Flags: []cli.Flag{
27-
flags.L2GenesisFlag,
27+
flags.GenesisFlag,
2828
flags.L2GenesisHeaderFlag,
2929
flags.ChainShortNameFlag,
3030
flags.SuperchainTargetFlag,
@@ -47,7 +47,7 @@ var CompressGenesisCmd = cli.Command{
4747
}
4848

4949
zipOutputDir := filepath.Join(superchainRepoRoot, "/superchain/extra/genesis", superchainTarget, chainShortName+".json.gz")
50-
genesisPath := ctx.Path(flags.L2GenesisFlag.Name)
50+
genesisPath := ctx.Path(flags.GenesisFlag.Name)
5151
if genesisPath == "" {
5252
// When the genesis-state is too large, or not meant to be available, only the header data is made available.
5353
// This allows the user to verify the header-chain starting from genesis, and state-sync the latest state,

add-chain/e2e_test.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import (
1212
)
1313

1414
const (
15-
addressDir = "../superchain/extra/addresses/sepolia/"
16-
ymlConfigDir = "../superchain/configs/sepolia/"
17-
genesisConfigDir = "../superchain/extra/genesis-system-configs/sepolia/"
15+
addressDir = "../superchain/extra/addresses/sepolia/"
16+
ymlConfigDir = "../superchain/configs/sepolia/"
17+
genesisSystemConfigDir = "../superchain/extra/genesis-system-configs/sepolia/"
1818
)
1919

2020
var tests = []struct {
@@ -34,6 +34,15 @@ var tests = []struct {
3434
deploymentsDir: "./testdata/monorepo/deployments",
3535
chainType: "standard",
3636
},
37+
{
38+
name: "zorasep",
39+
chainName: "testchain_zorasep",
40+
chainShortName: "testchain_zs",
41+
rollupConfigFile: "./testdata/monorepo/op-node/rollup_zorasep.json",
42+
deploymentsDir: "./testdata/monorepo/deployments",
43+
chainType: "frontier",
44+
standardChainCandidate: true,
45+
},
3746
{
3847
name: "plasma",
3948
chainName: "testchain_plasma",
@@ -93,15 +102,15 @@ func TestAddChain_Main(t *testing.T) {
93102

94103
t.Run("compress-genesis", func(t *testing.T) {
95104
// Must run this test to produce the .json.gz output artifact for the
96-
// subsequent CheckGenesisConfig test
105+
// subsequent TestAddChain_CheckGenesis
97106
t.Parallel()
98107
err := os.Setenv("SCR_RUN_TESTS", "true")
99108
require.NoError(t, err, "failed to set SCR_RUN_TESTS env var")
100109

101110
args := []string{
102111
"add-chain",
103112
"compress-genesis",
104-
"--l2-genesis=" + "./testdata/monorepo/op-node/genesis_zorasep.json",
113+
"--genesis=" + "./testdata/monorepo/op-node/genesis_zorasep.json",
105114
"--superchain-target=" + "sepolia",
106115
"--chain-short-name=" + "testchain_zs",
107116
}
@@ -131,6 +140,22 @@ func TestAddChain_CheckRollupConfig(t *testing.T) {
131140
}
132141
}
133142

143+
func TestAddChain_CheckGenesis(t *testing.T) {
144+
t.Run("genesis_zorasep", func(t *testing.T) {
145+
err := os.Setenv("SCR_RUN_TESTS", "true")
146+
require.NoError(t, err, "failed to set SCR_RUN_TESTS env var")
147+
148+
args := []string{
149+
"add-chain",
150+
"check-genesis",
151+
"--genesis=" + "./testdata/monorepo/op-node/genesis_zorasep.json",
152+
"--chain-id=" + "4206904",
153+
}
154+
err = runApp(args)
155+
require.NoError(t, err, "add-chain check-genesis failed")
156+
})
157+
}
158+
134159
func compareJsonFiles(t *testing.T, dirPath, testName, chainShortName string) {
135160
expectedBytes, err := os.ReadFile("./testdata/" + dirPath + "expected_" + testName + ".json")
136161
require.NoError(t, err, "failed to read expected.json file from "+dirPath)
@@ -167,7 +192,7 @@ func checkConfigYaml(t *testing.T, testName, chainShortName string) {
167192
func cleanupTestFiles(t *testing.T, chainShortName string) {
168193
paths := []string{
169194
addressDir + chainShortName + ".json",
170-
genesisConfigDir + chainShortName + ".json",
195+
genesisSystemConfigDir + chainShortName + ".json",
171196
ymlConfigDir + chainShortName + ".yaml",
172197
}
173198

add-chain/flags/flags.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ var (
7777
Usage: "Filepath to rollup.json input file",
7878
Required: true,
7979
}
80+
GenesisFlag = &cli.StringFlag{
81+
Name: "genesis",
82+
EnvVars: prefixEnvVars("GENESIS"),
83+
Usage: "Filepath to genesis.json input file",
84+
Required: true,
85+
}
8086
DeploymentsDirFlag = &cli.StringFlag{
8187
Name: "deployments-dir",
8288
Value: "",
@@ -93,22 +99,14 @@ var (
9399
}
94100
ChainIdFlag = &cli.Uint64Flag{
95101
Name: "chain-id",
96-
Usage: "ID of chain to promote",
102+
Usage: "globally unique ID of chain",
97103
Required: true,
98104
}
99105
)
100106

101-
var (
102-
L2GenesisFlag = &cli.PathFlag{
103-
Name: "l2-genesis",
104-
Value: "genesis.json",
105-
Usage: "Path to genesis json (go-ethereum format)",
106-
EnvVars: prefixEnvVars("L2_GENESIS"),
107-
}
108-
L2GenesisHeaderFlag = &cli.PathFlag{
109-
Name: "l2-genesis-header",
110-
Value: "genesis-header.json",
111-
Usage: "Alternative to l2-genesis flag, if genesis-state is omitted. Path to block header at genesis",
112-
EnvVars: prefixEnvVars("L2_GENESIS_HEADER"),
113-
}
114-
)
107+
var L2GenesisHeaderFlag = &cli.PathFlag{
108+
Name: "l2-genesis-header",
109+
Value: "genesis-header.json",
110+
Usage: "Alternative to l2-genesis flag, if genesis-state is omitted. Path to block header at genesis",
111+
EnvVars: prefixEnvVars("L2_GENESIS_HEADER"),
112+
}

add-chain/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var app = &cli.App{
3838
&cmd.PromoteToStandardCmd,
3939
&cmd.CheckRollupConfigCmd,
4040
&cmd.CompressGenesisCmd,
41+
&cmd.CheckGenesisCmd,
4142
},
4243
}
4344

add-chain/testdata/monorepo/op-node/genesis_zorasep.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
"terminalTotalDifficultyPassed": true,
2222
"optimism": {
2323
"eip1559Elasticity": 6,
24-
"eip1559Denominator": 50,
25-
"eip1559DenominatorCanyon": 250
24+
"eip1559Denominator": 50
2625
}
2726
},
2827
"nonce": "0x0",
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"genesis": {
3+
"l1": {
4+
"hash": "0xf782446a2487d900addb5d466a8597c7c543b59fa9aaa154d413830238f8798a",
5+
"number": 4548041
6+
},
7+
"l2": {
8+
"hash": "0x8b17d2d52564a5a90079d9c860e1386272579e87b17ea27a3868513f53facd74",
9+
"number": 0
10+
},
11+
"l2_time": 1698080004,
12+
"system_config": {
13+
"batcherAddr": "0x3cd868e221a3be64b161d596a7482257a99d857f",
14+
"overhead": "0x00000000000000000000000000000000000000000000000000000000000000bc",
15+
"scalar": "0x00000000000000000000000000000000000000000000000000000000000a6fe0",
16+
"gasLimit": 30000000
17+
}
18+
},
19+
"block_time": 2,
20+
"max_sequencer_drift": 600,
21+
"seq_window_size": 3600,
22+
"channel_timeout": 300,
23+
"l1_chain_id": 11155111,
24+
"l2_chain_id": 4206904,
25+
"regolith_time": 0,
26+
"batch_inbox_address": "0xcd734290e4bd0200dac631c7d4b9e8a33234e91f",
27+
"deposit_contract_address": "0x6c84ae91901ce8a4897187c33a0094a6e790f34d",
28+
"l1_system_config_address": "0x8787d3382f60d4e072b4276bbda065959195db33"
29+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: testchain_zorasep
2+
chain_id: 4206904
3+
public_rpc: http://awe.some.rpc
4+
sequencer_rpc: http://awe.some.seq.rpc
5+
explorer: https://awesomescan.org
6+
7+
superchain_level: 1
8+
standard_chain_candidate: true # This is a temporary field which causes most of the standard validation checks to run on this chain
9+
superchain_time: null # Missing hardfork times are NOT yet inherited from superchain.yaml
10+
contracts_version_tag: op-contracts/v1.3.0 # Multi-Chain Prep (MCP) https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.3.0
11+
12+
batch_inbox_addr: "0xCd734290E4bd0200dAC631c7D4b9E8a33234e91f"
13+
14+
genesis:
15+
l1:
16+
hash: "0xf782446a2487d900addb5d466a8597c7c543b59fa9aaa154d413830238f8798a"
17+
number: 4548041
18+
l2:
19+
hash: "0x8b17d2d52564a5a90079d9c860e1386272579e87b17ea27a3868513f53facd74"
20+
number: 0
21+
l2_time: 1698080004 # Mon 23 Oct 2023 16:53:24 UTC

0 commit comments

Comments
 (0)