Skip to content

Commit acd8cf8

Browse files
authored
genesis: fix permit2 panic (ethereum-optimism#10332)
* genesis: fix permit2 panic Its possible that permit2 isn't in the genesis allocs even though it should be, it removes the flexibility to define the genesis spec arbitrarily if we implicitly enforce it being present. We need a better way to check that the chain id during genesis allocation matches the chain id in the genesis spec. An attempt at this is done in ethereum-optimism#10326. Fixes ethereum-optimism#10309 * op-chain-ops: better check * cleanup: fix build * build: fix
1 parent aa1dc04 commit acd8cf8

File tree

2 files changed

+28
-33
lines changed

2 files changed

+28
-33
lines changed

Diff for: op-chain-ops/genesis/helpers.go

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package genesis
22

33
import (
4-
"bytes"
54
"context"
65
"fmt"
76
"math/big"
@@ -14,18 +13,12 @@ import (
1413
)
1514

1615
var (
17-
// codeNamespace represents the namespace of implementations of predeploys
18-
codeNamespace = common.HexToAddress("0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000")
19-
// l2PredeployNamespace represents the namespace of L2 predeploys
20-
l2PredeployNamespace = common.HexToAddress("0x4200000000000000000000000000000000000000")
21-
// BigL2PredeployNamespace represents the predeploy namespace as a big.Int
22-
BigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes())
23-
// bigCodeNamespace represents the predeploy namespace as a big.Int
24-
bigCodeNamespace = new(big.Int).SetBytes(codeNamespace.Bytes())
2516
// ImplementationSlot represents the EIP 1967 implementation storage slot
2617
ImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc")
2718
// AdminSlot represents the EIP 1967 admin storage slot
2819
AdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103")
20+
// The devBalance is the amount of wei that a dev account is funded with.
21+
devBalance = hexutil.MustDecodeBig("0x200000000000000000000000000000000000000000000000000000000000000")
2922
)
3023

3124
// DevAccounts represent the standard hardhat development accounts.
@@ -59,24 +52,6 @@ var DevAccounts = []common.Address{
5952
common.HexToAddress("0x3fab184622dc19b6109349b94811493bf2a45362"),
6053
}
6154

62-
// The devBalance is the amount of wei that a dev account is funded with.
63-
var devBalance = hexutil.MustDecodeBig("0x200000000000000000000000000000000000000000000000000000000000000")
64-
65-
// AddressToCodeNamespace takes a predeploy address and computes
66-
// the implementation address that the implementation should be deployed at
67-
func AddressToCodeNamespace(addr common.Address) (common.Address, error) {
68-
if !IsL2DevPredeploy(addr) {
69-
return common.Address{}, fmt.Errorf("cannot handle non predeploy: %s", addr)
70-
}
71-
bigAddress := new(big.Int).SetBytes(addr[18:])
72-
num := new(big.Int).Or(bigCodeNamespace, bigAddress)
73-
return common.BigToAddress(num), nil
74-
}
75-
76-
func IsL2DevPredeploy(addr common.Address) bool {
77-
return bytes.Equal(addr[0:2], []byte{0x42, 0x00})
78-
}
79-
8055
// GetBlockFromTag will resolve a Block given an rpc block tag
8156
func GetBlockFromTag(chain ethereum.ChainReader, tag *rpc.BlockNumberOrHash) (*types.Block, error) {
8257
if hash, ok := tag.Hash(); ok {

Diff for: op-chain-ops/genesis/layer_two.go

+26-6
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package genesis
33
import (
44
"encoding/json"
55
"fmt"
6+
"math/big"
67
"os"
78
"path/filepath"
89

910
hdwallet "github.com/ethereum-optimism/go-ethereum-hdwallet"
1011
"github.com/holiman/uint256"
1112

1213
"github.com/ethereum/go-ethereum/accounts"
14+
"github.com/ethereum/go-ethereum/common"
1315
"github.com/ethereum/go-ethereum/core"
1416
"github.com/ethereum/go-ethereum/core/types"
1517
"github.com/ethereum/go-ethereum/crypto"
@@ -24,6 +26,13 @@ const (
2426
L2AllocsEcotone L2AllocsMode = "" // the default in solidity scripting / testing
2527
)
2628

29+
var (
30+
// l2PredeployNamespace is the namespace for L2 predeploys
31+
l2PredeployNamespace = common.HexToAddress("0x4200000000000000000000000000000000000000")
32+
// mnemonic for the test accounts in hardhat/foundry
33+
testMnemonic = "test test test test test test test test test test test junk"
34+
)
35+
2736
type AllocsLoader func(mode L2AllocsMode) *ForgeAllocs
2837

2938
// BuildL2Genesis will build the L2 genesis block.
@@ -40,16 +49,27 @@ func BuildL2Genesis(config *DeployConfig, dump *ForgeAllocs, l1StartBlock *types
4049
return nil, fmt.Errorf("deploy config mismatch with allocs. Deploy config fundDevAccounts: %v, actual allocs: %v", config.FundDevAccounts, hasDevAccounts)
4150
}
4251
// sanity check the permit2 immutable, to verify we using the allocs for the right chain.
43-
chainID := [32]byte(genspec.Alloc[predeploys.Permit2Addr].Code[6945 : 6945+32])
44-
expected := uint256.MustFromBig(genspec.Config.ChainID).Bytes32()
45-
if chainID != expected {
46-
return nil, fmt.Errorf("allocs were generated for chain ID %x, but expected chain %x (%d)", chainID, expected, genspec.Config.ChainID)
52+
if permit2 := genspec.Alloc[predeploys.Permit2Addr].Code; len(permit2) != 0 {
53+
if len(permit2) < 6945+32 {
54+
return nil, fmt.Errorf("permit2 code is too short (%d)", len(permit2))
55+
}
56+
chainID := [32]byte(permit2[6945 : 6945+32])
57+
expected := uint256.MustFromBig(genspec.Config.ChainID).Bytes32()
58+
if chainID != expected {
59+
return nil, fmt.Errorf("allocs were generated for chain ID %x, but expected chain %x (%d)", chainID, expected, genspec.Config.ChainID)
60+
}
4761
}
62+
// sanity check that all predeploys are present
63+
for i := 0; i < 2048; i++ {
64+
addr := common.BigToAddress(new(big.Int).Or(l2PredeployNamespace.Big(), big.NewInt(int64(i))))
65+
if len(genspec.Alloc[addr].Code) == 0 {
66+
return nil, fmt.Errorf("predeploy %x is missing from L2 genesis allocs", addr)
67+
}
68+
}
69+
4870
return genspec, nil
4971
}
5072

51-
var testMnemonic = "test test test test test test test test test test test junk"
52-
5373
func HasAnyDevAccounts(allocs core.GenesisAlloc) (bool, error) {
5474
wallet, err := hdwallet.NewFromMnemonic(testMnemonic)
5575
if err != nil {

0 commit comments

Comments
 (0)