-
Notifications
You must be signed in to change notification settings - Fork 586
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow module safe queries in ICA (#5785)
* imp: initial modification of tx.proto * imp: ran 'make proto-all' * fix: compiler errors * imp: added query router interface * imp: added queryRouter to icahost keeper * imp: improved proto definitions * imp: ran 'make proto-all' * imp: added sdk.Msg helpers * feat: basic implementation * style: improved field names * imp: ran 'make proto-all' * fix: compiler errors * imp: ran gofumpt * feat: tests passing * feat: tests improved * test: removed unneeded code * imp: improved 'IsModuleSafe' function * imp: added IsModuleQuerySafe to msg_server * imp: added more test cases * fix: callbacks compiler * fix: non determinancy issues * fix: added query msg to codec * imp: whitelist logic added * e2e: new test added * fix: new test * fix: test * fix: e2e * fix: e2e * imp(e2e): added the QueryTxsByEvents function * fix: e2e * e2e: lint fix * fix: e2e * e2e: debug * fix: e2e * test: debug helpers * debug * test: added codec_test case * imp: additional test case * imp: added important unit test * r4r * e2e: debug * imp: added logs * fix: e2e * fix: e2e * fix: e2e * imp: added height to proto response * imp: ran 'make proto-all' * imp: added height * e2e: updated e2e to test height * imp: review suggestions * e2e: remove unneeded log * refactor: refactored 'ExtractValueFromEvents' * e2e: review item * imp: review item * nit: review item * docs: added godocs * test: unit test for mqsWhitelist added * imp: added logging * style: rename to allow list * add changelog --------- Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
- Loading branch information
1 parent
e7c74b0
commit eecfa5c
Showing
21 changed files
with
1,355 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
//go:build !test_e2e | ||
|
||
package interchainaccounts | ||
|
||
import ( | ||
"context" | ||
"encoding/hex" | ||
"encoding/json" | ||
"testing" | ||
"time" | ||
|
||
"github.com/cosmos/gogoproto/proto" | ||
"github.com/strangelove-ventures/interchaintest/v8/testutil" | ||
testifysuite "github.com/stretchr/testify/suite" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" | ||
|
||
"github.com/cosmos/ibc-go/e2e/testsuite" | ||
"github.com/cosmos/ibc-go/e2e/testvalues" | ||
controllertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" | ||
icahosttypes "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" | ||
ibctesting "github.com/cosmos/ibc-go/v8/testing" | ||
) | ||
|
||
func TestInterchainAccountsQueryTestSuite(t *testing.T) { | ||
testifysuite.Run(t, new(InterchainAccountsQueryTestSuite)) | ||
} | ||
|
||
type InterchainAccountsQueryTestSuite struct { | ||
testsuite.E2ETestSuite | ||
} | ||
|
||
func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() { | ||
t := s.T() | ||
ctx := context.TODO() | ||
|
||
// setup relayers and connection-0 between two chains | ||
// channel-0 is a transfer channel but it will not be used in this test case | ||
relayer, _ := s.SetupChainsRelayerAndChannel(ctx, nil) | ||
chainA, chainB := s.GetChains() | ||
|
||
// setup 2 accounts: controller account on chain A, a second chain B account. | ||
// host account will be created when the ICA is registered | ||
controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) | ||
controllerAddress := controllerAccount.FormattedAddress() | ||
chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) | ||
var hostAccount string | ||
|
||
t.Run("broadcast MsgRegisterInterchainAccount", func(t *testing.T) { | ||
// explicitly set the version string because we don't want to use incentivized channels. | ||
version := icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) | ||
msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAddress, version, channeltypes.UNORDERED) | ||
|
||
txResp := s.BroadcastMessages(ctx, chainA, controllerAccount, msgRegisterAccount) | ||
s.AssertTxSuccess(txResp) | ||
}) | ||
|
||
t.Run("start relayer", func(t *testing.T) { | ||
s.StartRelayer(relayer) | ||
}) | ||
|
||
t.Run("verify interchain account", func(t *testing.T) { | ||
var err error | ||
hostAccount, err = s.QueryInterchainAccount(ctx, chainA, controllerAddress, ibctesting.FirstConnectionID) | ||
s.Require().NoError(err) | ||
s.Require().NotZero(len(hostAccount)) | ||
|
||
channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) | ||
s.Require().NoError(err) | ||
s.Require().Len(channels, 2) | ||
}) | ||
|
||
t.Run("query via interchain account", func(t *testing.T) { | ||
// the host account need not be funded | ||
t.Run("broadcast query packet", func(t *testing.T) { | ||
balanceQuery := banktypes.NewQueryBalanceRequest(chainBAccount.Address(), chainB.Config().Denom) | ||
queryBz, err := balanceQuery.Marshal() | ||
s.Require().NoError(err) | ||
|
||
queryMsg := icahosttypes.NewMsgModuleQuerySafe(hostAccount, []*icahosttypes.QueryRequest{ | ||
{ | ||
Path: "/cosmos.bank.v1beta1.Query/Balance", | ||
Data: queryBz, | ||
}, | ||
}) | ||
|
||
cdc := testsuite.Codec() | ||
bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{queryMsg}, icatypes.EncodingProtobuf) | ||
s.Require().NoError(err) | ||
|
||
packetData := icatypes.InterchainAccountPacketData{ | ||
Type: icatypes.EXECUTE_TX, | ||
Data: bz, | ||
Memo: "e2e", | ||
} | ||
|
||
icaQueryMsg := controllertypes.NewMsgSendTx(controllerAddress, ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData) | ||
|
||
txResp := s.BroadcastMessages(ctx, chainA, controllerAccount, icaQueryMsg) | ||
s.AssertTxSuccess(txResp) | ||
|
||
s.Require().NoError(testutil.WaitForBlocks(ctx, 10, chainA, chainB)) | ||
}) | ||
|
||
t.Run("verify query response", func(t *testing.T) { | ||
var expQueryHeight uint64 | ||
|
||
ack := &channeltypes.Acknowledgement_Result{} | ||
t.Run("retrieve acknowledgement", func(t *testing.T) { | ||
txSearchRes, err := s.QueryTxsByEvents( | ||
ctx, chainB, 1, 1, | ||
"message.action='/ibc.core.channel.v1.MsgRecvPacket'", "", | ||
) | ||
s.Require().NoError(err) | ||
s.Require().Len(txSearchRes.Txs, 1) | ||
|
||
expQueryHeight = uint64(txSearchRes.Txs[0].Height) | ||
|
||
ackHexValue, isFound := s.ExtractValueFromEvents( | ||
txSearchRes.Txs[0].Events, | ||
channeltypes.EventTypeWriteAck, | ||
channeltypes.AttributeKeyAckHex, | ||
) | ||
s.Require().True(isFound) | ||
s.Require().NotEmpty(ackHexValue) | ||
|
||
ackBz, err := hex.DecodeString(ackHexValue) | ||
s.Require().NoError(err) | ||
|
||
err = json.Unmarshal(ackBz, ack) | ||
s.Require().NoError(err) | ||
}) | ||
|
||
icaAck := &sdk.TxMsgData{} | ||
t.Run("unmarshal ica response", func(t *testing.T) { | ||
err := proto.Unmarshal(ack.Result, icaAck) | ||
s.Require().NoError(err) | ||
s.Require().Len(icaAck.GetMsgResponses(), 1) | ||
}) | ||
|
||
queryTxResp := &icahosttypes.MsgModuleQuerySafeResponse{} | ||
t.Run("unmarshal MsgModuleQuerySafeResponse", func(t *testing.T) { | ||
err := proto.Unmarshal(icaAck.MsgResponses[0].Value, queryTxResp) | ||
s.Require().NoError(err) | ||
s.Require().Len(queryTxResp.Responses, 1) | ||
s.Require().Equal(expQueryHeight, queryTxResp.Height) | ||
}) | ||
|
||
balanceResp := &banktypes.QueryBalanceResponse{} | ||
t.Run("unmarshal and verify bank query response", func(t *testing.T) { | ||
err := proto.Unmarshal(queryTxResp.Responses[0], balanceResp) | ||
s.Require().NoError(err) | ||
s.Require().Equal(chainB.Config().Denom, balanceResp.Balance.Denom) | ||
s.Require().Equal(testvalues.StartingTokenAmount, balanceResp.Balance.Amount.Int64()) | ||
}) | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.