Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var CheckGenesisCmd = cli.Command{ Name: "check-genesis", Flags: []cli.Flag{flags.GenesisFlag}, Usage: "Sanity check genesis (genesis.json) is reproducible", Action: func(ctx *cli.Context) error { genesisPath := ctx.String(flags.GenesisFlag.Name) fmt.Printf("Attempting to read from %s\n", genesisPath) file, err := os.ReadFile(genesisPath) if err != nil { return fmt.Errorf("failed to read from local genesis.json config file: %w", err) } var localGenesis *core.Genesis if err = json.Unmarshal(file, &localGenesis); err != nil { return fmt.Errorf("failed to unmarshal local genesis.json into core.Genesis struct: %w", err) } chainId := localGenesis.Config.ChainID.Uint64() gethGenesis, err := core.LoadOPStackGenesis(chainId) if err != nil { return fmt.Errorf("failed to load genesis via op-geth: ensure chainId has already been added to registry: %w", err) } opts := cmp.Options{cmpopts.IgnoreUnexported(big.Int{})} if diff := cmp.Diff(localGenesis, gethGenesis, opts...); diff != "" { return fmt.Errorf("local genesis.json (-) does not match config generated by op-geth (+): %s", diff) } fmt.Println("Regenerated genesis config matches existing one") return nil }, }
View Source
var CheckRollupConfigCmd = cli.Command{ Name: "check-rollup-config", Flags: []cli.Flag{flags.RollupConfigFlag}, Usage: "Sanity check rollup config (rollup.json) is reproducible", Action: func(ctx *cli.Context) error { rollupConfigPath := ctx.String(flags.RollupConfigFlag.Name) fmt.Printf("Attempting to read from %s\n", rollupConfigPath) file, err := os.ReadFile(rollupConfigPath) if err != nil { return fmt.Errorf("failed to read from local rollup.json config file: %w", err) } var localRollupConfig *rollup.Config if err = json.Unmarshal(file, &localRollupConfig); err != nil { return fmt.Errorf("failed to unmarshal local rollup.json into rollup.Config struct: %w", err) } opNodeRollupConfig, err := rollup.LoadOPStackRollupConfig(localRollupConfig.L2ChainID.Uint64()) if err != nil { return fmt.Errorf("op-node failed to generate rollup config: %w", err) } localRollupConfig.ProtocolVersionsAddress = common.Address{} localRollupConfig.ChannelTimeoutGranite = 50 opNodeRollupConfig.ProtocolVersionsAddress = common.Address{} opts := cmp.Options{cmpopts.IgnoreUnexported(big.Int{})} if diff := cmp.Diff(localRollupConfig, opNodeRollupConfig, opts...); diff != "" { return fmt.Errorf("local rollup.json (-) does not match config generated by op-node (+): %s", diff) } fmt.Println("Regenerated rollup config matches existing one") return nil }, }
View Source
var CompressGenesisCmd = cli.Command{ Name: "compress-genesis", Flags: []cli.Flag{ flags.GenesisFlag, flags.L2GenesisHeaderFlag, flags.ChainShortNameFlag, flags.SuperchainTargetFlag, }, Usage: "Generate a single gzipped data file from a bytecode hex string", Action: func(ctx *cli.Context) error { _, thisFile, _, ok := runtime.Caller(0) if !ok { panic("error getting current filepath") } superchainRepoRoot := filepath.Dir(filepath.Dir(filepath.Dir(thisFile))) superchainTarget := ctx.String(flags.SuperchainTargetFlag.Name) if superchainTarget == "" { return fmt.Errorf("missing required flag: %s", flags.SuperchainTargetFlag.Name) } chainShortName := ctx.String(flags.ChainShortNameFlag.Name) if chainShortName == "" { return fmt.Errorf("missing required flag: %s", flags.ChainShortNameFlag.Name) } zipOutputDir := filepath.Join(superchainRepoRoot, "/superchain/extra/genesis", superchainTarget, chainShortName+".json.gz") genesisPath := ctx.Path(flags.GenesisFlag.Name) if genesisPath == "" { genesisHeaderPath := ctx.Path(flags.L2GenesisHeaderFlag.Name) genesisHeader, err := utils.LoadJSON[types.Header](genesisHeaderPath) if err != nil { return fmt.Errorf("genesis-header %q failed to load: %w", genesisHeaderPath, err) } if genesisHeader.TxHash != types.EmptyTxsHash { return errors.New("genesis-header based genesis must have no transactions") } if genesisHeader.ReceiptHash != types.EmptyReceiptsHash { return errors.New("genesis-header based genesis must have no receipts") } if genesisHeader.UncleHash != types.EmptyUncleHash { return errors.New("genesis-header based genesis must have no uncle hashes") } if genesisHeader.WithdrawalsHash != nil && *genesisHeader.WithdrawalsHash != types.EmptyWithdrawalsHash { return errors.New("genesis-header based genesis must have no withdrawals") } out := Genesis{ Nonce: genesisHeader.Nonce.Uint64(), Timestamp: genesisHeader.Time, ExtraData: genesisHeader.Extra, GasLimit: genesisHeader.GasLimit, Difficulty: (*hexutil.Big)(genesisHeader.Difficulty), Mixhash: genesisHeader.MixDigest, Coinbase: genesisHeader.Coinbase, Number: genesisHeader.Number.Uint64(), GasUsed: genesisHeader.GasUsed, ParentHash: genesisHeader.ParentHash, BaseFee: (*hexutil.Big)(genesisHeader.BaseFee), ExcessBlobGas: genesisHeader.ExcessBlobGas, BlobGasUsed: genesisHeader.BlobGasUsed, Alloc: make(jsonutil.LazySortedJsonMap[common.Address, GenesisAccount]), StateHash: &genesisHeader.Root, } if err := writeGzipJSON(zipOutputDir, out); err != nil { return fmt.Errorf("failed to write output: %w", err) } return nil } genesis, err := utils.LoadJSON[core.Genesis](genesisPath) if err != nil { return fmt.Errorf("failed to load L2 genesis: %w", err) } bytecodesDir := filepath.Join(superchainRepoRoot, "/superchain/extra/bytecodes") fmt.Printf("using output bytecodes dir: %s\n", bytecodesDir) if err := os.MkdirAll(bytecodesDir, 0o755); err != nil { return fmt.Errorf("failed to make bytecodes dir: %w", err) } for addr, account := range genesis.Alloc { if len(account.Code) > 0 { err = writeBytecode(bytecodesDir, account.Code, addr) if err != nil { return err } } } out := Genesis{ Nonce: genesis.Nonce, Timestamp: genesis.Timestamp, ExtraData: genesis.ExtraData, GasLimit: genesis.GasLimit, Difficulty: (*hexutil.Big)(genesis.Difficulty), Mixhash: genesis.Mixhash, Coinbase: genesis.Coinbase, Number: genesis.Number, GasUsed: genesis.GasUsed, ParentHash: genesis.ParentHash, BaseFee: (*hexutil.Big)(genesis.BaseFee), ExcessBlobGas: genesis.ExcessBlobGas, BlobGasUsed: genesis.BlobGasUsed, Alloc: make(jsonutil.LazySortedJsonMap[common.Address, GenesisAccount]), } for addr, account := range genesis.Alloc { var codeHash common.Hash if len(account.Code) > 0 { codeHash = crypto.Keccak256Hash(account.Code) } outAcc := GenesisAccount{ CodeHash: codeHash, Nonce: account.Nonce, } if account.Balance != nil && account.Balance.Cmp(common.Big0) != 0 { outAcc.Balance = (*hexutil.Big)(account.Balance) } if len(account.Storage) > 0 { outAcc.Storage = make(jsonutil.LazySortedJsonMap[common.Hash, common.Hash]) for k, v := range account.Storage { outAcc.Storage[k] = v } } out.Alloc[addr] = outAcc } if err := writeGzipJSON(zipOutputDir, out); err != nil { return fmt.Errorf("failed to write output: %w", err) } return nil }, }
View Source
var PromoteToStandardCmd = cli.Command{ Name: "promote-to-standard", Flags: []cli.Flag{flags.ChainIdFlag}, Aliases: []string{"p"}, Usage: "Promote a chain to standard.", Action: func(ctx *cli.Context) error { chainId := flags.ChainIdFlag.Get(ctx) chain, ok := superchain.OPChains[chainId] if !ok { panic(fmt.Sprintf("No chain found with id %d", chainId)) } copy, err := chain.PromoteToStandard() if err != nil { panic(err) } chain = copy _, thisFile, _, ok := runtime.Caller(0) if !ok { panic("Unable to get the current file path") } superchainRepoPath := filepath.Dir(filepath.Dir(filepath.Dir(thisFile))) targetDir := filepath.Join(superchainRepoPath, "superchain", "configs", chain.Superchain) targetFilePath := filepath.Join(targetDir, chain.Chain+".toml") err = config.WriteChainConfigTOML(*chain, targetFilePath) if err != nil { panic(err) } fmt.Println("Promoted chain to standard: ", chainId) return nil }, }
View Source
var UpdateConfigsCmd = cli.Command{ Name: "update-configs", Aliases: []string{"u"}, Usage: "Update all config toml files after superchain.ChainConfig struct is updated", Action: func(ctx *cli.Context) error { for _, chain := range superchain.OPChains { _, thisFile, _, ok := runtime.Caller(0) if !ok { panic("Unable to get the current file path") } err := chain.CheckDataAvailability() if err != nil { panic(err) } superchainRepoPath := filepath.Dir(filepath.Dir(filepath.Dir(thisFile))) targetDir := filepath.Join(superchainRepoPath, "superchain", "configs", chain.Superchain) targetFilePath := filepath.Join(targetDir, chain.Chain+".toml") err = config.WriteChainConfigTOML(*chain, targetFilePath) if err != nil { panic(err) } } return nil }, }
Functions ¶
This section is empty.
Types ¶
type Genesis ¶
type Genesis struct { Nonce uint64 `json:"nonce"` Timestamp uint64 `json:"timestamp"` ExtraData []byte `json:"extraData"` GasLimit uint64 `json:"gasLimit"` Difficulty *hexutil.Big `json:"difficulty"` Mixhash common.Hash `json:"mixHash"` Coinbase common.Address `json:"coinbase"` Number uint64 `json:"number"` GasUsed uint64 `json:"gasUsed"` ParentHash common.Hash `json:"parentHash"` BaseFee *hexutil.Big `json:"baseFeePerGas"` ExcessBlobGas *uint64 `json:"excessBlobGas"` // EIP-4844 BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844 Alloc jsonutil.LazySortedJsonMap[common.Address, GenesisAccount] `json:"alloc"` // For genesis definitions without full state (OP-Mainnet, OP-Goerli) StateHash *common.Hash `json:"stateHash,omitempty"` }
Click to show internal directories.
Click to hide internal directories.