diff --git a/modules/apps/27-interchain-accounts/keeper/account.go b/modules/apps/27-interchain-accounts/keeper/account.go index 8fdf5383d12..98883cd0dba 100644 --- a/modules/apps/27-interchain-accounts/keeper/account.go +++ b/modules/apps/27-interchain-accounts/keeper/account.go @@ -59,25 +59,7 @@ func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, portId string) { k.accountKeeper.NewAccount(ctx, interchainAccount) k.accountKeeper.SetAccount(ctx, interchainAccount) - _ = k.SetInterchainAccountAddress(ctx, portId, interchainAccount.Address) -} - -func (k Keeper) SetInterchainAccountAddress(ctx sdk.Context, portId string, address string) string { - store := ctx.KVStore(k.storeKey) - key := types.KeyOwnerAccount(portId) - store.Set(key, []byte(address)) - return address -} - -func (k Keeper) GetInterchainAccountAddress(ctx sdk.Context, portId string) (string, error) { - store := ctx.KVStore(k.storeKey) - key := types.KeyOwnerAccount(portId) - if !store.Has(key) { - return "", sdkerrors.Wrap(types.ErrInterchainAccountNotFound, portId) - } - - interchainAccountAddr := string(store.Get(key)) - return interchainAccountAddr, nil + k.SetInterchainAccountAddress(ctx, portId, interchainAccount.Address) } func (k Keeper) GetInterchainAccount(ctx sdk.Context, addr sdk.AccAddress) (types.InterchainAccount, error) { diff --git a/modules/apps/27-interchain-accounts/keeper/grpc_query.go b/modules/apps/27-interchain-accounts/keeper/grpc_query.go index fd344e83dd5..205722addef 100644 --- a/modules/apps/27-interchain-accounts/keeper/grpc_query.go +++ b/modules/apps/27-interchain-accounts/keeper/grpc_query.go @@ -4,6 +4,7 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -23,11 +24,9 @@ func (k Keeper) InterchainAccountAddress(ctx context.Context, req *types.QueryIn return nil, status.Error(codes.InvalidArgument, "counterparty portID cannot be empty") } - sdkCtx := sdk.UnwrapSDKContext(ctx) - - interchainAccountAddress, err := k.GetInterchainAccountAddress(sdkCtx, req.CounterpartyPortId) - if err != nil { - return nil, err + interchainAccountAddress, found := k.GetInterchainAccountAddress(sdk.UnwrapSDKContext(ctx), req.CounterpartyPortId) + if !found { + return nil, status.Error(codes.NotFound, sdkerrors.Wrap(types.ErrInterchainAccountNotFound, req.CounterpartyPortId).Error()) } return &types.QueryInterchainAccountAddressResponse{InterchainAccountAddress: interchainAccountAddress}, nil diff --git a/modules/apps/27-interchain-accounts/keeper/handshake.go b/modules/apps/27-interchain-accounts/keeper/handshake.go index c226b226ba9..e4677b72188 100644 --- a/modules/apps/27-interchain-accounts/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/keeper/handshake.go @@ -110,7 +110,6 @@ func (k Keeper) OnChanOpenConfirm( portID, channelID string, ) error { - return nil } diff --git a/modules/apps/27-interchain-accounts/keeper/keeper.go b/modules/apps/27-interchain-accounts/keeper/keeper.go index cea325ae1d4..17dd769295e 100644 --- a/modules/apps/27-interchain-accounts/keeper/keeper.go +++ b/modules/apps/27-interchain-accounts/keeper/keeper.go @@ -149,3 +149,21 @@ func (k Keeper) IsActiveChannel(ctx sdk.Context, portId string) bool { func (k Keeper) AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool { return k.scopedKeeper.AuthenticateCapability(ctx, cap, name) } + +// GetInterchainAccountAddress retrieves the InterchainAccount address from the store keyed by the provided portID +func (k Keeper) GetInterchainAccountAddress(ctx sdk.Context, portID string) (string, bool) { + store := ctx.KVStore(k.storeKey) + key := types.KeyOwnerAccount(portID) + + if !store.Has(key) { + return "", false + } + + return string(store.Get(key)), true +} + +// SetInterchainAccountAddress stores the InterchainAccount address, keyed by the associated portID +func (k Keeper) SetInterchainAccountAddress(ctx sdk.Context, portID string, address string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.KeyOwnerAccount(portID), []byte(address)) +} diff --git a/modules/apps/27-interchain-accounts/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/keeper/keeper_test.go index 3e26679d10b..d3cc61c8d6a 100644 --- a/modules/apps/27-interchain-accounts/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/keeper/keeper_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "testing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/stretchr/testify/suite" "github.com/cosmos/ibc-go/modules/apps/27-interchain-accounts/types" @@ -40,6 +41,27 @@ func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { return path } +// SetupICAPath invokes the InterchainAccounts entrypoint and subsequent channel handshake handlers +func SetupICAPath(path *ibctesting.Path, owner string) error { + if err := InitInterchainAccount(path.EndpointA, owner); err != nil { + return err + } + + if err := path.EndpointB.ChanOpenTry(); err != nil { + return err + } + + if err := path.EndpointA.ChanOpenAck(); err != nil { + return err + } + + if err := path.EndpointB.ChanOpenConfirm(); err != nil { + return err + } + + return nil +} + // InitInterchainAccount is a helper function for starting the channel handshake // TODO: parse identifiers from events func InitInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { @@ -76,3 +98,32 @@ func (suite *KeeperTestSuite) TestGetPort() { port := suite.chainA.GetSimApp().ICAKeeper.GetPort(suite.chainA.GetContext()) suite.Require().Equal(types.PortID, port) } + +func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() { + suite.SetupTest() + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, "testing") + suite.Require().NoError(err) + + counterpartyPortID := path.EndpointA.ChannelConfig.PortID + expectedAddr := authtypes.NewBaseAccountWithAddress(types.GenerateAddress(counterpartyPortID)).GetAddress() + + retrievedAddr, found := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), counterpartyPortID) + suite.Require().True(found) + suite.Require().Equal(expectedAddr.String(), retrievedAddr) + + retrievedAddr, found = suite.chainA.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), "invalid port") + suite.Require().False(found) + suite.Require().Empty(retrievedAddr) +} + +func (suite *KeeperTestSuite) TestSetInterchainAccountAddress() { + expectedAddr, portID := "address", "port" + suite.chainA.GetSimApp().ICAKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), portID, expectedAddr) + + retrievedAddr, found := suite.chainA.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), portID) + suite.Require().True(found) + suite.Require().Equal(expectedAddr, retrievedAddr) +} diff --git a/modules/apps/27-interchain-accounts/keeper/relay.go b/modules/apps/27-interchain-accounts/keeper/relay.go index dad941a7ead..5aa0ddda8be 100644 --- a/modules/apps/27-interchain-accounts/keeper/relay.go +++ b/modules/apps/27-interchain-accounts/keeper/relay.go @@ -136,8 +136,8 @@ func (k Keeper) AuthenticateTx(ctx sdk.Context, msgs []sdk.Msg, portId string) e } } - interchainAccountAddr, err := k.GetInterchainAccountAddress(ctx, portId) - if err != nil { + interchainAccountAddr, found := k.GetInterchainAccountAddress(ctx, portId) + if !found { return sdkerrors.ErrUnauthorized }