-
Notifications
You must be signed in to change notification settings - Fork 74
/
grpc_query.go
127 lines (99 loc) · 4.29 KB
/
grpc_query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package keeper
import (
"context"
"cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
querytypes "github.com/cosmos/cosmos-sdk/types/query"
contypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"
tndtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint"
"github.com/gogo/protobuf/proto"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/neutron-org/neutron/v3/x/interchainqueries/types"
)
var _ types.QueryServer = Keeper{}
func (k Keeper) RegisteredQuery(goCtx context.Context, request *types.QueryRegisteredQueryRequest) (*types.QueryRegisteredQueryResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
registeredQuery, err := k.GetQueryByID(ctx, request.QueryId)
if err != nil {
return nil, errors.Wrapf(types.ErrInvalidQueryID, "failed to get registered query by query id: %v", err)
}
return &types.QueryRegisteredQueryResponse{RegisteredQuery: registeredQuery}, nil
}
func (k Keeper) RegisteredQueries(goCtx context.Context, req *types.QueryRegisteredQueriesRequest) (*types.QueryRegisteredQueriesResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
return k.GetRegisteredQueries(ctx, req)
}
func (k Keeper) GetRegisteredQueries(ctx sdk.Context, req *types.QueryRegisteredQueriesRequest) (*types.QueryRegisteredQueriesResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
var (
store = prefix.NewStore(ctx.KVStore(k.storeKey), types.RegisteredQueryKey)
queries []types.RegisteredQuery
)
owners := newOwnersStore(req.GetOwners())
pageRes, err := querytypes.FilteredPaginate(store, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) {
query := types.RegisteredQuery{}
k.cdc.MustUnmarshal(value, &query)
var (
passedOwnerFilter = owners.Has(query.GetOwner())
passedConnectionIDFilter = req.GetConnectionId() == "" || query.ConnectionId == req.GetConnectionId()
)
// if result does not satisfy the filter, return (false, nil) to tell FilteredPaginate method to skip this value
if !(passedOwnerFilter && passedConnectionIDFilter) {
return false, nil
}
// when accumulate equals true, it means we are in the right offset/limit position
// so we check value satisfies the filter and add it to the final result slice
if accumulate && passedOwnerFilter && passedConnectionIDFilter {
queries = append(queries, query)
}
return true, nil
})
if err != nil {
return nil, status.Errorf(codes.Internal, "paginate: %v", err)
}
return &types.QueryRegisteredQueriesResponse{RegisteredQueries: queries, Pagination: pageRes}, nil
}
func (k Keeper) QueryResult(goCtx context.Context, request *types.QueryRegisteredQueryResultRequest) (*types.QueryRegisteredQueryResultResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
if !k.checkRegisteredQueryExists(ctx, request.QueryId) {
return nil, errors.Wrapf(types.ErrInvalidQueryID, "query with id %d doesn't exist", request.QueryId)
}
result, err := k.GetQueryResultByID(ctx, request.QueryId)
if err != nil {
return nil, errors.Wrapf(err, "failed to get query result by query id: %v", err)
}
return &types.QueryRegisteredQueryResultResponse{Result: result}, nil
}
func (k Keeper) LastRemoteHeight(goCtx context.Context, request *types.QueryLastRemoteHeight) (*types.QueryLastRemoteHeightResponse, error) {
req := contypes.QueryConnectionClientStateRequest{ConnectionId: request.ConnectionId}
r, err := k.ibcKeeper.ConnectionClientState(goCtx, &req)
if err != nil {
return nil, errors.Wrapf(types.ErrInvalidConnectionID, "connection not found")
}
clientState := r.GetIdentifiedClientState().GetClientState()
m := new(tndtypes.ClientState)
err = proto.Unmarshal(clientState.Value, m)
if err != nil {
return nil, errors.Wrapf(types.ErrProtoUnmarshal, "can't unmarshal client state")
}
return &types.QueryLastRemoteHeightResponse{Height: m.LatestHeight.RevisionHeight}, nil
}
type ownersStore map[string]bool
func newOwnersStore(ownerAddrs []string) ownersStore {
out := map[string]bool{}
for _, owner := range ownerAddrs {
out[owner] = true
}
return out
}
// Has returns true either if the store is empty or if the sore contains a given address.
func (o ownersStore) Has(addr string) bool {
if len(o) == 0 {
return true
}
return o[addr]
}