forked from forks/go-ethereum
all: create global hasher pool (#31769)
This PR creates a global hasher pool that can be used by all packages. It also removes a bunch of the package local pools. It also updates a few locations to use available hashers or the global hashing pool to reduce allocations all over the codebase. This change should reduce global allocation count by ~1% --------- Co-authored-by: Gary Rong <garyrong0905@gmail.com>
This commit is contained in:
parent
485ff4bbff
commit
0eb2eeea90
11 changed files with 34 additions and 121 deletions
|
|
@ -18,7 +18,6 @@ package rawdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
@ -45,25 +44,6 @@ const HashScheme = "hash"
|
||||||
// on extra state diffs to survive deep reorg.
|
// on extra state diffs to survive deep reorg.
|
||||||
const PathScheme = "path"
|
const PathScheme = "path"
|
||||||
|
|
||||||
// hasher is used to compute the sha256 hash of the provided data.
|
|
||||||
type hasher struct{ sha crypto.KeccakState }
|
|
||||||
|
|
||||||
var hasherPool = sync.Pool{
|
|
||||||
New: func() interface{} { return &hasher{sha: crypto.NewKeccakState()} },
|
|
||||||
}
|
|
||||||
|
|
||||||
func newHasher() *hasher {
|
|
||||||
return hasherPool.Get().(*hasher)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *hasher) hash(data []byte) common.Hash {
|
|
||||||
return crypto.HashData(h.sha, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *hasher) release() {
|
|
||||||
hasherPool.Put(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadAccountTrieNode retrieves the account trie node with the specified node path.
|
// ReadAccountTrieNode retrieves the account trie node with the specified node path.
|
||||||
func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) []byte {
|
func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) []byte {
|
||||||
data, _ := db.Get(accountTrieNodeKey(path))
|
data, _ := db.Get(accountTrieNodeKey(path))
|
||||||
|
|
@ -170,9 +150,7 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c
|
||||||
if len(blob) == 0 {
|
if len(blob) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
h := newHasher()
|
return crypto.Keccak256Hash(blob) == hash // exists but not match
|
||||||
defer h.release()
|
|
||||||
return h.hash(blob) == hash // exists but not match
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("Unknown scheme %v", scheme))
|
panic(fmt.Sprintf("Unknown scheme %v", scheme))
|
||||||
}
|
}
|
||||||
|
|
@ -194,9 +172,7 @@ func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash
|
||||||
if len(blob) == 0 {
|
if len(blob) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
h := newHasher()
|
if crypto.Keccak256Hash(blob) != hash {
|
||||||
defer h.release()
|
|
||||||
if h.hash(blob) != hash {
|
|
||||||
return nil // exists but not match
|
return nil // exists but not match
|
||||||
}
|
}
|
||||||
return blob
|
return blob
|
||||||
|
|
|
||||||
|
|
@ -33,24 +33,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/triedb/database"
|
"github.com/ethereum/go-ethereum/triedb/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
// bufferPool holds the buffers for keccak calculation.
|
|
||||||
var bufferPool = sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return crypto.NewKeccakState()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocBuff allocates the keccak buffer from the pool
|
|
||||||
func allocBuff() crypto.KeccakState {
|
|
||||||
return bufferPool.Get().(crypto.KeccakState)
|
|
||||||
}
|
|
||||||
|
|
||||||
// releaseBuff returns the provided keccak buffer to the pool. It's unnecessary
|
|
||||||
// to clear the buffer, as it will be cleared before the calculation.
|
|
||||||
func releaseBuff(buff crypto.KeccakState) {
|
|
||||||
bufferPool.Put(buff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContractCodeReader defines the interface for accessing contract code.
|
// ContractCodeReader defines the interface for accessing contract code.
|
||||||
type ContractCodeReader interface {
|
type ContractCodeReader interface {
|
||||||
// Code retrieves a particular contract's code.
|
// Code retrieves a particular contract's code.
|
||||||
|
|
@ -167,10 +149,7 @@ func newFlatReader(reader database.StateReader) *flatReader {
|
||||||
//
|
//
|
||||||
// The returned account might be nil if it's not existent.
|
// The returned account might be nil if it's not existent.
|
||||||
func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) {
|
func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) {
|
||||||
buff := allocBuff()
|
account, err := r.reader.Account(crypto.Keccak256Hash(addr.Bytes()))
|
||||||
defer releaseBuff(buff)
|
|
||||||
|
|
||||||
account, err := r.reader.Account(crypto.HashData(buff, addr.Bytes()))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -200,11 +179,8 @@ func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) {
|
||||||
//
|
//
|
||||||
// The returned storage slot might be empty if it's not existent.
|
// The returned storage slot might be empty if it's not existent.
|
||||||
func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) {
|
func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) {
|
||||||
buff := allocBuff()
|
addrHash := crypto.Keccak256Hash(addr.Bytes())
|
||||||
defer releaseBuff(buff)
|
slotHash := crypto.Keccak256Hash(key.Bytes())
|
||||||
|
|
||||||
addrHash := crypto.HashData(buff, addr.Bytes())
|
|
||||||
slotHash := crypto.HashData(buff, key.Bytes())
|
|
||||||
ret, err := r.reader.Storage(addrHash, slotHash)
|
ret, err := r.reader.Storage(addrHash, slotHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// hasherPool holds LegacyKeccak256 hashers for rlpHash.
|
// hasherPool holds LegacyKeccak256 hashers for rlpHash.
|
||||||
var hasherPool = sync.Pool{
|
var hasherPool = sync.Pool{
|
||||||
New: func() interface{} { return sha3.NewLegacyKeccak256() },
|
New: func() interface{} { return crypto.NewKeccakState() },
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding.
|
// encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding.
|
||||||
|
|
|
||||||
|
|
@ -555,7 +555,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:]
|
// 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.
|
// 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) {
|
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) {
|
||||||
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), crypto.Keccak256(code))
|
inithash := crypto.HashData(evm.interpreter.hasher, code)
|
||||||
|
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:])
|
||||||
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2)
|
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
@ -234,11 +233,7 @@ func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
|
||||||
offset, size := scope.Stack.pop(), scope.Stack.peek()
|
offset, size := scope.Stack.pop(), scope.Stack.peek()
|
||||||
data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
|
data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
|
||||||
|
|
||||||
if interpreter.hasher == nil {
|
interpreter.hasher.Reset()
|
||||||
interpreter.hasher = crypto.NewKeccakState()
|
|
||||||
} else {
|
|
||||||
interpreter.hasher.Reset()
|
|
||||||
}
|
|
||||||
interpreter.hasher.Write(data)
|
interpreter.hasher.Write(data)
|
||||||
interpreter.hasher.Read(interpreter.hasherBuf[:])
|
interpreter.hasher.Read(interpreter.hasherBuf[:])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
evm.Config.ExtraEips = extraEips
|
evm.Config.ExtraEips = extraEips
|
||||||
return &EVMInterpreter{evm: evm, table: table}
|
return &EVMInterpreter{evm: evm, table: table, hasher: crypto.NewKeccakState()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run loops and evaluates the contract's code with the given input data and returns
|
// Run loops and evaluates the contract's code with the given input data and returns
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
|
|
@ -73,6 +74,12 @@ func NewKeccakState() KeccakState {
|
||||||
return sha3.NewLegacyKeccak256().(KeccakState)
|
return sha3.NewLegacyKeccak256().(KeccakState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasherPool = sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
return sha3.NewLegacyKeccak256().(KeccakState)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// HashData hashes the provided data using the KeccakState and returns a 32 byte hash
|
// HashData hashes the provided data using the KeccakState and returns a 32 byte hash
|
||||||
func HashData(kh KeccakState, data []byte) (h common.Hash) {
|
func HashData(kh KeccakState, data []byte) (h common.Hash) {
|
||||||
kh.Reset()
|
kh.Reset()
|
||||||
|
|
@ -84,22 +91,26 @@ func HashData(kh KeccakState, data []byte) (h common.Hash) {
|
||||||
// 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 {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
d := NewKeccakState()
|
d := hasherPool.Get().(KeccakState)
|
||||||
|
d.Reset()
|
||||||
for _, b := range data {
|
for _, b := range data {
|
||||||
d.Write(b)
|
d.Write(b)
|
||||||
}
|
}
|
||||||
d.Read(b)
|
d.Read(b)
|
||||||
|
hasherPool.Put(d)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
|
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
|
||||||
// converting it to an internal Hash data structure.
|
// converting it to an internal Hash data structure.
|
||||||
func Keccak256Hash(data ...[]byte) (h common.Hash) {
|
func Keccak256Hash(data ...[]byte) (h common.Hash) {
|
||||||
d := NewKeccakState()
|
d := hasherPool.Get().(KeccakState)
|
||||||
|
d.Reset()
|
||||||
for _, b := range data {
|
for _, b := range data {
|
||||||
d.Write(b)
|
d.Write(b)
|
||||||
}
|
}
|
||||||
d.Read(h[:])
|
d.Read(h[:])
|
||||||
|
hasherPool.Put(d)
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type hasher struct {
|
||||||
|
|
||||||
// hasherPool holds pureHashers
|
// hasherPool holds pureHashers
|
||||||
var hasherPool = sync.Pool{
|
var hasherPool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() any {
|
||||||
return &hasher{
|
return &hasher{
|
||||||
tmp: make([]byte, 0, 550), // cap is as large as a full fullNode.
|
tmp: make([]byte, 0, 550), // cap is as large as a full fullNode.
|
||||||
sha: crypto.NewKeccakState(),
|
sha: crypto.NewKeccakState(),
|
||||||
|
|
|
||||||
24
trie/sync.go
24
trie/sync.go
|
|
@ -729,9 +729,7 @@ func (s *Sync) hasNode(owner common.Hash, path []byte, hash common.Hash) (exists
|
||||||
} else {
|
} else {
|
||||||
blob = rawdb.ReadStorageTrieNode(s.database, owner, path)
|
blob = rawdb.ReadStorageTrieNode(s.database, owner, path)
|
||||||
}
|
}
|
||||||
h := newBlobHasher()
|
exists = hash == crypto.Keccak256Hash(blob)
|
||||||
defer h.release()
|
|
||||||
exists = hash == h.hash(blob)
|
|
||||||
inconsistent = !exists && len(blob) != 0
|
inconsistent = !exists && len(blob) != 0
|
||||||
return exists, inconsistent
|
return exists, inconsistent
|
||||||
}
|
}
|
||||||
|
|
@ -746,23 +744,3 @@ func ResolvePath(path []byte) (common.Hash, []byte) {
|
||||||
}
|
}
|
||||||
return owner, path
|
return owner, path
|
||||||
}
|
}
|
||||||
|
|
||||||
// blobHasher is used to compute the sha256 hash of the provided data.
|
|
||||||
type blobHasher struct{ state crypto.KeccakState }
|
|
||||||
|
|
||||||
// blobHasherPool is the pool for reusing pre-allocated hash state.
|
|
||||||
var blobHasherPool = sync.Pool{
|
|
||||||
New: func() interface{} { return &blobHasher{state: crypto.NewKeccakState()} },
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBlobHasher() *blobHasher {
|
|
||||||
return blobHasherPool.Get().(*blobHasher)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *blobHasher) hash(data []byte) common.Hash {
|
|
||||||
return crypto.HashData(h.state, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *blobHasher) release() {
|
|
||||||
blobHasherPool.Put(h)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -115,15 +115,12 @@ func (dl *diskLayer) node(owner common.Hash, path []byte, depth int) ([]byte, co
|
||||||
dirtyNodeMissMeter.Mark(1)
|
dirtyNodeMissMeter.Mark(1)
|
||||||
|
|
||||||
// Try to retrieve the trie node from the clean memory cache
|
// Try to retrieve the trie node from the clean memory cache
|
||||||
h := newHasher()
|
|
||||||
defer h.release()
|
|
||||||
|
|
||||||
key := nodeCacheKey(owner, path)
|
key := nodeCacheKey(owner, path)
|
||||||
if dl.nodes != nil {
|
if dl.nodes != nil {
|
||||||
if blob := dl.nodes.Get(nil, key); len(blob) > 0 {
|
if blob := dl.nodes.Get(nil, key); len(blob) > 0 {
|
||||||
cleanNodeHitMeter.Mark(1)
|
cleanNodeHitMeter.Mark(1)
|
||||||
cleanNodeReadMeter.Mark(int64(len(blob)))
|
cleanNodeReadMeter.Mark(int64(len(blob)))
|
||||||
return blob, h.hash(blob), &nodeLoc{loc: locCleanCache, depth: depth}, nil
|
return blob, crypto.Keccak256Hash(blob), &nodeLoc{loc: locCleanCache, depth: depth}, nil
|
||||||
}
|
}
|
||||||
cleanNodeMissMeter.Mark(1)
|
cleanNodeMissMeter.Mark(1)
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +135,7 @@ func (dl *diskLayer) node(owner common.Hash, path []byte, depth int) ([]byte, co
|
||||||
dl.nodes.Set(key, blob)
|
dl.nodes.Set(key, blob)
|
||||||
cleanNodeWriteMeter.Mark(int64(len(blob)))
|
cleanNodeWriteMeter.Mark(int64(len(blob)))
|
||||||
}
|
}
|
||||||
return blob, h.hash(blob), &nodeLoc{loc: locDiskLayer, depth: depth}, nil
|
return blob, crypto.Keccak256Hash(blob), &nodeLoc{loc: locDiskLayer, depth: depth}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// account directly retrieves the account RLP associated with a particular
|
// account directly retrieves the account RLP associated with a particular
|
||||||
|
|
@ -359,22 +356,3 @@ func (dl *diskLayer) resetCache() {
|
||||||
dl.nodes.Reset()
|
dl.nodes.Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasher is used to compute the sha256 hash of the provided data.
|
|
||||||
type hasher struct{ sha crypto.KeccakState }
|
|
||||||
|
|
||||||
var hasherPool = sync.Pool{
|
|
||||||
New: func() interface{} { return &hasher{sha: crypto.NewKeccakState()} },
|
|
||||||
}
|
|
||||||
|
|
||||||
func newHasher() *hasher {
|
|
||||||
return hasherPool.Get().(*hasher)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *hasher) hash(data []byte) common.Hash {
|
|
||||||
return crypto.HashData(h.sha, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *hasher) release() {
|
|
||||||
hasherPool.Put(h)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
|
|
@ -85,10 +86,9 @@ func apply(db database.NodeDatabase, prevRoot common.Hash, postRoot common.Hash,
|
||||||
func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) error {
|
func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) error {
|
||||||
// The account was present in prev-state, decode it from the
|
// The account was present in prev-state, decode it from the
|
||||||
// 'slim-rlp' format bytes.
|
// 'slim-rlp' format bytes.
|
||||||
h := newHasher()
|
h := crypto.NewKeccakState()
|
||||||
defer h.release()
|
|
||||||
|
|
||||||
addrHash := h.hash(addr.Bytes())
|
addrHash := crypto.HashData(h, addr.Bytes())
|
||||||
prev, err := types.FullAccount(ctx.accounts[addr])
|
prev, err := types.FullAccount(ctx.accounts[addr])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -113,7 +113,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address)
|
||||||
for key, val := range ctx.storages[addr] {
|
for key, val := range ctx.storages[addr] {
|
||||||
tkey := key
|
tkey := key
|
||||||
if ctx.rawStorageKey {
|
if ctx.rawStorageKey {
|
||||||
tkey = h.hash(key.Bytes())
|
tkey = crypto.HashData(h, key.Bytes())
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
if len(val) == 0 {
|
if len(val) == 0 {
|
||||||
|
|
@ -149,10 +149,9 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address)
|
||||||
// account and storage is wiped out correctly.
|
// account and storage is wiped out correctly.
|
||||||
func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) error {
|
func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) error {
|
||||||
// The account must be existent in post-state, load the account.
|
// The account must be existent in post-state, load the account.
|
||||||
h := newHasher()
|
h := crypto.NewKeccakState()
|
||||||
defer h.release()
|
|
||||||
|
|
||||||
addrHash := h.hash(addr.Bytes())
|
addrHash := crypto.HashData(h, addr.Bytes())
|
||||||
blob, err := ctx.accountTrie.Get(addrHash.Bytes())
|
blob, err := ctx.accountTrie.Get(addrHash.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -174,7 +173,7 @@ func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address)
|
||||||
}
|
}
|
||||||
tkey := key
|
tkey := key
|
||||||
if ctx.rawStorageKey {
|
if ctx.rawStorageKey {
|
||||||
tkey = h.hash(key.Bytes())
|
tkey = crypto.HashData(h, key.Bytes())
|
||||||
}
|
}
|
||||||
if err := st.Delete(tkey.Bytes()); err != nil {
|
if err := st.Delete(tkey.Bytes()); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue