mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-20 23:09:27 +00:00
fix prefetcher issue + reader bootstrap and get rid of triedb.IsVerkle() checks (#564)
- Fix an issue in which the prefetcher was creating a new MPT tree in verkle mode, based on the fact that triedb.IsVerkle() was false. - Also fix the tree bootstrapping in the reader - generally, no longer use db.triedb.IsVerkle() as it's only true if the db is used when starting in verkle mode.
This commit is contained in:
parent
8cc4463bbd
commit
14839c9113
3 changed files with 21 additions and 9 deletions
|
|
@ -318,17 +318,22 @@ func newTrieReader(root common.Hash, db *triedb.Database, ts *overlay.Transition
|
||||||
tr Trie
|
tr Trie
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if !db.IsVerkle() {
|
if !db.IsVerkle() && (ts == nil || !ts.InTransition()) {
|
||||||
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
||||||
} else {
|
} else {
|
||||||
// When IsVerkle() is true, create a BinaryTrie wrapped in TransitionTrie
|
var binTrie *bintrie.BinaryTrie
|
||||||
binTrie, binErr := bintrie.NewBinaryTrie(root, db)
|
var binErr error
|
||||||
|
if ts.BaseRoot == (common.Hash{}) {
|
||||||
|
binTrie, binErr = bintrie.NewBinaryTrie(common.Hash{}, db)
|
||||||
|
} else {
|
||||||
|
binTrie, binErr = bintrie.NewBinaryTrie(root, db)
|
||||||
|
}
|
||||||
if binErr != nil {
|
if binErr != nil {
|
||||||
return nil, binErr
|
return nil, binErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on the transition status, determine if the overlay
|
// Based on the transition status, determine if the overlay
|
||||||
// tree needs to be created, or if a single, target tree is
|
// tree needs to be created, or if a single target tree is
|
||||||
// to be picked.
|
// to be picked.
|
||||||
if ts.InTransition() {
|
if ts.InTransition() {
|
||||||
mpt, err := trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), db)
|
mpt, err := trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), db)
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,9 @@ func (s *stateObject) getTrie() (Trie, error) {
|
||||||
func (s *stateObject) getPrefetchedTrie() Trie {
|
func (s *stateObject) getPrefetchedTrie() Trie {
|
||||||
// If there's nothing to meaningfully return, let the user figure it out by
|
// If there's nothing to meaningfully return, let the user figure it out by
|
||||||
// pulling the trie from disk.
|
// pulling the trie from disk.
|
||||||
|
if s.db.trie != nil && s.db.trie.IsVerkle() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsVerkle()) || s.db.prefetcher == nil {
|
if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsVerkle()) || s.db.prefetcher == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -356,6 +356,10 @@ func (s *StateDB) InTransition() bool {
|
||||||
return completeValue != (common.Hash{})
|
return completeValue != (common.Hash{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StateDB) isVerkle() bool {
|
||||||
|
return s.db.TrieDB().IsVerkle() || (s.trie != nil && s.trie.IsVerkle())
|
||||||
|
}
|
||||||
|
|
||||||
// TxIndex returns the current transaction index set by SetTxContext.
|
// TxIndex returns the current transaction index set by SetTxContext.
|
||||||
func (s *StateDB) TxIndex() int {
|
func (s *StateDB) TxIndex() int {
|
||||||
return s.txIndex
|
return s.txIndex
|
||||||
|
|
@ -830,7 +834,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
workers errgroup.Group
|
workers errgroup.Group
|
||||||
)
|
)
|
||||||
if s.db.TrieDB().IsVerkle() {
|
if s.isVerkle() {
|
||||||
// Whilst MPT storage tries are independent, Verkle has one single trie
|
// Whilst MPT storage tries are independent, Verkle has one single trie
|
||||||
// for all the accounts and all the storage slots merged together. The
|
// for all the accounts and all the storage slots merged together. The
|
||||||
// former can thus be simply parallelized, but updating the latter will
|
// former can thus be simply parallelized, but updating the latter will
|
||||||
|
|
@ -844,7 +848,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
}
|
}
|
||||||
obj := s.stateObjects[addr] // closure for the task runner below
|
obj := s.stateObjects[addr] // closure for the task runner below
|
||||||
workers.Go(func() error {
|
workers.Go(func() error {
|
||||||
if s.db.TrieDB().IsVerkle() {
|
if s.isVerkle() {
|
||||||
obj.updateTrie()
|
obj.updateTrie()
|
||||||
} else {
|
} else {
|
||||||
obj.updateRoot()
|
obj.updateRoot()
|
||||||
|
|
@ -861,7 +865,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
// If witness building is enabled, gather all the read-only accesses.
|
// If witness building is enabled, gather all the read-only accesses.
|
||||||
// Skip witness collection in Verkle mode, they will be gathered
|
// Skip witness collection in Verkle mode, they will be gathered
|
||||||
// together at the end.
|
// together at the end.
|
||||||
if s.witness != nil && !s.db.TrieDB().IsVerkle() {
|
if s.witness != nil && !s.isVerkle() {
|
||||||
// Pull in anything that has been accessed before destruction
|
// Pull in anything that has been accessed before destruction
|
||||||
for _, obj := range s.stateObjectsDestruct {
|
for _, obj := range s.stateObjectsDestruct {
|
||||||
// Skip any objects that haven't touched their storage
|
// Skip any objects that haven't touched their storage
|
||||||
|
|
@ -918,7 +922,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
// only a single trie is used for state hashing. Replacing a non-nil verkle tree
|
// only a single trie is used for state hashing. Replacing a non-nil verkle tree
|
||||||
// here could result in losing uncommitted changes from storage.
|
// here could result in losing uncommitted changes from storage.
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
if s.prefetcher != nil {
|
if s.prefetcher != nil && !s.isVerkle() {
|
||||||
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil {
|
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil {
|
||||||
log.Error("Failed to retrieve account pre-fetcher trie")
|
log.Error("Failed to retrieve account pre-fetcher trie")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1137,7 +1141,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco
|
||||||
deletes[addrHash] = op
|
deletes[addrHash] = op
|
||||||
|
|
||||||
// Short circuit if the origin storage was empty.
|
// Short circuit if the origin storage was empty.
|
||||||
if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsVerkle() {
|
if prev.Root == types.EmptyRootHash || s.isVerkle() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if noStorageWiping {
|
if noStorageWiping {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue