cmd

package
v0.0.0-...-fb63973 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2024 License: MIT Imports: 24 Imported by: 0

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"`
}

type GenesisAccount

type GenesisAccount struct {
	CodeHash common.Hash                                          `json:"codeHash,omitempty"`
	Storage  jsonutil.LazySortedJsonMap[common.Hash, common.Hash] `json:"storage,omitempty"`
	Balance  *hexutil.Big                                         `json:"balance,omitempty"`
	Nonce    uint64                                               `json:"nonce,omitempty"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL