github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/ante/EthMempoolFeeDecorator.go (about)

     1  package ante
     2  
     3  import (
     4  	"fmt"
     5  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     6  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     7  	evmtypes "github.com/fibonacci-chain/fbc/x/evm/types"
     8  	"math/big"
     9  	"sync"
    10  )
    11  
    12  // EthMempoolFeeDecorator validates that sufficient fees have been provided that
    13  // meet a minimum threshold defined by the proposer (for mempool purposes during CheckTx).
    14  type EthMempoolFeeDecorator struct {
    15  	evmKeeper EVMKeeper
    16  }
    17  
    18  // NewEthMempoolFeeDecorator creates a new EthMempoolFeeDecorator
    19  func NewEthMempoolFeeDecorator(ek EVMKeeper) EthMempoolFeeDecorator {
    20  	return EthMempoolFeeDecorator{
    21  		evmKeeper: ek,
    22  	}
    23  }
    24  
    25  var feeIntsPool = &sync.Pool{
    26  	New: func() interface{} {
    27  		return &[2]big.Int{}
    28  	},
    29  }
    30  
    31  // AnteHandle verifies that enough fees have been provided by the
    32  // Ethereum transaction that meet the minimum threshold set by the block
    33  // proposer.
    34  //
    35  // NOTE: This should only be run during a CheckTx mode.
    36  func (emfd EthMempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
    37  
    38  	// simulate means 'eth_call' or 'eth_estimateGas', when it means 'eth_estimateGas' we can not 'VerifySig'.so skip here
    39  	if !ctx.IsCheckTx() || simulate {
    40  		return next(ctx, tx, simulate)
    41  	}
    42  
    43  	msgEthTx, ok := tx.(*evmtypes.MsgEthereumTx)
    44  	if !ok {
    45  		return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
    46  	}
    47  
    48  	const evmDenom = sdk.DefaultBondDenom
    49  
    50  	feeInts := feeIntsPool.Get().(*[2]big.Int)
    51  
    52  	// fee = gas price * gas limit
    53  	fee := sdk.NewDecCoinFromDec(evmDenom, sdk.NewDecWithBigIntAndPrec(msgEthTx.CalcFee(&feeInts[0]), sdk.Precision))
    54  
    55  	minGasPrices := ctx.MinGasPrices()
    56  	// minFees := minGasPrices.AmountOf(evmDenom).MulInt64(int64(msgEthTx.Data.GasLimit))
    57  	var minFees = sdk.Dec{&feeInts[1]}
    58  	minGasPrices.AmountOf(evmDenom).MulInt64To(int64(msgEthTx.Data.GasLimit), &minFees)
    59  
    60  	// check that fee provided is greater than the minimum defined by the validator node
    61  	// NOTE: we only check if the evm denom tokens are present in min gas prices. It is up to the
    62  	// sender if they want to send additional fees in other denominations.
    63  	var hasEnoughFees bool
    64  	if fee.Amount.GTE(minFees) {
    65  		hasEnoughFees = true
    66  	}
    67  
    68  	// reject transaction if minimum gas price is not zero and the transaction does not
    69  	// meet the minimum fee
    70  	if !ctx.MinGasPrices().IsZero() && !hasEnoughFees {
    71  		err = sdkerrors.Wrap(
    72  			sdkerrors.ErrInsufficientFee,
    73  			fmt.Sprintf("insufficient fee, got: %q required: %q", fee, sdk.NewDecCoinFromDec(evmDenom, minFees)),
    74  		)
    75  		feeIntsPool.Put(feeInts)
    76  		return ctx, err
    77  	}
    78  	feeIntsPool.Put(feeInts)
    79  
    80  	return next(ctx, tx, simulate)
    81  }