Skip to content

Commit 4c9e7d1

Browse files
authored
core/filtermaps: make ChainView thread safe (#31671)
This PR makes `filtermaps.ChainView` thread safe because it is used concurrently both by the indexer and multiple matcher threads. Even though it represents an immutable view of the chain, adding a mutex lock to the `blockHash` function is necessary because it does so by extending its list of non-canonical hashes if the underlying blockchain is changed. The unsafe concurrency did cause a panic once after running the unit tests for several hours and it could also happen during live operation.
1 parent 2e0ad2c commit 4c9e7d1

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

core/filtermaps/chain_view.go

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package filtermaps
1818

1919
import (
20+
"sync"
21+
2022
"github.com/ethereum/go-ethereum/common"
2123
"github.com/ethereum/go-ethereum/core/types"
2224
"github.com/ethereum/go-ethereum/log"
@@ -39,6 +41,7 @@ type blockchain interface {
3941
// of the underlying blockchain, it should only possess the block headers
4042
// and receipts up until the expected chain view head.
4143
type ChainView struct {
44+
lock sync.Mutex
4245
chain blockchain
4346
headNumber uint64
4447
hashes []common.Hash // block hashes starting backwards from headNumber until first canonical hash
@@ -147,6 +150,9 @@ func (cv *ChainView) extendNonCanonical() bool {
147150

148151
// blockHash returns the given block hash without doing the head number check.
149152
func (cv *ChainView) blockHash(number uint64) common.Hash {
153+
cv.lock.Lock()
154+
defer cv.lock.Unlock()
155+
150156
if number+uint64(len(cv.hashes)) <= cv.headNumber {
151157
hash := cv.chain.GetCanonicalHash(number)
152158
if !cv.extendNonCanonical() {

0 commit comments

Comments
 (0)