Files
wasmd/x/wasm/handler.go
Ethan Frey 45ef2f331e Merge pull request #201 from CosmWasm/polish_handler
Polish types in message handler
2020-07-20 10:58:24 +02:00

161 lines
5.0 KiB
Go

package wasm
import (
"fmt"
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
// NewHandler returns a handler for "bank" type messages.
func NewHandler(k Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case MsgStoreCode:
return handleStoreCode(ctx, k, &msg)
case MsgInstantiateContract:
return handleInstantiate(ctx, k, &msg)
case MsgExecuteContract:
return handleExecute(ctx, k, &msg)
case MsgMigrateContract:
return handleMigration(ctx, k, &msg)
case MsgUpdateAdmin:
return handleUpdateContractAdmin(ctx, k, &msg)
case MsgClearAdmin:
return handleClearContractAdmin(ctx, k, &msg)
default:
errMsg := fmt.Sprintf("unrecognized wasm message type: %T", msg)
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
}
}
}
// filterMessageEvents returns the same events with all of type == EventTypeMessage removed.
// this is so only our top-level message event comes through
func filterMessageEvents(manager *sdk.EventManager) sdk.Events {
events := manager.Events()
res := make([]sdk.Event, 0, len(events)+1)
for _, e := range events {
if e.Type != sdk.EventTypeMessage {
res = append(res, e)
}
}
return res
}
func handleStoreCode(ctx sdk.Context, k Keeper, msg *MsgStoreCode) (*sdk.Result, error) {
err := msg.ValidateBasic()
if err != nil {
return nil, err
}
codeID, err := k.Create(ctx, msg.Sender, msg.WASMByteCode, msg.Source, msg.Builder, msg.InstantiatePermission)
if err != nil {
return nil, err
}
events := filterMessageEvents(ctx.EventManager())
ourEvent := sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName),
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()),
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", codeID)),
)
return &sdk.Result{
Data: []byte(fmt.Sprintf("%d", codeID)),
Events: append(events, ourEvent),
}, nil
}
func handleInstantiate(ctx sdk.Context, k Keeper, msg *MsgInstantiateContract) (*sdk.Result, error) {
contractAddr, err := k.Instantiate(ctx, msg.CodeID, msg.Sender, msg.Admin, msg.InitMsg, msg.Label, msg.InitFunds)
if err != nil {
return nil, err
}
events := filterMessageEvents(ctx.EventManager())
ourEvent := sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName),
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()),
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", msg.CodeID)),
sdk.NewAttribute(types.AttributeKeyContract, contractAddr.String()),
)
return &sdk.Result{
Data: contractAddr,
Events: append(events, ourEvent),
}, nil
}
func handleExecute(ctx sdk.Context, k Keeper, msg *MsgExecuteContract) (*sdk.Result, error) {
res, err := k.Execute(ctx, msg.Contract, msg.Sender, msg.Msg, msg.SentFunds)
if err != nil {
return nil, err
}
events := filterMessageEvents(ctx.EventManager())
ourEvent := sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName),
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()),
sdk.NewAttribute(types.AttributeKeyContract, msg.Contract.String()),
)
res.Events = append(events, ourEvent)
return res, nil
}
func handleMigration(ctx sdk.Context, k Keeper, msg *MsgMigrateContract) (*sdk.Result, error) {
res, err := k.Migrate(ctx, msg.Contract, msg.Sender, msg.CodeID, msg.MigrateMsg)
if err != nil {
return nil, err
}
events := filterMessageEvents(ctx.EventManager())
ourEvent := sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName),
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()),
sdk.NewAttribute(types.AttributeKeyContract, msg.Contract.String()),
)
res.Events = append(events, ourEvent)
return res, nil
}
func handleUpdateContractAdmin(ctx sdk.Context, k Keeper, msg *MsgUpdateAdmin) (*sdk.Result, error) {
if err := k.UpdateContractAdmin(ctx, msg.Contract, msg.Sender, msg.NewAdmin); err != nil {
return nil, err
}
events := ctx.EventManager().Events()
ourEvent := sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName),
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()),
sdk.NewAttribute(types.AttributeKeyContract, msg.Contract.String()),
)
return &sdk.Result{
Events: append(events, ourEvent),
}, nil
}
func handleClearContractAdmin(ctx sdk.Context, k Keeper, msg *MsgClearAdmin) (*sdk.Result, error) {
if err := k.ClearContractAdmin(ctx, msg.Contract, msg.Sender); err != nil {
return nil, err
}
events := ctx.EventManager().Events()
ourEvent := sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName),
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()),
sdk.NewAttribute(types.AttributeKeyContract, msg.Contract.String()),
)
return &sdk.Result{
Events: append(events, ourEvent),
}, nil
}