Skip to content

Commit b98353e

Browse files
authored
Merge pull request cosmos#435 from CosmWasm/stargate-msg-and-query
Stargate msg and query
2 parents b09a925 + cec6dcd commit b98353e

9 files changed

+217
-36
lines changed

app/app.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -346,14 +346,12 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
346346
)
347347
app.evidenceKeeper = *evidenceKeeper
348348

349-
// just re-use the full router - do we want to limit this more?
350-
var wasmRouter = bApp.Router()
351349
wasmDir := filepath.Join(homePath, "wasm")
352-
353350
wasmConfig, err := wasm.ReadWasmConfig(appOpts)
354351
if err != nil {
355352
panic("error while reading wasm config: " + err.Error())
356353
}
354+
357355
// The last arguments can contain custom message handlers, and custom query handlers,
358356
// if we want to allow any custom callbacks
359357
supportedFeatures := "staking,stargate"
@@ -368,7 +366,8 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
368366
app.ibcKeeper.ChannelKeeper,
369367
&app.ibcKeeper.PortKeeper,
370368
scopedWasmKeeper,
371-
wasmRouter,
369+
app.Router(),
370+
app.GRPCQueryRouter(),
372371
wasmDir,
373372
wasmConfig,
374373
supportedFeatures,

x/wasm/internal/keeper/genesis_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) {
616616
wasmConfig := wasmTypes.DefaultWasmConfig()
617617
pk := paramskeeper.NewKeeper(encodingConfig.Marshaler, encodingConfig.Amino, keyParams, tkeyParams)
618618

619-
srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.DefaultParamspace), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, tempDir, wasmConfig, SupportedFeatures, nil, nil)
619+
srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.DefaultParamspace), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, tempDir, wasmConfig, SupportedFeatures, nil, nil)
620620
return &srcKeeper, ctx, []sdk.StoreKey{keyWasm, keyParams}
621621
}
622622

x/wasm/internal/keeper/handler_plugin.go

+45-18
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package keeper
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
67
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
8+
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
79
sdk "github.com/cosmos/cosmos-sdk/types"
810
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
911
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
@@ -20,8 +22,8 @@ type DefaultMessageHandler struct {
2022
encoders MessageEncoders
2123
}
2224

23-
func NewDefaultMessageHandler(router sdk.Router, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, customEncoders *MessageEncoders) DefaultMessageHandler {
24-
encoders := DefaultEncoders(channelKeeper, capabilityKeeper).Merge(customEncoders)
25+
func NewDefaultMessageHandler(router sdk.Router, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker, customEncoders *MessageEncoders) DefaultMessageHandler {
26+
encoders := DefaultEncoders(channelKeeper, capabilityKeeper, unpacker).Merge(customEncoders)
2527
return DefaultMessageHandler{
2628
router: router,
2729
encoders: encoders,
@@ -31,24 +33,27 @@ func NewDefaultMessageHandler(router sdk.Router, channelKeeper types.ChannelKeep
3133
type BankEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.BankMsg) ([]sdk.Msg, error)
3234
type CustomEncoder func(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error)
3335
type StakingEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.StakingMsg) ([]sdk.Msg, error)
36+
type StargateEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.StargateMsg) ([]sdk.Msg, error)
3437
type WasmEncoder func(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, error)
3538
type IBCEncoder func(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error)
3639

3740
type MessageEncoders struct {
38-
Bank BankEncoder
39-
Custom CustomEncoder
40-
Staking StakingEncoder
41-
Wasm WasmEncoder
42-
IBC IBCEncoder
41+
Bank BankEncoder
42+
Custom CustomEncoder
43+
IBC IBCEncoder
44+
Staking StakingEncoder
45+
Stargate StargateEncoder
46+
Wasm WasmEncoder
4347
}
4448

45-
func DefaultEncoders(channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper) MessageEncoders {
49+
func DefaultEncoders(channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker) MessageEncoders {
4650
return MessageEncoders{
47-
Bank: EncodeBankMsg,
48-
Custom: NoCustomMsg,
49-
Staking: EncodeStakingMsg,
50-
Wasm: EncodeWasmMsg,
51-
IBC: EncodeIBCMsg(channelKeeper, capabilityKeeper),
51+
Bank: EncodeBankMsg,
52+
Custom: NoCustomMsg,
53+
IBC: EncodeIBCMsg(channelKeeper, capabilityKeeper),
54+
Staking: EncodeStakingMsg,
55+
Stargate: EncodeStargateMsg(unpacker),
56+
Wasm: EncodeWasmMsg,
5257
}
5358
}
5459

@@ -62,15 +67,18 @@ func (e MessageEncoders) Merge(o *MessageEncoders) MessageEncoders {
6267
if o.Custom != nil {
6368
e.Custom = o.Custom
6469
}
70+
if o.IBC != nil {
71+
e.IBC = o.IBC
72+
}
6573
if o.Staking != nil {
6674
e.Staking = o.Staking
6775
}
76+
if o.Stargate != nil {
77+
e.Stargate = o.Stargate
78+
}
6879
if o.Wasm != nil {
6980
e.Wasm = o.Wasm
7081
}
71-
if o.IBC != nil {
72-
e.IBC = o.IBC
73-
}
7482
return e
7583
}
7684

@@ -80,12 +88,14 @@ func (e MessageEncoders) Encode(ctx sdk.Context, contractAddr sdk.AccAddress, co
8088
return e.Bank(contractAddr, msg.Bank)
8189
case msg.Custom != nil:
8290
return e.Custom(contractAddr, msg.Custom)
91+
case msg.IBC != nil:
92+
return e.IBC(ctx, contractAddr, contractIBCPortID, msg.IBC)
8393
case msg.Staking != nil:
8494
return e.Staking(contractAddr, msg.Staking)
95+
case msg.Stargate != nil:
96+
return e.Stargate(contractAddr, msg.Stargate)
8597
case msg.Wasm != nil:
8698
return e.Wasm(contractAddr, msg.Wasm)
87-
case msg.IBC != nil:
88-
return e.IBC(ctx, contractAddr, contractIBCPortID, msg.IBC)
8999
}
90100
return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of Wasm")
91101
}
@@ -170,6 +180,23 @@ func EncodeStakingMsg(sender sdk.AccAddress, msg *wasmvmtypes.StakingMsg) ([]sdk
170180
}
171181
}
172182

183+
func EncodeStargateMsg(unpacker codectypes.AnyUnpacker) StargateEncoder {
184+
return func(sender sdk.AccAddress, msg *wasmvmtypes.StargateMsg) ([]sdk.Msg, error) {
185+
any := codectypes.Any{
186+
TypeUrl: msg.TypeURL,
187+
Value: msg.Value,
188+
}
189+
var sdkMsg sdk.Msg
190+
if err := unpacker.UnpackAny(&any, &sdkMsg); err != nil {
191+
return nil, sdkerrors.Wrap(types.ErrInvalidMsg, fmt.Sprintf("Cannot unpack proto message with type URL: %s", msg.TypeURL))
192+
}
193+
if err := codectypes.UnpackInterfaces(sdkMsg, unpacker); err != nil {
194+
return nil, sdkerrors.Wrap(types.ErrInvalidMsg, fmt.Sprintf("UnpackInterfaces inside msg: %s", err))
195+
}
196+
return []sdk.Msg{sdkMsg}, nil
197+
}
198+
}
199+
173200
func EncodeWasmMsg(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, error) {
174201
switch {
175202
case msg.Execute != nil:

x/wasm/internal/keeper/handler_plugin_test.go

+35-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
99
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
1010
ibcexported "github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
11+
"github.com/golang/protobuf/proto"
1112
"testing"
1213

1314
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
@@ -32,6 +33,17 @@ func TestEncoding(t *testing.T) {
3233

3334
jsonMsg := json.RawMessage(`{"foo": 123}`)
3435

36+
bankMsg := &banktypes.MsgSend{
37+
FromAddress: addr2.String(),
38+
ToAddress: addr1.String(),
39+
Amount: sdk.Coins{
40+
sdk.NewInt64Coin("uatom", 12345),
41+
sdk.NewInt64Coin("utgd", 54321),
42+
},
43+
}
44+
bankMsgBin, err := proto.Marshal(bankMsg)
45+
require.NoError(t, err)
46+
3547
cases := map[string]struct {
3648
sender sdk.AccAddress
3749
srcMsg wasmvmtypes.CosmosMsg
@@ -276,6 +288,27 @@ func TestEncoding(t *testing.T) {
276288
},
277289
},
278290
},
291+
// TODO: alpe? can you add an example with sub-interfaces (where the UnpackInterfaces call would be needed)
292+
"stargate encoded bank msg": {
293+
sender: addr2,
294+
srcMsg: wasmvmtypes.CosmosMsg{
295+
Stargate: &wasmvmtypes.StargateMsg{
296+
TypeURL: "/cosmos.bank.v1beta1.MsgSend",
297+
Value: bankMsgBin,
298+
},
299+
},
300+
output: []sdk.Msg{bankMsg},
301+
},
302+
"stargate encoded invalid typeUrl": {
303+
sender: addr2,
304+
srcMsg: wasmvmtypes.CosmosMsg{
305+
Stargate: &wasmvmtypes.StargateMsg{
306+
TypeURL: "/cosmos.bank.v2.MsgSend",
307+
Value: bankMsgBin,
308+
},
309+
},
310+
isError: true,
311+
},
279312
"IBC transfer with block timeout": {
280313
sender: addr1,
281314
srcIBCPort: "myIBCPort",
@@ -355,7 +388,8 @@ func TestEncoding(t *testing.T) {
355388
},
356389
},
357390
}
358-
encoder := DefaultEncoders(nil, nil)
391+
encodingConfig := MakeEncodingConfig(t)
392+
encoder := DefaultEncoders(nil, nil, encodingConfig.Marshaler)
359393
for name, tc := range cases {
360394
tc := tc
361395
t.Run(name, func(t *testing.T) {

x/wasm/internal/keeper/keeper.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func NewKeeper(
8888
portKeeper types.PortKeeper,
8989
capabilityKeeper types.CapabilityKeeper,
9090
router sdk.Router,
91+
queryRouter GRPCQueryRouter,
9192
homeDir string,
9293
wasmConfig types.WasmConfig,
9394
supportedFeatures string,
@@ -105,7 +106,6 @@ func NewKeeper(
105106
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
106107
}
107108

108-
messageEncoders := DefaultEncoders(channelKeeper, capabilityKeeper).Merge(customEncoders)
109109
keeper := Keeper{
110110
storeKey: storeKey,
111111
cdc: cdc,
@@ -115,12 +115,12 @@ func NewKeeper(
115115
ChannelKeeper: channelKeeper,
116116
portKeeper: portKeeper,
117117
capabilityKeeper: capabilityKeeper,
118-
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, &messageEncoders),
118+
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, cdc, customEncoders),
119119
queryGasLimit: wasmConfig.SmartQueryGasLimit,
120120
authZPolicy: DefaultAuthorizationPolicy{},
121121
paramSpace: paramSpace,
122122
}
123-
keeper.queryPlugins = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, &keeper).Merge(customPlugins)
123+
keeper.queryPlugins = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, queryRouter, &keeper).Merge(customPlugins)
124124
for _, o := range opts {
125125
o.apply(&keeper)
126126
}

x/wasm/internal/keeper/options_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func TestConstructorOptions(t *testing.T) {
4343
nil,
4444
nil,
4545
nil,
46+
nil,
4647
"tempDir",
4748
types.DefaultWasmConfig(),
4849
SupportedFeatures,

x/wasm/internal/keeper/query_plugins.go

+49-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package keeper
22

33
import (
44
"encoding/json"
5+
"fmt"
56

67
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
78
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -11,13 +12,26 @@ import (
1112
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
1213
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
1314
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
15+
abci "github.com/tendermint/tendermint/abci/types"
1416
)
1517

1618
type QueryHandler struct {
1719
Ctx sdk.Context
1820
Plugins QueryPlugins
1921
}
2022

23+
// -- interfaces from baseapp - so we can use the GPRQueryRouter --
24+
25+
// GRPCQueryHandler defines a function type which handles ABCI Query requests
26+
// using gRPC
27+
type GRPCQueryHandler = func(ctx sdk.Context, req abci.RequestQuery) (abci.ResponseQuery, error)
28+
29+
type GRPCQueryRouter interface {
30+
Route(path string) GRPCQueryHandler
31+
}
32+
33+
// -- end baseapp interfaces --
34+
2135
var _ wasmvmtypes.Querier = QueryHandler{}
2236

2337
func (q QueryHandler) Query(request wasmvmtypes.QueryRequest, gasLimit uint64) ([]byte, error) {
@@ -40,6 +54,9 @@ func (q QueryHandler) Query(request wasmvmtypes.QueryRequest, gasLimit uint64) (
4054
if request.Staking != nil {
4155
return q.Plugins.Staking(subctx, request.Staking)
4256
}
57+
if request.Stargate != nil {
58+
return q.Plugins.Stargate(subctx, request.Stargate)
59+
}
4360
if request.Wasm != nil {
4461
return q.Plugins.Wasm(subctx, request.Wasm)
4562
}
@@ -53,18 +70,20 @@ func (q QueryHandler) GasConsumed() uint64 {
5370
type CustomQuerier func(ctx sdk.Context, request json.RawMessage) ([]byte, error)
5471

5572
type QueryPlugins struct {
56-
Bank func(ctx sdk.Context, request *wasmvmtypes.BankQuery) ([]byte, error)
57-
Custom CustomQuerier
58-
Staking func(ctx sdk.Context, request *wasmvmtypes.StakingQuery) ([]byte, error)
59-
Wasm func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error)
73+
Bank func(ctx sdk.Context, request *wasmvmtypes.BankQuery) ([]byte, error)
74+
Custom CustomQuerier
75+
Staking func(ctx sdk.Context, request *wasmvmtypes.StakingQuery) ([]byte, error)
76+
Stargate func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error)
77+
Wasm func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error)
6078
}
6179

62-
func DefaultQueryPlugins(bank bankkeeper.ViewKeeper, staking stakingkeeper.Keeper, distKeeper distributionkeeper.Keeper, wasm *Keeper) QueryPlugins {
80+
func DefaultQueryPlugins(bank bankkeeper.ViewKeeper, staking stakingkeeper.Keeper, distKeeper distributionkeeper.Keeper, queryRouter GRPCQueryRouter, wasm *Keeper) QueryPlugins {
6381
return QueryPlugins{
64-
Bank: BankQuerier(bank),
65-
Custom: NoCustomQuerier,
66-
Staking: StakingQuerier(staking, distKeeper),
67-
Wasm: WasmQuerier(wasm),
82+
Bank: BankQuerier(bank),
83+
Custom: NoCustomQuerier,
84+
Staking: StakingQuerier(staking, distKeeper),
85+
Stargate: StargateQuerier(queryRouter),
86+
Wasm: WasmQuerier(wasm),
6887
}
6988
}
7089

@@ -82,6 +101,9 @@ func (e QueryPlugins) Merge(o *QueryPlugins) QueryPlugins {
82101
if o.Staking != nil {
83102
e.Staking = o.Staking
84103
}
104+
if o.Stargate != nil {
105+
e.Stargate = o.Stargate
106+
}
85107
if o.Wasm != nil {
86108
e.Wasm = o.Wasm
87109
}
@@ -124,6 +146,24 @@ func NoCustomQuerier(sdk.Context, json.RawMessage) ([]byte, error) {
124146
return nil, wasmvmtypes.UnsupportedRequest{Kind: "custom"}
125147
}
126148

149+
func StargateQuerier(queryRouter GRPCQueryRouter) func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) {
150+
return func(ctx sdk.Context, msg *wasmvmtypes.StargateQuery) ([]byte, error) {
151+
route := queryRouter.Route(msg.Path)
152+
if route == nil {
153+
return nil, wasmvmtypes.UnsupportedRequest{Kind: fmt.Sprintf("No route to query '%s'", msg.Path)}
154+
}
155+
req := abci.RequestQuery{
156+
Data: msg.Data,
157+
Path: msg.Path,
158+
}
159+
res, err := route(ctx, req)
160+
if err != nil {
161+
return nil, err
162+
}
163+
return res.Value, nil
164+
}
165+
}
166+
127167
func StakingQuerier(keeper stakingkeeper.Keeper, distKeeper distributionkeeper.Keeper) func(ctx sdk.Context, request *wasmvmtypes.StakingQuery) ([]byte, error) {
128168
return func(ctx sdk.Context, request *wasmvmtypes.StakingQuery) ([]byte, error) {
129169
if request.BondedDenom != nil {

0 commit comments

Comments
 (0)