From 85dbe96fc481ecb8b47f89ad99d0cb621edd76e6 Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Wed, 11 Mar 2026 17:25:59 +0800 Subject: [PATCH] fix(core): use sync.Once for SenderCacher initialization #31029 --- 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 3a4ec2ae473a..a0d7b76ff5dd 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1505,7 +1505,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] } // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) - SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) + SenderCacher().RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) // A queued approach to delivering events. This is generally // faster than direct delivery and requires much less mutex diff --git a/core/sender_cacher.go b/core/sender_cacher.go index e556ebd4e407..1fafe1d00d15 100644 --- a/core/sender_cacher.go +++ b/core/sender_cacher.go @@ -18,12 +18,21 @@ package core import ( "runtime" + "sync" "github.com/XinFinOrg/XDPoSChain/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 f827f5d3cc61..008fdc1bafdc 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1613,7 +1613,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) }