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

feat(connection): migrate connection params #3650

Merged
3 changes: 1 addition & 2 deletions docs/migrations/v7-to-v8.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ TODO: https://github.com/cosmos/ibc-go/pull/3505 (extra parameter added to trans
)
```

- You should pass the `authority` to the IBC keeper. ([#3640](https://github.com/cosmos/ibc-go/pull/3640)) See [diff](https://github.com/cosmos/ibc-go/pull/3640/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08a).
- You should pass the `authority` to the IBC keeper. ([#3640](https://github.com/cosmos/ibc-go/pull/3640) and [#3650](https://github.com/cosmos/ibc-go/pull/3650)) See [diff](https://github.com/cosmos/ibc-go/pull/3640/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08a).

```diff
// app.go

// IBC Keepers

app.IBCKeeper = ibckeeper.NewKeeper(
- appCodec, keys[ibcexported.StoreKey], app.GetSubspace(ibcexported.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
+ appCodec, keys[ibcexported.StoreKey], app.GetSubspace(ibcexported.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Expand Down
33 changes: 25 additions & 8 deletions e2e/tests/core/03-connection/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"
"time"

govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
test "github.com/strangelove-ventures/interchaintest/v7/testutil"
Expand All @@ -30,6 +31,13 @@ type ConnectionTestSuite struct {

// QueryMaxExpectedTimePerBlockParam queries the on-chain max expected time per block param for 03-connection
func (s *ConnectionTestSuite) QueryMaxExpectedTimePerBlockParam(ctx context.Context, chain ibc.Chain) uint64 {
if testvalues.SelfParamsFeatureReleases.IsSupported(chain.Config().Images[0].Version) {
queryClient := s.GetChainGRCPClients(chain).ConnectionQueryClient
res, err := queryClient.ConnectionParams(ctx, &connectiontypes.QueryConnectionParamsRequest{})
s.Require().NoError(err)

return res.Params.MaxExpectedTimePerBlock
}
queryClient := s.GetChainGRCPClients(chain).ParamsQueryClient
res, err := queryClient.Params(ctx, &paramsproposaltypes.QueryParamsRequest{
Subspace: ibcexported.ModuleName,
Expand All @@ -52,6 +60,7 @@ func (s *ConnectionTestSuite) TestMaxExpectedTimePerBlockParam() {

relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions())
chainA, chainB := s.GetChains()
chainAVersion := chainA.Config().Images[0].Version

chainBDenom := chainB.Config().Denom
chainAIBCToken := testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID)
Expand All @@ -65,19 +74,27 @@ func (s *ConnectionTestSuite) TestMaxExpectedTimePerBlockParam() {
s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")

t.Run("ensure delay is set to the default of 30 seconds", func(t *testing.T) {
expectedDelay := uint64(30 * time.Second)
delay := s.QueryMaxExpectedTimePerBlockParam(ctx, chainA)
s.Require().Equal(expectedDelay, delay)
s.Require().Equal(uint64(connectiontypes.DefaultTimePerBlock), delay)
})

t.Run("change the delay to 60 seconds", func(t *testing.T) {
delay := fmt.Sprintf(`"%d"`, 1*time.Minute)
changes := []paramsproposaltypes.ParamChange{
paramsproposaltypes.NewParamChange(ibcexported.ModuleName, string(connectiontypes.KeyMaxExpectedTimePerBlock), delay),
}
delay := uint64(1 * time.Minute)
if testvalues.SelfParamsFeatureReleases.IsSupported(chainAVersion) {
authority, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chainA)
s.Require().NoError(err)
s.Require().NotNil(authority)

msg := connectiontypes.NewMsgUpdateParams(authority.String(), connectiontypes.NewParams(delay))
s.ExecuteGovProposalV1(ctx, msg, chainA, chainAWallet, 1)
} else {
changes := []paramsproposaltypes.ParamChange{
paramsproposaltypes.NewParamChange(ibcexported.ModuleName, string(connectiontypes.KeyMaxExpectedTimePerBlock), fmt.Sprintf(`"%d"`, delay)),
}

proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes)
s.ExecuteGovProposal(ctx, chainA, chainAWallet, proposal)
proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes)
s.ExecuteGovProposal(ctx, chainA, chainAWallet, proposal)
}
})

t.Run("validate the param was successfully changed", func(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions e2e/tests/transfer/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func (s *TransferTestSuite) TestSendEnabledParam() {
chainBAddress := chainBWallet.FormattedAddress()

chainAVersion := chainA.Config().Images[0].Version
isSelfManagingParams := testvalues.TransferSelfParamsFeatureReleases.IsSupported(chainAVersion)
isSelfManagingParams := testvalues.SelfParamsFeatureReleases.IsSupported(chainAVersion)

govModuleAddress, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chainA)
s.Require().NoError(err)
Expand Down Expand Up @@ -308,7 +308,7 @@ func (s *TransferTestSuite) TestReceiveEnabledParam() {
)

chainAVersion := chainA.Config().Images[0].Version
isSelfManagingParams := testvalues.TransferSelfParamsFeatureReleases.IsSupported(chainAVersion)
isSelfManagingParams := testvalues.SelfParamsFeatureReleases.IsSupported(chainAVersion)

govModuleAddress, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chainA)
s.Require().NoError(err)
Expand Down
2 changes: 1 addition & 1 deletion e2e/testvalues/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var IcadNewGenesisCommandsFeatureReleases = semverutil.FeatureReleases{
}

// TransferSelfParamsFeatureReleases represents the releases the transfer module started managing its own params.
var TransferSelfParamsFeatureReleases = semverutil.FeatureReleases{
var SelfParamsFeatureReleases = semverutil.FeatureReleases{
MajorVersion: "v8",
}

Expand Down
42 changes: 31 additions & 11 deletions modules/core/03-connection/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,24 @@ type Keeper struct {
// implements gRPC QueryServer interface
types.QueryServer

storeKey storetypes.StoreKey
paramSpace paramtypes.Subspace
cdc codec.BinaryCodec
clientKeeper types.ClientKeeper
storeKey storetypes.StoreKey
legacySubspace paramtypes.Subspace
cdc codec.BinaryCodec
clientKeeper types.ClientKeeper
}

// NewKeeper creates a new IBC connection Keeper instance
func NewKeeper(cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, ck types.ClientKeeper) Keeper {
func NewKeeper(cdc codec.BinaryCodec, key storetypes.StoreKey, legacySubspace paramtypes.Subspace, ck types.ClientKeeper) Keeper {
// set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
if !legacySubspace.HasKeyTable() {
legacySubspace = legacySubspace.WithKeyTable(types.ParamKeyTable())
}

return Keeper{
storeKey: key,
cdc: cdc,
paramSpace: paramSpace,
clientKeeper: ck,
storeKey: key,
cdc: cdc,
legacySubspace: legacySubspace,
clientKeeper: ck,
}
}

Expand Down Expand Up @@ -221,3 +221,23 @@ func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID st
k.SetClientConnectionPaths(ctx, clientID, conns)
return nil
}

// GetParams returns the total set of ibc-connection parameters.
func (k Keeper) GetParams(ctx sdk.Context) types.Params {
store := ctx.KVStore(k.storeKey)
bz := store.Get([]byte(types.ParamsKey))
if bz == nil { // only panic on unset params and not on empty params
panic("connection params are not set in store")
}

var params types.Params
k.cdc.MustUnmarshal(bz, &params)
return params
}

// SetParams sets the total set of ibc-connection parameters.
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshal(&params)
store.Set([]byte(types.ParamsKey), bz)
}
52 changes: 52 additions & 0 deletions modules/core/03-connection/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,55 @@ func (suite *KeeperTestSuite) TestLocalhostConnectionEndCreation() {
expectedCounterParty := types.NewCounterparty(exported.LocalhostClientID, exported.LocalhostConnectionID, commitmenttypes.NewMerklePrefix(connectionKeeper.GetCommitmentPrefix().Bytes()))
suite.Require().Equal(expectedCounterParty, connectionEnd.Counterparty)
}

// TestDefaultSetParams tests the default params set are what is expected
func (suite *KeeperTestSuite) TestDefaultSetParams() {
expParams := types.DefaultParams()

params := suite.chainA.App.GetIBCKeeper().ConnectionKeeper.GetParams(suite.chainA.GetContext())
suite.Require().Equal(expParams, params)
}

// TestParams tests that param setting and retrieval works properly
func (suite *KeeperTestSuite) TestSetAndGetParams() {
testCases := []struct {
name string
input types.Params
expPass bool
}{
{"success: set default params", types.DefaultParams(), true},
{"success: valid value for MaxExpectedTimePerBlock", types.NewParams(10), true},
{"failure: invalid value for MaxExpectedTimePerBlock", types.NewParams(0), false},
}

for _, tc := range testCases {
tc := tc

suite.Run(tc.name, func() {
suite.SetupTest() // reset
ctx := suite.chainA.GetContext()
err := tc.input.Validate()
suite.chainA.GetSimApp().IBCKeeper.ConnectionKeeper.SetParams(ctx, tc.input)
if tc.expPass {
suite.Require().NoError(err)
expected := tc.input
p := suite.chainA.GetSimApp().IBCKeeper.ConnectionKeeper.GetParams(ctx)
suite.Require().Equal(expected, p)
} else {
suite.Require().Error(err)
}
})
}
}

// TestUnsetParams tests that trying to get params that are not set panics.
DimitrisJim marked this conversation as resolved.
Show resolved Hide resolved
func (suite *KeeperTestSuite) TestUnsetParams() {
suite.SetupTest()
ctx := suite.chainA.GetContext()
store := ctx.KVStore(suite.chainA.GetSimApp().GetKey(exported.StoreKey))
store.Delete([]byte(types.ParamsKey))

suite.Require().Panics(func() {
suite.chainA.GetSimApp().IBCKeeper.ConnectionKeeper.GetParams(ctx)
})
}
15 changes: 15 additions & 0 deletions modules/core/03-connection/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

connectionv7 "github.com/cosmos/ibc-go/v7/modules/core/03-connection/migrations/v7"
"github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"
)

// Migrator is a struct for handling in-place store migrations.
Expand All @@ -22,3 +23,17 @@ func (m Migrator) Migrate3to4(ctx sdk.Context) error {
connectionv7.MigrateLocalhostConnection(ctx, m.keeper)
return nil
}

// MigrateParams migrates from consensus version 4 to 5.
// This migration takes the parameters that are currently stored and managed by x/params
// and stores them directly in the ibc module's state.
func (m Migrator) MigrateParams(ctx sdk.Context) error {
var params types.Params
m.keeper.legacySubspace.GetParamSet(ctx, &params)

if err := params.Validate(); err != nil {
return err
}
m.keeper.SetParams(ctx, params)
return nil
}
43 changes: 43 additions & 0 deletions modules/core/03-connection/keeper/migrations_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package keeper_test

import (
"github.com/cosmos/ibc-go/v7/modules/core/03-connection/keeper"
"github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
)

// TestMigrateParams tests that the params for the connection are properly migrated
func (suite *KeeperTestSuite) TestMigrateParams() {
testCases := []struct {
name string
malleate func()
expectedParams types.Params
}{
{
"success: default params",
func() {
params := types.DefaultParams()
subspace := suite.chainA.GetSimApp().GetSubspace(ibcexported.ModuleName)
subspace.SetParamSet(suite.chainA.GetContext(), &params) // set params
},
types.DefaultParams(),
},
}

for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
suite.SetupTest() // reset

tc.malleate()

ctx := suite.chainA.GetContext()
migrator := keeper.NewMigrator(suite.chainA.GetSimApp().IBCKeeper.ConnectionKeeper)
err := migrator.MigrateParams(ctx)
suite.Require().NoError(err)

params := suite.chainA.GetSimApp().IBCKeeper.ConnectionKeeper.GetParams(ctx)
suite.Require().Equal(tc.expectedParams, params)
})
}
}
24 changes: 0 additions & 24 deletions modules/core/03-connection/keeper/params.go

This file was deleted.

17 changes: 0 additions & 17 deletions modules/core/03-connection/keeper/params_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion modules/core/03-connection/keeper/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ func (k Keeper) VerifyNextSequenceRecv(
func (k Keeper) getBlockDelay(ctx sdk.Context, connection exported.ConnectionI) uint64 {
// expectedTimePerBlock should never be zero, however if it is then return a 0 blcok delay for safety
// as the expectedTimePerBlock parameter was not set.
expectedTimePerBlock := k.GetMaxExpectedTimePerBlock(ctx)
expectedTimePerBlock := k.GetParams(ctx).MaxExpectedTimePerBlock
if expectedTimePerBlock == 0 {
return 0
}
Expand Down
1 change: 1 addition & 0 deletions modules/core/03-connection/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
&MsgConnectionOpenTry{},
&MsgConnectionOpenAck{},
&MsgConnectionOpenConfirm{},
&MsgUpdateParams{},
)

msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
Expand Down
3 changes: 3 additions & 0 deletions modules/core/03-connection/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const (

// ConnectionPrefix is the prefix used when creating a connection identifier
ConnectionPrefix = "connection-"

// ParamsKey is the store key for the IBC connection parameters
ParamsKey = "connectionParams"
)

// FormatConnectionIdentifier returns the connection identifier with the sequence appended.
Expand Down
Loading