-
Notifications
You must be signed in to change notification settings - Fork 371
/
grpc_query.go
151 lines (128 loc) · 4.26 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package keeper
import (
"context"
"strings"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/kava-labs/kava/x/swap/types"
)
type queryServer struct {
keeper Keeper
}
// NewQueryServerImpl creates a new server for handling gRPC queries.
func NewQueryServerImpl(k Keeper) types.QueryServer {
return &queryServer{keeper: k}
}
var _ types.QueryServer = queryServer{}
// Params implements the gRPC service handler for querying x/swap parameters.
func (s queryServer) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
params := s.keeper.GetParams(sdkCtx)
return &types.QueryParamsResponse{Params: params}, nil
}
// Pools implements the Query/Pools gRPC method
func (s queryServer) Pools(c context.Context, req *types.QueryPoolsRequest) (*types.QueryPoolsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
store := prefix.NewStore(ctx.KVStore(s.keeper.key), types.PoolKeyPrefix)
var queryResults []types.PoolResponse
pageRes, err := query.FilteredPaginate(store, req.Pagination, func(_, value []byte, shouldAccumulate bool) (bool, error) {
var poolRecord types.PoolRecord
err := s.keeper.cdc.Unmarshal(value, &poolRecord)
if err != nil {
return false, err
}
if (len(req.PoolId) > 0) && strings.Compare(poolRecord.PoolID, req.PoolId) != 0 {
return false, nil
}
if shouldAccumulate {
denominatedPool, err := types.NewDenominatedPoolWithExistingShares(poolRecord.Reserves(), poolRecord.TotalShares)
if err != nil {
return true, types.ErrInvalidPool
}
totalCoins := denominatedPool.ShareValue(denominatedPool.TotalShares())
queryResult := types.PoolResponse{
Name: poolRecord.PoolID,
Coins: totalCoins,
TotalShares: denominatedPool.TotalShares(),
}
queryResults = append(queryResults, queryResult)
}
return true, nil
})
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err)
}
return &types.QueryPoolsResponse{
Pools: queryResults,
Pagination: pageRes,
}, nil
}
// Deposits implements the Query/Deposits gRPC method
func (s queryServer) Deposits(c context.Context, req *types.QueryDepositsRequest) (*types.QueryDepositsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
store := prefix.NewStore(ctx.KVStore(s.keeper.key), types.DepositorPoolSharesPrefix)
records := types.ShareRecords{}
pageRes, err := query.FilteredPaginate(
store,
req.Pagination,
func(key []byte, value []byte, accumulate bool) (bool, error) {
var record types.ShareRecord
err := s.keeper.cdc.Unmarshal(value, &record)
if err != nil {
return false, err
}
// Filter for results match the request's pool ID/owner params if given
matchOwner, matchPool := true, true
if len(req.Owner) > 0 {
matchOwner = record.Depositor.String() == req.Owner
}
if len(req.PoolId) > 0 {
matchPool = strings.Compare(record.PoolID, req.PoolId) == 0
}
if !(matchOwner && matchPool) {
// inform paginate that there was no match on this key
return false, nil
}
if accumulate {
// only add to results if paginate tells us to
records = append(records, record)
}
// inform paginate that were was a match on this key
return true, nil
},
)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
var queryResults []types.DepositResponse
for _, record := range records {
pool, err := s.keeper.loadDenominatedPool(ctx, record.PoolID)
if err != nil {
return nil, err
}
shareValue := pool.ShareValue(record.SharesOwned)
queryResult := types.DepositResponse{
Depositor: record.Depositor.String(),
PoolId: record.PoolID,
SharesOwned: record.SharesOwned,
SharesValue: shareValue,
}
queryResults = append(queryResults, queryResult)
}
return &types.QueryDepositsResponse{
Deposits: queryResults,
Pagination: pageRes,
}, nil
}