Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: fix ica compatibility tests (backport #7976) #7994

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions .github/workflows/e2e-compatibility.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -236,24 +236,6 @@ jobs:
test-file: "e2e/tests/transfer/send_receive_test.go"
release-version: "${{ needs.determine-image-tag.outputs.release-version }}"

transfer-upgrades-v1-test:
needs:
- build-release-images
- determine-image-tag
uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml
with:
test-file: "e2e/tests/transfer/upgradesv1_test.go"
release-version: "${{ needs.determine-image-tag.outputs.release-version }}"

transfer-upgrades-v2-test:
needs:
- build-release-images
- determine-image-tag
uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml
with:
test-file: "e2e/tests/transfer/upgradesv2_test.go"
release-version: "${{ needs.determine-image-tag.outputs.release-version }}"

upgrade-genesis-test:
needs:
- build-release-images
Expand Down
7 changes: 2 additions & 5 deletions e2e/tests/interchain_accounts/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,13 @@ func (s *InterchainAccountsParamsTestSuite) TestHostEnabledParam() {
})

t.Run("verify acknowledgement error in ack transaction", func(t *testing.T) {
cmd := "message.action=/ibc.core.channel.v1.MsgRecvPacket"
if testvalues.TransactionEventQueryFeatureReleases.IsSupported(chainBVersion) {
cmd = "message.action='/ibc.core.channel.v1.MsgRecvPacket'"
}
cmd := "message.action='/ibc.core.channel.v1.MsgRecvPacket'"
txSearchRes, err := s.QueryTxsByEvents(ctx, chainB, 1, 1, cmd, "")
s.Require().NoError(err)
s.Require().Len(txSearchRes.Txs, 1)

errorMessage, isFound := s.ExtractValueFromEvents(
txSearchRes.Txs[0].Events,
txSearchRes.TxResponses[0].Events,
coretypes.ErrorAttributeKeyPrefix+icatypes.EventTypePacket,
coretypes.ErrorAttributeKeyPrefix+icatypes.AttributeKeyAckError,
)
Expand Down
16 changes: 6 additions & 10 deletions e2e/tests/interchain_accounts/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type InterchainAccountsQueryTestSuite struct {
testsuite.E2ETestSuite
}

// compatibility:InterchainAccountsQueryTestSuite:from_versions: v7.5.0,v7.6.0,v7.7.0,v7.8.0,v8.4.0,v8.5.0,v10.0.0
// compatibility:TestInterchainAccountsQuery:from_versions: v7.5.0,v7.6.0,v7.7.0,v7.8.0,v8.4.0,v8.5.0,v10.0.0
func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() {
t := s.T()
ctx := context.TODO()
Expand All @@ -44,7 +44,6 @@ func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() {
relayer := s.CreateDefaultPaths(testName)

chainA, chainB := s.GetChains()
chainBVersion := chainB.Config().Images[0].Version

// setup 2 accounts: controller account on chain A, a second chain B account.
// host account will be created when the ICA is registered
Expand Down Expand Up @@ -106,26 +105,23 @@ func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() {
txResp := s.BroadcastMessages(ctx, chainA, controllerAccount, icaQueryMsg)
s.AssertTxSuccess(txResp)

s.Require().NoError(testutil.WaitForBlocks(ctx, 10, chainA, chainB))
s.Require().NoError(testutil.WaitForBlocks(ctx, 20, 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) {
cmd := "message.action=/ibc.core.channel.v1.MsgRecvPacket"
if testvalues.TransactionEventQueryFeatureReleases.IsSupported(chainBVersion) {
cmd = "message.action='/ibc.core.channel.v1.MsgRecvPacket'"
}
cmd := "message.action='/ibc.core.channel.v1.MsgRecvPacket'"
txSearchRes, err := s.QueryTxsByEvents(ctx, chainB, 1, 1, cmd, "")
s.Require().NoError(err)
s.Require().Len(txSearchRes.Txs, 1)
s.Require().Len(txSearchRes.TxResponses, 1)

expQueryHeight = uint64(txSearchRes.Txs[0].Height)
expQueryHeight = uint64(txSearchRes.TxResponses[0].Height)

ackHexValue, isFound := s.ExtractValueFromEvents(
txSearchRes.Txs[0].Events,
txSearchRes.TxResponses[0].Events,
channeltypes.EventTypeWriteAck,
channeltypes.AttributeKeyAckHex,
)
Expand Down
94 changes: 51 additions & 43 deletions e2e/testsuite/query/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,49 @@ package query
import (
"context"
"fmt"
"strings"

"github.com/cosmos/gogoproto/proto"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "google.golang.org/protobuf/proto"

msgv1 "cosmossdk.io/api/cosmos/msg/v1"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
)

var queryReqToPath = make(map[string]string)

func PopulateQueryReqToPath(ctx context.Context, chain ibc.Chain) error {
resp, err := queryFileDescriptors(ctx, chain)
if err != nil {
return err
}

for _, fileDescriptor := range resp.Files {
for _, service := range fileDescriptor.GetService() {
// Skip services that are annotated with the "cosmos.msg.v1.service" option.
if ext := pb.GetExtension(service.GetOptions(), msgv1.E_Service); ext != nil {
if ok, extBool := ext.(bool); ok && extBool {
continue
}
}

for _, method := range service.GetMethod() {
// trim the first character from input which is a dot
queryReqToPath[method.GetInputType()[1:]] = fileDescriptor.GetPackage() + "." + service.GetName() + "/" + method.GetName()
}
}
}

return nil
}

// GRPCQuery queries the chain with a query request and deserializes the response to T
func GRPCQuery[T any](ctx context.Context, chain ibc.Chain, req proto.Message, opts ...grpc.CallOption) (*T, error) {
path, err := getProtoPath(req)
if err != nil {
return nil, err
path, ok := queryReqToPath[proto.MessageName(req)]
if !ok {
return nil, fmt.Errorf("no path found for %s", proto.MessageName(req))
}

return grpcQueryWithMethod[T](ctx, chain, req, path, opts...)
Expand Down Expand Up @@ -43,48 +73,26 @@ func grpcQueryWithMethod[T any](ctx context.Context, chain ibc.Chain, req proto.
return resp, nil
}

func getProtoPath(req proto.Message) (string, error) {
typeURL := "/" + proto.MessageName(req)

switch {
case strings.Contains(typeURL, "Query"):
return getQueryProtoPath(typeURL)
case strings.Contains(typeURL, "cosmos.base.tendermint"):
return getCmtProtoPath(typeURL)
default:
return "", fmt.Errorf("unsupported typeURL: %s", typeURL)
}
}

func getQueryProtoPath(queryTypeURL string) (string, error) {
queryIndex := strings.Index(queryTypeURL, "Query")
if queryIndex == -1 {
return "", fmt.Errorf("invalid typeURL: %s", queryTypeURL)
}

// Add to the index to account for the length of "Query"
queryIndex += len("Query")

// Add a slash before the query
urlWithSlash := queryTypeURL[:queryIndex] + "/" + queryTypeURL[queryIndex:]
if !strings.HasSuffix(urlWithSlash, "Request") {
return "", fmt.Errorf("invalid typeURL: %s", queryTypeURL)
func queryFileDescriptors(ctx context.Context, chain ibc.Chain) (*reflectionv1.FileDescriptorsResponse, error) {
// Create a connection to the gRPC server.
grpcConn, err := grpc.Dial(
chain.GetHostGRPCAddress(),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
return nil, err
}

return strings.TrimSuffix(urlWithSlash, "Request"), nil
}

func getCmtProtoPath(cmtTypeURL string) (string, error) {
cmtIndex := strings.Index(cmtTypeURL, "Get")
if cmtIndex == -1 {
return "", fmt.Errorf("invalid typeURL: %s", cmtTypeURL)
}
defer grpcConn.Close()

// Add a slash before the commitment
urlWithSlash := cmtTypeURL[:cmtIndex] + "Service/" + cmtTypeURL[cmtIndex:]
if !strings.HasSuffix(urlWithSlash, "Request") {
return "", fmt.Errorf("invalid typeURL: %s", cmtTypeURL)
resp := new(reflectionv1.FileDescriptorsResponse)
err = grpcConn.Invoke(
ctx, reflectionv1.ReflectionService_FileDescriptors_FullMethodName,
&reflectionv1.FileDescriptorsRequest{}, resp,
)
if err != nil {
return nil, err
}

return strings.TrimSuffix(urlWithSlash, "Request"), nil
return resp, nil
}
5 changes: 5 additions & 0 deletions e2e/testsuite/testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ func (s *E2ETestSuite) SetupChains(ctx context.Context, channelOptionsModifier C
}

s.Require().NoError(ic.Build(ctx, s.GetRelayerExecReporter(), buildOpts))

// setup query paths for GRPC queries:
for _, chain := range s.chains {
s.Require().NoError(query.PopulateQueryReqToPath(ctx, chain))
}
}

// CreateDefaultPaths creates a path between the chains using the default client and channel options.
Expand Down
36 changes: 11 additions & 25 deletions e2e/testsuite/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (
sdkmath "cosmossdk.io/math"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
Expand Down Expand Up @@ -309,43 +309,29 @@ func (s *E2ETestSuite) PruneAcknowledgements(
func (*E2ETestSuite) QueryTxsByEvents(
ctx context.Context, chain ibc.Chain,
page, limit int, queryReq, orderBy string,
) (*sdk.SearchTxsResult, error) {
) (*txtypes.GetTxsEventResponse, error) {
cosmosChain, ok := chain.(*cosmos.CosmosChain)
if !ok {
return nil, errors.New("QueryTxsByEvents must be passed a cosmos.CosmosChain")
}

cmd := []string{"txs"}

chainVersion := chain.Config().Images[0].Version
if testvalues.TransactionEventQueryFeatureReleases.IsSupported(chainVersion) {
cmd = append(cmd, "--query", queryReq)
} else {
cmd = append(cmd, "--events", queryReq)
}

if orderBy != "" {
cmd = append(cmd, "--order_by", orderBy)
}
if page != 0 {
cmd = append(cmd, "--"+flags.FlagPage, strconv.Itoa(page))
}
if limit != 0 {
cmd = append(cmd, "--"+flags.FlagLimit, strconv.Itoa(limit))
req := &txtypes.GetTxsEventRequest{
Page: uint64(page),
Limit: uint64(limit),
Query: queryReq,
}

stdout, _, err := cosmosChain.GetNode().ExecQuery(ctx, cmd...)
if err != nil {
return nil, err
if !testvalues.TransactionEventQueryFeatureReleases.IsSupported(chain.Config().Images[0].Version) {
req.Events = []string{queryReq}
req.Query = ""
}

result := &sdk.SearchTxsResult{}
err = Codec().UnmarshalJSON(stdout, result)
res, err := query.GRPCQuery[txtypes.GetTxsEventResponse](ctx, cosmosChain, req)
if err != nil {
return nil, err
}

return result, nil
return res, nil
}

// ExtractValueFromEvents extracts the value of an attribute from a list of events.
Expand Down
Loading