core/state: rewrite trie prefetcher to provide witness for snapshot-based execution

This commit is contained in:
Martin Holst Swende 2023-11-28 13:21:11 +01:00
parent 15cc2dfe52
commit 1a5a479c4e
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 11 additions and 7 deletions

View file

@ -4767,6 +4767,7 @@ func testIncrementSlotAcrossManyBlocks(t *testing.T, scheme string) {
// Import the canonical chain // Import the canonical chain
cache := DefaultCacheConfigWithScheme(scheme) cache := DefaultCacheConfigWithScheme(scheme)
cache.SnapshotLimit = 0 // disable snapshot cache.SnapshotLimit = 0 // disable snapshot
cache.SnapshotLimit = 500 // enable snapshot
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), cache, gspec, nil, engine, vm.Config{ chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), cache, gspec, nil, engine, vm.Config{
Tracer: logger.NewJSONLogger(nil, os.Stdout), Tracer: logger.NewJSONLogger(nil, os.Stdout),
}, nil, nil) }, nil, nil)

View file

@ -167,14 +167,13 @@ func (p *triePrefetcher) trie(owner common.Hash, root common.Hash) Trie {
p.deliveryMissMeter.Mark(1) p.deliveryMissMeter.Mark(1)
return nil return nil
} }
// Wait for the fether to finish // Wait for the fetcher to finish
fetcher.wait() // safe to do multiple times fetcher.wait() // safe to do multiple times
if fetcher.trie == nil { if fetcher.trie == nil {
p.deliveryMissMeter.Mark(1) p.deliveryMissMeter.Mark(1)
return nil return nil
} }
trie := fetcher.db.CopyTrie(fetcher.trie) return fetcher.db.CopyTrie(fetcher.trie)
return trie
} }
// used marks a batch of state items used to allow creating statistics as to // used marks a batch of state items used to allow creating statistics as to
@ -207,9 +206,9 @@ type subfetcher struct {
tasks [][]byte // Items queued up for retrieval tasks [][]byte // Items queued up for retrieval
lock sync.Mutex // Lock protecting the task queue lock sync.Mutex // Lock protecting the task queue
closing bool // set to true if the subfetcher is closing
wake chan struct{} // Wake channel if a new task is scheduled wake chan struct{} // Wake channel if a new task is scheduled
stop chan struct{} // Channel to interrupt processing
term chan struct{} // Channel to signal interruption term chan struct{} // Channel to signal interruption
seen map[string]struct{} // Tracks the entries already loaded seen map[string]struct{} // Tracks the entries already loaded
@ -249,6 +248,10 @@ func (sf *subfetcher) schedule(keys [][]byte) {
func (sf *subfetcher) wait() { func (sf *subfetcher) wait() {
// Signal termination by nil tasks // Signal termination by nil tasks
sf.lock.Lock() sf.lock.Lock()
if sf.closing {
return // already exiting
}
sf.closing = true
sf.tasks = nil sf.tasks = nil
sf.lock.Unlock() sf.lock.Unlock()
// Notify the prefetcher. The wake-chan is buffered, so this is async. // Notify the prefetcher. The wake-chan is buffered, so this is async.