- package mempool
-
- import (
- "fmt"
-
- abci "github.com/tendermint/tendermint/abci/types"
- "github.com/tendermint/tendermint/types"
- )
-
- // Mempool defines the mempool interface.
- //
- // Updates to the mempool need to be synchronized with committing a block so
- // apps can reset their transient state on Commit.
- type Mempool interface {
- // CheckTx executes a new transaction against the application to determine
- // its validity and whether it should be added to the mempool.
- CheckTx(tx types.Tx, callback func(*abci.Response)) error
-
- // CheckTxWithInfo performs the same operation as CheckTx, but with extra
- // meta data about the tx.
- // Currently this metadata is the peer who sent it, used to prevent the tx
- // from being gossiped back to them.
- CheckTxWithInfo(tx types.Tx, callback func(*abci.Response), txInfo TxInfo) error
-
- // ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes
- // bytes total with the condition that the total gasWanted must be less than
- // maxGas.
- // If both maxes are negative, there is no cap on the size of all returned
- // transactions (~ all available transactions).
- ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs
-
- // ReapMaxTxs reaps up to max transactions from the mempool.
- // If max is negative, there is no cap on the size of all returned
- // transactions (~ all available transactions).
- ReapMaxTxs(max int) types.Txs
-
- // OnNewTx allows one to set a callback, which will be called when a new
- // transaction is added to the mempool.
- // Used by Reactor to broadcast new transactions to peers.
- OnNewTx(cb func(Tx))
-
- // Lock locks the mempool. The consensus must be able to hold lock to safely update.
- Lock()
-
- // Unlock unlocks the mempool.
- Unlock()
-
- // Update informs the mempool that the given txs were committed and can be discarded.
- // NOTE: this should be called *after* block is committed by consensus.
- // NOTE: unsafe; Lock/Unlock must be managed by caller
- Update(blockHeight int64, blockTxs types.Txs, newPreFn PreCheckFunc, newPostFn PostCheckFunc) error
-
- // FlushAppConn flushes the mempool connection to ensure async reqResCb calls are
- // done. E.g. from CheckTx.
- FlushAppConn() error
-
- // Flush removes all transactions from the mempool and cache
- Flush()
-
- // TxsAvailable returns a channel which fires once for every height,
- // and only when transactions are available in the mempool.
- // NOTE: the returned channel may be nil if EnableTxsAvailable was not called.
- TxsAvailable() <-chan struct{}
-
- // EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will
- // trigger once every height when transactions are available.
- EnableTxsAvailable()
-
- // Size returns the number of transactions in the mempool.
- Size() int
-
- // TxsBytes returns the total size of all txs in the mempool.
- TxsBytes() int64
- }
-
- //--------------------------------------------------------------------------------
-
- // Tx wraps raw transaction and adds a few methods to extract useful
- // information like where transaction is coming from, at which height it was
- // received, etc.
- type Tx interface {
- Height() int64
- HasSender(uint16) bool
- Raw() types.Tx
- }
-
- //--------------------------------------------------------------------------------
-
- // PreCheckFunc is an optional filter executed before CheckTx and rejects
- // transaction if false is returned. An example would be to ensure that a
- // transaction doesn't exceeded the block size.
- type PreCheckFunc func(types.Tx) error
-
- // PostCheckFunc is an optional filter executed after CheckTx and rejects
- // transaction if false is returned. An example would be to ensure a
- // transaction doesn't require more gas than available for the block.
- type PostCheckFunc func(types.Tx, *abci.ResponseCheckTx) error
-
- // TxInfo are parameters that get passed when attempting to add a tx to the
- // mempool.
- type TxInfo struct {
- // We don't use p2p.ID here because it's too big. The gain is to store max 2
- // bytes with each tx to identify the sender rather than 20 bytes.
- SenderID uint16
- }
-
- //--------------------------------------------------------------------------------
-
- // PreCheckAminoMaxBytes checks that the size of the transaction plus the amino
- // overhead is smaller or equal to the expected maxBytes.
- func PreCheckAminoMaxBytes(maxBytes int64) PreCheckFunc {
- return func(tx types.Tx) error {
- // We have to account for the amino overhead in the tx size as well
- // NOTE: fieldNum = 1 as types.Block.Data contains Txs []Tx as first field.
- // If this field order ever changes this needs to updated here accordingly.
- // NOTE: if some []Tx are encoded without a parenting struct, the
- // fieldNum is also equal to 1.
- aminoOverhead := types.ComputeAminoOverhead(tx, 1)
- txSize := int64(len(tx)) + aminoOverhead
- if txSize > maxBytes {
- return fmt.Errorf("Tx size (including amino overhead) is too big: %d, max: %d",
- txSize, maxBytes)
- }
- return nil
- }
- }
-
- // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed
- // maxGas. Returns nil if maxGas is -1.
- func PostCheckMaxGas(maxGas int64) PostCheckFunc {
- return func(tx types.Tx, res *abci.ResponseCheckTx) error {
- if maxGas == -1 {
- return nil
- }
- if res.GasWanted < 0 {
- return fmt.Errorf("gas wanted %d is negative",
- res.GasWanted)
- }
- if res.GasWanted > maxGas {
- return fmt.Errorf("gas wanted %d is greater than max gas %d",
- res.GasWanted, maxGas)
- }
- return nil
- }
- }
|