Skip to content

Commit

Permalink
fix: ica handshake reopening channel - use GetAppVersion in favour …
Browse files Browse the repository at this point in the history
…of `channel.Version` (backport #2302) (#2357)

* fix: ica handshake reopening channel - use `GetAppVersion` in favour of `channel.Version` (#2302)

* adding unwrapping of channel version to ica controller handshake reopening flow

* adding changelog

* adding ics4Wrapper to ics27 host submodule, handling unwrapping channel version in OnChanOpenTry handshake cb

* updating changelog

Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com>
Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
(cherry picked from commit 9e6246f)

# Conflicts:
#	CHANGELOG.md
#	modules/apps/27-interchain-accounts/host/keeper/keeper.go

* fixing imports and interface type

Co-authored-by: Damian Nolan <damiannolan@gmail.com>
  • Loading branch information
mergify[bot] and damiannolan committed Sep 21, 2022
1 parent e4ff2c6 commit b6921cd
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -49,6 +49,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (core/ante) [\#1820](https://github.com/cosmos/ibc-go/pull/1418) `RedundancyDecorator` has been renamed to `RedundantRelayDecorator` to make the name for explicit.
* (testing) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) `MockIBCApp` has been renamed to `IBCApp` and `MockEmptyAcknowledgement` has been renamed to `EmptyAcknowledgement` to comply with go linting rules
* (apps/27-interchain-accounts) [\#2058](https://github.com/cosmos/ibc-go/pull/2058) Added `MessageRouter` interface and replaced `*baseapp.MsgServiceRouter` with it. The controller and host keepers of apps/27-interchain-accounts have been updated to use it.
* (apps/27-interchain-accounts)[\#2302](https://github.com/cosmos/ibc-go/pull/2302) Handle unwrapping of channel version in interchain accounts channel reopening handshake flow. The `host` submodule `Keeper` now requires an `ICS4Wrapper` similarly to the `controller` submodule.
* (apps/27-interchain-accounts) [\#2035](https://github.com/cosmos/ibc-go/pull/2035) Interchain accounts host and controller Keepers now expects a keeper which fulfills the expected `ScopedKeeper` interface for the capability keeper.

### State Machine Breaking
Expand Down
Expand Up @@ -70,7 +70,12 @@ func (k Keeper) OnChanOpenInit(
return "", sdkerrors.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s is already OPEN", activeChannelID, portID)
}

if !icatypes.IsPreviousMetadataEqual(channel.Version, metadata) {
appVersion, found := k.GetAppVersion(ctx, portID, activeChannelID)
if !found {
panic(fmt.Sprintf("active channel mapping set for %s, but channel does not exist in channel store", activeChannelID))
}

if !icatypes.IsPreviousMetadataEqual(appVersion, metadata) {
return "", sdkerrors.Wrap(icatypes.ErrInvalidVersion, "previous active channel metadata does not match provided version")
}
}
Expand Down
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"strings"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -37,7 +36,7 @@ type Keeper struct {
func NewKeeper(
cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace,
ics4Wrapper icatypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper,
scopedKeeper icatypes.ScopedKeeper, msgRouter *baseapp.MsgServiceRouter,
scopedKeeper icatypes.ScopedKeeper, msgRouter icatypes.MessageRouter,
) Keeper {
// set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() {
Expand Down
15 changes: 14 additions & 1 deletion modules/apps/27-interchain-accounts/host/ibc_module_test.go
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/host/types"
icatypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/types"
feetypes "github.com/cosmos/ibc-go/v5/modules/apps/29-fee/types"
clienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types"
host "github.com/cosmos/ibc-go/v5/modules/core/24-host"
Expand Down Expand Up @@ -77,7 +78,7 @@ func RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) erro

channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext())

if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion); err != nil {
if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version); err != nil {
return err
}

Expand Down Expand Up @@ -618,6 +619,18 @@ func (suite *InterchainAccountsTestSuite) fundICAWallet(ctx sdk.Context, portID
// A new channel will be opened for the controller portID. The interchain account address should remain unchanged.
func (suite *InterchainAccountsTestSuite) TestControlAccountAfterChannelClose() {
path := NewICAPath(suite.chainA, suite.chainB)

// use a fee enabled version to cover unwrapping channel version code paths
feeMetadata := feetypes.Metadata{
FeeVersion: feetypes.Version,
AppVersion: TestVersion,
}

feeICAVersion := string(feetypes.ModuleCdc.MustMarshalJSON(&feeMetadata))

path.EndpointA.ChannelConfig.Version = feeICAVersion
path.EndpointB.ChannelConfig.Version = feeICAVersion

suite.coordinator.SetupConnections(path)

err := SetupICAPath(path, TestOwnerAddress)
Expand Down
7 changes: 6 additions & 1 deletion modules/apps/27-interchain-accounts/host/keeper/handshake.go
Expand Up @@ -59,7 +59,12 @@ func (k Keeper) OnChanOpenTry(
return "", sdkerrors.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s is already OPEN", activeChannelID, portID)
}

if !icatypes.IsPreviousMetadataEqual(channel.Version, metadata) {
appVersion, found := k.GetAppVersion(ctx, portID, activeChannelID)
if !found {
panic(fmt.Sprintf("active channel mapping set for %s, but channel does not exist in channel store", activeChannelID))
}

if !icatypes.IsPreviousMetadataEqual(appVersion, metadata) {
return "", sdkerrors.Wrap(icatypes.ErrInvalidVersion, "previous active channel metadata does not match provided version")
}
}
Expand Down
12 changes: 9 additions & 3 deletions modules/apps/27-interchain-accounts/host/keeper/keeper.go
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"strings"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -24,6 +23,7 @@ type Keeper struct {
cdc codec.BinaryCodec
paramSpace paramtypes.Subspace

ics4Wrapper icatypes.ICS4Wrapper
channelKeeper icatypes.ChannelKeeper
portKeeper icatypes.PortKeeper
accountKeeper icatypes.AccountKeeper
Expand All @@ -36,8 +36,8 @@ type Keeper struct {
// NewKeeper creates a new interchain accounts host Keeper instance
func NewKeeper(
cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace,
channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper,
accountKeeper icatypes.AccountKeeper, scopedKeeper icatypes.ScopedKeeper, msgRouter *baseapp.MsgServiceRouter,
ics4Wrapper icatypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper,
accountKeeper icatypes.AccountKeeper, scopedKeeper icatypes.ScopedKeeper, msgRouter icatypes.MessageRouter,
) Keeper {
// ensure ibc interchain accounts module account is set
if addr := accountKeeper.GetModuleAddress(icatypes.ModuleName); addr == nil {
Expand All @@ -53,6 +53,7 @@ func NewKeeper(
storeKey: key,
cdc: cdc,
paramSpace: paramSpace,
ics4Wrapper: ics4Wrapper,
channelKeeper: channelKeeper,
portKeeper: portKeeper,
accountKeeper: accountKeeper,
Expand Down Expand Up @@ -90,6 +91,11 @@ func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability
return k.scopedKeeper.ClaimCapability(ctx, cap, name)
}

// GetAppVersion calls the ICS4Wrapper GetAppVersion function.
func (k Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) {
return k.ics4Wrapper.GetAppVersion(ctx, portID, channelID)
}

// GetActiveChannelID retrieves the active channelID from the store keyed by the provided connectionID and portID
func (k Keeper) GetActiveChannelID(ctx sdk.Context, connectionID, portID string) (string, bool) {
store := ctx.KVStore(k.storeKey)
Expand Down
1 change: 1 addition & 0 deletions testing/simapp/app.go
Expand Up @@ -393,6 +393,7 @@ func NewSimApp(
// ICA Host keeper
app.ICAHostKeeper = icahostkeeper.NewKeeper(
appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName),
app.IBCFeeKeeper, // use ics29 fee as ics4Wrapper in middleware stack
app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper,
app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(),
)
Expand Down

0 comments on commit b6921cd

Please sign in to comment.