github.com/aakash4dev/cometbft@v0.38.2/mempool/mempool.go (about)

     1  package mempool
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"errors"
     6  	"math"
     7  
     8  	"fmt"
     9  
    10  	abcicli "github.com/aakash4dev/cometbft/abci/client"
    11  	abci "github.com/aakash4dev/cometbft/abci/types"
    12  	"github.com/aakash4dev/cometbft/types"
    13  )
    14  
    15  const (
    16  	MempoolChannel = byte(0x30)
    17  
    18  	// PeerCatchupSleepIntervalMS defines how much time to sleep if a peer is behind
    19  	PeerCatchupSleepIntervalMS = 100
    20  
    21  	// UnknownPeerID is the peer ID to use when running CheckTx when there is
    22  	// no peer (e.g. RPC)
    23  	UnknownPeerID uint16 = 0
    24  
    25  	MaxActiveIDs = math.MaxUint16
    26  )
    27  
    28  //go:generate ../scripts/mockery_generate.sh Mempool
    29  
    30  // Mempool defines the mempool interface.
    31  //
    32  // Updates to the mempool need to be synchronized with committing a block so
    33  // applications can reset their transient state on Commit.
    34  type Mempool interface {
    35  	// CheckTx executes a new transaction against the application to determine
    36  	// its validity and whether it should be added to the mempool.
    37  	CheckTx(tx types.Tx) (*abcicli.ReqRes, error)
    38  
    39  	// RemoveTxByKey removes a transaction, identified by its key,
    40  	// from the mempool.
    41  	RemoveTxByKey(txKey types.TxKey) error
    42  
    43  	// ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes
    44  	// bytes total with the condition that the total gasWanted must be less than
    45  	// maxGas.
    46  	//
    47  	// If both maxes are negative, there is no cap on the size of all returned
    48  	// transactions (~ all available transactions).
    49  	ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs
    50  
    51  	// ReapMaxTxs reaps up to max transactions from the mempool. If max is
    52  	// negative, there is no cap on the size of all returned transactions
    53  	// (~ all available transactions).
    54  	ReapMaxTxs(max int) types.Txs
    55  
    56  	// Lock locks the mempool. The consensus must be able to hold lock to safely
    57  	// update.
    58  	Lock()
    59  
    60  	// Unlock unlocks the mempool.
    61  	Unlock()
    62  
    63  	// Update informs the mempool that the given txs were committed and can be
    64  	// discarded.
    65  	//
    66  	// NOTE:
    67  	// 1. This should be called *after* block is committed by consensus.
    68  	// 2. Lock/Unlock must be managed by the caller.
    69  	Update(
    70  		blockHeight int64,
    71  		blockTxs types.Txs,
    72  		deliverTxResponses []*abci.ExecTxResult,
    73  		newPreFn PreCheckFunc,
    74  		newPostFn PostCheckFunc,
    75  	) error
    76  
    77  	// FlushAppConn flushes the mempool connection to ensure async callback calls
    78  	// are done, e.g. from CheckTx.
    79  	//
    80  	// NOTE:
    81  	// 1. Lock/Unlock must be managed by caller.
    82  	FlushAppConn() error
    83  
    84  	// Flush removes all transactions from the mempool and caches.
    85  	Flush()
    86  
    87  	// TxsAvailable returns a channel which fires once for every height, and only
    88  	// when transactions are available in the mempool.
    89  	//
    90  	// NOTE:
    91  	// 1. The returned channel may be nil if EnableTxsAvailable was not called.
    92  	TxsAvailable() <-chan struct{}
    93  
    94  	// EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will
    95  	// trigger once every height when transactions are available.
    96  	EnableTxsAvailable()
    97  
    98  	// Set a callback function to be called when a transaction is removed from
    99  	// the mempool.
   100  	SetTxRemovedCallback(cb func(types.TxKey))
   101  
   102  	// Size returns the number of transactions in the mempool.
   103  	Size() int
   104  
   105  	// SizeBytes returns the total size of all txs in the mempool.
   106  	SizeBytes() int64
   107  }
   108  
   109  // PreCheckFunc is an optional filter executed before CheckTx and rejects
   110  // transaction if false is returned. An example would be to ensure that a
   111  // transaction doesn't exceeded the block size.
   112  type PreCheckFunc func(types.Tx) error
   113  
   114  // PostCheckFunc is an optional filter executed after CheckTx and rejects
   115  // transaction if false is returned. An example would be to ensure a
   116  // transaction doesn't require more gas than available for the block.
   117  type PostCheckFunc func(types.Tx, *abci.ResponseCheckTx) error
   118  
   119  // PreCheckMaxBytes checks that the size of the transaction is smaller or equal
   120  // to the expected maxBytes.
   121  func PreCheckMaxBytes(maxBytes int64) PreCheckFunc {
   122  	return func(tx types.Tx) error {
   123  		txSize := types.ComputeProtoSizeForTxs([]types.Tx{tx})
   124  
   125  		if txSize > maxBytes {
   126  			return fmt.Errorf("tx size is too big: %d, max: %d", txSize, maxBytes)
   127  		}
   128  
   129  		return nil
   130  	}
   131  }
   132  
   133  // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed
   134  // maxGas. Returns nil if maxGas is -1.
   135  func PostCheckMaxGas(maxGas int64) PostCheckFunc {
   136  	return func(tx types.Tx, res *abci.ResponseCheckTx) error {
   137  		if maxGas == -1 {
   138  			return nil
   139  		}
   140  		if res.GasWanted < 0 {
   141  			return fmt.Errorf("gas wanted %d is negative",
   142  				res.GasWanted)
   143  		}
   144  		if res.GasWanted > maxGas {
   145  			return fmt.Errorf("gas wanted %d is greater than max gas %d",
   146  				res.GasWanted, maxGas)
   147  		}
   148  
   149  		return nil
   150  	}
   151  }
   152  
   153  // ErrTxInCache is returned to the client if we saw tx earlier
   154  var ErrTxInCache = errors.New("tx already exists in cache")
   155  
   156  // TxKey is the fixed length array key used as an index.
   157  type TxKey [sha256.Size]byte
   158  
   159  // ErrTxTooLarge defines an error when a transaction is too big to be sent in a
   160  // message to other peers.
   161  type ErrTxTooLarge struct {
   162  	Max    int
   163  	Actual int
   164  }
   165  
   166  func (e ErrTxTooLarge) Error() string {
   167  	return fmt.Sprintf("Tx too large. Max size is %d, but got %d", e.Max, e.Actual)
   168  }
   169  
   170  // ErrMempoolIsFull defines an error where CometBFT and the application cannot
   171  // handle that much load.
   172  type ErrMempoolIsFull struct {
   173  	NumTxs      int
   174  	MaxTxs      int
   175  	TxsBytes    int64
   176  	MaxTxsBytes int64
   177  }
   178  
   179  func (e ErrMempoolIsFull) Error() string {
   180  	return fmt.Sprintf(
   181  		"mempool is full: number of txs %d (max: %d), total txs bytes %d (max: %d)",
   182  		e.NumTxs,
   183  		e.MaxTxs,
   184  		e.TxsBytes,
   185  		e.MaxTxsBytes,
   186  	)
   187  }
   188  
   189  // ErrPreCheck defines an error where a transaction fails a pre-check.
   190  type ErrPreCheck struct {
   191  	Reason error
   192  }
   193  
   194  func (e ErrPreCheck) Error() string {
   195  	return e.Reason.Error()
   196  }
   197  
   198  // IsPreCheckError returns true if err is due to pre check failure.
   199  func IsPreCheckError(err error) bool {
   200  	return errors.As(err, &ErrPreCheck{})
   201  }