From 4440d43c29be3eca035a60d1e84bfcde56989850 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Thu, 30 May 2024 21:32:47 +0200 Subject: [PATCH 1/9] imp: use UNORDERED as default ordering for new ICA channels --- CHANGELOG.md | 3 ++- .../02-interchain-accounts/09-active-channels.md | 2 +- .../10-legacy/03-keeper-api.md | 6 +++--- docs/docs/05-migrations/13-v8-to-v9.md | 11 +++++++++++ .../controller/client/cli/tx.go | 2 +- .../controller/ibc_middleware_test.go | 2 +- .../controller/keeper/account.go | 9 +++++++-- .../controller/keeper/account_test.go | 6 +++--- .../controller/keeper/keeper_test.go | 2 +- .../controller/keeper/msg_server.go | 11 ++++++++++- .../controller/keeper/msg_server_test.go | 16 ++++++++++++++++ .../controller/migrations/v6/migrations_test.go | 4 ++-- .../host/ibc_module_test.go | 2 +- .../host/keeper/keeper_test.go | 2 +- modules/apps/29-fee/ica_test.go | 2 +- 15 files changed, 61 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c14dcab09a5..f414e1cd8b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,7 +54,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (core) [\#6138](https://github.com/cosmos/ibc-go/pull/6138) Remove `Router` reference from IBC core keeper and use instead the router on the existing `PortKeeper` reference. * (core/04-channel) [\#6023](https://github.com/cosmos/ibc-go/pull/6023) Remove emission of non-hexlified event attributes `packet_data` and `packet_ack`. * (core) [\#6320](https://github.com/cosmos/ibc-go/pull/6320) Remove unnecessary `Proof` interface from `exported` package. -* (core/05-port) [\#6341](https://github.com/cosmos/ibc-go/pull/6341) Modify `UnmarshalPacketData` interface to take in the context, portID, and channelID. This allows for packet data's to be unmarshaled based on the channel version. +* (core/05-port) [\#6341](https://github.com/cosmos/ibc-go/pull/6341) Modify `UnmarshalPacketData` interface to take in the context, portID, and channelID. This allows for packet data's to be unmarshaled based on the channel version. +* (apps/27-interchain-accounts) [\#6433](https://github.com/cosmos/ibc-go/pull/6433) Use UNORDERED as the default ordering for new ICA channels. ### State Machine Breaking diff --git a/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md b/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md index 09ae7063a68..8d1a2321e57 100644 --- a/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md +++ b/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md @@ -11,7 +11,7 @@ The Interchain Accounts module uses either [ORDERED or UNORDERED](https://github When using `ORDERED` channels, the order of transactions when sending packets from a controller to a host chain is maintained. -When using `UNORDERED` channels, there is no guarantee that the order of transactions when sending packets from the controller to the host chain is maintained. +When using `UNORDERED` channels, there is no guarantee that the order of transactions when sending packets from the controller to the host chain is maintained.If no ordering is specified in `MsgRegisterInterchainAccount`, then the default ordering for new ICA channels is `UNORDERED`. > A limitation when using ORDERED channels is that when a packet times out the channel will be closed. diff --git a/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md b/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md index 252c7eaf7ff..127574f7069 100644 --- a/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md +++ b/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md @@ -19,7 +19,7 @@ The controller submodule keeper exposes two legacy functions that allow respecti The authentication module can begin registering interchain accounts by calling `RegisterInterchainAccount`: ```go -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID, owner.String(), version); err != nil { +if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID, owner.String(), version, channeltypes.UNORDERED); err != nil { return err } @@ -44,7 +44,7 @@ if err != nil { return err } -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(appVersion)); err != nil { +if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(appVersion), channeltypes.UNORDERED); err != nil { return err } ``` @@ -75,7 +75,7 @@ if err != nil { return err } -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(feeEnabledVersion)); err != nil { +if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(feeEnabledVersion), channeltypes.UNORDERED); err != nil { return err } ``` diff --git a/docs/docs/05-migrations/13-v8-to-v9.md b/docs/docs/05-migrations/13-v8-to-v9.md index bd67a09515d..1d3d165a133 100644 --- a/docs/docs/05-migrations/13-v8-to-v9.md +++ b/docs/docs/05-migrations/13-v8-to-v9.md @@ -84,6 +84,17 @@ func NewKeeper( ) Keeper ``` +The legacy function `RegisterInterchainAccount` takes now an extra parameter to specify the ordering of new ICA channels: + +```diff +func (k Keeper) RegisterInterchainAccount( + ctx sdk.Context, + connectionID, owner, + version string, ++ ordering channeltypes.Order +) error { +``` + ## Relayers - Renaming of event attribute keys in [#5603](https://github.com/cosmos/ibc-go/pull/5603). diff --git a/modules/apps/27-interchain-accounts/controller/client/cli/tx.go b/modules/apps/27-interchain-accounts/controller/client/cli/tx.go index 128e990d52d..6b938eaf10b 100644 --- a/modules/apps/27-interchain-accounts/controller/client/cli/tx.go +++ b/modules/apps/27-interchain-accounts/controller/client/cli/tx.go @@ -71,7 +71,7 @@ the associated capability.`), } cmd.Flags().String(flagVersion, "", "Controller chain channel version") - cmd.Flags().String(flagOrdering, channeltypes.ORDERED.String(), fmt.Sprintf("Channel ordering, can be one of: %s", strings.Join(connectiontypes.SupportedOrderings, ", "))) + cmd.Flags().String(flagOrdering, channeltypes.UNORDERED.String(), fmt.Sprintf("Channel ordering, can be one of: %s", strings.Join(connectiontypes.SupportedOrderings, ", "))) flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go b/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go index e9ab95cc1b9..e2af8caf3c8 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go @@ -78,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, TestVersion, channeltypes.ORDERED); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account.go b/modules/apps/27-interchain-accounts/controller/keeper/account.go index a494bb29a50..cb08bb44e19 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account.go @@ -29,7 +29,7 @@ import ( // Prior to v6.x.x of ibc-go, the controller module was only functional as middleware, with authentication performed // by the underlying application. For a full summary of the changes in v6.x.x, please see ADR009. // This API will be removed in later releases. -func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, connectionID, owner, version string) error { +func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, connectionID, owner, version string, ordering channeltypes.Order) error { portID, err := icatypes.NewControllerPortID(owner) if err != nil { return err @@ -41,7 +41,12 @@ func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, connectionID, owner, k.SetMiddlewareEnabled(ctx, portID, connectionID) - _, err = k.registerInterchainAccount(ctx, connectionID, portID, version, channeltypes.ORDERED) + // use ORDER_UNORDERED as default in case ordering is NONE + if ordering == channeltypes.NONE { + ordering = channeltypes.UNORDERED + } + + _, err = k.registerInterchainAccount(ctx, connectionID, portID, version, ordering) if err != nil { return err } 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 c462de350f6..cc4a28062f0 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { tc.malleate() // malleate mutates test data - err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), path.EndpointA.ConnectionID, owner, TestVersion) + err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), path.EndpointA.ConnectionID, owner, TestVersion, channeltypes.ORDERED) if tc.expPass { suite.Require().NoError(err) @@ -103,7 +103,7 @@ func (suite *KeeperTestSuite) TestRegisterSameOwnerMultipleConnections() { TxType: icatypes.TxTypeSDKMultiMsg, } - err := suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToB.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata))) + err := suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToB.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata)), channeltypes.ORDERED) suite.Require().NoError(err) // build ICS27 metadata with connection identifiers for path A->C @@ -115,6 +115,6 @@ func (suite *KeeperTestSuite) TestRegisterSameOwnerMultipleConnections() { TxType: icatypes.TxTypeSDKMultiMsg, } - err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToC.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata))) + err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToC.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata)), channeltypes.ORDERED) suite.Require().NoError(err) } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go index b733adff9ca..00af5616148 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go @@ -90,7 +90,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, TestVersion, channeltypes.ORDERED); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go b/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go index 66ad2afd0a9..27434730132 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" ) @@ -39,7 +40,15 @@ func (s msgServer) RegisterInterchainAccount(goCtx context.Context, msg *types.M s.SetMiddlewareDisabled(ctx, portID, msg.ConnectionId) - channelID, err := s.registerInterchainAccount(ctx, msg.ConnectionId, portID, msg.Version, msg.Ordering) + // use ORDER_UNORDERED as default in case msg's ordering is NONE + var order channeltypes.Order + if msg.Ordering == channeltypes.NONE { + order = channeltypes.UNORDERED + } else { + order = msg.Ordering + } + + channelID, err := s.registerInterchainAccount(ctx, msg.ConnectionId, portID, msg.Version, order) if err != nil { s.Logger(ctx).Error("error registering interchain account", "error", err.Error()) return nil, err diff --git a/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go b/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go index 625c0441859..71899dacf53 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go @@ -21,6 +21,7 @@ import ( func (suite *KeeperTestSuite) TestRegisterInterchainAccount_MsgServer() { var ( msg *types.MsgRegisterInterchainAccount + expectedOrderding channeltypes.Order expectedChannelID = "channel-0" ) @@ -34,6 +35,14 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount_MsgServer() { true, func() {}, }, + { + "success: ordering falls back to UNORDERED if not specified", + true, + func() { + msg.Ordering = channeltypes.NONE + expectedOrderding = channeltypes.UNORDERED + }, + }, { "invalid connection id", false, @@ -70,6 +79,8 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount_MsgServer() { tc := tc suite.Run(tc.name, func() { + expectedOrderding = channeltypes.ORDERED + suite.SetupTest() path := NewICAPath(suite.chainA, suite.chainB) @@ -92,6 +103,11 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount_MsgServer() { suite.Require().Len(events, 2) suite.Require().Equal(events[0].Type, channeltypes.EventTypeChannelOpenInit) suite.Require().Equal(events[1].Type, sdk.EventTypeMessage) + + path.EndpointA.ChannelConfig.PortID = res.PortId + path.EndpointA.ChannelID = res.ChannelId + channel := path.EndpointA.GetChannel() + suite.Require().Equal(expectedOrderding, channel.Ordering) } else { suite.Require().Error(err) suite.Require().Nil(res) diff --git a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go index 3c88c512d3d..1e9fcde0f81 100644 --- a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go +++ b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/migrations/v6" + v6 "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/migrations/v6" "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" @@ -68,7 +68,7 @@ func (*MigrationsTestSuite) RegisterInterchainAccount(endpoint *ibctesting.Endpo channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/host/ibc_module_test.go b/modules/apps/27-interchain-accounts/host/ibc_module_test.go index 9ffb67a8f4d..7279f680438 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module_test.go @@ -83,7 +83,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, endpoint.ChannelConfig.Version); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go index acbc274ef2f..cde36a00966 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go @@ -112,7 +112,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, endpoint.ChannelConfig.Version); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { return err } diff --git a/modules/apps/29-fee/ica_test.go b/modules/apps/29-fee/ica_test.go index ed121ae6e44..b7c43048593 100644 --- a/modules/apps/29-fee/ica_test.go +++ b/modules/apps/29-fee/ica_test.go @@ -75,7 +75,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, endpoint.ChannelConfig.Version); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { return err } From 6cd5267c1fcdb081616c29d23e0066e029354c0a Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Thu, 30 May 2024 21:40:08 +0200 Subject: [PATCH 2/9] Update migrations_test.go --- .../controller/migrations/v6/migrations_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go index 1e9fcde0f81..d63b69ec110 100644 --- a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go +++ b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - v6 "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/migrations/v6" + "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/migrations/v6" "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" From 0214746ddfd6604f46bd03b7efb68dae7e3fa3c0 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Fri, 31 May 2024 09:07:50 +0200 Subject: [PATCH 3/9] Update 09-active-channels.md --- docs/docs/02-apps/02-interchain-accounts/09-active-channels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md b/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md index 8d1a2321e57..0845c20ebe6 100644 --- a/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md +++ b/docs/docs/02-apps/02-interchain-accounts/09-active-channels.md @@ -11,7 +11,7 @@ The Interchain Accounts module uses either [ORDERED or UNORDERED](https://github When using `ORDERED` channels, the order of transactions when sending packets from a controller to a host chain is maintained. -When using `UNORDERED` channels, there is no guarantee that the order of transactions when sending packets from the controller to the host chain is maintained.If no ordering is specified in `MsgRegisterInterchainAccount`, then the default ordering for new ICA channels is `UNORDERED`. +When using `UNORDERED` channels, there is no guarantee that the order of transactions when sending packets from the controller to the host chain is maintained. If no ordering is specified in `MsgRegisterInterchainAccount`, then the default ordering for new ICA channels is `UNORDERED`. > A limitation when using ORDERED channels is that when a packet times out the channel will be closed. From 62dd2676378b444e8a74403faebcd24bd6a03b12 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Fri, 31 May 2024 09:28:42 +0200 Subject: [PATCH 4/9] update docs --- .../02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md b/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md index 127574f7069..120bdcd6365 100644 --- a/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md +++ b/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md @@ -26,7 +26,7 @@ if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID return nil ``` -The `version` argument is used to support ICS-29 fee middleware for relayer incentivization of ICS-27 packets. Consumers of the `RegisterInterchainAccount` are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. +The `version` argument is used to support ICS-29 fee middleware for relayer incentivization of ICS-27 packets. The `ordering` argument allows to specify the ordering of the channel that is created; if `NONE` is passed, then the default ordering will be `UNORDERED`. Consumers of the `RegisterInterchainAccount` are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. The following code snippet illustrates how to construct an appropriate interchain accounts `Metadata` and encode it as a JSON bytestring: From 5a7d723a8153c4dcfec7261338fe3428bb9b9776 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Tue, 4 Jun 2024 21:42:23 +0200 Subject: [PATCH 5/9] Update docs/docs/05-migrations/13-v8-to-v9.md Co-authored-by: Damian Nolan --- docs/docs/05-migrations/13-v8-to-v9.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/05-migrations/13-v8-to-v9.md b/docs/docs/05-migrations/13-v8-to-v9.md index 1d3d165a133..ebeb98b477b 100644 --- a/docs/docs/05-migrations/13-v8-to-v9.md +++ b/docs/docs/05-migrations/13-v8-to-v9.md @@ -84,7 +84,7 @@ func NewKeeper( ) Keeper ``` -The legacy function `RegisterInterchainAccount` takes now an extra parameter to specify the ordering of new ICA channels: +The legacy function `RegisterInterchainAccount` now takes an extra parameter to specify the ordering of new ICA channels: ```diff func (k Keeper) RegisterInterchainAccount( From bbba1e5d4d5711f426b280d73aeeac7887933b8d Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 5 Jun 2024 09:19:46 +0200 Subject: [PATCH 6/9] test both ORDERED and UNORDERED channels in most (probably all) tests involving something with ICA --- .../controller/ibc_middleware_test.go | 1159 +++++++++-------- .../controller/keeper/account_test.go | 195 +-- .../controller/keeper/genesis_test.go | 35 +- .../controller/keeper/grpc_query_test.go | 49 +- .../controller/keeper/handshake_test.go | 814 ++++++------ .../controller/keeper/keeper_test.go | 200 +-- .../controller/keeper/migrations_test.go | 48 +- .../controller/keeper/msg_server_test.go | 165 +-- .../controller/keeper/relay_test.go | 98 +- .../host/ibc_module_test.go | 971 +++++++------- .../host/keeper/genesis_test.go | 33 +- .../host/keeper/handshake_test.go | 696 +++++----- .../host/keeper/keeper_test.go | 172 +-- .../host/keeper/relay_test.go | 168 +-- modules/apps/29-fee/ibc_middleware_test.go | 192 +-- modules/apps/29-fee/ica_test.go | 217 +-- 16 files changed, 2683 insertions(+), 2529 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go b/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go index e2af8caf3c8..5daab5aac36 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go @@ -58,12 +58,12 @@ func (suite *InterchainAccountsTestSuite) SetupTest() { suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(3)) } -func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { +func NewICAPath(chainA, chainB *ibctesting.TestChain, ordering channeltypes.Order) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID - path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointA.ChannelConfig.Order = ordering + path.EndpointB.ChannelConfig.Order = ordering path.EndpointA.ChannelConfig.Version = TestVersion path.EndpointB.ChannelConfig.Version = TestVersion @@ -78,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, channeltypes.ORDERED); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion, endpoint.ChannelConfig.Order); err != nil { return err } @@ -185,67 +185,69 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset - isNilApp = false + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - // mock init interchain account - portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - suite.Require().NoError(err) + // mock init interchain account + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + suite.Require().NoError(err) - portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) - suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) //nolint:errcheck // checking this error isn't needed for the test + portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) + suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) //nolint:errcheck // checking this error isn't needed for the test - path.EndpointA.ChannelConfig.PortID = portID - path.EndpointA.ChannelID = ibctesting.FirstChannelID + path.EndpointA.ChannelConfig.PortID = portID + path.EndpointA.ChannelID = ibctesting.FirstChannelID - suite.chainA.GetSimApp().ICAControllerKeeper.SetMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + suite.chainA.GetSimApp().ICAControllerKeeper.SetMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) - // default values - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - channel = &channeltypes.Channel{ - State: channeltypes.INIT, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: path.EndpointA.ChannelConfig.Version, - } + // default values + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + channel = &channeltypes.Channel{ + State: channeltypes.INIT, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointA.ConnectionID}, + Version: path.EndpointA.ChannelConfig.Version, + } - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - // ensure channel on chainA is set in state - suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, *channel) + // ensure channel on chainA is set in state + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, *channel) - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - chanCap, err := suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) - suite.Require().NoError(err) + chanCap, err := suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) - } + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.Version, - ) + version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.Version, + ) - if tc.expPass { - suite.Require().Equal(TestVersion, version) - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().Equal(TestVersion, version) + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -256,48 +258,50 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { // core IBC checks not passing, so a call to the application callback is also // done directly. func (suite *InterchainAccountsTestSuite) TestChanOpenTry() { - suite.SetupTest() // reset - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - // chainB also creates a controller port - err = RegisterInterchainAccount(path.EndpointB, TestOwnerAddress) - suite.Require().NoError(err) + // chainB also creates a controller port + err = RegisterInterchainAccount(path.EndpointB, TestOwnerAddress) + suite.Require().NoError(err) - err = path.EndpointA.UpdateClient() - suite.Require().NoError(err) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) - channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - initProof, proofHeight := path.EndpointB.Chain.QueryProof(channelKey) + channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + initProof, proofHeight := path.EndpointB.Chain.QueryProof(channelKey) - // use chainA (controller) for ChanOpenTry - msg := channeltypes.NewMsgChannelOpenTry(path.EndpointA.ChannelConfig.PortID, TestVersion, channeltypes.ORDERED, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, TestVersion, initProof, proofHeight, icatypes.ModuleName) - handler := suite.chainA.GetSimApp().MsgServiceRouter().Handler(msg) - _, err = handler(suite.chainA.GetContext(), msg) + // use chainA (controller) for ChanOpenTry + msg := channeltypes.NewMsgChannelOpenTry(path.EndpointA.ChannelConfig.PortID, TestVersion, ordering, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, TestVersion, initProof, proofHeight, icatypes.ModuleName) + handler := suite.chainA.GetSimApp().MsgServiceRouter().Handler(msg) + _, err = handler(suite.chainA.GetContext(), msg) - suite.Require().Error(err) + suite.Require().Error(err) - // call application callback directly - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + // call application callback directly + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - chanCap, found := suite.chainA.App.GetScopedIBCKeeper().GetCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) - suite.Require().True(found) + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + chanCap, found := suite.chainA.App.GetScopedIBCKeeper().GetCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + suite.Require().True(found) - version, err := cbs.OnChanOpenTry( - suite.chainA.GetContext(), path.EndpointA.ChannelConfig.Order, []string{path.EndpointA.ConnectionID}, - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, - counterparty, path.EndpointB.ChannelConfig.Version, - ) - suite.Require().Error(err) - suite.Require().Equal("", version) + version, err := cbs.OnChanOpenTry( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.Order, []string{path.EndpointA.ConnectionID}, + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, + counterparty, path.EndpointB.ChannelConfig.Version, + ) + suite.Require().Error(err) + suite.Require().Equal("", version) + } } func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { @@ -351,42 +355,44 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset - isNilApp = false + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - err = cbs.OnChanOpenAck(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelID, path.EndpointB.ChannelConfig.Version) + err = cbs.OnChanOpenAck(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelID, path.EndpointB.ChannelConfig.Version) - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) - } + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -396,69 +402,75 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { // core IBC checks not passing, so a call to the application callback is also // done directly. func (suite *InterchainAccountsTestSuite) TestChanOpenConfirm() { - suite.SetupTest() // reset - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - // chainB maliciously sets channel to OPEN - channel := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, TestVersion) - suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, channel) + // chainB maliciously sets channel to OPEN + channel := channeltypes.NewChannel(channeltypes.OPEN, ordering, channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, TestVersion) + suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, channel) - // commit state changes so proof can be created - suite.chainB.NextBlock() + // commit state changes so proof can be created + suite.chainB.NextBlock() - err = path.EndpointA.UpdateClient() - suite.Require().NoError(err) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) - // query proof from ChainB - channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - ackProof, proofHeight := path.EndpointB.Chain.QueryProof(channelKey) + // query proof from ChainB + channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + ackProof, proofHeight := path.EndpointB.Chain.QueryProof(channelKey) - // use chainA (controller) for ChanOpenConfirm - msg := channeltypes.NewMsgChannelOpenConfirm(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ackProof, proofHeight, icatypes.ModuleName) - handler := suite.chainA.GetSimApp().MsgServiceRouter().Handler(msg) - _, err = handler(suite.chainA.GetContext(), msg) + // use chainA (controller) for ChanOpenConfirm + msg := channeltypes.NewMsgChannelOpenConfirm(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ackProof, proofHeight, icatypes.ModuleName) + handler := suite.chainA.GetSimApp().MsgServiceRouter().Handler(msg) + _, err = handler(suite.chainA.GetContext(), msg) - suite.Require().Error(err) + suite.Require().Error(err) - // call application callback directly - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + // call application callback directly + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - err = cbs.OnChanOpenConfirm( - suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, - ) - suite.Require().Error(err) + err = cbs.OnChanOpenConfirm( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, + ) + suite.Require().Error(err) + } } // OnChanCloseInit on controller (chainA) func (suite *InterchainAccountsTestSuite) TestOnChanCloseInit() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - err = cbs.OnChanCloseInit( - suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, - ) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + + err = cbs.OnChanCloseInit( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, + ) - suite.Require().Error(err) + suite.Require().Error(err) + } } func (suite *InterchainAccountsTestSuite) TestOnChanCloseConfirm() { @@ -482,39 +494,41 @@ func (suite *InterchainAccountsTestSuite) TestOnChanCloseConfirm() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset - isNilApp = false + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + tc.malleate() // malleate mutates test data + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) - } + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - err = cbs.OnChanCloseConfirm( - suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + err = cbs.OnChanCloseConfirm( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -529,54 +543,56 @@ func (suite *InterchainAccountsTestSuite) TestOnRecvPacket() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - tc.malleate() // malleate mutates test data - - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) - - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - - packet := channeltypes.NewPacket( - []byte("empty packet data"), - suite.chainB.SenderAccount.GetSequence(), - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - clienttypes.NewHeight(0, 100), - 0, - ) - - ctx := suite.chainA.GetContext() - ack := cbs.OnRecvPacket(ctx, packet, nil) - suite.Require().Equal(tc.expPass, ack.Success()) - - expectedEvents := sdk.Events{ - sdk.NewEvent( - icatypes.EventTypePacket, - sdk.NewAttribute(sdk.AttributeKeyModule, icatypes.ModuleName), - sdk.NewAttribute(icatypes.AttributeKeyControllerChannelID, packet.GetDestChannel()), - sdk.NewAttribute(icatypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", false)), - sdk.NewAttribute(icatypes.AttributeKeyAckError, "cannot receive packet on controller chain: invalid message sent to channel end"), - ), - }.ToABCIEvents() - - expectedEvents = sdk.MarkEventsToIndex(expectedEvents, map[string]struct{}{}) - ibctesting.AssertEvents(&suite.Suite, expectedEvents, ctx.EventManager().Events().ToABCIEvents()) - }) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + tc.malleate() // malleate mutates test data + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) + + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + + packet := channeltypes.NewPacket( + []byte("empty packet data"), + suite.chainB.SenderAccount.GetSequence(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + clienttypes.NewHeight(0, 100), + 0, + ) + + ctx := suite.chainA.GetContext() + ack := cbs.OnRecvPacket(ctx, packet, nil) + suite.Require().Equal(tc.expPass, ack.Success()) + + expectedEvents := sdk.Events{ + sdk.NewEvent( + icatypes.EventTypePacket, + sdk.NewAttribute(sdk.AttributeKeyModule, icatypes.ModuleName), + sdk.NewAttribute(icatypes.AttributeKeyControllerChannelID, packet.GetDestChannel()), + sdk.NewAttribute(icatypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", false)), + sdk.NewAttribute(icatypes.AttributeKeyAckError, "cannot receive packet on controller chain: invalid message sent to channel end"), + ), + }.ToABCIEvents() + + expectedEvents = sdk.MarkEventsToIndex(expectedEvents, map[string]struct{}{}) + ibctesting.AssertEvents(&suite.Suite, expectedEvents, ctx.EventManager().Events().ToABCIEvents()) + }) + } } } @@ -628,50 +644,52 @@ func (suite *InterchainAccountsTestSuite) TestOnAcknowledgementPacket() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.msg, func() { - suite.SetupTest() // reset - isNilApp = false + suite.Run(tc.msg, func() { + suite.SetupTest() // reset + isNilApp = false - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - packet := channeltypes.NewPacket( - []byte("empty packet data"), - suite.chainA.SenderAccount.GetSequence(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - clienttypes.NewHeight(0, 100), - 0, - ) + packet := channeltypes.NewPacket( + []byte("empty packet data"), + suite.chainA.SenderAccount.GetSequence(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + clienttypes.NewHeight(0, 100), + 0, + ) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) - } + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - err = cbs.OnAcknowledgementPacket(suite.chainA.GetContext(), packet, []byte("ack"), nil) + err = cbs.OnAcknowledgementPacket(suite.chainA.GetContext(), packet, []byte("ack"), nil) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -723,59 +741,60 @@ func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.msg, func() { - suite.SetupTest() // reset - isNilApp = false + suite.Run(tc.msg, func() { + suite.SetupTest() // reset + isNilApp = false - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - packet := channeltypes.NewPacket( - []byte("empty packet data"), - suite.chainA.SenderAccount.GetSequence(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - clienttypes.NewHeight(0, 100), - 0, - ) + packet := channeltypes.NewPacket( + []byte("empty packet data"), + suite.chainA.SenderAccount.GetSequence(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + clienttypes.NewHeight(0, 100), + 0, + ) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) - } + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, nil) + err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, nil) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeInit() { var ( - path *ibctesting.Path - isNilApp bool - version string - channelOrder channeltypes.Order + path *ibctesting.Path + isNilApp bool + version string ) testCases := []struct { @@ -784,12 +803,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeInit() { expError error }{ { - "success w/ ORDERED channel", func() {}, nil, - }, - { - "success w/ UNORDERED channel", func() { - channelOrder = channeltypes.UNORDERED - }, nil, + "success", func() {}, nil, }, { "success: nil underlying app", @@ -825,81 +839,83 @@ func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeInit() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - isNilApp = false + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - version = icatypes.NewDefaultMetadataString(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + version = icatypes.NewDefaultMetadataString(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + tc.malleate() // malleate mutates test data - app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - cbs, ok := app.(porttypes.UpgradableModule) - suite.Require().True(ok) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) - } + app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) - channelOrder = channeltypes.ORDERED + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - version, err = cbs.OnChanUpgradeInit( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - channelOrder, - []string{path.EndpointA.ConnectionID}, - version, - ) + version, err = cbs.OnChanUpgradeInit( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + ordering, + []string{path.EndpointA.ConnectionID}, + version, + ) - if tc.expError == nil { - suite.Require().NoError(err) - } else { - suite.Require().ErrorIs(err, tc.expError) - suite.Require().Empty(version) - } - }) + if tc.expError == nil { + suite.Require().NoError(err) + } else { + suite.Require().ErrorIs(err, tc.expError) + suite.Require().Empty(version) + } + }) + } } } // OnChanUpgradeTry callback returns error on controller chains func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeTry() { - suite.SetupTest() // reset - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - // call application callback directly - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) - - app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - cbs, ok := app.(porttypes.UpgradableModule) - suite.Require().True(ok) - - version, err := cbs.OnChanUpgradeTry( - suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, - path.EndpointA.ChannelConfig.Order, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.Version, - ) - suite.Require().Error(err) - suite.Require().ErrorIs(err, icatypes.ErrInvalidChannelFlow) - suite.Require().Equal("", version) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + // call application callback directly + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + version, err := cbs.OnChanUpgradeTry( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, + path.EndpointA.ChannelConfig.Order, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.Version, + ) + suite.Require().Error(err) + suite.Require().ErrorIs(err, icatypes.ErrInvalidChannelFlow) + suite.Require().Equal("", version) + } } func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeAck() { @@ -951,48 +967,50 @@ func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeAck() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset - isNilApp = false + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - counterpartyVersion = path.EndpointB.GetChannel().Version + counterpartyVersion = path.EndpointB.GetChannel().Version - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - cbs, ok := app.(porttypes.UpgradableModule) - suite.Require().True(ok) + app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) - } + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - err = cbs.OnChanUpgradeAck( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - counterpartyVersion, - ) + err = cbs.OnChanUpgradeAck( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + counterpartyVersion, + ) - if tc.expError == nil { - suite.Require().NoError(err) - } else { - suite.Require().ErrorIs(err, tc.expError) - } - }) + if tc.expError == nil { + suite.Require().NoError(err) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } } } @@ -1001,7 +1019,6 @@ func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeOpen() { path *ibctesting.Path isNilApp bool counterpartyVersion string - channelOrder channeltypes.Order ) testCases := []struct { @@ -1010,13 +1027,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeOpen() { expPanic error }{ { - "success w/ ORDERED channel", func() {}, nil, - }, - { - "success w/ UNORDERED channel", func() { - channelOrder = channeltypes.UNORDERED - }, - nil, + "success", func() {}, nil, }, { "success: nil app", func() { @@ -1046,56 +1057,58 @@ func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeOpen() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset - isNilApp = false + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - counterpartyVersion = path.EndpointB.GetChannel().Version + counterpartyVersion = path.EndpointB.GetChannel().Version - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - cbs, ok := app.(porttypes.UpgradableModule) - suite.Require().True(ok) + app, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + upgradeOpenCb := func(cbs porttypes.UpgradableModule) { + cbs.OnChanUpgradeOpen( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + ordering, + []string{path.EndpointA.ConnectionID}, + counterpartyVersion, + ) + } - upgradeOpenCb := func(cbs porttypes.UpgradableModule) { - cbs.OnChanUpgradeOpen( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - channelOrder, - []string{path.EndpointA.ConnectionID}, - counterpartyVersion, - ) - } + if tc.expPanic != nil { + mockModule := ibcmock.NewAppModule(suite.chainA.App.GetIBCKeeper().PortKeeper) + mockApp := ibcmock.NewIBCApp(path.EndpointA.ChannelConfig.PortID, suite.chainA.App.GetScopedIBCKeeper()) + cbs = controller.NewIBCMiddleware(ibcmock.NewBlockUpgradeMiddleware(&mockModule, mockApp), suite.chainA.GetSimApp().ICAControllerKeeper) - if tc.expPanic != nil { - mockModule := ibcmock.NewAppModule(suite.chainA.App.GetIBCKeeper().PortKeeper) - mockApp := ibcmock.NewIBCApp(path.EndpointA.ChannelConfig.PortID, suite.chainA.App.GetScopedIBCKeeper()) - cbs = controller.NewIBCMiddleware(ibcmock.NewBlockUpgradeMiddleware(&mockModule, mockApp), suite.chainA.GetSimApp().ICAControllerKeeper) + suite.Require().PanicsWithError(tc.expPanic.Error(), func() { upgradeOpenCb(cbs) }) + } else { + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } - suite.Require().PanicsWithError(tc.expPanic.Error(), func() { upgradeOpenCb(cbs) }) - } else { - if isNilApp { - cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + upgradeOpenCb(cbs) } - - upgradeOpenCb(cbs) - } - }) + }) + } } } @@ -1117,174 +1130,198 @@ func (suite *InterchainAccountsTestSuite) TestSingleHostMultipleControllers() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.msg, func() { - suite.SetupTest() // reset + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - // Setup a new path from A(controller) -> B(host) - pathAToB = NewICAPath(suite.chainA, suite.chainB) - pathAToB.SetupConnections() + suite.Run(tc.msg, func() { + // reset + suite.SetupTest() + TestVersion = icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) - err := SetupICAPath(pathAToB, TestOwnerAddress) - suite.Require().NoError(err) + // Setup a new path from A(controller) -> B(host) + pathAToB = NewICAPath(suite.chainA, suite.chainB, ordering) + pathAToB.SetupConnections() - // Setup a new path from C(controller) -> B(host) - pathCToB = NewICAPath(suite.chainC, suite.chainB) - pathCToB.SetupConnections() - - // NOTE: Here the version metadata is overridden to include to the next host connection sequence (i.e. chainB's connection to chainC) - // SetupICAPath() will set endpoint.ChannelConfig.Version to TestVersion - TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: pathCToB.EndpointA.ConnectionID, - HostConnectionId: pathCToB.EndpointB.ConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, - })) + err := SetupICAPath(pathAToB, TestOwnerAddress) + suite.Require().NoError(err) - err = SetupICAPath(pathCToB, TestOwnerAddress) - suite.Require().NoError(err) + // Setup a new path from C(controller) -> B(host) + pathCToB = NewICAPath(suite.chainC, suite.chainB, ordering) + pathCToB.SetupConnections() + + // NOTE: Here the version metadata is overridden to include to the next host connection sequence (i.e. chainB's connection to chainC) + // SetupICAPath() will set endpoint.ChannelConfig.Version to TestVersion + TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: pathCToB.EndpointA.ConnectionID, + HostConnectionId: pathCToB.EndpointB.ConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, + })) + + err = SetupICAPath(pathCToB, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - accAddressChainA, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), pathAToB.EndpointB.ConnectionID, pathAToB.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + accAddressChainA, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), pathAToB.EndpointB.ConnectionID, pathAToB.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - accAddressChainC, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), pathCToB.EndpointB.ConnectionID, pathCToB.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + accAddressChainC, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), pathCToB.EndpointB.ConnectionID, pathCToB.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - suite.Require().NotEqual(accAddressChainA, accAddressChainC) + suite.Require().NotEqual(accAddressChainA, accAddressChainC) - chainAChannelID, found := suite.chainB.GetSimApp().ICAHostKeeper.GetActiveChannelID(suite.chainB.GetContext(), pathAToB.EndpointB.ConnectionID, pathAToB.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + chainAChannelID, found := suite.chainB.GetSimApp().ICAHostKeeper.GetActiveChannelID(suite.chainB.GetContext(), pathAToB.EndpointB.ConnectionID, pathAToB.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - chainCChannelID, found := suite.chainB.GetSimApp().ICAHostKeeper.GetActiveChannelID(suite.chainB.GetContext(), pathCToB.EndpointB.ConnectionID, pathCToB.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + chainCChannelID, found := suite.chainB.GetSimApp().ICAHostKeeper.GetActiveChannelID(suite.chainB.GetContext(), pathCToB.EndpointB.ConnectionID, pathCToB.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - suite.Require().NotEqual(chainAChannelID, chainCChannelID) - }) + suite.Require().NotEqual(chainAChannelID, chainCChannelID) + }) + } } } func (suite *InterchainAccountsTestSuite) TestGetAppVersion() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - controllerStack, ok := cbs.(porttypes.ICS4Wrapper) - suite.Require().True(ok) + controllerStack, ok := cbs.(porttypes.ICS4Wrapper) + suite.Require().True(ok) - appVersion, found := controllerStack.GetAppVersion(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - suite.Require().True(found) - suite.Require().Equal(path.EndpointA.ChannelConfig.Version, appVersion) + appVersion, found := controllerStack.GetAppVersion(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(path.EndpointA.ChannelConfig.Version, appVersion) + } } func (suite *InterchainAccountsTestSuite) TestInFlightHandshakeRespectsGoAPICaller() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - // initiate a channel handshake such that channel.State == INIT - err := RegisterInterchainAccount(path.EndpointA, suite.chainA.SenderAccount.GetAddress().String()) - suite.Require().NoError(err) + // initiate a channel handshake such that channel.State == INIT + err := RegisterInterchainAccount(path.EndpointA, suite.chainA.SenderAccount.GetAddress().String()) + suite.Require().NoError(err) - // attempt to start a second handshake via the controller msg server - msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) - msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), TestVersion, channeltypes.ORDERED) + // attempt to start a second handshake via the controller msg server + msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), TestVersion, ordering) - res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) - suite.Require().Error(err) - suite.Require().Nil(res) + res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) + suite.Require().Error(err) + suite.Require().Nil(res) + } } func (suite *InterchainAccountsTestSuite) TestInFlightHandshakeRespectsMsgServerCaller() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - // initiate a channel handshake such that channel.State == INIT - msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) - msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), TestVersion, channeltypes.ORDERED) + // initiate a channel handshake such that channel.State == INIT + msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), TestVersion, ordering) - res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) - suite.Require().NotNil(res) - suite.Require().NoError(err) + res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) + suite.Require().NotNil(res) + suite.Require().NoError(err) - // attempt to start a second handshake via the legacy Go API - err = RegisterInterchainAccount(path.EndpointA, suite.chainA.SenderAccount.GetAddress().String()) - suite.Require().Error(err) + // attempt to start a second handshake via the legacy Go API + err = RegisterInterchainAccount(path.EndpointA, suite.chainA.SenderAccount.GetAddress().String()) + suite.Require().Error(err) + } } func (suite *InterchainAccountsTestSuite) TestClosedChannelReopensWithMsgServer() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, suite.chainA.SenderAccount.GetAddress().String()) - suite.Require().NoError(err) + err := SetupICAPath(path, suite.chainA.SenderAccount.GetAddress().String()) + suite.Require().NoError(err) - // set the channel state to closed - path.EndpointA.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) - path.EndpointB.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) + // set the channel state to closed + path.EndpointA.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) + path.EndpointB.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) - // reset endpoint channel ids - path.EndpointA.ChannelID = "" - path.EndpointB.ChannelID = "" + // reset endpoint channel ids + path.EndpointA.ChannelID = "" + path.EndpointB.ChannelID = "" - // fetch the next channel sequence before reinitiating the channel handshake - channelSeq := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(suite.chainA.GetContext()) + // fetch the next channel sequence before reinitiating the channel handshake + channelSeq := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(suite.chainA.GetContext()) - // route a new MsgRegisterInterchainAccount in order to reopen the - msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) - msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), path.EndpointA.ChannelConfig.Version, channeltypes.ORDERED) + // route a new MsgRegisterInterchainAccount in order to reopen the + msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), path.EndpointA.ChannelConfig.Version, ordering) - res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) - suite.Require().NoError(err) - suite.Require().Equal(channeltypes.FormatChannelIdentifier(channelSeq), res.ChannelId) + res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) + suite.Require().NoError(err) + suite.Require().Equal(channeltypes.FormatChannelIdentifier(channelSeq), res.ChannelId) - // assign the channel sequence to endpointA before generating proofs and initiating the TRY step - path.EndpointA.ChannelID = channeltypes.FormatChannelIdentifier(channelSeq) + // assign the channel sequence to endpointA before generating proofs and initiating the TRY step + path.EndpointA.ChannelID = channeltypes.FormatChannelIdentifier(channelSeq) - path.EndpointA.Chain.NextBlock() + path.EndpointA.Chain.NextBlock() - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - err = path.EndpointA.ChanOpenAck() - suite.Require().NoError(err) + err = path.EndpointA.ChanOpenAck() + suite.Require().NoError(err) - err = path.EndpointB.ChanOpenConfirm() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenConfirm() + suite.Require().NoError(err) + } } func (suite *InterchainAccountsTestSuite) TestPacketDataUnmarshalerInterface() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - expPacketData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: []byte("data"), - Memo: "", + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + expPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: []byte("data"), + Memo: "", + } + + // Context, port identifier and channel identifier are unused for controller. + packetData, err := controller.IBCMiddleware{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", expPacketData.GetBytes()) + suite.Require().NoError(err) + suite.Require().Equal(expPacketData, packetData) + + // test invalid packet data + invalidPacketData := []byte("invalid packet data") + // Context, port identifier and channel identifier are not used for controller. + packetData, err = controller.IBCMiddleware{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", invalidPacketData) + suite.Require().Error(err) + suite.Require().Nil(packetData) } - - // Context, port identifier and channel identifier are unused for controller. - packetData, err := controller.IBCMiddleware{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", expPacketData.GetBytes()) - suite.Require().NoError(err) - suite.Require().Equal(expPacketData, packetData) - - // test invalid packet data - invalidPacketData := []byte("invalid packet data") - // Context, port identifier and channel identifier are not used for controller. - packetData, err = controller.IBCMiddleware{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", invalidPacketData) - suite.Require().Error(err) - suite.Require().Nil(packetData) } 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 cc4a28062f0..8fac043ccab 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go @@ -8,113 +8,118 @@ import ( ) func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { - var ( - owner string - path *ibctesting.Path - err error - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "success", func() {}, true, - }, - { - "port is already bound for owner but capability is claimed by another module", - func() { - capability := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), TestPortID) - err := suite.chainA.GetSimApp().TransferKeeper.ClaimCapability(suite.chainA.GetContext(), capability, host.PortPath(TestPortID)) - suite.Require().NoError(err) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + var ( + owner string + path *ibctesting.Path + err error + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", func() {}, true, }, - false, - }, - { - "fails to generate port-id", - func() { - owner = "" + { + "port is already bound for owner but capability is claimed by another module", + func() { + capability := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), TestPortID) + err := suite.chainA.GetSimApp().TransferKeeper.ClaimCapability(suite.chainA.GetContext(), capability, host.PortPath(TestPortID)) + suite.Require().NoError(err) + }, + false, }, - false, - }, - { - "MsgChanOpenInit fails - channel is already active & in state OPEN", - func() { - portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - suite.Require().NoError(err) - - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, portID, path.EndpointA.ChannelID) - - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - channel := channeltypes.Channel{ - State: channeltypes.OPEN, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: TestVersion, - } - suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), portID, path.EndpointA.ChannelID, channel) + { + "fails to generate port-id", + func() { + owner = "" + }, + false, }, - false, - }, - } - for _, tc := range testCases { - tc := tc + { + "MsgChanOpenInit fails - channel is already active & in state OPEN", + func() { + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + suite.Require().NoError(err) + + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, portID, path.EndpointA.ChannelID) + + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + channel := channeltypes.Channel{ + State: channeltypes.OPEN, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointA.ConnectionID}, + Version: TestVersion, + } + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), portID, path.EndpointA.ChannelID, channel) + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() + suite.Run(tc.name, func() { + suite.SetupTest() - owner = TestOwnerAddress // must be explicitly changed + owner = TestOwnerAddress // must be explicitly changed - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), path.EndpointA.ConnectionID, owner, TestVersion, channeltypes.ORDERED) + err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), path.EndpointA.ConnectionID, owner, TestVersion, ordering) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } func (suite *KeeperTestSuite) TestRegisterSameOwnerMultipleConnections() { - suite.SetupTest() - - owner := TestOwnerAddress - - pathAToB := NewICAPath(suite.chainA, suite.chainB) - pathAToB.SetupConnections() - - pathAToC := NewICAPath(suite.chainA, suite.chainC) - pathAToC.SetupConnections() - - // build ICS27 metadata with connection identifiers for path A->B - metadata := &icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: pathAToB.EndpointA.ConnectionID, - HostConnectionId: pathAToB.EndpointB.ConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, - } - - err := suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToB.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata)), channeltypes.ORDERED) - suite.Require().NoError(err) - - // build ICS27 metadata with connection identifiers for path A->C - metadata = &icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: pathAToC.EndpointA.ConnectionID, - HostConnectionId: pathAToC.EndpointB.ConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() + + owner := TestOwnerAddress + + pathAToB := NewICAPath(suite.chainA, suite.chainB, ordering) + pathAToB.SetupConnections() + + pathAToC := NewICAPath(suite.chainA, suite.chainC, ordering) + pathAToC.SetupConnections() + + // build ICS27 metadata with connection identifiers for path A->B + metadata := &icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: pathAToB.EndpointA.ConnectionID, + HostConnectionId: pathAToB.EndpointB.ConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, + } + + err := suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToB.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata)), ordering) + suite.Require().NoError(err) + + // build ICS27 metadata with connection identifiers for path A->C + metadata = &icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: pathAToC.EndpointA.ConnectionID, + HostConnectionId: pathAToC.EndpointB.ConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, + } + + err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToC.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata)), ordering) + suite.Require().NoError(err) } - - err = suite.chainA.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(suite.chainA.GetContext(), pathAToC.EndpointA.ConnectionID, owner, string(icatypes.ModuleCdc.MustMarshalJSON(metadata)), channeltypes.ORDERED) - suite.Require().NoError(err) } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go b/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go index b8f8acf9537..a27932988d0 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" genesistypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/genesis/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -95,28 +96,30 @@ func (suite *KeeperTestSuite) TestInitGenesis() { } func (suite *KeeperTestSuite) TestExportGenesis() { - suite.SetupTest() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(exists) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) - genesisState := keeper.ExportGenesis(suite.chainA.GetContext(), suite.chainA.GetSimApp().ICAControllerKeeper) + genesisState := keeper.ExportGenesis(suite.chainA.GetContext(), suite.chainA.GetSimApp().ICAControllerKeeper) - suite.Require().Equal(path.EndpointA.ChannelID, genesisState.ActiveChannels[0].ChannelId) - suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.ActiveChannels[0].PortId) - suite.Require().True(genesisState.ActiveChannels[0].IsMiddlewareEnabled) + suite.Require().Equal(path.EndpointA.ChannelID, genesisState.ActiveChannels[0].ChannelId) + suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.ActiveChannels[0].PortId) + suite.Require().True(genesisState.ActiveChannels[0].IsMiddlewareEnabled) - suite.Require().Equal(interchainAccAddr, genesisState.InterchainAccounts[0].AccountAddress) - suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.InterchainAccounts[0].PortId) + suite.Require().Equal(interchainAccAddr, genesisState.InterchainAccounts[0].AccountAddress) + suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.InterchainAccounts[0].PortId) - suite.Require().Equal([]string{TestPortID}, genesisState.GetPorts()) + suite.Require().Equal([]string{TestPortID}, genesisState.GetPorts()) - expParams := types.DefaultParams() - suite.Require().Equal(expParams, genesisState.GetParams()) + expParams := types.DefaultParams() + suite.Require().Equal(expParams, genesisState.GetParams()) + } } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go b/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go index 465f103b924..471d343dc4f 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -41,37 +42,39 @@ func (suite *KeeperTestSuite) TestQueryInterchainAccount() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() + suite.Run(tc.name, func() { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, ibctesting.TestAccAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, ibctesting.TestAccAddress) + suite.Require().NoError(err) - req = &types.QueryInterchainAccountRequest{ - ConnectionId: ibctesting.FirstConnectionID, - Owner: ibctesting.TestAccAddress, - } + req = &types.QueryInterchainAccountRequest{ + ConnectionId: ibctesting.FirstConnectionID, + Owner: ibctesting.TestAccAddress, + } - tc.malleate() + tc.malleate() - res, err := suite.chainA.GetSimApp().ICAControllerKeeper.InterchainAccount(suite.chainA.GetContext(), req) + res, err := suite.chainA.GetSimApp().ICAControllerKeeper.InterchainAccount(suite.chainA.GetContext(), req) - if tc.expPass { - expAddress, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(exists) + if tc.expPass { + expAddress, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) - suite.Require().NoError(err) - suite.Require().Equal(expAddress, res.Address) - } else { - suite.Require().Error(err) - } - }) + suite.Require().NoError(err) + suite.Require().Equal(expAddress, res.Address) + } else { + suite.Require().Error(err) + } + }) + } } } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index ec8a671b307..42b8d8eabd1 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -15,301 +15,309 @@ const ( ) func (suite *KeeperTestSuite) TestOnChanOpenInit() { - var ( - channel *channeltypes.Channel - path *ibctesting.Path - chanCap *capabilitytypes.Capability - metadata icatypes.Metadata - expectedVersion string - ) - - testCases := []struct { - name string - malleate func() - expError error - }{ - { - "success", - func() {}, - nil, - }, - { - "success: previous active channel closed", - func() { - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - channel := channeltypes.Channel{ - State: channeltypes.CLOSED, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: TestVersion, - } - - path.EndpointA.SetChannel(channel) - }, - nil, - }, - { - "success: empty channel version returns default metadata JSON string", - func() { - channel.Version = "" - expectedVersion = icatypes.NewDefaultMetadataString(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) - }, - nil, - }, - { - "success: channel reopening", - func() { - err := SetupICAPath(path, TestOwnerAddress) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + var ( + channel *channeltypes.Channel + path *ibctesting.Path + chanCap *capabilitytypes.Capability + metadata icatypes.Metadata + expectedVersion string + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success: previous active channel closed", + func() { + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + channel := channeltypes.Channel{ + State: channeltypes.CLOSED, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointA.ConnectionID}, + Version: TestVersion, + } + + path.EndpointA.SetChannel(channel) + }, + nil, + }, + { + "success: empty channel version returns default metadata JSON string", + func() { + channel.Version = "" + expectedVersion = icatypes.NewDefaultMetadataString(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + }, + nil, + }, + { + "success: channel reopening", + func() { + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + path.EndpointA.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) + path.EndpointB.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) + + path.EndpointA.ChannelID = "" + path.EndpointB.ChannelID = "" + }, + nil, + }, + { + "failure: different ordering from previous channel", + func() { + differentOrdering := channeltypes.UNORDERED + if ordering == channeltypes.UNORDERED { + differentOrdering = channeltypes.ORDERED + } + + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + channel := channeltypes.Channel{ + State: channeltypes.CLOSED, + Ordering: differentOrdering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointA.ConnectionID}, + Version: TestVersion, + } + + path.EndpointA.SetChannel(channel) + }, + channeltypes.ErrInvalidChannelOrdering, + }, + { + "invalid metadata - previous metadata is different", + func() { + // set active channel to closed + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + // attempt to downgrade version by reinitializing channel with version 1, but setting channel to version 2 + metadata.Version = "ics27-2" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + closedChannel := channeltypes.Channel{ + State: channeltypes.CLOSED, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointA.ConnectionID}, + Version: string(versionBytes), + } + path.EndpointA.SetChannel(closedChannel) + }, + icatypes.ErrInvalidVersion, + }, + { + "invalid port ID", + func() { + path.EndpointA.ChannelConfig.PortID = "invalid-port-id" //nolint:goconst + }, + icatypes.ErrInvalidControllerPort, + }, + { + "invalid counterparty port ID", + func() { + path.EndpointA.SetChannel(*channel) + channel.Counterparty.PortId = "invalid-port-id" + }, + icatypes.ErrInvalidHostPort, + }, + { + "invalid metadata bytestring", + func() { + path.EndpointA.SetChannel(*channel) + channel.Version = "invalid-metadata-bytestring" + }, + icatypes.ErrUnknownDataType, + }, + { + "unsupported encoding format", + func() { + metadata.Encoding = "invalid-encoding-format" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(versionBytes) + path.EndpointA.SetChannel(*channel) + }, + icatypes.ErrInvalidCodec, + }, + { + "unsupported transaction type", + func() { + metadata.TxType = "invalid-tx-types" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(versionBytes) + path.EndpointA.SetChannel(*channel) + }, + icatypes.ErrUnknownDataType, + }, + { + "connection not found", + func() { + channel.ConnectionHops = []string{"invalid-connnection-id"} + path.EndpointA.SetChannel(*channel) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "connection not found with default empty channel version", + func() { + channel.ConnectionHops = []string{"connection-10"} + channel.Version = "" + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "invalid controller connection ID", + func() { + metadata.ControllerConnectionId = "invalid-connnection-id" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(versionBytes) + path.EndpointA.SetChannel(*channel) + }, + connectiontypes.ErrInvalidConnection, + }, + { + "invalid host connection ID", + func() { + metadata.HostConnectionId = "invalid-connnection-id" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(versionBytes) + path.EndpointA.SetChannel(*channel) + }, + connectiontypes.ErrInvalidConnection, + }, + { + "invalid version", + func() { + metadata.Version = "invalid-version" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(versionBytes) + path.EndpointA.SetChannel(*channel) + }, + icatypes.ErrInvalidVersion, + }, + { + "channel is already active (OPEN state)", + func() { + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + channel := channeltypes.Channel{ + State: channeltypes.OPEN, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointA.ConnectionID}, + Version: TestVersion, + } + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) + }, + icatypes.ErrActiveChannelAlreadySet, + }, + { + "channel is already active (FLUSHING state)", + func() { + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + channel := channeltypes.Channel{ + State: channeltypes.FLUSHING, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointA.ConnectionID}, + Version: TestVersion, + } + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) + }, + icatypes.ErrActiveChannelAlreadySet, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + + // mock init interchain account + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) suite.Require().NoError(err) - path.EndpointA.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) - path.EndpointB.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) - - path.EndpointA.ChannelID = "" - path.EndpointB.ChannelID = "" - }, - nil, - }, - { - "failure: different ordering from previous channel", - func() { - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - channel := channeltypes.Channel{ - State: channeltypes.CLOSED, - Ordering: channeltypes.UNORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: TestVersion, - } - - path.EndpointA.SetChannel(channel) - }, - channeltypes.ErrInvalidChannelOrdering, - }, - { - "invalid metadata - previous metadata is different", - func() { - // set active channel to closed - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - - // attempt to downgrade version by reinitializing channel with version 1, but setting channel to version 2 - metadata.Version = "ics27-2" + portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) + suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) //nolint:errcheck // this error check isn't needed for tests + path.EndpointA.ChannelConfig.PortID = portID + // default values + metadata = icatypes.NewMetadata(icatypes.Version, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID, "", icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) + expectedVersion = string(versionBytes) + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - closedChannel := channeltypes.Channel{ - State: channeltypes.CLOSED, - Ordering: channeltypes.ORDERED, + channel = &channeltypes.Channel{ + State: channeltypes.INIT, + Ordering: ordering, Counterparty: counterparty, ConnectionHops: []string{path.EndpointA.ConnectionID}, Version: string(versionBytes), } - path.EndpointA.SetChannel(closedChannel) - }, - icatypes.ErrInvalidVersion, - }, - { - "invalid port ID", - func() { - path.EndpointA.ChannelConfig.PortID = "invalid-port-id" //nolint:goconst - }, - icatypes.ErrInvalidControllerPort, - }, - { - "invalid counterparty port ID", - func() { - path.EndpointA.SetChannel(*channel) - channel.Counterparty.PortId = "invalid-port-id" - }, - icatypes.ErrInvalidHostPort, - }, - { - "invalid metadata bytestring", - func() { - path.EndpointA.SetChannel(*channel) - channel.Version = "invalid-metadata-bytestring" - }, - icatypes.ErrUnknownDataType, - }, - { - "unsupported encoding format", - func() { - metadata.Encoding = "invalid-encoding-format" - - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) - - channel.Version = string(versionBytes) - path.EndpointA.SetChannel(*channel) - }, - icatypes.ErrInvalidCodec, - }, - { - "unsupported transaction type", - func() { - metadata.TxType = "invalid-tx-types" - - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) - - channel.Version = string(versionBytes) - path.EndpointA.SetChannel(*channel) - }, - icatypes.ErrUnknownDataType, - }, - { - "connection not found", - func() { - channel.ConnectionHops = []string{"invalid-connnection-id"} - path.EndpointA.SetChannel(*channel) - }, - connectiontypes.ErrConnectionNotFound, - }, - { - "connection not found with default empty channel version", - func() { - channel.ConnectionHops = []string{"connection-10"} - channel.Version = "" - }, - connectiontypes.ErrConnectionNotFound, - }, - { - "invalid controller connection ID", - func() { - metadata.ControllerConnectionId = "invalid-connnection-id" - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) suite.Require().NoError(err) - channel.Version = string(versionBytes) - path.EndpointA.SetChannel(*channel) - }, - connectiontypes.ErrInvalidConnection, - }, - { - "invalid host connection ID", - func() { - metadata.HostConnectionId = "invalid-connnection-id" + tc.malleate() // malleate mutates test data - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) - - channel.Version = string(versionBytes) - path.EndpointA.SetChannel(*channel) - }, - connectiontypes.ErrInvalidConnection, - }, - { - "invalid version", - func() { - metadata.Version = "invalid-version" - - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) - - channel.Version = string(versionBytes) - path.EndpointA.SetChannel(*channel) - }, - icatypes.ErrInvalidVersion, - }, - { - "channel is already active (OPEN state)", - func() { - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - channel := channeltypes.Channel{ - State: channeltypes.OPEN, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: TestVersion, - } - suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) - }, - icatypes.ErrActiveChannelAlreadySet, - }, - { - "channel is already active (FLUSHING state)", - func() { - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + version, err := suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.Version, + ) - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - channel := channeltypes.Channel{ - State: channeltypes.FLUSHING, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: TestVersion, + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(expectedVersion, version) + } else { + suite.Require().Error(err) + suite.Require().ErrorIs(err, tc.expError) } - suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) - }, - icatypes.ErrActiveChannelAlreadySet, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - // mock init interchain account - portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - suite.Require().NoError(err) - - portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) - suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) //nolint:errcheck // this error check isn't needed for tests - path.EndpointA.ChannelConfig.PortID = portID - - // default values - metadata = icatypes.NewMetadata(icatypes.Version, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID, "", icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) - - expectedVersion = string(versionBytes) - - counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - channel = &channeltypes.Channel{ - State: channeltypes.INIT, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: string(versionBytes), - } - - chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) - suite.Require().NoError(err) - - tc.malleate() // malleate mutates test data - - version, err := suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.Version, - ) - - expPass := tc.expError == nil - if expPass { - suite.Require().NoError(err) - suite.Require().Equal(expectedVersion, version) - } else { - suite.Require().Error(err) - suite.Require().ErrorIs(err, tc.expError) - } - }) + }) + } } } func (suite *KeeperTestSuite) TestOnChanOpenAck() { + var ( path *ibctesting.Path metadata icatypes.Metadata @@ -417,52 +425,54 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(exists) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) - metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, interchainAccAddr, icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) + metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, interchainAccAddr, icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - path.EndpointB.ChannelConfig.Version = string(versionBytes) + path.EndpointB.ChannelConfig.Version = string(versionBytes) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenAck(suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointA.Counterparty.ChannelConfig.Version, - ) + err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenAck(suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointA.Counterparty.ChannelConfig.Version, + ) - if tc.expPass { - suite.Require().NoError(err) + if tc.expPass { + suite.Require().NoError(err) - activeChannelID, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + activeChannelID, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - suite.Require().Equal(path.EndpointA.ChannelID, activeChannelID) + suite.Require().Equal(path.EndpointA.ChannelID, activeChannelID) - interchainAccAddress, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + interchainAccAddress, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - suite.Require().Equal(metadata.Address, interchainAccAddress) - } else { - suite.Require().Error(err) - } - }) + suite.Require().Equal(metadata.Address, interchainAccAddress) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -479,33 +489,35 @@ func (suite *KeeperTestSuite) TestOnChanCloseConfirm() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - err = suite.chainB.GetSimApp().ICAControllerKeeper.OnChanCloseConfirm(suite.chainB.GetContext(), - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + err = suite.chainB.GetSimApp().ICAControllerKeeper.OnChanCloseConfirm(suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - activeChannelID, found := suite.chainB.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointB.ChannelConfig.PortID) + activeChannelID, found := suite.chainB.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointB.ChannelConfig.PortID) - if tc.expPass { - suite.Require().NoError(err) - suite.Require().False(found) - suite.Require().Empty(activeChannelID) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + suite.Require().False(found) + suite.Require().Empty(activeChannelID) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -640,54 +652,56 @@ func (suite *KeeperTestSuite) TestOnChanUpgradeInit() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - currentMetadata, err := suite.chainA.GetSimApp().ICAControllerKeeper.GetAppMetadata(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - suite.Require().NoError(err) + currentMetadata, err := suite.chainA.GetSimApp().ICAControllerKeeper.GetAppMetadata(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().NoError(err) - order = channeltypes.ORDERED - metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) - // use the same address as the previous metadata. - metadata.Address = currentMetadata.Address + order = channeltypes.ORDERED + metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + // use the same address as the previous metadata. + metadata.Address = currentMetadata.Address - // this is the actual change to the version. - metadata.Encoding = icatypes.EncodingProto3JSON + // this is the actual change to the version. + metadata.Encoding = icatypes.EncodingProto3JSON - path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - version = path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version + version = path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - upgradeVersion, err := path.EndpointA.Chain.GetSimApp().ICAControllerKeeper.OnChanUpgradeInit( - path.EndpointA.Chain.GetContext(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - order, - []string{path.EndpointA.ConnectionID}, - version, - ) + upgradeVersion, err := path.EndpointA.Chain.GetSimApp().ICAControllerKeeper.OnChanUpgradeInit( + path.EndpointA.Chain.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + order, + []string{path.EndpointA.ConnectionID}, + version, + ) - expPass := tc.expError == nil + expPass := tc.expError == nil - if expPass { - suite.Require().NoError(err) - suite.Require().Equal(upgradeVersion, version) - } else { - suite.Require().ErrorIs(err, tc.expError) - } - }) + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(upgradeVersion, version) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } } } @@ -806,55 +820,57 @@ func (suite *KeeperTestSuite) TestOnChanUpgradeAck() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - currentMetadata, err := suite.chainA.GetSimApp().ICAControllerKeeper.GetAppMetadata(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - suite.Require().NoError(err) + currentMetadata, err := suite.chainA.GetSimApp().ICAControllerKeeper.GetAppMetadata(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().NoError(err) - metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) - // use the same address as the previous metadata. - metadata.Address = currentMetadata.Address + metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + // use the same address as the previous metadata. + metadata.Address = currentMetadata.Address - // this is the actual change to the version. - metadata.Encoding = icatypes.EncodingProto3JSON + // this is the actual change to the version. + metadata.Encoding = icatypes.EncodingProto3JSON - path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - err = path.EndpointA.ChanUpgradeInit() - suite.Require().NoError(err) + err = path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) - err = path.EndpointB.ChanUpgradeTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) - counterpartyVersion = path.EndpointB.GetChannel().Version + counterpartyVersion = path.EndpointB.GetChannel().Version - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanUpgradeAck( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - counterpartyVersion, - ) + err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanUpgradeAck( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + counterpartyVersion, + ) - expPass := tc.expError == nil - if expPass { - suite.Require().NoError(err) - suite.Require().Equal(path.EndpointA.GetChannel().Version, counterpartyVersion) - } else { - suite.Require().ErrorIs(err, tc.expError) - } - }) + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(path.EndpointA.GetChannel().Version, counterpartyVersion) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } } } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go index 00af5616148..f8e2486d15d 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go @@ -52,12 +52,12 @@ func (suite *KeeperTestSuite) SetupTest() { suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(3)) } -func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { +func NewICAPath(chainA, chainB *ibctesting.TestChain, ordering channeltypes.Order) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID - path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointA.ChannelConfig.Order = ordering + path.EndpointB.ChannelConfig.Order = ordering path.EndpointA.ChannelConfig.Version = TestVersion path.EndpointB.ChannelConfig.Version = TestVersion @@ -90,7 +90,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, channeltypes.ORDERED); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion, endpoint.ChannelConfig.Order); err != nil { return err } @@ -161,127 +161,137 @@ func (suite *KeeperTestSuite) TestNewKeeper() { } func (suite *KeeperTestSuite) TestGetAllPorts() { - suite.SetupTest() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - expectedPorts := []string{TestPortID} + expectedPorts := []string{TestPortID} - ports := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllPorts(suite.chainA.GetContext()) - suite.Require().Len(ports, len(expectedPorts)) - suite.Require().Equal(expectedPorts, ports) + ports := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllPorts(suite.chainA.GetContext()) + suite.Require().Len(ports, len(expectedPorts)) + suite.Require().Equal(expectedPorts, ports) + } } func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() { - suite.SetupTest() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - counterpartyPortID := path.EndpointA.ChannelConfig.PortID + counterpartyPortID := path.EndpointA.ChannelConfig.PortID - retrievedAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, counterpartyPortID) - suite.Require().True(found) - suite.Require().NotEmpty(retrievedAddr) + retrievedAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, counterpartyPortID) + suite.Require().True(found) + suite.Require().NotEmpty(retrievedAddr) - retrievedAddr, found = suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), "invalid conn", "invalid port") - suite.Require().False(found) - suite.Require().Empty(retrievedAddr) + retrievedAddr, found = suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), "invalid conn", "invalid port") + suite.Require().False(found) + suite.Require().Empty(retrievedAddr) + } } func (suite *KeeperTestSuite) TestGetAllActiveChannels() { - var ( - expectedChannelID = "test-channel" - expectedPortID = "test-port" - ) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + var ( + expectedChannelID = "test-channel" + expectedPortID = "test-port" + ) - suite.SetupTest() + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedChannelID) - - expectedChannels := []genesistypes.ActiveChannel{ - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: TestPortID, - ChannelId: path.EndpointA.ChannelID, - IsMiddlewareEnabled: true, - }, - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: expectedPortID, - ChannelId: expectedChannelID, - IsMiddlewareEnabled: false, - }, + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedChannelID) + + expectedChannels := []genesistypes.ActiveChannel{ + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: TestPortID, + ChannelId: path.EndpointA.ChannelID, + IsMiddlewareEnabled: true, + }, + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: expectedPortID, + ChannelId: expectedChannelID, + IsMiddlewareEnabled: false, + }, + } + + activeChannels := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllActiveChannels(suite.chainA.GetContext()) + suite.Require().Len(activeChannels, len(expectedChannels)) + suite.Require().Equal(expectedChannels, activeChannels) } - - activeChannels := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllActiveChannels(suite.chainA.GetContext()) - suite.Require().Len(activeChannels, len(expectedChannels)) - suite.Require().Equal(expectedChannels, activeChannels) } func (suite *KeeperTestSuite) TestGetAllInterchainAccounts() { - var ( - expectedAccAddr = "test-acc-addr" - expectedPortID = "test-port" - ) - - suite.SetupTest() - - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(exists) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + var ( + expectedAccAddr = "test-acc-addr" + expectedPortID = "test-port" + ) - suite.chainA.GetSimApp().ICAControllerKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) + suite.SetupTest() - expectedAccounts := []genesistypes.RegisteredInterchainAccount{ - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: TestPortID, - AccountAddress: interchainAccAddr, - }, - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: expectedPortID, - AccountAddress: expectedAccAddr, - }, + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + + suite.chainA.GetSimApp().ICAControllerKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) + + expectedAccounts := []genesistypes.RegisteredInterchainAccount{ + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: TestPortID, + AccountAddress: interchainAccAddr, + }, + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: expectedPortID, + AccountAddress: expectedAccAddr, + }, + } + + interchainAccounts := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllInterchainAccounts(suite.chainA.GetContext()) + suite.Require().Len(interchainAccounts, len(expectedAccounts)) + suite.Require().Equal(expectedAccounts, interchainAccounts) } - - interchainAccounts := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllInterchainAccounts(suite.chainA.GetContext()) - suite.Require().Len(interchainAccounts, len(expectedAccounts)) - suite.Require().Equal(expectedAccounts, interchainAccounts) } func (suite *KeeperTestSuite) TestIsActiveChannel() { - suite.SetupTest() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - owner := TestOwnerAddress - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, ordering) + owner := TestOwnerAddress + path.SetupConnections() - err := SetupICAPath(path, owner) - suite.Require().NoError(err) - portID := path.EndpointA.ChannelConfig.PortID + err := SetupICAPath(path, owner) + suite.Require().NoError(err) + portID := path.EndpointA.ChannelConfig.PortID - isActive := suite.chainA.GetSimApp().ICAControllerKeeper.IsActiveChannel(suite.chainA.GetContext(), ibctesting.FirstConnectionID, portID) - suite.Require().Equal(isActive, true) + isActive := suite.chainA.GetSimApp().ICAControllerKeeper.IsActiveChannel(suite.chainA.GetContext(), ibctesting.FirstConnectionID, portID) + suite.Require().Equal(isActive, true) + } } func (suite *KeeperTestSuite) TestSetInterchainAccountAddress() { diff --git a/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go b/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go index f0011439d14..ec48a442860 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go @@ -43,37 +43,39 @@ func (suite *KeeperTestSuite) TestAssertChannelCapabilityMigrations() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() + suite.Run(tc.name, func() { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, ibctesting.TestAccAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, ibctesting.TestAccAddress) + suite.Require().NoError(err) - tc.malleate() + tc.malleate() - migrator := icacontrollerkeeper.NewMigrator(&suite.chainA.GetSimApp().ICAControllerKeeper) - err = migrator.AssertChannelCapabilityMigrations(suite.chainA.GetContext()) + migrator := icacontrollerkeeper.NewMigrator(&suite.chainA.GetSimApp().ICAControllerKeeper) + err = migrator.AssertChannelCapabilityMigrations(suite.chainA.GetContext()) - if tc.expPass { - suite.Require().NoError(err) + if tc.expPass { + suite.Require().NoError(err) - isMiddlewareEnabled := suite.chainA.GetSimApp().ICAControllerKeeper.IsMiddlewareEnabled( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ConnectionID, - ) + isMiddlewareEnabled := suite.chainA.GetSimApp().ICAControllerKeeper.IsMiddlewareEnabled( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ConnectionID, + ) - suite.Require().True(isMiddlewareEnabled) - } else { - suite.Require().Error(err) - } - }) + suite.Require().True(isMiddlewareEnabled) + } else { + suite.Require().Error(err) + } + }) + } } } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go b/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go index 71899dacf53..462bc422a8f 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go @@ -75,45 +75,46 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount_MsgServer() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - expectedOrderding = channeltypes.ORDERED - - suite.SetupTest() - - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - msg = types.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, ibctesting.TestAccAddress, "", channeltypes.ORDERED) - - tc.malleate() - - ctx := suite.chainA.GetContext() - msgServer := keeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) - res, err := msgServer.RegisterInterchainAccount(ctx, msg) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().NotNil(res) - suite.Require().Equal(expectedChannelID, res.ChannelId) - - events := ctx.EventManager().Events() - suite.Require().Len(events, 2) - suite.Require().Equal(events[0].Type, channeltypes.EventTypeChannelOpenInit) - suite.Require().Equal(events[1].Type, sdk.EventTypeMessage) - - path.EndpointA.ChannelConfig.PortID = res.PortId - path.EndpointA.ChannelID = res.ChannelId - channel := path.EndpointA.GetChannel() - suite.Require().Equal(expectedOrderding, channel.Ordering) - } else { - suite.Require().Error(err) - suite.Require().Nil(res) - } - }) - + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + expectedOrderding = ordering + + suite.SetupTest() + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + + msg = types.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, ibctesting.TestAccAddress, "", ordering) + + tc.malleate() + + ctx := suite.chainA.GetContext() + msgServer := keeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + res, err := msgServer.RegisterInterchainAccount(ctx, msg) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(expectedChannelID, res.ChannelId) + + events := ctx.EventManager().Events() + suite.Require().Len(events, 2) + suite.Require().Equal(events[0].Type, channeltypes.EventTypeChannelOpenInit) + suite.Require().Equal(events[1].Type, sdk.EventTypeMessage) + + path.EndpointA.ChannelConfig.PortID = res.PortId + path.EndpointA.ChannelID = res.ChannelId + channel := path.EndpointA.GetChannel() + suite.Require().Equal(expectedOrderding, channel.Ordering) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + }) + } } } @@ -165,61 +166,63 @@ func (suite *KeeperTestSuite) TestSubmitTx() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() + suite.Run(tc.name, func() { + suite.SetupTest() - owner := TestOwnerAddress - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + owner := TestOwnerAddress + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, owner) - suite.Require().NoError(err) + err := SetupICAPath(path, owner) + suite.Require().NoError(err) - portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - suite.Require().NoError(err) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + suite.Require().NoError(err) - // get the address of the interchain account stored in state during handshake step - interchainAccountAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), path.EndpointA.ConnectionID, portID) - suite.Require().True(found) + // get the address of the interchain account stored in state during handshake step + interchainAccountAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), path.EndpointA.ConnectionID, portID) + suite.Require().True(found) - // create bank transfer message that will execute on the host chain - icaMsg := &banktypes.MsgSend{ - FromAddress: interchainAccountAddr, - ToAddress: suite.chainB.SenderAccount.GetAddress().String(), - Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100))), - } + // create bank transfer message that will execute on the host chain + icaMsg := &banktypes.MsgSend{ + FromAddress: interchainAccountAddr, + ToAddress: suite.chainB.SenderAccount.GetAddress().String(), + Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100))), + } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{icaMsg}, icatypes.EncodingProtobuf) - suite.Require().NoError(err) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{icaMsg}, icatypes.EncodingProtobuf) + suite.Require().NoError(err) - packetData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: data, - Memo: "memo", - } + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + Memo: "memo", + } - timeoutTimestamp := uint64(suite.chainA.GetContext().BlockTime().Add(time.Minute).UnixNano()) - connectionID := path.EndpointA.ConnectionID + timeoutTimestamp := uint64(suite.chainA.GetContext().BlockTime().Add(time.Minute).UnixNano()) + connectionID := path.EndpointA.ConnectionID - msg = types.NewMsgSendTx(owner, connectionID, timeoutTimestamp, packetData) + msg = types.NewMsgSendTx(owner, connectionID, timeoutTimestamp, packetData) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - ctx := suite.chainA.GetContext() - msgServer := keeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) - res, err := msgServer.SendTx(ctx, msg) + ctx := suite.chainA.GetContext() + msgServer := keeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + res, err := msgServer.SendTx(ctx, msg) - if tc.expPass { - suite.Require().NoError(err) - suite.Require().NotNil(res) - } else { - suite.Require().Error(err) - suite.Require().Nil(res) - } - }) + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + }) + } } } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go b/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go index 3f81bb6dbf6..910e3bf9173 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go @@ -142,30 +142,32 @@ func (suite *KeeperTestSuite) TestSendTx() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.msg, func() { - suite.SetupTest() // reset - timeoutTimestamp = ^uint64(0) // default + suite.Run(tc.msg, func() { + suite.SetupTest() // reset + timeoutTimestamp = ^uint64(0) // default - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) - _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, packetData, timeoutTimestamp) + //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) + _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, packetData, timeoutTimestamp) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -184,38 +186,40 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.msg, func() { - suite.SetupTest() // reset - - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + suite.Run(tc.msg, func() { + suite.SetupTest() // reset - tc.malleate() // malleate mutates test data + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - packet := channeltypes.NewPacket( - []byte{}, - 1, - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - clienttypes.NewHeight(0, 100), - 0, - ) - - err = suite.chainA.GetSimApp().ICAControllerKeeper.OnTimeoutPacket(suite.chainA.GetContext(), packet) - - if tc.expPass { + err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + + tc.malleate() // malleate mutates test data + + packet := channeltypes.NewPacket( + []byte{}, + 1, + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + clienttypes.NewHeight(0, 100), + 0, + ) + + err = suite.chainA.GetSimApp().ICAControllerKeeper.OnTimeoutPacket(suite.chainA.GetContext(), packet) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } diff --git a/modules/apps/27-interchain-accounts/host/ibc_module_test.go b/modules/apps/27-interchain-accounts/host/ibc_module_test.go index 7279f680438..481856e08a5 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module_test.go @@ -63,12 +63,12 @@ func (suite *InterchainAccountsTestSuite) SetupTest() { suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) } -func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { +func NewICAPath(chainA, chainB *ibctesting.TestChain, ordering channeltypes.Order) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID - path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointA.ChannelConfig.Order = ordering + path.EndpointB.ChannelConfig.Order = ordering path.EndpointA.ChannelConfig.Version = TestVersion path.EndpointB.ChannelConfig.Version = TestVersion @@ -83,7 +83,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, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, endpoint.ChannelConfig.Order); err != nil { return err } @@ -117,16 +117,18 @@ func SetupICAPath(path *ibctesting.Path, owner string) error { // Test initiating a ChanOpenInit using the host chain instead of the controller chain // ChainA is the controller chain. ChainB is the host chain func (suite *InterchainAccountsTestSuite) TestChanOpenInit() { - suite.SetupTest() // reset - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - // use chainB (host) for ChanOpenInit - msg := channeltypes.NewMsgChannelOpenInit(path.EndpointB.ChannelConfig.PortID, icatypes.Version, channeltypes.ORDERED, []string{path.EndpointB.ConnectionID}, path.EndpointA.ChannelConfig.PortID, icatypes.ModuleName) - handler := suite.chainB.GetSimApp().MsgServiceRouter().Handler(msg) - _, err := handler(suite.chainB.GetContext(), msg) + // use chainB (host) for ChanOpenInit + msg := channeltypes.NewMsgChannelOpenInit(path.EndpointB.ChannelConfig.PortID, icatypes.Version, ordering, []string{path.EndpointB.ConnectionID}, path.EndpointA.ChannelConfig.PortID, icatypes.ModuleName) + handler := suite.chainB.GetSimApp().MsgServiceRouter().Handler(msg) + _, err := handler(suite.chainB.GetContext(), msg) - suite.Require().Error(err) + suite.Require().Error(err) + } } func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { @@ -141,12 +143,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { expPass bool }{ { - "success w/ ORDERED channel", func() {}, true, - }, - { - "success w/ UNORDERED channel", func() { - channel.Ordering = channeltypes.UNORDERED - }, true, + "success", func() {}, true, }, { "account address generation is block dependent", func() { @@ -177,94 +174,98 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + suite.Run(tc.name, func() { + suite.SetupTest() // reset - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) - path.EndpointB.ChannelID = ibctesting.FirstChannelID + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - // default values - counterparty := channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - channel = &channeltypes.Channel{ - State: channeltypes.TRYOPEN, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointB.ConnectionID}, - Version: path.EndpointB.ChannelConfig.Version, - } + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) + path.EndpointB.ChannelID = ibctesting.FirstChannelID + + // default values + counterparty := channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + channel = &channeltypes.Channel{ + State: channeltypes.TRYOPEN, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointB.ConnectionID}, + Version: path.EndpointB.ChannelConfig.Version, + } - tc.malleate() + tc.malleate() - // ensure channel on chainB is set in state - suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, *channel) + // ensure channel on chainB is set in state + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, *channel) - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - chanCap, err := suite.chainB.App.GetScopedIBCKeeper().NewCapability(suite.chainB.GetContext(), host.ChannelCapabilityPath(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) - suite.Require().NoError(err) + chanCap, err := suite.chainB.App.GetScopedIBCKeeper().NewCapability(suite.chainB.GetContext(), host.ChannelCapabilityPath(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) + suite.Require().NoError(err) - cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - version, err := cbs.OnChanOpenTry(suite.chainB.GetContext(), channel.Ordering, channel.ConnectionHops, - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, path.EndpointA.ChannelConfig.Version, - ) + version, err := cbs.OnChanOpenTry(suite.chainB.GetContext(), channel.Ordering, channel.ConnectionHops, + path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, path.EndpointA.ChannelConfig.Version, + ) - if tc.expPass { - suite.Require().NoError(err) + if tc.expPass { + suite.Require().NoError(err) - addr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, counterparty.PortId) - suite.Require().True(exists) - suite.Require().NotNil(addr) - } else { - suite.Require().Error(err) - suite.Require().Equal("", version) - } - }) + addr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, counterparty.PortId) + suite.Require().True(exists) + suite.Require().NotNil(addr) + } else { + suite.Require().Error(err) + suite.Require().Equal("", version) + } + }) + } } } // Test initiating a ChanOpenAck using the host chain instead of the controller chain // ChainA is the controller chain. ChainB is the host chain func (suite *InterchainAccountsTestSuite) TestChanOpenAck() { - suite.SetupTest() // reset - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - // chainA maliciously sets channel to TRYOPEN - channel := channeltypes.NewChannel(channeltypes.TRYOPEN, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, TestVersion) - suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) + // chainA maliciously sets channel to TRYOPEN + channel := channeltypes.NewChannel(channeltypes.TRYOPEN, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, TestVersion) + suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) - // commit state changes so proof can be created - suite.chainA.NextBlock() + // commit state changes so proof can be created + suite.chainA.NextBlock() - err = path.EndpointB.UpdateClient() - suite.Require().NoError(err) + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) - // query proof from ChainA - channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - tryProof, proofHeight := path.EndpointA.Chain.QueryProof(channelKey) + // query proof from ChainA + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + tryProof, proofHeight := path.EndpointA.Chain.QueryProof(channelKey) - // use chainB (host) for ChanOpenAck - msg := channeltypes.NewMsgChannelOpenAck(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelID, TestVersion, tryProof, proofHeight, icatypes.ModuleName) - handler := suite.chainB.GetSimApp().MsgServiceRouter().Handler(msg) - _, err = handler(suite.chainB.GetContext(), msg) + // use chainB (host) for ChanOpenAck + msg := channeltypes.NewMsgChannelOpenAck(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelID, TestVersion, tryProof, proofHeight, icatypes.ModuleName) + handler := suite.chainB.GetSimApp().MsgServiceRouter().Handler(msg) + _, err = handler(suite.chainB.GetContext(), msg) - suite.Require().Error(err) + suite.Require().Error(err) + } } func (suite *InterchainAccountsTestSuite) TestOnChanOpenConfirm() { @@ -293,61 +294,67 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenConfirm() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + suite.Run(tc.name, func() { + suite.SetupTest() + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - err = path.EndpointA.ChanOpenAck() - suite.Require().NoError(err) + err = path.EndpointA.ChanOpenAck() + suite.Require().NoError(err) - tc.malleate() + tc.malleate() - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - err = cbs.OnChanOpenConfirm(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + err = cbs.OnChanOpenConfirm(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } // OnChanCloseInit on host (chainB) func (suite *InterchainAccountsTestSuite) TestOnChanCloseInit() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - err = cbs.OnChanCloseInit( - suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, - ) + cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - suite.Require().Error(err) + err = cbs.OnChanCloseInit( + suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, + ) + + suite.Require().Error(err) + } } func (suite *InterchainAccountsTestSuite) TestOnChanCloseConfirm() { @@ -363,34 +370,36 @@ func (suite *InterchainAccountsTestSuite) TestOnChanCloseConfirm() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + tc.malleate() // malleate mutates test data + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - err = cbs.OnChanCloseConfirm( - suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + err = cbs.OnChanCloseConfirm( + suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -429,106 +438,108 @@ func (suite *InterchainAccountsTestSuite) TestOnRecvPacket() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - // send 100stake to interchain account wallet - amount, _ := sdk.ParseCoinsNormalized("100stake") - interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) - bankMsg := &banktypes.MsgSend{FromAddress: suite.chainB.SenderAccount.GetAddress().String(), ToAddress: interchainAccountAddr, Amount: amount} - - _, err = suite.chainB.SendMsgs(bankMsg) - suite.Require().NoError(err) - - // build packet data - msg := &banktypes.MsgSend{ - FromAddress: interchainAccountAddr, - ToAddress: suite.chainB.SenderAccount.GetAddress().String(), - Amount: amount, - } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}, icatypes.EncodingProtobuf) - suite.Require().NoError(err) - - icaPacketData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: data, - } - packetData = icaPacketData.GetBytes() - - // build expected ack - protoAny, err := codectypes.NewAnyWithValue(&banktypes.MsgSendResponse{}) - suite.Require().NoError(err) - - expectedTxResponse, err := proto.Marshal(&sdk.TxMsgData{ - MsgResponses: []*codectypes.Any{protoAny}, - }) - suite.Require().NoError(err) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - expectedAck := channeltypes.NewResultAcknowledgement(expectedTxResponse) + suite.Run(tc.name, func() { + suite.SetupTest() // reset - params := types.NewParams(true, []string{sdk.MsgTypeURL(msg)}) - suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - // malleate packetData for test cases - tc.malleate() + // send 100stake to interchain account wallet + amount, _ := sdk.ParseCoinsNormalized("100stake") + interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) + bankMsg := &banktypes.MsgSend{FromAddress: suite.chainB.SenderAccount.GetAddress().String(), ToAddress: interchainAccountAddr, Amount: amount} - seq := uint64(1) - packet := channeltypes.NewPacket(packetData, seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) + _, err = suite.chainB.SendMsgs(bankMsg) + suite.Require().NoError(err) - tc.malleate() + // build packet data + msg := &banktypes.MsgSend{ + FromAddress: interchainAccountAddr, + ToAddress: suite.chainB.SenderAccount.GetAddress().String(), + Amount: amount, + } + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}, icatypes.EncodingProtobuf) + suite.Require().NoError(err) + + icaPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + } + packetData = icaPacketData.GetBytes() + + // build expected ack + protoAny, err := codectypes.NewAnyWithValue(&banktypes.MsgSendResponse{}) + suite.Require().NoError(err) + + expectedTxResponse, err := proto.Marshal(&sdk.TxMsgData{ + MsgResponses: []*codectypes.Any{protoAny}, + }) + suite.Require().NoError(err) - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + expectedAck := channeltypes.NewResultAcknowledgement(expectedTxResponse) - cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + params := types.NewParams(true, []string{sdk.MsgTypeURL(msg)}) + suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) - ctx := suite.chainB.GetContext() - ack := cbs.OnRecvPacket(ctx, packet, nil) + // malleate packetData for test cases + tc.malleate() - expectedAttributes := []sdk.Attribute{ - sdk.NewAttribute(sdk.AttributeKeyModule, icatypes.ModuleName), - sdk.NewAttribute(icatypes.AttributeKeyHostChannelID, packet.GetDestChannel()), - sdk.NewAttribute(icatypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success())), - } + seq := uint64(1) + packet := channeltypes.NewPacket(packetData, seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) - if tc.expAckSuccess { - suite.Require().True(ack.Success()) - suite.Require().Equal(expectedAck, ack) + tc.malleate() - expectedEvents := sdk.Events{ - sdk.NewEvent( - icatypes.EventTypePacket, - expectedAttributes..., - ), - }.ToABCIEvents() + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - expectedEvents = sdk.MarkEventsToIndex(expectedEvents, map[string]struct{}{}) - ibctesting.AssertEvents(&suite.Suite, expectedEvents, ctx.EventManager().Events().ToABCIEvents()) + cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - } else { - suite.Require().False(ack.Success()) + ctx := suite.chainB.GetContext() + ack := cbs.OnRecvPacket(ctx, packet, nil) - expectedAttributes = append(expectedAttributes, sdk.NewAttribute(icatypes.AttributeKeyAckError, tc.eventErrorMsg)) - expectedEvents := sdk.Events{ - sdk.NewEvent( - icatypes.EventTypePacket, - expectedAttributes..., - ), - }.ToABCIEvents() + expectedAttributes := []sdk.Attribute{ + sdk.NewAttribute(sdk.AttributeKeyModule, icatypes.ModuleName), + sdk.NewAttribute(icatypes.AttributeKeyHostChannelID, packet.GetDestChannel()), + sdk.NewAttribute(icatypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success())), + } - expectedEvents = sdk.MarkEventsToIndex(expectedEvents, map[string]struct{}{}) - ibctesting.AssertEvents(&suite.Suite, expectedEvents, ctx.EventManager().Events().ToABCIEvents()) - } - }) + if tc.expAckSuccess { + suite.Require().True(ack.Success()) + suite.Require().Equal(expectedAck, ack) + + expectedEvents := sdk.Events{ + sdk.NewEvent( + icatypes.EventTypePacket, + expectedAttributes..., + ), + }.ToABCIEvents() + + expectedEvents = sdk.MarkEventsToIndex(expectedEvents, map[string]struct{}{}) + ibctesting.AssertEvents(&suite.Suite, expectedEvents, ctx.EventManager().Events().ToABCIEvents()) + + } else { + suite.Require().False(ack.Success()) + + expectedAttributes = append(expectedAttributes, sdk.NewAttribute(icatypes.AttributeKeyAckError, tc.eventErrorMsg)) + expectedEvents := sdk.Events{ + sdk.NewEvent( + icatypes.EventTypePacket, + expectedAttributes..., + ), + }.ToABCIEvents() + + expectedEvents = sdk.MarkEventsToIndex(expectedEvents, map[string]struct{}{}) + ibctesting.AssertEvents(&suite.Suite, expectedEvents, ctx.EventManager().Events().ToABCIEvents()) + } + }) + } } } @@ -543,45 +554,47 @@ func (suite *InterchainAccountsTestSuite) TestOnAcknowledgementPacket() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - tc.malleate() // malleate mutates test data + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + suite.Run(tc.name, func() { + suite.SetupTest() // reset - cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - packet := channeltypes.NewPacket( - []byte("empty packet data"), - suite.chainA.SenderAccount.GetSequence(), - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - clienttypes.NewHeight(0, 100), - 0, - ) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - err = cbs.OnAcknowledgementPacket(suite.chainB.GetContext(), packet, []byte("ackBytes"), nil) + tc.malleate() // malleate mutates test data - if tc.expPass { + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + + cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + + packet := channeltypes.NewPacket( + []byte("empty packet data"), + suite.chainA.SenderAccount.GetSequence(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + clienttypes.NewHeight(0, 100), + 0, + ) + + err = cbs.OnAcknowledgementPacket(suite.chainB.GetContext(), packet, []byte("ackBytes"), nil) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -596,73 +609,79 @@ func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - tc.malleate() // malleate mutates test data + suite.Run(tc.name, func() { + suite.SetupTest() // reset - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - - packet := channeltypes.NewPacket( - []byte("empty packet data"), - suite.chainA.SenderAccount.GetSequence(), - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - clienttypes.NewHeight(0, 100), - 0, - ) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, nil) + tc.malleate() // malleate mutates test data - if tc.expPass { + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointB.ChannelConfig.PortID) suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + + packet := channeltypes.NewPacket( + []byte("empty packet data"), + suite.chainA.SenderAccount.GetSequence(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + clienttypes.NewHeight(0, 100), + 0, + ) + + err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, nil) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } // OnChanUpgradeInit callback returns error on host chains func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeInit() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - // call application callback directly - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - app, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - cbs, ok := app.(porttypes.UpgradableModule) - suite.Require().True(ok) + // call application callback directly + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - version, err := cbs.OnChanUpgradeInit( - suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, - path.EndpointB.ChannelConfig.Order, []string{path.EndpointB.ConnectionID}, path.EndpointB.ChannelConfig.Version, - ) + app, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) - suite.Require().Error(err) - suite.Require().ErrorIs(err, icatypes.ErrInvalidChannelFlow) - suite.Require().Equal("", version) + version, err := cbs.OnChanUpgradeInit( + suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, + path.EndpointB.ChannelConfig.Order, []string{path.EndpointB.ConnectionID}, path.EndpointB.ChannelConfig.Version, + ) + + suite.Require().Error(err) + suite.Require().ErrorIs(err, icatypes.ErrInvalidChannelFlow) + suite.Require().Equal("", version) + } } func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeTry() { @@ -681,81 +700,87 @@ func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeTry() { }, } - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + suite.Run(tc.name, func() { + suite.SetupTest() // reset - interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - metadata := icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) - metadata.Address = interchainAccountAddr - metadata.Encoding = icatypes.EncodingProto3JSON // this is the actual change to the version - path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - - err = path.EndpointA.ChanUpgradeInit() - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + metadata := icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + metadata.Address = interchainAccountAddr + metadata.Encoding = icatypes.EncodingProto3JSON // this is the actual change to the version + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - app, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - cbs, ok := app.(porttypes.UpgradableModule) - suite.Require().True(ok) + err = path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) - version, err := cbs.OnChanUpgradeTry( - suite.chainB.GetContext(), - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - channeltypes.ORDERED, - []string{path.EndpointB.ConnectionID}, - path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version, - ) + tc.malleate() // malleate mutates test data - if tc.expError == nil { + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) suite.Require().NoError(err) - } else { - suite.Require().Error(err) - suite.Require().Empty(version) - } - }) + + app, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + version, err := cbs.OnChanUpgradeTry( + suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + ordering, + []string{path.EndpointB.ConnectionID}, + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version, + ) + + if tc.expError == nil { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + suite.Require().Empty(version) + } + }) + } } } // OnChanUpgradeAck callback returns error on host chains func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeAck() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() - // call application callback directly - module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - app, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) - cbs, ok := app.(porttypes.UpgradableModule) - suite.Require().True(ok) + // call application callback directly + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) - err = cbs.OnChanUpgradeAck( - suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelConfig.Version, - ) + app, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) - suite.Require().Error(err) - suite.Require().ErrorIs(err, icatypes.ErrInvalidChannelFlow) + err = cbs.OnChanUpgradeAck( + suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelConfig.Version, + ) + + suite.Require().Error(err) + suite.Require().ErrorIs(err, icatypes.ErrInvalidChannelFlow) + } } func (suite *InterchainAccountsTestSuite) fundICAWallet(ctx sdk.Context, portID string, amount sdk.Coins) { @@ -776,92 +801,96 @@ func (suite *InterchainAccountsTestSuite) fundICAWallet(ctx sdk.Context, portID // TestControlAccountAfterChannelClose tests that a controller chain can control a registered interchain account after the currently active channel for that interchain account has been closed. // 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, + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + + // 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 + + path.SetupConnections() + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + // two sends will be performed, one after initial creation of the account and one after channel closure and reopening + var ( + startingBal = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000))) + tokenAmt = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(5000))) + expBalAfterFirstSend = startingBal.Sub(tokenAmt...) + expBalAfterSecondSend = expBalAfterFirstSend.Sub(tokenAmt...) + ) + + // check that the account is working as expected + suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, startingBal) + interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + msg := &banktypes.MsgSend{ + FromAddress: interchainAccountAddr, + ToAddress: suite.chainB.SenderAccount.GetAddress().String(), + Amount: tokenAmt, + } + + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}, icatypes.EncodingProtobuf) + suite.Require().NoError(err) + + icaPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + } + + params := types.NewParams(true, []string{sdk.MsgTypeURL(msg)}) + suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) + + //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) + _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) + suite.Require().NoError(err) + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + // relay the packet + packetRelay := channeltypes.NewPacket(icaPacketData.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.ZeroHeight(), ^uint64(0)) + err = path.RelayPacket(packetRelay) + suite.Require().NoError(err) // relay committed + + // check that the ica balance is updated + icaAddr, err := sdk.AccAddressFromBech32(interchainAccountAddr) + suite.Require().NoError(err) + + suite.assertBalance(icaAddr, expBalAfterFirstSend) + + // close the channel + path.EndpointA.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) + path.EndpointB.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) + + // open a new channel on the same port + path.EndpointA.ChannelID = "" + path.EndpointB.ChannelID = "" + path.CreateChannels() + + //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) + _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) + suite.Require().NoError(err) + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + // relay the packet + packetRelay = channeltypes.NewPacket(icaPacketData.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.ZeroHeight(), ^uint64(0)) + err = path.RelayPacket(packetRelay) + suite.Require().NoError(err) // relay committed + + suite.assertBalance(icaAddr, expBalAfterSecondSend) } - - feeICAVersion := string(feetypes.ModuleCdc.MustMarshalJSON(&feeMetadata)) - - path.EndpointA.ChannelConfig.Version = feeICAVersion - path.EndpointB.ChannelConfig.Version = feeICAVersion - - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - // two sends will be performed, one after initial creation of the account and one after channel closure and reopening - var ( - startingBal = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000))) - tokenAmt = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(5000))) - expBalAfterFirstSend = startingBal.Sub(tokenAmt...) - expBalAfterSecondSend = expBalAfterFirstSend.Sub(tokenAmt...) - ) - - // check that the account is working as expected - suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, startingBal) - interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) - - msg := &banktypes.MsgSend{ - FromAddress: interchainAccountAddr, - ToAddress: suite.chainB.SenderAccount.GetAddress().String(), - Amount: tokenAmt, - } - - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}, icatypes.EncodingProtobuf) - suite.Require().NoError(err) - - icaPacketData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: data, - } - - params := types.NewParams(true, []string{sdk.MsgTypeURL(msg)}) - suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) - - //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) - _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) - suite.Require().NoError(err) - err = path.EndpointB.UpdateClient() - suite.Require().NoError(err) - - // relay the packet - packetRelay := channeltypes.NewPacket(icaPacketData.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.ZeroHeight(), ^uint64(0)) - err = path.RelayPacket(packetRelay) - suite.Require().NoError(err) // relay committed - - // check that the ica balance is updated - icaAddr, err := sdk.AccAddressFromBech32(interchainAccountAddr) - suite.Require().NoError(err) - - suite.assertBalance(icaAddr, expBalAfterFirstSend) - - // close the channel - path.EndpointA.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) - path.EndpointB.UpdateChannel(func(channel *channeltypes.Channel) { channel.State = channeltypes.CLOSED }) - - // open a new channel on the same port - path.EndpointA.ChannelID = "" - path.EndpointB.ChannelID = "" - path.CreateChannels() - - //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) - _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) - suite.Require().NoError(err) - err = path.EndpointB.UpdateClient() - suite.Require().NoError(err) - - // relay the packet - packetRelay = channeltypes.NewPacket(icaPacketData.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.ZeroHeight(), ^uint64(0)) - err = path.RelayPacket(packetRelay) - suite.Require().NoError(err) // relay committed - - suite.assertBalance(icaAddr, expBalAfterSecondSend) } // assertBalance asserts that the provided address has exactly the expected balance. @@ -872,26 +901,30 @@ func (suite *InterchainAccountsTestSuite) assertBalance(addr sdk.AccAddress, exp } func (suite *InterchainAccountsTestSuite) TestPacketDataUnmarshalerInterface() { - path := NewICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - expPacketData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: []byte("data"), - Memo: "", + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + expPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: []byte("data"), + Memo: "", + } + + // Context, port identifier and channel identifier are unused for host. + packetData, err := icahost.IBCModule{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", expPacketData.GetBytes()) + suite.Require().NoError(err) + suite.Require().Equal(expPacketData, packetData) + + // test invalid packet data + invalidPacketData := []byte("invalid packet data") + // Context, port identifier and channel identifier are unused for host. + packetData, err = icahost.IBCModule{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", invalidPacketData) + suite.Require().Error(err) + suite.Require().Nil(packetData) } - - // Context, port identifier and channel identifier are unused for host. - packetData, err := icahost.IBCModule{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", expPacketData.GetBytes()) - suite.Require().NoError(err) - suite.Require().Equal(expPacketData, packetData) - - // test invalid packet data - invalidPacketData := []byte("invalid packet data") - // Context, port identifier and channel identifier are unused for host. - packetData, err = icahost.IBCModule{}.UnmarshalPacketData(suite.chainA.GetContext(), "", "", invalidPacketData) - suite.Require().Error(err) - suite.Require().Nil(packetData) } diff --git a/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go b/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go index 642288fed3f..5bb0f58d046 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/keeper" "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -112,27 +113,29 @@ func (suite *KeeperTestSuite) TestGenesisParams() { } func (suite *KeeperTestSuite) TestExportGenesis() { - suite.SetupTest() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(exists) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) - genesisState := keeper.ExportGenesis(suite.chainB.GetContext(), suite.chainB.GetSimApp().ICAHostKeeper) + genesisState := keeper.ExportGenesis(suite.chainB.GetContext(), suite.chainB.GetSimApp().ICAHostKeeper) - suite.Require().Equal(path.EndpointB.ChannelID, genesisState.ActiveChannels[0].ChannelId) - suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.ActiveChannels[0].PortId) + suite.Require().Equal(path.EndpointB.ChannelID, genesisState.ActiveChannels[0].ChannelId) + suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.ActiveChannels[0].PortId) - suite.Require().Equal(interchainAccAddr, genesisState.InterchainAccounts[0].AccountAddress) - suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.InterchainAccounts[0].PortId) + suite.Require().Equal(interchainAccAddr, genesisState.InterchainAccounts[0].AccountAddress) + suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.InterchainAccounts[0].PortId) - suite.Require().Equal(icatypes.HostPortID, genesisState.GetPort()) + suite.Require().Equal(icatypes.HostPortID, genesisState.GetPort()) - expParams := types.DefaultParams() - suite.Require().Equal(expParams, genesisState.GetParams()) + expParams := types.DefaultParams() + suite.Require().Equal(expParams, genesisState.GetParams()) + } } diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index 46c653c8dc0..0b16fb39ea6 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -20,7 +20,7 @@ const ( ) // open and close channel is a helper function for TestOnChanOpenTry for reopening accounts -func (suite *KeeperTestSuite) openAndCloseChannel(path *ibctesting.Path) { +func (suite *KeeperTestSuite) openAndCloseChannel(path *ibctesting.Path, ordering channeltypes.Order) { err := path.EndpointB.ChanOpenTry() suite.Require().NoError(err) @@ -43,318 +43,320 @@ func (suite *KeeperTestSuite) openAndCloseChannel(path *ibctesting.Path) { } func (suite *KeeperTestSuite) TestOnChanOpenTry() { - var ( - channel *channeltypes.Channel - path *ibctesting.Path - chanCap *capabilitytypes.Capability - metadata icatypes.Metadata - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "success", - func() {}, - true, - }, - { - "success - reopening closed active channel", - func() { - // create interchain account - // undo setup - path.EndpointB.ChannelID = "" - err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) - suite.Require().NoError(err) - - suite.openAndCloseChannel(path) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + var ( + channel *channeltypes.Channel + path *ibctesting.Path + chanCap *capabilitytypes.Capability + metadata icatypes.Metadata + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, }, - true, - }, - { - "success - reopening account with new address", - func() { - // create interchain account - // undo setup - path.EndpointB.ChannelID = "" - err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) - suite.Require().NoError(err) - - suite.openAndCloseChannel(path) - - // delete interchain account address - store := suite.chainB.GetContext().KVStore(suite.chainB.GetSimApp().GetKey(hosttypes.SubModuleName)) - store.Delete(icatypes.KeyOwnerAccount(path.EndpointA.ChannelConfig.PortID, path.EndpointB.ConnectionID)) - - // assert interchain account address mapping was deleted - _, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().False(found) + { + "success - reopening closed active channel", + func() { + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) + + suite.openAndCloseChannel(path, ordering) + }, + true, }, - true, - }, - { - "success - empty host connection ID", - func() { - metadata.HostConnectionId = "" - - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) - - path.EndpointA.ChannelConfig.Version = string(versionBytes) + { + "success - reopening account with new address", + func() { + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) + + suite.openAndCloseChannel(path, ordering) + + // delete interchain account address + store := suite.chainB.GetContext().KVStore(suite.chainB.GetSimApp().GetKey(hosttypes.SubModuleName)) + store.Delete(icatypes.KeyOwnerAccount(path.EndpointA.ChannelConfig.PortID, path.EndpointB.ConnectionID)) + + // assert interchain account address mapping was deleted + _, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().False(found) + }, + true, }, - true, - }, - { - "success - previous metadata is different", - func() { - // set the active channelID in state - suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) + { + "success - empty host connection ID", + func() { + metadata.HostConnectionId = "" - // set the previous encoding to be proto3json. - // the new encoding is set to be protobuf in the test below. - metadata.Encoding = icatypes.EncodingProto3JSON - - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - channel.State = channeltypes.CLOSED - channel.Version = string(versionBytes) - - path.EndpointB.SetChannel(*channel) - }, true, - }, - { - "reopening account fails - no existing account", - func() { - // create interchain account - // undo setup - path.EndpointB.ChannelID = "" - err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) - suite.Require().NoError(err) - - suite.openAndCloseChannel(path) - - // delete existing account - addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) - - acc := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), sdk.MustAccAddressFromBech32(addr)) - suite.chainB.GetSimApp().AccountKeeper.RemoveAccount(suite.chainB.GetContext(), acc) + path.EndpointA.ChannelConfig.Version = string(versionBytes) + }, + true, }, - false, - }, - { - "reopening account fails - existing account is not interchain account type", - func() { - // create interchain account - // undo setup - path.EndpointB.ChannelID = "" - err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) - suite.Require().NoError(err) - - suite.openAndCloseChannel(path) + { + "success - previous metadata is different", + func() { + // set the active channelID in state + suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) - addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + // set the previous encoding to be proto3json. + // the new encoding is set to be protobuf in the test below. + metadata.Encoding = icatypes.EncodingProto3JSON - accAddress := sdk.MustAccAddressFromBech32(addr) - acc := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), accAddress) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - icaAcc, ok := acc.(*icatypes.InterchainAccount) - suite.Require().True(ok) + channel.State = channeltypes.CLOSED + channel.Version = string(versionBytes) - // overwrite existing account with only base account type, not intercahin account type - suite.chainB.GetSimApp().AccountKeeper.SetAccount(suite.chainB.GetContext(), icaAcc.BaseAccount) + path.EndpointB.SetChannel(*channel) + }, true, }, - false, - }, - { - "account already exists", - func() { - interchainAccAddr := icatypes.GenerateAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - err := suite.chainB.GetSimApp().BankKeeper.SendCoins(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), interchainAccAddr, sdk.Coins{sdk.NewCoin("stake", sdkmath.NewInt(1))}) - suite.Require().NoError(err) - suite.Require().True(suite.chainB.GetSimApp().AccountKeeper.HasAccount(suite.chainB.GetContext(), interchainAccAddr)) + { + "reopening account fails - no existing account", + func() { + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) + + suite.openAndCloseChannel(path, ordering) + + // delete existing account + addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + acc := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), sdk.MustAccAddressFromBech32(addr)) + suite.chainB.GetSimApp().AccountKeeper.RemoveAccount(suite.chainB.GetContext(), acc) + }, + false, }, - false, - }, - { - "invalid port ID", - func() { - path.EndpointB.ChannelConfig.PortID = "invalid-port-id" //nolint:goconst + { + "reopening account fails - existing account is not interchain account type", + func() { + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) + + suite.openAndCloseChannel(path, ordering) + + addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + accAddress := sdk.MustAccAddressFromBech32(addr) + acc := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), accAddress) + + icaAcc, ok := acc.(*icatypes.InterchainAccount) + suite.Require().True(ok) + + // overwrite existing account with only base account type, not intercahin account type + suite.chainB.GetSimApp().AccountKeeper.SetAccount(suite.chainB.GetContext(), icaAcc.BaseAccount) + }, + false, }, - false, - }, - { - "connection not found", - func() { - channel.ConnectionHops = []string{"invalid-connnection-id"} - path.EndpointB.SetChannel(*channel) + { + "account already exists", + func() { + interchainAccAddr := icatypes.GenerateAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + err := suite.chainB.GetSimApp().BankKeeper.SendCoins(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), interchainAccAddr, sdk.Coins{sdk.NewCoin("stake", sdkmath.NewInt(1))}) + suite.Require().NoError(err) + suite.Require().True(suite.chainB.GetSimApp().AccountKeeper.HasAccount(suite.chainB.GetContext(), interchainAccAddr)) + }, + false, }, - false, - }, - { - "invalid metadata bytestring", - func() { - // the try step will propose a new valid version - path.EndpointA.ChannelConfig.Version = "invalid-metadata-bytestring" + { + "invalid port ID", + func() { + path.EndpointB.ChannelConfig.PortID = "invalid-port-id" //nolint:goconst + }, + false, }, - true, - }, - { - "unsupported encoding format", - func() { - metadata.Encoding = "invalid-encoding-format" + { + "connection not found", + func() { + channel.ConnectionHops = []string{"invalid-connnection-id"} + path.EndpointB.SetChannel(*channel) + }, + false, + }, + { + "invalid metadata bytestring", + func() { + // the try step will propose a new valid version + path.EndpointA.ChannelConfig.Version = "invalid-metadata-bytestring" + }, + true, + }, + { + "unsupported encoding format", + func() { + metadata.Encoding = "invalid-encoding-format" - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - path.EndpointA.ChannelConfig.Version = string(versionBytes) + path.EndpointA.ChannelConfig.Version = string(versionBytes) + }, + false, }, - false, - }, - { - "unsupported transaction type", - func() { - metadata.TxType = "invalid-tx-types" + { + "unsupported transaction type", + func() { + metadata.TxType = "invalid-tx-types" - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - path.EndpointA.ChannelConfig.Version = string(versionBytes) + path.EndpointA.ChannelConfig.Version = string(versionBytes) + }, + false, }, - false, - }, - { - "invalid controller connection ID", - func() { - metadata.ControllerConnectionId = "invalid-connnection-id" + { + "invalid controller connection ID", + func() { + metadata.ControllerConnectionId = "invalid-connnection-id" - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - path.EndpointA.ChannelConfig.Version = string(versionBytes) + path.EndpointA.ChannelConfig.Version = string(versionBytes) + }, + false, }, - false, - }, - { - "invalid counterparty version", - func() { - metadata.Version = "invalid-version" + { + "invalid counterparty version", + func() { + metadata.Version = "invalid-version" - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - path.EndpointA.ChannelConfig.Version = string(versionBytes) + path.EndpointA.ChannelConfig.Version = string(versionBytes) + }, + false, }, - false, - }, - { - "capability already claimed", - func() { - path.EndpointB.SetChannel(*channel) - err := suite.chainB.GetSimApp().ScopedICAHostKeeper.ClaimCapability(suite.chainB.GetContext(), chanCap, host.ChannelCapabilityPath(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) - suite.Require().NoError(err) + { + "capability already claimed", + func() { + path.EndpointB.SetChannel(*channel) + err := suite.chainB.GetSimApp().ScopedICAHostKeeper.ClaimCapability(suite.chainB.GetContext(), chanCap, host.ChannelCapabilityPath(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) + suite.Require().NoError(err) + }, + false, }, - false, - }, - { - "active channel already set (OPEN state)", - func() { - // create a new channel and set it in state - ch := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointA.ConnectionID}, ibctesting.DefaultChannelVersion) - suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, ch) - - // set the active channelID in state - suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) + { + "active channel already set (OPEN state)", + func() { + // create a new channel and set it in state + ch := channeltypes.NewChannel(channeltypes.OPEN, ordering, channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointA.ConnectionID}, ibctesting.DefaultChannelVersion) + suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, ch) + + // set the active channelID in state + suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) + }, + false, }, - false, - }, - { - "channel is already active (FLUSHING state)", - func() { - suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) - - counterparty := channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - channel := channeltypes.Channel{ - State: channeltypes.FLUSHING, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointB.ConnectionID}, - Version: TestVersion, - } - suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, channel) + { + "channel is already active (FLUSHING state)", + func() { + suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) + + counterparty := channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + channel := channeltypes.Channel{ + State: channeltypes.FLUSHING, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointB.ConnectionID}, + Version: TestVersion, + } + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, channel) + }, + false, }, - false, - }, - } + } - for _, tc := range testCases { - tc := tc + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - // set the channel id on host - channelSequence := path.EndpointB.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(path.EndpointB.Chain.GetContext()) - path.EndpointB.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) + // set the channel id on host + channelSequence := path.EndpointB.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(path.EndpointB.Chain.GetContext()) + path.EndpointB.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) - // default values - metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, "", icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) + // default values + metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, "", icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) - expectedMetadata := metadata + expectedMetadata := metadata - counterparty := channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - channel = &channeltypes.Channel{ - State: channeltypes.TRYOPEN, - Ordering: channeltypes.ORDERED, - Counterparty: counterparty, - ConnectionHops: []string{path.EndpointB.ConnectionID}, - Version: string(versionBytes), - } + counterparty := channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + channel = &channeltypes.Channel{ + State: channeltypes.TRYOPEN, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{path.EndpointB.ConnectionID}, + Version: string(versionBytes), + } - chanCap, err = suite.chainB.App.GetScopedIBCKeeper().NewCapability(suite.chainB.GetContext(), host.ChannelCapabilityPath(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) - suite.Require().NoError(err) + chanCap, err = suite.chainB.App.GetScopedIBCKeeper().NewCapability(suite.chainB.GetContext(), host.ChannelCapabilityPath(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - version, err := suite.chainB.GetSimApp().ICAHostKeeper.OnChanOpenTry(suite.chainB.GetContext(), channel.Ordering, channel.ConnectionHops, - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, path.EndpointA.ChannelConfig.Version, - ) + version, err := suite.chainB.GetSimApp().ICAHostKeeper.OnChanOpenTry(suite.chainB.GetContext(), channel.Ordering, channel.ConnectionHops, + path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, path.EndpointA.ChannelConfig.Version, + ) - if tc.expPass { - suite.Require().NoError(err) + if tc.expPass { + suite.Require().NoError(err) - storedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + storedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - interchainAccAddr, err := sdk.AccAddressFromBech32(storedAddr) - suite.Require().NoError(err) + interchainAccAddr, err := sdk.AccAddressFromBech32(storedAddr) + suite.Require().NoError(err) - // Check if account is created - interchainAccount := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), interchainAccAddr) - suite.Require().Equal(interchainAccount.GetAddress().String(), storedAddr) + // Check if account is created + interchainAccount := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), interchainAccAddr) + suite.Require().Equal(interchainAccount.GetAddress().String(), storedAddr) - expectedMetadata.Address = storedAddr - expectedVersionBytes, err := icatypes.ModuleCdc.MarshalJSON(&expectedMetadata) - suite.Require().NoError(err) + expectedMetadata.Address = storedAddr + expectedVersionBytes, err := icatypes.ModuleCdc.MarshalJSON(&expectedMetadata) + suite.Require().NoError(err) - suite.Require().Equal(string(expectedVersionBytes), version) - } else { - suite.Require().Error(err) - suite.Require().Equal("", version) - } - }) + suite.Require().Equal(string(expectedVersionBytes), version) + } else { + suite.Require().Error(err) + suite.Require().Equal("", version) + } + }) + } } } @@ -379,35 +381,37 @@ func (suite *KeeperTestSuite) TestOnChanOpenConfirm() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() - err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) - suite.Require().NoError(err) + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - err = path.EndpointA.ChanOpenAck() - suite.Require().NoError(err) + err = path.EndpointA.ChanOpenAck() + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - err = suite.chainB.GetSimApp().ICAHostKeeper.OnChanOpenConfirm(suite.chainB.GetContext(), - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + err = suite.chainB.GetSimApp().ICAHostKeeper.OnChanOpenConfirm(suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -424,27 +428,29 @@ func (suite *KeeperTestSuite) TestOnChanCloseConfirm() { }, } - for _, tc := range testCases { - suite.Run(tc.name, func() { - suite.SetupTest() // reset + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + tc.malleate() // malleate mutates test data - err = suite.chainB.GetSimApp().ICAHostKeeper.OnChanCloseConfirm(suite.chainB.GetContext(), - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + err = suite.chainB.GetSimApp().ICAHostKeeper.OnChanCloseConfirm(suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } @@ -572,54 +578,56 @@ func (suite *KeeperTestSuite) TestOnChanUpgradeTry() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - suite.SetupTest() // reset + suite.Run(tc.name, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - currentMetadata, err := suite.chainB.GetSimApp().ICAHostKeeper.GetAppMetadata(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - suite.Require().NoError(err) - - order = channeltypes.ORDERED - metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) - // use the same address as the previous metadata. - metadata.Address = currentMetadata.Address - // this is the actual change to the version. - metadata.Encoding = icatypes.EncodingProto3JSON - - path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - - err = path.EndpointA.ChanUpgradeInit() - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - counterpartyVersion = path.EndpointA.GetChannel().Version + currentMetadata, err := suite.chainB.GetSimApp().ICAHostKeeper.GetAppMetadata(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().NoError(err) - tc.malleate() // malleate mutates test data + order = channeltypes.ORDERED + metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + // use the same address as the previous metadata. + metadata.Address = currentMetadata.Address + // this is the actual change to the version. + metadata.Encoding = icatypes.EncodingProto3JSON - version, err := suite.chainB.GetSimApp().ICAHostKeeper.OnChanUpgradeTry( - suite.chainB.GetContext(), - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - order, - []string{path.EndpointB.ConnectionID}, - counterpartyVersion, - ) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) - expPass := tc.expError == nil - if expPass { + err = path.EndpointA.ChanUpgradeInit() suite.Require().NoError(err) - suite.Require().Equal(path.EndpointB.GetChannel().Version, version) - } else { - suite.Require().ErrorIs(err, tc.expError) - } - }) + + counterpartyVersion = path.EndpointA.GetChannel().Version + + tc.malleate() // malleate mutates test data + + version, err := suite.chainB.GetSimApp().ICAHostKeeper.OnChanUpgradeTry( + suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + order, + []string{path.EndpointB.ConnectionID}, + counterpartyVersion, + ) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(path.EndpointB.GetChannel().Version, version) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } } } diff --git a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go index cde36a00966..9d947129dc8 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go @@ -63,7 +63,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(3)) } -func NewICAPath(chainA, chainB *ibctesting.TestChain, encoding string) *ibctesting.Path { +func NewICAPath(chainA, chainB *ibctesting.TestChain, encoding string, ordering channeltypes.Order) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) var version string @@ -78,8 +78,8 @@ func NewICAPath(chainA, chainB *ibctesting.TestChain, encoding string) *ibctesti path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID - path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED + path.EndpointA.ChannelConfig.Order = ordering + path.EndpointB.ChannelConfig.Order = ordering path.EndpointA.ChannelConfig.Version = version path.EndpointB.ChannelConfig.Version = version @@ -112,7 +112,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, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, endpoint.ChannelConfig.Order); err != nil { return err } @@ -227,107 +227,115 @@ func (suite *KeeperTestSuite) TestNewModuleQuerySafeAllowList() { } func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() { - suite.SetupTest() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - counterpartyPortID := path.EndpointA.ChannelConfig.PortID + counterpartyPortID := path.EndpointA.ChannelConfig.PortID - retrievedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, counterpartyPortID) - suite.Require().True(found) - suite.Require().NotEmpty(retrievedAddr) + retrievedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, counterpartyPortID) + suite.Require().True(found) + suite.Require().NotEmpty(retrievedAddr) - retrievedAddr, found = suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, "invalid port") - suite.Require().False(found) - suite.Require().Empty(retrievedAddr) + retrievedAddr, found = suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, "invalid port") + suite.Require().False(found) + suite.Require().Empty(retrievedAddr) + } } func (suite *KeeperTestSuite) TestGetAllActiveChannels() { - var ( - expectedChannelID = "test-channel" - expectedPortID = "test-port" - ) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + var ( + expectedChannelID = "test-channel" + expectedPortID = "test-port" + ) - suite.SetupTest() + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedChannelID) - - expectedChannels := []genesistypes.ActiveChannel{ - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: path.EndpointA.ChannelConfig.PortID, - ChannelId: path.EndpointB.ChannelID, - }, - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: expectedPortID, - ChannelId: expectedChannelID, - }, + path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedChannelID) + + expectedChannels := []genesistypes.ActiveChannel{ + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: path.EndpointA.ChannelConfig.PortID, + ChannelId: path.EndpointB.ChannelID, + }, + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: expectedPortID, + ChannelId: expectedChannelID, + }, + } + + activeChannels := suite.chainB.GetSimApp().ICAHostKeeper.GetAllActiveChannels(suite.chainB.GetContext()) + suite.Require().Len(activeChannels, len(expectedChannels)) + suite.Require().Equal(expectedChannels, activeChannels) } - - activeChannels := suite.chainB.GetSimApp().ICAHostKeeper.GetAllActiveChannels(suite.chainB.GetContext()) - suite.Require().Len(activeChannels, len(expectedChannels)) - suite.Require().Equal(expectedChannels, activeChannels) } func (suite *KeeperTestSuite) TestGetAllInterchainAccounts() { - var ( - expectedAccAddr = "test-acc-addr" - expectedPortID = "test-port" - ) - - suite.SetupTest() - - path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(exists) + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + var ( + expectedAccAddr = "test-acc-addr" + expectedPortID = "test-port" + ) - suite.chainB.GetSimApp().ICAHostKeeper.SetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) + suite.SetupTest() - expectedAccounts := []genesistypes.RegisteredInterchainAccount{ - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: TestPortID, - AccountAddress: interchainAccAddr, - }, - { - ConnectionId: ibctesting.FirstConnectionID, - PortId: expectedPortID, - AccountAddress: expectedAccAddr, - }, + path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + + suite.chainB.GetSimApp().ICAHostKeeper.SetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) + + expectedAccounts := []genesistypes.RegisteredInterchainAccount{ + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: TestPortID, + AccountAddress: interchainAccAddr, + }, + { + ConnectionId: ibctesting.FirstConnectionID, + PortId: expectedPortID, + AccountAddress: expectedAccAddr, + }, + } + + interchainAccounts := suite.chainB.GetSimApp().ICAHostKeeper.GetAllInterchainAccounts(suite.chainB.GetContext()) + suite.Require().Len(interchainAccounts, len(expectedAccounts)) + suite.Require().Equal(expectedAccounts, interchainAccounts) } - - interchainAccounts := suite.chainB.GetSimApp().ICAHostKeeper.GetAllInterchainAccounts(suite.chainB.GetContext()) - suite.Require().Len(interchainAccounts, len(expectedAccounts)) - suite.Require().Equal(expectedAccounts, interchainAccounts) } func (suite *KeeperTestSuite) TestIsActiveChannel() { - suite.SetupTest() + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() - path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) - path.SetupConnections() + path := NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - isActive := suite.chainB.GetSimApp().ICAHostKeeper.IsActiveChannel(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(isActive) + isActive := suite.chainB.GetSimApp().ICAHostKeeper.IsActiveChannel(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(isActive) + } } func (suite *KeeperTestSuite) TestSetInterchainAccountAddress() { diff --git a/modules/apps/27-interchain-accounts/host/keeper/relay_test.go b/modules/apps/27-interchain-accounts/host/keeper/relay_test.go index f49e623e939..28c71b36d73 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/relay_test.go @@ -25,7 +25,9 @@ import ( ) func (suite *KeeperTestSuite) TestOnRecvPacket() { + testedOrderings := []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} testedEncodings := []string{icatypes.EncodingProtobuf, icatypes.EncodingProto3JSON} + var ( path *ibctesting.Path packetData []byte @@ -523,59 +525,61 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { }, } - for _, encoding := range testedEncodings { - for _, tc := range testCases { - tc := tc - - suite.Run(tc.msg, func() { - suite.SetupTest() // reset - - path = NewICAPath(suite.chainA, suite.chainB, encoding) - path.SetupConnections() - - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - suite.Require().NoError(err) - - // Get the address of the interchain account stored in state during handshake step - storedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, portID) - suite.Require().True(found) + for _, ordering := range testedOrderings { + for _, encoding := range testedEncodings { + for _, tc := range testCases { + tc := tc - icaAddr, err := sdk.AccAddressFromBech32(storedAddr) - suite.Require().NoError(err) + suite.Run(tc.msg, func() { + suite.SetupTest() // reset - // Check if account is created - interchainAccount := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), icaAddr) - suite.Require().Equal(interchainAccount.GetAddress().String(), storedAddr) + path = NewICAPath(suite.chainA, suite.chainB, encoding, ordering) + path.SetupConnections() - suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(1000000)))) - - tc.malleate(encoding) // malleate mutates test data + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - packet := channeltypes.NewPacket( - packetData, - suite.chainA.SenderAccount.GetSequence(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - suite.chainB.GetTimeoutHeight(), - 0, - ) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + suite.Require().NoError(err) - txResponse, err := suite.chainB.GetSimApp().ICAHostKeeper.OnRecvPacket(suite.chainB.GetContext(), packet) + // Get the address of the interchain account stored in state during handshake step + storedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, portID) + suite.Require().True(found) - expPass := tc.expErr == nil - if expPass { + icaAddr, err := sdk.AccAddressFromBech32(storedAddr) suite.Require().NoError(err) - suite.Require().NotNil(txResponse) - } else { - suite.Require().ErrorIs(err, tc.expErr) - suite.Require().Nil(txResponse) - } - }) + + // Check if account is created + interchainAccount := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), icaAddr) + suite.Require().Equal(interchainAccount.GetAddress().String(), storedAddr) + + suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(1000000)))) + + tc.malleate(encoding) // malleate mutates test data + + packet := channeltypes.NewPacket( + packetData, + suite.chainA.SenderAccount.GetSequence(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + suite.chainB.GetTimeoutHeight(), + 0, + ) + + txResponse, err := suite.chainB.GetSimApp().ICAHostKeeper.OnRecvPacket(suite.chainB.GetContext(), packet) + + expPass := tc.expErr == nil + if expPass { + suite.Require().NoError(err) + suite.Require().NotNil(txResponse) + } else { + suite.Require().ErrorIs(err, tc.expErr) + suite.Require().Nil(txResponse) + } + }) + } } } } @@ -874,51 +878,53 @@ func (suite *KeeperTestSuite) TestJSONOnRecvPacket() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.msg, func() { - suite.SetupTest() // reset + suite.Run(tc.msg, func() { + suite.SetupTest() // reset - path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProto3JSON) - path.SetupConnections() + path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProto3JSON, ordering) + path.SetupConnections() - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) - portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - suite.Require().NoError(err) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + suite.Require().NoError(err) - // Get the address of the interchain account stored in state during handshake step - icaAddress, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, portID) - suite.Require().True(found) + // Get the address of the interchain account stored in state during handshake step + icaAddress, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, portID) + suite.Require().True(found) - suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000000)))) + suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000000)))) - tc.malleate(icaAddress) // malleate mutates test data + tc.malleate(icaAddress) // malleate mutates test data - packet := channeltypes.NewPacket( - packetData, - suite.chainA.SenderAccount.GetSequence(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ChannelID, - path.EndpointB.ChannelConfig.PortID, - path.EndpointB.ChannelID, - suite.chainB.GetTimeoutHeight(), - 0, - ) + packet := channeltypes.NewPacket( + packetData, + suite.chainA.SenderAccount.GetSequence(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + suite.chainB.GetTimeoutHeight(), + 0, + ) - txResponse, err := suite.chainB.GetSimApp().ICAHostKeeper.OnRecvPacket(suite.chainB.GetContext(), packet) + txResponse, err := suite.chainB.GetSimApp().ICAHostKeeper.OnRecvPacket(suite.chainB.GetContext(), packet) - expPass := tc.expErr == nil - if expPass { - suite.Require().NoError(err) - suite.Require().NotNil(txResponse) - } else { - suite.Require().ErrorIs(err, tc.expErr) - suite.Require().Nil(txResponse) - } - }) + expPass := tc.expErr == nil + if expPass { + suite.Require().NoError(err) + suite.Require().NotNil(txResponse) + } else { + suite.Require().ErrorIs(err, tc.expErr) + suite.Require().Nil(txResponse) + } + }) + } } } diff --git a/modules/apps/29-fee/ibc_middleware_test.go b/modules/apps/29-fee/ibc_middleware_test.go index dc59f277d3f..b0a4a7301a9 100644 --- a/modules/apps/29-fee/ibc_middleware_test.go +++ b/modules/apps/29-fee/ibc_middleware_test.go @@ -73,70 +73,72 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - // reset suite - suite.SetupTest() - suite.path.SetupConnections() + suite.Run(tc.name, func() { + // reset suite + suite.SetupTest() + suite.path.SetupConnections() - // setup mock callback - suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanOpenInit = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, - portID, channelID string, chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, version string, - ) (string, error) { - if version != ibcmock.Version { - return "", fmt.Errorf("incorrect mock version") + // setup mock callback + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanOpenInit = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, + portID, channelID string, chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, version string, + ) (string, error) { + if version != ibcmock.Version { + return "", fmt.Errorf("incorrect mock version") + } + return ibcmock.Version, nil } - return ibcmock.Version, nil - } - suite.path.EndpointA.ChannelID = ibctesting.FirstChannelID + suite.path.EndpointA.ChannelID = ibctesting.FirstChannelID - counterparty := channeltypes.NewCounterparty(suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID) - channel := &channeltypes.Channel{ - State: channeltypes.INIT, - Ordering: channeltypes.UNORDERED, - Counterparty: counterparty, - ConnectionHops: []string{suite.path.EndpointA.ConnectionID}, - Version: tc.version, - } + counterparty := channeltypes.NewCounterparty(suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID) + channel := &channeltypes.Channel{ + State: channeltypes.INIT, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{suite.path.EndpointA.ConnectionID}, + Version: tc.version, + } - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.MockFeePort) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.MockFeePort) + suite.Require().NoError(err) - chanCap, err := suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)) - suite.Require().NoError(err) + chanCap, err := suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, chanCap, counterparty, channel.Version) + version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, chanCap, counterparty, channel.Version) - if tc.expPass { - // check if the channel is fee enabled. If so version string should include metaData - if tc.isFeeEnabled { - versionMetadata := types.Metadata{ - FeeVersion: types.Version, - AppVersion: ibcmock.Version, - } + if tc.expPass { + // check if the channel is fee enabled. If so version string should include metaData + if tc.isFeeEnabled { + versionMetadata := types.Metadata{ + FeeVersion: types.Version, + AppVersion: ibcmock.Version, + } - versionBytes, err := types.ModuleCdc.MarshalJSON(&versionMetadata) - suite.Require().NoError(err) + versionBytes, err := types.ModuleCdc.MarshalJSON(&versionMetadata) + suite.Require().NoError(err) + + suite.Require().Equal(version, string(versionBytes)) + } else { + suite.Require().Equal(ibcmock.Version, version) + } - suite.Require().Equal(version, string(versionBytes)) + suite.Require().NoError(err, "unexpected error from version: %s", tc.version) } else { - suite.Require().Equal(ibcmock.Version, version) + suite.Require().Error(err, "error not returned for version: %s", tc.version) + suite.Require().Equal("", version) } - - suite.Require().NoError(err, "unexpected error from version: %s", tc.version) - } else { - suite.Require().Error(err, "error not returned for version: %s", tc.version) - suite.Require().Equal("", version) - } - }) + }) + } } } @@ -169,61 +171,63 @@ func (suite *FeeTestSuite) TestOnChanOpenTry() { }, } - for _, tc := range testCases { - tc := tc + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + for _, tc := range testCases { + tc := tc - suite.Run(tc.name, func() { - // reset suite - suite.SetupTest() - suite.path.SetupConnections() - err := suite.path.EndpointB.ChanOpenInit() - suite.Require().NoError(err) + suite.Run(tc.name, func() { + // reset suite + suite.SetupTest() + suite.path.SetupConnections() + err := suite.path.EndpointB.ChanOpenInit() + suite.Require().NoError(err) - // setup mock callback - suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanOpenTry = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, - portID, channelID string, chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, counterpartyVersion string, - ) (string, error) { - if counterpartyVersion != ibcmock.Version { - return "", fmt.Errorf("incorrect mock version") + // setup mock callback + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanOpenTry = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, + portID, channelID string, chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, counterpartyVersion string, + ) (string, error) { + if counterpartyVersion != ibcmock.Version { + return "", fmt.Errorf("incorrect mock version") + } + return ibcmock.Version, nil } - return ibcmock.Version, nil - } - var ( - chanCap *capabilitytypes.Capability - ok bool - ) + var ( + chanCap *capabilitytypes.Capability + ok bool + ) - chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)) - suite.Require().NoError(err) + chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)) + suite.Require().NoError(err) - suite.path.EndpointA.ChannelID = ibctesting.FirstChannelID + suite.path.EndpointA.ChannelID = ibctesting.FirstChannelID - counterparty := channeltypes.NewCounterparty(suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID) - channel := &channeltypes.Channel{ - State: channeltypes.INIT, - Ordering: channeltypes.UNORDERED, - Counterparty: counterparty, - ConnectionHops: []string{suite.path.EndpointA.ConnectionID}, - Version: tc.cpVersion, - } + counterparty := channeltypes.NewCounterparty(suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID) + channel := &channeltypes.Channel{ + State: channeltypes.INIT, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: []string{suite.path.EndpointA.ConnectionID}, + Version: tc.cpVersion, + } - module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.MockFeePort) - suite.Require().NoError(err) + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.MockFeePort) + suite.Require().NoError(err) - cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) - suite.Require().True(ok) + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) - _, err = cbs.OnChanOpenTry(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, chanCap, counterparty, tc.cpVersion) + _, err = cbs.OnChanOpenTry(suite.chainA.GetContext(), channel.Ordering, channel.ConnectionHops, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, chanCap, counterparty, tc.cpVersion) - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } } } diff --git a/modules/apps/29-fee/ica_test.go b/modules/apps/29-fee/ica_test.go index b7c43048593..9cf67aa759a 100644 --- a/modules/apps/29-fee/ica_test.go +++ b/modules/apps/29-fee/ica_test.go @@ -29,7 +29,7 @@ var ( ) // NewIncentivizedICAPath creates and returns a new ibctesting path configured for a fee enabled interchain accounts channel -func NewIncentivizedICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { +func NewIncentivizedICAPath(chainA, chainB *ibctesting.TestChain, ordering channeltypes.Order) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) feeMetadata := types.Metadata{ @@ -39,11 +39,12 @@ func NewIncentivizedICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Pa feeICAVersion := string(types.ModuleCdc.MustMarshalJSON(&feeMetadata)) - path.SetChannelOrdered() path.EndpointA.ChannelConfig.Version = feeICAVersion path.EndpointB.ChannelConfig.Version = feeICAVersion path.EndpointA.ChannelConfig.PortID = defaultPortID path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointA.ChannelConfig.Order = ordering + path.EndpointB.ChannelConfig.Order = ordering return path } @@ -75,7 +76,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, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, endpoint.ChannelConfig.Order); err != nil { return err } @@ -91,119 +92,127 @@ func RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) erro // TestFeeInterchainAccounts Integration test to ensure ics29 works with ics27 func (suite *FeeTestSuite) TestFeeInterchainAccounts() { - path := NewIncentivizedICAPath(suite.chainA, suite.chainB) - path.SetupConnections() - - err := SetupPath(path, defaultOwnerAddress) - suite.Require().NoError(err) - - // assert the newly established channel is fee enabled on both ends - suite.Require().True(suite.chainA.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) - suite.Require().True(suite.chainB.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) - - // register counterparty address on destination chainB as chainA.SenderAccounts[1] for recv fee distribution - suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyPayeeAddress(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccounts[1].SenderAccount.GetAddress().String(), path.EndpointB.ChannelID) - - // escrow a packet fee for the next send sequence - expectedFee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) - msgPayPacketFee := types.NewMsgPayPacketFee(expectedFee, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, suite.chainA.SenderAccount.GetAddress().String(), nil) - - // fetch the account balance before fees are escrowed and assert the difference below - preEscrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) - - res, err := suite.chainA.SendMsgs(msgPayPacketFee) - suite.Require().NotNil(res) - suite.Require().NoError(err) - - postEscrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) - suite.Require().Equal(postEscrowBalance.AddAmount(expectedFee.Total().AmountOf(sdk.DefaultBondDenom)), preEscrowBalance) - - packetID := channeltypes.NewPacketID(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1) - packetFees, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) - suite.Require().True(found) - suite.Require().Equal(expectedFee, packetFees.PacketFees[0].Fee) - - interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) - - // fund the interchain account on chainB - coins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000))) - msgBankSend := &banktypes.MsgSend{ - FromAddress: suite.chainB.SenderAccount.GetAddress().String(), - ToAddress: interchainAccountAddr, - Amount: coins, - } - - res, err = suite.chainB.SendMsgs(msgBankSend) - suite.Require().NotEmpty(res) - suite.Require().NoError(err) - - // prepare a simple stakingtypes.MsgDelegate to be used as the interchain account msg executed on chainB - validatorAddr := (sdk.ValAddress)(suite.chainB.Vals.Validators[0].Address) - msgDelegate := &stakingtypes.MsgDelegate{ - DelegatorAddress: interchainAccountAddr, - ValidatorAddress: validatorAddr.String(), - Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(5000)), - } - - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msgDelegate}, icatypes.EncodingProtobuf) - suite.Require().NoError(err) - - icaPacketData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: data, + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + path := NewIncentivizedICAPath(suite.chainA, suite.chainB, ordering) + path.SetupConnections() + + err := SetupPath(path, defaultOwnerAddress) + suite.Require().NoError(err) + + // assert the newly established channel is fee enabled on both ends + suite.Require().True(suite.chainA.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + suite.Require().True(suite.chainB.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) + + // register counterparty address on destination chainB as chainA.SenderAccounts[1] for recv fee distribution + suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyPayeeAddress(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccounts[1].SenderAccount.GetAddress().String(), path.EndpointB.ChannelID) + + // escrow a packet fee for the next send sequence + expectedFee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) + msgPayPacketFee := types.NewMsgPayPacketFee(expectedFee, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, suite.chainA.SenderAccount.GetAddress().String(), nil) + + // fetch the account balance before fees are escrowed and assert the difference below + preEscrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) + + res, err := suite.chainA.SendMsgs(msgPayPacketFee) + suite.Require().NotNil(res) + suite.Require().NoError(err) + + postEscrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) + suite.Require().Equal(postEscrowBalance.AddAmount(expectedFee.Total().AmountOf(sdk.DefaultBondDenom)), preEscrowBalance) + + packetID := channeltypes.NewPacketID(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1) + packetFees, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) + suite.Require().True(found) + suite.Require().Equal(expectedFee, packetFees.PacketFees[0].Fee) + + interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + // fund the interchain account on chainB + coins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000))) + msgBankSend := &banktypes.MsgSend{ + FromAddress: suite.chainB.SenderAccount.GetAddress().String(), + ToAddress: interchainAccountAddr, + Amount: coins, + } + + res, err = suite.chainB.SendMsgs(msgBankSend) + suite.Require().NotEmpty(res) + suite.Require().NoError(err) + + // prepare a simple stakingtypes.MsgDelegate to be used as the interchain account msg executed on chainB + validatorAddr := (sdk.ValAddress)(suite.chainB.Vals.Validators[0].Address) + msgDelegate := &stakingtypes.MsgDelegate{ + DelegatorAddress: interchainAccountAddr, + ValidatorAddress: validatorAddr.String(), + Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(5000)), + } + + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msgDelegate}, icatypes.EncodingProtobuf) + suite.Require().NoError(err) + + icaPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + } + + // ensure chainB is allowed to execute stakingtypes.MsgDelegate + params := icahosttypes.NewParams(true, []string{sdk.MsgTypeURL(msgDelegate)}) + suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) + + // build the interchain accounts packet + packet := buildInterchainAccountsPacket(path, icaPacketData.GetBytes(), 1) + + // write packet commitment to state on chainA and commit state + commitment := channeltypes.CommitPacket(suite.chainA.GetSimApp().AppCodec(), packet) + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1, commitment) + suite.chainA.NextBlock() + + err = path.RelayPacket(packet) + suite.Require().NoError(err) + + // ensure escrowed fees are cleaned up + packetFees, found = suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) + suite.Require().False(found) + suite.Require().Empty(packetFees) + + // assert the value of the account balance after fee distribution + // NOTE: the balance after fee distribution should be equal to the pre-escrow balance minus the recv fee + // as chainA.SenderAccount is used as the msg signer and refund address for msgPayPacketFee above as well as the relyer account for acknowledgements in path.RelayPacket() + postDistBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) + suite.Require().Equal(preEscrowBalance.SubAmount(defaultRecvFee.AmountOf(sdk.DefaultBondDenom)), postDistBalance) } - - // ensure chainB is allowed to execute stakingtypes.MsgDelegate - params := icahosttypes.NewParams(true, []string{sdk.MsgTypeURL(msgDelegate)}) - suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) - - // build the interchain accounts packet - packet := buildInterchainAccountsPacket(path, icaPacketData.GetBytes(), 1) - - // write packet commitment to state on chainA and commit state - commitment := channeltypes.CommitPacket(suite.chainA.GetSimApp().AppCodec(), packet) - suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1, commitment) - suite.chainA.NextBlock() - - err = path.RelayPacket(packet) - suite.Require().NoError(err) - - // ensure escrowed fees are cleaned up - packetFees, found = suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) - suite.Require().False(found) - suite.Require().Empty(packetFees) - - // assert the value of the account balance after fee distribution - // NOTE: the balance after fee distribution should be equal to the pre-escrow balance minus the recv fee - // as chainA.SenderAccount is used as the msg signer and refund address for msgPayPacketFee above as well as the relyer account for acknowledgements in path.RelayPacket() - postDistBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) - suite.Require().Equal(preEscrowBalance.SubAmount(defaultRecvFee.AmountOf(sdk.DefaultBondDenom)), postDistBalance) } func (suite *FeeTestSuite) TestOnesidedFeeMiddlewareICAHandshake() { - RemoveFeeMiddleware(suite.chainB) // remove fee middleware from chainB + for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { + suite.SetupTest() // reset + + RemoveFeeMiddleware(suite.chainB) // remove fee middleware from chainB - path := NewIncentivizedICAPath(suite.chainA, suite.chainB) + path := NewIncentivizedICAPath(suite.chainA, suite.chainB, ordering) - path.SetupConnections() + path.SetupConnections() - err := SetupPath(path, defaultOwnerAddress) - suite.Require().NoError(err) + err := SetupPath(path, defaultOwnerAddress) + suite.Require().NoError(err) - // assert the newly established channel is not fee enabled on chainB - interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) - suite.Require().True(found) + // assert the newly established channel is not fee enabled on chainB + interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) - expVersionMetadata, err := icatypes.MetadataFromVersion(defaultICAVersion) - suite.Require().NoError(err) + expVersionMetadata, err := icatypes.MetadataFromVersion(defaultICAVersion) + suite.Require().NoError(err) - expVersionMetadata.Address = interchainAccountAddr + expVersionMetadata.Address = interchainAccountAddr - expVersion := string(icatypes.ModuleCdc.MustMarshalJSON(&expVersionMetadata)) + expVersion := string(icatypes.ModuleCdc.MustMarshalJSON(&expVersionMetadata)) - suite.Require().Equal(path.EndpointA.ChannelConfig.Version, expVersion) - suite.Require().Equal(path.EndpointB.ChannelConfig.Version, expVersion) + suite.Require().Equal(path.EndpointA.ChannelConfig.Version, expVersion) + suite.Require().Equal(path.EndpointB.ChannelConfig.Version, expVersion) + } } func buildInterchainAccountsPacket(path *ibctesting.Path, data []byte, seq uint64) channeltypes.Packet { From 016c6f1d50c2e40717a93977c292f4ae7e9a15ca Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 5 Jun 2024 09:33:33 +0200 Subject: [PATCH 7/9] remove unnecessary parameter --- .../host/keeper/handshake_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index 0b16fb39ea6..2e37ddb4418 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -20,7 +20,7 @@ const ( ) // open and close channel is a helper function for TestOnChanOpenTry for reopening accounts -func (suite *KeeperTestSuite) openAndCloseChannel(path *ibctesting.Path, ordering channeltypes.Order) { +func (suite *KeeperTestSuite) openAndCloseChannel(path *ibctesting.Path) { err := path.EndpointB.ChanOpenTry() suite.Require().NoError(err) @@ -70,7 +70,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) suite.Require().NoError(err) - suite.openAndCloseChannel(path, ordering) + suite.openAndCloseChannel(path) }, true, }, @@ -83,7 +83,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) suite.Require().NoError(err) - suite.openAndCloseChannel(path, ordering) + suite.openAndCloseChannel(path) // delete interchain account address store := suite.chainB.GetContext().KVStore(suite.chainB.GetSimApp().GetKey(hosttypes.SubModuleName)) @@ -135,7 +135,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) suite.Require().NoError(err) - suite.openAndCloseChannel(path, ordering) + suite.openAndCloseChannel(path) // delete existing account addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) @@ -155,7 +155,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) suite.Require().NoError(err) - suite.openAndCloseChannel(path, ordering) + suite.openAndCloseChannel(path) addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) suite.Require().True(found) From 134f138d0354e60a733b2111deab890debc67e8c Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 5 Jun 2024 09:33:54 +0200 Subject: [PATCH 8/9] gofumpt --- .../27-interchain-accounts/controller/keeper/handshake_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index 42b8d8eabd1..7e6f0add2f8 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -317,7 +317,6 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { } func (suite *KeeperTestSuite) TestOnChanOpenAck() { - var ( path *ibctesting.Path metadata icatypes.Metadata From b1ed0f673cf6ec356fbde469f6c5aae6d13c55e7 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 5 Jun 2024 14:14:15 +0200 Subject: [PATCH 9/9] Update modules/apps/27-interchain-accounts/controller/keeper/msg_server.go Co-authored-by: DimitrisJim --- .../27-interchain-accounts/controller/keeper/msg_server.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go b/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go index 27434730132..1cdeb601eae 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go @@ -41,11 +41,9 @@ func (s msgServer) RegisterInterchainAccount(goCtx context.Context, msg *types.M s.SetMiddlewareDisabled(ctx, portID, msg.ConnectionId) // use ORDER_UNORDERED as default in case msg's ordering is NONE - var order channeltypes.Order - if msg.Ordering == channeltypes.NONE { + order := msg.Ordering + if order == channeltypes.NONE { order = channeltypes.UNORDERED - } else { - order = msg.Ordering } channelID, err := s.registerInterchainAccount(ctx, msg.ConnectionId, portID, msg.Version, order)