-
Notifications
You must be signed in to change notification settings - Fork 20.9k
core/filtermaps: clone cached slices, fix tempRange #31680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2c163ec
1fd2b97
8c4ec6a
c83f4e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,6 +128,7 @@ type FilterMaps struct { | |
|
||
// test hooks | ||
testDisableSnapshots, testSnapshotUsed bool | ||
testProcessEventsHook func() | ||
} | ||
|
||
// filterMap is a full or partial in-memory representation of a filter map where | ||
|
@@ -573,7 +574,7 @@ func (f *FilterMaps) getFilterMapRow(mapIndex, rowIndex uint32, baseLayerOnly bo | |
} | ||
f.baseRowsCache.Add(baseMapRowIndex, baseRows) | ||
} | ||
baseRow := baseRows[mapIndex&(f.baseRowGroupLength-1)] | ||
baseRow := slices.Clone(baseRows[mapIndex&(f.baseRowGroupLength-1)]) | ||
if baseLayerOnly { | ||
return baseRow, nil | ||
} | ||
|
@@ -610,7 +611,9 @@ func (f *FilterMaps) storeFilterMapRowsOfGroup(batch ethdb.Batch, mapIndices []u | |
if uint32(len(mapIndices)) != f.baseRowGroupLength { // skip base rows read if all rows are replaced | ||
var ok bool | ||
baseRows, ok = f.baseRowsCache.Get(baseMapRowIndex) | ||
if !ok { | ||
if ok { | ||
baseRows = slices.Clone(baseRows) | ||
} else { | ||
var err error | ||
baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth) | ||
if err != nil { | ||
|
@@ -656,7 +659,7 @@ func (f *FilterMaps) mapRowIndex(mapIndex, rowIndex uint32) uint64 { | |
// called from outside the indexerLoop goroutine. | ||
func (f *FilterMaps) getBlockLvPointer(blockNumber uint64) (uint64, error) { | ||
if blockNumber >= f.indexedRange.blocks.AfterLast() && f.indexedRange.headIndexed { | ||
return f.indexedRange.headDelimiter, nil | ||
return f.indexedRange.headDelimiter + 1, nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we error out if blockNumber > f.indexedRange.blocks.AfterLast()? Theoretically, the returned log index is for the next block and it must be consecutive with the latest indexed one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the search works async (range might change any time during the process) the underlying functions of the matcher backend do not fail when they are queried out of range, they just return results so that the search will not find any additional items (the head part of the results will be invalidated anyways in this case). |
||
} | ||
if lvPointer, ok := f.lvPointerCache.Get(blockNumber); ok { | ||
return lvPointer, nil | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ import ( | |
"errors" | ||
"fmt" | ||
"math" | ||
"slices" | ||
"sort" | ||
"time" | ||
|
||
|
@@ -107,7 +108,7 @@ func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, erro | |
filterMap: cp.filterMap.fullCopy(), | ||
mapIndex: cp.mapIndex, | ||
lastBlock: cp.lastBlock, | ||
blockLvPtrs: cp.blockLvPtrs, | ||
blockLvPtrs: slices.Clone(cp.blockLvPtrs), | ||
}, | ||
finishedMaps: make(map[uint32]*renderedMap), | ||
finished: common.NewRange(cp.mapIndex, 0), | ||
|
@@ -244,7 +245,7 @@ func (f *FilterMaps) loadHeadSnapshot() error { | |
} | ||
} | ||
f.renderSnapshots.Add(f.indexedRange.blocks.Last(), &renderedMap{ | ||
filterMap: fm, | ||
filterMap: fm.fullCopy(), | ||
mapIndex: f.indexedRange.maps.Last(), | ||
lastBlock: f.indexedRange.blocks.Last(), | ||
lastBlockId: f.indexedView.BlockId(f.indexedRange.blocks.Last()), | ||
|
@@ -536,6 +537,7 @@ func (r *mapRenderer) getTempRange() (filterMapsRange, error) { | |
} else { | ||
tempRange.blocks.SetAfterLast(0) | ||
} | ||
tempRange.headIndexed = false | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it the real root cause? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes |
||
tempRange.headDelimiter = 0 | ||
} | ||
return tempRange, nil | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also clone the slice in
getFilterMapRow
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do clone
baseRow
and if required then we appendextRow
which is always retrieved from the database so it's guaranteed that the returned result does not share an underlying array with anything.