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 }