mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 01:41:36 +00:00
core/state: fix typed nil panic in StopPrefetcher
commitAndFlush discarded errors from db.Reader() and db.Hasher() at
lines 1040-1041, storing the result directly into s.reader/s.hasher.
When Hasher() fails (e.g. newBinaryHasher returns nil, err), Go wraps
the nil *binaryHasher in the Hasher interface as a typed nil — an
interface value {type: *binaryHasher, value: nil} that passes == nil
checks. StopPrefetcher then type-asserts to Prefetcher (succeeds) and
calls TermPrefetch on the nil receiver, panicking at h.trie.term().
Fix: propagate errors from Reader() and Hasher() in commitAndFlush
instead of discarding them, and add defensive nil-receiver guards to
both binaryHasher.TermPrefetch and merkleHasher.TermPrefetch.
This commit is contained in:
parent
b4caa05448
commit
5850970e57
3 changed files with 18 additions and 2 deletions
|
|
@ -387,5 +387,8 @@ func (h *binaryHasher) PrefetchStorage(addr common.Address, keys []common.Hash,
|
|||
|
||||
// TermPrefetch terminates all prefetcher goroutines. Safe to call multiple times.
|
||||
func (h *binaryHasher) TermPrefetch() {
|
||||
if h == nil {
|
||||
return
|
||||
}
|
||||
h.trie.term()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -457,6 +457,9 @@ func (h *merkleHasher) PrefetchStorage(addr common.Address, keys []common.Hash,
|
|||
|
||||
// TermPrefetch terminates all prefetcher goroutines. Safe to call multiple times.
|
||||
func (h *merkleHasher) TermPrefetch() {
|
||||
if h == nil {
|
||||
return
|
||||
}
|
||||
h.acctTrie.term()
|
||||
for _, tr := range h.storageTries {
|
||||
tr.term()
|
||||
|
|
|
|||
|
|
@ -1040,8 +1040,18 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorag
|
|||
}
|
||||
s.DatabaseCommits = time.Since(start)
|
||||
|
||||
s.reader, _ = s.db.Reader(s.originalRoot)
|
||||
s.hasher, _ = s.db.Hasher(s.originalRoot)
|
||||
reader, err := s.db.Reader(s.originalRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.reader = reader
|
||||
|
||||
hasher, err := s.db.Hasher(s.originalRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.hasher = hasher
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue