@@ -53,9 +53,10 @@ func (h *nonceHeap) Pop() interface{} {
5353// sortedMap is a nonce->transaction hash map with a heap based index to allow
5454// iterating over the contents in a nonce-incrementing way.
5555type sortedMap struct {
56- items map [uint64 ]* types.Transaction // Hash map storing the transaction data
57- index * nonceHeap // Heap of nonces of all the stored transactions (non-strict mode)
58- cache types.Transactions // Cache of the transactions already sorted
56+ items map [uint64 ]* types.Transaction // Hash map storing the transaction data
57+ index * nonceHeap // Heap of nonces of all the stored transactions (non-strict mode)
58+ cache types.Transactions // Cache of the transactions already sorted
59+ cacheMu sync.Mutex // Mutex covering the cache
5960}
6061
6162// newSortedMap creates a new nonce-sorted transaction map.
@@ -78,6 +79,8 @@ func (m *sortedMap) Put(tx *types.Transaction) {
7879 if m .items [nonce ] == nil {
7980 heap .Push (m .index , nonce )
8081 }
82+ m .cacheMu .Lock ()
83+ defer m .cacheMu .Unlock ()
8184 m .items [nonce ], m .cache = tx , nil
8285}
8386
@@ -94,6 +97,8 @@ func (m *sortedMap) Forward(threshold uint64) types.Transactions {
9497 delete (m .items , nonce )
9598 }
9699 // If we had a cached order, shift the front
100+ m .cacheMu .Lock ()
101+ defer m .cacheMu .Unlock ()
97102 if m .cache != nil {
98103 m .cache = m .cache [len (removed ):]
99104 }
@@ -120,6 +125,8 @@ func (m *sortedMap) reheap() {
120125 * m .index = append (* m .index , nonce )
121126 }
122127 heap .Init (m .index )
128+ m .cacheMu .Lock ()
129+ defer m .cacheMu .Unlock ()
123130 m .cache = nil
124131}
125132
@@ -136,7 +143,9 @@ func (m *sortedMap) filter(filter func(*types.Transaction) bool) types.Transacti
136143 }
137144 }
138145 if len (removed ) > 0 {
146+ m .cacheMu .Lock ()
139147 m .cache = nil
148+ m .cacheMu .Unlock ()
140149 }
141150 return removed
142151}
@@ -160,6 +169,8 @@ func (m *sortedMap) Cap(threshold int) types.Transactions {
160169 heap .Init (m .index )
161170
162171 // If we had a cache, shift the back
172+ m .cacheMu .Lock ()
173+ defer m .cacheMu .Unlock ()
163174 if m .cache != nil {
164175 m .cache = m .cache [:len (m .cache )- len (drops )]
165176 }
@@ -182,6 +193,8 @@ func (m *sortedMap) Remove(nonce uint64) bool {
182193 }
183194 }
184195 delete (m .items , nonce )
196+ m .cacheMu .Lock ()
197+ defer m .cacheMu .Unlock ()
185198 m .cache = nil
186199
187200 return true
@@ -206,6 +219,8 @@ func (m *sortedMap) Ready(start uint64) types.Transactions {
206219 delete (m .items , next )
207220 heap .Pop (m .index )
208221 }
222+ m .cacheMu .Lock ()
223+ defer m .cacheMu .Unlock ()
209224 m .cache = nil
210225
211226 return ready
@@ -217,6 +232,8 @@ func (m *sortedMap) Len() int {
217232}
218233
219234func (m * sortedMap ) flatten () types.Transactions {
235+ m .cacheMu .Lock ()
236+ defer m .cacheMu .Unlock ()
220237 // If the sorting was not cached yet, create and cache it
221238 if m .cache == nil {
222239 m .cache = make (types.Transactions , 0 , len (m .items ))
@@ -232,8 +249,8 @@ func (m *sortedMap) flatten() types.Transactions {
232249// sorted internal representation. The result of the sorting is cached in case
233250// it's requested again before any modifications are made to the contents.
234251func (m * sortedMap ) Flatten () types.Transactions {
235- // Copy the cache to prevent accidental modifications
236252 cache := m .flatten ()
253+ // Copy the cache to prevent accidental modification
237254 txs := make (types.Transactions , len (cache ))
238255 copy (txs , cache )
239256 return txs
0 commit comments