mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +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
|
||||
err error
|
||||
)
|
||||
if !db.IsVerkle() {
|
||||
if !db.IsVerkle() && (ts == nil || !ts.InTransition()) {
|
||||
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
||||
} else {
|
||||
// When IsVerkle() is true, create a BinaryTrie wrapped in TransitionTrie
|
||||
binTrie, binErr := bintrie.NewBinaryTrie(root, db)
|
||||
var binTrie *bintrie.BinaryTrie
|
||||
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 {
|
||||
return nil, binErr
|
||||
}
|
||||
|
||||
// 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.
|
||||
if ts.InTransition() {
|
||||
mpt, err := trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), db)
|
||||
|
|
|
|||
|
|
@ -147,6 +147,9 @@ func (s *stateObject) getTrie() (Trie, error) {
|
|||
func (s *stateObject) getPrefetchedTrie() Trie {
|
||||
// If there's nothing to meaningfully return, let the user figure it out by
|
||||
// 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 {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -356,6 +356,10 @@ func (s *StateDB) InTransition() bool {
|
|||
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.
|
||||
func (s *StateDB) TxIndex() int {
|
||||
return s.txIndex
|
||||
|
|
@ -830,7 +834,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
|||
start = time.Now()
|
||||
workers errgroup.Group
|
||||
)
|
||||
if s.db.TrieDB().IsVerkle() {
|
||||
if s.isVerkle() {
|
||||
// Whilst MPT storage tries are independent, Verkle has one single trie
|
||||
// for all the accounts and all the storage slots merged together. The
|
||||
// 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
|
||||
workers.Go(func() error {
|
||||
if s.db.TrieDB().IsVerkle() {
|
||||
if s.isVerkle() {
|
||||
obj.updateTrie()
|
||||
} else {
|
||||
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.
|
||||
// Skip witness collection in Verkle mode, they will be gathered
|
||||
// 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
|
||||
for _, obj := range s.stateObjectsDestruct {
|
||||
// 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
|
||||
// here could result in losing uncommitted changes from storage.
|
||||
start = time.Now()
|
||||
if s.prefetcher != nil {
|
||||
if s.prefetcher != nil && !s.isVerkle() {
|
||||
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil {
|
||||
log.Error("Failed to retrieve account pre-fetcher trie")
|
||||
} else {
|
||||
|
|
@ -1137,7 +1141,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco
|
|||
deletes[addrHash] = op
|
||||
|
||||
// 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
|
||||
}
|
||||
if noStorageWiping {
|
||||
|
|
|
|||
Loading…
Reference in a new issue