Skip to content

Commit afa85da

Browse files
alpepinosu
andauthored
Set default query limit and ensure constraints (#1632)
* Set default query limit and ensure constraints * Update x/wasm/client/cli/query.go Co-authored-by: pinosu <[email protected]> --------- Co-authored-by: pinosu <[email protected]>
1 parent c12e85e commit afa85da

File tree

3 files changed

+147
-51
lines changed

3 files changed

+147
-51
lines changed

x/wasm/client/cli/query.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func GetCmdListCode() *cobra.Command {
144144
SilenceUsage: true,
145145
}
146146
flags.AddQueryFlagsToCmd(cmd)
147-
flags.AddPaginationFlagsToCmd(cmd, "list codes")
147+
addPaginationFlags(cmd, "list codes")
148148
return cmd
149149
}
150150

@@ -190,7 +190,7 @@ func GetCmdListContractByCode() *cobra.Command {
190190
SilenceUsage: true,
191191
}
192192
flags.AddQueryFlagsToCmd(cmd)
193-
flags.AddPaginationFlagsToCmd(cmd, "list contracts by code")
193+
addPaginationFlags(cmd, "list contracts by code")
194194
return cmd
195195
}
196196

@@ -368,10 +368,7 @@ func GetCmdGetContractStateAll() *cobra.Command {
368368
SilenceUsage: true,
369369
}
370370
flags.AddQueryFlagsToCmd(cmd)
371-
cmd.Flags().String(flags.FlagPageKey, "", "pagination page-key of contract state to query for")
372-
cmd.Flags().Uint64(flags.FlagLimit, 100, "pagination limit of contract state to query for")
373-
cmd.Flags().Bool(flags.FlagReverse, false, "results are sorted in descending order")
374-
371+
addPaginationFlags(cmd, "contract state")
375372
return cmd
376373
}
377374

@@ -507,7 +504,7 @@ func GetCmdGetContractHistory() *cobra.Command {
507504
}
508505

509506
flags.AddQueryFlagsToCmd(cmd)
510-
flags.AddPaginationFlagsToCmd(cmd, "contract history")
507+
addPaginationFlags(cmd, "contract history")
511508
return cmd
512509
}
513510

@@ -543,7 +540,7 @@ func GetCmdListPinnedCode() *cobra.Command {
543540
SilenceUsage: true,
544541
}
545542
flags.AddQueryFlagsToCmd(cmd)
546-
flags.AddPaginationFlagsToCmd(cmd, "list codes")
543+
addPaginationFlags(cmd, "list codes")
547544
return cmd
548545
}
549546

@@ -584,7 +581,7 @@ func GetCmdListContractsByCreator() *cobra.Command {
584581
SilenceUsage: true,
585582
}
586583
flags.AddQueryFlagsToCmd(cmd)
587-
flags.AddPaginationFlagsToCmd(cmd, "list contracts by creator")
584+
addPaginationFlags(cmd, "list contracts by creator")
588585
return cmd
589586
}
590587

@@ -677,3 +674,10 @@ func GetCmdQueryParams() *cobra.Command {
677674

678675
return cmd
679676
}
677+
678+
// supports a subset of the SDK pagination params for better resource utilization
679+
func addPaginationFlags(cmd *cobra.Command, query string) {
680+
cmd.Flags().String(flags.FlagPageKey, "", fmt.Sprintf("pagination page-key of %s to query for", query))
681+
cmd.Flags().Uint64(flags.FlagLimit, 100, fmt.Sprintf("pagination limit of %s to query for", query))
682+
cmd.Flags().Bool(flags.FlagReverse, false, "results are sorted in descending order")
683+
}

x/wasm/keeper/querier.go

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,15 @@ func (q GrpcQuerier) ContractHistory(c context.Context, req *types.QueryContract
6161
if err != nil {
6262
return nil, err
6363
}
64+
paginationParams, err := ensurePaginationParams(req.Pagination)
65+
if err != nil {
66+
return nil, err
67+
}
6468

6569
ctx := sdk.UnwrapSDKContext(c)
6670
r := make([]types.ContractCodeHistoryEntry, 0)
67-
6871
prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractCodeHistoryElementPrefix(contractAddr))
69-
pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) {
72+
pageRes, err := query.FilteredPaginate(prefixStore, paginationParams, func(key, value []byte, accumulate bool) (bool, error) {
7073
if accumulate {
7174
var e types.ContractCodeHistoryEntry
7275
if err := q.cdc.Unmarshal(value, &e); err != nil {
@@ -93,11 +96,15 @@ func (q GrpcQuerier) ContractsByCode(c context.Context, req *types.QueryContract
9396
if req.CodeId == 0 {
9497
return nil, errorsmod.Wrap(types.ErrInvalid, "code id")
9598
}
99+
paginationParams, err := ensurePaginationParams(req.Pagination)
100+
if err != nil {
101+
return nil, err
102+
}
103+
96104
ctx := sdk.UnwrapSDKContext(c)
97105
r := make([]string, 0)
98-
99106
prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractByCodeIDSecondaryIndexPrefix(req.CodeId))
100-
pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) {
107+
pageRes, err := query.FilteredPaginate(prefixStore, paginationParams, func(key, value []byte, accumulate bool) (bool, error) {
101108
if accumulate {
102109
var contractAddr sdk.AccAddress = key[types.AbsoluteTxPositionLen:]
103110
r = append(r, contractAddr.String())
@@ -117,14 +124,16 @@ func (q GrpcQuerier) AllContractState(c context.Context, req *types.QueryAllCont
117124
if req == nil {
118125
return nil, status.Error(codes.InvalidArgument, "empty request")
119126
}
120-
if req.Pagination != nil &&
121-
(req.Pagination.Offset != 0 || req.Pagination.CountTotal) {
122-
return nil, status.Error(codes.InvalidArgument, "offset and count queries not supported anymore")
123-
}
127+
124128
contractAddr, err := sdk.AccAddressFromBech32(req.Address)
125129
if err != nil {
126130
return nil, err
127131
}
132+
paginationParams, err := ensurePaginationParams(req.Pagination)
133+
if err != nil {
134+
return nil, err
135+
}
136+
128137
ctx := sdk.UnwrapSDKContext(c)
129138
if !q.keeper.HasContractInfo(ctx, contractAddr) {
130139
return nil, types.ErrNoSuchContractFn(contractAddr.String()).
@@ -133,7 +142,7 @@ func (q GrpcQuerier) AllContractState(c context.Context, req *types.QueryAllCont
133142

134143
r := make([]types.Model, 0)
135144
prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractStorePrefix(contractAddr))
136-
pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) {
145+
pageRes, err := query.FilteredPaginate(prefixStore, paginationParams, func(key, value []byte, accumulate bool) (bool, error) {
137146
if accumulate {
138147
r = append(r, types.Model{
139148
Key: key,
@@ -238,10 +247,15 @@ func (q GrpcQuerier) Codes(c context.Context, req *types.QueryCodesRequest) (*ty
238247
if req == nil {
239248
return nil, status.Error(codes.InvalidArgument, "empty request")
240249
}
250+
paginationParams, err := ensurePaginationParams(req.Pagination)
251+
if err != nil {
252+
return nil, err
253+
}
254+
241255
ctx := sdk.UnwrapSDKContext(c)
242256
r := make([]types.CodeInfoResponse, 0)
243257
prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.CodeKeyPrefix)
244-
pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) {
258+
pageRes, err := query.FilteredPaginate(prefixStore, paginationParams, func(key, value []byte, accumulate bool) (bool, error) {
245259
if accumulate {
246260
var c types.CodeInfo
247261
if err := q.cdc.Unmarshal(value, &c); err != nil {
@@ -302,11 +316,15 @@ func (q GrpcQuerier) PinnedCodes(c context.Context, req *types.QueryPinnedCodesR
302316
if req == nil {
303317
return nil, status.Error(codes.InvalidArgument, "empty request")
304318
}
319+
paginationParams, err := ensurePaginationParams(req.Pagination)
320+
if err != nil {
321+
return nil, err
322+
}
323+
305324
ctx := sdk.UnwrapSDKContext(c)
306325
r := make([]uint64, 0)
307-
308326
prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.PinnedCodeIndexPrefix)
309-
pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key, _ []byte, accumulate bool) (bool, error) {
327+
pageRes, err := query.FilteredPaginate(prefixStore, paginationParams, func(key, _ []byte, accumulate bool) (bool, error) {
310328
if accumulate {
311329
r = append(r, sdk.BigEndianToUint64(key))
312330
}
@@ -332,6 +350,11 @@ func (q GrpcQuerier) ContractsByCreator(c context.Context, req *types.QueryContr
332350
if req == nil {
333351
return nil, status.Error(codes.InvalidArgument, "empty request")
334352
}
353+
paginationParams, err := ensurePaginationParams(req.Pagination)
354+
if err != nil {
355+
return nil, err
356+
}
357+
335358
ctx := sdk.UnwrapSDKContext(c)
336359
contracts := make([]string, 0)
337360

@@ -340,7 +363,7 @@ func (q GrpcQuerier) ContractsByCreator(c context.Context, req *types.QueryContr
340363
return nil, err
341364
}
342365
prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractsByCreatorPrefix(creatorAddress))
343-
pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key, _ []byte, accumulate bool) (bool, error) {
366+
pageRes, err := query.FilteredPaginate(prefixStore, paginationParams, func(key, _ []byte, accumulate bool) (bool, error) {
344367
if accumulate {
345368
accAddres := sdk.AccAddress(key[types.AbsoluteTxPositionLen:])
346369
contracts = append(contracts, accAddres.String())
@@ -356,3 +379,25 @@ func (q GrpcQuerier) ContractsByCreator(c context.Context, req *types.QueryContr
356379
Pagination: pageRes,
357380
}, nil
358381
}
382+
383+
// max limit to pagination queries
384+
const maxResultEntries = 100
385+
386+
var errLegacyPaginationUnsupported = status.Error(codes.InvalidArgument, "offset and count queries not supported")
387+
388+
// ensure that pagination is done via key iterator with reasonable limit
389+
func ensurePaginationParams(req *query.PageRequest) (*query.PageRequest, error) {
390+
if req == nil {
391+
return &query.PageRequest{
392+
Key: nil,
393+
Limit: query.DefaultLimit,
394+
}, nil
395+
}
396+
if req.Offset != 0 || req.CountTotal {
397+
return nil, errLegacyPaginationUnsupported
398+
}
399+
if req.Limit > maxResultEntries || req.Limit <= 0 {
400+
req.Limit = maxResultEntries
401+
}
402+
return req, nil
403+
}

0 commit comments

Comments
 (0)