Skip to content

Commit e58cce2

Browse files
authored
Add rpc and cli command for getting an epoch (#3258)
1 parent b207205 commit e58cce2

File tree

11 files changed

+799
-37
lines changed

11 files changed

+799
-37
lines changed

indexer/packages/v4-protos/src/codegen/dydxprotocol/stats/query.lcd.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { LCDClient } from "@osmonauts/lcd";
2-
import { QueryParamsRequest, QueryParamsResponseSDKType, QueryStatsMetadataRequest, QueryStatsMetadataResponseSDKType, QueryGlobalStatsRequest, QueryGlobalStatsResponseSDKType, QueryUserStatsRequest, QueryUserStatsResponseSDKType } from "./query";
2+
import { QueryParamsRequest, QueryParamsResponseSDKType, QueryStatsMetadataRequest, QueryStatsMetadataResponseSDKType, QueryGlobalStatsRequest, QueryGlobalStatsResponseSDKType, QueryUserStatsRequest, QueryUserStatsResponseSDKType, QueryEpochStatsRequest, QueryEpochStatsResponseSDKType } from "./query";
33
export class LCDQueryClient {
44
req: LCDClient;
55

@@ -13,6 +13,7 @@ export class LCDQueryClient {
1313
this.statsMetadata = this.statsMetadata.bind(this);
1414
this.globalStats = this.globalStats.bind(this);
1515
this.userStats = this.userStats.bind(this);
16+
this.epochStats = this.epochStats.bind(this);
1617
}
1718
/* Queries the Params. */
1819

@@ -50,5 +51,12 @@ export class LCDQueryClient {
5051
const endpoint = `dydxprotocol/v4/stats/user_stats`;
5152
return await this.req.get<QueryUserStatsResponseSDKType>(endpoint, options);
5253
}
54+
/* Queries EpochStats for a specific epoch. */
55+
56+
57+
async epochStats(params: QueryEpochStatsRequest): Promise<QueryEpochStatsResponseSDKType> {
58+
const endpoint = `dydxprotocol/v4/stats/epoch_stats/${params.epoch}`;
59+
return await this.req.get<QueryEpochStatsResponseSDKType>(endpoint);
60+
}
5361

5462
}

indexer/packages/v4-protos/src/codegen/dydxprotocol/stats/query.rpc.Query.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Rpc } from "../../helpers";
22
import * as _m0 from "protobufjs/minimal";
33
import { QueryClient, createProtobufRpcClient } from "@cosmjs/stargate";
4-
import { QueryParamsRequest, QueryParamsResponse, QueryStatsMetadataRequest, QueryStatsMetadataResponse, QueryGlobalStatsRequest, QueryGlobalStatsResponse, QueryUserStatsRequest, QueryUserStatsResponse } from "./query";
4+
import { QueryParamsRequest, QueryParamsResponse, QueryStatsMetadataRequest, QueryStatsMetadataResponse, QueryGlobalStatsRequest, QueryGlobalStatsResponse, QueryUserStatsRequest, QueryUserStatsResponse, QueryEpochStatsRequest, QueryEpochStatsResponse } from "./query";
55
/** Query defines the gRPC querier service. */
66

77
export interface Query {
@@ -16,6 +16,9 @@ export interface Query {
1616
/** Queries UserStats. */
1717

1818
userStats(request: QueryUserStatsRequest): Promise<QueryUserStatsResponse>;
19+
/** Queries EpochStats for a specific epoch. */
20+
21+
epochStats(request: QueryEpochStatsRequest): Promise<QueryEpochStatsResponse>;
1922
}
2023
export class QueryClientImpl implements Query {
2124
private readonly rpc: Rpc;
@@ -26,6 +29,7 @@ export class QueryClientImpl implements Query {
2629
this.statsMetadata = this.statsMetadata.bind(this);
2730
this.globalStats = this.globalStats.bind(this);
2831
this.userStats = this.userStats.bind(this);
32+
this.epochStats = this.epochStats.bind(this);
2933
}
3034

3135
params(request: QueryParamsRequest = {}): Promise<QueryParamsResponse> {
@@ -52,6 +56,12 @@ export class QueryClientImpl implements Query {
5256
return promise.then(data => QueryUserStatsResponse.decode(new _m0.Reader(data)));
5357
}
5458

59+
epochStats(request: QueryEpochStatsRequest): Promise<QueryEpochStatsResponse> {
60+
const data = QueryEpochStatsRequest.encode(request).finish();
61+
const promise = this.rpc.request("dydxprotocol.stats.Query", "EpochStats", data);
62+
return promise.then(data => QueryEpochStatsResponse.decode(new _m0.Reader(data)));
63+
}
64+
5565
}
5666
export const createRpcQueryExtension = (base: QueryClient) => {
5767
const rpc = createProtobufRpcClient(base);
@@ -71,6 +81,10 @@ export const createRpcQueryExtension = (base: QueryClient) => {
7181

7282
userStats(request: QueryUserStatsRequest): Promise<QueryUserStatsResponse> {
7383
return queryService.userStats(request);
84+
},
85+
86+
epochStats(request: QueryEpochStatsRequest): Promise<QueryEpochStatsResponse> {
87+
return queryService.epochStats(request);
7488
}
7589

7690
};

indexer/packages/v4-protos/src/codegen/dydxprotocol/stats/query.ts

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Params, ParamsSDKType } from "./params";
2-
import { StatsMetadata, StatsMetadataSDKType, GlobalStats, GlobalStatsSDKType, UserStats, UserStatsSDKType } from "./stats";
2+
import { StatsMetadata, StatsMetadataSDKType, GlobalStats, GlobalStatsSDKType, UserStats, UserStatsSDKType, EpochStats, EpochStatsSDKType } from "./stats";
33
import * as _m0 from "protobufjs/minimal";
44
import { DeepPartial } from "../../helpers";
55
/** QueryParamsRequest is a request type for the Params RPC method. */
@@ -90,6 +90,30 @@ export interface QueryUserStatsResponseSDKType {
9090
/** QueryUserStatsResponse is a request type for the UserStats RPC method. */
9191
stats?: UserStatsSDKType;
9292
}
93+
/** QueryEpochStatsRequest is a request type for the EpochStats RPC method. */
94+
95+
export interface QueryEpochStatsRequest {
96+
/** QueryEpochStatsRequest is a request type for the EpochStats RPC method. */
97+
epoch: number;
98+
}
99+
/** QueryEpochStatsRequest is a request type for the EpochStats RPC method. */
100+
101+
export interface QueryEpochStatsRequestSDKType {
102+
/** QueryEpochStatsRequest is a request type for the EpochStats RPC method. */
103+
epoch: number;
104+
}
105+
/** QueryEpochStatsResponse is a response type for the EpochStats RPC method. */
106+
107+
export interface QueryEpochStatsResponse {
108+
/** QueryEpochStatsResponse is a response type for the EpochStats RPC method. */
109+
stats?: EpochStats;
110+
}
111+
/** QueryEpochStatsResponse is a response type for the EpochStats RPC method. */
112+
113+
export interface QueryEpochStatsResponseSDKType {
114+
/** QueryEpochStatsResponse is a response type for the EpochStats RPC method. */
115+
stats?: EpochStatsSDKType;
116+
}
93117

94118
function createBaseQueryParamsRequest(): QueryParamsRequest {
95119
return {};
@@ -416,4 +440,94 @@ export const QueryUserStatsResponse = {
416440
return message;
417441
}
418442

443+
};
444+
445+
function createBaseQueryEpochStatsRequest(): QueryEpochStatsRequest {
446+
return {
447+
epoch: 0
448+
};
449+
}
450+
451+
export const QueryEpochStatsRequest = {
452+
encode(message: QueryEpochStatsRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
453+
if (message.epoch !== 0) {
454+
writer.uint32(8).uint32(message.epoch);
455+
}
456+
457+
return writer;
458+
},
459+
460+
decode(input: _m0.Reader | Uint8Array, length?: number): QueryEpochStatsRequest {
461+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
462+
let end = length === undefined ? reader.len : reader.pos + length;
463+
const message = createBaseQueryEpochStatsRequest();
464+
465+
while (reader.pos < end) {
466+
const tag = reader.uint32();
467+
468+
switch (tag >>> 3) {
469+
case 1:
470+
message.epoch = reader.uint32();
471+
break;
472+
473+
default:
474+
reader.skipType(tag & 7);
475+
break;
476+
}
477+
}
478+
479+
return message;
480+
},
481+
482+
fromPartial(object: DeepPartial<QueryEpochStatsRequest>): QueryEpochStatsRequest {
483+
const message = createBaseQueryEpochStatsRequest();
484+
message.epoch = object.epoch ?? 0;
485+
return message;
486+
}
487+
488+
};
489+
490+
function createBaseQueryEpochStatsResponse(): QueryEpochStatsResponse {
491+
return {
492+
stats: undefined
493+
};
494+
}
495+
496+
export const QueryEpochStatsResponse = {
497+
encode(message: QueryEpochStatsResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
498+
if (message.stats !== undefined) {
499+
EpochStats.encode(message.stats, writer.uint32(10).fork()).ldelim();
500+
}
501+
502+
return writer;
503+
},
504+
505+
decode(input: _m0.Reader | Uint8Array, length?: number): QueryEpochStatsResponse {
506+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
507+
let end = length === undefined ? reader.len : reader.pos + length;
508+
const message = createBaseQueryEpochStatsResponse();
509+
510+
while (reader.pos < end) {
511+
const tag = reader.uint32();
512+
513+
switch (tag >>> 3) {
514+
case 1:
515+
message.stats = EpochStats.decode(reader, reader.uint32());
516+
break;
517+
518+
default:
519+
reader.skipType(tag & 7);
520+
break;
521+
}
522+
}
523+
524+
return message;
525+
},
526+
527+
fromPartial(object: DeepPartial<QueryEpochStatsResponse>): QueryEpochStatsResponse {
528+
const message = createBaseQueryEpochStatsResponse();
529+
message.stats = object.stats !== undefined && object.stats !== null ? EpochStats.fromPartial(object.stats) : undefined;
530+
return message;
531+
}
532+
419533
};

proto/dydxprotocol/stats/query.proto

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ service Query {
3030
rpc UserStats(QueryUserStatsRequest) returns (QueryUserStatsResponse) {
3131
option (google.api.http).get = "/dydxprotocol/v4/stats/user_stats";
3232
}
33+
34+
// Queries EpochStats for a specific epoch.
35+
rpc EpochStats(QueryEpochStatsRequest) returns (QueryEpochStatsResponse) {
36+
option (google.api.http).get = "/dydxprotocol/v4/stats/epoch_stats/{epoch}";
37+
}
3338
}
3439

3540
// QueryParamsRequest is a request type for the Params RPC method.
@@ -57,3 +62,8 @@ message QueryGlobalStatsResponse { GlobalStats stats = 1; }
5762
message QueryUserStatsRequest { string user = 1; }
5863
// QueryUserStatsResponse is a request type for the UserStats RPC method.
5964
message QueryUserStatsResponse { UserStats stats = 1; }
65+
66+
// QueryEpochStatsRequest is a request type for the EpochStats RPC method.
67+
message QueryEpochStatsRequest { uint32 epoch = 1; }
68+
// QueryEpochStatsResponse is a response type for the EpochStats RPC method.
69+
message QueryEpochStatsResponse { EpochStats stats = 1; }

protocol/x/epochs/keeper/keeper.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ type (
2020
func NewKeeper(
2121
cdc codec.BinaryCodec,
2222
storeKey storetypes.StoreKey,
23-
2423
) *Keeper {
2524
return &Keeper{
2625
cdc: cdc,

protocol/x/stats/client/cli/query.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cli
33
import (
44
"context"
55
"fmt"
6+
"strconv"
67

78
"github.com/cosmos/cosmos-sdk/client"
89
"github.com/cosmos/cosmos-sdk/client/flags"
@@ -25,6 +26,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command {
2526
cmd.AddCommand(CmdQueryStatsMetadata())
2627
cmd.AddCommand(CmdQueryGlobalStats())
2728
cmd.AddCommand(CmdQueryUserStats())
29+
cmd.AddCommand(CmdQueryEpochStats())
2830

2931
return cmd
3032
}
@@ -123,3 +125,34 @@ func CmdQueryUserStats() *cobra.Command {
123125

124126
return cmd
125127
}
128+
129+
func CmdQueryEpochStats() *cobra.Command {
130+
cmd := &cobra.Command{
131+
Use: "get-epoch-stats [epoch]",
132+
Short: "get stats for a specific epoch",
133+
Args: cobra.ExactArgs(1),
134+
RunE: func(cmd *cobra.Command, args []string) (err error) {
135+
epochNum, err := strconv.ParseUint(args[0], 10, 32)
136+
if err != nil {
137+
return fmt.Errorf("invalid epoch number: %w", err)
138+
}
139+
140+
clientCtx := client.GetClientContextFromCmd(cmd)
141+
queryClient := types.NewQueryClient(clientCtx)
142+
res, err := queryClient.EpochStats(
143+
context.Background(),
144+
&types.QueryEpochStatsRequest{
145+
Epoch: uint32(epochNum),
146+
},
147+
)
148+
if err != nil {
149+
return err
150+
}
151+
return clientCtx.PrintProto(res)
152+
},
153+
}
154+
155+
flags.AddQueryFlagsToCmd(cmd)
156+
157+
return cmd
158+
}

protocol/x/stats/client/cli/query_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,13 @@ func TestQueryUserStats(t *testing.T) {
8282
var resp types.QueryUserStatsResponse
8383
require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp))
8484
}
85+
86+
func TestQueryEpochStats(t *testing.T) {
87+
net, ctx := setupNetwork(t)
88+
89+
out, err := clitestutil.ExecTestCLICmd(ctx, cli.CmdQueryEpochStats(), []string{"0"})
90+
91+
require.NoError(t, err)
92+
var resp types.QueryEpochStatsResponse
93+
require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp))
94+
}

protocol/x/stats/keeper/grpc_query.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,29 @@ func (k Keeper) UserStats(
8383
Stats: userStats,
8484
}, nil
8585
}
86+
87+
func (k Keeper) EpochStats(
88+
c context.Context,
89+
req *types.QueryEpochStatsRequest,
90+
) (
91+
*types.QueryEpochStatsResponse,
92+
error,
93+
) {
94+
if req == nil {
95+
return nil, status.Error(codes.InvalidArgument, "invalid request")
96+
}
97+
98+
ctx := lib.UnwrapSDKContext(c, types.ModuleName)
99+
epochStats := k.GetEpochStatsOrNil(ctx, req.Epoch)
100+
101+
// Return empty stats if epoch not found
102+
if epochStats == nil {
103+
epochStats = &types.EpochStats{
104+
Stats: []*types.EpochStats_UserWithStats{},
105+
}
106+
}
107+
108+
return &types.QueryEpochStatsResponse{
109+
Stats: epochStats,
110+
}, nil
111+
}

0 commit comments

Comments
 (0)