From fed6a86e607aa8e0f5c7ad6cb685476f78dde87f Mon Sep 17 00:00:00 2001 From: Sean King Date: Wed, 2 Feb 2022 16:03:11 +0100 Subject: [PATCH] refactor: RegisterInterchainAccount (#814) ## Description closes: #802 --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [ ] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md). - [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#testing) - [ ] Updated relevant documentation (`docs/`) or specification (`x//spec/`) - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md` - [ ] Re-reviewed `Files changed` in the Github PR explorer - [ ] Review `Codecov Report` in the comment section below once CI passes --- .../controller/keeper/account.go | 17 ++++++++++++----- .../controller/keeper/account_test.go | 9 +++++---- .../apps/27-interchain-accounts/types/errors.go | 4 ++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account.go b/modules/apps/27-interchain-accounts/controller/keeper/account.go index aacbe751c6b..143c3a6055e 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account.go @@ -21,13 +21,20 @@ func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, connectionID, owner s return err } - if k.portKeeper.IsBound(ctx, portID) { - return sdkerrors.Wrap(icatypes.ErrPortAlreadyBound, portID) + // if there is an active channel for this portID / connectionID return an error + activeChannelID, found := k.GetOpenActiveChannel(ctx, connectionID, portID) + if found { + return sdkerrors.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s on connection %s for owner %s", activeChannelID, portID, connectionID, owner) } - cap := k.BindPort(ctx, portID) - if err := k.ClaimCapability(ctx, cap, host.PortPath(portID)); err != nil { - return sdkerrors.Wrap(err, "unable to bind to newly generated portID") + switch { + case k.portKeeper.IsBound(ctx, portID) && !k.IsBound(ctx, portID): + return sdkerrors.Wrapf(icatypes.ErrPortAlreadyBound, "another module has claimed capability for and bound port with portID: %s", portID) + case !k.portKeeper.IsBound(ctx, portID): + cap := k.BindPort(ctx, portID) + if err := k.ClaimCapability(ctx, cap, host.PortPath(portID)); err != nil { + return sdkerrors.Wrapf(err, "unable to bind to newly generated portID: %s", portID) + } } connectionEnd, err := k.channelKeeper.GetConnection(ctx, connectionID) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go index 8086726bdc2..11334c332ea 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go @@ -3,6 +3,7 @@ package keeper_test import ( icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v3/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v3/testing" ) @@ -22,9 +23,11 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { "success", func() {}, true, }, { - "port is already bound", + "port is already bound for owner but capability is claimed by another module", func() { - suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), TestPortID) + cap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), TestPortID) + err := suite.chainA.GetSimApp().TransferKeeper.ClaimCapability(suite.chainA.GetContext(), cap, host.PortPath(TestPortID)) + suite.Require().NoError(err) }, false, }, @@ -56,7 +59,6 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { false, }, } - for _, tc := range testCases { tc := tc @@ -77,7 +79,6 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { } else { suite.Require().Error(err) } - }) } } diff --git a/modules/apps/27-interchain-accounts/types/errors.go b/modules/apps/27-interchain-accounts/types/errors.go index 6ce9f2a9dea..7bb391dbe93 100644 --- a/modules/apps/27-interchain-accounts/types/errors.go +++ b/modules/apps/27-interchain-accounts/types/errors.go @@ -13,8 +13,8 @@ var ( ErrInvalidRoute = sdkerrors.Register(ModuleName, 7, "invalid route") ErrInterchainAccountNotFound = sdkerrors.Register(ModuleName, 8, "interchain account not found") ErrInterchainAccountAlreadySet = sdkerrors.Register(ModuleName, 9, "interchain account is already set") - ErrActiveChannelNotFound = sdkerrors.Register(ModuleName, 10, "no active channel for this owner") - ErrActiveChannelAlreadySet = sdkerrors.Register(ModuleName, 11, "active channel already set for this owner") + ErrActiveChannelAlreadySet = sdkerrors.Register(ModuleName, 10, "active channel already set for this owner") + ErrActiveChannelNotFound = sdkerrors.Register(ModuleName, 11, "no active channel for this owner") ErrInvalidVersion = sdkerrors.Register(ModuleName, 12, "invalid interchain accounts version") ErrInvalidAccountAddress = sdkerrors.Register(ModuleName, 13, "invalid account address") ErrUnsupported = sdkerrors.Register(ModuleName, 14, "interchain account does not support this action")