@@ -3,15 +3,12 @@ package keeper
33import (
44 "bytes"
55 "context"
6- "fmt"
7- stdmath "math"
86 "math/big"
97
108 "github.com/vocdoni/circom2gnark/parser"
119
1210 "cosmossdk.io/collections"
1311 "cosmossdk.io/errors"
14- "cosmossdk.io/math"
1512
1613 sdk "github.com/cosmos/cosmos-sdk/types"
1714 "github.com/cosmos/cosmos-sdk/types/query"
@@ -48,6 +45,7 @@ func (k Querier) DkimPubKey(ctx context.Context, msg *types.QueryDkimPubKeyReque
4845
4946// DkimPubKeys implements types.QueryServer
5047func (k Querier ) DkimPubKeys (ctx context.Context , msg * types.QueryDkimPubKeysRequest ) (* types.QueryDkimPubKeysResponse , error ) {
48+ // Direct lookup when both domain and selector are provided
5149 if msg .Domain != "" && msg .Selector != "" {
5250 key := collections .Join (msg .Domain , msg .Selector )
5351 dkimPubKey , err := k .Keeper .DkimPubKeys .Get (ctx , key )
@@ -67,6 +65,27 @@ func (k Querier) DkimPubKeys(ctx context.Context, msg *types.QueryDkimPubKeysReq
6765 }, nil
6866 }
6967
68+ // Parse pagination parameters
69+ limit := uint64 (100 )
70+ offset := uint64 (0 )
71+ useKeyBasedPagination := false
72+ countTotal := false
73+ var paginationKey []byte
74+
75+ if msg .Pagination != nil {
76+ if msg .Pagination .Limit != 0 {
77+ limit = msg .Pagination .Limit
78+ }
79+ if len (msg .Pagination .Key ) > 0 {
80+ useKeyBasedPagination = true
81+ paginationKey = msg .Pagination .Key
82+ } else if msg .Pagination .Offset != 0 {
83+ offset = msg .Pagination .Offset
84+ }
85+ countTotal = msg .Pagination .CountTotal
86+ }
87+
88+ // Set up the iterator range
7089 var ranger collections.Ranger [collections.Pair [string , string ]]
7190 if msg .Domain != "" {
7291 ranger = collections.NewPrefixedPairRange [string , string ](msg .Domain )
@@ -78,17 +97,68 @@ func (k Querier) DkimPubKeys(ctx context.Context, msg *types.QueryDkimPubKeysReq
7897 }
7998 defer iter .Close ()
8099
81- var allPubKeys []* types.DkimPubKey
100+ keyCodec := k .Keeper .DkimPubKeys .KeyCodec ()
101+
102+ // For key-based pagination, fast-forward to the starting key
103+ if useKeyBasedPagination && len (paginationKey ) > 0 {
104+ for ; iter .Valid (); iter .Next () {
105+ fullKey , err := iter .Key ()
106+ if err != nil {
107+ return nil , err
108+ }
109+ buf := make ([]byte , 256 )
110+ n , err := keyCodec .EncodeNonTerminal (buf , fullKey )
111+ if err != nil {
112+ return nil , err
113+ }
114+ // Start from the first key >= pagination key
115+ if bytes .Compare (buf [:n ], paginationKey ) >= 0 {
116+ break
117+ }
118+ }
119+ }
120+
121+ // Collect results
122+ var results []* types.DkimPubKey
123+ var lastKey collections.Pair [string , string ]
124+ var hasLastKey bool
125+ skipped := uint64 (0 )
126+ collected := uint64 (0 )
127+ totalMatching := uint64 (0 )
128+
82129 for ; iter .Valid (); iter .Next () {
83130 dkimPubKey , err := iter .Value ()
84131 if err != nil {
85132 return nil , err
86133 }
87134
135+ // Apply PoseidonHash filter if specified
88136 if len (msg .PoseidonHash ) > 0 && ! bytes .Equal (dkimPubKey .PoseidonHash , msg .PoseidonHash ) {
89137 continue
90138 }
91139
140+ totalMatching ++
141+
142+ // For offset-based pagination (without key), skip first 'offset' matching records
143+ if ! useKeyBasedPagination && skipped < offset {
144+ skipped ++
145+ continue
146+ }
147+
148+ // Check if we've collected enough
149+ if collected >= limit {
150+ // We have one more record, so there's a next page
151+ if ! hasLastKey {
152+ lastKey , _ = iter .Key ()
153+ hasLastKey = true
154+ }
155+ // Continue iterating to count total if needed (for offset-based pagination or CountTotal)
156+ if ! countTotal && useKeyBasedPagination {
157+ break
158+ }
159+ continue
160+ }
161+
92162 pubKey := types.DkimPubKey {
93163 Domain : dkimPubKey .Domain ,
94164 PubKey : dkimPubKey .PubKey ,
@@ -97,62 +167,28 @@ func (k Querier) DkimPubKeys(ctx context.Context, msg *types.QueryDkimPubKeysReq
97167 Version : types .Version (dkimPubKey .Version ),
98168 KeyType : types .KeyType (dkimPubKey .KeyType ),
99169 }
100- allPubKeys = append (allPubKeys , & pubKey )
170+ results = append (results , & pubKey )
171+ collected ++
101172 }
102173
103- // Pagination
104- offset , limit := uint64 (0 ), uint64 (100 )
105- if msg .Pagination != nil {
106- if msg .Pagination .Offset != 0 {
107- offset = msg .Pagination .Offset
108- }
109- if msg .Pagination .Limit != 0 {
110- limit = msg .Pagination .Limit
111- } else {
112- limit = 100
174+ // Generate NextKey if there are more results
175+ var nextKey []byte
176+ if hasLastKey {
177+ buf := make ([]byte , 256 )
178+ n , err := keyCodec .EncodeNonTerminal (buf , lastKey )
179+ if err != nil {
180+ return nil , err
113181 }
182+ nextKey = buf [:n ]
114183 }
115184
116- allPubKeysLen := uint64 (len (allPubKeys ))
117-
118- // Safe conversion: check if offset is within bounds
119- if offset >= allPubKeysLen {
120- return & types.QueryDkimPubKeysResponse {
121- DkimPubKeys : []* types.DkimPubKey {},
122- Pagination : & query.PageResponse {
123- NextKey : nil ,
124- Total : allPubKeysLen ,
125- },
126- }, nil
127- }
128-
129- // Safe addition: check for overflow and bounds
130- endOffset := math .NewUint (offset ).Add (math .NewUint (limit ))
131- var end uint64
132- if endOffset .GT (math .NewUint (allPubKeysLen )) {
133- end = allPubKeysLen
134- } else {
135- end = endOffset .Uint64 ()
136- }
137-
138- // Safe conversion to int for slicing - validate against math.MaxInt to prevent overflow
139- if offset > uint64 (stdmath .MaxInt ) || end > uint64 (stdmath .MaxInt ) {
140- return nil , fmt .Errorf ("pagination offset or end exceeds maximum int value" )
141- }
142- offsetInt := int (offset )
143- endInt := int (end )
144- paginatedPubKeys := allPubKeys [offsetInt :endInt ]
145-
146- // TODO: Implement key-based pagination for nextKey when needed
147- nextKey := []byte (nil )
148-
149185 pageRes := & query.PageResponse {
150186 NextKey : nextKey ,
151- Total : allPubKeysLen ,
187+ Total : totalMatching ,
152188 }
153189
154190 return & types.QueryDkimPubKeysResponse {
155- DkimPubKeys : paginatedPubKeys ,
191+ DkimPubKeys : results ,
156192 Pagination : pageRes ,
157193 }, nil
158194}
@@ -281,59 +317,3 @@ func IsSubset[T comparable](a, b []T) bool {
281317 }
282318 return true
283319}
284-
285- // func convertPageRequest(request *query.PageRequest) *queryv1beta1.PageRequest {
286- // if request != nil {
287- // pageRequest := queryv1beta1.PageRequest{}
288- // pageRequest.CountTotal = request.CountTotal
289- // pageRequest.Key = request.Key
290- // pageRequest.Offset = request.Offset
291- // pageRequest.Limit = request.Limit
292- // pageRequest.Reverse = request.Reverse
293- // return &pageRequest
294- // }
295- // return nil
296- // }
297-
298- // func convertPageResponse(response *queryv1beta1.PageResponse) *query.PageResponse {
299- // if response != nil {
300- // pageResponse := query.PageResponse{}
301- // pageResponse.NextKey = response.NextKey
302- // pageResponse.Total = response.Total
303- // return &pageResponse
304- // }
305- // return nil
306- // }
307-
308- // func consumeIteratorResults(iterator collections.Iterator[collections.Pair[string, string], apiv1.DkimPubKey], domain string, poseidonHash []byte) ([]*types.DkimPubKey, error) {
309- // defer iterator.Close()
310-
311- // var output []*types.DkimPubKey
312- // for ; iterator.Valid(); iterator.Next() {
313- // dkimPubKey, err := iterator.Value()
314- // if err != nil {
315- // return nil, err
316- // }
317-
318- // match := true
319- // if domain != "" && dkimPubKey.Domain != domain {
320- // match = false
321- // }
322- // if len(poseidonHash) > 0 && !bytes.Equal(dkimPubKey.PoseidonHash, poseidonHash) {
323- // match = false
324- // }
325-
326- // if match {
327- // output = append(output, &types.DkimPubKey{
328- // Domain: dkimPubKey.Domain,
329- // PubKey: dkimPubKey.PubKey,
330- // Selector: dkimPubKey.Selector,
331- // PoseidonHash: dkimPubKey.PoseidonHash,
332- // Version: types.Version(dkimPubKey.Version),
333- // KeyType: types.KeyType(dkimPubKey.KeyType),
334- // })
335- // }
336- // }
337-
338- // return output, nil
339- // }
0 commit comments