Skip to content
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
8 changes: 2 additions & 6 deletions bedrock-devnet/devnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,7 @@ def devnet_l1_allocs(paths):
'forge', 'script', '--chain-id', '900', fqn, "--sig", "runWithStateDump()", "--private-key", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
], env={}, cwd=paths.contracts_bedrock_dir)

forge_dump = read_json(paths.forge_l1_dump_path)
write_json(paths.allocs_l1_path, { "accounts": forge_dump })
os.remove(paths.forge_l1_dump_path)
shutil.move(src=paths.forge_l1_dump_path, dst=paths.allocs_l1_path)

shutil.copy(paths.l1_deployments_path, paths.addresses_json_path)

Expand All @@ -168,10 +166,8 @@ def devnet_l2_allocs(paths):
# move the forge-dumps into place as .devnet allocs.
for suffix in ["-delta", ""]:
input_path = pjoin(paths.contracts_bedrock_dir, f"state-dump-901{suffix}.json")
forge_dump = read_json(input_path)
output_path = pjoin(paths.devnet_dir, f'allocs-l2{suffix}.json')
write_json(output_path, { "accounts": forge_dump })
os.remove(input_path)
shutil.move(src=input_path, dst=output_path)
log.info("Generated L2 allocs: "+output_path)


Expand Down
74 changes: 7 additions & 67 deletions op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
"path/filepath"
"reflect"

"github.com/holiman/uint256"
"golang.org/x/exp/maps"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
gstate "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -768,65 +768,8 @@ func NewL1Deployments(path string) (*L1Deployments, error) {
return &deployments, nil
}

// NewStateDump will read a Dump JSON file from disk
func NewStateDump(path string) (*gstate.Dump, error) {
file, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("dump at %s not found: %w", path, err)
}

var fdump ForgeDump
if err := json.Unmarshal(file, &fdump); err != nil {
return nil, fmt.Errorf("cannot unmarshal dump: %w", err)
}
dump := (gstate.Dump)(fdump)
return &dump, nil
}

// ForgeDump is a simple alias for state.Dump that can read "nonce" as a hex string.
// It appears as if updates to foundry have changed the serialization of the state dump.
type ForgeDump gstate.Dump

func (d *ForgeDump) UnmarshalJSON(b []byte) error {
type forgeDumpAccount struct {
Balance string `json:"balance"`
Nonce hexutil.Uint64 `json:"nonce"`
Root hexutil.Bytes `json:"root"`
CodeHash hexutil.Bytes `json:"codeHash"`
Code hexutil.Bytes `json:"code,omitempty"`
Storage map[common.Hash]string `json:"storage,omitempty"`
Address *common.Address `json:"address,omitempty"`
AddressHash hexutil.Bytes `json:"key,omitempty"`
}
type forgeDump struct {
Root string `json:"root"`
Accounts map[common.Address]forgeDumpAccount `json:"accounts"`
}
var dump forgeDump
if err := json.Unmarshal(b, &dump); err != nil {
return err
}

d.Root = dump.Root
d.Accounts = make(map[string]gstate.DumpAccount)
for addr, acc := range dump.Accounts {
acc := acc
d.Accounts[addr.String()] = gstate.DumpAccount{
Balance: acc.Balance,
Nonce: (uint64)(acc.Nonce),
Root: acc.Root,
CodeHash: acc.CodeHash,
Code: acc.Code,
Storage: acc.Storage,
Address: acc.Address,
AddressHash: acc.AddressHash,
}
}
return nil
}

type ForgeAllocs struct {
Accounts types.GenesisAlloc `json:"accounts"`
Accounts types.GenesisAlloc
}

func (d *ForgeAllocs) Copy() *ForgeAllocs {
Expand All @@ -838,25 +781,22 @@ func (d *ForgeAllocs) Copy() *ForgeAllocs {
func (d *ForgeAllocs) UnmarshalJSON(b []byte) error {
// forge, since integrating Alloy, likes to hex-encode everything.
type forgeAllocAccount struct {
Balance hexutil.Big `json:"balance"`
Balance hexutil.U256 `json:"balance"`
Nonce hexutil.Uint64 `json:"nonce"`
Code hexutil.Bytes `json:"code,omitempty"`
Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
}
type forgeAllocs struct {
Accounts map[common.Address]forgeAllocAccount `json:"accounts"`
}
var allocs forgeAllocs
var allocs map[common.Address]forgeAllocAccount
if err := json.Unmarshal(b, &allocs); err != nil {
return err
}
d.Accounts = make(types.GenesisAlloc, len(allocs.Accounts))
for addr, acc := range allocs.Accounts {
d.Accounts = make(types.GenesisAlloc, len(allocs))
for addr, acc := range allocs {
acc := acc
d.Accounts[addr] = types.Account{
Code: acc.Code,
Storage: acc.Storage,
Balance: acc.Balance.ToInt(),
Balance: (*uint256.Int)(&acc.Balance).ToBig(),
Nonce: (uint64)(acc.Nonce),
PrivateKey: nil,
}
Expand Down
47 changes: 13 additions & 34 deletions op-chain-ops/genesis/layer_one.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
gstate "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -50,50 +49,30 @@ func init() {
// all of the state required for an Optimism network to function.
// It is expected that the dump contains all of the required state to bootstrap
// the L1 chain.
func BuildL1DeveloperGenesis(config *DeployConfig, dump *gstate.Dump, l1Deployments *L1Deployments) (*core.Genesis, error) {
func BuildL1DeveloperGenesis(config *DeployConfig, dump *ForgeAllocs, l1Deployments *L1Deployments) (*core.Genesis, error) {
log.Info("Building developer L1 genesis block")
genesis, err := NewL1Genesis(config)
if err != nil {
return nil, fmt.Errorf("cannot create L1 developer genesis: %w", err)
}

if genesis.Alloc != nil && len(genesis.Alloc) != 0 {
panic("Did not expect NewL1Genesis to generate non-empty state") // sanity check for dev purposes.
}
// copy, for safety when the dump is reused (like in e2e testing)
genesis.Alloc = dump.Copy().Accounts
memDB := state.NewMemoryStateDB(genesis)
FundDevAccounts(memDB)
SetPrecompileBalances(memDB)

if dump != nil {
for addrstr, account := range dump.Accounts {
if !common.IsHexAddress(addrstr) {
// Changes in https://github.com/ethereum/go-ethereum/pull/28504
// add accounts to the Dump with "pre(<AddressHash>)" as key
// if the address itself is nil.
// So depending on how `dump` was created, this might be a
// pre-image key, which we skip.
continue
}
address := common.HexToAddress(addrstr)
name := "<unknown>"
if l1Deployments != nil {
if n := l1Deployments.GetName(address); n != "" {
name = n
}
}
log.Info("Setting account", "name", name, "address", address.Hex())
memDB.CreateAccount(address)
memDB.SetNonce(address, account.Nonce)

balance := &uint256.Int{}
if err := balance.UnmarshalText([]byte(account.Balance)); err != nil {
return nil, fmt.Errorf("failed to parse balance for %s: %w", address, err)
}
memDB.AddBalance(address, balance)
memDB.SetCode(address, account.Code)
for key, value := range account.Storage {
log.Info("Setting storage", "name", name, "key", key.Hex(), "value", value)
memDB.SetState(address, key, common.HexToHash(value))
}
l1Deployments.ForEach(func(name string, addr common.Address) {
acc := memDB.GetAccount(addr)
if acc != nil {
log.Info("Included L1 deployment", "name", name, "address", addr, "balance", acc.Balance, "storage", len(acc.Storage), "nonce", acc.Nonce)
} else {
log.Info("Excluded L1 deployment", "name", name, "address", addr)
}
}
})

return memDB.Genesis(), nil
}
Expand Down
4 changes: 2 additions & 2 deletions op-chain-ops/genesis/layer_two.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ func BuildL2Genesis(config *DeployConfig, dump *ForgeAllocs, l1StartBlock *types
if err != nil {
return nil, err
}
genspec.Alloc = dump.Accounts
genspec.Alloc = dump.Copy().Accounts
// ensure the dev accounts are not funded unintentionally
if hasDevAccounts, err := HasAnyDevAccounts(dump.Accounts); err != nil {
if hasDevAccounts, err := HasAnyDevAccounts(genspec.Alloc); err != nil {
return nil, fmt.Errorf("failed to check dev accounts: %w", err)
} else if hasDevAccounts != config.FundDevAccounts {
return nil, fmt.Errorf("deploy config mismatch with allocs. Deploy config fundDevAccounts: %v, actual allocs: %v", config.FundDevAccounts, hasDevAccounts)
Expand Down
5 changes: 2 additions & 3 deletions op-e2e/config/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"golang.org/x/exp/slog"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/log"

"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
Expand All @@ -40,7 +39,7 @@ var (
// in end to end tests.

// L1Allocs represents the L1 genesis block state.
L1Allocs *state.Dump
L1Allocs *genesis.ForgeAllocs
// L1Deployments maps contract names to accounts in the L1
// genesis block state.
L1Deployments *genesis.L1Deployments
Expand Down Expand Up @@ -108,7 +107,7 @@ func init() {
return
}

L1Allocs, err = genesis.NewStateDump(l1AllocsPath)
L1Allocs, err = genesis.LoadForgeAllocs(l1AllocsPath)
if err != nil {
panic(err)
}
Expand Down
5 changes: 2 additions & 3 deletions op-node/cmd/genesis/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/urfave/cli/v2"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
Expand Down Expand Up @@ -113,9 +112,9 @@ var Subcommands = cli.Commands{
return fmt.Errorf("deploy config at %s invalid: %w", deployConfig, err)
}

var dump *state.Dump
var dump *genesis.ForgeAllocs
if l1Allocs := ctx.String("l1-allocs"); l1Allocs != "" {
dump, err = genesis.NewStateDump(l1Allocs)
dump, err = genesis.LoadForgeAllocs(l1Allocs)
if err != nil {
return err
}
Expand Down