Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> Co-authored-by: marbar3778 <marbar3778@yahoo.com> Co-authored-by: Marko <marko@baricevic.me>
70 lines
2.2 KiB
Go
70 lines
2.2 KiB
Go
package runtime
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
appmodulev2 "cosmossdk.io/core/appmodule/v2"
|
|
)
|
|
|
|
var _ appmodulev2.MigrationRegistrar = (*migrationRegistrar)(nil)
|
|
|
|
type migrationRegistrar struct {
|
|
// migrations is a map of moduleName -> fromVersion -> migration script handler
|
|
migrations map[string]map[uint64]appmodulev2.MigrationHandler
|
|
}
|
|
|
|
// newMigrationRegistrar is constructor for registering in-place store migrations for modules.
|
|
func newMigrationRegistrar() *migrationRegistrar {
|
|
return &migrationRegistrar{
|
|
migrations: make(map[string]map[uint64]appmodulev2.MigrationHandler),
|
|
}
|
|
}
|
|
|
|
// Register registers an in-place store migration for a module.
|
|
// It permits to register modules migrations that have migrated to serverv2 but still be compatible with baseapp.
|
|
func (mr *migrationRegistrar) Register(moduleName string, fromVersion uint64, handler appmodulev2.MigrationHandler) error {
|
|
if fromVersion == 0 {
|
|
return fmt.Errorf("module migration versions should start at 1: %s", moduleName)
|
|
}
|
|
|
|
if mr.migrations[moduleName] == nil {
|
|
mr.migrations[moduleName] = map[uint64]appmodulev2.MigrationHandler{}
|
|
}
|
|
|
|
if mr.migrations[moduleName][fromVersion] != nil {
|
|
return fmt.Errorf("another migration for module %s and version %d already exists", moduleName, fromVersion)
|
|
}
|
|
|
|
mr.migrations[moduleName][fromVersion] = handler
|
|
|
|
return nil
|
|
}
|
|
|
|
// RunModuleMigrations runs all in-place store migrations for one given module from a version to another version.
|
|
func (mr *migrationRegistrar) RunModuleMigrations(ctx context.Context, moduleName string, fromVersion, toVersion uint64) error {
|
|
// No-op if toVersion is the initial version or if the version is unchanged.
|
|
if toVersion <= 1 || fromVersion == toVersion {
|
|
return nil
|
|
}
|
|
|
|
moduleMigrationsMap, found := mr.migrations[moduleName]
|
|
if !found {
|
|
return fmt.Errorf("no migrations found for module %s", moduleName)
|
|
}
|
|
|
|
// Run in-place migrations for the module sequentially until toVersion.
|
|
for i := fromVersion; i < toVersion; i++ {
|
|
migrateFn, found := moduleMigrationsMap[i]
|
|
if !found {
|
|
return fmt.Errorf("no migration found for module %s from version %d to version %d", moduleName, i, i+1)
|
|
}
|
|
|
|
if err := migrateFn(ctx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|