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

     1  package txs
     2  
     3  import (
     4  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     5  	authexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
     6  	bam "github.com/fibonacci-chain/fbc/libs/system/trace"
     7  	"github.com/fibonacci-chain/fbc/x/evm/txs/base"
     8  	"github.com/fibonacci-chain/fbc/x/evm/types"
     9  )
    10  
    11  type Tx interface {
    12  	// Prepare convert msg to tx
    13  	Prepare(msg *types.MsgEthereumTx) (err error)
    14  
    15  	// SaveTx since the txCount is used by the stateDB, and a simulated tx is run only on the node it's submitted to,
    16  	// then this will cause the txCount/stateDB of the node that ran the simulated tx to be different with the
    17  	// other nodes, causing a consensus error
    18  	SaveTx(msg *types.MsgEthereumTx)
    19  
    20  	// GetChainConfig get chain config(the chain config may cached)
    21  	GetChainConfig() (types.ChainConfig, bool)
    22  
    23  	// GetSenderAccount get sender account
    24  	GetSenderAccount() authexported.Account
    25  
    26  	// Transition execute evm tx
    27  	Transition(config types.ChainConfig) (result base.Result, err error)
    28  
    29  	// DecorateResult some case(trace tx log) will modify the inResult to log and swallow inErr
    30  	DecorateResult(inResult *base.Result, inErr error) (result *sdk.Result, err error)
    31  
    32  	// Commit save the inner tx and contracts
    33  	Commit(msg *types.MsgEthereumTx, result *base.Result)
    34  
    35  	// EmitEvent emit event
    36  	EmitEvent(msg *types.MsgEthereumTx, result *base.Result)
    37  
    38  	// FinalizeWatcher after execute evm tx run here
    39  	FinalizeWatcher(msg *types.MsgEthereumTx, err error, panic bool)
    40  
    41  	// AnalyzeStart start record tag
    42  	AnalyzeStart(tag string)
    43  
    44  	// AnalyzeStop stop record tag
    45  	AnalyzeStop(tag string)
    46  
    47  	// Dispose release the resources of the tx, should be called after the tx is unused
    48  	Dispose()
    49  }
    50  
    51  // TransitionEvmTx execute evm transition template
    52  func TransitionEvmTx(tx Tx, msg *types.MsgEthereumTx) (result *sdk.Result, err error) {
    53  	tx.AnalyzeStart(bam.EvmHandler)
    54  	defer tx.AnalyzeStop(bam.EvmHandler)
    55  
    56  	// Prepare convert msg to state transition
    57  	err = tx.Prepare(msg)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	// save tx
    63  	tx.SaveTx(msg)
    64  
    65  	// execute transition, the result
    66  	tx.AnalyzeStart(bam.TransitionDb)
    67  	defer tx.AnalyzeStop(bam.TransitionDb)
    68  
    69  	config, found := tx.GetChainConfig()
    70  	if !found {
    71  		return nil, types.ErrChainConfigNotFound
    72  	}
    73  
    74  	defer func() {
    75  		e := recover()
    76  		isPanic := e != nil
    77  		tx.FinalizeWatcher(msg, err, isPanic)
    78  		if isPanic {
    79  			panic(e)
    80  		}
    81  	}()
    82  
    83  	// execute evm tx
    84  	var baseResult base.Result
    85  	baseResult, err = tx.Transition(config)
    86  	if err == nil {
    87  		// Commit save the inner tx and contracts
    88  		tx.Commit(msg, &baseResult)
    89  		tx.EmitEvent(msg, &baseResult)
    90  	}
    91  
    92  	return tx.DecorateResult(&baseResult, err)
    93  }