Commit c8f4b3a0 authored by Sam Stokes's avatar Sam Stokes Committed by GitHub

op-deployer: add intent-config-type (#12970)

* op-deployer: add config-intent-type

* op-deployer: revert name change of GasLimit

* op-deployer: add Intent.setStandardValues and Intent.validateStandardValues

* op-deployer: improve standard intent-config err messages

* op-deployr: chain intent custom err types

* op-deployer: add unit test for inent.validateStandardValues

* linter fix

* add intent-config-type custom

* add intent-config-type strict

* add intent-config-type standard-overrides,strict-overrides

* refactor intent.ConfigType validation methods, add intent NewIntent* funcs

* add TestValidateCustomValues, refactor contract tag check

* remove duplicate chainIntent.Check() code

* fix SuperchainRoles.ProxyAdminOwner for standard chains
parent 91099581
...@@ -141,6 +141,9 @@ func ApplyPipeline( ...@@ -141,6 +141,9 @@ func ApplyPipeline(
opts ApplyPipelineOpts, opts ApplyPipelineOpts,
) error { ) error {
intent := opts.Intent intent := opts.Intent
if err := intent.Check(); err != nil {
return err
}
st := opts.State st := opts.State
progressor := func(curr, total int64) { progressor := func(curr, total int64) {
......
...@@ -70,11 +70,7 @@ func (a *Locator) MarshalText() ([]byte, error) { ...@@ -70,11 +70,7 @@ func (a *Locator) MarshalText() ([]byte, error) {
return []byte(a.URL.String()), nil return []byte(a.URL.String()), nil
} }
if a.Tag != "" {
return []byte("tag://" + a.Tag), nil return []byte("tag://" + a.Tag), nil
}
return nil, fmt.Errorf("no URL, path or tag set")
} }
func (a *Locator) IsTag() bool { func (a *Locator) IsTag() bool {
......
...@@ -20,6 +20,7 @@ const ( ...@@ -20,6 +20,7 @@ const (
OutdirFlagName = "outdir" OutdirFlagName = "outdir"
PrivateKeyFlagName = "private-key" PrivateKeyFlagName = "private-key"
DeploymentStrategyFlagName = "deployment-strategy" DeploymentStrategyFlagName = "deployment-strategy"
IntentConfigTypeFlagName = "intent-config-type"
) )
var ( var (
...@@ -35,7 +36,7 @@ var ( ...@@ -35,7 +36,7 @@ var (
Name: L1ChainIDFlagName, Name: L1ChainIDFlagName,
Usage: "Chain ID of the L1 chain.", Usage: "Chain ID of the L1 chain.",
EnvVars: PrefixEnvVar("L1_CHAIN_ID"), EnvVars: PrefixEnvVar("L1_CHAIN_ID"),
Value: 900, Value: 11155111,
} }
L2ChainIDsFlag = &cli.StringFlag{ L2ChainIDsFlag = &cli.StringFlag{
Name: L2ChainIDsFlagName, Name: L2ChainIDsFlagName,
...@@ -62,6 +63,17 @@ var ( ...@@ -62,6 +63,17 @@ var (
EnvVars: PrefixEnvVar("DEPLOYMENT_STRATEGY"), EnvVars: PrefixEnvVar("DEPLOYMENT_STRATEGY"),
Value: string(state.DeploymentStrategyLive), Value: string(state.DeploymentStrategyLive),
} }
IntentConfigTypeFlag = &cli.StringFlag{
Name: IntentConfigTypeFlagName,
Usage: fmt.Sprintf("Intent config type to use. Options: %s (default), %s, %s, %s, %s",
state.IntentConfigTypeStandard,
state.IntentConfigTypeCustom,
state.IntentConfigTypeStrict,
state.IntentConfigTypeStandardOverrides,
state.IntentConfigTypeStrictOverrides),
EnvVars: PrefixEnvVar("INTENT_CONFIG_TYPE"),
Value: string(state.IntentConfigTypeStandard),
}
) )
var GlobalFlags = append([]cli.Flag{}, oplog.CLIFlags(EnvVarPrefix)...) var GlobalFlags = append([]cli.Flag{}, oplog.CLIFlags(EnvVarPrefix)...)
...@@ -71,6 +83,7 @@ var InitFlags = []cli.Flag{ ...@@ -71,6 +83,7 @@ var InitFlags = []cli.Flag{
L2ChainIDsFlag, L2ChainIDsFlag,
WorkdirFlag, WorkdirFlag,
DeploymentStrategyFlag, DeploymentStrategyFlag,
IntentConfigTypeFlag,
} }
var ApplyFlags = []cli.Flag{ var ApplyFlags = []cli.Flag{
......
...@@ -7,19 +7,17 @@ import ( ...@@ -7,19 +7,17 @@ import (
"path" "path"
"strings" "strings"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
op_service "github.com/ethereum-optimism/optimism/op-service" op_service "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-chain-ops/devkeys"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
type InitConfig struct { type InitConfig struct {
DeploymentStrategy state.DeploymentStrategy DeploymentStrategy state.DeploymentStrategy
IntentConfigType state.IntentConfigType
L1ChainID uint64 L1ChainID uint64
Outdir string Outdir string
L2ChainIDs []common.Hash L2ChainIDs []common.Hash
...@@ -51,6 +49,7 @@ func InitCLI() func(ctx *cli.Context) error { ...@@ -51,6 +49,7 @@ func InitCLI() func(ctx *cli.Context) error {
l1ChainID := ctx.Uint64(L1ChainIDFlagName) l1ChainID := ctx.Uint64(L1ChainIDFlagName)
outdir := ctx.String(OutdirFlagName) outdir := ctx.String(OutdirFlagName)
l2ChainIDsRaw := ctx.String(L2ChainIDsFlagName) l2ChainIDsRaw := ctx.String(L2ChainIDsFlagName)
intentConfigType := ctx.String(IntentConfigTypeFlagName)
if len(l2ChainIDsRaw) == 0 { if len(l2ChainIDsRaw) == 0 {
return fmt.Errorf("must specify at least one L2 chain ID") return fmt.Errorf("must specify at least one L2 chain ID")
...@@ -68,6 +67,7 @@ func InitCLI() func(ctx *cli.Context) error { ...@@ -68,6 +67,7 @@ func InitCLI() func(ctx *cli.Context) error {
err := Init(InitConfig{ err := Init(InitConfig{
DeploymentStrategy: state.DeploymentStrategy(deploymentStrategy), DeploymentStrategy: state.DeploymentStrategy(deploymentStrategy),
IntentConfigType: state.IntentConfigType(intentConfigType),
L1ChainID: l1ChainID, L1ChainID: l1ChainID,
Outdir: outdir, Outdir: outdir,
L2ChainIDs: l2ChainIDs, L2ChainIDs: l2ChainIDs,
...@@ -86,55 +86,12 @@ func Init(cfg InitConfig) error { ...@@ -86,55 +86,12 @@ func Init(cfg InitConfig) error {
return fmt.Errorf("invalid config for init: %w", err) return fmt.Errorf("invalid config for init: %w", err)
} }
intent := &state.Intent{ intent, err := state.NewIntent(cfg.IntentConfigType, cfg.DeploymentStrategy, cfg.L1ChainID, cfg.L2ChainIDs)
DeploymentStrategy: cfg.DeploymentStrategy,
L1ChainID: cfg.L1ChainID,
FundDevAccounts: true,
L1ContractsLocator: artifacts.DefaultL1ContractsLocator,
L2ContractsLocator: artifacts.DefaultL2ContractsLocator,
}
l1ChainIDBig := intent.L1ChainIDBig()
dk, err := devkeys.NewMnemonicDevKeys(devkeys.TestMnemonic)
if err != nil { if err != nil {
return fmt.Errorf("failed to create dev keys: %w", err) return err
}
addrFor := func(key devkeys.Key) common.Address {
// The error below should never happen, so panic if it does.
addr, err := dk.Address(key)
if err != nil {
panic(err)
}
return addr
}
intent.SuperchainRoles = &state.SuperchainRoles{
ProxyAdminOwner: addrFor(devkeys.L1ProxyAdminOwnerRole.Key(l1ChainIDBig)),
ProtocolVersionsOwner: addrFor(devkeys.SuperchainProtocolVersionsOwner.Key(l1ChainIDBig)),
Guardian: addrFor(devkeys.SuperchainConfigGuardianKey.Key(l1ChainIDBig)),
}
for _, l2ChainID := range cfg.L2ChainIDs {
l2ChainIDBig := l2ChainID.Big()
intent.Chains = append(intent.Chains, &state.ChainIntent{
ID: l2ChainID,
BaseFeeVaultRecipient: addrFor(devkeys.BaseFeeVaultRecipientRole.Key(l2ChainIDBig)),
L1FeeVaultRecipient: addrFor(devkeys.L1FeeVaultRecipientRole.Key(l2ChainIDBig)),
SequencerFeeVaultRecipient: addrFor(devkeys.SequencerFeeVaultRecipientRole.Key(l2ChainIDBig)),
Eip1559Denominator: 50,
Eip1559Elasticity: 6,
Roles: state.ChainRoles{
L1ProxyAdminOwner: addrFor(devkeys.L1ProxyAdminOwnerRole.Key(l2ChainIDBig)),
L2ProxyAdminOwner: addrFor(devkeys.L2ProxyAdminOwnerRole.Key(l2ChainIDBig)),
SystemConfigOwner: addrFor(devkeys.SystemConfigOwner.Key(l2ChainIDBig)),
UnsafeBlockSigner: addrFor(devkeys.SequencerP2PRole.Key(l2ChainIDBig)),
Batcher: addrFor(devkeys.BatcherRole.Key(l2ChainIDBig)),
Proposer: addrFor(devkeys.ProposerRole.Key(l2ChainIDBig)),
Challenger: addrFor(devkeys.ChallengerRole.Key(l2ChainIDBig)),
},
})
} }
intent.DeploymentStrategy = cfg.DeploymentStrategy
intent.ConfigType = cfg.IntentConfigType
st := &state.State{ st := &state.State{
Version: 1, Version: 1,
......
...@@ -714,6 +714,7 @@ func newIntent( ...@@ -714,6 +714,7 @@ func newIntent(
l2Loc *artifacts.Locator, l2Loc *artifacts.Locator,
) (*state.Intent, *state.State) { ) (*state.Intent, *state.State) {
intent := &state.Intent{ intent := &state.Intent{
ConfigType: state.IntentConfigTypeCustom,
DeploymentStrategy: state.DeploymentStrategyLive, DeploymentStrategy: state.DeploymentStrategyLive,
L1ChainID: l1ChainID.Uint64(), L1ChainID: l1ChainID.Uint64(),
SuperchainRoles: &state.SuperchainRoles{ SuperchainRoles: &state.SuperchainRoles{
...@@ -740,8 +741,9 @@ func newChainIntent(t *testing.T, dk *devkeys.MnemonicDevKeys, l1ChainID *big.In ...@@ -740,8 +741,9 @@ func newChainIntent(t *testing.T, dk *devkeys.MnemonicDevKeys, l1ChainID *big.In
BaseFeeVaultRecipient: addrFor(t, dk, devkeys.BaseFeeVaultRecipientRole.Key(l1ChainID)), BaseFeeVaultRecipient: addrFor(t, dk, devkeys.BaseFeeVaultRecipientRole.Key(l1ChainID)),
L1FeeVaultRecipient: addrFor(t, dk, devkeys.L1FeeVaultRecipientRole.Key(l1ChainID)), L1FeeVaultRecipient: addrFor(t, dk, devkeys.L1FeeVaultRecipientRole.Key(l1ChainID)),
SequencerFeeVaultRecipient: addrFor(t, dk, devkeys.SequencerFeeVaultRecipientRole.Key(l1ChainID)), SequencerFeeVaultRecipient: addrFor(t, dk, devkeys.SequencerFeeVaultRecipientRole.Key(l1ChainID)),
Eip1559Denominator: 50, Eip1559DenominatorCanyon: standard.Eip1559DenominatorCanyon,
Eip1559Elasticity: 6, Eip1559Denominator: standard.Eip1559Denominator,
Eip1559Elasticity: standard.Eip1559Elasticity,
Roles: state.ChainRoles{ Roles: state.ChainRoles{
L1ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)), L1ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)),
L2ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)), L2ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)),
......
...@@ -26,6 +26,9 @@ const ( ...@@ -26,6 +26,9 @@ const (
DisputeSplitDepth uint64 = 30 DisputeSplitDepth uint64 = 30
DisputeClockExtension uint64 = 10800 DisputeClockExtension uint64 = 10800
DisputeMaxClockDuration uint64 = 302400 DisputeMaxClockDuration uint64 = 302400
Eip1559DenominatorCanyon uint64 = 250
Eip1559Denominator uint64 = 50
Eip1559Elasticity uint64 = 6
ContractsV160Tag = "op-contracts/v1.6.0" ContractsV160Tag = "op-contracts/v1.6.0"
ContractsV170Beta1L2Tag = "op-contracts/v1.7.0-beta.1+l2-contracts" ContractsV170Beta1L2Tag = "op-contracts/v1.7.0-beta.1+l2-contracts"
...@@ -97,6 +100,28 @@ func L1VersionsFor(chainID uint64) (L1Versions, error) { ...@@ -97,6 +100,28 @@ func L1VersionsFor(chainID uint64) (L1Versions, error) {
} }
} }
func GuardianAddressFor(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.HexToAddress("0x09f7150D8c019BeF34450d6920f6B3608ceFdAf2"), nil
case 11155111:
return common.HexToAddress("0x7a50f00e8D05b95F98fE38d8BeE366a7324dCf7E"), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
}
func ChallengerAddressFor(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.HexToAddress("0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A"), nil
case 11155111:
return common.HexToAddress("0xfd1D2e729aE8eEe2E146c033bf4400fE75284301"), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
}
func SuperchainFor(chainID uint64) (*superchain.Superchain, error) { func SuperchainFor(chainID uint64) (*superchain.Superchain, error) {
switch chainID { switch chainID {
case 1: case 1:
...@@ -115,7 +140,7 @@ func ChainNameFor(chainID uint64) (string, error) { ...@@ -115,7 +140,7 @@ func ChainNameFor(chainID uint64) (string, error) {
case 11155111: case 11155111:
return "sepolia", nil return "sepolia", nil
default: default:
return "", fmt.Errorf("unrecognized chain ID: %d", chainID) return "", fmt.Errorf("unrecognized l1 chain ID: %d", chainID)
} }
} }
...@@ -173,6 +198,17 @@ func SystemOwnerAddrFor(chainID uint64) (common.Address, error) { ...@@ -173,6 +198,17 @@ func SystemOwnerAddrFor(chainID uint64) (common.Address, error) {
} }
} }
func L1ProxyAdminOwner(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.HexToAddress("0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A"), nil
case 11155111:
return common.HexToAddress("0x1Eb2fFc903729a0F03966B917003800b145F56E2"), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
}
func ArtifactsURLForTag(tag string) (*url.URL, error) { func ArtifactsURLForTag(tag string) (*url.URL, error) {
switch tag { switch tag {
case "op-contracts/v1.6.0": case "op-contracts/v1.6.0":
......
package state
import (
"fmt"
"reflect"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum/go-ethereum/common"
)
type ChainIntent struct {
ID common.Hash `json:"id" toml:"id"`
BaseFeeVaultRecipient common.Address `json:"baseFeeVaultRecipient" toml:"baseFeeVaultRecipient"`
L1FeeVaultRecipient common.Address `json:"l1FeeVaultRecipient" toml:"l1FeeVaultRecipient"`
SequencerFeeVaultRecipient common.Address `json:"sequencerFeeVaultRecipient" toml:"sequencerFeeVaultRecipient"`
Eip1559DenominatorCanyon uint64 `json:"eip1559DenominatorCanyon" toml:"eip1559DenominatorCanyon"`
Eip1559Denominator uint64 `json:"eip1559Denominator" toml:"eip1559Denominator"`
Eip1559Elasticity uint64 `json:"eip1559Elasticity" toml:"eip1559Elasticity"`
Roles ChainRoles `json:"roles" toml:"roles"`
DeployOverrides map[string]any `json:"deployOverrides" toml:"deployOverrides"`
DangerousAltDAConfig genesis.AltDADeployConfig `json:"dangerousAltDAConfig,omitempty" toml:"dangerousAltDAConfig,omitempty"`
}
type ChainRoles struct {
L1ProxyAdminOwner common.Address `json:"l1ProxyAdminOwner" toml:"l1ProxyAdminOwner"`
L2ProxyAdminOwner common.Address `json:"l2ProxyAdminOwner" toml:"l2ProxyAdminOwner"`
SystemConfigOwner common.Address `json:"systemConfigOwner" toml:"systemConfigOwner"`
UnsafeBlockSigner common.Address `json:"unsafeBlockSigner" toml:"unsafeBlockSigner"`
Batcher common.Address `json:"batcher" toml:"batcher"`
Proposer common.Address `json:"proposer" toml:"proposer"`
Challenger common.Address `json:"challenger" toml:"challenger"`
}
var ErrChainRoleZeroAddress = fmt.Errorf("ChainRole is set to zero address")
var ErrFeeVaultZeroAddress = fmt.Errorf("chain has a fee vault set to zero address")
var ErrNonStandardValue = fmt.Errorf("chain contains non-standard config value")
var ErrEip1559ZeroValue = fmt.Errorf("eip1559 param is set to zero value")
func (c *ChainIntent) Check() error {
if c.ID == emptyHash {
return fmt.Errorf("id must be set")
}
if err := c.Roles.CheckNoZeroAddresses(); err != nil {
return err
}
if c.Eip1559DenominatorCanyon == 0 ||
c.Eip1559Denominator == 0 ||
c.Eip1559Elasticity == 0 {
return fmt.Errorf("%w: chainId=%s", ErrEip1559ZeroValue, c.ID)
}
if c.BaseFeeVaultRecipient == emptyAddress ||
c.L1FeeVaultRecipient == emptyAddress ||
c.SequencerFeeVaultRecipient == emptyAddress {
return fmt.Errorf("%w: chainId=%s", ErrFeeVaultZeroAddress, c.ID)
}
if c.DangerousAltDAConfig.UseAltDA {
return c.DangerousAltDAConfig.Check(nil)
}
return nil
}
// Returns an error if any fields in ChainRoles is set to common.Address{}
func (cr *ChainRoles) CheckNoZeroAddresses() error {
val := reflect.ValueOf(*cr)
typ := reflect.TypeOf(*cr)
// Iterate through all the fields
for i := 0; i < val.NumField(); i++ {
fieldValue := val.Field(i)
fieldName := typ.Field(i).Name
if fieldValue.Interface() == (common.Address{}) {
return fmt.Errorf("%w: %s", ErrChainRoleZeroAddress, fieldName)
}
}
return nil
}
This diff is collapsed.
package state
import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestValidateStandardValues(t *testing.T) {
intent, err := NewIntentStandard(DeploymentStrategyLive, 1, []common.Hash{common.HexToHash("0x336")})
require.NoError(t, err)
err = intent.Check()
require.Error(t, err)
require.ErrorIs(t, err, ErrChainRoleZeroAddress)
setChainRoles(&intent)
err = intent.Check()
require.Error(t, err)
require.ErrorIs(t, err, ErrFeeVaultZeroAddress)
setFeeAddresses(&intent)
err = intent.Check()
require.NoError(t, err)
intent.Chains[0].Eip1559Denominator = 3 // set to non-standard value
err = intent.Check()
require.Error(t, err)
require.ErrorIs(t, err, ErrNonStandardValue)
}
func TestValidateCustomValues(t *testing.T) {
intent, err := NewIntentCustom(DeploymentStrategyLive, 1, []common.Hash{common.HexToHash("0x336")})
require.NoError(t, err)
err = intent.Check()
require.Error(t, err)
require.ErrorIs(t, err, ErrSuperchainRoleZeroAddress)
setSuperchainRoles(&intent)
err = intent.Check()
require.Error(t, err)
require.ErrorIs(t, err, ErrChainRoleZeroAddress)
setChainRoles(&intent)
err = intent.Check()
require.Error(t, err)
require.ErrorIs(t, err, ErrEip1559ZeroValue)
setEip1559Params(&intent)
err = intent.Check()
require.Error(t, err)
require.ErrorIs(t, err, ErrFeeVaultZeroAddress)
setFeeAddresses(&intent)
err = intent.Check()
require.NoError(t, err)
}
func setSuperchainRoles(intent *Intent) {
intent.SuperchainRoles = &SuperchainRoles{
ProxyAdminOwner: common.HexToAddress("0xa"),
ProtocolVersionsOwner: common.HexToAddress("0xb"),
Guardian: common.HexToAddress("0xc"),
}
}
func setEip1559Params(intent *Intent) {
intent.Chains[0].Eip1559Denominator = 5000
intent.Chains[0].Eip1559DenominatorCanyon = 5000
intent.Chains[0].Eip1559Elasticity = 5000
}
func setChainRoles(intent *Intent) {
intent.Chains[0].Roles.L1ProxyAdminOwner = common.HexToAddress("0x01")
intent.Chains[0].Roles.L2ProxyAdminOwner = common.HexToAddress("0x02")
intent.Chains[0].Roles.SystemConfigOwner = common.HexToAddress("0x03")
intent.Chains[0].Roles.UnsafeBlockSigner = common.HexToAddress("0x04")
intent.Chains[0].Roles.Batcher = common.HexToAddress("0x05")
intent.Chains[0].Roles.Proposer = common.HexToAddress("0x06")
intent.Chains[0].Roles.Challenger = common.HexToAddress("0x07")
}
func setFeeAddresses(intent *Intent) {
intent.Chains[0].BaseFeeVaultRecipient = common.HexToAddress("0x08")
intent.Chains[0].L1FeeVaultRecipient = common.HexToAddress("0x09")
intent.Chains[0].SequencerFeeVaultRecipient = common.HexToAddress("0x0A")
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment