From 9e4f08c25dd0cb4b3d7bd992cadc5218f8623cea Mon Sep 17 00:00:00 2001 From: georgehao Date: Thu, 16 Jan 2025 21:36:45 +0800 Subject: [PATCH] core: use sync.Once for SenderCacher initialization (#31029) This changes the SenderCacher so its goroutines will only be started on first use. Avoids starting them when package core is just imported but core.BlockChain isn't used. --- core/blockchain.go | 2 +- core/sender_cacher.go | 13 +++++++++++-- core/txpool/legacypool/legacypool.go | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index b056b7ed0c..4ced94bb68 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1619,7 +1619,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) + SenderCacher().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..73bd5c85f2 100644 --- a/core/sender_cacher.go +++ b/core/sender_cacher.go @@ -18,12 +18,21 @@ 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()) +// senderCacherOnce is used to ensure that the SenderCacher is initialized only once. +var senderCacherOnce = sync.OnceValue(func() *txSenderCacher { + return newTxSenderCacher(runtime.NumCPU()) +}) + +// SenderCacher returns the singleton instance of SenderCacher, initializing it if called for the first time. +// This function is thread-safe and ensures that initialization happens only once. +func SenderCacher() *txSenderCacher { + return senderCacherOnce() +} // 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..55899c18fb 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.SenderCacher().Recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) }