@@ -244,6 +244,8 @@ type BlockChain struct {
244244 bodyRLPCache * lru.Cache [common.Hash , rlp.RawValue ]
245245 receiptsCache * lru.Cache [common.Hash , []* types.Receipt ]
246246 blockCache * lru.Cache [common.Hash , * types.Block ]
247+
248+ txLookupLock sync.RWMutex
247249 txLookupCache * lru.Cache [common.Hash , txLookup ]
248250
249251 wg sync.WaitGroup
@@ -2290,14 +2292,14 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
22902292 // rewind the canonical chain to a lower point.
22912293 log .Error ("Impossible reorg, please file an issue" , "oldnum" , oldBlock .Number (), "oldhash" , oldBlock .Hash (), "oldblocks" , len (oldChain ), "newnum" , newBlock .Number (), "newhash" , newBlock .Hash (), "newblocks" , len (newChain ))
22922294 }
2293- // Reset the tx lookup cache in case to clear stale txlookups.
2294- // This is done before writing any new chain data to avoid the
2295- // weird scenario that canonical chain is changed while the
2296- // stale lookups are still cached.
2297- bc .txLookupCache .Purge ()
2295+ // Acquire the tx-lookup lock before mutation. This step is essential
2296+ // as the txlookups should be changed atomically, and all subsequent
2297+ // reads should be blocked until the mutation is complete.
2298+ bc .txLookupLock .Lock ()
22982299
2299- // Insert the new chain(except the head block(reverse order)),
2300- // taking care of the proper incremental order.
2300+ // Insert the new chain segment in incremental order, from the old
2301+ // to the new. The new chain head (newChain[0]) is not inserted here,
2302+ // as it will be handled separately outside of this function
23012303 for i := len (newChain ) - 1 ; i >= 1 ; i -- {
23022304 // Insert the block in the canonical way, re-writing history
23032305 bc .writeHeadBlock (newChain [i ])
@@ -2334,6 +2336,11 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
23342336 if err := indexesBatch .Write (); err != nil {
23352337 log .Crit ("Failed to delete useless indexes" , "err" , err )
23362338 }
2339+ // Reset the tx lookup cache to clear stale txlookup cache.
2340+ bc .txLookupCache .Purge ()
2341+
2342+ // Release the tx-lookup lock after mutation.
2343+ bc .txLookupLock .Unlock ()
23372344
23382345 // Send out events for logs from the old canon chain, and 'reborn'
23392346 // logs from the new canon chain. The number of logs can be very
0 commit comments