mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/state: make statedb/stateobjects reuse a hasher
This commit is contained in:
parent
31e89911b1
commit
3f4bc341c5
4 changed files with 37 additions and 4 deletions
|
|
@ -325,6 +325,7 @@ func (s *stateObject) updateTrie(db Database) Trie {
|
|||
var storage map[common.Hash][]byte
|
||||
// Insert all the pending updates into the trie
|
||||
tr := s.getTrie(db)
|
||||
hasher := s.db.hasher
|
||||
for key, value := range s.pendingStorage {
|
||||
// Skip noop changes, persist actual changes
|
||||
if value == s.originStorage[key] {
|
||||
|
|
@ -349,7 +350,7 @@ func (s *stateObject) updateTrie(db Database) Trie {
|
|||
s.db.snapStorage[s.addrHash] = storage
|
||||
}
|
||||
}
|
||||
storage[crypto.Keccak256Hash(key[:])] = v // v will be nil if value is 0x00
|
||||
storage[crypto.HashData(hasher, key[:])] = v // v will be nil if value is 0x00
|
||||
}
|
||||
}
|
||||
if len(s.pendingStorage) > 0 {
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ func (n *proofList) Delete(key []byte) error {
|
|||
// * Contracts
|
||||
// * Accounts
|
||||
type StateDB struct {
|
||||
db Database
|
||||
trie Trie
|
||||
db Database
|
||||
trie Trie
|
||||
hasher crypto.KeccakHasher
|
||||
|
||||
snaps *snapshot.Tree
|
||||
snap snapshot.Snapshot
|
||||
|
|
@ -131,6 +132,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
|
|||
logs: make(map[common.Hash][]*types.Log),
|
||||
preimages: make(map[common.Hash][]byte),
|
||||
journal: newJournal(),
|
||||
hasher: crypto.NewKeccakHasher(),
|
||||
}
|
||||
if sdb.snaps != nil {
|
||||
if sdb.snap = sdb.snaps.Snapshot(root); sdb.snap != nil {
|
||||
|
|
@ -516,7 +518,7 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
|||
defer func(start time.Time) { s.SnapshotAccountReads += time.Since(start) }(time.Now())
|
||||
}
|
||||
var acc *snapshot.Account
|
||||
if acc, err = s.snap.Account(crypto.Keccak256Hash(addr[:])); err == nil {
|
||||
if acc, err = s.snap.Account(crypto.HashData(s.hasher, addr[:])); err == nil {
|
||||
if acc == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -648,6 +650,7 @@ func (s *StateDB) Copy() *StateDB {
|
|||
logSize: s.logSize,
|
||||
preimages: make(map[common.Hash][]byte, len(s.preimages)),
|
||||
journal: newJournal(),
|
||||
hasher: crypto.NewKeccakHasher(),
|
||||
}
|
||||
// Copy the dirty states, logs, and preimages
|
||||
for addr := range s.journal.dirties {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
|
|
@ -51,6 +52,27 @@ var (
|
|||
|
||||
var errInvalidPubkey = errors.New("invalid secp256k1 public key")
|
||||
|
||||
// KeccakHasher wraps sha3.state. In addition to the usual hash methods, it also supports
|
||||
// Read to get a variable amount of data from the hash state. Read is faster than Sum
|
||||
// because it doesn't copy the internal state, but also modifies the internal state.
|
||||
type KeccakHasher interface {
|
||||
hash.Hash
|
||||
Read([]byte) (int, error)
|
||||
}
|
||||
|
||||
func NewKeccakHasher() KeccakHasher {
|
||||
return sha3.NewLegacyKeccak256().(KeccakHasher)
|
||||
}
|
||||
|
||||
// hashData hashes the provided data and returns a 32 byte hash
|
||||
// This method is not threadsafe
|
||||
func HashData(kh KeccakHasher, data []byte) (h common.Hash) {
|
||||
kh.Reset()
|
||||
kh.Write(data)
|
||||
kh.Read(h[:])
|
||||
return h
|
||||
}
|
||||
|
||||
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
||||
func Keccak256(data ...[]byte) []byte {
|
||||
d := sha3.NewLegacyKeccak256()
|
||||
|
|
|
|||
|
|
@ -42,6 +42,13 @@ func TestKeccak256Hash(t *testing.T) {
|
|||
checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
|
||||
}
|
||||
|
||||
func TestKeccak256Hasher(t *testing.T) {
|
||||
msg := []byte("abc")
|
||||
exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
|
||||
hasher := NewKeccakHasher()
|
||||
checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := HashData(hasher, in); return h[:] }, msg, exp)
|
||||
}
|
||||
|
||||
func TestToECDSAErrors(t *testing.T) {
|
||||
if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
|
||||
t.Fatal("HexToECDSA should've returned error")
|
||||
|
|
|
|||
Loading…
Reference in a new issue