From 412c99880c587aba13ec66f7fe7a7a2c18e98302 Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Fri, 17 Apr 2026 14:55:56 +0800 Subject: [PATCH] feat(core): create global hasher pool #31769 Replace pooled and embedded Keccak state with stateless crypto helpers. This simplifies trie node hashing and EVM keccak handling while keeping focused package tests green. --- core/rawdb/accessors_trie.go | 30 +++--------------------------- core/vm/evm.go | 7 ++----- core/vm/instructions.go | 9 ++++----- 3 files changed, 9 insertions(+), 37 deletions(-) diff --git a/core/rawdb/accessors_trie.go b/core/rawdb/accessors_trie.go index 42493c59fb22..f41d31b94f43 100644 --- a/core/rawdb/accessors_trie.go +++ b/core/rawdb/accessors_trie.go @@ -18,7 +18,6 @@ package rawdb import ( "fmt" - "sync" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -45,25 +44,6 @@ const HashScheme = "hashScheme" // on extra state diffs to survive deep reorg. const PathScheme = "pathScheme" -// hasher is used to compute the sha256 hash of the provided data. -type hasher struct{ sha crypto.KeccakState } - -var hasherPool = sync.Pool{ - New: func() interface{} { return &hasher{sha: crypto.NewKeccakState()} }, -} - -func newHasher() *hasher { - return hasherPool.Get().(*hasher) -} - -func (h *hasher) hash(data []byte) common.Hash { - return crypto.HashData(h.sha, data) -} - -func (h *hasher) release() { - hasherPool.Put(h) -} - // ReadAccountTrieNode retrieves the account trie node with the specified node path. func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) []byte { data, _ := db.Get(accountTrieNodeKey(path)) @@ -170,9 +150,7 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c if len(blob) == 0 { return false } - h := newHasher() - defer h.release() - return h.hash(blob) == hash // exists but not match + return crypto.Keccak256Hash(blob) == hash // exist and match default: panic(fmt.Sprintf("Unknown scheme %v", scheme)) } @@ -194,10 +172,8 @@ func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash if len(blob) == 0 { return nil } - h := newHasher() - defer h.release() - if h.hash(blob) != hash { - return nil // exists but not match + if crypto.Keccak256Hash(blob) != hash { + return nil // exist but not match } return blob default: diff --git a/core/vm/evm.go b/core/vm/evm.go index 181ebbad43a3..548cf2d8765c 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -124,9 +124,6 @@ type EVM struct { // jumpDests stores results of JUMPDEST analysis. jumpDests JumpDestCache - hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes - hasherBuf common.Hash // Keccak256 hasher result array shared across opcodes - readOnly bool // Whether to throw on stateful modifications returnData []byte // Last CALL's return data for subsequent reuse } @@ -144,7 +141,6 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, tradingStateDB *tradingstate chainConfig: chainConfig, chainRules: chainConfig.Rules(blockCtx.BlockNumber), jumpDests: newMapJumpDests(), - hasher: crypto.NewKeccakState(), } evm.precompiles = activePrecompiledContracts(evm.chainRules) @@ -566,7 +562,8 @@ func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *ui // The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), crypto.Keccak256(code)) + inithash := crypto.Keccak256Hash(code) + contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:]) return evm.create(caller, code, gas, endowment, contractAddr, CREATE2) } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 8773d619658b..b9a31e310722 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -22,6 +22,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/tracing" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" "github.com/holiman/uint256" ) @@ -233,14 +234,12 @@ func opKeccak256(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { offset, size := scope.Stack.pop(), scope.Stack.peek() data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64()) - evm.hasher.Reset() - evm.hasher.Write(data) - evm.hasher.Read(evm.hasherBuf[:]) + hash := crypto.Keccak256Hash(data) if evm.Config.EnablePreimageRecording { - evm.StateDB.AddPreimage(evm.hasherBuf, data) + evm.StateDB.AddPreimage(hash, data) } - size.SetBytes(evm.hasherBuf[:]) + size.SetBytes(hash[:]) return nil, nil }