diff --git a/x/wasm/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go index c29a829010..5a3b383130 100644 --- a/x/wasm/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - proto "github.com/gogo/protobuf/proto" abci "github.com/tendermint/tendermint/abci/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" @@ -275,7 +274,7 @@ func IBCQuerier(wasm contractMetaDataSource, channelKeeper types.ChannelKeeper) func StargateQuerier(queryRouter GRPCQueryRouter, codec codec.Codec) func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) { return func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) { - protoResponse, whitelisted := StargateWhitelist.Load(request.Path) + protoResponse, whitelisted := AcceptList.Load(request.Path) if !whitelisted { return nil, wasmvmtypes.UnsupportedRequest{Kind: fmt.Sprintf("'%s' path is not allowed from the contract", request.Path)} } @@ -548,20 +547,20 @@ func ConvertSdkCoinToWasmCoin(coin sdk.Coin) wasmvmtypes.Coin { // ConvertProtoToJSONMarshal unmarshals the given bytes into a proto message and then marshals it to json. // This is done so that clients calling stargate queries do not need to define their own proto unmarshalers, // being able to use response directly by json marshalling, which is supported in cosmwasm. -func ConvertProtoToJSONMarshal(protoResponse interface{}, bz []byte, codec codec.Codec) ([]byte, error) { +func ConvertProtoToJSONMarshal(protoResponse interface{}, bz []byte, cdc codec.Codec) ([]byte, error) { // all values are proto message - message, ok := protoResponse.(proto.Message) + message, ok := protoResponse.(codec.ProtoMarshaler) if !ok { return nil, wasmvmtypes.Unknown{} } // unmarshal binary into stargate response data structure - err := proto.Unmarshal(bz, message) + err := cdc.Unmarshal(bz, message) if err != nil { return nil, wasmvmtypes.Unknown{} } - bz, err = codec.MarshalJSON(message) + bz, err = cdc.MarshalJSON(message) if err != nil { return nil, wasmvmtypes.Unknown{} } diff --git a/x/wasm/keeper/query_plugins_test.go b/x/wasm/keeper/query_plugins_test.go index 1e287265b2..c6fdbc1c09 100644 --- a/x/wasm/keeper/query_plugins_test.go +++ b/x/wasm/keeper/query_plugins_test.go @@ -588,7 +588,7 @@ func TestConvertProtoToJSONMarshal(t *testing.T) { // check response by json marshalling proto response into json response manually jsonMarshalExpectedResponse, err := wasmApp.AppCodec().MarshalJSON(tc.expectedProtoResponse) require.NoError(t, err) - require.Equal(t, jsonMarshalledResponse, jsonMarshalExpectedResponse) + require.JSONEq(t, string(jsonMarshalledResponse), string(jsonMarshalExpectedResponse)) }) } } @@ -596,7 +596,6 @@ func TestConvertProtoToJSONMarshal(t *testing.T) { // TestDeterministicJsonMarshal tests that we get deterministic JSON marshalled response upon // proto struct update in the state machine. func TestDeterministicJsonMarshal(t *testing.T) { - testCases := []struct { name string originalResponse string @@ -605,50 +604,6 @@ func TestDeterministicJsonMarshal(t *testing.T) { responseProtoStruct interface{} expectedProto func() proto.Message }{ - - /** - * Origin Response - * balances: pagination: - * "0a090a036261721202333012050a03666f6f" - * - * New Version Response - * The binary built from the proto response with additional field address - * balances: pagination: address:"cosmos1j6j5tsquq2jlw2af7l3xekyaq7zg4l8jsufu78" - * "0a090a036261721202333012050a03666f6f1a2d636f736d6f73316a366a357473717571326a6c77326166376c3378656b796171377a67346c386a737566753738" - // Origin proto - message QueryAllBalancesResponse { - // balances is the balances of all the coins. - repeated cosmos.base.v1beta1.Coin balances = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; - } - // Updated proto - message QueryAllBalancesResponse { - // balances is the balances of all the coins. - repeated cosmos.base.v1beta1.Coin balances = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // address is the address to query all balances for. - string address = 3; - } - */ - { - "Query All Balances", - "0a090a036261721202333012050a03666f6f", - "0a090a036261721202333012050a03666f6f1a2d636f736d6f73316a366a357473717571326a6c77326166376c3378656b796171377a67346c386a737566753738", - "/cosmos.bank.v1beta1.Query/AllBalances", - &banktypes.QueryAllBalancesResponse{}, - func() proto.Message { - return &banktypes.QueryAllBalancesResponse{ - Balances: sdk.NewCoins(sdk.NewCoin("bar", sdk.NewInt(30))), - Pagination: &query.PageResponse{ - NextKey: []byte("foo"), - }, - } - }, - }, /** * * Origin Response @@ -690,38 +645,22 @@ func TestDeterministicJsonMarshal(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) { - // set up app for testing wasmApp := app.SetupWithEmptyStore(t) - // wasmApp := app.SetupWithEmptyStore(t) - // set up whitelist manually for testing - protoResponse, ok := tc.responseProtoStruct.(proto.Message) - require.True(t, ok) - keeper.StargateWhitelist.Store(tc.queryPath, protoResponse) - - // decode original response originVersionBz, err := hex.DecodeString(tc.originalResponse) require.NoError(t, err) - - // use proto response struct by loading from whitelist - loadedResponseStruct, ok := keeper.StargateWhitelist.Load(tc.queryPath) - require.True(t, ok) - protoResponse, ok = loadedResponseStruct.(proto.Message) - - jsonMarshalledOriginalBz, err := keeper.ConvertProtoToJSONMarshal(protoResponse, originVersionBz, wasmApp.AppCodec()) + jsonMarshalledOriginalBz, err := keeper.ConvertProtoToJSONMarshal(tc.responseProtoStruct, originVersionBz, wasmApp.AppCodec()) require.NoError(t, err) - wasmApp.AppCodec().MustUnmarshalJSON(jsonMarshalledOriginalBz, protoResponse) - newVersionBz, err := hex.DecodeString(tc.updatedResponse) require.NoError(t, err) - jsonMarshalledUpdatedBz, err := keeper.ConvertProtoToJSONMarshal(protoResponse, newVersionBz, wasmApp.AppCodec()) + jsonMarshalledUpdatedBz, err := keeper.ConvertProtoToJSONMarshal(tc.responseProtoStruct, newVersionBz, wasmApp.AppCodec()) require.NoError(t, err) - // json marshalled bytes should be the same since we use the same proto sturct for unmarshalling + // json marshalled bytes should be the same since we use the same proto struct for unmarshalling require.Equal(t, jsonMarshalledOriginalBz, jsonMarshalledUpdatedBz) - // raw build should also make same result + // raw build also make same result jsonMarshalExpectedResponse, err := wasmApp.AppCodec().MarshalJSON(tc.expectedProto()) require.NoError(t, err) require.Equal(t, jsonMarshalledUpdatedBz, jsonMarshalExpectedResponse) diff --git a/x/wasm/keeper/stargate_bindings.go b/x/wasm/keeper/stargate_bindings.go deleted file mode 100644 index a63b88a956..0000000000 --- a/x/wasm/keeper/stargate_bindings.go +++ /dev/null @@ -1,18 +0,0 @@ -package keeper - -import ( - "sync" -) - -// StargateWhitelist keeps whitelist and its deterministic -// response binding for stargate queries. -// -// The query can be multi-thread, so we have to use -// thread safe sync.Map. -var StargateWhitelist sync.Map - -// Define whitelists here as maps using 'StargateWhitelist' -// e.x) StargateWhitelist.Store("/cosmos.auth.v1beta1.Query/Account", &authtypes.QueryAccountResponse{}) -func init() { - -} diff --git a/x/wasm/keeper/stargate_whitelist.go b/x/wasm/keeper/stargate_whitelist.go new file mode 100644 index 0000000000..ce90738035 --- /dev/null +++ b/x/wasm/keeper/stargate_whitelist.go @@ -0,0 +1,18 @@ +package keeper + +import ( + "sync" +) + +// AcceptList keeps whitelist and its deterministic +// response binding for stargate queries. +// +// The query can be multi-thread, so we have to use +// thread safe sync.Map. +var AcceptList sync.Map + +// Define AcceptList here as maps using 'AcceptList' +// e.x) AcceptList.Store("/cosmos.auth.v1beta1.Query/Account", &authtypes.QueryAccountResponse{}) +func init() { + +}