Commit 4a51b33c authored by Mark Tyneway's avatar Mark Tyneway

op-chain-ops: cleanup abstractions

parent b604f4f8
...@@ -4,6 +4,8 @@ import ( ...@@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/ethereum-optimism/superchain-registry/superchain"
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )
...@@ -19,6 +21,17 @@ var deployedBytecodes = make(map[string]string) ...@@ -19,6 +21,17 @@ var deployedBytecodes = make(map[string]string)
// in an init function. // in an init function.
var immutableReferences = make(map[string]string) var immutableReferences = make(map[string]string)
// Create2DeployerCodeHash represents the codehash of the Create2Deployer contract.
var Create2DeployerCodeHash = common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2")
func init() {
code, err := superchain.LoadContractBytecode(superchain.Hash(Create2DeployerCodeHash))
if err != nil {
panic(err)
}
deployedBytecodes["Create2Deployer"] = common.Bytes2Hex(code)
}
// GetStorageLayout returns the storage layout of a contract by name. // GetStorageLayout returns the storage layout of a contract by name.
func GetStorageLayout(name string) (*solc.StorageLayout, error) { func GetStorageLayout(name string) (*solc.StorageLayout, error) {
layout := layouts[name] layout := layouts[name]
......
...@@ -749,6 +749,7 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block) (*immutables ...@@ -749,6 +749,7 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block) (*immutables
}{ }{
Name: "EAS", Name: "EAS",
}, },
Create2Deployer: struct{}{},
} }
if err := cfg.Check(); err != nil { if err := cfg.Check(); err != nil {
......
...@@ -33,7 +33,7 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene ...@@ -33,7 +33,7 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene
return nil, err return nil, err
} }
immutable, err := NewL2ImmutableConfig(config, l1StartBlock) immutableConfig, err := NewL2ImmutableConfig(config, l1StartBlock)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -44,8 +44,8 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene ...@@ -44,8 +44,8 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene
return nil, err return nil, err
} }
// Set up the implementations // Set up the implementations that contain immutables
deployResults, err := immutables.BuildOptimism(immutable) deployResults, err := immutables.Deploy(immutableConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -18,7 +18,6 @@ import ( ...@@ -18,7 +18,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
) )
...@@ -76,7 +75,7 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi ...@@ -76,7 +75,7 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi
create2Deployer := gen.Alloc[predeploys.Create2DeployerAddr] create2Deployer := gen.Alloc[predeploys.Create2DeployerAddr]
codeHash := crypto.Keccak256Hash(create2Deployer.Code) codeHash := crypto.Keccak256Hash(create2Deployer.Code)
require.Equal(t, codeHash, immutables.Create2DeployerCodeHash) require.Equal(t, codeHash, bindings.Create2DeployerCodeHash)
if writeFile { if writeFile {
file, _ := json.MarshalIndent(gen, "", " ") file, _ := json.MarshalIndent(gen, "", " ")
......
...@@ -5,13 +5,11 @@ import ( ...@@ -5,13 +5,11 @@ import (
"math/big" "math/big"
"reflect" "reflect"
"github.com/ethereum-optimism/superchain-registry/superchain"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"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-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
...@@ -69,10 +67,9 @@ type PredeploysImmutableConfig struct { ...@@ -69,10 +67,9 @@ type PredeploysImmutableConfig struct {
EAS struct { EAS struct {
Name string Name string
} }
Create2Deployer struct{}
} }
var Create2DeployerCodeHash = common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2")
// Check will ensure that the required fields are set on the config. // Check will ensure that the required fields are set on the config.
// An error returned by `GetImmutableReferences` means that the solc compiler // An error returned by `GetImmutableReferences` means that the solc compiler
// output for the contract has no immutables in it. // output for the contract has no immutables in it.
...@@ -122,11 +119,11 @@ func (c *PredeploysImmutableConfig) ForEach(cb func(string, any) error) error { ...@@ -122,11 +119,11 @@ func (c *PredeploysImmutableConfig) ForEach(cb func(string, any) error) error {
// contracts so that the immutables can be set properly in the bytecode. // contracts so that the immutables can be set properly in the bytecode.
type DeploymentResults map[string]hexutil.Bytes type DeploymentResults map[string]hexutil.Bytes
// BuildOptimism will deploy L2 predeploys that include immutables. This is to prevent the need // Deploy will deploy L2 predeploys that include immutables. This is to prevent the need
// for parsing the solc output to find the correct immutable offsets and splicing in the values. // for parsing the solc output to find the correct immutable offsets and splicing in the values.
// Skip any predeploys that do not have immutables as their bytecode will be directly inserted // Skip any predeploys that do not have immutables as their bytecode will be directly inserted
// into the state. This does not currently support recursive structs. // into the state. This does not currently support recursive structs.
func BuildOptimism(config *PredeploysImmutableConfig) (DeploymentResults, error) { func Deploy(config *PredeploysImmutableConfig) (DeploymentResults, error) {
if err := config.Check(); err != nil { if err := config.Check(); err != nil {
return DeploymentResults{}, err return DeploymentResults{}, err
} }
...@@ -154,20 +151,18 @@ func BuildOptimism(config *PredeploysImmutableConfig) (DeploymentResults, error) ...@@ -154,20 +151,18 @@ func BuildOptimism(config *PredeploysImmutableConfig) (DeploymentResults, error)
deployments = append(deployments, deployment) deployments = append(deployments, deployment)
} }
superchainPredeploys := []deployer.SuperchainPredeploy{
{ results, err := deployContractsWithImmutables(deployments)
Name: "Create2Deployer", if err != nil {
CodeHash: Create2DeployerCodeHash, return nil, fmt.Errorf("cannot deploy contracts with immutables: %w", err)
},
} }
return BuildL2(deployments, superchainPredeploys) return results, nil
} }
// BuildL2 will deploy contracts to a simulated backend so that their immutables // deployContractsWithImmutables will deploy contracts to a simulated backend so that their immutables
// can be properly set. The bytecode returned in the results is suitable to be // can be properly set. The bytecode returned in the results is suitable to be
// inserted into the state via state surgery. // inserted into the state via state surgery.
func BuildL2(constructors []deployer.Constructor, superchainPredeploys []deployer.SuperchainPredeploy) (DeploymentResults, error) { func deployContractsWithImmutables(constructors []deployer.Constructor) (DeploymentResults, error) {
log.Info("Creating L2 state")
deployments, err := deployer.Deploy(deployer.NewL2Backend(), constructors, l2ImmutableDeployer) deployments, err := deployer.Deploy(deployer.NewL2Backend(), constructors, l2ImmutableDeployer)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -176,13 +171,6 @@ func BuildL2(constructors []deployer.Constructor, superchainPredeploys []deploye ...@@ -176,13 +171,6 @@ func BuildL2(constructors []deployer.Constructor, superchainPredeploys []deploye
for _, dep := range deployments { for _, dep := range deployments {
results[dep.Name] = dep.Bytecode results[dep.Name] = dep.Bytecode
} }
for _, dep := range superchainPredeploys {
code, err := superchain.LoadContractBytecode(superchain.Hash(dep.CodeHash))
if err != nil {
return nil, err
}
results[dep.Name] = code
}
return results, nil return results, nil
} }
...@@ -270,6 +258,7 @@ func l2ImmutableDeployer(backend *backends.SimulatedBackend, opts *bind.Transact ...@@ -270,6 +258,7 @@ func l2ImmutableDeployer(backend *backends.SimulatedBackend, opts *bind.Transact
return tx, err return tx, err
} }
// prepareFeeVaultArguments is a helper function that parses the arguments for the fee vault contracts.
func prepareFeeVaultArguments(deployment deployer.Constructor) (common.Address, *big.Int, uint8, error) { func prepareFeeVaultArguments(deployment deployer.Constructor) (common.Address, *big.Int, uint8, error) {
recipient, ok := deployment.Args[0].(common.Address) recipient, ok := deployment.Args[0].(common.Address)
if !ok { if !ok {
......
...@@ -84,10 +84,11 @@ func TestBuildOptimism(t *testing.T) { ...@@ -84,10 +84,11 @@ func TestBuildOptimism(t *testing.T) {
EAS: struct{ Name string }{ EAS: struct{ Name string }{
Name: "EAS", Name: "EAS",
}, },
Create2Deployer: struct{}{},
} }
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
results, err := immutables.BuildOptimism(&cfg) results, err := immutables.Deploy(&cfg)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, results) require.NotNil(t, results)
...@@ -112,7 +113,7 @@ func TestBuildOptimism(t *testing.T) { ...@@ -112,7 +113,7 @@ func TestBuildOptimism(t *testing.T) {
// Ensure that the PredeploysImmutableConfig is kept up to date // Ensure that the PredeploysImmutableConfig is kept up to date
for name := range predeploys.Predeploys { for name := range predeploys.Predeploys {
require.True(t, all[name]) require.Truef(t, all[name], "predeploy %s not in set of predeploys", name)
ref, err := bindings.GetImmutableReferences(name) ref, err := bindings.GetImmutableReferences(name)
// If there is predeploy config, there should be an immutable reference // If there is predeploy config, there should be an immutable reference
......
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