From 44d9fba09ae918cb549a1ac6785fedffedd473f2 Mon Sep 17 00:00:00 2001
From: Hao Duan <duanhao0814@gmail.com>
Date: Tue, 4 Aug 2020 17:51:53 +0800
Subject: [PATCH] core: avoid modification of accountSet cache in tx_pool
 (#21159)

* core: avoid modification of accountSet cache in tx_pool

when runReorg, we may copy the dirtyAccounts' accountSet cache to promoteAddrs
in which accounts will be promoted, however, if we have reset request at the
same time, we may reuse promoteAddrs and modify the cache content which is
against the original intention of accountSet cache. So, we need to make a new
slice here to avoid modify accountSet cache.

* core: fix flatten condition + comment

Co-authored-by: Felix Lange <fjl@twurst.com>
---
 core/tx_pool.go | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/core/tx_pool.go b/core/tx_pool.go
index 16cd7076b0..3f9ad1bada 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -1052,7 +1052,10 @@ func (pool *TxPool) runReorg(done chan struct{}, dirtyAccounts *accountSet, even
 	defer close(done)
 
 	var promoteAddrs []common.Address
-	if dirtyAccounts != nil {
+	if dirtyAccounts != nil && reset == nil {
+		// Only dirty accounts need to be promoted, unless we're resetting.
+		// For resets, all addresses in the tx queue will be promoted and
+		// the flatten operation can be avoided.
 		promoteAddrs = dirtyAccounts.flatten()
 	}
 	pool.mu.Lock()
@@ -1065,7 +1068,7 @@ func (pool *TxPool) runReorg(done chan struct{}, dirtyAccounts *accountSet, even
 			}
 		}
 		// Reset needs promote for all addresses
-		promoteAddrs = promoteAddrs[:0]
+		promoteAddrs = make([]common.Address, 0, len(pool.queue))
 		for addr := range pool.queue {
 			promoteAddrs = append(promoteAddrs, addr)
 		}
-- 
GitLab