diff --git a/modules/core/02-client/keeper/grpc_query.go b/modules/core/02-client/keeper/grpc_query.go index 3f7aa9ac3e6..988316ce1e8 100644 --- a/modules/core/02-client/keeper/grpc_query.go +++ b/modules/core/02-client/keeper/grpc_query.go @@ -94,8 +94,10 @@ func (q *queryServer) ClientStates(ctx context.Context, req *types.QueryClientSt return false, err } - identifiedClient := types.NewIdentifiedClientState(clientID, clientState) - clientStates = append(clientStates, identifiedClient) + if accumulate { + identifiedClient := types.NewIdentifiedClientState(clientID, clientState) + clientStates = append(clientStates, identifiedClient) + } return true, nil }) if err != nil { @@ -184,7 +186,10 @@ func (q *queryServer) ConsensusStates(ctx context.Context, req *types.QueryConse return false, err } - consensusStates = append(consensusStates, types.NewConsensusStateWithHeight(height, consensusState)) + if accumulate { + consensusStates = append(consensusStates, types.NewConsensusStateWithHeight(height, consensusState)) + } + return true, nil }) if err != nil { @@ -221,7 +226,10 @@ func (q *queryServer) ConsensusStateHeights(ctx context.Context, req *types.Quer return false, err } - consensusStateHeights = append(consensusStateHeights, height) + if accumulate { + consensusStateHeights = append(consensusStateHeights, height) + } + return true, nil }) if err != nil { diff --git a/modules/core/02-client/keeper/grpc_query_test.go b/modules/core/02-client/keeper/grpc_query_test.go index 1abaa4a1d15..63c51556824 100644 --- a/modules/core/02-client/keeper/grpc_query_test.go +++ b/modules/core/02-client/keeper/grpc_query_test.go @@ -110,6 +110,7 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { var ( req *types.QueryClientStatesRequest expClientStates = types.IdentifiedClientStates{} + expCount = 0 ) testCases := []struct { @@ -121,6 +122,7 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { "req is nil", func() { req = nil + expCount = 0 }, status.Error(codes.InvalidArgument, "empty request"), }, @@ -128,6 +130,7 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { "empty pagination", func() { expClientStates = nil + expCount = 0 req = &types.QueryClientStatesRequest{} }, nil, @@ -155,6 +158,31 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { CountTotal: true, }, } + expCount = 2 + }, + nil, + }, + { + "success request with pagination limit", + func() { + path1 := ibctesting.NewPath(suite.chainA, suite.chainB) + path1.SetupClients() + + path2 := ibctesting.NewPath(suite.chainA, suite.chainB) + path2.SetupClients() + + clientStateA1 := path1.EndpointA.GetClientState() + + idcs := types.NewIdentifiedClientState(path1.EndpointA.ClientID, clientStateA1) + + expClientStates = types.IdentifiedClientStates{idcs}.Sort() + req = &types.QueryClientStatesRequest{ + Pagination: &query.PageRequest{ + Limit: 1, + CountTotal: true, + }, + } + expCount = 2 }, nil, }, @@ -174,7 +202,8 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { suite.Require().NoError(err) suite.Require().NotNil(res) suite.Require().Equal(expClientStates.Sort(), res.ClientStates) - suite.Require().Equal(len(expClientStates), int(res.Pagination.Total)) + suite.Require().Equal(expCount, int(res.Pagination.Total)) + } else { suite.Require().Error(err) suite.Require().ErrorIs(err, tc.expErr) @@ -370,6 +399,36 @@ func (suite *KeeperTestSuite) TestQueryConsensusStates() { }, nil, }, + { + "success with pagination limit", + func() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + path.SetupClients() + + height1, ok := path.EndpointA.GetClientLatestHeight().(types.Height) + suite.Require().True(ok) + expConsensusStates = []types.ConsensusStateWithHeight{ + types.NewConsensusStateWithHeight( + height1, + path.EndpointA.GetConsensusState(height1), + ), + } + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + _, ok = path.EndpointA.GetClientLatestHeight().(types.Height) + suite.Require().True(ok) + + req = &types.QueryConsensusStatesRequest{ + ClientId: path.EndpointA.ClientID, + Pagination: &query.PageRequest{ + Limit: 1, + CountTotal: true, + }, + } + }, + nil, + }, { "invalid client identifier", func() { @@ -465,6 +524,29 @@ func (suite *KeeperTestSuite) TestQueryConsensusStateHeights() { }, nil, }, + { + "success: pagination with limit", + func() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + path.SetupClients() + + expConsensusStateHeights = []types.Height{path.EndpointA.GetClientLatestHeight().(types.Height)} + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // expConsensusStateHeights = append(expConsensusStateHeights, path.EndpointA.GetClientLatestHeight().(types.Height)) + + req = &types.QueryConsensusStateHeightsRequest{ + ClientId: path.EndpointA.ClientID, + Pagination: &query.PageRequest{ + Limit: 1, + CountTotal: true, + }, + } + }, + nil, + }, { "invalid client identifier", func() { diff --git a/modules/core/04-channel/keeper/grpc_query.go b/modules/core/04-channel/keeper/grpc_query.go index d2ef8fed802..0e074f4e1dd 100644 --- a/modules/core/04-channel/keeper/grpc_query.go +++ b/modules/core/04-channel/keeper/grpc_query.go @@ -126,8 +126,11 @@ func (q *queryServer) ConnectionChannels(ctx context.Context, req *types.QueryCo return false, err } - identifiedChannel := types.NewIdentifiedChannel(portID, channelID, result) - channels = append(channels, &identifiedChannel) + if accumulate { + identifiedChannel := types.NewIdentifiedChannel(portID, channelID, result) + channels = append(channels, &identifiedChannel) + } + return true, nil }) if err != nil { diff --git a/modules/core/04-channel/keeper/grpc_query_test.go b/modules/core/04-channel/keeper/grpc_query_test.go index 3b42625120a..516d78bea82 100644 --- a/modules/core/04-channel/keeper/grpc_query_test.go +++ b/modules/core/04-channel/keeper/grpc_query_test.go @@ -323,6 +323,47 @@ func (suite *KeeperTestSuite) TestQueryConnectionChannels() { }, nil, }, + { + "success with pagination limit", + func() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + path.Setup() + // channel0 on first connection on chainA + counterparty0 := types.Counterparty{ + PortId: path.EndpointB.ChannelConfig.PortID, + ChannelId: path.EndpointB.ChannelID, + } + + // path1 creates a second channel on first connection on chainA + path1 := ibctesting.NewPath(suite.chainA, suite.chainB) + path1.SetChannelOrdered() + path1.EndpointA.ClientID = path.EndpointA.ClientID + path1.EndpointB.ClientID = path.EndpointB.ClientID + path1.EndpointA.ConnectionID = path.EndpointA.ConnectionID + path1.EndpointB.ConnectionID = path.EndpointB.ConnectionID + + suite.coordinator.CreateMockChannels(path1) + + channel0 := types.NewChannel( + types.OPEN, types.UNORDERED, + counterparty0, []string{path.EndpointA.ConnectionID}, path.EndpointA.ChannelConfig.Version, + ) + + idCh0 := types.NewIdentifiedChannel(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel0) + + expChannels = []*types.IdentifiedChannel{&idCh0} + + req = &types.QueryConnectionChannelsRequest{ + Connection: path.EndpointA.ConnectionID, + Pagination: &query.PageRequest{ + Key: nil, + Limit: 1, + CountTotal: true, + }, + } + }, + nil, + }, } for _, tc := range testCases {