Commit 9fbeebda authored by Matthew Slipper's avatar Matthew Slipper

op-chain-ops: Preserve predeploy nonces

Users are unable to use the OptimismMintableERC20Factory contract due to the nonce being reset to zero. This PR updates the predeploy storage wipe function to preserve nonces during the migration. This is fixable on Goerli by incrementing the nonce manually on the factory contract.
parent 1211ba29
......@@ -119,6 +119,11 @@ func PostCheckMigratedDB(
Preimages: true,
})
prevDB, err := state.New(prevHeader.Root, underlyingDB, nil)
if err != nil {
return fmt.Errorf("cannot open historical StateDB: %w", err)
}
db, err := state.New(header.Root, underlyingDB, nil)
if err != nil {
return fmt.Errorf("cannot open StateDB: %w", err)
......@@ -134,7 +139,7 @@ func PostCheckMigratedDB(
}
log.Info("checked untouchables")
if err := PostCheckPredeploys(db); err != nil {
if err := PostCheckPredeploys(prevDB, db); err != nil {
return err
}
log.Info("checked predeploys")
......@@ -209,13 +214,13 @@ func PostCheckUntouchables(udb state.Database, currDB *state.StateDB, prevRoot c
// PostCheckPredeploys will check that there is code at each predeploy
// address
func PostCheckPredeploys(db *state.StateDB) error {
func PostCheckPredeploys(prevDB, currDB *state.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)
code := currDB.GetCode(addr)
// There must be code for the predeploy
if len(code) == 0 {
return fmt.Errorf("no code found at predeploy %s", addr)
......@@ -227,11 +232,23 @@ func PostCheckPredeploys(db *state.StateDB) error {
}
// There must be an admin
admin := db.GetState(addr, AdminSlot)
admin := currDB.GetState(addr, AdminSlot)
adminAddr := common.BytesToAddress(admin.Bytes())
if addr != predeploys.ProxyAdminAddr && addr != predeploys.GovernanceTokenAddr && adminAddr != predeploys.ProxyAdminAddr {
return fmt.Errorf("expected admin for %s to be %s but got %s", addr, predeploys.ProxyAdminAddr, adminAddr)
}
// Balances and nonces should match legacy
oldNonce := prevDB.GetNonce(addr)
oldBalance := prevDB.GetBalance(addr)
newNonce := currDB.GetNonce(addr)
newBalance := currDB.GetBalance(addr)
if oldNonce != newNonce {
return fmt.Errorf("expected nonce for %s to be %d but got %d", addr, oldNonce, newNonce)
}
if oldBalance.Cmp(newBalance) != 0 {
return fmt.Errorf("expected balance for %s to be %d but got %d", addr, oldBalance, newBalance)
}
}
// For each predeploy, check that we've set the implementation correctly when
......@@ -248,7 +265,7 @@ func PostCheckPredeploys(db *state.StateDB) error {
}
if *proxyAddr == predeploys.ProxyAdminAddr {
implCode := db.GetCode(*proxyAddr)
implCode := currDB.GetCode(*proxyAddr)
if len(implCode) == 0 {
return errors.New("no code found at proxy admin")
}
......@@ -260,12 +277,12 @@ func PostCheckPredeploys(db *state.StateDB) error {
return fmt.Errorf("error converting to code namespace: %w", err)
}
implCode := db.GetCode(expImplAddr)
implCode := currDB.GetCode(expImplAddr)
if len(implCode) == 0 {
return fmt.Errorf("no code found at predeploy impl %s", *proxyAddr)
}
impl := db.GetState(*proxyAddr, ImplementationSlot)
impl := currDB.GetState(*proxyAddr, ImplementationSlot)
actImplAddr := common.BytesToAddress(impl.Bytes())
if expImplAddr != actImplAddr {
return fmt.Errorf("expected implementation for %s to be at %s, but got %s", *proxyAddr, expImplAddr, actImplAddr)
......
......@@ -92,7 +92,17 @@ func WipePredeployStorage(db vm.StateDB) error {
}
log.Info("wiping storage", "name", name, "address", *addr)
// We need to make sure that we preserve nonces.
oldNonce := db.GetNonce(*addr)
oldBalance := db.GetBalance(*addr)
db.CreateAccount(*addr)
if oldNonce > 0 {
db.SetNonce(*addr, oldNonce)
}
if oldBalance.Cmp(common.Big0) != 0 {
db.AddBalance(*addr, oldBalance)
}
}
return nil
......
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