init.go 3.02 KB
Newer Older
1 2 3
package deployer

import (
4
	"errors"
5
	"fmt"
6
	"os"
7
	"path"
8 9
	"strings"

10
	"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
11

12
	op_service "github.com/ethereum-optimism/optimism/op-service"
13 14 15 16 17 18

	"github.com/ethereum/go-ethereum/common"
	"github.com/urfave/cli/v2"
)

type InitConfig struct {
19
	DeploymentStrategy state.DeploymentStrategy
20
	IntentConfigType   state.IntentConfigType
21 22 23
	L1ChainID          uint64
	Outdir             string
	L2ChainIDs         []common.Hash
24 25 26
}

func (c *InitConfig) Check() error {
27 28 29 30
	if err := c.DeploymentStrategy.Check(); err != nil {
		return err
	}

31 32 33 34 35 36 37 38
	if c.L1ChainID == 0 {
		return fmt.Errorf("l1ChainID must be specified")
	}

	if c.Outdir == "" {
		return fmt.Errorf("outdir must be specified")
	}

39 40 41 42
	if len(c.L2ChainIDs) == 0 {
		return fmt.Errorf("must specify at least one L2 chain ID")
	}

43 44 45 46 47
	return nil
}

func InitCLI() func(ctx *cli.Context) error {
	return func(ctx *cli.Context) error {
48
		deploymentStrategy := ctx.String(DeploymentStrategyFlagName)
49 50
		l1ChainID := ctx.Uint64(L1ChainIDFlagName)
		outdir := ctx.String(OutdirFlagName)
51
		l2ChainIDsRaw := ctx.String(L2ChainIDsFlagName)
52
		intentConfigType := ctx.String(IntentConfigTypeFlagName)
53 54 55 56 57

		if len(l2ChainIDsRaw) == 0 {
			return fmt.Errorf("must specify at least one L2 chain ID")
		}

58 59
		l2ChainIDsStr := strings.Split(strings.TrimSpace(l2ChainIDsRaw), ",")
		l2ChainIDs := make([]common.Hash, len(l2ChainIDsStr))
60
		for i, idStr := range l2ChainIDsStr {
61 62
			id, err := op_service.Parse256BitChainID(idStr)
			if err != nil {
63
				return fmt.Errorf("invalid L2 chain ID '%s': %w", idStr, err)
64
			}
65
			l2ChainIDs[i] = id
66
		}
67

68
		err := Init(InitConfig{
69
			DeploymentStrategy: state.DeploymentStrategy(deploymentStrategy),
70
			IntentConfigType:   state.IntentConfigType(intentConfigType),
71 72 73
			L1ChainID:          l1ChainID,
			Outdir:             outdir,
			L2ChainIDs:         l2ChainIDs,
74
		})
75 76 77 78 79 80
		if err != nil {
			return err
		}

		fmt.Printf("Successfully initialized op-deployer intent in directory: %s\n", outdir)
		return nil
81 82 83 84 85 86 87 88
	}
}

func Init(cfg InitConfig) error {
	if err := cfg.Check(); err != nil {
		return fmt.Errorf("invalid config for init: %w", err)
	}

89
	intent, err := state.NewIntent(cfg.IntentConfigType, cfg.DeploymentStrategy, cfg.L1ChainID, cfg.L2ChainIDs)
90
	if err != nil {
91
		return err
92
	}
93 94
	intent.DeploymentStrategy = cfg.DeploymentStrategy
	intent.ConfigType = cfg.IntentConfigType
95

96
	st := &state.State{
97 98 99
		Version: 1,
	}

100 101 102 103 104 105 106 107 108 109 110
	stat, err := os.Stat(cfg.Outdir)
	if errors.Is(err, os.ErrNotExist) {
		if err := os.MkdirAll(cfg.Outdir, 0755); err != nil {
			return fmt.Errorf("failed to create outdir: %w", err)
		}
	} else if err != nil {
		return fmt.Errorf("failed to stat outdir: %w", err)
	} else if !stat.IsDir() {
		return fmt.Errorf("outdir is not a directory")
	}

111 112 113 114 115 116 117 118
	if err := intent.WriteToFile(path.Join(cfg.Outdir, "intent.toml")); err != nil {
		return fmt.Errorf("failed to write intent to file: %w", err)
	}
	if err := st.WriteToFile(path.Join(cfg.Outdir, "state.json")); err != nil {
		return fmt.Errorf("failed to write state to file: %w", err)
	}
	return nil
}