github.com/evdatsion/aphelion-dpos-bft@v0.32.1/mempool/mempool.go (about) 1 package mempool 2 3 import ( 4 "fmt" 5 6 abci "github.com/evdatsion/aphelion-dpos-bft/abci/types" 7 "github.com/evdatsion/aphelion-dpos-bft/types" 8 ) 9 10 // Mempool defines the mempool interface. 11 // 12 // Updates to the mempool need to be synchronized with committing a block so 13 // apps can reset their transient state on Commit. 14 type Mempool interface { 15 // CheckTx executes a new transaction against the application to determine 16 // its validity and whether it should be added to the mempool. 17 CheckTx(tx types.Tx, callback func(*abci.Response)) error 18 19 // CheckTxWithInfo performs the same operation as CheckTx, but with extra 20 // meta data about the tx. 21 // Currently this metadata is the peer who sent it, used to prevent the tx 22 // from being gossiped back to them. 23 CheckTxWithInfo(tx types.Tx, callback func(*abci.Response), txInfo TxInfo) error 24 25 // ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes 26 // bytes total with the condition that the total gasWanted must be less than 27 // maxGas. 28 // If both maxes are negative, there is no cap on the size of all returned 29 // transactions (~ all available transactions). 30 ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs 31 32 // ReapMaxTxs reaps up to max transactions from the mempool. 33 // If max is negative, there is no cap on the size of all returned 34 // transactions (~ all available transactions). 35 ReapMaxTxs(max int) types.Txs 36 37 // Lock locks the mempool. The consensus must be able to hold lock to safely update. 38 Lock() 39 40 // Unlock unlocks the mempool. 41 Unlock() 42 43 // Update informs the mempool that the given txs were committed and can be discarded. 44 // NOTE: this should be called *after* block is committed by consensus. 45 // NOTE: unsafe; Lock/Unlock must be managed by caller 46 Update(blockHeight int64, blockTxs types.Txs, deliverTxResponses []*abci.ResponseDeliverTx, newPreFn PreCheckFunc, newPostFn PostCheckFunc) error 47 48 // FlushAppConn flushes the mempool connection to ensure async reqResCb calls are 49 // done. E.g. from CheckTx. 50 FlushAppConn() error 51 52 // Flush removes all transactions from the mempool and cache 53 Flush() 54 55 // TxsAvailable returns a channel which fires once for every height, 56 // and only when transactions are available in the mempool. 57 // NOTE: the returned channel may be nil if EnableTxsAvailable was not called. 58 TxsAvailable() <-chan struct{} 59 60 // EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will 61 // trigger once every height when transactions are available. 62 EnableTxsAvailable() 63 64 // Size returns the number of transactions in the mempool. 65 Size() int 66 67 // TxsBytes returns the total size of all txs in the mempool. 68 TxsBytes() int64 69 70 // InitWAL creates a directory for the WAL file and opens a file itself. 71 InitWAL() 72 73 // CloseWAL closes and discards the underlying WAL file. 74 // Any further writes will not be relayed to disk. 75 CloseWAL() 76 } 77 78 //-------------------------------------------------------------------------------- 79 80 // PreCheckFunc is an optional filter executed before CheckTx and rejects 81 // transaction if false is returned. An example would be to ensure that a 82 // transaction doesn't exceeded the block size. 83 type PreCheckFunc func(types.Tx) error 84 85 // PostCheckFunc is an optional filter executed after CheckTx and rejects 86 // transaction if false is returned. An example would be to ensure a 87 // transaction doesn't require more gas than available for the block. 88 type PostCheckFunc func(types.Tx, *abci.ResponseCheckTx) error 89 90 // TxInfo are parameters that get passed when attempting to add a tx to the 91 // mempool. 92 type TxInfo struct { 93 // We don't use p2p.ID here because it's too big. The gain is to store max 2 94 // bytes with each tx to identify the sender rather than 20 bytes. 95 SenderID uint16 96 } 97 98 //-------------------------------------------------------------------------------- 99 100 // PreCheckAminoMaxBytes checks that the size of the transaction plus the amino 101 // overhead is smaller or equal to the expected maxBytes. 102 func PreCheckAminoMaxBytes(maxBytes int64) PreCheckFunc { 103 return func(tx types.Tx) error { 104 // We have to account for the amino overhead in the tx size as well 105 // NOTE: fieldNum = 1 as types.Block.Data contains Txs []Tx as first field. 106 // If this field order ever changes this needs to updated here accordingly. 107 // NOTE: if some []Tx are encoded without a parenting struct, the 108 // fieldNum is also equal to 1. 109 aminoOverhead := types.ComputeAminoOverhead(tx, 1) 110 txSize := int64(len(tx)) + aminoOverhead 111 if txSize > maxBytes { 112 return fmt.Errorf("Tx size (including amino overhead) is too big: %d, max: %d", 113 txSize, maxBytes) 114 } 115 return nil 116 } 117 } 118 119 // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed 120 // maxGas. Returns nil if maxGas is -1. 121 func PostCheckMaxGas(maxGas int64) PostCheckFunc { 122 return func(tx types.Tx, res *abci.ResponseCheckTx) error { 123 if maxGas == -1 { 124 return nil 125 } 126 if res.GasWanted < 0 { 127 return fmt.Errorf("gas wanted %d is negative", 128 res.GasWanted) 129 } 130 if res.GasWanted > maxGas { 131 return fmt.Errorf("gas wanted %d is greater than max gas %d", 132 res.GasWanted, maxGas) 133 } 134 return nil 135 } 136 }