Skip to content

Commit dbf9ded

Browse files
committed
provider migration
1 parent 2d95e2e commit dbf9ded

File tree

5 files changed

+218
-9
lines changed

5 files changed

+218
-9
lines changed

x/ccv/consumer/keeper/migration.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import (
1111

1212
// Migrator is a struct for handling in-place store migrations.
1313
type Migrator struct {
14-
ccvConsumerParamSpace paramtypes.Subspace
1514
ccvConsumerKeeper Keeper
15+
ccvConsumerParamSpace paramtypes.Subspace
1616
}
1717

1818
// NewMigrator returns a new Migrator.
19-
func NewMigrator(ccvConsumerKeeper Keeper) Migrator {
20-
return Migrator{ccvConsumerKeeper: ccvConsumerKeeper}
19+
func NewMigrator(ccvConsumerKeeper Keeper, ccvConsumerParamSpace paramtypes.Subspace) Migrator {
20+
return Migrator{ccvConsumerKeeper: ccvConsumerKeeper, ccvConsumerParamSpace: ccvConsumerParamSpace}
2121
}
2222

2323
func (m Migrator) Migratev1p0To1p3(ctx sdk.Context) error {

x/ccv/provider/keeper/keeper.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ func NewKeeper(
8282
return k
8383
}
8484

85+
func (k *Keeper) SetParamSpace(ctx sdk.Context, ps paramtypes.Subspace) {
86+
k.paramSpace = ps
87+
}
88+
8589
// Validates that the provider keeper is initialized with non-zero and
8690
// non-nil values for all its fields. Otherwise this method will panic.
8791
func (k Keeper) mustValidateFields() {

x/ccv/provider/keeper/migration.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package keeper
2+
3+
import (
4+
"time"
5+
6+
sdk "github.com/cosmos/cosmos-sdk/types"
7+
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
8+
ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types"
9+
providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types"
10+
ccvtypes "github.com/cosmos/interchain-security/x/ccv/types"
11+
)
12+
13+
// Migrator is a struct for handling in-place store migrations.
14+
type Migrator struct {
15+
ccvProviderKeeper Keeper
16+
stakingKeeper ccvtypes.StakingKeeper
17+
ccvProviderParamSpace paramtypes.Subspace
18+
}
19+
20+
// NewMigrator returns a new Migrator.
21+
func NewMigrator(ccvProviderKeeper Keeper, stakingKeeper ccvtypes.StakingKeeper,
22+
ccvProviderParamSpace paramtypes.Subspace) Migrator {
23+
return Migrator{ccvProviderKeeper: ccvProviderKeeper, ccvProviderParamSpace: ccvProviderParamSpace}
24+
}
25+
26+
func (m Migrator) Migratev1p0To1p3(ctx sdk.Context) error {
27+
// Migrate params
28+
MigrateParamsv1p0To1p3(ctx,
29+
m.ccvProviderParamSpace,
30+
// See https://github.com/cosmos/interchain-security/blob/7861804cb311507ec6aebebbfad60ea42eb8ed4b/x/ccv/provider/keeper/params.go#L84
31+
// The v1.1.0-multiden version of ICS hardcodes this param as 10 of bond type: k.stakingKeeper.BondDenom(ctx).
32+
// Here we use the same starting value, but the param can now be changed through governance.
33+
sdk.NewCoin(m.stakingKeeper.BondDenom(ctx), sdk.NewInt(10000000)),
34+
)
35+
36+
return nil
37+
}
38+
39+
// MigrateParamsv1p0To1p3 migrates the provider CCV module params from v1.0.0 to v1.3.0,
40+
// setting default values for new params.
41+
func MigrateParamsv1p0To1p3(ctx sdk.Context, paramsSubspace paramtypes.Subspace, consumerRewardDenomRegistrationFee sdk.Coin) {
42+
// Get old params
43+
var templateClient ibctmtypes.ClientState
44+
paramsSubspace.Get(ctx, providertypes.KeyTemplateClient, &templateClient)
45+
var trustingPeriodFraction string
46+
paramsSubspace.Get(ctx, providertypes.KeyTrustingPeriodFraction, &trustingPeriodFraction)
47+
var ccvTimeoutPeriod time.Duration
48+
paramsSubspace.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &ccvTimeoutPeriod)
49+
var initTimeoutPeriod time.Duration
50+
paramsSubspace.Get(ctx, providertypes.KeyInitTimeoutPeriod, &initTimeoutPeriod)
51+
var vscTimeoutPeriod time.Duration
52+
paramsSubspace.Get(ctx, providertypes.KeyVscTimeoutPeriod, &vscTimeoutPeriod)
53+
var slashMeterReplenishPeriod time.Duration
54+
paramsSubspace.Get(ctx, providertypes.KeySlashMeterReplenishPeriod, &slashMeterReplenishPeriod)
55+
var slashMeterReplenishFraction string
56+
paramsSubspace.Get(ctx, providertypes.KeySlashMeterReplenishFraction, &slashMeterReplenishFraction)
57+
var maxThrottledPackets int64
58+
paramsSubspace.Get(ctx, providertypes.KeyMaxThrottledPackets, &maxThrottledPackets)
59+
60+
// Recycle old params, set new param to input value
61+
newParams := providertypes.NewParams(
62+
&templateClient,
63+
trustingPeriodFraction,
64+
ccvTimeoutPeriod,
65+
initTimeoutPeriod,
66+
vscTimeoutPeriod,
67+
slashMeterReplenishPeriod,
68+
slashMeterReplenishFraction,
69+
maxThrottledPackets,
70+
consumerRewardDenomRegistrationFee,
71+
)
72+
73+
// Persist new params
74+
paramsSubspace.SetParamSet(ctx, &newParams)
75+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package keeper_test
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/cosmos/cosmos-sdk/codec"
8+
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
9+
"github.com/cosmos/cosmos-sdk/store"
10+
storetypes "github.com/cosmos/cosmos-sdk/store/types"
11+
sdk "github.com/cosmos/cosmos-sdk/types"
12+
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
13+
types2 "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types"
14+
providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper"
15+
providertypes "github.com/cosmos/interchain-security/x/ccv/provider/types"
16+
ccvtypes "github.com/cosmos/interchain-security/x/ccv/types"
17+
"github.com/stretchr/testify/require"
18+
"github.com/tendermint/tendermint/libs/log"
19+
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
20+
tmdb "github.com/tendermint/tm-db"
21+
)
22+
23+
func TestMigrateParamsv1p0To1p3(t *testing.T) {
24+
// Setup raw store
25+
db := tmdb.NewMemDB()
26+
stateStore := store.NewCommitMultiStore(db)
27+
storeKey := sdk.NewKVStoreKey(paramtypes.StoreKey)
28+
memStoreKey := storetypes.NewMemoryStoreKey("mem_key")
29+
stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db)
30+
stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil)
31+
require.NoError(t, stateStore.LoadLatestVersion())
32+
registry := codectypes.NewInterfaceRegistry()
33+
cdc := codec.NewProtoCodec(registry)
34+
ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())
35+
require.NoError(t, stateStore.LoadLatestVersion())
36+
37+
// Create new empty subspace
38+
subspace := paramtypes.NewSubspace(cdc,
39+
codec.NewLegacyAmino(),
40+
storeKey,
41+
memStoreKey,
42+
paramtypes.ModuleName,
43+
)
44+
45+
// Note that new param key table is set in keeper constructor
46+
subspace = subspace.WithKeyTable(v1p0p0KeyTable())
47+
48+
// Set 8 params from v1.0.0
49+
subspace.Set(ctx, providertypes.KeyTemplateClient, providertypes.DefaultParams().TemplateClient)
50+
subspace.Set(ctx, providertypes.KeyTrustingPeriodFraction, "0.75")
51+
subspace.Set(ctx, ccvtypes.KeyCCVTimeoutPeriod, time.Hour)
52+
subspace.Set(ctx, providertypes.KeyInitTimeoutPeriod, time.Hour)
53+
subspace.Set(ctx, providertypes.KeyVscTimeoutPeriod, time.Hour)
54+
subspace.Set(ctx, providertypes.KeySlashMeterReplenishPeriod, time.Hour)
55+
subspace.Set(ctx, providertypes.KeySlashMeterReplenishFraction, "0.5")
56+
subspace.Set(ctx, providertypes.KeyMaxThrottledPackets, int64(10))
57+
58+
// Confirm new param cannot be set with old key table
59+
require.Panics(t, func() {
60+
subspace.Set(ctx, providertypes.KeyConsumerRewardDenomRegistrationFee, sdk.NewInt64Coin("uatom", 100))
61+
})
62+
63+
// Now create new subspace, mocking an upgrade where app initialization happens again
64+
subspace = paramtypes.NewSubspace(cdc,
65+
codec.NewLegacyAmino(),
66+
storeKey,
67+
memStoreKey,
68+
paramtypes.ModuleName,
69+
).WithKeyTable(providertypes.ParamKeyTable()) // Use new key table, this would be set in keeper constructor
70+
71+
// Run migration
72+
providerkeeper.MigrateParamsv1p0To1p3(ctx, subspace, sdk.NewCoin("uatom", sdk.NewInt(100000)))
73+
74+
// Use keeper to confirm params are set correctly
75+
keeper := providerkeeper.Keeper{}
76+
keeper.SetParamSpace(ctx, subspace)
77+
78+
params := keeper.GetParams(ctx)
79+
require.Equal(t, providertypes.DefaultParams().TemplateClient, params.TemplateClient)
80+
require.Equal(t, "0.75", params.TrustingPeriodFraction)
81+
require.Equal(t, time.Hour, params.CcvTimeoutPeriod)
82+
require.Equal(t, time.Hour, params.InitTimeoutPeriod)
83+
require.Equal(t, time.Hour, params.VscTimeoutPeriod)
84+
require.Equal(t, time.Hour, params.SlashMeterReplenishPeriod)
85+
require.Equal(t, "0.5", params.SlashMeterReplenishFraction)
86+
require.Equal(t, int64(10), params.MaxThrottledPackets)
87+
// New param should be set
88+
require.Equal(t, sdk.NewCoin("uatom", sdk.NewInt(100000)), params.ConsumerRewardDenomRegistrationFee)
89+
90+
// Set new params to other values
91+
params.ConsumerRewardDenomRegistrationFee = sdk.NewCoin("uatom", sdk.NewInt(1000000000))
92+
keeper.SetParams(ctx, params)
93+
require.Equal(t, sdk.NewCoin("uatom", sdk.NewInt(1000000000)), keeper.GetParams(ctx).ConsumerRewardDenomRegistrationFee)
94+
}
95+
96+
//
97+
// Note: the following methods and struct could be removed if v1.3.0 is actually defined as v2.0.0
98+
// and we bump the go.mod package name accordingly
99+
//
100+
101+
// v1p0p0Params is a copy of the ParamKeyTable method from v1.0.0
102+
func v1p0p0KeyTable() paramtypes.KeyTable {
103+
return paramtypes.NewKeyTable().RegisterParamSet(&v1p0p0Params{})
104+
}
105+
106+
// ParamSetPairs implements params.ParamSet for v1p0p0Params
107+
func (p *v1p0p0Params) ParamSetPairs() paramtypes.ParamSetPairs {
108+
return paramtypes.ParamSetPairs{
109+
paramtypes.NewParamSetPair(providertypes.KeyTemplateClient, p.TemplateClient, providertypes.ValidateTemplateClient),
110+
paramtypes.NewParamSetPair(providertypes.KeyTrustingPeriodFraction, p.TrustingPeriodFraction, ccvtypes.ValidateStringFraction),
111+
paramtypes.NewParamSetPair(ccvtypes.KeyCCVTimeoutPeriod, p.CcvTimeoutPeriod, ccvtypes.ValidateDuration),
112+
paramtypes.NewParamSetPair(providertypes.KeyInitTimeoutPeriod, p.InitTimeoutPeriod, ccvtypes.ValidateDuration),
113+
paramtypes.NewParamSetPair(providertypes.KeyVscTimeoutPeriod, p.VscTimeoutPeriod, ccvtypes.ValidateDuration),
114+
paramtypes.NewParamSetPair(providertypes.KeySlashMeterReplenishPeriod, p.SlashMeterReplenishPeriod, ccvtypes.ValidateDuration),
115+
paramtypes.NewParamSetPair(providertypes.KeySlashMeterReplenishFraction, p.SlashMeterReplenishFraction, ccvtypes.ValidateStringFraction),
116+
paramtypes.NewParamSetPair(providertypes.KeyMaxThrottledPackets, p.MaxThrottledPackets, ccvtypes.ValidatePositiveInt64),
117+
}
118+
}
119+
120+
// v1p0p0Params is a copy of the Params struct from v1.0.0
121+
type v1p0p0Params struct {
122+
TemplateClient *types2.ClientState `protobuf:"bytes,1,opt,name=template_client,json=templateClient,proto3" json:"template_client,omitempty"`
123+
TrustingPeriodFraction string `protobuf:"bytes,2,opt,name=trusting_period_fraction,json=trustingPeriodFraction,proto3" json:"trusting_period_fraction,omitempty"`
124+
CcvTimeoutPeriod time.Duration `protobuf:"bytes,3,opt,name=ccv_timeout_period,json=ccvTimeoutPeriod,proto3,stdduration" json:"ccv_timeout_period"`
125+
InitTimeoutPeriod time.Duration `protobuf:"bytes,4,opt,name=init_timeout_period,json=initTimeoutPeriod,proto3,stdduration" json:"init_timeout_period"`
126+
VscTimeoutPeriod time.Duration `protobuf:"bytes,5,opt,name=vsc_timeout_period,json=vscTimeoutPeriod,proto3,stdduration" json:"vsc_timeout_period"`
127+
SlashMeterReplenishPeriod time.Duration `protobuf:"bytes,6,opt,name=slash_meter_replenish_period,json=slashMeterReplenishPeriod,proto3,stdduration" json:"slash_meter_replenish_period"`
128+
SlashMeterReplenishFraction string `protobuf:"bytes,7,opt,name=slash_meter_replenish_fraction,json=slashMeterReplenishFraction,proto3" json:"slash_meter_replenish_fraction,omitempty"`
129+
MaxThrottledPackets int64 `protobuf:"varint,8,opt,name=max_throttled_packets,json=maxThrottledPackets,proto3" json:"max_throttled_packets,omitempty"`
130+
}

x/ccv/provider/types/params.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (p Params) Validate() error {
121121
if p.TemplateClient == nil {
122122
return fmt.Errorf("template client is nil")
123123
}
124-
if err := validateTemplateClient(*p.TemplateClient); err != nil {
124+
if err := ValidateTemplateClient(*p.TemplateClient); err != nil {
125125
return err
126126
}
127127
if err := ccvtypes.ValidateStringFraction(p.TrustingPeriodFraction); err != nil {
@@ -145,7 +145,7 @@ func (p Params) Validate() error {
145145
if err := ccvtypes.ValidatePositiveInt64(p.MaxThrottledPackets); err != nil {
146146
return fmt.Errorf("max throttled packets is invalid: %s", err)
147147
}
148-
if err := validateCoin(p.ConsumerRewardDenomRegistrationFee); err != nil {
148+
if err := ValidateCoin(p.ConsumerRewardDenomRegistrationFee); err != nil {
149149
return fmt.Errorf("consumer reward denom registration fee is invalid: %s", err)
150150
}
151151
return nil
@@ -154,19 +154,19 @@ func (p Params) Validate() error {
154154
// ParamSetPairs implements params.ParamSet
155155
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
156156
return paramtypes.ParamSetPairs{
157-
paramtypes.NewParamSetPair(KeyTemplateClient, p.TemplateClient, validateTemplateClient),
157+
paramtypes.NewParamSetPair(KeyTemplateClient, p.TemplateClient, ValidateTemplateClient),
158158
paramtypes.NewParamSetPair(KeyTrustingPeriodFraction, p.TrustingPeriodFraction, ccvtypes.ValidateStringFraction),
159159
paramtypes.NewParamSetPair(ccvtypes.KeyCCVTimeoutPeriod, p.CcvTimeoutPeriod, ccvtypes.ValidateDuration),
160160
paramtypes.NewParamSetPair(KeyInitTimeoutPeriod, p.InitTimeoutPeriod, ccvtypes.ValidateDuration),
161161
paramtypes.NewParamSetPair(KeyVscTimeoutPeriod, p.VscTimeoutPeriod, ccvtypes.ValidateDuration),
162162
paramtypes.NewParamSetPair(KeySlashMeterReplenishPeriod, p.SlashMeterReplenishPeriod, ccvtypes.ValidateDuration),
163163
paramtypes.NewParamSetPair(KeySlashMeterReplenishFraction, p.SlashMeterReplenishFraction, ccvtypes.ValidateStringFraction),
164164
paramtypes.NewParamSetPair(KeyMaxThrottledPackets, p.MaxThrottledPackets, ccvtypes.ValidatePositiveInt64),
165-
paramtypes.NewParamSetPair(KeyConsumerRewardDenomRegistrationFee, p.ConsumerRewardDenomRegistrationFee, validateCoin),
165+
paramtypes.NewParamSetPair(KeyConsumerRewardDenomRegistrationFee, p.ConsumerRewardDenomRegistrationFee, ValidateCoin),
166166
}
167167
}
168168

169-
func validateTemplateClient(i interface{}) error {
169+
func ValidateTemplateClient(i interface{}) error {
170170
cs, ok := i.(ibctmtypes.ClientState)
171171
if !ok {
172172
return fmt.Errorf("invalid parameter type: %T, expected: %T", i, ibctmtypes.ClientState{})
@@ -193,7 +193,7 @@ func validateTemplateClient(i interface{}) error {
193193
return nil
194194
}
195195

196-
func validateCoin(i interface{}) error {
196+
func ValidateCoin(i interface{}) error {
197197
v, ok := i.(sdk.Coin)
198198
if !ok {
199199
return fmt.Errorf("invalid parameter type: %T", i)

0 commit comments

Comments
 (0)