/
querier.go
142 lines (114 loc) · 4.13 KB
/
querier.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
package keeper
import (
"context"
"fmt"
"runtime/debug"
"github.com/terra-money/core/x/wasm/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
// querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over q
type querier struct {
Keeper
}
// NewQuerier returns an implementation of the market QueryServer interface
// for the provided Keeper.
func NewQuerier(keeper Keeper) types.QueryServer {
return &querier{Keeper: keeper}
}
var _ types.QueryServer = querier{}
// Params queries params of wasm module
func (q querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
return &types.QueryParamsResponse{Params: q.GetParams(ctx)}, nil
}
// CodeInfo returns the stored code info
func (q querier) CodeInfo(c context.Context, req *types.QueryCodeInfoRequest) (*types.QueryCodeInfoResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
codeInfo, err := q.GetCodeInfo(ctx, req.CodeId)
if err != nil {
return nil, status.Error(codes.NotFound, err.Error())
}
return &types.QueryCodeInfoResponse{CodeInfo: codeInfo}, nil
}
// ByteCode returns the stored byte code
func (q querier) ByteCode(c context.Context, req *types.QueryByteCodeRequest) (*types.QueryByteCodeResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
byteCode, err := q.GetByteCode(ctx, req.CodeId)
if err != nil {
return nil, status.Error(codes.NotFound, err.Error())
}
if len(byteCode) == 0 {
return nil, status.Error(codes.NotFound, "Code not found")
}
return &types.QueryByteCodeResponse{ByteCode: byteCode}, nil
}
// ContractInfo returns the stored contract info
func (q querier) ContractInfo(c context.Context, req *types.QueryContractInfoRequest) (*types.QueryContractInfoResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
contractAddr, err := sdk.AccAddressFromBech32(req.ContractAddress)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
contractInfo, err := q.GetContractInfo(ctx, contractAddr)
if err != nil {
return nil, status.Error(codes.NotFound, err.Error())
}
return &types.QueryContractInfoResponse{ContractInfo: contractInfo}, nil
}
// ContractStore return smart query result from the contract
func (q querier) ContractStore(c context.Context, req *types.QueryContractStoreRequest) (res *types.QueryContractStoreResponse, err error) {
ctx := sdk.UnwrapSDKContext(c)
// external query gas limit must be specified here
ctx = ctx.WithGasMeter(sdk.NewGasMeter(q.wasmConfig.ContractQueryGasLimit))
var contractAddr sdk.AccAddress
contractAddr, err = sdk.AccAddressFromBech32(req.ContractAddress)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
// recover from out-of-gas panic
defer func() {
if r := recover(); r != nil {
switch rType := r.(type) {
// TODO: Use ErrOutOfGas instead of ErrorOutOfGas which would allow us
// to keep the stracktrace.
case sdk.ErrorOutOfGas:
err = sdkerrors.Wrap(
sdkerrors.ErrOutOfGas, fmt.Sprintf(
"out of gas in location: %v; gasWanted: %d, gasUsed: %d",
rType.Descriptor, ctx.GasMeter().Limit(), ctx.GasMeter().GasConsumed(),
),
)
default:
err = sdkerrors.Wrap(
sdkerrors.ErrPanic, fmt.Sprintf(
"recovered: %v\nstack:\n%v", r, string(debug.Stack()),
),
)
}
res = nil
}
}()
bz, err := q.queryToContract(ctx, contractAddr, req.QueryMsg)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
res = &types.QueryContractStoreResponse{
QueryResult: bz,
}
return
}
// RawStore return single key from the raw store data of a contract
func (q querier) RawStore(c context.Context, req *types.QueryRawStoreRequest) (*types.QueryRawStoreResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
contractAddr, err := sdk.AccAddressFromBech32(req.ContractAddress)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
res := q.queryToStore(ctx, contractAddr, req.Key)
return &types.QueryRawStoreResponse{
Data: res,
}, nil
}