Skip to content

Commit

Permalink
chore: add consumer and provider migrations for ICS v5 (#1817)
Browse files Browse the repository at this point in the history
* chore: add consumer migration 2 -> 3

* chore: add provider migration; update params

* fix: resolve review nits
  • Loading branch information
MSalopek authored Apr 25, 2024
1 parent 7cd900a commit 728a1e5
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 49 deletions.
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 {
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

0 comments on commit 728a1e5

Please sign in to comment.