@@ -185,11 +185,14 @@ type filterMapsRange struct {
185
185
initialized bool
186
186
headIndexed bool
187
187
headDelimiter uint64 // zero if headIndexed is false
188
+
188
189
// if initialized then all maps are rendered in the maps range
189
190
maps common.Range [uint32 ]
191
+
190
192
// if tailPartialEpoch > 0 then maps between firstRenderedMap-mapsPerEpoch and
191
193
// firstRenderedMap-mapsPerEpoch+tailPartialEpoch-1 are rendered
192
194
tailPartialEpoch uint32
195
+
193
196
// if initialized then all log values in the blocks range are fully
194
197
// rendered
195
198
// blockLvPointers are available in the blocks range
@@ -223,13 +226,15 @@ type Config struct {
223
226
}
224
227
225
228
// NewFilterMaps creates a new FilterMaps and starts the indexer.
226
- func NewFilterMaps (db ethdb.KeyValueStore , initView * ChainView , historyCutoff , finalBlock uint64 , params Params , config Config ) * FilterMaps {
229
+ func NewFilterMaps (db ethdb.KeyValueStore , initView * ChainView , historyCutoff , finalBlock uint64 , params Params , config Config ) ( * FilterMaps , error ) {
227
230
rs , initialized , err := rawdb .ReadFilterMapsRange (db )
228
231
if err != nil || (initialized && rs .Version != databaseVersion ) {
229
232
rs , initialized = rawdb.FilterMapsRange {}, false
230
233
log .Warn ("Invalid log index database version; resetting log index" )
231
234
}
232
- params .deriveFields ()
235
+ if err := params .sanitize (); err != nil {
236
+ return nil , err
237
+ }
233
238
f := & FilterMaps {
234
239
db : db ,
235
240
closeCh : make (chan struct {}),
@@ -254,15 +259,14 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f
254
259
},
255
260
// deleting last unindexed epoch might have been interrupted by shutdown
256
261
cleanedEpochsBefore : max (rs .MapsFirst >> params .logMapsPerEpoch , 1 ) - 1 ,
257
-
258
- historyCutoff : historyCutoff ,
259
- finalBlock : finalBlock ,
260
- matcherSyncCh : make (chan * FilterMapsMatcherBackend ),
261
- matchers : make (map [* FilterMapsMatcherBackend ]struct {}),
262
- filterMapCache : lru.NewCache [uint32 , filterMap ](cachedFilterMaps ),
263
- lastBlockCache : lru.NewCache [uint32 , lastBlockOfMap ](cachedLastBlocks ),
264
- lvPointerCache : lru.NewCache [uint64 , uint64 ](cachedLvPointers ),
265
- renderSnapshots : lru.NewCache [uint64 , * renderedMap ](cachedRenderSnapshots ),
262
+ historyCutoff : historyCutoff ,
263
+ finalBlock : finalBlock ,
264
+ matcherSyncCh : make (chan * FilterMapsMatcherBackend ),
265
+ matchers : make (map [* FilterMapsMatcherBackend ]struct {}),
266
+ filterMapCache : lru.NewCache [uint32 , filterMap ](cachedFilterMaps ),
267
+ lastBlockCache : lru.NewCache [uint32 , lastBlockOfMap ](cachedLastBlocks ),
268
+ lvPointerCache : lru.NewCache [uint64 , uint64 ](cachedLvPointers ),
269
+ renderSnapshots : lru.NewCache [uint64 , * renderedMap ](cachedRenderSnapshots ),
266
270
}
267
271
f .checkRevertRange () // revert maps that are inconsistent with the current chain view
268
272
@@ -272,7 +276,7 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f
272
276
"firstmap" , f .indexedRange .maps .First (), "lastmap" , f .indexedRange .maps .Last (),
273
277
"headindexed" , f .indexedRange .headIndexed )
274
278
}
275
- return f
279
+ return f , nil
276
280
}
277
281
278
282
// Start starts the indexer.
@@ -399,7 +403,7 @@ func (f *FilterMaps) init() error {
399
403
batch := f .db .NewBatch ()
400
404
for epoch := range bestLen {
401
405
cp := checkpoints [bestIdx ][epoch ]
402
- f .storeLastBlockOfMap (batch , (uint32 (epoch + 1 ) << f . logMapsPerEpoch ) - 1 , cp .BlockNumber , cp .BlockId )
406
+ f .storeLastBlockOfMap (batch , f . lastEpochMap (uint32 (epoch )) , cp .BlockNumber , cp .BlockId )
403
407
f .storeBlockLvPointer (batch , cp .BlockNumber , cp .FirstIndex )
404
408
}
405
409
fmr := filterMapsRange {
@@ -408,7 +412,7 @@ func (f *FilterMaps) init() error {
408
412
if bestLen > 0 {
409
413
cp := checkpoints [bestIdx ][bestLen - 1 ]
410
414
fmr .blocks = common .NewRange (cp .BlockNumber + 1 , 0 )
411
- fmr .maps = common .NewRange (uint32 (bestLen )<< f . logMapsPerEpoch , 0 )
415
+ fmr .maps = common .NewRange (f . firstEpochMap ( uint32 (bestLen )) , 0 )
412
416
}
413
417
f .setRange (batch , f .targetView , fmr , false )
414
418
return batch .Write ()
@@ -578,9 +582,11 @@ func (f *FilterMaps) getFilterMapRows(mapIndices []uint32, rowIndex uint32, base
578
582
rows := make ([]FilterRow , len (mapIndices ))
579
583
var ptr int
580
584
for len (mapIndices ) > ptr {
581
- baseRowGroup := mapIndices [ptr ] / f .baseRowGroupLength
582
- groupLength := 1
583
- for ptr + groupLength < len (mapIndices ) && mapIndices [ptr + groupLength ]/ f .baseRowGroupLength == baseRowGroup {
585
+ var (
586
+ groupIndex = f .mapGroupIndex (mapIndices [ptr ])
587
+ groupLength = 1
588
+ )
589
+ for ptr + groupLength < len (mapIndices ) && f .mapGroupIndex (mapIndices [ptr + groupLength ]) == groupIndex {
584
590
groupLength ++
585
591
}
586
592
if err := f .getFilterMapRowsOfGroup (rows [ptr :ptr + groupLength ], mapIndices [ptr :ptr + groupLength ], rowIndex , baseLayerOnly ); err != nil {
@@ -594,17 +600,19 @@ func (f *FilterMaps) getFilterMapRows(mapIndices []uint32, rowIndex uint32, base
594
600
// getFilterMapRowsOfGroup fetches a set of filter map rows at map indices
595
601
// belonging to the same base row group.
596
602
func (f * FilterMaps ) getFilterMapRowsOfGroup (target []FilterRow , mapIndices []uint32 , rowIndex uint32 , baseLayerOnly bool ) error {
597
- baseRowGroup := mapIndices [0 ] / f .baseRowGroupLength
598
- baseMapRowIndex := f .mapRowIndex (baseRowGroup * f .baseRowGroupLength , rowIndex )
599
- baseRows , err := rawdb .ReadFilterMapBaseRows (f .db , baseMapRowIndex , f .baseRowGroupLength , f .logMapWidth )
603
+ var (
604
+ groupIndex = f .mapGroupIndex (mapIndices [0 ])
605
+ mapRowIndex = f .mapRowIndex (groupIndex , rowIndex )
606
+ )
607
+ baseRows , err := rawdb .ReadFilterMapBaseRows (f .db , mapRowIndex , f .baseRowGroupSize , f .logMapWidth )
600
608
if err != nil {
601
- return fmt .Errorf ("failed to retrieve base row group %d of row %d: %v" , baseRowGroup , rowIndex , err )
609
+ return fmt .Errorf ("failed to retrieve base row group %d of row %d: %v" , groupIndex , rowIndex , err )
602
610
}
603
611
for i , mapIndex := range mapIndices {
604
- if mapIndex / f . baseRowGroupLength != baseRowGroup {
605
- panic ( "mapIndices are not in the same base row group" )
612
+ if f . mapGroupIndex ( mapIndex ) != groupIndex {
613
+ return fmt . Errorf ( "maps are not in the same base row group, index: %d, group: %d" , mapIndex , groupIndex )
606
614
}
607
- row := baseRows [mapIndex & ( f . baseRowGroupLength - 1 )]
615
+ row := baseRows [f . mapGroupOffset ( mapIndex )]
608
616
if ! baseLayerOnly {
609
617
extRow , err := rawdb .ReadFilterMapExtRow (f .db , f .mapRowIndex (mapIndex , rowIndex ), f .logMapWidth )
610
618
if err != nil {
@@ -621,48 +629,52 @@ func (f *FilterMaps) getFilterMapRowsOfGroup(target []FilterRow, mapIndices []ui
621
629
// indices and a shared row index.
622
630
func (f * FilterMaps ) storeFilterMapRows (batch ethdb.Batch , mapIndices []uint32 , rowIndex uint32 , rows []FilterRow ) error {
623
631
for len (mapIndices ) > 0 {
624
- baseRowGroup := mapIndices [0 ] / f .baseRowGroupLength
625
- groupLength := 1
626
- for groupLength < len (mapIndices ) && mapIndices [groupLength ]/ f .baseRowGroupLength == baseRowGroup {
627
- groupLength ++
628
- }
629
- if err := f .storeFilterMapRowsOfGroup (batch , mapIndices [:groupLength ], rowIndex , rows [:groupLength ]); err != nil {
632
+ var (
633
+ pos = 1
634
+ groupIndex = f .mapGroupIndex (mapIndices [0 ])
635
+ )
636
+ for pos < len (mapIndices ) && f .mapGroupIndex (mapIndices [pos ]) == groupIndex {
637
+ pos ++
638
+ }
639
+ if err := f .storeFilterMapRowsOfGroup (batch , mapIndices [:pos ], rowIndex , rows [:pos ]); err != nil {
630
640
return err
631
641
}
632
- mapIndices , rows = mapIndices [groupLength :], rows [groupLength :]
642
+ mapIndices , rows = mapIndices [pos :], rows [pos :]
633
643
}
634
644
return nil
635
645
}
636
646
637
647
// storeFilterMapRowsOfGroup stores a set of filter map rows at map indices
638
648
// belonging to the same base row group.
639
649
func (f * FilterMaps ) storeFilterMapRowsOfGroup (batch ethdb.Batch , mapIndices []uint32 , rowIndex uint32 , rows []FilterRow ) error {
640
- baseRowGroup := mapIndices [0 ] / f .baseRowGroupLength
641
- baseMapRowIndex := f .mapRowIndex (baseRowGroup * f .baseRowGroupLength , rowIndex )
642
- var baseRows [][]uint32
643
- if uint32 (len (mapIndices )) != f .baseRowGroupLength { // skip base rows read if all rows are replaced
650
+ var (
651
+ baseRows [][]uint32
652
+ groupIndex = f .mapGroupIndex (mapIndices [0 ])
653
+ mapRowIndex = f .mapRowIndex (groupIndex , rowIndex )
654
+ )
655
+ if uint32 (len (mapIndices )) != f .baseRowGroupSize { // skip base rows read if all rows are replaced
644
656
var err error
645
- baseRows , err = rawdb .ReadFilterMapBaseRows (f .db , baseMapRowIndex , f .baseRowGroupLength , f .logMapWidth )
657
+ baseRows , err = rawdb .ReadFilterMapBaseRows (f .db , mapRowIndex , f .baseRowGroupSize , f .logMapWidth )
646
658
if err != nil {
647
- return fmt .Errorf ("failed to retrieve base row group %d of row %d for modification: %v" , baseRowGroup , rowIndex , err )
659
+ return fmt .Errorf ("failed to retrieve filter map %d base rows %d for modification: %v" , groupIndex , rowIndex , err )
648
660
}
649
661
} else {
650
- baseRows = make ([][]uint32 , f .baseRowGroupLength )
662
+ baseRows = make ([][]uint32 , f .baseRowGroupSize )
651
663
}
652
664
for i , mapIndex := range mapIndices {
653
- if mapIndex / f . baseRowGroupLength != baseRowGroup {
654
- panic ( "mapIndices are not in the same base row group" )
665
+ if f . mapGroupIndex ( mapIndex ) != groupIndex {
666
+ return fmt . Errorf ( "maps are not in the same base row group, index: %d, group: %d" , mapIndex , groupIndex )
655
667
}
656
668
baseRow := []uint32 (rows [i ])
657
669
var extRow FilterRow
658
670
if uint32 (len (rows [i ])) > f .baseRowLength {
659
671
extRow = baseRow [f .baseRowLength :]
660
672
baseRow = baseRow [:f .baseRowLength ]
661
673
}
662
- baseRows [mapIndex & ( f . baseRowGroupLength - 1 )] = baseRow
674
+ baseRows [f . mapGroupOffset ( mapIndex )] = baseRow
663
675
rawdb .WriteFilterMapExtRow (batch , f .mapRowIndex (mapIndex , rowIndex ), extRow , f .logMapWidth )
664
676
}
665
- rawdb .WriteFilterMapBaseRows (batch , baseMapRowIndex , baseRows , f .logMapWidth )
677
+ rawdb .WriteFilterMapBaseRows (batch , mapRowIndex , baseRows , f .logMapWidth )
666
678
return nil
667
679
}
668
680
@@ -747,12 +759,12 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
747
759
defer f .indexLock .Unlock ()
748
760
749
761
// determine epoch boundaries
750
- firstMap := epoch << f .logMapsPerEpoch
751
- lastBlock , _ , err := f .getLastBlockOfMap (firstMap + f .mapsPerEpoch - 1 )
762
+ lastBlock , _ , err := f .getLastBlockOfMap (f .lastEpochMap (epoch ))
752
763
if err != nil {
753
764
return false , fmt .Errorf ("failed to retrieve last block of deleted epoch %d: %v" , epoch , err )
754
765
}
755
766
var firstBlock uint64
767
+ firstMap := f .firstEpochMap (epoch )
756
768
if epoch > 0 {
757
769
firstBlock , _ , err = f .getLastBlockOfMap (firstMap - 1 )
758
770
if err != nil {
@@ -763,8 +775,8 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
763
775
// update rendered range if necessary
764
776
var (
765
777
fmr = f .indexedRange
766
- firstEpoch = f .indexedRange .maps .First () >> f . logMapsPerEpoch
767
- afterLastEpoch = (f .indexedRange .maps .AfterLast () + f .mapsPerEpoch - 1 ) >> f . logMapsPerEpoch
778
+ firstEpoch = f .mapEpoch ( f . indexedRange .maps .First ())
779
+ afterLastEpoch = f . mapEpoch (f .indexedRange .maps .AfterLast () + f .mapsPerEpoch - 1 )
768
780
)
769
781
if f .indexedRange .tailPartialEpoch != 0 && firstEpoch > 0 {
770
782
firstEpoch --
@@ -776,7 +788,7 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
776
788
// first fully or partially rendered epoch and there is at least one
777
789
// rendered map in the next epoch; remove from indexed range
778
790
fmr .tailPartialEpoch = 0
779
- fmr .maps .SetFirst ((epoch + 1 ) << f . logMapsPerEpoch )
791
+ fmr .maps .SetFirst (f . firstEpochMap (epoch + 1 ))
780
792
fmr .blocks .SetFirst (lastBlock + 1 )
781
793
f .setRange (f .db , f .indexedView , fmr , false )
782
794
default :
@@ -857,7 +869,7 @@ func (f *FilterMaps) exportCheckpoints() {
857
869
w .WriteString ("[\n " )
858
870
comma := ","
859
871
for epoch := uint32 (0 ); epoch < epochCount ; epoch ++ {
860
- lastBlock , lastBlockId , err := f .getLastBlockOfMap ((epoch + 1 ) << f . logMapsPerEpoch - 1 )
872
+ lastBlock , lastBlockId , err := f .getLastBlockOfMap (f . lastEpochMap (epoch ) )
861
873
if err != nil {
862
874
log .Error ("Error fetching last block of epoch" , "epoch" , epoch , "error" , err )
863
875
return
0 commit comments