From b29998a3af3507e5b25691f452f96f2aef7b919b Mon Sep 17 00:00:00 2001 From: maskpp Date: Wed, 14 May 2025 15:46:29 +0800 Subject: [PATCH] upgrade hasher pool --- accounts/accounts.go | 6 ++-- cmd/evm/internal/t8ntool/execution.go | 6 +--- cmd/workload/historytestgen.go | 5 +-- consensus/clique/clique.go | 10 +++--- consensus/ethash/consensus.go | 9 ++--- crypto/crypto.go | 49 ++++++++++++++++++--------- p2p/dnsdisc/tree.go | 12 +++---- p2p/enode/idscheme.go | 11 +++--- 8 files changed, 51 insertions(+), 57 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 7bd911577a..5d06306798 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -24,8 +24,8 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" - "golang.org/x/crypto/sha3" ) // Account represents an Ethereum account located at a specific location defined @@ -196,9 +196,7 @@ func TextHash(data []byte) []byte { // This gives context to the signed message and prevents signing of transactions. func TextAndHash(data []byte) ([]byte, string) { msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) - hasher := sha3.NewLegacyKeccak256() - hasher.Write([]byte(msg)) - return hasher.Sum(nil), msg + return crypto.Keccak256([]byte(msg)), msg } // WalletEventType represents the different event types that can be fired by diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index b2e5f70714..da492b355c 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -40,7 +40,6 @@ import ( "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) type Prestate struct { @@ -437,10 +436,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB } func rlpHash(x interface{}) (h common.Hash) { - hw := sha3.NewLegacyKeccak256() - rlp.Encode(hw, x) - hw.Sum(h[:0]) - return h + return crypto.Keccak256RLPHash(x) } // calcDifficulty is based on ethash.CalcDifficulty. This method is used in case diff --git a/cmd/workload/historytestgen.go b/cmd/workload/historytestgen.go index 9d98bb28e6..84b3d7c194 100644 --- a/cmd/workload/historytestgen.go +++ b/cmd/workload/historytestgen.go @@ -27,7 +27,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/internal/flags" - "github.com/ethereum/go-ethereum/rlp" "github.com/urfave/cli/v2" ) @@ -131,9 +130,7 @@ func generateHistoryTests(clictx *cli.Context) error { } func calcReceiptsHash(rcpt []*types.Receipt) common.Hash { - h := crypto.NewKeccakState() - rlp.Encode(h, rcpt) - return common.Hash(h.Sum(nil)) + return crypto.Keccak256RLPHash(rcpt) } func writeJSON(fileName string, value any) { diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index d31efd7445..79afa3e830 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -43,7 +43,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" - "golang.org/x/crypto/sha3" ) const ( @@ -651,11 +650,10 @@ func (c *Clique) APIs(chain consensus.ChainHeaderReader) []rpc.API { } // SealHash returns the hash of a block prior to it being sealed. -func SealHash(header *types.Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() - encodeSigHeader(hasher, header) - hasher.(crypto.KeccakState).Read(hash[:]) - return hash +func SealHash(header *types.Header) common.Hash { + buf := bytes.NewBuffer(nil) + encodeSigHeader(buf, header) + return crypto.Keccak256Hash(buf.Bytes()) } // CliqueRLP returns the rlp bytes which needs to be signed for the proof-of-authority diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 4f92f1282b..fc5522c012 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -31,11 +31,10 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) // Ethash proof-of-work protocol constants. @@ -527,8 +526,6 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea // SealHash returns the hash of a block prior to it being sealed. func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() - enc := []interface{}{ header.ParentHash, header.UncleHash, @@ -559,9 +556,7 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) { if header.ParentBeaconRoot != nil { panic("parent beacon root set on ethash") } - rlp.Encode(hasher, enc) - hasher.Sum(hash[:0]) - return hash + return crypto.Keccak256RLPHash(enc) } // accumulateRewards credits the coinbase of the given block with the mining diff --git a/crypto/crypto.go b/crypto/crypto.go index 09596c05ce..ff02cedbab 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -74,9 +74,17 @@ func NewKeccakState() KeccakState { return sha3.NewLegacyKeccak256().(KeccakState) } +type keccakState struct { + KeccakState + hashBuf common.Hash +} + var hasherPool = sync.Pool{ New: func() any { - return sha3.NewLegacyKeccak256().(KeccakState) + return &keccakState{ + hashBuf: common.Hash{}, + KeccakState: sha3.NewLegacyKeccak256().(KeccakState), + } }, } @@ -90,28 +98,38 @@ func HashData(kh KeccakState, data []byte) (h common.Hash) { // Keccak256 calculates and returns the Keccak256 hash of the input data. func Keccak256(data ...[]byte) []byte { - b := make([]byte, 32) - d := hasherPool.Get().(KeccakState) - d.Reset() - for _, b := range data { - d.Write(b) - } - d.Read(b) - hasherPool.Put(d) - return b + b := Keccak256Hash(data...) + return b[:] +} + +// Keccak256RLP calculates and returns the Keccak256 hash of the input interface. +func Keccak256RLP(x interface{}) []byte { + b := Keccak256RLPHash(x) + return b[:] } // Keccak256Hash calculates and returns the Keccak256 hash of the input data, // converting it to an internal Hash data structure. -func Keccak256Hash(data ...[]byte) (h common.Hash) { - d := hasherPool.Get().(KeccakState) +func Keccak256Hash(data ...[]byte) common.Hash { + d := hasherPool.Get().(*keccakState) d.Reset() for _, b := range data { d.Write(b) } - d.Read(h[:]) + d.Read(d.hashBuf[:]) hasherPool.Put(d) - return h + return d.hashBuf +} + +// Keccak256RLPHash calculates and returns the Keccak256 hash of the input interface, +// converting it to an internal Hash data structure. +func Keccak256RLPHash(x interface{}) common.Hash { + d := hasherPool.Get().(*keccakState) + d.Reset() + rlp.Encode(d, x) + d.Read(d.hashBuf[:]) + hasherPool.Put(d) + return d.hashBuf } // Keccak512 calculates and returns the Keccak512 hash of the input data. @@ -125,8 +143,7 @@ func Keccak512(data ...[]byte) []byte { // CreateAddress creates an ethereum address given the bytes and the nonce func CreateAddress(b common.Address, nonce uint64) common.Address { - data, _ := rlp.EncodeToBytes([]interface{}{b, nonce}) - return common.BytesToAddress(Keccak256(data)[12:]) + return common.BytesToAddress(Keccak256RLP([]interface{}{b, nonce})[12:]) } // CreateAddress2 creates an ethereum address given the address bytes, initial diff --git a/p2p/dnsdisc/tree.go b/p2p/dnsdisc/tree.go index a8295ac9eb..6bcf89c121 100644 --- a/p2p/dnsdisc/tree.go +++ b/p2p/dnsdisc/tree.go @@ -23,7 +23,6 @@ import ( "encoding/base64" "errors" "fmt" - "io" "slices" "strings" @@ -31,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // Tree is a merkle tree of node records. @@ -262,9 +260,8 @@ const ( ) func subdomain(e entry) string { - h := sha3.NewLegacyKeccak256() - io.WriteString(h, e.String()) - return b32format.EncodeToString(h.Sum(nil)[:16]) + src := crypto.Keccak256([]byte(e.String())) + return b32format.EncodeToString(src[:16]) } func (e *rootEntry) String() string { @@ -272,9 +269,8 @@ func (e *rootEntry) String() string { } func (e *rootEntry) sigHash() []byte { - h := sha3.NewLegacyKeccak256() - fmt.Fprintf(h, rootPrefix+" e=%s l=%s seq=%d", e.eroot, e.lroot, e.seq) - return h.Sum(nil) + prefix := fmt.Sprintf(rootPrefix+" e=%s l=%s seq=%d", e.eroot, e.lroot, e.seq) + return crypto.Keccak256([]byte(prefix)) } func (e *rootEntry) verifySignature(pubkey *ecdsa.PublicKey) bool { diff --git a/p2p/enode/idscheme.go b/p2p/enode/idscheme.go index db7841c047..8061eea968 100644 --- a/p2p/enode/idscheme.go +++ b/p2p/enode/idscheme.go @@ -25,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // ValidSchemes is a List of known secure identity schemes. @@ -49,9 +48,8 @@ func SignV4(r *enr.Record, privkey *ecdsa.PrivateKey) error { cpy.Set(enr.ID("v4")) cpy.Set(Secp256k1(privkey.PublicKey)) - h := sha3.NewLegacyKeccak256() - rlp.Encode(h, cpy.AppendElements(nil)) - sig, err := crypto.Sign(h.Sum(nil), privkey) + digestHash := crypto.Keccak256RLP(cpy.AppendElements(nil)) + sig, err := crypto.Sign(digestHash, privkey) if err != nil { return err } @@ -70,9 +68,8 @@ func (V4ID) Verify(r *enr.Record, sig []byte) error { return errors.New("invalid public key") } - h := sha3.NewLegacyKeccak256() - rlp.Encode(h, r.AppendElements(nil)) - if !crypto.VerifySignature(entry, h.Sum(nil), sig) { + digestHash := crypto.Keccak256RLP(r.AppendElements(nil)) + if !crypto.VerifySignature(entry, digestHash, sig) { return enr.ErrInvalidSig } return nil