Commit 62eaab9f authored by Mark Tyneway's avatar Mark Tyneway

op-chain-ops: better migration check

parent 6fe0eefa
......@@ -179,11 +179,30 @@ func main() {
dryRun := ctx.Bool("dry-run")
noCheck := ctx.Bool("no-check")
// Perform the migration
res, err := genesis.MigrateDB(ldb, config, block, &migrationData, !dryRun, noCheck)
if err != nil {
return err
}
// Close the database handle
if err := ldb.Close(); err != nil {
return err
}
postLDB, err := rawdb.NewLevelDBDatabaseWithFreezer(chaindataPath, dbCache, dbHandles, ancientPath, "", false)
if err != nil {
return err
}
if err := genesis.CheckMigratedDB(postLDB); err != nil {
return err
}
if err := postLDB.Close(); err != nil {
return err
}
opNodeConfig, err := config.RollupConfig(block, res.TransitionBlockHash, res.TransitionHeight)
if err != nil {
return err
......
package genesis
import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/trie"
)
// CheckMigratedDB will check that the migration was performed correctly
func CheckMigratedDB(ldb ethdb.Database) error {
log.Info("Validating database migration")
hash := rawdb.ReadHeadHeaderHash(ldb)
log.Info("Reading chain tip from database", "hash", hash)
num := rawdb.ReadHeaderNumber(ldb, hash)
if num == nil {
return fmt.Errorf("cannot find header number for %s", hash)
}
header := rawdb.ReadHeader(ldb, hash, *num)
log.Info("Read header from database", "number", *num)
underlyingDB := state.NewDatabaseWithConfig(ldb, &trie.Config{
Preimages: true,
})
db, err := state.New(header.Root, underlyingDB, nil)
if err != nil {
return fmt.Errorf("cannot open StateDB: %w", err)
}
if err := CheckPredeploys(db); err != nil {
return err
}
return nil
}
// CheckPredeploys will check that there is code at each predeploy
// address
func CheckPredeploys(db vm.StateDB) error {
for i := uint64(0); i <= 2048; i++ {
// Compute the predeploy address
bigAddr := new(big.Int).Or(bigL2PredeployNamespace, new(big.Int).SetUint64(i))
addr := common.BigToAddress(bigAddr)
// Get the code for the predeploy
code := db.GetCode(addr)
// There must be code for the predeploy
if len(code) == 0 {
return fmt.Errorf("no code found at predeploy %s", addr)
}
// There must be an implementation
impl := db.GetState(addr, ImplementationSlot)
implAddr := common.BytesToAddress(impl.Bytes())
if implAddr == (common.Address{}) {
return fmt.Errorf("no implementation for %s", addr)
}
implCode := db.GetCode(implAddr)
if len(implCode) == 0 {
return fmt.Errorf("no code found at predeploy impl %s", addr)
}
// There must be an admin
admin := db.GetState(addr, AdminSlot)
adminAddr := common.BytesToAddress(admin.Bytes())
if adminAddr != predeploys.ProxyAdminAddr {
return fmt.Errorf("admin is %s when it should be % for %s", adminAddr, predeploys.ProxyAdminAddr, addr)
}
}
return nil
}
......@@ -227,32 +227,9 @@ func MigrateDB(ldb ethdb.Database, config *DeployConfig, l1Block *types.Block, m
"hash", bedrockHeader.Hash().String(),
)
postDB, err := state.New(newRoot, underlyingDB, nil)
if err != nil {
return nil, err
}
if err := CheckPredeploys(postDB); err != nil {
return nil, err
}
return res, nil
}
// CheckPredeploys will check that there is code at each predeploy
// address
func CheckPredeploys(db vm.StateDB) error {
for i := uint64(0); i <= 2048; i++ {
bigAddr := new(big.Int).Or(bigL2PredeployNamespace, new(big.Int).SetUint64(i))
addr := common.BigToAddress(bigAddr)
code := db.GetCode(addr)
if len(code) == 0 {
return fmt.Errorf("no code found at %s", addr)
}
}
return nil
}
// CheckWithdrawals will ensure that the entire list of withdrawals is being
// operated on during the database migration.
func CheckWithdrawals(db vm.StateDB, withdrawals []*crossdomain.LegacyWithdrawal) 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