Skip to content

Commit e0381a9

Browse files
darioushqdm12ARR4N
authored
refactor trie_prefetcher to be similar to upstream structurally (#1395)
Co-authored-by: Quentin McGaw <[email protected]> Co-authored-by: Arran Schlosberg <[email protected]>
1 parent a99bc80 commit e0381a9

10 files changed

+590
-420
lines changed

RELEASES.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
## Pending Release
44

5-
## Updates
5+
* Refactored trie_prefetcher.go to be structurally similar to upstream.
6+
7+
## [v0.7.0](https://github.com/ava-labs/subnet-evm/releases/tag/v0.7.0)
8+
9+
### Updates
610

711
- Changed default write option from `Sync` to `NoSync` in PebbleDB
812

9-
## Fixes
13+
### Fixes
1014

1115
- Fixed database close on shutdown
1216

core/blockchain.go

+4-16
Original file line numberDiff line numberDiff line change
@@ -1349,16 +1349,6 @@ func (bc *BlockChain) insertBlock(block *types.Block, writes bool) error {
13491349
blockContentValidationTimer.Inc(time.Since(substart).Milliseconds())
13501350

13511351
// No validation errors for the block
1352-
var activeState *state.StateDB
1353-
defer func() {
1354-
// The chain importer is starting and stopping trie prefetchers. If a bad
1355-
// block or other error is hit however, an early return may not properly
1356-
// terminate the background threads. This defer ensures that we clean up
1357-
// and dangling prefetcher, without deferring each and holding on live refs.
1358-
if activeState != nil {
1359-
activeState.StopPrefetcher()
1360-
}
1361-
}()
13621352

13631353
// Retrieve the parent block to determine which root to build state on
13641354
substart = time.Now()
@@ -1377,8 +1367,8 @@ func (bc *BlockChain) insertBlock(block *types.Block, writes bool) error {
13771367
blockStateInitTimer.Inc(time.Since(substart).Milliseconds())
13781368

13791369
// Enable prefetching to pull in trie node paths while processing transactions
1380-
statedb.StartPrefetcher("chain", bc.cacheConfig.TriePrefetcherParallelism)
1381-
activeState = statedb
1370+
statedb.StartPrefetcher("chain", state.WithConcurrentWorkers(bc.cacheConfig.TriePrefetcherParallelism))
1371+
defer statedb.StopPrefetcher()
13821372

13831373
// Process block using the parent state as reference point
13841374
pstart := time.Now()
@@ -1736,10 +1726,8 @@ func (bc *BlockChain) reprocessBlock(parent *types.Block, current *types.Block)
17361726
}
17371727

17381728
// Enable prefetching to pull in trie node paths while processing transactions
1739-
statedb.StartPrefetcher("chain", bc.cacheConfig.TriePrefetcherParallelism)
1740-
defer func() {
1741-
statedb.StopPrefetcher()
1742-
}()
1729+
statedb.StartPrefetcher("chain", state.WithConcurrentWorkers(bc.cacheConfig.TriePrefetcherParallelism))
1730+
defer statedb.StopPrefetcher()
17431731

17441732
// Process previously stored block
17451733
receipts, _, usedGas, err := bc.processor.Process(current, parent.Header(), statedb, vm.Config{})

core/state/statedb.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/ava-labs/subnet-evm/trie"
4242
"github.com/ava-labs/subnet-evm/trie/trienode"
4343
"github.com/ava-labs/subnet-evm/trie/triestate"
44+
"github.com/ava-labs/subnet-evm/utils"
4445
"github.com/ethereum/go-ethereum/common"
4546
"github.com/ethereum/go-ethereum/crypto"
4647
"github.com/ethereum/go-ethereum/log"
@@ -200,16 +201,33 @@ func NewWithSnapshot(root common.Hash, db Database, snap snapshot.Snapshot) (*St
200201
return sdb, nil
201202
}
202203

204+
type workerPool struct {
205+
*utils.BoundedWorkers
206+
}
207+
208+
func (wp *workerPool) Done() {
209+
// Done is guaranteed to only be called after all work is already complete,
210+
// so Wait()ing is redundant, but it also releases resources.
211+
wp.BoundedWorkers.Wait()
212+
}
213+
214+
func WithConcurrentWorkers(prefetchers int) PrefetcherOption {
215+
pool := &workerPool{
216+
BoundedWorkers: utils.NewBoundedWorkers(prefetchers),
217+
}
218+
return WithWorkerPools(func() WorkerPool { return pool })
219+
}
220+
203221
// StartPrefetcher initializes a new trie prefetcher to pull in nodes from the
204222
// state trie concurrently while the state is mutated so that when we reach the
205223
// commit phase, most of the needed data is already hot.
206-
func (s *StateDB) StartPrefetcher(namespace string, maxConcurrency int) {
224+
func (s *StateDB) StartPrefetcher(namespace string, opts ...PrefetcherOption) {
207225
if s.prefetcher != nil {
208226
s.prefetcher.close()
209227
s.prefetcher = nil
210228
}
211229
if s.snap != nil {
212-
s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace, maxConcurrency)
230+
s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace, opts...)
213231
}
214232
}
215233

0 commit comments

Comments
 (0)