github.com/Finschia/ostracon@v1.1.5/mempool/mempool.go (about) 1 package mempool 2 3 import ( 4 "crypto/sha256" 5 "errors" 6 "fmt" 7 "math" 8 9 abci "github.com/tendermint/tendermint/abci/types" 10 11 ocabci "github.com/Finschia/ostracon/abci/types" 12 "github.com/Finschia/ostracon/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 // Mempool defines the mempool interface. 29 // 30 // Updates to the mempool need to be synchronized with committing a block so 31 // applications can reset their transient state on Commit. 32 type Mempool interface { 33 // CheckTx executes a new transaction against the application to determine 34 // its validity and whether it should be added to the mempool. 35 CheckTxSync(tx types.Tx, checkTxCb func(*ocabci.Response), txInfo TxInfo) error 36 CheckTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), checkTxCb func(*ocabci.Response)) 37 38 // RemoveTxByKey removes a transaction, identified by its key, 39 // from the mempool. 40 RemoveTxByKey(txKey types.TxKey) error 41 42 // ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes 43 // bytes total with the condition that the total gasWanted must be less than 44 // maxGas. 45 // 46 // If both maxes are negative, there is no cap on the size of all returned 47 // transactions (~ all available transactions). 48 ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs 49 50 // ReapMaxBytesMaxGasMaxTxs puts cap on txs as well on top of ReapMaxBytesMaxGas 51 ReapMaxBytesMaxGasMaxTxs(maxBytes, maxGas, maxTxs int64) types.Txs 52 53 // ReapMaxTxs reaps up to max transactions from the mempool. If max is 54 // negative, there is no cap on the size of all returned transactions 55 // (~ all available transactions). 56 ReapMaxTxs(max int) types.Txs 57 58 // Lock locks the mempool. The consensus must be able to hold lock to safely 59 // update. 60 Lock() 61 62 // Unlock unlocks the mempool. 63 Unlock() 64 65 // Update informs the mempool that the given txs were committed and can be 66 // discarded. 67 // 68 // NOTE: 69 // 1. This should be called *after* block is committed by consensus. 70 // 2. Lock/Unlock must be managed by the caller. 71 Update( 72 block *types.Block, 73 deliverTxResponses []*abci.ResponseDeliverTx, 74 newPreFn PreCheckFunc, 75 newPostFn PostCheckFunc, 76 ) error 77 78 // FlushAppConn flushes the mempool connection to ensure async callback calls 79 // are done, e.g. from CheckTx. 80 // 81 // NOTE: 82 // 1. Lock/Unlock must be managed by caller. 83 FlushAppConn() error 84 85 // Flush removes all transactions from the mempool and caches. 86 Flush() 87 88 // TxsAvailable returns a channel which fires once for every height, and only 89 // when transactions are available in the mempool. 90 // 91 // NOTE: 92 // 1. The returned channel may be nil if EnableTxsAvailable was not called. 93 TxsAvailable() <-chan struct{} 94 95 // EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will 96 // trigger once every height when transactions are available. 97 EnableTxsAvailable() 98 99 // Size returns the number of transactions in the mempool. 100 Size() int 101 102 // SizeBytes returns the total size of all txs in the mempool. 103 SizeBytes() int64 104 } 105 106 // PreCheckFunc is an optional filter executed before CheckTx and rejects 107 // transaction if false is returned. An example would be to ensure that a 108 // transaction doesn't exceeded the block size. 109 type PreCheckFunc func(types.Tx) error 110 111 // PostCheckFunc is an optional filter executed after CheckTx and rejects 112 // transaction if false is returned. An example would be to ensure a 113 // transaction doesn't require more gas than available for the block. 114 type PostCheckFunc func(types.Tx, *ocabci.ResponseCheckTx) error 115 116 // PreCheckMaxBytes checks that the size of the transaction is smaller or equal 117 // to the expected maxBytes. 118 func PreCheckMaxBytes(maxBytes int64) PreCheckFunc { 119 return func(tx types.Tx) error { 120 txSize := types.ComputeProtoSizeForTxs([]types.Tx{tx}) 121 122 if txSize > maxBytes { 123 return fmt.Errorf("tx size is too big: %d, max: %d", txSize, maxBytes) 124 } 125 126 return nil 127 } 128 } 129 130 // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed 131 // maxGas. Returns nil if maxGas is -1. 132 func PostCheckMaxGas(maxGas int64) PostCheckFunc { 133 return func(tx types.Tx, res *ocabci.ResponseCheckTx) error { 134 if maxGas == -1 { 135 return nil 136 } 137 if res.GasWanted < 0 { 138 return fmt.Errorf("gas wanted %d is negative", 139 res.GasWanted) 140 } 141 if res.GasWanted > maxGas { 142 return fmt.Errorf("gas wanted %d is greater than max gas %d", 143 res.GasWanted, maxGas) 144 } 145 146 return nil 147 } 148 } 149 150 // ErrTxInMap is returned to the client if we saw tx earlier in txsMap 151 var ErrTxInMap = errors.New("tx already exists in txsMap") 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 Tendermint 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 }