You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
4.4 KiB

  1. package mempool
  2. import (
  3. "context"
  4. "fmt"
  5. "math"
  6. abci "github.com/tendermint/tendermint/abci/types"
  7. "github.com/tendermint/tendermint/internal/p2p"
  8. "github.com/tendermint/tendermint/types"
  9. )
  10. const (
  11. MempoolChannel = p2p.ChannelID(0x30)
  12. // PeerCatchupSleepIntervalMS defines how much time to sleep if a peer is behind
  13. PeerCatchupSleepIntervalMS = 100
  14. // UnknownPeerID is the peer ID to use when running CheckTx when there is
  15. // no peer (e.g. RPC)
  16. UnknownPeerID uint16 = 0
  17. MaxActiveIDs = math.MaxUint16
  18. )
  19. // Mempool defines the mempool interface.
  20. //
  21. // Updates to the mempool need to be synchronized with committing a block so
  22. // applications can reset their transient state on Commit.
  23. type Mempool interface {
  24. // CheckTx executes a new transaction against the application to determine
  25. // its validity and whether it should be added to the mempool.
  26. CheckTx(ctx context.Context, tx types.Tx, callback func(*abci.ResponseCheckTx), txInfo TxInfo) error
  27. // RemoveTxByKey removes a transaction, identified by its key,
  28. // from the mempool.
  29. RemoveTxByKey(txKey types.TxKey) error
  30. // ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes
  31. // bytes total with the condition that the total gasWanted must be less than
  32. // maxGas.
  33. //
  34. // If both maxes are negative, there is no cap on the size of all returned
  35. // transactions (~ all available transactions).
  36. ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs
  37. // ReapMaxTxs reaps up to max transactions from the mempool. If max is
  38. // negative, there is no cap on the size of all returned transactions
  39. // (~ all available transactions).
  40. ReapMaxTxs(max int) types.Txs
  41. // Lock locks the mempool. The consensus must be able to hold lock to safely
  42. // update.
  43. Lock()
  44. // Unlock unlocks the mempool.
  45. Unlock()
  46. // Update informs the mempool that the given txs were committed and can be
  47. // discarded.
  48. //
  49. // NOTE:
  50. // 1. This should be called *after* block is committed by consensus.
  51. // 2. Lock/Unlock must be managed by the caller.
  52. Update(
  53. ctx context.Context,
  54. blockHeight int64,
  55. blockTxs types.Txs,
  56. txResults []*abci.ExecTxResult,
  57. newPreFn PreCheckFunc,
  58. newPostFn PostCheckFunc,
  59. ) error
  60. // FlushAppConn flushes the mempool connection to ensure async callback calls
  61. // are done, e.g. from CheckTx.
  62. //
  63. // NOTE:
  64. // 1. Lock/Unlock must be managed by caller.
  65. FlushAppConn(context.Context) error
  66. // Flush removes all transactions from the mempool and caches.
  67. Flush()
  68. // TxsAvailable returns a channel which fires once for every height, and only
  69. // when transactions are available in the mempool.
  70. //
  71. // NOTE:
  72. // 1. The returned channel may be nil if EnableTxsAvailable was not called.
  73. TxsAvailable() <-chan struct{}
  74. // EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will
  75. // trigger once every height when transactions are available.
  76. EnableTxsAvailable()
  77. // Size returns the number of transactions in the mempool.
  78. Size() int
  79. // SizeBytes returns the total size of all txs in the mempool.
  80. SizeBytes() int64
  81. }
  82. // PreCheckFunc is an optional filter executed before CheckTx and rejects
  83. // transaction if false is returned. An example would be to ensure that a
  84. // transaction doesn't exceeded the block size.
  85. type PreCheckFunc func(types.Tx) error
  86. // PostCheckFunc is an optional filter executed after CheckTx and rejects
  87. // transaction if false is returned. An example would be to ensure a
  88. // transaction doesn't require more gas than available for the block.
  89. type PostCheckFunc func(types.Tx, *abci.ResponseCheckTx) error
  90. // PreCheckMaxBytes checks that the size of the transaction is smaller or equal
  91. // to the expected maxBytes.
  92. func PreCheckMaxBytes(maxBytes int64) PreCheckFunc {
  93. return func(tx types.Tx) error {
  94. txSize := types.ComputeProtoSizeForTxs([]types.Tx{tx})
  95. if txSize > maxBytes {
  96. return fmt.Errorf("tx size is too big: %d, max: %d", txSize, maxBytes)
  97. }
  98. return nil
  99. }
  100. }
  101. // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed
  102. // maxGas. Returns nil if maxGas is -1.
  103. func PostCheckMaxGas(maxGas int64) PostCheckFunc {
  104. return func(tx types.Tx, res *abci.ResponseCheckTx) error {
  105. if maxGas == -1 {
  106. return nil
  107. }
  108. if res.GasWanted < 0 {
  109. return fmt.Errorf("gas wanted %d is negative",
  110. res.GasWanted)
  111. }
  112. if res.GasWanted > maxGas {
  113. return fmt.Errorf("gas wanted %d is greater than max gas %d",
  114. res.GasWanted, maxGas)
  115. }
  116. return nil
  117. }
  118. }