Skip to content

Commit

Permalink
fix(x/upgrade): register missing implementation for SoftwareUpgradePr…
Browse files Browse the repository at this point in the history
…oposal (#23179)
  • Loading branch information
mmsqe authored and tac0turtle committed Jan 14, 2025
1 parent 4466ea5 commit e0251f6
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 173 deletions.
20 changes: 17 additions & 3 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,23 @@ Accounts's AccountNumber will be used as a global account number tracking replac
```go
import authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
...
err := authkeeper.MigrateAccountNumberUnsafe(ctx, &app.AuthKeeper)
if err != nil {
return nil, err
app.UpgradeKeeper.SetUpgradeHandler(planName,
func(ctx context.Context, _ upgradetypes.Plan, fromVM appmodule.VersionMap) (appmodule.VersionMap, error) {
if err := authkeeper.MigrateAccountNumberUnsafe(ctx, &app.AuthKeeper); err != nil {
return nil, err
}
return app.ModuleManager.RunMigrations(ctx, app.configurator, fromVM)
},
)
```

Add `x/accounts` store while upgrading to v0.52.x:

```go
storetypes.StoreUpgrades{
Added: []string{
accounts.StoreKey,
},
}
```

Expand Down
7 changes: 0 additions & 7 deletions simapp/v2/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/store"
"cosmossdk.io/runtime/v2"
"cosmossdk.io/x/accounts"
bankv2types "cosmossdk.io/x/bank/v2/types"
epochstypes "cosmossdk.io/x/epochs/types"
protocolpooltypes "cosmossdk.io/x/protocolpool/types"
upgradetypes "cosmossdk.io/x/upgrade/types"
)

Expand Down Expand Up @@ -37,12 +34,8 @@ func (app *SimApp[T]) RegisterUpgradeHandlers() {
if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := store.StoreUpgrades{
Added: []string{
accounts.StoreKey,
protocolpooltypes.StoreKey,
epochstypes.StoreKey,
bankv2types.ModuleName,
},
Deleted: []string{"crisis"}, // The SDK discontinued the crisis module in v0.52.0
}

app.SetStoreLoader(runtime.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
Expand Down
47 changes: 2 additions & 45 deletions store/v2/root/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ import (
"cosmossdk.io/store/v2/db"
"cosmossdk.io/store/v2/internal"
"cosmossdk.io/store/v2/metrics"
"cosmossdk.io/store/v2/migration"
"cosmossdk.io/store/v2/pruning"
"cosmossdk.io/store/v2/snapshots"
)

type (
Expand Down Expand Up @@ -115,31 +113,15 @@ func CreateRootStore(opts *FactoryOptions) (store.RootStore, error) {
}

// check if we need to migrate the store
isMigrating := false
scType := storeOpts.SCType

if scType != SCTypeIavl {
isMigrating = true // need to migrate
scType = SCTypeIavl // only support iavl v1 for migration
}
scType := storeOpts.SCType

trees := make(map[string]commitment.Tree, len(opts.StoreKeys))
for _, key := range opts.StoreKeys {
tree, err := newTreeFn(key, scType)
if err != nil {
return nil, err
}
if isMigrating {
v, err := tree.GetLatestVersion()
if err != nil {
return nil, err
}
if v == 0 && latestVersion > 0 {
if err := tree.SetInitialVersion(latestVersion + 1); err != nil {
return nil, err
}
}
}
trees[key] = tree
}
oldTrees := make(map[string]commitment.Tree, len(opts.StoreKeys))
Expand All @@ -156,31 +138,6 @@ func CreateRootStore(opts *FactoryOptions) (store.RootStore, error) {
return nil, err
}

var mm *migration.Manager
if isMigrating {
snapshotDB, err := snapshots.NewStore(fmt.Sprintf("%s/data/snapshots/store.db", opts.RootDir))
if err != nil {
return nil, err
}
snapshotMgr := snapshots.NewManager(snapshotDB, snapshots.SnapshotOptions{}, sc, nil, opts.Logger)
var newSC *commitment.CommitStore
if scType != storeOpts.SCType {
newTrees := make(map[string]commitment.Tree, len(opts.StoreKeys))
for _, key := range opts.StoreKeys {
tree, err := newTreeFn(key, storeOpts.SCType)
if err != nil {
return nil, err
}
newTrees[key] = tree
}
newSC, err = commitment.NewCommitStore(newTrees, nil, opts.SCRawDB, opts.Logger)
if err != nil {
return nil, err
}
}
mm = migration.NewManager(opts.SCRawDB, snapshotMgr, newSC, opts.Logger)
}

pm := pruning.NewManager(sc, storeOpts.SCPruningOption)
return New(opts.SCRawDB, opts.Logger, sc, pm, mm, metrics.NoOpMetrics{})
return New(opts.SCRawDB, opts.Logger, sc, pm, metrics.NoOpMetrics{})
}
1 change: 0 additions & 1 deletion store/v2/root/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ func TestFactory(t *testing.T) {
f, err = CreateRootStore(&fop)
require.NoError(t, err)
require.NotNil(t, f)
require.False(t, f.(*Store).isMigrating)
}

func setLatestVersion(db corestore.KVStoreWithBatch, version int64) error {
Expand Down
8 changes: 1 addition & 7 deletions store/v2/root/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import (
"cosmossdk.io/store/v2/commitment"
"cosmossdk.io/store/v2/commitment/iavl"
dbm "cosmossdk.io/store/v2/db"
"cosmossdk.io/store/v2/migration"
"cosmossdk.io/store/v2/pruning"
"cosmossdk.io/store/v2/snapshots"
)

var storeKeys = []string{"store1", "store2", "store3"}
Expand Down Expand Up @@ -66,14 +64,10 @@ func (s *MigrateStoreTestSuite) SetupTest() {
sc, err := commitment.NewCommitStore(multiTrees1, nil, dbm.NewMemDB(), testLog)
s.Require().NoError(err)

snapshotsStore, err := snapshots.NewStore(s.T().TempDir())
s.Require().NoError(err)
snapshotManager := snapshots.NewManager(snapshotsStore, snapshots.NewSnapshotOptions(1500, 2), orgSC, nil, testLog)
migrationManager := migration.NewManager(dbm.NewMemDB(), snapshotManager, sc, testLog)
pm := pruning.NewManager(sc, nil)

// assume no storage store, simulate the migration process
s.rootStore, err = New(dbm.NewMemDB(), testLog, orgSC, pm, migrationManager, nil)
s.rootStore, err = New(dbm.NewMemDB(), testLog, orgSC, pm, nil)
s.Require().NoError(err)
}

Expand Down
96 changes: 5 additions & 91 deletions store/v2/root/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import (
"errors"
"fmt"
"io"
"sync"
"time"

corelog "cosmossdk.io/core/log"
corestore "cosmossdk.io/core/store"
"cosmossdk.io/store/v2"
"cosmossdk.io/store/v2/metrics"
"cosmossdk.io/store/v2/migration"
"cosmossdk.io/store/v2/proof"
"cosmossdk.io/store/v2/pruning"
)
Expand Down Expand Up @@ -43,17 +41,6 @@ type Store struct {

// pruningManager reflects the pruning manager used to prune state of the SS and SC backends
pruningManager *pruning.Manager

// Migration related fields
// migrationManager reflects the migration manager used to migrate state from v1 to v2
migrationManager *migration.Manager
// chChangeset reflects the channel used to send the changeset to the migration manager
chChangeset chan *migration.VersionedChangeset
// chDone reflects the channel used to signal the migration manager that the migration
// is done
chDone chan struct{}
// isMigrating reflects whether the store is currently migrating
isMigrating bool
}

// New creates a new root Store instance.
Expand All @@ -64,17 +51,14 @@ func New(
logger corelog.Logger,
sc store.Committer,
pm *pruning.Manager,
mm *migration.Manager,
m metrics.StoreMetrics,
) (store.RootStore, error) {
return &Store{
dbCloser: dbCloser,
logger: logger,
stateCommitment: sc,
pruningManager: pm,
migrationManager: mm,
telemetry: m,
isMigrating: mm != nil,
dbCloser: dbCloser,
logger: logger,
stateCommitment: sc,
pruningManager: pm,
telemetry: m,
}, nil
}

Expand Down Expand Up @@ -233,10 +217,6 @@ func (s *Store) LoadVersionAndUpgrade(version uint64, upgrades *corestore.StoreU
defer s.telemetry.MeasureSince(time.Now(), "root_store", "load_version_and_upgrade")
}

if s.isMigrating {
return errors.New("cannot upgrade while migrating")
}

if err := s.loadVersion(version, upgrades, true); err != nil {
return err
}
Expand Down Expand Up @@ -271,11 +251,6 @@ func (s *Store) loadVersion(v uint64, upgrades *corestore.StoreUpgrades, overrid
return fmt.Errorf("failed to get commit info for version %d: %w", v, err)
}

// if we're migrating, we need to start the migration process
if s.isMigrating {
s.startMigration()
}

return nil
}

Expand All @@ -291,10 +266,6 @@ func (s *Store) Commit(cs *corestore.Changeset) ([]byte, error) {
}()
}

if err := s.handleMigration(cs); err != nil {
return nil, err
}

// signal to the pruning manager that a new version is about to be committed
// this may be required if the SS and SC backends implementation have the
// background pruning process (iavl v1 for example) which must be paused during the commit
Expand Down Expand Up @@ -325,63 +296,6 @@ func (s *Store) Commit(cs *corestore.Changeset) ([]byte, error) {
return s.lastCommitInfo.Hash(), nil
}

// startMigration starts a migration process to migrate the RootStore/v1 to the
// SS and SC backends of store/v2 and initializes the channels.
// It runs in a separate goroutine and replaces the current RootStore with the
// migrated new backends once the migration is complete.
//
// NOTE: This method should only be called once after loadVersion.
func (s *Store) startMigration() {
// buffer at most 1 changeset, if the receiver is behind attempting to buffer
// more than 1 will block.
s.chChangeset = make(chan *migration.VersionedChangeset, 1)
// it is used to signal the migration manager that the migration is done
s.chDone = make(chan struct{})

mtx := sync.Mutex{}
mtx.Lock()
go func() {
version := s.lastCommitInfo.Version
s.logger.Info("starting migration", "version", version)
mtx.Unlock()
if err := s.migrationManager.Start(uint64(version), s.chChangeset, s.chDone); err != nil {
s.logger.Error("failed to start migration", "err", err)
}
}()

// wait for the migration manager to start
mtx.Lock()
defer mtx.Unlock()
}

func (s *Store) handleMigration(cs *corestore.Changeset) error {
if s.isMigrating {
// if the migration manager has already migrated to the version, close the
// channels and replace the state commitment
if s.migrationManager.GetMigratedVersion() == uint64(s.lastCommitInfo.Version) {
close(s.chDone)
close(s.chChangeset)
s.isMigrating = false
newStateCommitment := s.migrationManager.GetStateCommitment()
if newStateCommitment != nil {
// close the old state commitment and replace it with the new one
if err := s.stateCommitment.Close(); err != nil {
return fmt.Errorf("failed to close the old SC store: %w", err)
}
s.stateCommitment = newStateCommitment
}
if err := s.migrationManager.Close(); err != nil {
return fmt.Errorf("failed to close migration manager: %w", err)
}
s.logger.Info("migration completed", "version", s.lastCommitInfo.Version)
} else {
// queue the next changeset to the migration manager
s.chChangeset <- &migration.VersionedChangeset{Version: uint64(s.lastCommitInfo.Version + 1), Changeset: cs}
}
}
return nil
}

func (s *Store) Prune(version uint64) error {
return s.pruningManager.Prune(version)
}
11 changes: 0 additions & 11 deletions store/v2/root/store_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ func newTestRootStore(sc store.Committer) *Store {
telemetry: metrics.Metrics{},
stateCommitment: sc,
pruningManager: pm,
isMigrating: false,
}
}

Expand Down Expand Up @@ -62,12 +61,6 @@ func TestQuery(t *testing.T) {
_, err = rs.Query(nil, 0, nil, true)
require.Error(t, err)

// Query with Migration

rs.isMigrating = true
sc.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte("value"), nil)
_, err = rs.Query(nil, 0, nil, false)
require.NoError(t, err)
}

func TestLoadVersion(t *testing.T) {
Expand Down Expand Up @@ -96,8 +89,4 @@ func TestLoadVersion(t *testing.T) {
err = rs.LoadVersionAndUpgrade(uint64(2), v)
require.Error(t, err)

// LoadVersionUpgrade with Migration
rs.isMigrating = true
err = rs.LoadVersionAndUpgrade(uint64(2), v)
require.Error(t, err)
}
6 changes: 3 additions & 3 deletions store/v2/root/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *RootStoreTestSuite) SetupTest() {
s.Require().NoError(err)

pm := pruning.NewManager(sc, nil)
rs, err := New(dbm.NewMemDB(), noopLog, sc, pm, nil, nil)
rs, err := New(dbm.NewMemDB(), noopLog, sc, pm, nil)
s.Require().NoError(err)

s.rootStore = rs
Expand All @@ -73,7 +73,7 @@ func (s *RootStoreTestSuite) newStoreWithPruneConfig(config *store.PruningOption

pm := pruning.NewManager(sc, config)

rs, err := New(dbm.NewMemDB(), noopLog, sc, pm, nil, nil)
rs, err := New(dbm.NewMemDB(), noopLog, sc, pm, nil)
s.Require().NoError(err)

s.rootStore = rs
Expand All @@ -82,7 +82,7 @@ func (s *RootStoreTestSuite) newStoreWithPruneConfig(config *store.PruningOption
func (s *RootStoreTestSuite) newStoreWithBackendMount(sc store.Committer, pm *pruning.Manager) {
noopLog := coretesting.NewNopLogger()

rs, err := New(dbm.NewMemDB(), noopLog, sc, pm, nil, nil)
rs, err := New(dbm.NewMemDB(), noopLog, sc, pm, nil)
s.Require().NoError(err)

s.rootStore = rs
Expand Down
4 changes: 2 additions & 2 deletions store/v2/root/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (s *UpgradeStoreTestSuite) SetupTest() {
sc, err := commitment.NewCommitStore(multiTrees, nil, s.commitDB, testLog)
s.Require().NoError(err)
pm := pruning.NewManager(sc, nil)
s.rootStore, err = New(s.commitDB, testLog, sc, pm, nil, nil)
s.rootStore, err = New(s.commitDB, testLog, sc, pm, nil)
s.Require().NoError(err)

// commit changeset
Expand Down Expand Up @@ -86,7 +86,7 @@ func (s *UpgradeStoreTestSuite) loadWithUpgrades(upgrades *corestore.StoreUpgrad
sc, err := commitment.NewCommitStore(multiTrees, oldTrees, s.commitDB, testLog)
s.Require().NoError(err)
pm := pruning.NewManager(sc, nil)
s.rootStore, err = New(s.commitDB, testLog, sc, pm, nil, nil)
s.rootStore, err = New(s.commitDB, testLog, sc, pm, nil)
s.Require().NoError(err)
}

Expand Down
2 changes: 1 addition & 1 deletion tests/systemtests/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestChainUpgrade(t *testing.T) {

const (
upgradeHeight int64 = 22
upgradeName = "v052-to-v054" // must match UpgradeName in simapp/upgrades.go
upgradeName = "v052-to-v2" // must match UpgradeName in simapp/upgrades.go
)

systest.Sut.StartChain(t, fmt.Sprintf("--comet.halt-height=%d", upgradeHeight+1))
Expand Down
Loading

0 comments on commit e0251f6

Please sign in to comment.