From ce3a30967df302c23a57d9194a6a616ddaf9f38e Mon Sep 17 00:00:00 2001 From: bbaktaeho Date: Thu, 13 Nov 2025 13:40:30 +0900 Subject: [PATCH] fix: add mutex for thread-safe access in indexReader and historyReader --- triedb/pathdb/history_index.go | 10 ++++++++++ triedb/pathdb/history_reader.go | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/triedb/pathdb/history_index.go b/triedb/pathdb/history_index.go index 5b4c91d7e6..49acf6f21b 100644 --- a/triedb/pathdb/history_index.go +++ b/triedb/pathdb/history_index.go @@ -21,6 +21,7 @@ import ( "fmt" "math" "sort" + "sync" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" @@ -74,6 +75,8 @@ type indexReader struct { descList []*indexBlockDesc readers map[uint32]*blockReader state stateIdent + + mu sync.RWMutex } // loadIndexData loads the index data associated with the specified state. @@ -103,6 +106,9 @@ func newIndexReader(db ethdb.KeyValueReader, state stateIdent) (*indexReader, er // refresh reloads the last section of index data to account for any additional // elements that may have been written to disk. func (r *indexReader) refresh() error { + r.mu.Lock() + defer r.mu.Unlock() + // Release the reader for the last section of index data, as its content // may have been modified by additional elements written to the disk. if len(r.descList) != 0 { @@ -130,7 +136,9 @@ func (r *indexReader) readGreaterThan(id uint64) (uint64, error) { } desc := r.descList[index] + r.mu.RLock() br, ok := r.readers[desc.id] + r.mu.RUnlock() if !ok { var err error blob := readStateIndexBlock(r.state, r.db, desc.id) @@ -138,7 +146,9 @@ func (r *indexReader) readGreaterThan(id uint64) (uint64, error) { if err != nil { return 0, err } + r.mu.Lock() r.readers[desc.id] = br + r.mu.Unlock() } // The supplied ID is not greater than block.max, ensuring that an element // satisfying the condition can be found. diff --git a/triedb/pathdb/history_reader.go b/triedb/pathdb/history_reader.go index 1bf4cf648d..83e7d86413 100644 --- a/triedb/pathdb/history_reader.go +++ b/triedb/pathdb/history_reader.go @@ -23,6 +23,7 @@ import ( "fmt" "math" "sort" + "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" @@ -104,6 +105,8 @@ type historyReader struct { disk ethdb.KeyValueReader freezer ethdb.AncientReader readers map[string]*indexReaderWithLimitTag + + mu sync.RWMutex } // newHistoryReader constructs the history reader with the supplied db. @@ -248,15 +251,19 @@ func (r *historyReader) read(state stateIdentQuery, stateID uint64, lastID uint6 return nil, fmt.Errorf("state history is not fully indexed, requested: %d, indexed: %s", stateID, indexed) } + r.mu.RLock() // Construct the index reader to locate the corresponding history for // state retrieval ir, ok := r.readers[state.String()] + r.mu.RUnlock() if !ok { ir, err = newIndexReaderWithLimitTag(r.disk, state.stateIdent, metadata.Last) if err != nil { return nil, err } + r.mu.Lock() r.readers[state.String()] = ir + r.mu.Unlock() } historyID, err := ir.readGreaterThan(stateID, lastID) if err != nil {