Skip to content
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

chore: add consumer and provider migrations for ICS v5 #1817

Merged
merged 4 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions x/ccv/consumer/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

v2 "github.com/cosmos/interchain-security/v5/x/ccv/consumer/migrations/v2"
v3 "github.com/cosmos/interchain-security/v5/x/ccv/consumer/migrations/v3"
)

// Migrator is a struct for handling in-place store migrations.
Expand All @@ -24,8 +25,10 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error {
return v2.MigrateConsumerPacketData(ctx, store)
}

// Migrate2to3 migrates x/ccvconsumer state from consensus version 2 to 3.
// Migrate2to3 migrates x/ccvconsumer from consensus version 2 to 3.
// This migration is necessary to move the consumer module legacy params.
func (m Migrator) Migrate2to3(ctx sdk.Context) error {
store := ctx.KVStore(m.keeper.storeKey)
return v2.MigrateConsumerPacketData(ctx, store)
cdc := m.keeper.cdc
return v3.MigrateLegacyParams(ctx, cdc, store, m.paramSpace)
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package keeper
package v3

import (
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types"
)

// Legacy: used for migration only!
// GetConsumerParamsLegacy returns the params for the consumer ccv module from x/param subspace
// which will be deprecated soon
func GetConsumerParamsLegacy(ctx sdk.Context, keeper Keeper, paramSpace paramtypes.Subspace) ccvtypes.ConsumerParams {
// GetConsumerParamsLegacy returns the params for the consumer ccv module from legacy subspace
func GetConsumerParamsLegacy(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) ccvtypes.ConsumerParams {
return ccvtypes.NewParams(
getEnabled(ctx, paramSpace),
getBlocksPerDistributionTransmission(ctx, paramSpace),
Expand All @@ -31,39 +29,39 @@ func GetConsumerParamsLegacy(ctx sdk.Context, keeper Keeper, paramSpace paramtyp
}

// getEnabled returns the enabled flag for the consumer module
func getEnabled(ctx sdk.Context, paramStore paramtypes.Subspace) bool {
func getEnabled(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) bool {
var enabled bool
paramStore.Get(ctx, ccvtypes.KeyEnabled, &enabled)
return enabled
}

func getBlocksPerDistributionTransmission(ctx sdk.Context, paramStore paramtypes.Subspace) int64 {
func getBlocksPerDistributionTransmission(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) int64 {
var bpdt int64
paramStore.Get(ctx, ccvtypes.KeyBlocksPerDistributionTransmission, &bpdt)
return bpdt
}

func getDistributionTransmissionChannel(ctx sdk.Context, paramStore paramtypes.Subspace) string {
func getDistributionTransmissionChannel(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string {
var s string
paramStore.Get(ctx, ccvtypes.KeyDistributionTransmissionChannel, &s)
return s
}

func getProviderFeePoolAddrStr(ctx sdk.Context, paramStore paramtypes.Subspace) string {
func getProviderFeePoolAddrStr(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string {
var s string
paramStore.Get(ctx, ccvtypes.KeyProviderFeePoolAddrStr, &s)
return s
}

// getCCVTimeoutPeriod returns the timeout period for sent ccv related ibc packets
func getCCVTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration {
func getCCVTimeoutPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration {
var p time.Duration
paramStore.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &p)
return p
}

// getTransferTimeoutPeriod returns the timeout period for sent transfer related ibc packets
func getTransferTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration {
func getTransferTimeoutPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration {
var p time.Duration
paramStore.Get(ctx, ccvtypes.KeyTransferTimeoutPeriod, &p)
return p
Expand All @@ -72,46 +70,46 @@ func getTransferTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) t
// getConsumerRedistributionFrac returns the fraction of tokens allocated to the consumer redistribution
// address during distribution events. The fraction is a string representing a
// decimal number. For example "0.75" would represent 75%.
func getConsumerRedistributionFrac(ctx sdk.Context, paramStore paramtypes.Subspace) string {
func getConsumerRedistributionFrac(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string {
var str string
paramStore.Get(ctx, ccvtypes.KeyConsumerRedistributionFrac, &str)
return str
}

// getHistoricalEntries returns the number of historical info entries to persist in store
func getHistoricalEntries(ctx sdk.Context, paramStore paramtypes.Subspace) int64 {
func getHistoricalEntries(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) int64 {
var n int64
paramStore.Get(ctx, ccvtypes.KeyHistoricalEntries, &n)
return n
}

func getUnbondingPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration {
func getUnbondingPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration {
var period time.Duration
paramStore.Get(ctx, ccvtypes.KeyConsumerUnbondingPeriod, &period)
return period
}

// getSoftOptOutThreshold returns the percentage of validators at the bottom of the set
// that can opt out of running the consumer chain
func getSoftOptOutThreshold(ctx sdk.Context, paramStore paramtypes.Subspace) string {
func getSoftOptOutThreshold(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string {
var str string
paramStore.Get(ctx, ccvtypes.KeySoftOptOutThreshold, &str)
return str
}

func getRewardDenoms(ctx sdk.Context, paramStore paramtypes.Subspace) []string {
func getRewardDenoms(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) []string {
var denoms []string
paramStore.Get(ctx, ccvtypes.KeyRewardDenoms, &denoms)
return denoms
}

func getProviderRewardDenoms(ctx sdk.Context, paramStore paramtypes.Subspace) []string {
func getProviderRewardDenoms(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) []string {
var denoms []string
paramStore.Get(ctx, ccvtypes.KeyProviderRewardDenoms, &denoms)
return denoms
}

func getRetryDelayPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration {
func getRetryDelayPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration {
var period time.Duration
paramStore.Get(ctx, ccvtypes.KeyRetryDelayPeriod, &period)
return period
Expand Down
19 changes: 12 additions & 7 deletions x/ccv/consumer/migrations/v3/migration.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
package v3

import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
storetypes "cosmossdk.io/store/types"

consumerKeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper"
consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types"
ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types"
)

// MigrateParams migrates the consumers module's parameters from the x/params subspace to the
// MigrateLegacyParams migrates the consumers module's parameters from the x/params subspace to the
// consumer modules store.
func MigrateParams(ctx sdk.Context, keeper consumerKeeper.Keeper, legacyParamspace paramtypes.Subspace) error {
params := consumerKeeper.GetConsumerParamsLegacy(ctx, keeper, legacyParamspace)
func MigrateLegacyParams(ctx sdk.Context, cdc codec.BinaryCodec, store storetypes.KVStore, legacyParamspace ccvtypes.LegacyParamSubspace) error {
ctx.Logger().Info("starting consumer legacy params migration")
params := GetConsumerParamsLegacy(ctx, legacyParamspace)
err := params.Validate()
if err != nil {
return err
}
keeper.SetParams(ctx, params)
keeper.Logger(ctx).Info("successfully migrated provider parameters")

bz := cdc.MustMarshal(&params)
store.Set(consumertypes.ParametersKey(), bz)
ctx.Logger().Info("successfully migrated consumer parameters")
return nil
}
95 changes: 95 additions & 0 deletions x/ccv/consumer/migrations/v3/migration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package v3

import (
"fmt"
"testing"
"time"

storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/interchain-security/v5/app/encoding"
consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types"
ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types"

"github.com/stretchr/testify/require"
)

type testLegacyParamSubspace struct {
*ccvtypes.ConsumerParams
}

func newTestLegacyParamsSubspace(p ccvtypes.ConsumerParams) testLegacyParamSubspace {
return testLegacyParamSubspace{
&p,
}
}

func (ps testLegacyParamSubspace) Get(ctx sdk.Context, key []byte, ptr interface{}) {
switch string(key) {
case string(ccvtypes.KeyEnabled):
*ptr.(*bool) = ps.Enabled
case string(ccvtypes.KeyBlocksPerDistributionTransmission):
*ptr.(*int64) = ps.BlocksPerDistributionTransmission
case string(ccvtypes.KeyDistributionTransmissionChannel):
*ptr.(*string) = ps.DistributionTransmissionChannel
case string(ccvtypes.KeyProviderFeePoolAddrStr):
*ptr.(*string) = ps.ProviderFeePoolAddrStr
case string(ccvtypes.KeyCCVTimeoutPeriod):
*ptr.(*time.Duration) = ps.CcvTimeoutPeriod
case string(ccvtypes.KeyTransferTimeoutPeriod):
*ptr.(*time.Duration) = ps.TransferTimeoutPeriod
case string(ccvtypes.KeyConsumerRedistributionFrac):
*ptr.(*string) = ps.ConsumerRedistributionFraction
case string(ccvtypes.KeyHistoricalEntries):
*ptr.(*int64) = ps.HistoricalEntries
case string(ccvtypes.KeyConsumerUnbondingPeriod):
*ptr.(*time.Duration) = ps.UnbondingPeriod
case string(ccvtypes.KeySoftOptOutThreshold):
*ptr.(*string) = ps.SoftOptOutThreshold
case string(ccvtypes.KeyRewardDenoms):
*ptr.(*[]string) = ps.RewardDenoms
case string(ccvtypes.KeyProviderRewardDenoms):
*ptr.(*[]string) = ps.ProviderRewardDenoms
case string(ccvtypes.KeyRetryDelayPeriod):
*ptr.(*time.Duration) = ps.RetryDelayPeriod
default:
panic(fmt.Sprintf("invalid paramspace key: %s", string(key)))

}
}

func TestMigrateParams(t *testing.T) {
cdc := encoding.MakeTestEncodingConfig().Codec
storeKey := storetypes.NewKVStoreKey("ccvconsumer")
ctx := testutil.DefaultContext(storeKey, storetypes.NewTransientStoreKey("transient_test"))
store := ctx.KVStore(storeKey)

defaultParams := ccvtypes.DefaultParams()
legacyParamSubspace := newTestLegacyParamsSubspace(defaultParams)
// confirms that testLegacyParamSubspace works as expected
require.NotPanics(t, func() {
GetConsumerParamsLegacy(ctx, legacyParamSubspace)
})

emptyParams := ccvtypes.ConsumerParams{}
bz := store.Get(consumertypes.ParametersKey())
require.NoError(t, cdc.Unmarshal(bz, &emptyParams))
require.NotNil(t, emptyParams)
require.Empty(t, emptyParams)
require.NotEqual(t, defaultParams, emptyParams)

err := MigrateLegacyParams(ctx, cdc, store, legacyParamSubspace)
require.NoError(t, err)

// check that new params are available after migration and equal to defaults
// legacyParamSubspace was set to match defaultParams
migratedParams := ccvtypes.ConsumerParams{}
paramsBz := store.Get(consumertypes.ParametersKey())
require.NotEqual(t, bz, paramsBz)
require.NoError(t, cdc.Unmarshal(paramsBz, &migratedParams))

require.Equal(t, defaultParams, migratedParams)
require.NotEqual(t, emptyParams, migratedParams)
}
5 changes: 4 additions & 1 deletion x/ccv/consumer/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
if err := cfg.RegisterMigration(consumertypes.ModuleName, 1, m.Migrate1to2); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove as v3.0.0 and v3.1.0 have consensus version 1 and they are both deprecated. The consumer module on >= v3.2.0 has consensus version 2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's leave the migrations as they are written now.

Removing the migrations would make it difficult to figure out what was happening and when. Having all migrations in front of you makes it somewhat easier.

This is from experience we got during provider v2 -> v3 migration which was a mess and some previously registered migrations were just deleted. Due to the deletion previous code versions needed to be cross-checked to make sure we're not dropping something.

panic(fmt.Sprintf("failed to register migrator for %s: %s", consumertypes.ModuleName, err))
}
if err := cfg.RegisterMigration(consumertypes.ModuleName, 2, m.Migrate2to3); err != nil {
panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 2 -> 3", consumertypes.ModuleName, err))
}
}

// InitGenesis performs genesis initialization for the consumer module. It returns
Expand All @@ -146,7 +149,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw

// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 {
return 2
return 3
}

// BeginBlock implements the AppModule interface
Expand Down
4 changes: 4 additions & 0 deletions x/ccv/provider/migrations/migrator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package migrations

import (
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
sdktypes "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

Expand All @@ -14,6 +16,8 @@ import (
type Migrator struct {
providerKeeper providerkeeper.Keeper
paramSpace paramtypes.Subspace
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
}

// NewMigrator returns a new Migrator.
Expand Down
Loading
Loading