github.com/line/ostracon@v1.0.10-0.20230328032236-7f20145f065d/mempool/mempool.go (about)

     1  package mempool
     2  
     3  import (
     4  	"fmt"
     5  
     6  	abci "github.com/tendermint/tendermint/abci/types"
     7  
     8  	ocabci "github.com/line/ostracon/abci/types"
     9  	"github.com/line/ostracon/p2p"
    10  	"github.com/line/ostracon/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  	CheckTxSync(tx types.Tx, txInfo TxInfo) (*ocabci.Response, error)
    21  	CheckTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), checkTxCb func(*ocabci.Response))
    22  
    23  	// ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes
    24  	// bytes total with the condition that the total gasWanted must be less than
    25  	// maxGas.
    26  	// If both maxes are negative, there is no cap on the size of all returned
    27  	// transactions (~ all available transactions).
    28  	ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs
    29  
    30  	// Puts cap on txs as well on top of ReapMaxBytesMaxGas
    31  	ReapMaxBytesMaxGasMaxTxs(maxBytes, maxGas, maxTxs int64) types.Txs
    32  
    33  	// ReapMaxTxs reaps up to max transactions from the mempool.
    34  	// If max is negative, there is no cap on the size of all returned
    35  	// transactions (~ all available transactions).
    36  	ReapMaxTxs(max int) types.Txs
    37  
    38  	// Lock locks the mempool. The consensus must be able to hold lock to safely update.
    39  	Lock()
    40  
    41  	// Unlock unlocks the mempool.
    42  	Unlock()
    43  
    44  	// Update informs the mempool that the given txs were committed and can be discarded.
    45  	// NOTE: this should be called *after* block is committed by consensus.
    46  	// NOTE: Lock/Unlock must be managed by caller
    47  	Update(
    48  		block *types.Block,
    49  		deliverTxResponses []*abci.ResponseDeliverTx,
    50  		newPreFn PreCheckFunc,
    51  		newPostFn PostCheckFunc,
    52  	) error
    53  
    54  	// FlushAppConn flushes the mempool connection to ensure async reqResCb calls are
    55  	// done. E.g. from CheckTx.
    56  	// NOTE: Lock/Unlock must be managed by caller
    57  	FlushAppConn() error
    58  
    59  	// Flush removes all transactions from the mempool and cache
    60  	Flush()
    61  
    62  	// TxsAvailable returns a channel which fires once for every height,
    63  	// and only when transactions are available in the mempool.
    64  	// NOTE: the returned channel may be nil if EnableTxsAvailable was not called.
    65  	TxsAvailable() <-chan struct{}
    66  
    67  	// EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will
    68  	// trigger once every height when transactions are available.
    69  	EnableTxsAvailable()
    70  
    71  	// Size returns the number of transactions in the mempool.
    72  	Size() int
    73  
    74  	// TxsBytes returns the total size of all txs in the mempool.
    75  	TxsBytes() int64
    76  
    77  	// InitWAL creates a directory for the WAL file and opens a file itself. If
    78  	// there is an error, it will be of type *PathError.
    79  	InitWAL() error
    80  
    81  	// CloseWAL closes and discards the underlying WAL file.
    82  	// Any further writes will not be relayed to disk.
    83  	CloseWAL()
    84  }
    85  
    86  //--------------------------------------------------------------------------------
    87  
    88  // PreCheckFunc is an optional filter executed before CheckTx and rejects
    89  // transaction if false is returned. An example would be to ensure that a
    90  // transaction doesn't exceeded the block size.
    91  type PreCheckFunc func(types.Tx) error
    92  
    93  // PostCheckFunc is an optional filter executed after CheckTx and rejects
    94  // transaction if false is returned. An example would be to ensure a
    95  // transaction doesn't require more gas than available for the block.
    96  type PostCheckFunc func(types.Tx, *ocabci.ResponseCheckTx) error
    97  
    98  // TxInfo are parameters that get passed when attempting to add a tx to the
    99  // mempool.
   100  type TxInfo struct {
   101  	// SenderID is the internal peer ID used in the mempool to identify the
   102  	// sender, storing 2 bytes with each tx instead of 20 bytes for the p2p.ID.
   103  	SenderID uint16
   104  	// SenderP2PID is the actual p2p.ID of the sender, used e.g. for logging.
   105  	SenderP2PID p2p.ID
   106  }
   107  
   108  //--------------------------------------------------------------------------------
   109  
   110  // PreCheckMaxBytes checks that the size of the transaction is smaller or equal to the expected maxBytes.
   111  func PreCheckMaxBytes(maxBytes int64) PreCheckFunc {
   112  	return func(tx types.Tx) error {
   113  		txSize := types.ComputeProtoSizeForTxs([]types.Tx{tx})
   114  
   115  		if txSize > maxBytes {
   116  			return fmt.Errorf("tx size is too big: %d, max: %d",
   117  				txSize, maxBytes)
   118  		}
   119  		return nil
   120  	}
   121  }
   122  
   123  // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed
   124  // maxGas. Returns nil if maxGas is -1.
   125  func PostCheckMaxGas(maxGas int64) PostCheckFunc {
   126  	return func(tx types.Tx, res *ocabci.ResponseCheckTx) error {
   127  		if maxGas == -1 {
   128  			return nil
   129  		}
   130  		if res.GasWanted < 0 {
   131  			return fmt.Errorf("gas wanted %d is negative",
   132  				res.GasWanted)
   133  		}
   134  		if res.GasWanted > maxGas {
   135  			return fmt.Errorf("gas wanted %d is greater than max gas %d",
   136  				res.GasWanted, maxGas)
   137  		}
   138  		return nil
   139  	}
   140  }