From 1d50ff42797edd07305484f70306d601ac01387b Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 27 Mar 2024 23:17:29 +0100 Subject: [PATCH 1/5] docs for ica queries --- .../02-interchain-accounts/04-integration.md | 8 ++- .../02-interchain-accounts/05-messages.md | 25 +++++++ docs/docs/05-migrations/13-v8-to-v9.md | 15 ++++ .../host/types/msgs_test.go | 69 +++++++++++++++++++ 4 files changed, 114 insertions(+), 3 deletions(-) diff --git a/docs/docs/02-apps/02-interchain-accounts/04-integration.md b/docs/docs/02-apps/02-interchain-accounts/04-integration.md index 974e7f978df..8547c2198ef 100644 --- a/docs/docs/02-apps/02-interchain-accounts/04-integration.md +++ b/docs/docs/02-apps/02-interchain-accounts/04-integration.md @@ -82,14 +82,16 @@ scopedICAAuthKeeper := app.CapabilityKeeper.ScopeToModule(icaauthtypes.ModuleNam app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper( appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, + app.IBCKeeper.ChannelKeeper, app.IBCKeeper.PortKeeper, scopedICAControllerKeeper, app.MsgServiceRouter(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) app.ICAHostKeeper = icahostkeeper.NewKeeper( appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), + app.IBCKeeper.ChannelKeeper, app.IBCKeeper.PortKeeper, app.AccountKeeper, + scopedICAHostKeeper, app.MsgServiceRouter(), app.GRPCQueryRouter(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) // Create Interchain Accounts AppModule diff --git a/docs/docs/02-apps/02-interchain-accounts/05-messages.md b/docs/docs/02-apps/02-interchain-accounts/05-messages.md index 4e108fa1243..0fabc21e094 100644 --- a/docs/docs/02-apps/02-interchain-accounts/05-messages.md +++ b/docs/docs/02-apps/02-interchain-accounts/05-messages.md @@ -72,6 +72,31 @@ type MsgSendTxResponse struct { The packet `Sequence` is returned in the message response. +### Queries + +It is possible to use [`MsgModuleQuerySafe`](https://github.com/cosmos/ibc-go/blob/eecfa5c09a4c38a5c9f2cc2a322d2286f45911da/proto/ibc/applications/interchain_accounts/host/v1/tx.proto#L41-L51) to execute a list of queries on the host chain. This message can be included in the list of encoded `sdk.Msg`s of `InterchainPacketData`. The host chain will return on the acknowledgment the responses for all the queries. Please note that only module safe queries can be executed. The following code block shows an example of how this message can be used to query the account balance of an account on the host chain. The resulting packet data variable is used to set the `PacketData` of `MsgSendTx`. + +```go +balanceQuery := banktypes.NewQueryBalanceRequest("cosmos1...", "uatom") +queryBz, err := balanceQuery.Marshal() + +// signer of message must be the interchain account on the host +queryMsg := icahosttypes.NewMsgModuleQuerySafe("cosmos2...", []*icahosttypes.QueryRequest{ + { + Path: "/cosmos.bank.v1beta1.Query/Balance", + Data: queryBz, + }, +}) + +bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{queryMsg}, icatypes.EncodingProtobuf) + +packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "", +} +``` + ## Atomicity As the Interchain Accounts module supports the execution of multiple transactions using the Cosmos SDK `Msg` interface, it provides the same atomicity guarantees as Cosmos SDK-based applications, leveraging the [`CacheMultiStore`](https://docs.cosmos.network/main/learn/advanced/store#cachemultistore) architecture provided by the [`Context`](https://docs.cosmos.network/main/learn/advanced/context.html) type. diff --git a/docs/docs/05-migrations/13-v8-to-v9.md b/docs/docs/05-migrations/13-v8-to-v9.md index 1fafc4c8265..4783c1c06c0 100644 --- a/docs/docs/05-migrations/13-v8-to-v9.md +++ b/docs/docs/05-migrations/13-v8-to-v9.md @@ -47,6 +47,21 @@ Please use the new functions `path.Setup`, `path.SetupClients`, `path.SetupConne - Functions `ConstructUpdateTMClientHeader` and `ConstructUpdateTMClientHeaderWithTrustedHeight` of `TestChain` type have been replaced with `IBCClientHeader`. This function will construct a `07-tendermint` header to update the light client on the counterparty chain. The trusted height must be passed in as a non-zero height. - `GetValsAtHeight` has been renamed to `GetTrustedValidators` +### ICS27 - Interchain Accounts + +In [#5785](https://github.com/cosmos/ibc-go/pull/5785) the list of arguments of the `NewKeeper` constructor function of the host submodule was extended with an extra argument for the gRPC query router that the submodule uses when executing a [`MsgModuleQuerySafe`](https://github.com/cosmos/ibc-go/blob/eecfa5c09a4c38a5c9f2cc2a322d2286f45911da/proto/ibc/applications/interchain_accounts/host/v1/tx.proto#L41-L51) to perform queries that are module safe: + +```diff +func NewKeeper( + cdc codec.Codec, key storetypes.StoreKey, legacySubspace icatypes.ParamSubspace, + ics4Wrapper porttypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, + portKeeper icatypes.PortKeeper, accountKeeper icatypes.AccountKeeper, + scopedKeeper exported.ScopedKeeper, msgRouter icatypes.MessageRouter, ++ queryRouter icatypes.QueryRouter, + authority string, +) Keeper +``` + ## Relayers - Renaming of event attribute keys in [#5603](https://github.com/cosmos/ibc-go/pull/5603). diff --git a/modules/apps/27-interchain-accounts/host/types/msgs_test.go b/modules/apps/27-interchain-accounts/host/types/msgs_test.go index b9d1d96e2bc..b19ad329915 100644 --- a/modules/apps/27-interchain-accounts/host/types/msgs_test.go +++ b/modules/apps/27-interchain-accounts/host/types/msgs_test.go @@ -10,6 +10,7 @@ import ( ica "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts" "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types" + ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -74,3 +75,71 @@ func TestMsgUpdateParamsGetSigners(t *testing.T) { } } } + +func TestMsgModuleQuerySafeValidateBasic(t *testing.T) { + var queryRequest = &types.QueryRequest{ + Path: "/cosmos.bank.v1beta1.Query/Balance", + Data: []byte{}, + } + + testCases := []struct { + name string + msg *types.MsgModuleQuerySafe + expErr error + }{ + { + "success: valid signer address", + types.NewMsgModuleQuerySafe(sdk.AccAddress(ibctesting.TestAccAddress).String(), []*types.QueryRequest{queryRequest}), + nil, + }, + { + "failure: invalid signer address", + types.NewMsgModuleQuerySafe("signer", []*types.QueryRequest{queryRequest}), + ibcerrors.ErrInvalidAddress, + }, + { + "failure: empty query requests", + types.NewMsgModuleQuerySafe(sdk.AccAddress(ibctesting.TestAccAddress).String(), []*types.QueryRequest{}), + ibcerrors.ErrInvalidRequest, + }, + } + + for _, tc := range testCases { + tc := tc + + err := tc.msg.ValidateBasic() + + expPass := tc.expErr == nil + if expPass { + require.NoError(t, err) + } else { + require.Error(t, err) + require.ErrorIs(t, err, tc.expErr) + } + } +} + +func TestMsgModuleQuerySafeGetSigners(t *testing.T) { + testCases := []struct { + name string + address sdk.AccAddress + expPass bool + }{ + {"success: valid address", sdk.AccAddress(ibctesting.TestAccAddress), true}, + {"failure: nil address", nil, false}, + } + + for _, tc := range testCases { + tc := tc + + msg := types.NewMsgModuleQuerySafe(tc.address.String(), []*types.QueryRequest{}) + encodingCfg := moduletestutil.MakeTestEncodingConfig(ica.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + if tc.expPass { + require.NoError(t, err) + require.Equal(t, tc.address.Bytes(), signers[0]) + } else { + require.Error(t, err) + } + } +} From ca4400c9c25fff433be38f7cd7d5897a9b8014af Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 27 Mar 2024 23:18:55 +0100 Subject: [PATCH 2/5] indentation --- docs/docs/05-migrations/13-v8-to-v9.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/05-migrations/13-v8-to-v9.md b/docs/docs/05-migrations/13-v8-to-v9.md index 4783c1c06c0..d2f462cf427 100644 --- a/docs/docs/05-migrations/13-v8-to-v9.md +++ b/docs/docs/05-migrations/13-v8-to-v9.md @@ -53,11 +53,11 @@ In [#5785](https://github.com/cosmos/ibc-go/pull/5785) the list of arguments of ```diff func NewKeeper( - cdc codec.Codec, key storetypes.StoreKey, legacySubspace icatypes.ParamSubspace, - ics4Wrapper porttypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, + cdc codec.Codec, key storetypes.StoreKey, legacySubspace icatypes.ParamSubspace, + ics4Wrapper porttypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, accountKeeper icatypes.AccountKeeper, scopedKeeper exported.ScopedKeeper, msgRouter icatypes.MessageRouter, -+ queryRouter icatypes.QueryRouter, ++ queryRouter icatypes.QueryRouter, authority string, ) Keeper ``` From cd7e5b1c50c44c5f643bc66af74ebaf7cc002be6 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 27 Mar 2024 23:19:33 +0100 Subject: [PATCH 3/5] lint --- 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 d2f462cf427..fc97b0a26c4 100644 --- a/docs/docs/05-migrations/13-v8-to-v9.md +++ b/docs/docs/05-migrations/13-v8-to-v9.md @@ -47,7 +47,7 @@ Please use the new functions `path.Setup`, `path.SetupClients`, `path.SetupConne - Functions `ConstructUpdateTMClientHeader` and `ConstructUpdateTMClientHeaderWithTrustedHeight` of `TestChain` type have been replaced with `IBCClientHeader`. This function will construct a `07-tendermint` header to update the light client on the counterparty chain. The trusted height must be passed in as a non-zero height. - `GetValsAtHeight` has been renamed to `GetTrustedValidators` -### ICS27 - Interchain Accounts +### ICS27 - Interchain Accounts In [#5785](https://github.com/cosmos/ibc-go/pull/5785) the list of arguments of the `NewKeeper` constructor function of the host submodule was extended with an extra argument for the gRPC query router that the submodule uses when executing a [`MsgModuleQuerySafe`](https://github.com/cosmos/ibc-go/blob/eecfa5c09a4c38a5c9f2cc2a322d2286f45911da/proto/ibc/applications/interchain_accounts/host/v1/tx.proto#L41-L51) to perform queries that are module safe: From 3f5bee70a0424234451673ba9b719ee0b73f16cd Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Wed, 27 Mar 2024 23:24:31 +0100 Subject: [PATCH 4/5] lint --- modules/apps/27-interchain-accounts/host/types/msgs_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/apps/27-interchain-accounts/host/types/msgs_test.go b/modules/apps/27-interchain-accounts/host/types/msgs_test.go index b19ad329915..658148693e1 100644 --- a/modules/apps/27-interchain-accounts/host/types/msgs_test.go +++ b/modules/apps/27-interchain-accounts/host/types/msgs_test.go @@ -77,7 +77,7 @@ func TestMsgUpdateParamsGetSigners(t *testing.T) { } func TestMsgModuleQuerySafeValidateBasic(t *testing.T) { - var queryRequest = &types.QueryRequest{ + queryRequest := &types.QueryRequest{ Path: "/cosmos.bank.v1beta1.Query/Balance", Data: []byte{}, } From 0e86b53c250402e85f65183edebf87f5346ab8ef Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Fri, 29 Mar 2024 10:05:44 +0100 Subject: [PATCH 5/5] review comment --- .../host/types/msgs_test.go | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/modules/apps/27-interchain-accounts/host/types/msgs_test.go b/modules/apps/27-interchain-accounts/host/types/msgs_test.go index 658148693e1..eb088d7c597 100644 --- a/modules/apps/27-interchain-accounts/host/types/msgs_test.go +++ b/modules/apps/27-interchain-accounts/host/types/msgs_test.go @@ -107,15 +107,17 @@ func TestMsgModuleQuerySafeValidateBasic(t *testing.T) { for _, tc := range testCases { tc := tc - err := tc.msg.ValidateBasic() - - expPass := tc.expErr == nil - if expPass { - require.NoError(t, err) - } else { - require.Error(t, err) - require.ErrorIs(t, err, tc.expErr) - } + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + + expPass := tc.expErr == nil + if expPass { + require.NoError(t, err) + } else { + require.Error(t, err) + require.ErrorIs(t, err, tc.expErr) + } + }) } } @@ -132,14 +134,16 @@ func TestMsgModuleQuerySafeGetSigners(t *testing.T) { for _, tc := range testCases { tc := tc - msg := types.NewMsgModuleQuerySafe(tc.address.String(), []*types.QueryRequest{}) - encodingCfg := moduletestutil.MakeTestEncodingConfig(ica.AppModuleBasic{}) - signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) - if tc.expPass { - require.NoError(t, err) - require.Equal(t, tc.address.Bytes(), signers[0]) - } else { - require.Error(t, err) - } + t.Run(tc.name, func(t *testing.T) { + msg := types.NewMsgModuleQuerySafe(tc.address.String(), []*types.QueryRequest{}) + encodingCfg := moduletestutil.MakeTestEncodingConfig(ica.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + if tc.expPass { + require.NoError(t, err) + require.Equal(t, tc.address.Bytes(), signers[0]) + } else { + require.Error(t, err) + } + }) } }