Skip to content

Commit 5862611

Browse files
committed
fix map renderer reorg issue
1 parent 87c1347 commit 5862611

8 files changed

Lines changed: 47 additions & 38 deletions

File tree

core/filtermaps/filtermaps.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ var (
5050
)
5151

5252
const (
53+
databaseVersion = 1 // reindexed if database version does not match
5354
cachedLastBlocks = 1000 // last block of map pointers
5455
cachedLvPointers = 1000 // first log value pointer of block pointers
5556
cachedBaseRows = 100 // groups of base layer filter row data
@@ -138,13 +139,25 @@ type FilterMaps struct {
138139
// as transparent (uncached/unchanged).
139140
type filterMap []FilterRow
140141

141-
// copy returns a copy of the given filter map. Note that the row slices are
142-
// copied but their contents are not. This permits extending the rows further
142+
// fastCopy returns a copy of the given filter map. Note that the row slices are
143+
// copied but their contents are not. This permits appending to the rows further
143144
// (which happens during map rendering) without affecting the validity of
144145
// copies made for snapshots during rendering.
145-
func (fm filterMap) copy() filterMap {
146+
// Appending to the rows of both the original map and the fast copy, or two fast
147+
// copies of the same map would result in data corruption, therefore a fast copy
148+
// should always be used in a read only way.
149+
func (fm filterMap) fastCopy() filterMap {
150+
return slices.Clone(fm)
151+
}
152+
153+
// fullCopy returns a copy of the given filter map, also making a copy of each
154+
// individual filter row, ensuring that a modification to either one will never
155+
// affect the other.
156+
func (fm filterMap) fullCopy() filterMap {
146157
c := make(filterMap, len(fm))
147-
copy(c, fm)
158+
for i, row := range fm {
159+
c[i] = slices.Clone(row)
160+
}
148161
return c
149162
}
150163

@@ -207,8 +220,9 @@ type Config struct {
207220
// NewFilterMaps creates a new FilterMaps and starts the indexer.
208221
func NewFilterMaps(db ctxcdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) *FilterMaps {
209222
rs, initialized, err := rawdb.ReadFilterMapsRange(db)
210-
if err != nil {
211-
log.Error("Error reading log index range", "error", err)
223+
if err != nil || rs.Version != databaseVersion {
224+
rs, initialized = rawdb.FilterMapsRange{}, false
225+
log.Warn("Invalid log index database version; resetting log index")
212226
}
213227
params.deriveFields()
214228
f := &FilterMaps{
@@ -437,6 +451,7 @@ func (f *FilterMaps) setRange(batch ctxcdb.KeyValueWriter, newView *ChainView, n
437451
f.updateMatchersValidRange()
438452
if newRange.initialized {
439453
rs := rawdb.FilterMapsRange{
454+
Version: databaseVersion,
440455
HeadIndexed: newRange.headIndexed,
441456
HeadDelimiter: newRange.headDelimiter,
442457
BlocksFirst: newRange.blocks.First(),

core/filtermaps/map_renderer.go

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (f *FilterMaps) renderMapsBefore(renderBefore uint32) (*mapRenderer, error)
8484
if err != nil {
8585
return nil, err
8686
}
87-
if snapshot := f.lastCanonicalSnapshotBefore(renderBefore); snapshot != nil && snapshot.mapIndex >= nextMap {
87+
if snapshot := f.lastCanonicalSnapshotOfMap(nextMap); snapshot != nil {
8888
return f.renderMapsFromSnapshot(snapshot)
8989
}
9090
if nextMap >= renderBefore {
@@ -97,14 +97,14 @@ func (f *FilterMaps) renderMapsBefore(renderBefore uint32) (*mapRenderer, error)
9797
// snapshot made at a block boundary.
9898
func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, error) {
9999
f.testSnapshotUsed = true
100-
iter, err := f.newLogIteratorFromBlockDelimiter(cp.lastBlock)
100+
iter, err := f.newLogIteratorFromBlockDelimiter(cp.lastBlock, cp.headDelimiter)
101101
if err != nil {
102102
return nil, fmt.Errorf("failed to create log iterator from block delimiter %d: %v", cp.lastBlock, err)
103103
}
104104
return &mapRenderer{
105105
f: f,
106106
currentMap: &renderedMap{
107-
filterMap: cp.filterMap.copy(),
107+
filterMap: cp.filterMap.fullCopy(),
108108
mapIndex: cp.mapIndex,
109109
lastBlock: cp.lastBlock,
110110
blockLvPtrs: cp.blockLvPtrs,
@@ -137,14 +137,14 @@ func (f *FilterMaps) renderMapsFromMapBoundary(firstMap, renderBefore uint32, st
137137
}, nil
138138
}
139139

140-
// lastCanonicalSnapshotBefore returns the latest cached snapshot that matches
141-
// the current targetView.
142-
func (f *FilterMaps) lastCanonicalSnapshotBefore(renderBefore uint32) *renderedMap {
140+
// lastCanonicalSnapshotOfMap returns the latest cached snapshot of the given map
141+
// that is also consistent with the current targetView.
142+
func (f *FilterMaps) lastCanonicalSnapshotOfMap(mapIndex uint32) *renderedMap {
143143
var best *renderedMap
144144
for _, blockNumber := range f.renderSnapshots.Keys() {
145145
if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.blocks.AfterLast() &&
146146
blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId &&
147-
cp.mapIndex < renderBefore && (best == nil || blockNumber > best.lastBlock) {
147+
cp.mapIndex == mapIndex && (best == nil || blockNumber > best.lastBlock) {
148148
best = cp
149149
}
150150
}
@@ -171,10 +171,9 @@ func (f *FilterMaps) lastCanonicalMapBoundaryBefore(renderBefore uint32) (nextMa
171171
if err != nil {
172172
return 0, 0, 0, fmt.Errorf("failed to retrieve last block of reverse iterated map %d: %v", mapIndex, err)
173173
}
174-
if lastBlock >= f.indexedView.headNumber || lastBlock >= f.targetView.headNumber ||
175-
lastBlockId != f.targetView.getBlockId(lastBlock) {
176-
// map is not full or inconsistent with targetView; roll back
177-
continue
174+
if (f.indexedRange.headIndexed && mapIndex >= f.indexedRange.maps.Last()) ||
175+
lastBlock >= f.targetView.headNumber || lastBlockId != f.targetView.getBlockId(lastBlock) {
176+
continue // map is not full or inconsistent with targetView; roll back
178177
}
179178
lvPtr, err := f.getBlockLvPointer(lastBlock)
180179
if err != nil {
@@ -257,11 +256,14 @@ func (f *FilterMaps) loadHeadSnapshot() error {
257256

258257
// makeSnapshot creates a snapshot of the current state of the rendered map.
259258
func (r *mapRenderer) makeSnapshot() {
260-
r.f.renderSnapshots.Add(r.iterator.blockNumber, &renderedMap{
261-
filterMap: r.currentMap.filterMap.copy(),
259+
if r.iterator.blockNumber != r.currentMap.lastBlock || r.iterator.chainView != r.f.targetView {
260+
panic("iterator state inconsistent with current rendered map")
261+
}
262+
r.f.renderSnapshots.Add(r.currentMap.lastBlock, &renderedMap{
263+
filterMap: r.currentMap.filterMap.fastCopy(),
262264
mapIndex: r.currentMap.mapIndex,
263-
lastBlock: r.iterator.blockNumber,
264-
lastBlockId: r.f.targetView.getBlockId(r.currentMap.lastBlock),
265+
lastBlock: r.currentMap.lastBlock,
266+
lastBlockId: r.iterator.chainView.getBlockId(r.currentMap.lastBlock),
265267
blockLvPtrs: r.currentMap.blockLvPtrs,
266268
finished: true,
267269
headDelimiter: r.iterator.lvIndex,
@@ -661,24 +663,13 @@ var errUnindexedRange = errors.New("unindexed range")
661663
// newLogIteratorFromBlockDelimiter creates a logIterator starting at the
662664
// given block's first log value entry (the block delimiter), according to the
663665
// current targetView.
664-
func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber uint64) (*logIterator, error) {
666+
func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber, lvIndex uint64) (*logIterator, error) {
665667
if blockNumber > f.targetView.headNumber {
666668
return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.headNumber)
667669
}
668670
if !f.indexedRange.blocks.Includes(blockNumber) {
669671
return nil, errUnindexedRange
670672
}
671-
var lvIndex uint64
672-
if f.indexedRange.headIndexed && blockNumber+1 == f.indexedRange.blocks.AfterLast() {
673-
lvIndex = f.indexedRange.headDelimiter
674-
} else {
675-
var err error
676-
lvIndex, err = f.getBlockLvPointer(blockNumber + 1)
677-
if err != nil {
678-
return nil, fmt.Errorf("failed to retrieve log value pointer of block %d after delimiter: %v", blockNumber+1, err)
679-
}
680-
lvIndex--
681-
}
682673
finished := blockNumber == f.targetView.headNumber
683674
l := &logIterator{
684675
chainView: f.targetView,

core/filtermaps/matcher_backend.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ func (fm *FilterMapsMatcherBackend) Close() {
7575
// on write.
7676
// GetFilterMapRow implements MatcherBackend.
7777
func (fm *FilterMapsMatcherBackend) GetFilterMapRow(ctx context.Context, mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error) {
78+
fm.f.indexLock.RLock()
79+
defer fm.f.indexLock.RUnlock()
80+
7881
return fm.f.getFilterMapRow(mapIndex, rowIndex, baseLayerOnly)
7982
}
8083

core/rawdb/accessors_indexes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ func DeleteBloombits(db ctxcdb.Database, bit uint, from uint64, to uint64) {
469469
// FilterMapsRange is a storage representation of the block range covered by the
470470
// filter maps structure and the corresponting log value index range.
471471
type FilterMapsRange struct {
472+
Version uint32
472473
HeadIndexed bool
473474
HeadDelimiter uint64
474475
BlocksFirst, BlocksAfterLast uint64

ctxc/backend.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ func New(stack *node.Node, config *Config) (*Cortex, error) {
216216

217217
//StateHistory: config.StateHistory,
218218
//StateScheme: scheme,
219-
//HistoryPruningCutoff: historyPruningCutoff,
220219
ChainHistoryMode: config.HistoryMode,
221220
}
222221
)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0
77
github.com/CortexFoundation/inference v1.0.2-0.20230307032835-9197d586a4e8
88
github.com/CortexFoundation/statik v0.0.0-20210315012922-8bb8a7b5dc66
9-
github.com/CortexFoundation/torrentfs v1.0.69-0.20250415134051-0b782fe8b66d
9+
github.com/CortexFoundation/torrentfs v1.0.69-0.20250416125950-ceaf4dd388f2
1010
github.com/VictoriaMetrics/fastcache v1.12.2
1111
github.com/arsham/figurine v1.3.0
1212
github.com/aws/aws-sdk-go-v2 v1.36.3

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ github.com/CortexFoundation/statik v0.0.0-20210315012922-8bb8a7b5dc66/go.mod h1:
7070
github.com/CortexFoundation/torrentfs v1.0.13-0.20200623060705-ce027f43f2f8/go.mod h1:Ma+tGhPPvz4CEZHaqEJQMOEGOfHeQBiAoNd1zyc/w3Q=
7171
github.com/CortexFoundation/torrentfs v1.0.14-0.20200703071639-3fcabcabf274/go.mod h1:qnb3YlIJmuetVBtC6Lsejr0Xru+1DNmDCdTqnwy7lhk=
7272
github.com/CortexFoundation/torrentfs v1.0.20-0.20200810031954-d36d26f82fcc/go.mod h1:N5BsicP5ynjXIi/Npl/SRzlJ630n1PJV2sRj0Z0t2HA=
73-
github.com/CortexFoundation/torrentfs v1.0.69-0.20250415134051-0b782fe8b66d h1:oZk98KwRFZJHPhztM2yGwHobSa0wls6gdJXHRbSTdPs=
74-
github.com/CortexFoundation/torrentfs v1.0.69-0.20250415134051-0b782fe8b66d/go.mod h1:Lf7iaFiGPvExQiyPufsbQ8hs0XkKUunTLcp0r77/IaY=
73+
github.com/CortexFoundation/torrentfs v1.0.69-0.20250416125950-ceaf4dd388f2 h1:qvdjsYBKOJRrufSDO+DtpnX7TJdugbhrvL7/xhQBBdw=
74+
github.com/CortexFoundation/torrentfs v1.0.69-0.20250416125950-ceaf4dd388f2/go.mod h1:Lf7iaFiGPvExQiyPufsbQ8hs0XkKUunTLcp0r77/IaY=
7575
github.com/CortexFoundation/wormhole v0.0.2-0.20241128010855-a23c88842cfa h1:46VAGWxOwpoLlPNcR9etAhK0NtT215skO9Wl4i14r4o=
7676
github.com/CortexFoundation/wormhole v0.0.2-0.20241128010855-a23c88842cfa/go.mod h1:ipzmPabDgzYKUbXkGVe2gTkBEp+MsDx6pXGiuYzmP6s=
7777
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=

vendor/modules.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ github.com/CortexFoundation/robot/backend
6161
# github.com/CortexFoundation/statik v0.0.0-20210315012922-8bb8a7b5dc66
6262
## explicit; go 1.16
6363
github.com/CortexFoundation/statik
64-
# github.com/CortexFoundation/torrentfs v1.0.69-0.20250415134051-0b782fe8b66d
64+
# github.com/CortexFoundation/torrentfs v1.0.69-0.20250416125950-ceaf4dd388f2
6565
## explicit; go 1.23.4
6666
github.com/CortexFoundation/torrentfs
6767
github.com/CortexFoundation/torrentfs/backend

0 commit comments

Comments
 (0)