Commit 9ee4f3d7 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

op-chain-ops: Fix validation logic (#4316)

parent 98722d8c
...@@ -42,10 +42,12 @@ func CheckMigratedDB(ldb ethdb.Database) error { ...@@ -42,10 +42,12 @@ func CheckMigratedDB(ldb ethdb.Database) error {
if err := CheckPredeploys(db); err != nil { if err := CheckPredeploys(db); err != nil {
return err return err
} }
log.Info("checked predeploys")
if err := CheckLegacyETH(db); err != nil { if err := CheckLegacyETH(db); err != nil {
return err return err
} }
log.Info("checked legacy eth")
return nil return nil
} }
...@@ -64,24 +66,36 @@ func CheckPredeploys(db vm.StateDB) error { ...@@ -64,24 +66,36 @@ func CheckPredeploys(db vm.StateDB) error {
return fmt.Errorf("no code found at predeploy %s", addr) return fmt.Errorf("no code found at predeploy %s", addr)
} }
// There must be an implementation // There must be an admin
impl := db.GetState(addr, ImplementationSlot) admin := db.GetState(addr, AdminSlot)
adminAddr := common.BytesToAddress(admin.Bytes())
if addr != predeploys.ProxyAdminAddr && addr != predeploys.GovernanceTokenAddr && adminAddr != predeploys.ProxyAdminAddr {
return fmt.Errorf("admin is %s when it should be %s for %s", adminAddr, predeploys.ProxyAdminAddr, addr)
}
}
// For each predeploy, check that we've set the implementation correctly when
// necessary and that there's code at the implementation.
for _, proxyAddr := range predeploys.Predeploys {
implAddr, special, err := mapImplementationAddress(proxyAddr)
if err != nil {
return err
}
if !special {
impl := db.GetState(*proxyAddr, ImplementationSlot)
implAddr := common.BytesToAddress(impl.Bytes()) implAddr := common.BytesToAddress(impl.Bytes())
if implAddr == (common.Address{}) { if implAddr == (common.Address{}) {
return fmt.Errorf("no implementation for %s", addr) return fmt.Errorf("no implementation for %s", *proxyAddr)
} }
implCode := db.GetCode(implAddr)
if len(implCode) == 0 {
return fmt.Errorf("no code found at predeploy impl %s", addr)
} }
// There must be an admin implCode := db.GetCode(implAddr)
admin := db.GetState(addr, AdminSlot) if len(implCode) == 0 {
adminAddr := common.BytesToAddress(admin.Bytes()) return fmt.Errorf("no code found at predeploy impl %s", *proxyAddr)
if adminAddr != predeploys.ProxyAdminAddr {
return fmt.Errorf("admin is %s when it should be % for %s", adminAddr, predeploys.ProxyAdminAddr, addr)
} }
} }
return nil return nil
} }
......
...@@ -5,9 +5,10 @@ import ( ...@@ -5,9 +5,10 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/op-chain-ops/ether"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/ether"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
......
...@@ -76,20 +76,12 @@ func SetImplementations(db vm.StateDB, storage state.StorageConfig, immutable im ...@@ -76,20 +76,12 @@ func SetImplementations(db vm.StateDB, storage state.StorageConfig, immutable im
for name, address := range predeploys.Predeploys { for name, address := range predeploys.Predeploys {
// Convert the address to the code address unless it is // Convert the address to the code address unless it is
// designed to not be behind a proxy // designed to not be behind a proxy
var addr common.Address addr, special, err := mapImplementationAddress(address)
switch *address {
case predeploys.GovernanceTokenAddr:
addr = predeploys.GovernanceTokenAddr
case predeploys.LegacyERC20ETHAddr:
addr = predeploys.LegacyERC20ETHAddr
case predeploys.ProxyAdminAddr:
addr = predeploys.ProxyAdminAddr
default:
addr, err = AddressToCodeNamespace(*address)
if err != nil { if err != nil {
return err return err
} }
// Set the implementation slot in the predeploy proxy
if !special {
db.SetState(*address, ImplementationSlot, addr.Hash()) db.SetState(*address, ImplementationSlot, addr.Hash())
} }
...@@ -136,3 +128,23 @@ func SetPrecompileBalances(db vm.StateDB) { ...@@ -136,3 +128,23 @@ func SetPrecompileBalances(db vm.StateDB) {
db.AddBalance(addr, common.Big1) db.AddBalance(addr, common.Big1)
} }
} }
func mapImplementationAddress(addrP *common.Address) (common.Address, bool, error) {
var addr common.Address
var err error
var special bool
switch *addrP {
case predeploys.GovernanceTokenAddr:
addr = predeploys.GovernanceTokenAddr
special = true
case predeploys.LegacyERC20ETHAddr:
addr = predeploys.LegacyERC20ETHAddr
special = true
case predeploys.ProxyAdminAddr:
addr = predeploys.ProxyAdminAddr
special = true
default:
addr, err = AddressToCodeNamespace(*addrP)
}
return addr, special, err
}
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