Skip to content

Commit

Permalink
fix: set upgrade handler to fix iavl stores in testnet
Browse files Browse the repository at this point in the history
chore: update comments and use proper upgrade name

chore: add check for storage version in the upgrade handler

chore: remove upgrade logic
  • Loading branch information
Lockwarr committed Apr 21, 2023
1 parent fdc9aa9 commit 9f14d69
Showing 1 changed file with 77 additions and 14 deletions.
91 changes: 77 additions & 14 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/Nolus-Protocol/nolus-core/app/keepers"
"github.com/Nolus-Protocol/nolus-core/app/upgrades"

"github.com/cosmos/cosmos-sdk/store/iavl"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
Expand All @@ -19,22 +20,9 @@ func (app *App) RegisterUpgradeHandlers() {
app.registerUpgrade(upgradeInfo)
}

func (app *App) createUpgradeHandlerTestnet(
mm *module.Manager,
configurator module.Configurator,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
ctx.Logger().Info("Upgrade handler execution", "name", "v0.2.2")
ctx.Logger().Info("Running migrations")
return app.mm.RunMigrations(ctx, app.configurator, fromVM)
}
}

// upgrade v0.2.2.
func (app *App) registerUpgrade(_ storetypes.UpgradeInfo) {
testnetUpgrade := upgrades.Upgrade{
UpgradeName: "v0.2.2",
UpgradeName: "v0.2.2-store-fix",
CreateUpgradeHandler: app.createUpgradeHandlerTestnet,
StoreUpgrades: storetypes.StoreUpgrades{
Added: []string{},
Expand All @@ -49,3 +37,78 @@ func (app *App) registerUpgrade(_ storetypes.UpgradeInfo) {
),
)
}

func (app *App) createUpgradeHandlerTestnet(
mm *module.Manager,
configurator module.Configurator,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
ctx.Logger().Info("Upgrade handler execution", "name", "v0.2.2-store-fix")
// Get the Commit multistore
// cms := app.BaseApp.CommitMultiStore()

// Get the underlying iavl Stores for the contractmanager and feerefunder modules
// contractManagerStore := cms.GetCommitKVStore(app.GetKey(contractmanagertypes.StoreKey)).(*iavl.Store)
// feeRefunderStore := cms.GetCommitKVStore(app.GetKey(feerefundertypes.StoreKey)).(*iavl.Store)

// We found this issue thanks to a code change introduced in the cosmos-sdk v0.45.12
// https://github.com/cosmos/gaia/issues/2313

// Export(at latest commit height) and import the store at the latest block height
// We do this because we didn't use a custom store loader
// on the upgrade where the two modules(contractmanager && feerefunder) were introduced and
// their store versions began from height 0/1 but they should have started at the height of the upgrade
// so right now we have a gap, other modules' stores initialized at genesis are at height X, while those two modules are behind at height X-softwareUpgradeHeight
// err := exportAndImportStoreAtLatestHeight(ctx, contractManagerStore)
// if err != nil {
// return nil, err
// }
// err = exportAndImportStoreAtLatestHeight(ctx, feeRefunderStore)
// if err != nil {
// return nil, err
// }
return app.mm.RunMigrations(ctx, configurator, fromVM)
}
}

// the base purpose of this export-import is to update the store's version to the latest height.
func exportAndImportStoreAtLatestHeight(ctx sdk.Context, store *iavl.Store) error {
exporter, err := store.Export(store.LastCommitID().Version)
if err != nil {
return err
}
defer exporter.Close()

// If there is already version for the latest or latest-1 blocks height, then we don't do anything
if store.VersionExists(ctx.BlockHeight()) || store.VersionExists(ctx.BlockHeight()-1) {
ctx.Logger().Info("Version is already stored. ", "v0.2.2-store-fix")
return nil
}

importer, err := store.Import(ctx.BlockHeight())
if err != nil {
return err
}

// exporter.Next() can return nil or ExportDone as the second value
// In our case, exportDone will be nil because we know that we have at least 1 node to export, and we won't need more
exportNode, exportDone := exporter.Next()
if exportDone != nil {
ctx.Logger().Debug("ExportDone is called when there is no data to export. ", " v0.2.2-store-fix")
return nil
}

ctx.Logger().Info("Importing store at height/version ", ctx.BlockHeight(), " v0.2.2-store-fix")
err = importer.Add(exportNode)
if err != nil {
return err
}
// No need to call importer.Close() as it is called internally inside the Commit() method
err = importer.Commit()
if err != nil {
return err
}

return nil
}

0 comments on commit 9f14d69

Please sign in to comment.