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

zoneconcierge: debugging API ChainInfo #211

Merged
merged 11 commits into from
Nov 22, 2022
17 changes: 17 additions & 0 deletions proto/babylon/zoneconcierge/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/babylonchain/babylon/zoneconcierge/params";
}
// ChainList queries the list of chains that checkpoint to Babylon
rpc ChainList(QueryChainListRequest) returns (QueryChainListResponse) {
option (google.api.http).get = "/babylonchain/babylon/zoneconcierge/chains";
}
// ChainInfo queries the latest info of a chain in Babylon's view
rpc ChainInfo(QueryChainInfoRequest) returns (QueryChainInfoResponse) {
option (google.api.http).get = "/babylonchain/babylon/zoneconcierge/chain_info/{chain_id}";
}
// FinalizedChainInfo queries the BTC-finalised info of a chain, with proofs
rpc FinalizedChainInfo(QueryFinalizedChainInfoRequest) returns (QueryFinalizedChainInfoResponse) {
option (google.api.http).get = "/babylonchain/babylon/zoneconcierge/finalized_chain_info/{chain_id}";
}
Expand All @@ -45,6 +51,17 @@ message QueryChainListResponse {
repeated string chain_ids = 1;
}

// QueryChainInfoRequest is request type for the Query/ChainInfo RPC method.
message QueryChainInfoRequest {
string chain_id = 1;
}

// QueryChainInfoResponse is response type for the Query/ChainInfo RPC method.
message QueryChainInfoResponse {
// chain_info is the info of the CZ
babylon.zoneconcierge.v1.ChainInfo chain_info = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we add further attributes here as with QueryFinalizedChainInfoResponse?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, epoch info and btc checkpoint info would be super useful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we add further attributes here as with QueryFinalizedChainInfoResponse?

Since this API is only for debugging, it would be overkill to add stuff like inclusion proofs to this API. At the moment as long as the query gives us latest chain info then it should be enough for debugging.

For example, epoch info and btc checkpoint info would be super useful.

Such a latest chain info can be in an epoch that hasn't ended yet. To have these info the epoch with this chain info has to be at least submitted.

}

// QueryFinalizedChainInfoRequest is request type for the Query/FinalizedChainInfo RPC method.
message QueryFinalizedChainInfoRequest {
string chain_id = 1;
Expand Down
18 changes: 18 additions & 0 deletions x/zoneconcierge/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ func (k Keeper) ChainList(c context.Context, req *types.QueryChainListRequest) (
return resp, nil
}

// ChainInfo returns the latest info of a chain with given ID
func (k Keeper) ChainInfo(c context.Context, req *types.QueryChainInfoRequest) (*types.QueryChainInfoResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

if len(req.ChainId) == 0 {
return nil, status.Error(codes.InvalidArgument, "chain ID cannot be empty")
}

ctx := sdk.UnwrapSDKContext(c)

// find the chain info of this epoch
chainInfo := k.GetChainInfo(ctx, req.ChainId)
resp := &types.QueryChainInfoResponse{ChainInfo: chainInfo}
return resp, nil
}

func (k Keeper) FinalizedChainInfo(c context.Context, req *types.QueryFinalizedChainInfoRequest) (*types.QueryFinalizedChainInfoResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
Expand Down
25 changes: 25 additions & 0 deletions x/zoneconcierge/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,31 @@ func FuzzChainList(f *testing.F) {
})
}

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

f.Fuzz(func(t *testing.T, seed int64) {
rand.Seed(seed)

_, babylonChain, czChain, zcKeeper := SetupTest(t)

ctx := babylonChain.GetContext()
hooks := zcKeeper.Hooks()

// invoke the hook a random number of times to simulate a random number of blocks
numHeaders := datagen.RandomInt(100) + 1
numForkHeaders := datagen.RandomInt(10) + 1
SimulateHeadersAndForksViaHook(ctx, hooks, czChain.ChainID, numHeaders, numForkHeaders)

// check if the chain info of is recorded or not
resp, err := zcKeeper.ChainInfo(ctx, &zctypes.QueryChainInfoRequest{ChainId: czChain.ChainID})
require.NoError(t, err)
chainInfo := resp.ChainInfo
require.Equal(t, numHeaders-1, chainInfo.LatestHeader.Height)
require.Equal(t, numForkHeaders, uint64(len(chainInfo.LatestForks.Headers)))
})
}

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

Expand Down
Loading