github.com/okex/exchain@v1.8.0/libs/tendermint/mempool/mempool.go (about)

     1  package mempool
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"fmt"
     6  
     7  	abci "github.com/okex/exchain/libs/tendermint/abci/types"
     8  	cfg "github.com/okex/exchain/libs/tendermint/config"
     9  	"github.com/okex/exchain/libs/tendermint/p2p"
    10  	"github.com/okex/exchain/libs/tendermint/types"
    11  )
    12  
    13  // Mempool defines the mempool interface.
    14  //
    15  // Updates to the mempool need to be synchronized with committing a block so
    16  // apps can reset their transient state on Commit.
    17  type Mempool interface {
    18  	// CheckTx executes a new transaction against the application to determine
    19  	// its validity and whether it should be added to the mempool.
    20  	CheckTx(tx types.Tx, callback func(*abci.Response), txInfo TxInfo) error
    21  
    22  	// ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes
    23  	// bytes total with the condition that the total gasWanted must be less than
    24  	// maxGas.
    25  	// If both maxes are negative, there is no cap on the size of all returned
    26  	// transactions (~ all available transactions).
    27  	ReapMaxBytesMaxGas(maxBytes, maxGas int64) []types.Tx
    28  	ReapEssentialTx(tx types.Tx) abci.TxEssentials
    29  
    30  	// ReapMaxTxs reaps up to max transactions from the mempool.
    31  	// If max is negative, there is no cap on the size of all returned
    32  	// transactions (~ all available transactions).
    33  	ReapMaxTxs(max int) types.Txs
    34  
    35  	ReapUserTxsCnt(address string) int
    36  
    37  	// only for checkTx used!
    38  	GetUserPendingTxsCnt(address string) int
    39  
    40  	ReapUserTxs(address string, max int) types.Txs
    41  	GetPendingNonce(address string) (uint64, bool)
    42  
    43  	// Lock locks the mempool. The consensus must be able to hold lock to safely update.
    44  	Lock()
    45  
    46  	// Unlock unlocks the mempool.
    47  	Unlock()
    48  
    49  	// Update informs the mempool that the given txs were committed and can be discarded.
    50  	// NOTE: this should be called *after* block is committed by consensus.
    51  	// NOTE: Lock/Unlock must be managed by caller
    52  	Update(
    53  		blockHeight int64,
    54  		blockTxs types.Txs,
    55  		deliverTxResponses []*abci.ResponseDeliverTx,
    56  		newPreFn PreCheckFunc,
    57  		newPostFn PostCheckFunc,
    58  	) error
    59  
    60  	// FlushAppConn flushes the mempool connection to ensure async reqResCb calls are
    61  	// done. E.g. from CheckTx.
    62  	// NOTE: Lock/Unlock must be managed by caller
    63  	FlushAppConn() error
    64  
    65  	// Flush removes all transactions from the mempool and cache
    66  	Flush()
    67  
    68  	// TxsAvailable returns a channel which fires once for every height,
    69  	// and only when transactions are available in the mempool.
    70  	// NOTE: the returned channel may be nil if EnableTxsAvailable was not called.
    71  	TxsAvailable() <-chan struct{}
    72  
    73  	// EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will
    74  	// trigger once every height when transactions are available.
    75  	EnableTxsAvailable()
    76  
    77  	// Size returns the number of transactions in the mempool.
    78  	Size() int
    79  
    80  	// TxsBytes returns the total size of all txs in the mempool.
    81  	TxsBytes() int64
    82  
    83  	SetEventBus(eventBus types.TxEventPublisher)
    84  
    85  	GetConfig() *cfg.MempoolConfig
    86  	GetTxByHash(hash [sha256.Size]byte) (types.Tx, error)
    87  
    88  	GetAddressList() []string
    89  	SetAccountRetriever(retriever AccountRetriever)
    90  
    91  	SetTxInfoParser(parser TxInfoParser)
    92  
    93  	GetTxSimulateGas(txHash string) int64
    94  
    95  	GetEnableDeleteMinGPTx() bool
    96  
    97  	GetPendingPoolTxsBytes() map[string]map[string]types.WrappedMempoolTx
    98  }
    99  
   100  //--------------------------------------------------------------------------------
   101  
   102  // PreCheckFunc is an optional filter executed before CheckTx and rejects
   103  // transaction if false is returned. An example would be to ensure that a
   104  // transaction doesn't exceeded the block size.
   105  type PreCheckFunc func(types.Tx) error
   106  
   107  // PostCheckFunc is an optional filter executed after CheckTx and rejects
   108  // transaction if false is returned. An example would be to ensure a
   109  // transaction doesn't require more gas than available for the block.
   110  type PostCheckFunc func(types.Tx, *abci.ResponseCheckTx) error
   111  
   112  // TxInfo are parameters that get passed when attempting to add a tx to the
   113  // mempool.
   114  type TxInfo struct {
   115  	// SenderID is the internal peer ID used in the mempool to identify the
   116  	// sender, storing 2 bytes with each tx instead of 20 bytes for the p2p.ID.
   117  	SenderID uint16
   118  	// SenderP2PID is the actual p2p.ID of the sender, used e.g. for logging.
   119  	SenderP2PID p2p.ID
   120  
   121  	from         string
   122  	wtx          *WrappedTx
   123  	checkType    abci.CheckTxType
   124  	isGasPrecise bool
   125  	gasUsed      int64
   126  
   127  	wrapCMTx *types.WrapCMTx
   128  }
   129  
   130  //--------------------------------------------------------------------------------
   131  
   132  // PreCheckAminoMaxBytes checks that the size of the transaction plus the amino
   133  // overhead is smaller or equal to the expected maxBytes.
   134  func PreCheckAminoMaxBytes(maxBytes int64) PreCheckFunc {
   135  	return func(tx types.Tx) error {
   136  		// We have to account for the amino overhead in the tx size as well
   137  		// NOTE: fieldNum = 1 as types.Block.Data contains Txs []Tx as first field.
   138  		// If this field order ever changes this needs to updated here accordingly.
   139  		// NOTE: if some []Tx are encoded without a parenting struct, the
   140  		// fieldNum is also equal to 1.
   141  		aminoOverhead := types.ComputeAminoOverhead(tx, 1)
   142  		txSize := int64(len(tx)) + aminoOverhead
   143  		if txSize > maxBytes {
   144  			return fmt.Errorf("tx size (including amino overhead) is too big: %d, max: %d",
   145  				txSize, maxBytes)
   146  		}
   147  		return nil
   148  	}
   149  }
   150  
   151  // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed
   152  // maxGas. Returns nil if maxGas is -1.
   153  func PostCheckMaxGas(maxGas int64) PostCheckFunc {
   154  	return func(tx types.Tx, res *abci.ResponseCheckTx) error {
   155  		if maxGas == -1 {
   156  			return nil
   157  		}
   158  		if res.GasWanted < 0 {
   159  			return fmt.Errorf("gas wanted %d is negative",
   160  				res.GasWanted)
   161  		}
   162  		if res.GasWanted > maxGas {
   163  			return fmt.Errorf("gas wanted %d is greater than max gas %d",
   164  				res.GasWanted, maxGas)
   165  		}
   166  		return nil
   167  	}
   168  }