Skip to content

Commit

Permalink
zoneconcierge API: pagtinating chain IDs API (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianElvis authored Feb 3, 2023
1 parent 0a0c300 commit c960956
Show file tree
Hide file tree
Showing 10 changed files with 379 additions and 98 deletions.
117 changes: 117 additions & 0 deletions client/docs/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6740,6 +6740,38 @@ paths:
type: array
items:
type: string
title: >-
chain_ids are IDs of the chains in ascending alphabetical
order
pagination:
title: pagination defines the pagination in the response
type: object
properties:
next_key:
type: string
format: byte
description: |-
next_key is the key to be passed to PageRequest.key to
query the next page most efficiently. It will be empty if
there are no more results.
total:
type: string
format: uint64
title: >-
total is total number of results available if
PageRequest.count_total

was set, its value is undefined otherwise
description: >-
PageResponse is to be embedded in gRPC response messages where
the

corresponding request message has used PageRequest.

message SomeResponse {
repeated Bar results = 1;
PageResponse page = 2;
}
title: >-
QueryChainListResponse is response type for the Query/ChainList
RPC method
Expand Down Expand Up @@ -6935,6 +6967,63 @@ paths:
"@type": "type.googleapis.com/google.protobuf.Duration",
"value": "1.212s"
}
parameters:
- name: pagination.key
description: |-
key is a value returned in PageResponse.next_key to begin
querying the next page most efficiently. Only one of offset or key
should be set.
in: query
required: false
type: string
format: byte
- name: pagination.offset
description: >-
offset is a numeric offset that can be used when key is unavailable.

It is less efficient than using key. Only one of offset or key
should

be set.
in: query
required: false
type: string
format: uint64
- name: pagination.limit
description: >-
limit is the total number of results to be returned in the result
page.

If left empty it will default to a value to be set by each app.
in: query
required: false
type: string
format: uint64
- name: pagination.count_total
description: >-
count_total is set to true to indicate that the result set should
include

a count of the total number of items available for pagination in
UIs.

count_total is only respected when offset is used. It is ignored
when key

is set.
in: query
required: false
type: boolean
- name: pagination.reverse
description: >-
reverse is set to true if results are to be returned in the
descending order.


Since: cosmos-sdk 0.43
in: query
required: false
type: boolean
tags:
- Query
/babylon/zoneconcierge/v1/finalized_chain_info/{chain_id}:
Expand Down Expand Up @@ -15289,6 +15378,34 @@ definitions:
type: array
items:
type: string
title: chain_ids are IDs of the chains in ascending alphabetical order
pagination:
title: pagination defines the pagination in the response
type: object
properties:
next_key:
type: string
format: byte
description: |-
next_key is the key to be passed to PageRequest.key to
query the next page most efficiently. It will be empty if
there are no more results.
total:
type: string
format: uint64
title: >-
total is total number of results available if
PageRequest.count_total

was set, its value is undefined otherwise
description: |-
PageResponse is to be embedded in gRPC response messages where the
corresponding request message has used PageRequest.

message SomeResponse {
repeated Bar results = 1;
PageResponse page = 2;
}
title: QueryChainListResponse is response type for the Query/ChainList RPC method
babylon.zoneconcierge.v1.QueryEpochChainInfoResponse:
type: object
Expand Down
2 changes: 1 addition & 1 deletion proto/babylon/btccheckpoint/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ message QueryBtcCheckpointsInfoRequest {
uint64 start_epoch = 1;
uint64 end_epoch = 2;

// pagination defines whether to have the pagination in the response
// pagination defines whether to have the pagination in the request
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}

Expand Down
4 changes: 2 additions & 2 deletions proto/babylon/epoching/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ message QueryEpochsInfoRequest {
uint64 start_epoch = 1;
uint64 end_epoch = 2;

// pagination defines whether to have the pagination in the response
// pagination defines whether to have the pagination in the request
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}

Expand All @@ -107,7 +107,7 @@ message QueryEpochMsgsRequest {
// epoch_num is the number of epoch of the requested msg queue
uint64 epoch_num = 1;

// pagination defines whether to have the pagination in the response
// pagination defines whether to have the pagination in the request
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

Expand Down
10 changes: 8 additions & 2 deletions proto/babylon/zoneconcierge/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,17 @@ message QueryHeaderResponse {
}

// QueryChainListRequest is request type for the Query/ChainList RPC method
message QueryChainListRequest {}
message QueryChainListRequest {
// pagination defines whether to have the pagination in the request
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}

// QueryChainListResponse is response type for the Query/ChainList RPC method
message QueryChainListResponse {
// chain_ids are IDs of the chains in ascending alphabetical order
repeated string chain_ids = 1;
// pagination defines the pagination in the response
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryChainInfoRequest is request type for the Query/ChainInfo RPC method.
Expand Down Expand Up @@ -109,7 +115,7 @@ message QueryEpochChainInfoResponse {
// QueryListHeadersRequest is request type for the Query/ListHeaders RPC method.
message QueryListHeadersRequest {
string chain_id = 1;
// pagination defines whether to have the pagination in the response
// pagination defines whether to have the pagination in the request
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

Expand Down
2 changes: 1 addition & 1 deletion x/btccheckpoint/types/query.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions x/epoching/types/query.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions x/zoneconcierge/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,22 @@ func (k Keeper) ChainList(c context.Context, req *types.QueryChainListRequest) (
}

ctx := sdk.UnwrapSDKContext(c)
chainIDs := k.GetAllChainIDs(ctx)
// TODO: pagination for this API
resp := &types.QueryChainListResponse{ChainIds: chainIDs}

chainIDs := []string{}
store := k.chainInfoStore(ctx)
pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error {
chainID := string(key)
chainIDs = append(chainIDs, chainID)
return nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

resp := &types.QueryChainListResponse{
ChainIds: chainIDs,
Pagination: pageRes,
}
return resp, nil
}

Expand Down
29 changes: 16 additions & 13 deletions x/zoneconcierge/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package keeper_test

import (
"math/rand"
"sort"
"testing"

"github.com/babylonchain/babylon/testutil/datagen"
Expand All @@ -20,7 +19,7 @@ import (
)

func FuzzChainList(f *testing.F) {
datagen.AddRandomSeedsToFuzzer(f, 100)
datagen.AddRandomSeedsToFuzzer(f, 10)

f.Fuzz(func(t *testing.T, seed int64) {
rand.Seed(seed)
Expand All @@ -32,32 +31,36 @@ func FuzzChainList(f *testing.F) {
hooks := zcKeeper.Hooks()

// invoke the hook a random number of times with random chain IDs
numHeaders := datagen.RandomInt(100)
expectedChainIDs := []string{}
numHeaders := datagen.RandomInt(100) + 1
allChainIDs := []string{}
for i := uint64(0); i < numHeaders; i++ {
var chainID string
// simulate the scenario that some headers belong to the same chain
if i > 0 && datagen.OneInN(2) {
chainID = expectedChainIDs[rand.Intn(len(expectedChainIDs))]
chainID = allChainIDs[rand.Intn(len(allChainIDs))]
} else {
chainID = datagen.GenRandomHexStr(30)
expectedChainIDs = append(expectedChainIDs, chainID)
allChainIDs = append(allChainIDs, chainID)
}
header := datagen.GenRandomIBCTMHeader(chainID, 0)
hooks.AfterHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(32), header, false)
}

limit := datagen.RandomInt(len(allChainIDs)) + 1

// make query to get actual chain IDs
resp, err := zcKeeper.ChainList(ctx, &zctypes.QueryChainListRequest{})
resp, err := zcKeeper.ChainList(ctx, &zctypes.QueryChainListRequest{
Pagination: &query.PageRequest{
Limit: limit,
},
})
require.NoError(t, err)
actualChainIDs := resp.ChainIds

// sort them and assert equality
sort.Strings(expectedChainIDs)
sort.Strings(actualChainIDs)
require.Equal(t, len(expectedChainIDs), len(actualChainIDs))
for i := 0; i < len(expectedChainIDs); i++ {
require.Equal(t, expectedChainIDs[i], actualChainIDs[i])
require.Equal(t, limit, uint64(len(actualChainIDs)))
allChainIDs = zcKeeper.GetAllChainIDs(ctx)
for i := uint64(0); i < limit; i++ {
require.Equal(t, allChainIDs[i], actualChainIDs[i])
}
})
}
Expand Down
Loading

0 comments on commit c960956

Please sign in to comment.