Commit e7b70e47 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #3437 from ethereum-optimism/feat/modularize-setting-state

op-chain-ops: modularize setting the state
parents 6fb1f979 48a8d3a0
...@@ -112,14 +112,10 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block, proxyL1Stand ...@@ -112,14 +112,10 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block, proxyL1Stand
return immutable, nil return immutable, nil
} }
// StorageConfig represents the storage configuration for the L2 predeploy
// contracts.
type StorageConfig map[string]state.StorageValues
// NewL2StorageConfig will create a StorageConfig given an instance of a // NewL2StorageConfig will create a StorageConfig given an instance of a
// Hardhat and a DeployConfig. // Hardhat and a DeployConfig.
func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1StandardBridge common.Address, proxyL1CrossDomainMessenger common.Address) (StorageConfig, error) { func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1StandardBridge common.Address, proxyL1CrossDomainMessenger common.Address) (state.StorageConfig, error) {
storage := make(StorageConfig) storage := make(state.StorageConfig)
storage["L2ToL1MessagePasser"] = state.StorageValues{ storage["L2ToL1MessagePasser"] = state.StorageValues{
"nonce": 0, "nonce": 0,
......
...@@ -62,7 +62,7 @@ func setProxies(db vm.StateDB, proxyAdminAddr common.Address, namespace *big.Int ...@@ -62,7 +62,7 @@ func setProxies(db vm.StateDB, proxyAdminAddr common.Address, namespace *big.Int
// SetImplementations will set the implmentations of the contracts in the state // SetImplementations will set the implmentations of the contracts in the state
// and configure the proxies to point to the implementations. It also sets // and configure the proxies to point to the implementations. It also sets
// the appropriate storage values for each contract at the proxy address. // the appropriate storage values for each contract at the proxy address.
func SetImplementations(db vm.StateDB, storage StorageConfig, immutable immutables.ImmutableConfig) error { func SetImplementations(db vm.StateDB, storage state.StorageConfig, immutable immutables.ImmutableConfig) error {
deployResults, err := immutables.BuildOptimism(immutable) deployResults, err := immutables.BuildOptimism(immutable)
if err != nil { if err != nil {
return err return err
...@@ -102,18 +102,9 @@ func SetImplementations(db vm.StateDB, storage StorageConfig, immutable immutabl ...@@ -102,18 +102,9 @@ func SetImplementations(db vm.StateDB, storage StorageConfig, immutable immutabl
// Set the storage values // Set the storage values
if storageConfig, ok := storage[name]; ok { if storageConfig, ok := storage[name]; ok {
layout, err := bindings.GetStorageLayout(name) if err := state.SetStorage(name, *address, storageConfig, db); err != nil {
if err != nil {
return err return err
} }
slots, err := state.ComputeStorageSlots(layout, storageConfig)
if err != nil {
return fmt.Errorf("%s: %w", name, err)
}
// The storage values must go in the proxy address
for _, slot := range slots {
db.SetState(*address, slot.Key, slot.Value)
}
} }
code := db.GetCode(addr) code := db.GetCode(addr)
......
...@@ -5,8 +5,15 @@ import ( ...@@ -5,8 +5,15 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"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"
"github.com/ethereum/go-ethereum/core/vm"
)
var (
errInvalidType = errors.New("invalid type")
errUnimplemented = errors.New("type unimplemented")
) )
// StorageValues represents the values to be set in storage. // StorageValues represents the values to be set in storage.
...@@ -14,6 +21,10 @@ import ( ...@@ -14,6 +21,10 @@ import (
// is the value to set in storage. // is the value to set in storage.
type StorageValues map[string]any type StorageValues map[string]any
// StorageConfig represents the storage configuration for the L2 predeploy
// contracts.
type StorageConfig map[string]StorageValues
// EncodedStorage represents the storage key and value serialized // EncodedStorage represents the storage key and value serialized
// to be placed in Ethereum state. // to be placed in Ethereum state.
type EncodedStorage struct { type EncodedStorage struct {
...@@ -34,8 +45,22 @@ func EncodeStorage(entry solc.StorageLayoutEntry, value any, storageType solc.St ...@@ -34,8 +45,22 @@ func EncodeStorage(entry solc.StorageLayoutEntry, value any, storageType solc.St
return encoded, nil return encoded, nil
} }
var errInvalidType = errors.New("invalid type") // SetStorage will set the storage values in a db given a contract name,
var errUnimplemented = errors.New("type unimplemented") // address and the storage values
func SetStorage(name string, address common.Address, values StorageValues, db vm.StateDB) error {
layout, err := bindings.GetStorageLayout(name)
if err != nil {
return err
}
slots, err := ComputeStorageSlots(layout, values)
if err != nil {
return fmt.Errorf("%s: %w", name, err)
}
for _, slot := range slots {
db.SetState(address, slot.Key, slot.Value)
}
return nil
}
// ComputeStorageSlots will compute the storage slots for a given contract. // ComputeStorageSlots will compute the storage slots for a given contract.
func ComputeStorageSlots(layout *solc.StorageLayout, values StorageValues) ([]*EncodedStorage, error) { func ComputeStorageSlots(layout *solc.StorageLayout, values StorageValues) ([]*EncodedStorage, error) {
......
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