Commit d4737872 authored by Mark Tyneway's avatar Mark Tyneway

op-chain-ops: add helper function for deployments

Adds a helper function to read the correct deployment
artifacts from disk given a `hardhat.Hardhat` instance.
This code was being repeated throughout the codebase
so its better to consolidate it into a single location.
Now the `DeployConfig` has the L1 contract addresses
required to build a L2 genesis. These addresses do not
need to be present in the JSON file itself and instead
can be read from disk dynamically.

Also add a check function that will error on a config
that is not sane. This can be made more strict in the
future, currently do not want to break anything in the
process of introducing this.
parent 1aa7e74b
...@@ -84,6 +84,10 @@ func main() { ...@@ -84,6 +84,10 @@ func main() {
return err return err
} }
if err := config.Check(); err != nil {
return err
}
ovmAddresses, err := migration.NewAddresses(ctx.String("ovm-addresses")) ovmAddresses, err := migration.NewAddresses(ctx.String("ovm-addresses"))
if err != nil { if err != nil {
return err return err
...@@ -143,25 +147,16 @@ func main() { ...@@ -143,25 +147,16 @@ func main() {
return err return err
} }
// Get the addresses from the hardhat deploy artifacts // Read the required deployment addresses from disk if required
l1StandardBridgeProxyDeployment, err := hh.GetDeployment("Proxy__OVM_L1StandardBridge") if err := config.GetDeployedAddresses(hh); err != nil {
if err != nil {
return err
}
l1CrossDomainMessengerProxyDeployment, err := hh.GetDeployment("Proxy__OVM_L1CrossdomainMessenger")
if err != nil {
return err
}
l1ERC721BridgeProxyDeployment, err := hh.GetDeployment("L1ERC721BridgeProxy")
if err != nil {
return err return err
} }
l2Addrs := genesis.L2Addresses{ l2Addrs := genesis.L2Addresses{
ProxyAdminOwner: config.ProxyAdminOwner, ProxyAdminOwner: config.ProxyAdminOwner,
L1StandardBridgeProxy: l1StandardBridgeProxyDeployment.Address, L1StandardBridgeProxy: config.L1StandardBridgeProxy,
L1CrossDomainMessengerProxy: l1CrossDomainMessengerProxyDeployment.Address, L1CrossDomainMessengerProxy: config.L1CrossDomainMessengerProxy,
L1ERC721BridgeProxy: l1ERC721BridgeProxyDeployment.Address, L1ERC721BridgeProxy: config.L1ERC721BridgeProxy,
BaseFeeVaultRecipient: config.BaseFeeVaultRecipient, BaseFeeVaultRecipient: config.BaseFeeVaultRecipient,
L1FeeVaultRecipient: config.L1FeeVaultRecipient, L1FeeVaultRecipient: config.L1FeeVaultRecipient,
SequencerFeeVaultRecipient: config.SequencerFeeVaultRecipient, SequencerFeeVaultRecipient: config.SequencerFeeVaultRecipient,
......
...@@ -11,13 +11,17 @@ import ( ...@@ -11,13 +11,17 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables" "github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-chain-ops/state" "github.com/ethereum-optimism/optimism/op-chain-ops/state"
) )
var ErrInvalidDeployConfig = errors.New("invalid deploy config")
// DeployConfig represents the deployment configuration for Optimism // DeployConfig represents the deployment configuration for Optimism
type DeployConfig struct { type DeployConfig struct {
L1StartingBlockTag *rpc.BlockNumberOrHash `json:"l1StartingBlockTag"` L1StartingBlockTag *rpc.BlockNumberOrHash `json:"l1StartingBlockTag"`
...@@ -75,6 +79,16 @@ type DeployConfig struct { ...@@ -75,6 +79,16 @@ type DeployConfig struct {
L1FeeVaultRecipient common.Address `json:"l1FeeVaultRecipient"` L1FeeVaultRecipient common.Address `json:"l1FeeVaultRecipient"`
// L1 recipient of fees accumulated in the SequencerFeeVault // L1 recipient of fees accumulated in the SequencerFeeVault
SequencerFeeVaultRecipient common.Address `json:"sequencerFeeVaultRecipient"` SequencerFeeVaultRecipient common.Address `json:"sequencerFeeVaultRecipient"`
// L1StandardBridge proxy address on L1
L1StandardBridgeProxy common.Address `json:"l1StandardBridgeProxy"`
// L1CrossDomainMessenger proxy address on L1
L1CrossDomainMessengerProxy common.Address `json:"l1CrossDomainMessengerProxy"`
// L1ERC721Bridge proxy address on L1
L1ERC721BridgeProxy common.Address `json:"l1ERC721BridgeProxy"`
// SystemConfig proxy address on L1
SystemConfigProxy common.Address `json:"systemConfigProxy"`
// OptimismPortal proxy address on L1
OptimismPortalProxy common.Address `json:"optimismPortalProxy"`
GasPriceOracleOverhead uint64 `json:"gasPriceOracleOverhead"` GasPriceOracleOverhead uint64 `json:"gasPriceOracleOverhead"`
GasPriceOracleScalar uint64 `json:"gasPriceOracleScalar"` GasPriceOracleScalar uint64 `json:"gasPriceOracleScalar"`
...@@ -87,6 +101,154 @@ type DeployConfig struct { ...@@ -87,6 +101,154 @@ type DeployConfig struct {
FundDevAccounts bool `json:"fundDevAccounts"` FundDevAccounts bool `json:"fundDevAccounts"`
} }
// Check will ensure that the config is sane and return an error when it is not
func (d *DeployConfig) Check() error {
if d.L1ChainID == 0 {
return fmt.Errorf("%w: L1ChainID cannot be 0", ErrInvalidDeployConfig)
}
if d.L2ChainID == 0 {
return fmt.Errorf("%w: L2ChainID cannot be 0", ErrInvalidDeployConfig)
}
if d.L2BlockTime == 0 {
return fmt.Errorf("%w: L2BlockTime cannot be 0", ErrInvalidDeployConfig)
}
if d.FinalizationPeriodSeconds == 0 {
return fmt.Errorf("%w: FinalizationPeriodSeconds cannot be 0", ErrInvalidDeployConfig)
}
if d.MaxSequencerDrift == 0 {
return fmt.Errorf("%w: MaxSequencerDrift cannot be 0", ErrInvalidDeployConfig)
}
if d.SequencerWindowSize == 0 {
return fmt.Errorf("%w: SequencerWindowSize cannot be 0", ErrInvalidDeployConfig)
}
if d.ChannelTimeout == 0 {
return fmt.Errorf("%w: ChannelTimeout cannot be 0", ErrInvalidDeployConfig)
}
if d.P2PSequencerAddress == (common.Address{}) {
return fmt.Errorf("%w: P2PSequencerAddress cannot be address(0)", ErrInvalidDeployConfig)
}
if d.BatchInboxAddress == (common.Address{}) {
return fmt.Errorf("%w: BatchInboxAddress cannot be address(0)", ErrInvalidDeployConfig)
}
if d.BatchSenderAddress == (common.Address{}) {
return fmt.Errorf("%w: BatchSenderAddress cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2OutputOracleSubmissionInterval == 0 {
return fmt.Errorf("%w: L2OutputOracleSubmissionInterval cannot be 0", ErrInvalidDeployConfig)
}
if d.L2OutputOracleStartingTimestamp == 0 {
log.Warn("L2OutputOracleStartingTimestamp is 0")
}
if d.L2OutputOracleProposer == (common.Address{}) {
return fmt.Errorf("%w: L2OutputOracleProposer cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2OutputOracleOwner == (common.Address{}) {
return fmt.Errorf("%w: L2OutputOracleOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2OutputOracleGenesisL2Output == (common.Hash{}) {
log.Warn("L2OutputOracleGenesisL2Output is bytes32(0)")
}
if d.SystemConfigOwner == (common.Address{}) {
return fmt.Errorf("%w: SystemConfigOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.ProxyAdminOwner == (common.Address{}) {
return fmt.Errorf("%w: ProxyAdminOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2CrossDomainMessengerOwner == (common.Address{}) {
return fmt.Errorf("%w: L2CrossDomainMessengerOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.BaseFeeVaultRecipient == (common.Address{}) {
log.Warn("BaseFeeVaultRecipient is address(0)")
}
if d.L1FeeVaultRecipient == (common.Address{}) {
log.Warn("L1FeeVaultRecipient is address(0)")
}
if d.SequencerFeeVaultRecipient == (common.Address{}) {
log.Warn("SequencerFeeVaultRecipient is address(0)")
}
if d.GasPriceOracleOverhead == 0 {
log.Warn("GasPriceOracleOverhead is 0")
}
if d.GasPriceOracleScalar == 0 {
log.Warn("GasPriceOracleScalar is address(0)")
}
if d.L1StandardBridgeProxy == (common.Address{}) {
log.Warn("L1StandardBridgeProxy is address(0)")
}
if d.L1CrossDomainMessengerProxy == (common.Address{}) {
log.Warn("L1CrossDomainMessengerProxy is address(0)")
}
if d.L1ERC721BridgeProxy == (common.Address{}) {
log.Warn("L1ERC721BridgeProxy is address(0)")
}
if d.SystemConfigProxy == (common.Address{}) {
log.Warn("SystemConfigProxy is address(0)")
}
if d.OptimismPortalProxy == (common.Address{}) {
log.Warn("OptimismPortalProxy is address(0)")
}
return nil
}
// GetDeployedAddresses will get the deployed addresses of deployed L1 contracts
// required for the L2 genesis creation. Legacy systems use the `Proxy__` prefix
// while modern systems use the `Proxy` suffix. First check for the legacy
// deployments so that this works with upgrading a system.
func (d *DeployConfig) GetDeployedAddresses(hh *hardhat.Hardhat) error {
var err error
if d.L1StandardBridgeProxy == (common.Address{}) {
var l1StandardBridgeProxyDeployment *hardhat.Deployment
l1StandardBridgeProxyDeployment, err = hh.GetDeployment("Proxy__OVM_L1StandardBridge")
if errors.Is(err, hardhat.ErrCannotFindDeployment) {
l1StandardBridgeProxyDeployment, err = hh.GetDeployment("L1StandardBridgeProxy")
if err != nil {
return err
}
}
d.L1StandardBridgeProxy = l1StandardBridgeProxyDeployment.Address
}
if d.L1CrossDomainMessengerProxy == (common.Address{}) {
var l1CrossDomainMessengerProxyDeployment *hardhat.Deployment
l1CrossDomainMessengerProxyDeployment, err = hh.GetDeployment("Proxy__OVM_L1CrossdomainMessenger")
if errors.Is(err, hardhat.ErrCannotFindDeployment) {
l1CrossDomainMessengerProxyDeployment, err = hh.GetDeployment("L1CrossDomainMessengerProxy")
if err != nil {
return err
}
}
d.L1CrossDomainMessengerProxy = l1CrossDomainMessengerProxyDeployment.Address
}
if d.L1ERC721BridgeProxy == (common.Address{}) {
// There is no legacy deployment of this contract
l1ERC721BridgeProxyDeployment, err := hh.GetDeployment("L1ERC721BridgeProxy")
if err != nil {
return err
}
d.L1ERC721BridgeProxy = l1ERC721BridgeProxyDeployment.Address
}
if d.SystemConfigProxy == (common.Address{}) {
systemConfigProxyDeployment, err := hh.GetDeployment("SystemConfigProxy")
if err != nil {
return err
}
d.SystemConfigProxy = systemConfigProxyDeployment.Address
}
if d.OptimismPortalProxy == (common.Address{}) {
optimismPortalProxyDeployment, err := hh.GetDeployment("OptimismPortalProxy")
if err != nil {
return err
}
d.OptimismPortalProxy = optimismPortalProxyDeployment.Address
}
return nil
}
// NewDeployConfig reads a config file given a path on the filesystem. // NewDeployConfig reads a config file given a path on the filesystem.
func NewDeployConfig(path string) (*DeployConfig, error) { func NewDeployConfig(path string) (*DeployConfig, error) {
file, err := os.ReadFile(path) file, err := os.ReadFile(path)
......
...@@ -26,6 +26,8 @@ type L2Addresses struct { ...@@ -26,6 +26,8 @@ type L2Addresses struct {
L1FeeVaultRecipient common.Address L1FeeVaultRecipient common.Address
// BaseFeeVaultRecipient represents the L1 address that the BaseFeeVault can withdraw to // BaseFeeVaultRecipient represents the L1 address that the BaseFeeVault can withdraw to
BaseFeeVaultRecipient common.Address BaseFeeVaultRecipient common.Address
// SystemConfigProxy represents the L1 contract address of the SystemConfigProxy
SystemConfigProxy common.Address
} }
// BuildL2DeveloperGenesis will build the developer Optimism Genesis // BuildL2DeveloperGenesis will build the developer Optimism Genesis
...@@ -46,11 +48,12 @@ func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2 ...@@ -46,11 +48,12 @@ func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2
// Use the known developer addresses if they are not set // Use the known developer addresses if they are not set
if l2Addrs == nil { if l2Addrs == nil {
l2Addrs = &L2Addresses{ l2Addrs = &L2Addresses{
// Hardcoded address corresponds to m/44'/60'/0'/0/1 in the 'test test... junk' mnemonic
ProxyAdminOwner: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr, L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr, L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr, L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr,
SystemConfigProxy: predeploys.DevSystemConfigAddr,
// Hardcoded address corresponds to m/44'/60'/0'/0/1 in the 'test test... junk' mnemonic
ProxyAdminOwner: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
SequencerFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"), SequencerFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
L1FeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"), L1FeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
BaseFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"), BaseFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
......
...@@ -42,6 +42,11 @@ ...@@ -42,6 +42,11 @@
"baseFeeVaultRecipient": "0x42000000000000000000000000000000000000f5", "baseFeeVaultRecipient": "0x42000000000000000000000000000000000000f5",
"l1FeeVaultRecipient": "0x42000000000000000000000000000000000000f6", "l1FeeVaultRecipient": "0x42000000000000000000000000000000000000f6",
"sequencerFeeVaultRecipient": "0x42000000000000000000000000000000000000f7", "sequencerFeeVaultRecipient": "0x42000000000000000000000000000000000000f7",
"l1StandardBridgeProxy": "0x42000000000000000000000000000000000000f8",
"l1CrossDomainMessengerProxy": "0x42000000000000000000000000000000000000f9",
"l1ERC721BridgeProxy": "0x4200000000000000000000000000000000000060",
"systemConfigProxy": "0x4200000000000000000000000000000000000061",
"optimismPortalProxy": "0x4200000000000000000000000000000000000062",
"proxyAdminOwner": "0x0000000000000000000000000000000000000000", "proxyAdminOwner": "0x0000000000000000000000000000000000000000",
"gasPriceOracleOverhead": 2100, "gasPriceOracleOverhead": 2100,
"gasPriceOracleScalar": 1000000, "gasPriceOracleScalar": 1000000,
......
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