diff --git a/x/asset/keeper/migrations.go b/x/asset/keeper/migrations.go new file mode 100644 index 0000000..9b0d35b --- /dev/null +++ b/x/asset/keeper/migrations.go @@ -0,0 +1,18 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + v2 "github.com/planetmint/planetmint-go/x/asset/migrations/v2" +) + +type Migrator struct { + keeper Keeper +} + +func NewMigrator(keeper Keeper) Migrator { + return Migrator{keeper: keeper} +} + +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + return v2.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) +} diff --git a/x/asset/migrations/v2/store.go b/x/asset/migrations/v2/store.go new file mode 100644 index 0000000..2a9dac3 --- /dev/null +++ b/x/asset/migrations/v2/store.go @@ -0,0 +1,39 @@ +package v2 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/planetmint/planetmint-go/util" + "github.com/planetmint/planetmint-go/x/asset/types" +) + +func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { + store := prefix.NewStore(ctx.KVStore(storeKey), types.KeyPrefix(types.AssetKey)) + + mapping := make(map[string][][]byte) + + // read all cids + iterator := store.Iterator(nil, nil) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + addressBytes := iterator.Value() + cidBytes := iterator.Key() + + // map all cids by address + mapping[string(addressBytes)] = append(mapping[string(addressBytes)], cidBytes) + } + + // store all cids with new key + for address, cids := range mapping { + assetByAddressStore := prefix.NewStore(ctx.KVStore(storeKey), types.AddressPrefix(address)) + for i, cid := range cids { + assetByAddressStore.Set(util.SerializeUint64(uint64(i)), cid) + } + addressAssetCountStore := prefix.NewStore(ctx.KVStore(storeKey), types.KeyPrefix(types.AssetKey)) + addressAssetCountStore.Set(types.AddressCountKey(address), util.SerializeUint64(uint64(len(cids)))) + } + + return nil +} diff --git a/x/asset/module.go b/x/asset/module.go index b79e807..99a108b 100644 --- a/x/asset/module.go +++ b/x/asset/module.go @@ -116,6 +116,11 @@ func NewAppModule( func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) + + m := keeper.NewMigrator(am.keeper) + if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { + panic(fmt.Errorf("failed to register migration of %s to v2: %w", types.ModuleName, err)) + } } // RegisterInvariants registers the invariants of the module. If an invariant deviates from its predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will be halted) @@ -141,7 +146,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should be set to 1 -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { return 2 } // BeginBlock contains the logic that is automatically triggered at the beginning of each block func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {