Skip to content

Commit

Permalink
Introduce new interfaces for extendability
Browse files Browse the repository at this point in the history
  • Loading branch information
alpe committed Mar 22, 2021
1 parent cfcfa64 commit ea33f64
Show file tree
Hide file tree
Showing 20 changed files with 184 additions and 89 deletions.
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
if len(enabledProposals) != 0 {
govRouter.AddRoute(wasm.RouterKey, wasm.NewWasmProposalHandler(app.wasmKeeper, enabledProposals))
}
ibcRouter.AddRoute(wasm.ModuleName, wasm.NewIBCHandler(app.wasmKeeper))
ibcRouter.AddRoute(wasm.ModuleName, wasm.NewIBCHandler(app.wasmKeeper, app.ibcKeeper.ChannelKeeper))
app.ibcKeeper.SetRouter(ibcRouter)

app.govKeeper = govkeeper.NewKeeper(
Expand Down
6 changes: 3 additions & 3 deletions x/wasm/alias.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// nolint
// autogenerated code using github.com/rigelrozanski/multitool
// aliases generated for the following subdirectories:
// ALIASGEN: github.com/cosmwasm/wasmd/x/wasm/types
// ALIASGEN: github.com/cosmwasm/wasmd/x/wasm/keeper
// ALIASGEN: github.com/Cosmwasm/wasmd/x/wasm/types
// ALIASGEN: github.com/CosmWasm/wasmd/x/wasm/keeper
package wasm

import (
Expand Down Expand Up @@ -76,7 +76,7 @@ var (
CreateTestInput = keeper.CreateTestInput
TestHandler = keeper.TestHandler
NewWasmProposalHandler = keeper.NewWasmProposalHandler
NewQuerier = keeper.NewQuerier
NewQuerier = keeper.Querier
ContractFromPortID = keeper.ContractFromPortID
WithWasmEngine = keeper.WithWasmEngine

Expand Down
2 changes: 1 addition & 1 deletion x/wasm/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

// NewHandler returns a handler for "bank" type messages.
func NewHandler(k *Keeper) sdk.Handler {
func NewHandler(k types.MsgOpsKeeper) sdk.Handler {
msgServer := keeper.NewMsgServerImpl(k)

return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
Expand Down
12 changes: 6 additions & 6 deletions x/wasm/ibc.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package wasm

import (
wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types"
types "github.com/CosmWasm/wasmd/x/wasm/types"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand All @@ -15,12 +15,12 @@ import (
var _ porttypes.IBCModule = IBCHandler{}

type IBCHandler struct {
keeper Keeper
channelKeeper wasmTypes.ChannelKeeper
keeper types.IBCContractKeeper
channelKeeper types.ChannelKeeper
}

func NewIBCHandler(keeper Keeper) IBCHandler {
return IBCHandler{keeper: keeper, channelKeeper: keeper.ChannelKeeper}
func NewIBCHandler(k types.IBCContractKeeper, ck types.ChannelKeeper) IBCHandler {
return IBCHandler{keeper: k, channelKeeper: ck}
}

// OnChanOpenInit implements the IBCModule interface
Expand Down Expand Up @@ -265,7 +265,7 @@ func ValidateChannelParams(channelID string) error {
return err
}
if channelSequence > math.MaxUint32 {
return sdkerrors.Wrapf(wasmTypes.ErrMaxIBCChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, math.MaxUint32)
return sdkerrors.Wrapf(types.ErrMaxIBCChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, math.MaxUint32)
}
return nil
}
8 changes: 4 additions & 4 deletions x/wasm/keeper/handler_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type SDKMessageHandler struct {
encoders msgEncoder
}

func NewDefaultMessageHandler(router sdk.Router, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker, portSource types.ICS20TransferPortSource, customEncoders ...*MessageEncoders) messenger {
func NewDefaultMessageHandler(router sdk.Router, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker, portSource types.ICS20TransferPortSource, customEncoders ...*MessageEncoders) Messenger {
encoders := DefaultEncoders(unpacker, portSource)
for _, e := range customEncoders {
encoders = encoders.Merge(e)
Expand Down Expand Up @@ -89,11 +89,11 @@ func (h SDKMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Ad

// MessageHandlerChain defines a chain of handlers that are called one by one until it can be handled.
type MessageHandlerChain struct {
handlers []messenger
handlers []Messenger
}

func NewMessageHandlerChain(first messenger, others ...messenger) *MessageHandlerChain {
r := &MessageHandlerChain{handlers: append([]messenger{first}, others...)}
func NewMessageHandlerChain(first Messenger, others ...Messenger) *MessageHandlerChain {
r := &MessageHandlerChain{handlers: append([]Messenger{first}, others...)}
for i := range r.handlers {
if r.handlers[i] == nil {
panic(fmt.Sprintf("handler must not be nil at position : %d", i))
Expand Down
14 changes: 7 additions & 7 deletions x/wasm/keeper/handler_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,28 @@ func TestMessageHandlerChainDispatch(t *testing.T) {

myMsg := wasmvmtypes.CosmosMsg{Custom: []byte(`{}`)}
specs := map[string]struct {
handlers []messenger
handlers []Messenger
expErr *sdkerrors.Error
expEvents []sdk.Event
}{
"single handler": {
handlers: []messenger{capturingHandler},
handlers: []Messenger{capturingHandler},
},
"passed to next handler": {
handlers: []messenger{alwaysUnknownMsgHandler, capturingHandler},
handlers: []Messenger{alwaysUnknownMsgHandler, capturingHandler},
},
"stops iteration when handled": {
handlers: []messenger{capturingHandler, assertNotCalledHandler},
handlers: []Messenger{capturingHandler, assertNotCalledHandler},
},
"stops iteration on handler error": {
handlers: []messenger{&wasmtesting.MockMessageHandler{
handlers: []Messenger{&wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
return nil, nil, types.ErrInvalidMsg
}}, assertNotCalledHandler},
expErr: types.ErrInvalidMsg,
},
"return events when handle": {
handlers: []messenger{&wasmtesting.MockMessageHandler{
handlers: []Messenger{&wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
_, data, _ = capturingHandler.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
return []sdk.Event{sdk.NewEvent("myEvent", sdk.NewAttribute("foo", "bar"))}, data, nil
Expand All @@ -63,7 +63,7 @@ func TestMessageHandlerChainDispatch(t *testing.T) {
expEvents: []sdk.Event{sdk.NewEvent("myEvent", sdk.NewAttribute("foo", "bar"))},
},
"return error when none can handle": {
handlers: []messenger{alwaysUnknownMsgHandler},
handlers: []Messenger{alwaysUnknownMsgHandler},
expErr: types.ErrUnknownMsg,
},
}
Expand Down
30 changes: 21 additions & 9 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ type Option interface {
}

// WasmVMQueryHandler is an extension point for custom query handler implementations
type wasmVMQueryHandler interface {
type WASMVMQueryHandler interface {
// HandleQuery executes the requested query
HandleQuery(ctx sdk.Context, caller sdk.AccAddress, request wasmvmtypes.QueryRequest) ([]byte, error)
}

// messenger is an extension point for custom wasmVM message handling
type messenger interface {
// Messenger is an extension point for custom wasmVM message handling
type Messenger interface {
// DispatchMsg encodes the wasmVM message and dispatches it.
DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error)
}
Expand All @@ -73,12 +73,11 @@ type Keeper struct {
cdc codec.Marshaler
accountKeeper types.AccountKeeper
bank coinTransferrer
ChannelKeeper types.ChannelKeeper
portKeeper types.PortKeeper
capabilityKeeper types.CapabilityKeeper
wasmVM types.WasmerEngine
wasmVMQueryHandler wasmVMQueryHandler
messenger messenger
wasmVMQueryHandler WASMVMQueryHandler
messenger Messenger
// queryGasLimit is the max wasmvm gas that can be spent on executing a query with a contract
queryGasLimit uint64
authZPolicy AuthorizationPolicy
Expand Down Expand Up @@ -121,7 +120,6 @@ func NewKeeper(
wasmVM: wasmer,
accountKeeper: accountKeeper,
bank: NewBankCoinTransferrer(bankKeeper),
ChannelKeeper: channelKeeper,
portKeeper: portKeeper,
capabilityKeeper: capabilityKeeper,
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, cdc, portSource),
Expand Down Expand Up @@ -647,7 +645,7 @@ func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress)
return &contract
}

func (k Keeper) containsContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) bool {
func (k Keeper) HasContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) bool {
store := ctx.KVStore(k.storeKey)
return store.Has(types.GetContractAddressKey(contractAddress))
}
Expand Down Expand Up @@ -1003,7 +1001,7 @@ func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, c *
if !k.containsCodeInfo(ctx, c.CodeID) {
return sdkerrors.Wrapf(types.ErrNotFound, "code id: %d", c.CodeID)
}
if k.containsContractInfo(ctx, contractAddr) {
if k.HasContractInfo(ctx, contractAddr) {
return sdkerrors.Wrapf(types.ErrDuplicate, "contract: %s", contractAddr)
}

Expand Down Expand Up @@ -1039,9 +1037,23 @@ func gasMeter(ctx sdk.Context) MultipliedGasMeter {

// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return moduleLogger(ctx)
}

func moduleLogger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}

// Querier creates a new grpc querier instance
func Querier(k *Keeper) *grpcQuerier {
return NewGrpcQuerier(k.cdc, k.storeKey, k, k.queryGasLimit)
}

// QueryGasLimit returns the gas limit for smart queries.
func (k Keeper) QueryGasLimit() sdk.Gas {
return k.queryGasLimit
}

// CoinTransferrer replicates the cosmos-sdk behaviour as in
// https://github.com/cosmos/cosmos-sdk/blob/v0.41.4/x/bank/keeper/msg_server.go#L26
type CoinTransferrer struct {
Expand Down
22 changes: 11 additions & 11 deletions x/wasm/keeper/legacy_querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const (
)

// NewLegacyQuerier creates a new querier
func NewLegacyQuerier(keeper *Keeper) sdk.Querier {
func NewLegacyQuerier(keeper types.ViewKeeper, gasLimit sdk.Gas) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) {
var (
rsp interface{}
Expand All @@ -41,32 +41,32 @@ func NewLegacyQuerier(keeper *Keeper) sdk.Querier {
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, err.Error())
}
rsp, err = queryContractInfo(ctx, addr, *keeper)
rsp, err = queryContractInfo(ctx, addr, keeper)
case QueryListContractByCode:
codeID, err := strconv.ParseUint(path[1], 10, 64)
if err != nil {
return nil, sdkerrors.Wrapf(types.ErrInvalid, "code id: %s", err.Error())
}
rsp, err = queryContractListByCode(ctx, codeID, *keeper)
rsp, err = queryContractListByCode(ctx, codeID, keeper)
case QueryGetContractState:
if len(path) < 3 {
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown data query endpoint")
}
return queryContractState(ctx, path[1], path[2], req.Data, keeper)
return queryContractState(ctx, path[1], path[2], req.Data, gasLimit, keeper)
case QueryGetCode:
codeID, err := strconv.ParseUint(path[1], 10, 64)
if err != nil {
return nil, sdkerrors.Wrapf(types.ErrInvalid, "code id: %s", err.Error())
}
rsp, err = queryCode(ctx, codeID, keeper)
case QueryListCode:
rsp, err = queryCodeList(ctx, *keeper)
rsp, err = queryCodeList(ctx, keeper)
case QueryContractHistory:
contractAddr, err := sdk.AccAddressFromBech32(path[1])
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, err.Error())
}
rsp, err = queryContractHistory(ctx, contractAddr, *keeper)
rsp, err = queryContractHistory(ctx, contractAddr, keeper)
default:
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown data query endpoint")
}
Expand All @@ -84,7 +84,7 @@ func NewLegacyQuerier(keeper *Keeper) sdk.Querier {
}
}

func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, keeper *Keeper) (json.RawMessage, error) {
func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, gasLimit sdk.Gas, keeper types.ViewKeeper) (json.RawMessage, error) {
contractAddr, err := sdk.AccAddressFromBech32(bech)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, bech)
Expand All @@ -108,7 +108,7 @@ func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte,
return keeper.QueryRaw(ctx, contractAddr, data), nil
case QueryMethodContractStateSmart:
// we enforce a subjective gas limit on all queries to avoid infinite loops
ctx = ctx.WithGasMeter(sdk.NewGasMeter(keeper.queryGasLimit))
ctx = ctx.WithGasMeter(sdk.NewGasMeter(gasLimit))
// this returns raw bytes (must be base64-encoded)
return keeper.QuerySmart(ctx, contractAddr, data)
default:
Expand All @@ -121,7 +121,7 @@ func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte,
return bz, nil
}

func queryCodeList(ctx sdk.Context, keeper Keeper) ([]types.CodeInfoResponse, error) {
func queryCodeList(ctx sdk.Context, keeper types.ViewKeeper) ([]types.CodeInfoResponse, error) {
var info []types.CodeInfoResponse
keeper.IterateCodeInfos(ctx, func(i uint64, res types.CodeInfo) bool {
info = append(info, types.CodeInfoResponse{
Expand All @@ -136,7 +136,7 @@ func queryCodeList(ctx sdk.Context, keeper Keeper) ([]types.CodeInfoResponse, er
return info, nil
}

func queryContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, keeper Keeper) ([]types.ContractCodeHistoryEntry, error) {
func queryContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, keeper types.ViewKeeper) ([]types.ContractCodeHistoryEntry, error) {
history := keeper.GetContractHistory(ctx, contractAddr)
// redact response
for i := range history {
Expand All @@ -145,7 +145,7 @@ func queryContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, keeper K
return history, nil
}

func queryContractListByCode(ctx sdk.Context, codeID uint64, keeper Keeper) ([]types.ContractInfoWithAddress, error) {
func queryContractListByCode(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) ([]types.ContractInfoWithAddress, error) {
var contracts []types.ContractInfoWithAddress
keeper.IterateContractInfo(ctx, func(addr sdk.AccAddress, info types.ContractInfo) bool {
if info.CodeID == codeID {
Expand Down
15 changes: 11 additions & 4 deletions x/wasm/keeper/legacy_querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ func TestLegacyQueryContractState(t *testing.T) {
keeper.importContractState(ctx, addr, contractModel)

// this gets us full error, not redacted sdk.Error
q := NewLegacyQuerier(keeper)
var defaultQueryGasLimit sdk.Gas = 3000000
q := NewLegacyQuerier(keeper, defaultQueryGasLimit)

specs := map[string]struct {
srcPath []string
srcReq abci.RequestQuery
Expand Down Expand Up @@ -195,7 +197,9 @@ func TestLegacyQueryContractListByCodeOrdering(t *testing.T) {
}

// query and check the results are properly sorted
q := NewLegacyQuerier(keeper)
var defaultQueryGasLimit sdk.Gas = 3000000
q := NewLegacyQuerier(keeper, defaultQueryGasLimit)

query := []string{QueryListContractByCode, fmt.Sprintf("%d", codeID)}
data := abci.RequestQuery{}
res, err := q(ctx, query, data)
Expand Down Expand Up @@ -287,7 +291,9 @@ func TestLegacyQueryContractHistory(t *testing.T) {
t.Run(msg, func(t *testing.T) {
_, _, myContractAddr := keyPubAddr()
keeper.appendToContractHistory(ctx, myContractAddr, spec.srcHistory...)
q := NewLegacyQuerier(keeper)

var defaultQueryGasLimit sdk.Gas = 3000000
q := NewLegacyQuerier(keeper, defaultQueryGasLimit)
queryContractAddr := spec.srcQueryAddr
if queryContractAddr == nil {
queryContractAddr = myContractAddr
Expand Down Expand Up @@ -336,7 +342,8 @@ func TestLegacyQueryCodeList(t *testing.T) {
wasmCode),
)
}
q := NewLegacyQuerier(keeper)
var defaultQueryGasLimit sdk.Gas = 3000000
q := NewLegacyQuerier(keeper, defaultQueryGasLimit)
// when
query := []string{QueryListCode}
data := abci.RequestQuery{}
Expand Down
4 changes: 2 additions & 2 deletions x/wasm/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
var _ types.MsgServer = msgServer{}

type msgServer struct {
keeper *Keeper
keeper types.MsgOpsKeeper
}

func NewMsgServerImpl(k *Keeper) types.MsgServer {
func NewMsgServerImpl(k types.MsgOpsKeeper) types.MsgServer {
return &msgServer{keeper: k}
}

Expand Down
4 changes: 2 additions & 2 deletions x/wasm/keeper/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ func WithWasmEngine(x types.WasmerEngine) Option {

// WithMessageHandler is an optional constructor parameter to set a custom handler for wasmVM messages.
// This option should not be combined with Option `WithMessageEncoders`.
func WithMessageHandler(x messenger) Option {
func WithMessageHandler(x Messenger) Option {
return optsFn(func(k *Keeper) {
k.messenger = x
})
}

// WithQueryHandler is an optional constructor parameter to set custom query handler for wasmVM requests.
// This option should not be combined with Option `WithQueryPlugins`.
func WithQueryHandler(x wasmVMQueryHandler) Option {
func WithQueryHandler(x WASMVMQueryHandler) Option {
return optsFn(func(k *Keeper) {
k.wasmVMQueryHandler = x
})
Expand Down
Loading

0 comments on commit ea33f64

Please sign in to comment.