Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy create2deployer in the next hardfork #126

Merged
merged 5 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions consensus/misc/create2deployer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package misc

import (
"github.com/ethereum-optimism/superchain-registry/superchain"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
)

// The original create2deployer contract could not be deployed to Base mainnet at
// the canonical address of 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2 due to
// an accidental nonce increment from a deposit transaction. See
// https://github.com/pcaversaccio/create2deployer/issues/128 for context. This
// file applies the contract code to the canonical address manually in the Canyon
// hardfork.

// create2deployer is already deployed to Base testnets at 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2,
// so we deploy it to 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF1 for hardfork testing purposes
var create2DeployerAddresses = map[uint64]common.Address{
11763071: common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF1"), // Base Goerli devnet
params.BaseGoerliChainID: common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF1"), // Base Goerli testnet
11763072: common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF1"), // Base Sepolia devnet
84532: common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF1"), // Base Sepolia testnet
params.BaseMainnetChainID: common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2"), // Base mainnet
}
var create2DeployerCodeHash = common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2")
var create2DeployerCode []byte

func init() {
code, err := superchain.LoadContractBytecode(superchain.Hash(create2DeployerCodeHash))
mdehoog marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
panic(err)
}
create2DeployerCode = code
}

func EnsureCreate2Deployer(c *params.ChainConfig, timestamp uint64, db vm.StateDB) {
if !c.IsOptimism() || c.CanyonTime == nil || *c.CanyonTime != timestamp {
return
}
address, ok := create2DeployerAddresses[c.ChainID.Uint64()]
if !ok || db.GetCodeSize(address) > 0 {
return
}
log.Info("Setting Create2Deployer code", "address", address, "codeHash", create2DeployerCodeHash)
db.SetCode(address, create2DeployerCode)
}
103 changes: 103 additions & 0 deletions consensus/misc/create2deployer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package misc

import (
"math/big"
"testing"

"github.com/stretchr/testify/assert"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
)

func TestEnsureCreate2Deployer(t *testing.T) {
canyonTime := uint64(1000)
var tests = []struct {
name string
override func(cfg *params.ChainConfig)
timestamp uint64
codeExists bool
applied bool
}{
{
name: "at hardfork",
timestamp: canyonTime,
applied: true,
},
{
name: "non-optimism chain",
override: func(cfg *params.ChainConfig) {
cfg.Optimism = nil
},
timestamp: canyonTime,
applied: false,
},
{
name: "non-base chain",
override: func(cfg *params.ChainConfig) {
cfg.ChainID = big.NewInt(params.OPMainnetChainID)
},
timestamp: canyonTime,
applied: false,
},
{
name: "pre canyon",
timestamp: canyonTime - 1,
applied: false,
},
{
name: "post hardfork",
timestamp: canyonTime + 1,
applied: false,
},
{
name: "canyon not configured",
override: func(cfg *params.ChainConfig) {
cfg.CanyonTime = nil
},
timestamp: canyonTime,
applied: false,
},
{
name: "code already exists",
timestamp: canyonTime,
codeExists: true,
applied: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := params.ChainConfig{
ChainID: big.NewInt(params.BaseMainnetChainID),
Optimism: &params.OptimismConfig{},
CanyonTime: &canyonTime,
}
if tt.override != nil {
tt.override(&cfg)
}
state := &stateDb{
codeExists: tt.codeExists,
}
EnsureCreate2Deployer(&cfg, tt.timestamp, state)
assert.Equal(t, tt.applied, state.codeSet)
})
}
}

type stateDb struct {
vm.StateDB
codeExists bool
codeSet bool
}

func (s *stateDb) GetCodeSize(_ common.Address) int {
if s.codeExists {
return 1
}
return 0
}

func (s *stateDb) SetCode(_ common.Address, _ []byte) {
s.codeSet = true
}
1 change: 1 addition & 0 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
}
misc.EnsureCreate2Deployer(p.config, block.Time(), statedb)
var (
context = NewEVMBlockContext(header, p.bc, nil, p.config, statedb)
vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
Expand Down
3 changes: 3 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core"
Expand Down Expand Up @@ -1071,6 +1072,8 @@ func (w *worker) generateWork(genParams *generateParams) *newPayloadResult {
work.gasPool = new(core.GasPool).AddGas(work.header.GasLimit)
}

misc.EnsureCreate2Deployer(w.chainConfig, work.header.Time, work.state)

for _, tx := range genParams.txs {
from, _ := types.Sender(work.signer, tx)
work.state.SetTxContext(tx.Hash(), work.tcount)
Expand Down
14 changes: 9 additions & 5 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ var (
)

const (
OPMainnetChainID = 10
OPGoerliChainID = 420
BaseGoerliChainID = 84531
devnetChainID = 997
chaosnetChainID = 888
OPMainnetChainID = 10
OPGoerliChainID = 420
BaseMainnetChainID = 8453
BaseGoerliChainID = 84531
devnetChainID = 997
chaosnetChainID = 888
)

// OP Stack chain config
Expand Down Expand Up @@ -495,6 +496,9 @@ func (c *ChainConfig) Description() string {
if c.RegolithTime != nil {
banner += fmt.Sprintf(" - Regolith: @%-10v\n", *c.RegolithTime)
}
if c.CanyonTime != nil {
banner += fmt.Sprintf(" - Canyon: @%-10v\n", *c.CanyonTime)
}
return banner
}

Expand Down