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
|
var storage map[common.Hash][]byte
|
||||||
// Insert all the pending updates into the trie
|
// Insert all the pending updates into the trie
|
||||||
tr := s.getTrie(db)
|
tr := s.getTrie(db)
|
||||||
|
hasher := s.db.hasher
|
||||||
for key, value := range s.pendingStorage {
|
for key, value := range s.pendingStorage {
|
||||||
// Skip noop changes, persist actual changes
|
// Skip noop changes, persist actual changes
|
||||||
if value == s.originStorage[key] {
|
if value == s.originStorage[key] {
|
||||||
|
|
@ -349,7 +350,7 @@ func (s *stateObject) updateTrie(db Database) Trie {
|
||||||
s.db.snapStorage[s.addrHash] = storage
|
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 {
|
if len(s.pendingStorage) > 0 {
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,9 @@ func (n *proofList) Delete(key []byte) error {
|
||||||
// * Contracts
|
// * Contracts
|
||||||
// * Accounts
|
// * Accounts
|
||||||
type StateDB struct {
|
type StateDB struct {
|
||||||
db Database
|
db Database
|
||||||
trie Trie
|
trie Trie
|
||||||
|
hasher crypto.KeccakHasher
|
||||||
|
|
||||||
snaps *snapshot.Tree
|
snaps *snapshot.Tree
|
||||||
snap snapshot.Snapshot
|
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),
|
logs: make(map[common.Hash][]*types.Log),
|
||||||
preimages: make(map[common.Hash][]byte),
|
preimages: make(map[common.Hash][]byte),
|
||||||
journal: newJournal(),
|
journal: newJournal(),
|
||||||
|
hasher: crypto.NewKeccakHasher(),
|
||||||
}
|
}
|
||||||
if sdb.snaps != nil {
|
if sdb.snaps != nil {
|
||||||
if sdb.snap = sdb.snaps.Snapshot(root); sdb.snap != 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())
|
defer func(start time.Time) { s.SnapshotAccountReads += time.Since(start) }(time.Now())
|
||||||
}
|
}
|
||||||
var acc *snapshot.Account
|
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 {
|
if acc == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -648,6 +650,7 @@ func (s *StateDB) Copy() *StateDB {
|
||||||
logSize: s.logSize,
|
logSize: s.logSize,
|
||||||
preimages: make(map[common.Hash][]byte, len(s.preimages)),
|
preimages: make(map[common.Hash][]byte, len(s.preimages)),
|
||||||
journal: newJournal(),
|
journal: newJournal(),
|
||||||
|
hasher: crypto.NewKeccakHasher(),
|
||||||
}
|
}
|
||||||
// Copy the dirty states, logs, and preimages
|
// Copy the dirty states, logs, and preimages
|
||||||
for addr := range s.journal.dirties {
|
for addr := range s.journal.dirties {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -51,6 +52,27 @@ var (
|
||||||
|
|
||||||
var errInvalidPubkey = errors.New("invalid secp256k1 public key")
|
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.
|
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
||||||
func Keccak256(data ...[]byte) []byte {
|
func Keccak256(data ...[]byte) []byte {
|
||||||
d := sha3.NewLegacyKeccak256()
|
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)
|
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) {
|
func TestToECDSAErrors(t *testing.T) {
|
||||||
if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
|
if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
|
||||||
t.Fatal("HexToECDSA should've returned error")
|
t.Fatal("HexToECDSA should've returned error")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue