diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 86f4ac19cb..8854336327 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -667,7 +667,6 @@ func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool, var ( count, deleted, skipped int - buff = crypto.NewKeccakState() startTime = time.Now() ) @@ -680,7 +679,7 @@ func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool, for it.Next() && bytes.Compare(end, it.Key()) > 0 { // Prevent deletion for trie nodes in hash mode - if len(it.Key()) != 32 || crypto.HashData(buff, it.Value()) != common.BytesToHash(it.Key()) { + if len(it.Key()) != 32 || crypto.Keccak256Hash(it.Value()) != common.BytesToHash(it.Key()) { if err := batch.Delete(it.Key()); err != nil { return err } diff --git a/core/rawdb/database_test.go b/core/rawdb/database_test.go deleted file mode 100644 index a0d7b5ec66..0000000000 --- a/core/rawdb/database_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb diff --git a/core/state/reader.go b/core/state/reader.go index 09edf6ab8d..695521a71e 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -204,9 +204,8 @@ func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash, // // trieReader is safe for concurrent read. type trieReader struct { - root common.Hash // State root which uniquely represent a state - db *triedb.Database // Database for loading trie - buff crypto.KeccakState // Buffer for keccak256 hashing + root common.Hash // State root which uniquely represent a state + db *triedb.Database // Database for loading trie // Main trie, resolved in constructor. Note either the Merkle-Patricia-tree // or Verkle-tree is not safe for concurrent read. @@ -235,7 +234,6 @@ func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCach return &trieReader{ root: root, db: db, - buff: crypto.NewKeccakState(), mainTrie: tr, subRoots: make(map[common.Address]common.Hash), subTries: make(map[common.Address]Trie), @@ -298,7 +296,7 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash, root = r.subRoots[addr] } var err error - tr, err = trie.NewStateTrie(trie.StorageTrieID(r.root, crypto.HashData(r.buff, addr.Bytes()), root), r.db) + tr, err = trie.NewStateTrie(trie.StorageTrieID(r.root, crypto.Keccak256Hash(addr.Bytes()), root), r.db) if err != nil { return common.Hash{}, err } diff --git a/core/state/state_object.go b/core/state/state_object.go index a6979bd361..73a3b5146c 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -377,7 +377,6 @@ func (s *stateObject) updateRoot() { // fulfills the storage diffs into the given accountUpdate struct. func (s *stateObject) commitStorage(op *accountUpdate) { var ( - buf = crypto.NewKeccakState() encode = func(val common.Hash) []byte { if val == (common.Hash{}) { return nil @@ -394,7 +393,7 @@ func (s *stateObject) commitStorage(op *accountUpdate) { if val == s.originStorage[key] { continue } - hash := crypto.HashData(buf, key[:]) + hash := crypto.Keccak256Hash(key[:]) if op.storages == nil { op.storages = make(map[common.Hash][]byte) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 62f984de56..6b474ea0a4 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1064,7 +1064,6 @@ func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*accountDelete, []*trienode.NodeSet, error) { var ( nodes []*trienode.NodeSet - buf = crypto.NewKeccakState() deletes = make(map[common.Hash]*accountDelete) ) for addr, prevObj := range s.stateObjectsDestruct { @@ -1079,7 +1078,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco continue } // The account was existent, it can be either case (c) or (d). - addrHash := crypto.HashData(buf, addr.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) op := &accountDelete{ address: addr, origin: types.SlimAccountRLP(*prev), diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 5b0c9c0533..e620d6ee3a 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -19,6 +19,7 @@ package crypto import ( "bytes" "crypto/ecdsa" + "crypto/rand" "encoding/hex" "math/big" "os" @@ -297,3 +298,38 @@ func TestPythonIntegration(t *testing.T) { t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0) t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1) } + +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/crypto +// cpu: Apple M1 Pro +// BenchmarkKeccak256Hash +// BenchmarkKeccak256Hash-8 931095 1270 ns/op 32 B/op 1 allocs/op +func BenchmarkKeccak256Hash(b *testing.B) { + var input [512]byte + rand.Read(input[:]) + + b.ReportAllocs() + for i := 0; i < b.N; i++ { + Keccak256Hash(input[:]) + } +} + +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/crypto +// cpu: Apple M1 Pro +// BenchmarkHashData +// BenchmarkHashData-8 793386 1278 ns/op 32 B/op 1 allocs/op +func BenchmarkHashData(b *testing.B) { + var ( + input [512]byte + buffer = NewKeccakState() + ) + rand.Read(input[:]) + + b.ReportAllocs() + for i := 0; i < b.N; i++ { + HashData(buffer, input[:]) + } +} diff --git a/triedb/pathdb/execute.go b/triedb/pathdb/execute.go index db1e679277..aa4bd8b44b 100644 --- a/triedb/pathdb/execute.go +++ b/triedb/pathdb/execute.go @@ -86,9 +86,7 @@ func apply(db database.NodeDatabase, prevRoot common.Hash, postRoot common.Hash, func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) error { // The account was present in prev-state, decode it from the // 'slim-rlp' format bytes. - h := crypto.NewKeccakState() - - addrHash := crypto.HashData(h, addr.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) prev, err := types.FullAccount(ctx.accounts[addr]) if err != nil { return err @@ -113,7 +111,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) for key, val := range ctx.storages[addr] { tkey := key if ctx.rawStorageKey { - tkey = crypto.HashData(h, key.Bytes()) + tkey = crypto.Keccak256Hash(key.Bytes()) } var err error if len(val) == 0 { @@ -149,9 +147,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) // account and storage is wiped out correctly. func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) error { // The account must be existent in post-state, load the account. - h := crypto.NewKeccakState() - - addrHash := crypto.HashData(h, addr.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) blob, err := ctx.accountTrie.Get(addrHash.Bytes()) if err != nil { return err @@ -173,7 +169,7 @@ func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) } tkey := key if ctx.rawStorageKey { - tkey = crypto.HashData(h, key.Bytes()) + tkey = crypto.Keccak256Hash(key.Bytes()) } if err := st.Delete(tkey.Bytes()); err != nil { return err diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index aed0296da5..63c9152bf7 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -278,12 +278,11 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map // and the hash of the storage slot key. func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) { var ( - buff = crypto.NewKeccakState() accounts = make(map[common.Hash][]byte) storages = make(map[common.Hash]map[common.Hash][]byte) ) for addr, blob := range h.accounts { - addrHash := crypto.HashData(buff, addr.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) accounts[addrHash] = blob storage, exist := h.storages[addr] @@ -295,7 +294,7 @@ func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common } else { subset := make(map[common.Hash][]byte) for key, slot := range storage { - subset[crypto.HashData(buff, key.Bytes())] = slot + subset[crypto.Keccak256Hash(key.Bytes())] = slot } storages[addrHash] = subset }