github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/handler.go (about)

     1  package wasm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     8  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/kv"
     9  	types2 "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    10  	"github.com/fibonacci-chain/fbc/x/wasm/keeper"
    11  	"github.com/fibonacci-chain/fbc/x/wasm/types"
    12  	"github.com/fibonacci-chain/fbc/x/wasm/watcher"
    13  	"github.com/gogo/protobuf/proto"
    14  )
    15  
    16  // NewHandler returns a handler for "wasm" type messages.
    17  func NewHandler(k types.ContractOpsKeeper) sdk.Handler {
    18  	msgServer := keeper.NewMsgServerImpl(k)
    19  
    20  	return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
    21  		ctx.SetEventManager(sdk.NewEventManager())
    22  
    23  		if !types2.HigherThanEarth(ctx.BlockHeight()) {
    24  			errMsg := fmt.Sprintf("wasm not support at height %d", ctx.BlockHeight())
    25  			return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
    26  		}
    27  
    28  		var (
    29  			res proto.Message
    30  			err error
    31  		)
    32  		// update watcher
    33  		defer func() {
    34  			// update watchDB when delivering tx
    35  			if ctx.IsDeliver() || ctx.ParaMsg() != nil {
    36  				watcher.Save(err)
    37  			}
    38  		}()
    39  
    40  		switch msg := msg.(type) {
    41  		case *MsgStoreCode: //nolint:typecheck
    42  			res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), msg)
    43  		case *MsgInstantiateContract:
    44  			res, err = msgServer.InstantiateContract(sdk.WrapSDKContext(ctx), msg)
    45  		case *MsgExecuteContract:
    46  			res, err = msgServer.ExecuteContract(sdk.WrapSDKContext(ctx), msg)
    47  		case *MsgMigrateContract:
    48  			res, err = msgServer.MigrateContract(sdk.WrapSDKContext(ctx), msg)
    49  		case *MsgUpdateAdmin:
    50  			res, err = msgServer.UpdateAdmin(sdk.WrapSDKContext(ctx), msg)
    51  		case *MsgClearAdmin:
    52  			res, err = msgServer.ClearAdmin(sdk.WrapSDKContext(ctx), msg)
    53  		default:
    54  			errMsg := fmt.Sprintf("unrecognized wasm message type: %T", msg)
    55  			return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
    56  		}
    57  
    58  		ctx.SetEventManager(filterMessageEvents(ctx))
    59  		return sdk.WrapServiceResult(ctx, res, err)
    60  	}
    61  }
    62  
    63  // filterMessageEvents returns the same events with all of type == EventTypeMessage removed except
    64  // for wasm message types.
    65  // this is so only our top-level message event comes through
    66  func filterMessageEvents(ctx sdk.Context) *sdk.EventManager {
    67  	m := sdk.NewEventManager()
    68  	for _, e := range ctx.EventManager().Events() {
    69  		if e.Type == sdk.EventTypeMessage &&
    70  			!hasWasmModuleAttribute(e.Attributes) {
    71  			continue
    72  		}
    73  		m.EmitEvent(e)
    74  	}
    75  	return m
    76  }
    77  
    78  func hasWasmModuleAttribute(attrs []kv.Pair) bool {
    79  	for _, a := range attrs {
    80  		if sdk.AttributeKeyModule == string(a.Key) &&
    81  			types.ModuleName == string(a.Value) {
    82  			return true
    83  		}
    84  	}
    85  	return false
    86  }