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

     1  package evm
     2  
     3  import (
     4  	bam "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/baseapp"
     5  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     6  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     7  	cfg "github.com/fibonacci-chain/fbc/libs/tendermint/config"
     8  	"github.com/fibonacci-chain/fbc/x/evm/txs"
     9  	"github.com/fibonacci-chain/fbc/x/evm/txs/base"
    10  	"github.com/fibonacci-chain/fbc/x/evm/types"
    11  	"github.com/fibonacci-chain/fbc/x/evm/watcher"
    12  )
    13  
    14  // NewHandler returns a handler for Ethermint type messages.
    15  func NewHandler(k *Keeper) sdk.Handler {
    16  	return func(ctx sdk.Context, msg sdk.Msg) (result *sdk.Result, err error) {
    17  		ctx.SetEventManager(sdk.NewEventManager())
    18  
    19  		if ctx.IsDeliver() {
    20  			k.EvmStateDb.WithContext(ctx).MarkUpdatedAcc(k.UpdatedAccount)
    21  			k.UpdatedAccount = k.UpdatedAccount[:0]
    22  		}
    23  
    24  		evmTx, ok := msg.(*types.MsgEthereumTx)
    25  		if ok {
    26  			if watcher.IsWatcherEnabled() {
    27  				ctx.SetWatcher(watcher.NewTxWatcher())
    28  			}
    29  			result, err = handleMsgEthereumTx(ctx, k, evmTx)
    30  			if err != nil {
    31  				err = sdkerrors.New(types.ModuleName, types.CodeSpaceEvmCallFailed, err.Error())
    32  			}
    33  		} else {
    34  			err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
    35  		}
    36  
    37  		return result, err
    38  	}
    39  }
    40  
    41  func updateHGU(ctx sdk.Context, msg sdk.Msg) {
    42  	if cfg.DynamicConfig.GetMaxGasUsedPerBlock() <= 0 {
    43  		return
    44  	}
    45  
    46  	msgFnSignature, toDeployContractSize := getMsgCallFnSignature(msg)
    47  
    48  	if msgFnSignature == nil {
    49  		return
    50  	}
    51  
    52  	gc := int64(ctx.GasMeter().GasConsumed())
    53  	if toDeployContractSize > 0 {
    54  		// calculate average gas consume for deploy contract case
    55  		gc = gc / int64(toDeployContractSize)
    56  	}
    57  
    58  	bam.InstanceOfHistoryGasUsedRecordDB().UpdateGasUsed(msgFnSignature, gc)
    59  }
    60  
    61  func getMsgCallFnSignature(msg sdk.Msg) ([]byte, int) {
    62  	switch msg := msg.(type) {
    63  	case *types.MsgEthereumTx:
    64  		return msg.GetTxFnSignatureInfo()
    65  	default:
    66  		return nil, 0
    67  	}
    68  }
    69  
    70  // handleMsgEthereumTx handles an Ethereum specific tx
    71  // 1. txs can be divided into TraceTxLog/CheckTx/DeliverTx
    72  func handleMsgEthereumTx(ctx sdk.Context, k *Keeper, msg *types.MsgEthereumTx) (*sdk.Result, error) {
    73  	txFactory := txs.NewFactory(base.Config{
    74  		Ctx:    ctx,
    75  		Keeper: k,
    76  	})
    77  	tx, err := txFactory.CreateTx()
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	defer tx.Dispose()
    82  
    83  	// core logical to handle ethereum tx
    84  	rst, err := txs.TransitionEvmTx(tx, msg)
    85  	if err == nil && !ctx.IsCheckTx() {
    86  		updateHGU(ctx, msg)
    87  	}
    88  
    89  	return rst, err
    90  }