9 "github.com/bytom/protocol/bc"
10 "github.com/bytom/protocol/bc/legacy"
11 "github.com/golang/groupcache/lru"
15 maxCachedErrTxs = 1000
17 ErrTransactionNotExist = errors.New("transaction are not existed in the mempool")
32 pool map[bc.Hash]*TxDesc
34 newTxCh chan *legacy.Tx
37 func NewTxPool() *TxPool {
39 lastUpdated: time.Now().Unix(),
40 pool: make(map[bc.Hash]*TxDesc),
41 errCache: lru.New(maxCachedErrTxs),
42 newTxCh: make(chan *legacy.Tx, maxNewTxChSize),
46 func (mp *TxPool) GetNewTxCh() chan *legacy.Tx {
50 func (mp *TxPool) AddTransaction(tx *legacy.Tx, height, fee uint64) *TxDesc {
54 Weight: tx.TxData.SerializedSize,
57 FeePerKB: fee * 1000 / tx.TxHeader.SerializedSize,
63 mp.pool[tx.Tx.ID] = txD
64 atomic.StoreInt64(&mp.lastUpdated, time.Now().Unix())
70 func (mp *TxPool) AddErrCache(txHash *bc.Hash, err error) {
74 mp.errCache.Add(txHash, err)
77 func (mp *TxPool) GetErrCache(txHash *bc.Hash) error {
81 v, ok := mp.errCache.Get(txHash)
88 func (mp *TxPool) RemoveTransaction(txHash *bc.Hash) {
92 if _, ok := mp.pool[*txHash]; ok {
93 delete(mp.pool, *txHash)
94 atomic.StoreInt64(&mp.lastUpdated, time.Now().Unix())
98 func (mp *TxPool) GetTransaction(txHash *bc.Hash) (*TxDesc, error) {
100 defer mp.mtx.RUnlock()
102 if txD, ok := mp.pool[*txHash]; ok {
106 return nil, ErrTransactionNotExist
109 func (mp *TxPool) GetTransactions() []*TxDesc {
111 defer mp.mtx.RUnlock()
113 txDs := make([]*TxDesc, len(mp.pool))
115 for _, desc := range mp.pool {
122 func (mp *TxPool) IsTransactionInPool(txHash *bc.Hash) bool {
124 defer mp.mtx.RUnlock()
126 if _, ok := mp.pool[*txHash]; ok {
132 func (mp *TxPool) IsTransactionInErrCache(txHash *bc.Hash) bool {
134 defer mp.mtx.RUnlock()
136 _, ok := mp.errCache.Get(txHash)
140 func (mp *TxPool) HaveTransaction(txHash *bc.Hash) bool {
141 return mp.IsTransactionInPool(txHash) || mp.IsTransactionInErrCache(txHash)
144 func (mp *TxPool) Count() int {
146 defer mp.mtx.RUnlock()
148 count := len(mp.pool)