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

     1  package keeper
     2  
     3  import (
     4  	"github.com/ethereum/go-ethereum/common"
     5  	ethtypes "github.com/ethereum/go-ethereum/core/types"
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	sdkerror "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     8  	"github.com/fibonacci-chain/fbc/x/evm/types"
     9  )
    10  
    11  var (
    12  	_ types.EvmHooks = MultiEvmHooks{}
    13  	_ types.EvmHooks = LogProcessEvmHook{}
    14  )
    15  
    16  // MultiEvmHooks combine multiple evm hooks, all hook functions are run in array sequence
    17  type MultiEvmHooks []types.EvmHooks
    18  
    19  // NewMultiEvmHooks combine multiple evm hooks
    20  func NewMultiEvmHooks(hooks ...types.EvmHooks) MultiEvmHooks {
    21  	return hooks
    22  }
    23  
    24  // PostTxProcessing delegate the call to underlying hooks
    25  func (mh MultiEvmHooks) PostTxProcessing(ctx sdk.Context, st *types.StateTransition, receipt *ethtypes.Receipt) error {
    26  	for i := range mh {
    27  		if err := mh[i].PostTxProcessing(ctx, st, receipt); err != nil {
    28  			return sdkerror.Wrapf(err, "EVM hook %T failed", mh[i])
    29  		}
    30  	}
    31  	return nil
    32  }
    33  
    34  // LogProcessEvmHook is an evm hook that convert specific contract logs into native module calls
    35  type LogProcessEvmHook struct {
    36  	handlers map[common.Hash]types.EvmLogHandler
    37  }
    38  
    39  func NewLogProcessEvmHook(handlers ...types.EvmLogHandler) LogProcessEvmHook {
    40  	handlerMap := make(map[common.Hash]types.EvmLogHandler)
    41  	for _, h := range handlers {
    42  		handlerMap[h.EventID()] = h
    43  	}
    44  	return LogProcessEvmHook{handlerMap}
    45  }
    46  
    47  // PostTxProcessing delegate the call to underlying hooks
    48  func (lh LogProcessEvmHook) PostTxProcessing(ctx sdk.Context, st *types.StateTransition, receipt *ethtypes.Receipt) error {
    49  	for _, log := range receipt.Logs {
    50  		if len(log.Topics) == 0 {
    51  			continue
    52  		}
    53  		if handler, ok := lh.handlers[log.Topics[0]]; ok {
    54  			if ctx.Cache() != nil {
    55  				ctx.Cache().DisableCache()
    56  			}
    57  			if err := handler.Handle(ctx, log.Address, log.Data); err != nil {
    58  				return err
    59  			}
    60  		}
    61  	}
    62  	return nil
    63  }