From d078ad321c9d4ba79756924ef2798a52d104bc59 Mon Sep 17 00:00:00 2001 From: georgehao Date: Tue, 14 Jan 2025 09:03:59 +0800 Subject: [PATCH] improve txSenderCacher init --- core/blockchain.go | 2 +- core/sender_cacher.go | 20 ++++++++++++++++++-- core/txpool/legacypool/legacypool.go | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 0fe4812626..408d5a4c53 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1616,7 +1616,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness return nil, 0, nil } // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) - SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain) + GetSenderCacher().RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain) var ( stats = insertStats{startTime: mclock.Now()} diff --git a/core/sender_cacher.go b/core/sender_cacher.go index 4be53619eb..c6f33e315c 100644 --- a/core/sender_cacher.go +++ b/core/sender_cacher.go @@ -18,12 +18,28 @@ package core import ( "runtime" + "sync" "github.com/ethereum/go-ethereum/core/types" ) -// SenderCacher is a concurrent transaction sender recoverer and cacher. -var SenderCacher = newTxSenderCacher(runtime.NumCPU()) +var ( + // senderCacherOnce is used to ensure that the SenderCacher is initialized only once. + // It leverages sync.Once to provide thread-safe lazy initialization. + senderCacherOnce sync.Once + // senderCacherInstance is a concurrent transaction sender recoverer and cacher. + senderCacherInstance = newTxSenderCacher(runtime.NumCPU()) +) + +// GetSenderCacher returns the singleton instance of SenderCacher. +// If the instance has not been initialized yet, it will be created using newTxSenderCacher. +// This function is thread-safe and ensures that initialization happens only once. +func GetSenderCacher() *txSenderCacher { + senderCacherOnce.Do(func() { + senderCacherInstance = newTxSenderCacher(runtime.NumCPU()) + }) + return senderCacherInstance +} // txSenderCacherRequest is a request for recovering transaction senders with a // specific signature scheme and caching it into the transactions themselves. diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 71cca7d1db..84975f4396 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1440,7 +1440,7 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) { // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) - core.SenderCacher.Recover(pool.signer, reinject) + core.GetSenderCacher().Recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) }