github.com/okex/exchain@v1.8.0/libs/tendermint/mempool/txqueue.go (about) 1 package mempool 2 3 import ( 4 "crypto/sha256" 5 "sync" 6 7 "github.com/okex/exchain/libs/tendermint/libs/clist" 8 "github.com/okex/exchain/libs/tendermint/types" 9 ) 10 11 type ITransactionQueue interface { 12 Len() int 13 Insert(tx *mempoolTx) error 14 Remove(element *clist.CElement) 15 RemoveByKey(key [sha256.Size]byte) *clist.CElement 16 Front() *clist.CElement 17 Back() *clist.CElement 18 BroadcastFront() *clist.CElement 19 BroadcastLen() int 20 Load(hash [sha256.Size]byte) (*clist.CElement, bool) 21 TxsWaitChan() <-chan struct{} 22 23 AddressRecorder 24 } 25 26 type AddressRecorder interface { 27 GetAddressList() []string 28 GetAddressNonce(address string) (uint64, bool) 29 GetAddressTxsCnt(address string) int 30 GetAddressTxs(address string, max int) types.Txs 31 CleanItems(address string, nonce uint64) 32 } 33 34 type BaseTxQueue struct { 35 txs *clist.CList // FIFO list 36 txsMap sync.Map //txKey -> CElement 37 38 *AddressRecord 39 } 40 41 func NewBaseTxQueue() *BaseTxQueue { 42 return &BaseTxQueue{ 43 txs: clist.New(), 44 AddressRecord: newAddressRecord(nil), 45 } 46 } 47 48 func (q *BaseTxQueue) Len() int { 49 return q.txs.Len() 50 } 51 52 func (q *BaseTxQueue) Insert(tx *mempoolTx) error { 53 /* 54 1. insert tx list 55 2. insert address record 56 3. insert tx map 57 */ 58 ele := q.txs.PushBack(tx) 59 60 q.AddressRecord.AddItem(ele.Address, ele) 61 q.txsMap.Store(txKey(ele.Value.(*mempoolTx).tx), ele) 62 return nil 63 } 64 65 func (q *BaseTxQueue) Remove(element *clist.CElement) { 66 q.removeElement(element) 67 q.AddressRecord.DeleteItem(element) 68 } 69 70 func (q *BaseTxQueue) RemoveByKey(key [32]byte) (ele *clist.CElement) { 71 ele = q.removeElementByKey(key) 72 if ele != nil { 73 q.AddressRecord.DeleteItem(ele) 74 } 75 return 76 } 77 78 func (q *BaseTxQueue) Front() *clist.CElement { 79 return q.txs.Front() 80 } 81 82 func (q *BaseTxQueue) Back() *clist.CElement { 83 return q.txs.Back() 84 } 85 86 func (q *BaseTxQueue) BroadcastFront() *clist.CElement { 87 return q.txs.Front() 88 } 89 90 func (q *BaseTxQueue) BroadcastLen() int { 91 return q.txs.Len() 92 } 93 94 func (q *BaseTxQueue) TxsWaitChan() <-chan struct{} { 95 return q.txs.WaitChan() 96 } 97 98 func (q *BaseTxQueue) Load(hash [sha256.Size]byte) (*clist.CElement, bool) { 99 v, ok := q.txsMap.Load(hash) 100 if !ok { 101 return nil, false 102 } 103 return v.(*clist.CElement), true 104 } 105 106 func (q *BaseTxQueue) removeElement(element *clist.CElement) { 107 q.txs.Remove(element) 108 element.DetachPrev() 109 110 tx := element.Value.(*mempoolTx).tx 111 txHash := txKey(tx) 112 q.txsMap.Delete(txHash) 113 } 114 115 func (q *BaseTxQueue) removeElementByKey(key [32]byte) *clist.CElement { 116 if v, ok := q.txsMap.LoadAndDelete(key); ok { 117 element := v.(*clist.CElement) 118 q.txs.Remove(element) 119 element.DetachPrev() 120 return element 121 } 122 return nil 123 } 124 125 func (q *BaseTxQueue) CleanItems(address string, nonce uint64) { 126 q.AddressRecord.CleanItems(address, nonce, q.removeElement) 127 }