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
36 func NewTxPool() *TxPool {
38 lastUpdated: time.Now().Unix(),
39 pool: make(map[bc.Hash]*TxDesc),
40 errCache: lru.New(maxCachedErrTxs),
44 func (mp *TxPool) AddTransaction(tx *legacy.Tx, weight, height, fee uint64) *TxDesc {
51 FeePerKB: fee * 1000 / tx.TxHeader.SerializedSize,
57 mp.pool[tx.Tx.ID] = txD
58 atomic.StoreInt64(&mp.lastUpdated, time.Now().Unix())
62 func (mp *TxPool) AddErrCache(txHash *bc.Hash) {
66 mp.errCache.Add(txHash, nil)
69 func (mp *TxPool) RemoveTransaction(txHash *bc.Hash) {
73 if _, ok := mp.pool[*txHash]; ok {
74 delete(mp.pool, *txHash)
75 atomic.StoreInt64(&mp.lastUpdated, time.Now().Unix())
79 func (mp *TxPool) GetTransaction(txHash *bc.Hash) (*TxDesc, error) {
81 defer mp.mtx.RUnlock()
83 if txD, ok := mp.pool[*txHash]; ok {
87 return nil, ErrTransactionNotExist
90 func (mp *TxPool) GetTransactions() []*TxDesc {
92 defer mp.mtx.RUnlock()
94 txDs := make([]*TxDesc, len(mp.pool))
96 for _, desc := range mp.pool {
103 func (mp *TxPool) IsTransactionInPool(txHash *bc.Hash) bool {
105 defer mp.mtx.RUnlock()
107 if _, ok := mp.pool[*txHash]; ok {
113 func (mp *TxPool) IsTransactionInErrCache(txHash *bc.Hash) bool {
115 defer mp.mtx.RUnlock()
117 _, ok := mp.errCache.Get(txHash)
121 func (mp *TxPool) HaveTransaction(txHash *bc.Hash) bool {
122 return mp.IsTransactionInPool(txHash) || mp.IsTransactionInErrCache(txHash)
125 func (mp *TxPool) Count() int {
127 defer mp.mtx.RUnlock()
129 count := len(mp.pool)