Skip to content

Commit

Permalink
Merge pull request #7401 from ethereum-optimism/fix/op-upgrade
Browse files Browse the repository at this point in the history
op-chain-ops: clean up `op-upgrade`
  • Loading branch information
tynes authored Sep 28, 2023
2 parents 199ef3b + 7a484b6 commit 1a490d9
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 50 deletions.
29 changes: 19 additions & 10 deletions op-chain-ops/cmd/op-upgrade/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,29 +99,31 @@ func entrypoint(ctx *cli.Context) error {
batch := safe.Batch{}

for _, chainConfig := range targets {
name, err := toDeployConfigName(chainConfig)
name, _ := toDeployConfigName(chainConfig)
config, err := genesis.NewDeployConfigWithNetwork(name, deployConfig)
if err != nil {
log.Warn("Skipping unsupported network", "name", chainConfig.Name)
continue
log.Warn("Cannot find deploy config for network", "name", chainConfig.Name, "deploy-config-name", name, "path", deployConfig)
}

config, err := genesis.NewDeployConfigWithNetwork(name, deployConfig)
if err != nil {
return err
if config != nil {
log.Info("Checking deploy config validity", "name", chainConfig.Name)
if err := config.Check(); err != nil {
return fmt.Errorf("error checking deploy config: %w", err)
}
}

clients, err := clients.NewClients(ctx.String("l1-rpc-url"), chainConfig.PublicRPC)
if err != nil {
return err
return fmt.Errorf("cannot create RPC clients: %w", err)
}

l1ChainID, err := clients.L1Client.ChainID(ctx.Context)
if err != nil {
return err
return fmt.Errorf("cannot fetch L1 chain ID: %w", err)
}
l2ChainID, err := clients.L2Client.ChainID(ctx.Context)
if err != nil {
return err
return fmt.Errorf("cannot fetch L2 chain ID: %w", err)
}
log.Info(chainConfig.Name, "l1-chain-id", l1ChainID, "l2-chain-id", l2ChainID)

Expand Down Expand Up @@ -164,15 +166,19 @@ func entrypoint(ctx *cli.Context) error {
log.Info("OptimismPortal", "version", list.OptimismPortal.Version, "address", list.OptimismPortal.Address)
log.Info("SystemConfig", "version", list.SystemConfig.Version, "address", list.SystemConfig.Address)

// Ensure that the superchain registry information is correct by checking the
// actual versions based on what the registry says is true.
if err := upgrades.CheckL1(ctx.Context, &list, clients.L1Client); err != nil {
return fmt.Errorf("error checking L1: %w", err)
}

if err := upgrades.L1(&batch, list, *addresses, config, chainConfig); err != nil {
// Build the batch
if err := upgrades.L1(&batch, list, *addresses, config, chainConfig, clients.L1Client); err != nil {
return err
}
}

// Write the batch to disk or stdout
if outfile := ctx.Path("outfile"); outfile != "" {
if err := writeJSON(outfile, batch); err != nil {
return err
Expand Down Expand Up @@ -207,6 +213,9 @@ func toDeployConfigName(cfg *superchain.ChainConfig) (string, error) {
if cfg.Name == "OP-Mainnet" {
return "mainnet", nil
}
if cfg.Name == "Zora Goerli" {
return "zora-goerli", nil
}
return "", fmt.Errorf("unsupported chain name %s", cfg.Name)
}

Expand Down
179 changes: 140 additions & 39 deletions op-chain-ops/upgrades/l1.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"

"github.com/ethereum-optimism/optimism/op-bindings/bindings"
Expand All @@ -14,33 +15,33 @@ import (
)

// L1 will add calls for upgrading each of the L1 contracts.
func L1(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
if err := L1CrossDomainMessenger(batch, implementations, list, config, chainConfig); err != nil {
return err
func L1(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
if err := L1CrossDomainMessenger(batch, implementations, list, config, chainConfig, backend); err != nil {
return fmt.Errorf("upgrading L1CrossDomainMessenger: %w", err)
}
if err := L1ERC721Bridge(batch, implementations, list, config, chainConfig); err != nil {
return err
if err := L1ERC721Bridge(batch, implementations, list, config, chainConfig, backend); err != nil {
return fmt.Errorf("upgrading L1ERC721Bridge: %w", err)
}
if err := L1StandardBridge(batch, implementations, list, config, chainConfig); err != nil {
return err
if err := L1StandardBridge(batch, implementations, list, config, chainConfig, backend); err != nil {
return fmt.Errorf("upgrading L1StandardBridge: %w", err)
}
if err := L2OutputOracle(batch, implementations, list, config, chainConfig); err != nil {
return err
if err := L2OutputOracle(batch, implementations, list, config, chainConfig, backend); err != nil {
return fmt.Errorf("upgrading L2OutputOracle: %w", err)
}
if err := OptimismMintableERC20Factory(batch, implementations, list, config, chainConfig); err != nil {
return err
if err := OptimismMintableERC20Factory(batch, implementations, list, config, chainConfig, backend); err != nil {
return fmt.Errorf("upgrading OptimismMintableERC20Factory: %w", err)
}
if err := OptimismPortal(batch, implementations, list, config, chainConfig); err != nil {
return err
if err := OptimismPortal(batch, implementations, list, config, chainConfig, backend); err != nil {
return fmt.Errorf("upgrading OptimismPortal: %w", err)
}
if err := SystemConfig(batch, implementations, list, config, chainConfig); err != nil {
return err
if err := SystemConfig(batch, implementations, list, config, chainConfig, backend); err != nil {
return fmt.Errorf("upgrading SystemConfig: %w", err)
}
return nil
}

// L1CrossDomainMessenger will add a call to the batch that upgrades the L1CrossDomainMessenger.
func L1CrossDomainMessenger(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
func L1CrossDomainMessenger(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
proxyAdminABI, err := bindings.ProxyAdminMetaData.GetAbi()
if err != nil {
return err
Expand Down Expand Up @@ -79,7 +80,7 @@ func L1CrossDomainMessenger(batch *safe.Batch, implementations superchain.Implem
}

// L1ERC721Bridge will add a call to the batch that upgrades the L1ERC721Bridge.
func L1ERC721Bridge(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
func L1ERC721Bridge(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
proxyAdminABI, err := bindings.ProxyAdminMetaData.GetAbi()
if err != nil {
return err
Expand Down Expand Up @@ -118,7 +119,7 @@ func L1ERC721Bridge(batch *safe.Batch, implementations superchain.Implementation
}

// L1StandardBridge will add a call to the batch that upgrades the L1StandardBridge.
func L1StandardBridge(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
func L1StandardBridge(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
proxyAdminABI, err := bindings.ProxyAdminMetaData.GetAbi()
if err != nil {
return err
Expand Down Expand Up @@ -157,7 +158,7 @@ func L1StandardBridge(batch *safe.Batch, implementations superchain.Implementati
}

// L2OutputOracle will add a call to the batch that upgrades the L2OutputOracle.
func L2OutputOracle(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
func L2OutputOracle(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
proxyAdminABI, err := bindings.ProxyAdminMetaData.GetAbi()
if err != nil {
return err
Expand All @@ -173,17 +174,47 @@ func L2OutputOracle(batch *safe.Batch, implementations superchain.Implementation
return fmt.Errorf("no initialize method")
}

l2OutputOracleStartingBlockNumber := new(big.Int).SetUint64(config.L2OutputOracleStartingBlockNumber)
if config.L2OutputOracleStartingTimestamp < 0 {
return fmt.Errorf("L2OutputOracleStartingBlockNumber must be concrete")
var l2OutputOracleStartingBlockNumber, l2OutputOracleStartingTimestamp *big.Int
var l2OutputOracleProposer, l2OutputOracleChallenger common.Address
if config != nil {
l2OutputOracleStartingBlockNumber = new(big.Int).SetUint64(config.L2OutputOracleStartingBlockNumber)
if config.L2OutputOracleStartingTimestamp < 0 {
return fmt.Errorf("L2OutputOracleStartingTimestamp must be concrete")
}
l2OutputOracleStartingTimestamp = new(big.Int).SetInt64(int64(config.L2OutputOracleStartingTimestamp))
l2OutputOracleProposer = config.L2OutputOracleProposer
l2OutputOracleChallenger = config.L2OutputOracleChallenger
} else {
l2OutputOracle, err := bindings.NewL2OutputOracleCaller(common.HexToAddress(list.L2OutputOracleProxy.String()), backend)
if err != nil {
return err
}
l2OutputOracleStartingBlockNumber, err = l2OutputOracle.StartingBlockNumber(&bind.CallOpts{})
if err != nil {
return err
}

l2OutputOracleStartingTimestamp, err = l2OutputOracle.StartingTimestamp(&bind.CallOpts{})
if err != nil {
return err
}

l2OutputOracleProposer, err = l2OutputOracle.PROPOSER(&bind.CallOpts{})
if err != nil {
return err
}

l2OutputOracleChallenger, err = l2OutputOracle.CHALLENGER(&bind.CallOpts{})
if err != nil {
return err
}
}
l2OutputOraclesStartingTimestamp := new(big.Int).SetInt64(int64(config.L2OutputOracleStartingTimestamp))

calldata, err := initialize.Inputs.PackValues([]any{
l2OutputOracleStartingBlockNumber,
l2OutputOraclesStartingTimestamp,
config.L2OutputOracleProposer,
config.L2OutputOracleChallenger,
l2OutputOracleStartingTimestamp,
l2OutputOracleProposer,
l2OutputOracleChallenger,
})
if err != nil {
return err
Expand All @@ -205,7 +236,7 @@ func L2OutputOracle(batch *safe.Batch, implementations superchain.Implementation
}

// OptimismMintableERC20Factory will add a call to the batch that upgrades the OptimismMintableERC20Factory.
func OptimismMintableERC20Factory(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
func OptimismMintableERC20Factory(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
proxyAdminABI, err := bindings.ProxyAdminMetaData.GetAbi()
if err != nil {
return err
Expand Down Expand Up @@ -244,7 +275,7 @@ func OptimismMintableERC20Factory(batch *safe.Batch, implementations superchain.
}

// OptimismPortal will add a call to the batch that upgrades the OptimismPortal.
func OptimismPortal(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
func OptimismPortal(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
proxyAdminABI, err := bindings.ProxyAdminMetaData.GetAbi()
if err != nil {
return err
Expand All @@ -260,9 +291,24 @@ func OptimismPortal(batch *safe.Batch, implementations superchain.Implementation
return fmt.Errorf("no initialize method")
}

var portalGuardian common.Address
if config != nil {
portalGuardian = config.PortalGuardian
} else {
optimismPortal, err := bindings.NewOptimismPortalCaller(common.HexToAddress(list.OptimismPortalProxy.String()), backend)
if err != nil {
return err
}
guardian, err := optimismPortal.GUARDIAN(&bind.CallOpts{})
if err != nil {
return err
}
portalGuardian = guardian
}

calldata, err := initialize.Inputs.PackValues([]any{
common.HexToAddress(list.L2OutputOracleProxy.String()),
config.PortalGuardian,
portalGuardian,
common.HexToAddress(chainConfig.SystemConfigAddr.String()),
false,
})
Expand All @@ -286,7 +332,7 @@ func OptimismPortal(batch *safe.Batch, implementations superchain.Implementation
}

// SystemConfig will add a call to the batch that upgrades the SystemConfig.
func SystemConfig(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig) error {
func SystemConfig(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error {
proxyAdminABI, err := bindings.ProxyAdminMetaData.GetAbi()
if err != nil {
return err
Expand All @@ -302,11 +348,67 @@ func SystemConfig(batch *safe.Batch, implementations superchain.ImplementationLi
return fmt.Errorf("no initialize method")
}

gasPriceOracleOverhead := new(big.Int).SetUint64(config.GasPriceOracleOverhead)
gasPriceOracleScalar := new(big.Int).SetUint64(config.GasPriceOracleScalar)
batcherHash := common.BytesToHash(config.BatchSenderAddress.Bytes())
l2GenesisBlockGasLimit := uint64(config.L2GenesisBlockGasLimit)
startBlock := new(big.Int).SetUint64(config.SystemConfigStartBlock)
// If we want to be able to override these based on the values in the config,
// the logic below will need to be updated. Right now the logic prefers the
// on chain values over the offchain values. This to maintain backwards compatibility
// in the short term.
startBlock := big.NewInt(0)
batchInboxAddress := common.HexToAddress(chainConfig.BatchInboxAddr.String())

var gasPriceOracleOverhead, gasPriceOracleScalar *big.Int
var batcherHash common.Hash
var p2pSequencerAddress, finalSystemOwner common.Address
var l2GenesisBlockGasLimit uint64

if config != nil {
gasPriceOracleOverhead = new(big.Int).SetUint64(config.GasPriceOracleOverhead)
gasPriceOracleScalar = new(big.Int).SetUint64(config.GasPriceOracleScalar)
batcherHash = common.BytesToHash(config.BatchSenderAddress.Bytes())
l2GenesisBlockGasLimit = uint64(config.L2GenesisBlockGasLimit)
startBlock = new(big.Int).SetUint64(config.SystemConfigStartBlock)
batchInboxAddress = config.BatchInboxAddress
p2pSequencerAddress = config.P2PSequencerAddress
finalSystemOwner = config.FinalSystemOwner
} else {
systemConfig, err := bindings.NewSystemConfigCaller(common.HexToAddress(chainConfig.SystemConfigAddr.String()), backend)
if err != nil {
return err
}
gasPriceOracleOverhead, err = systemConfig.Overhead(&bind.CallOpts{})
if err != nil {
return err
}
gasPriceOracleScalar, err = systemConfig.Scalar(&bind.CallOpts{})
if err != nil {
return err
}
batcherHash, err = systemConfig.BatcherHash(&bind.CallOpts{})
if err != nil {
return err
}
l2GenesisBlockGasLimit, err = systemConfig.GasLimit(&bind.CallOpts{})
if err != nil {
return err
}
// StartBlock is a new property, we want to explicitly set it to 0 if there is an error fetching it
systemConfigStartBlock, err := systemConfig.StartBlock(&bind.CallOpts{})
if err != nil && systemConfigStartBlock != nil {
startBlock = systemConfigStartBlock
}
// BatchInboxAddress is a new property, we want to set it to the offchain value if there is an error fetching it
systemConfigBatchInboxAddress, err := systemConfig.BatchInbox(&bind.CallOpts{})
if err != nil && systemConfigBatchInboxAddress != (common.Address{}) {
batchInboxAddress = systemConfigBatchInboxAddress
}
p2pSequencerAddress, err = systemConfig.UnsafeBlockSigner(&bind.CallOpts{})
if err != nil {
return err
}
finalSystemOwner, err = systemConfig.Owner(&bind.CallOpts{})
if err != nil {
return err
}
}

addresses := bindings.SystemConfigAddresses{
L1CrossDomainMessenger: common.HexToAddress(list.L1CrossDomainMessengerProxy.String()),
Expand All @@ -317,17 +419,16 @@ func SystemConfig(batch *safe.Batch, implementations superchain.ImplementationLi
OptimismMintableERC20Factory: common.HexToAddress(list.OptimismMintableERC20FactoryProxy.String()),
}

// This is more complex
calldata, err := initialize.Inputs.PackValues([]any{
config.FinalSystemOwner,
finalSystemOwner,
gasPriceOracleOverhead,
gasPriceOracleScalar,
batcherHash,
l2GenesisBlockGasLimit,
config.P2PSequencerAddress,
p2pSequencerAddress,
genesis.DefaultResourceConfig,
startBlock,
config.BatchInboxAddress,
batchInboxAddress,
addresses,
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts-bedrock/deploy-config/zora-goerli.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"l2GenesisRegolithTimeOffset": "0x0",
"portalGuardian": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7",
"l2OutputOracleSubmissionInterval": 180,
"l2OutputOracleStartingTimestamp": -1,
"l2OutputOracleStartingTimestamp": 0,
"l2OutputOracleProposer": "0xa98B585654fC03E2fEa3FAB56E1C851E4f5c2B54",
"l2GenesisBlockGasLimit": "0x1c9c380",
"fundDevAccounts": false,
Expand Down

0 comments on commit 1a490d9

Please sign in to comment.