-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: add migrator to the commit abci call #387
Conversation
storeMigrations, err := app.migrator.storeMigrator(header.Version.App, app.appVersion) | ||
if err != nil { | ||
panic(fmt.Sprintf("failed to get store migrations: %v", err)) | ||
} | ||
app.MountKVStores(storeMigrations.Added) | ||
err = app.cms.LoadLatestVersionAndUpgrade(storeMigrations.ToStoreUpgrades()) | ||
if err != nil { | ||
panic(fmt.Sprintf("failed to upgrade stores: %v", err)) | ||
} | ||
|
||
// create a new cached branch of the store to apply migrations to | ||
app.setDeliverState(header) | ||
err = app.migrator.moduleMigrator(app.deliverState.ctx, header.Version.App, app.appVersion) | ||
if err != nil { | ||
panic(fmt.Sprintf("failed to migrate modules: %v", err)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to be careful about atomicity here. I need to double check how CometBFT would handle this panic but iirc, we should also revert all the transactions previously committed
for name := range sm.Added { | ||
added[i] = name | ||
i++ | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
for name := range sm.Deleted { | ||
deleted[i] = name | ||
i++ | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, great work debugging the app hash mismatches
baseapp/abci.go
Outdated
@@ -130,7 +130,7 @@ func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOp | |||
func (app *BaseApp) Info(req abci.RequestInfo) abci.ResponseInfo { | |||
lastCommitID := app.cms.LastCommitID() | |||
// load the app version for a non zero height and zero app hash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional] this comment seems confusing b/c it doesn't immediately apply to the conditional below it
// load the app version for a non zero height and zero app hash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it still applies because you are still loading the app version if it hasn't been set
…ores (#3320) As was discovered with the apphash mismatch in #3167, by adding both v1 and v2 stores in the constructor we actually end up with a different app hash to `v1.x` as now there are a bunch of empy but initialized stores. What's needed is a mechanism that can start with only the v1 stores and then during the upgrade process add or remove the store for v2 as necessary. The main problem with this is that because we are using a branch of state we can't actually modify the stores until we write the new state to disk. Hence we can no longer perform the migration in `EndBlock` but in `Commit` whereby we first write state, then create the new stores, then perform the module migrations (like call `InitGenesis`) and then write it again finally returning the app hash. This PR depends on celestiaorg/cosmos-sdk#387 which introduces the upgrade hooks during `Commit`. This PR itself adds the two hooks for updating the stores and performing the migrations. --------- Co-authored-by: Rootul Patel <rootulp@gmail.com>
…ores (#3320) As was discovered with the apphash mismatch in celestiaorg/celestia-app#3167, by adding both v1 and v2 stores in the constructor we actually end up with a different app hash to `v1.x` as now there are a bunch of empy but initialized stores. What's needed is a mechanism that can start with only the v1 stores and then during the upgrade process add or remove the store for v2 as necessary. The main problem with this is that because we are using a branch of state we can't actually modify the stores until we write the new state to disk. Hence we can no longer perform the migration in `EndBlock` but in `Commit` whereby we first write state, then create the new stores, then perform the module migrations (like call `InitGenesis`) and then write it again finally returning the app hash. This PR depends on celestiaorg/cosmos-sdk#387 which introduces the upgrade hooks during `Commit`. This PR itself adds the two hooks for updating the stores and performing the migrations. --------- Co-authored-by: Rootul Patel <rootulp@gmail.com>
This PR addresses the app hash bug identified in this issue: celestiaorg/celestia-app#3167
It introduces a
migrator
struct toBaseApp
which allows the application to handle adding and removing stores as well as performing module migrations to any store.This needs to be done in
Commit
as we need to first write the changes on the current deliver tx branch of state, add and remove the stores from theMultiCommitStore
and then create a new branch of state to perform the migrations on. Only once they are completed and written can we calculate the new app hash