@@ -3,10 +3,12 @@ package keeper
3
3
import (
4
4
"encoding/json"
5
5
"errors"
6
+ "fmt"
6
7
7
8
abci "github.com/tendermint/tendermint/abci/types"
8
9
9
10
baseapp "github.com/Finschia/finschia-sdk/baseapp"
11
+ "github.com/Finschia/finschia-sdk/codec"
10
12
sdk "github.com/Finschia/finschia-sdk/types"
11
13
sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
12
14
distributiontypes "github.com/Finschia/finschia-sdk/x/distribution/types"
@@ -107,7 +109,7 @@ func DefaultQueryPlugins(
107
109
Custom : CustomQuerierImpl (queryRouter ),
108
110
IBC : IBCQuerier (wasm , channelKeeper ),
109
111
Staking : StakingQuerier (staking , distKeeper ),
110
- Stargate : StargateQuerier ( queryRouter ),
112
+ Stargate : RejectStargateQuerier ( ),
111
113
Wasm : WasmQuerier (wasm ),
112
114
}
113
115
}
@@ -302,9 +304,47 @@ func IBCQuerier(wasm contractMetaDataSource, channelKeeper types.ChannelKeeper)
302
304
}
303
305
}
304
306
305
- func StargateQuerier (queryRouter GRPCQueryRouter ) func (ctx sdk.Context , request * wasmvmtypes.StargateQuery ) ([]byte , error ) {
306
- return func (ctx sdk.Context , msg * wasmvmtypes.StargateQuery ) ([]byte , error ) {
307
- return nil , wasmvmtypes.UnsupportedRequest {Kind : "Stargate queries are disabled." }
307
+ // RejectStargateQuerier rejects all stargate queries
308
+ func RejectStargateQuerier () func (ctx sdk.Context , request * wasmvmtypes.StargateQuery ) ([]byte , error ) {
309
+ return func (ctx sdk.Context , request * wasmvmtypes.StargateQuery ) ([]byte , error ) {
310
+ return nil , wasmvmtypes.UnsupportedRequest {Kind : "Stargate queries are disabled" }
311
+ }
312
+ }
313
+
314
+ // AcceptedStargateQueries define accepted Stargate queries as a map with path as key and response type as value.
315
+ // For example:
316
+ // acceptList["/cosmos.auth.v1beta1.Query/Account"]= &authtypes.QueryAccountResponse{}
317
+ type AcceptedStargateQueries map [string ]codec.ProtoMarshaler
318
+
319
+ // AcceptListStargateQuerier supports a preconfigured set of stargate queries only.
320
+ // All arguments must be non nil.
321
+ //
322
+ // Warning: Chains need to test and maintain their accept list carefully.
323
+ // There were critical consensus breaking issues in the past with non-deterministic behaviour in the SDK.
324
+ //
325
+ // This queries can be set via WithQueryPlugins option in the wasm keeper constructor:
326
+ // WithQueryPlugins(&QueryPlugins{Stargate: AcceptListStargateQuerier(acceptList, queryRouter, codec)})
327
+ func AcceptListStargateQuerier (acceptList AcceptedStargateQueries , queryRouter GRPCQueryRouter , codec codec.Codec ) func (ctx sdk.Context , request * wasmvmtypes.StargateQuery ) ([]byte , error ) {
328
+ return func (ctx sdk.Context , request * wasmvmtypes.StargateQuery ) ([]byte , error ) {
329
+ protoResponse , accepted := acceptList [request .Path ]
330
+ if ! accepted {
331
+ return nil , wasmvmtypes.UnsupportedRequest {Kind : fmt .Sprintf ("'%s' path is not allowed from the contract" , request .Path )}
332
+ }
333
+
334
+ route := queryRouter .Route (request .Path )
335
+ if route == nil {
336
+ return nil , wasmvmtypes.UnsupportedRequest {Kind : fmt .Sprintf ("No route to query '%s'" , request .Path )}
337
+ }
338
+
339
+ res , err := route (ctx , abci.RequestQuery {
340
+ Data : request .Data ,
341
+ Path : request .Path ,
342
+ })
343
+ if err != nil {
344
+ return nil , err
345
+ }
346
+
347
+ return ConvertProtoToJSONMarshal (codec , protoResponse , res .Value )
308
348
}
309
349
}
310
350
@@ -551,6 +591,24 @@ func ConvertSdkCoinToWasmCoin(coin sdk.Coin) wasmvmtypes.Coin {
551
591
}
552
592
}
553
593
594
+ // ConvertProtoToJSONMarshal unmarshals the given bytes into a proto message and then marshals it to json.
595
+ // This is done so that clients calling stargate queries do not need to define their own proto unmarshalers,
596
+ // being able to use response directly by json marshalling, which is supported in cosmwasm.
597
+ func ConvertProtoToJSONMarshal (cdc codec.Codec , protoResponse codec.ProtoMarshaler , bz []byte ) ([]byte , error ) {
598
+ // unmarshal binary into stargate response data structure
599
+ err := cdc .Unmarshal (bz , protoResponse )
600
+ if err != nil {
601
+ return nil , sdkerrors .Wrap (err , "to proto" )
602
+ }
603
+
604
+ bz , err = cdc .MarshalJSON (protoResponse )
605
+ if err != nil {
606
+ return nil , sdkerrors .Wrap (err , "to json" )
607
+ }
608
+
609
+ return bz , nil
610
+ }
611
+
554
612
var _ WasmVMQueryHandler = WasmVMQueryHandlerFn (nil )
555
613
556
614
// WasmVMQueryHandlerFn is a helper to construct a function based query handler.
0 commit comments