From bc9e3faed1674a234f4c16e4c5319ce5b6f6318f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 18 Nov 2025 11:19:45 +0100 Subject: [PATCH] core: use stateless keccak --- core/stateless/database.go | 18 +++--------------- core/types/hashing.go | 22 ++++------------------ core/vm/evm.go | 8 ++------ 3 files changed, 9 insertions(+), 39 deletions(-) diff --git a/core/stateless/database.go b/core/stateless/database.go index f54c123dda..5655bc28bf 100644 --- a/core/stateless/database.go +++ b/core/stateless/database.go @@ -34,11 +34,7 @@ import ( // // Acceleration structures built would need to explicitly validate the witness. func (w *Witness) MakeHashDB() ethdb.Database { - var ( - memdb = rawdb.NewMemoryDatabase() - hasher = crypto.NewKeccakState() - hash = make([]byte, 32) - ) + var memdb = rawdb.NewMemoryDatabase() // Inject all the "block hashes" (i.e. headers) into the ephemeral database for _, header := range w.Headers { rawdb.WriteHeader(memdb, header) @@ -46,21 +42,13 @@ func (w *Witness) MakeHashDB() ethdb.Database { // Inject all the bytecodes into the ephemeral database for code := range w.Codes { blob := []byte(code) - - hasher.Reset() - hasher.Write(blob) - hasher.Read(hash) - + hash := crypto.Keccak256(blob) rawdb.WriteCode(memdb, common.BytesToHash(hash), blob) } // Inject all the MPT trie nodes into the ephemeral database for node := range w.State { blob := []byte(node) - - hasher.Reset() - hasher.Write(blob) - hasher.Read(hash) - + hash := crypto.Keccak256(blob) rawdb.WriteLegacyTrieNode(memdb, common.BytesToHash(hash), blob) } return memdb diff --git a/core/types/hashing.go b/core/types/hashing.go index 98fe64e15a..31e0e91e99 100644 --- a/core/types/hashing.go +++ b/core/types/hashing.go @@ -27,11 +27,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) -// hasherPool holds LegacyKeccak256 buffer for rlpHash. -var hasherPool = sync.Pool{ - New: func() interface{} { return crypto.NewKeccakState() }, -} - // encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding. var encodeBufferPool = sync.Pool{ New: func() interface{} { return new(bytes.Buffer) }, @@ -55,24 +50,15 @@ func getPooledBuffer(size uint64) ([]byte, *bytes.Buffer, error) { // rlpHash encodes x and hashes the encoded bytes. func rlpHash(x interface{}) (h common.Hash) { - sha := hasherPool.Get().(crypto.KeccakState) - defer hasherPool.Put(sha) - sha.Reset() - rlp.Encode(sha, x) - sha.Read(h[:]) - return h + encoded, _ := rlp.EncodeToBytes(x) + return crypto.Keccak256Hash(encoded) } // prefixedRlpHash writes the prefix into the hasher before rlp-encoding x. // It's used for typed transactions. func prefixedRlpHash(prefix byte, x interface{}) (h common.Hash) { - sha := hasherPool.Get().(crypto.KeccakState) - defer hasherPool.Put(sha) - sha.Reset() - sha.Write([]byte{prefix}) - rlp.Encode(sha, x) - sha.Read(h[:]) - return h + encoded, _ := rlp.EncodeToBytes(x) + return crypto.Keccak256Hash([]byte{prefix}, encoded) } // ListHasher defines the interface for computing the hash of a derivable list. diff --git a/core/vm/evm.go b/core/vm/evm.go index 8975c791c8..5595cc963d 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -125,9 +125,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, chainConfig *params.ChainCon chainConfig: chainConfig, chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time), jumpDests: newMapJumpDests(), - hasher: crypto.NewKeccakState(), } evm.precompiles = activePrecompiledContracts(evm.chainRules) @@ -618,8 +614,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) { - inithash := crypto.HashData(evm.hasher, code) - contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:]) + inithash := crypto.Keccak256(code) + contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash) return evm.create(caller, code, gas, endowment, contractAddr, CREATE2) }