Skip to content

Commit ab480f0

Browse files
committed
fix: Pool.Put() trie copy _inside_ concurrent function
1 parent 02d59d9 commit ab480f0

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

core/state/trie_prefetcher.libevm.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ type prefetcherConfig struct {
3131
newWorkers func() WorkerPool
3232
}
3333

34-
// A WorkerPool is responsible for executing functions, possibly asynchronously.
34+
// A WorkerPool executes functions asynchronously.
3535
type WorkerPool interface {
3636
Execute(func())
3737
Wait()
3838
}
3939

4040
// WithWorkerPools configures trie prefetching to execute asynchronously. The
41-
// provided constructor is called once for each trie being fetched and it MAY
41+
// provided constructor is called once for each trie being fetched but it MAY
4242
// return the same pool.
4343
func WithWorkerPools(ctor func() WorkerPool) PrefetcherOption {
4444
return options.Func[prefetcherConfig](func(c *prefetcherConfig) {
@@ -76,21 +76,24 @@ func (p *subfetcherPool) wait() {
7676
}
7777

7878
// execute runs the provided function with a copy of the subfetcher's Trie.
79-
// Copies are stored in a [sync.Pool] to reduce creation overhead. If sf was
79+
// Copies are stored in a [sync.Pool] to reduce creation overhead. If p was
8080
// configured with a [WorkerPool] then it is used for function execution,
8181
// otherwise `fn` is just called directly.
8282
func (p *subfetcherPool) execute(fn func(Trie)) {
83-
trie := p.tries.Get().(Trie)
83+
do := func() {
84+
t := p.tries.Get().(Trie)
85+
fn(t)
86+
p.tries.Put(t)
87+
}
8488
if w := p.workers; w != nil {
85-
w.Execute(func() { fn(trie) })
89+
w.Execute(do)
8690
} else {
87-
fn(trie)
91+
do()
8892
}
89-
p.tries.Put(trie)
9093
}
9194

9295
// GetAccount optimistically pre-fetches an account, dropping the returned value
93-
// and logging errors. See [subfetcher.execute] re worker pools.
96+
// and logging errors. See [subfetcherPool.execute] re worker pools.
9497
func (p *subfetcherPool) GetAccount(addr common.Address) {
9598
p.execute(func(t Trie) {
9699
if _, err := t.GetAccount(addr); err != nil {
@@ -99,7 +102,7 @@ func (p *subfetcherPool) GetAccount(addr common.Address) {
99102
})
100103
}
101104

102-
// GetStorage is the storage equivalent of [subfetcher.GetAccount].
105+
// GetStorage is the storage equivalent of [subfetcherPool.GetAccount].
103106
func (p *subfetcherPool) GetStorage(addr common.Address, key []byte) {
104107
p.execute(func(t Trie) {
105108
if _, err := t.GetStorage(addr, key); err != nil {

0 commit comments

Comments
 (0)