From cbd6ed9e0bf2c8ef94260bcf0d9373cef61cdcc5 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 1 Jul 2025 22:31:09 +0800 Subject: [PATCH] core/filtermaps: define APIs for map, epoch calculation (#31659) This pull request refines the filtermap implementation, defining key APIs for map and epoch calculations to improve readability. This pull request doesn't change any logic, it's a pure cleanup. --------- Co-authored-by: zsfelfoldi --- core/filtermaps/filtermaps.go | 106 +++++++++++++++++------------- core/filtermaps/indexer.go | 12 ++-- core/filtermaps/indexer_test.go | 4 +- core/filtermaps/map_renderer.go | 2 +- core/filtermaps/matcher.go | 4 +- core/filtermaps/math.go | 103 ++++++++++++++++++++++------- core/rawdb/accessors_indexes.go | 6 +- eth/backend.go | 6 +- eth/filters/filter_system_test.go | 2 +- 9 files changed, 160 insertions(+), 85 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 752a211786..fede54df57 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -185,11 +185,14 @@ type filterMapsRange struct { initialized bool headIndexed bool headDelimiter uint64 // zero if headIndexed is false + // if initialized then all maps are rendered in the maps range maps common.Range[uint32] + // if tailPartialEpoch > 0 then maps between firstRenderedMap-mapsPerEpoch and // firstRenderedMap-mapsPerEpoch+tailPartialEpoch-1 are rendered tailPartialEpoch uint32 + // if initialized then all log values in the blocks range are fully // rendered // blockLvPointers are available in the blocks range @@ -223,13 +226,15 @@ type Config struct { } // NewFilterMaps creates a new FilterMaps and starts the indexer. -func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) *FilterMaps { +func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) (*FilterMaps, error) { rs, initialized, err := rawdb.ReadFilterMapsRange(db) if err != nil || (initialized && rs.Version != databaseVersion) { rs, initialized = rawdb.FilterMapsRange{}, false log.Warn("Invalid log index database version; resetting log index") } - params.deriveFields() + if err := params.sanitize(); err != nil { + return nil, err + } f := &FilterMaps{ db: db, closeCh: make(chan struct{}), @@ -254,15 +259,14 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f }, // deleting last unindexed epoch might have been interrupted by shutdown cleanedEpochsBefore: max(rs.MapsFirst>>params.logMapsPerEpoch, 1) - 1, - - historyCutoff: historyCutoff, - finalBlock: finalBlock, - matcherSyncCh: make(chan *FilterMapsMatcherBackend), - matchers: make(map[*FilterMapsMatcherBackend]struct{}), - filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), - lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks), - lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers), - renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), + historyCutoff: historyCutoff, + finalBlock: finalBlock, + matcherSyncCh: make(chan *FilterMapsMatcherBackend), + matchers: make(map[*FilterMapsMatcherBackend]struct{}), + filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps), + lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks), + lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers), + renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots), } f.checkRevertRange() // revert maps that are inconsistent with the current chain view @@ -272,7 +276,7 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f "firstmap", f.indexedRange.maps.First(), "lastmap", f.indexedRange.maps.Last(), "headindexed", f.indexedRange.headIndexed) } - return f + return f, nil } // Start starts the indexer. @@ -399,7 +403,7 @@ func (f *FilterMaps) init() error { batch := f.db.NewBatch() for epoch := range bestLen { cp := checkpoints[bestIdx][epoch] - f.storeLastBlockOfMap(batch, (uint32(epoch+1)< 0 { cp := checkpoints[bestIdx][bestLen-1] fmr.blocks = common.NewRange(cp.BlockNumber+1, 0) - fmr.maps = common.NewRange(uint32(bestLen)< ptr { - baseRowGroup := mapIndices[ptr] / f.baseRowGroupLength - groupLength := 1 - for ptr+groupLength < len(mapIndices) && mapIndices[ptr+groupLength]/f.baseRowGroupLength == baseRowGroup { + var ( + groupIndex = f.mapGroupIndex(mapIndices[ptr]) + groupLength = 1 + ) + for ptr+groupLength < len(mapIndices) && f.mapGroupIndex(mapIndices[ptr+groupLength]) == groupIndex { groupLength++ } 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 // getFilterMapRowsOfGroup fetches a set of filter map rows at map indices // belonging to the same base row group. func (f *FilterMaps) getFilterMapRowsOfGroup(target []FilterRow, mapIndices []uint32, rowIndex uint32, baseLayerOnly bool) error { - baseRowGroup := mapIndices[0] / f.baseRowGroupLength - baseMapRowIndex := f.mapRowIndex(baseRowGroup*f.baseRowGroupLength, rowIndex) - baseRows, err := rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth) + var ( + groupIndex = f.mapGroupIndex(mapIndices[0]) + mapRowIndex = f.mapRowIndex(groupIndex, rowIndex) + ) + baseRows, err := rawdb.ReadFilterMapBaseRows(f.db, mapRowIndex, f.baseRowGroupSize, f.logMapWidth) if err != nil { - return fmt.Errorf("failed to retrieve base row group %d of row %d: %v", baseRowGroup, rowIndex, err) + return fmt.Errorf("failed to retrieve base row group %d of row %d: %v", groupIndex, rowIndex, err) } for i, mapIndex := range mapIndices { - if mapIndex/f.baseRowGroupLength != baseRowGroup { - panic("mapIndices are not in the same base row group") + if f.mapGroupIndex(mapIndex) != groupIndex { + return fmt.Errorf("maps are not in the same base row group, index: %d, group: %d", mapIndex, groupIndex) } - row := baseRows[mapIndex&(f.baseRowGroupLength-1)] + row := baseRows[f.mapGroupOffset(mapIndex)] if !baseLayerOnly { extRow, err := rawdb.ReadFilterMapExtRow(f.db, f.mapRowIndex(mapIndex, rowIndex), f.logMapWidth) if err != nil { @@ -621,15 +629,17 @@ func (f *FilterMaps) getFilterMapRowsOfGroup(target []FilterRow, mapIndices []ui // indices and a shared row index. func (f *FilterMaps) storeFilterMapRows(batch ethdb.Batch, mapIndices []uint32, rowIndex uint32, rows []FilterRow) error { for len(mapIndices) > 0 { - baseRowGroup := mapIndices[0] / f.baseRowGroupLength - groupLength := 1 - for groupLength < len(mapIndices) && mapIndices[groupLength]/f.baseRowGroupLength == baseRowGroup { - groupLength++ + var ( + pos = 1 + groupIndex = f.mapGroupIndex(mapIndices[0]) + ) + for pos < len(mapIndices) && f.mapGroupIndex(mapIndices[pos]) == groupIndex { + pos++ } - if err := f.storeFilterMapRowsOfGroup(batch, mapIndices[:groupLength], rowIndex, rows[:groupLength]); err != nil { + if err := f.storeFilterMapRowsOfGroup(batch, mapIndices[:pos], rowIndex, rows[:pos]); err != nil { return err } - mapIndices, rows = mapIndices[groupLength:], rows[groupLength:] + mapIndices, rows = mapIndices[pos:], rows[pos:] } return nil } @@ -637,21 +647,23 @@ func (f *FilterMaps) storeFilterMapRows(batch ethdb.Batch, mapIndices []uint32, // storeFilterMapRowsOfGroup stores a set of filter map rows at map indices // belonging to the same base row group. func (f *FilterMaps) storeFilterMapRowsOfGroup(batch ethdb.Batch, mapIndices []uint32, rowIndex uint32, rows []FilterRow) error { - baseRowGroup := mapIndices[0] / f.baseRowGroupLength - baseMapRowIndex := f.mapRowIndex(baseRowGroup*f.baseRowGroupLength, rowIndex) - var baseRows [][]uint32 - if uint32(len(mapIndices)) != f.baseRowGroupLength { // skip base rows read if all rows are replaced + var ( + baseRows [][]uint32 + groupIndex = f.mapGroupIndex(mapIndices[0]) + mapRowIndex = f.mapRowIndex(groupIndex, rowIndex) + ) + if uint32(len(mapIndices)) != f.baseRowGroupSize { // skip base rows read if all rows are replaced var err error - baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth) + baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, mapRowIndex, f.baseRowGroupSize, f.logMapWidth) if err != nil { - return fmt.Errorf("failed to retrieve base row group %d of row %d for modification: %v", baseRowGroup, rowIndex, err) + return fmt.Errorf("failed to retrieve filter map %d base rows %d for modification: %v", groupIndex, rowIndex, err) } } else { - baseRows = make([][]uint32, f.baseRowGroupLength) + baseRows = make([][]uint32, f.baseRowGroupSize) } for i, mapIndex := range mapIndices { - if mapIndex/f.baseRowGroupLength != baseRowGroup { - panic("mapIndices are not in the same base row group") + if f.mapGroupIndex(mapIndex) != groupIndex { + return fmt.Errorf("maps are not in the same base row group, index: %d, group: %d", mapIndex, groupIndex) } baseRow := []uint32(rows[i]) var extRow FilterRow @@ -659,10 +671,10 @@ func (f *FilterMaps) storeFilterMapRowsOfGroup(batch ethdb.Batch, mapIndices []u extRow = baseRow[f.baseRowLength:] baseRow = baseRow[:f.baseRowLength] } - baseRows[mapIndex&(f.baseRowGroupLength-1)] = baseRow + baseRows[f.mapGroupOffset(mapIndex)] = baseRow rawdb.WriteFilterMapExtRow(batch, f.mapRowIndex(mapIndex, rowIndex), extRow, f.logMapWidth) } - rawdb.WriteFilterMapBaseRows(batch, baseMapRowIndex, baseRows, f.logMapWidth) + rawdb.WriteFilterMapBaseRows(batch, mapRowIndex, baseRows, f.logMapWidth) return nil } @@ -747,12 +759,12 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { defer f.indexLock.Unlock() // determine epoch boundaries - firstMap := epoch << f.logMapsPerEpoch - lastBlock, _, err := f.getLastBlockOfMap(firstMap + f.mapsPerEpoch - 1) + lastBlock, _, err := f.getLastBlockOfMap(f.lastEpochMap(epoch)) if err != nil { return false, fmt.Errorf("failed to retrieve last block of deleted epoch %d: %v", epoch, err) } var firstBlock uint64 + firstMap := f.firstEpochMap(epoch) if epoch > 0 { firstBlock, _, err = f.getLastBlockOfMap(firstMap - 1) if err != nil { @@ -763,8 +775,8 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { // update rendered range if necessary var ( fmr = f.indexedRange - firstEpoch = f.indexedRange.maps.First() >> f.logMapsPerEpoch - afterLastEpoch = (f.indexedRange.maps.AfterLast() + f.mapsPerEpoch - 1) >> f.logMapsPerEpoch + firstEpoch = f.mapEpoch(f.indexedRange.maps.First()) + afterLastEpoch = f.mapEpoch(f.indexedRange.maps.AfterLast() + f.mapsPerEpoch - 1) ) if f.indexedRange.tailPartialEpoch != 0 && firstEpoch > 0 { firstEpoch-- @@ -776,7 +788,7 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { // first fully or partially rendered epoch and there is at least one // rendered map in the next epoch; remove from indexed range fmr.tailPartialEpoch = 0 - fmr.maps.SetFirst((epoch + 1) << f.logMapsPerEpoch) + fmr.maps.SetFirst(f.firstEpochMap(epoch + 1)) fmr.blocks.SetFirst(lastBlock + 1) f.setRange(f.db, f.indexedView, fmr, false) default: @@ -857,7 +869,7 @@ func (f *FilterMaps) exportCheckpoints() { w.WriteString("[\n") comma := "," for epoch := uint32(0); epoch < epochCount; epoch++ { - lastBlock, lastBlockId, err := f.getLastBlockOfMap((epoch+1)<> f.logMapsPerEpoch + firstEpoch := f.mapEpoch(f.indexedRange.maps.First()) if firstEpoch == 0 || !f.needTailEpoch(firstEpoch-1) { break } @@ -359,7 +359,7 @@ func (f *FilterMaps) tryIndexTail() (bool, error) { // Note that unindexing is very quick as it only removes continuous ranges of // data from the database and is also called while running head indexing. func (f *FilterMaps) tryUnindexTail() (bool, error) { - firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch + firstEpoch := f.mapEpoch(f.indexedRange.maps.First()) if f.indexedRange.tailPartialEpoch > 0 && firstEpoch > 0 { firstEpoch-- } @@ -392,11 +392,11 @@ func (f *FilterMaps) tryUnindexTail() (bool, error) { // needTailEpoch returns true if the given tail epoch needs to be kept // according to the current tail target, false if it can be removed. func (f *FilterMaps) needTailEpoch(epoch uint32) bool { - firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch + firstEpoch := f.mapEpoch(f.indexedRange.maps.First()) if epoch > firstEpoch { return true } - if (epoch+1)<= f.indexedRange.maps.AfterLast() { + if f.firstEpochMap(epoch+1) >= f.indexedRange.maps.AfterLast() { return true } if epoch+1 < firstEpoch { @@ -405,7 +405,7 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool { var lastBlockOfPrevEpoch uint64 if epoch > 0 { var err error - lastBlockOfPrevEpoch, _, err = f.getLastBlockOfMap(epoch<= firstEpoch @@ -414,7 +414,7 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool { if f.historyCutoff > lastBlockOfPrevEpoch { return false } - lastBlockOfEpoch, _, err := f.getLastBlockOfMap((epoch+1)<= firstEpoch diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go index 4144f4cccc..35441905b7 100644 --- a/core/filtermaps/indexer_test.go +++ b/core/filtermaps/indexer_test.go @@ -41,7 +41,7 @@ var testParams = Params{ logMapWidth: 24, logMapsPerEpoch: 4, logValuesPerMap: 4, - baseRowGroupLength: 4, + baseRowGroupSize: 4, baseRowLengthRatio: 2, logLayerDiff: 2, } @@ -370,7 +370,7 @@ func (ts *testSetup) setHistory(history uint64, noHistory bool) { History: history, Disabled: noHistory, } - ts.fm = NewFilterMaps(ts.db, view, 0, 0, ts.params, config) + ts.fm, _ = NewFilterMaps(ts.db, view, 0, 0, ts.params, config) ts.fm.testDisableSnapshots = ts.testDisableSnapshots ts.fm.Start() } diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index 5379cbb157..e1284a3829 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -284,7 +284,7 @@ func (r *mapRenderer) run(stopCb func() bool, writeCb func()) (bool, error) { // map finished r.finishedMaps[r.currentMap.mapIndex] = r.currentMap r.finished.SetLast(r.finished.AfterLast()) - if len(r.finishedMaps) >= maxMapsPerBatch || r.finished.AfterLast()&(r.f.baseRowGroupLength-1) == 0 { + if len(r.finishedMaps) >= maxMapsPerBatch || r.f.mapGroupOffset(r.finished.AfterLast()) == 0 { if err := r.writeFinishedMaps(stopCb); err != nil { return false, err } diff --git a/core/filtermaps/matcher.go b/core/filtermaps/matcher.go index 82ea2ceee6..238723fe1d 100644 --- a/core/filtermaps/matcher.go +++ b/core/filtermaps/matcher.go @@ -844,7 +844,7 @@ func (m *matchSequenceInstance) dropNext(mapIndex uint32) bool { // results at mapIndex and mapIndex+1. Note that acquiring nextNextRes may be // skipped and it can be substituted with an empty list if baseRes has no potential // matches that could be sequence matched with anything that could be in nextNextRes. -func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes potentialMatches) potentialMatches { +func (p *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes potentialMatches) potentialMatches { if nextRes == nil || (baseRes != nil && len(baseRes) == 0) { // if nextRes is a wild card or baseRes is empty then the sequence matcher // result equals baseRes. @@ -854,7 +854,7 @@ func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, next // if baseRes is a wild card or nextRes is empty then the sequence matcher // result is the items of nextRes with a negative offset applied. result := make(potentialMatches, 0, len(nextRes)) - min := (uint64(mapIndex) << params.logValuesPerMap) + offset + min := (uint64(mapIndex) << p.logValuesPerMap) + offset for _, v := range nextRes { if v >= min { result = append(result, v-offset) diff --git a/core/filtermaps/math.go b/core/filtermaps/math.go index 762a99be9e..33ac07f721 100644 --- a/core/filtermaps/math.go +++ b/core/filtermaps/math.go @@ -19,6 +19,7 @@ package filtermaps import ( "crypto/sha256" "encoding/binary" + "fmt" "hash/fnv" "math" "sort" @@ -28,19 +29,36 @@ import ( // Params defines the basic parameters of the log index structure. type Params struct { - logMapHeight uint // log2(mapHeight) - logMapWidth uint // log2(mapWidth) - logMapsPerEpoch uint // log2(mapsPerEpoch) - logValuesPerMap uint // log2(logValuesPerMap) - baseRowLengthRatio uint // baseRowLength / average row length - logLayerDiff uint // maxRowLength log2 growth per layer - // derived fields - mapHeight uint32 // filter map height (number of rows) - mapsPerEpoch uint32 // number of maps in an epoch + logMapHeight uint // The number of bits required to represent the map height + logMapWidth uint // The number of bits required to represent the map width + logMapsPerEpoch uint // The number of bits required to represent the number of maps per epoch + logValuesPerMap uint // The number of bits required to represent the number of log values per map + + // baseRowLengthRatio represents the ratio of base row length + // to the average row length. + baseRowLengthRatio uint + + // logLayerDiff defines the logarithmic growth factor (base 2) of + // the maximum row length per layer. It indicates how much the maximum + // row length increases as the layer depth increases. + // + // Specifically: + // - the row length in base layer (layer == 0) is baseRowLength + // - the row length in layer x is baseRowLength << (logLayerDiff * x) + logLayerDiff uint + + // These fields can be derived with the information above + mapHeight uint32 // The number of rows in the filter map + mapsPerEpoch uint32 // The number of maps in an epoch + valuesPerMap uint64 // The number of log values marked on each filter map baseRowLength uint32 // maximum number of log values per row on layer 0 - valuesPerMap uint64 // number of log values marked on each filter map - // not affecting consensus - baseRowGroupLength uint32 // length of base row groups in local database + + // baseRowGroupSize defines the number of base row entries grouped together + // as a single database entry in the local database to optimize storage + // and retrieval efficiency. + // + // This value can be configured based on the specific implementation. + baseRowGroupSize uint32 } // DefaultParams is the set of parameters used on mainnet. @@ -49,7 +67,7 @@ var DefaultParams = Params{ logMapWidth: 24, logMapsPerEpoch: 10, logValuesPerMap: 16, - baseRowGroupLength: 32, + baseRowGroupSize: 32, baseRowLengthRatio: 8, logLayerDiff: 4, } @@ -60,7 +78,7 @@ var RangeTestParams = Params{ logMapWidth: 24, logMapsPerEpoch: 0, logValuesPerMap: 0, - baseRowGroupLength: 32, + baseRowGroupSize: 32, baseRowLengthRatio: 16, // baseRowLength >= 1 logLayerDiff: 4, } @@ -91,6 +109,44 @@ func topicValue(topic common.Hash) common.Hash { return result } +// sanitize derives any missing fields and validates the parameter values. +func (p *Params) sanitize() error { + p.deriveFields() + if p.logMapWidth%8 != 0 { + return fmt.Errorf("invalid configuration: logMapWidth (%d) must be a multiple of 8", p.logMapWidth) + } + if p.baseRowGroupSize == 0 || (p.baseRowGroupSize&(p.baseRowGroupSize-1)) != 0 { + return fmt.Errorf("invalid configuration: baseRowGroupSize (%d) must be a power of 2", p.baseRowGroupSize) + } + return nil +} + +// mapGroupIndex returns the start index of the base row group that contains the +// given map index. Assumes baseRowGroupSize is a power of 2. +func (p *Params) mapGroupIndex(index uint32) uint32 { + return index & ^(p.baseRowGroupSize - 1) +} + +// mapGroupOffset returns the offset of the given map index within its base row group. +func (p *Params) mapGroupOffset(index uint32) uint32 { + return index & (p.baseRowGroupSize - 1) +} + +// mapEpoch returns the epoch number that the given map index belongs to. +func (p *Params) mapEpoch(index uint32) uint32 { + return index >> p.logMapsPerEpoch +} + +// firstEpochMap returns the index of the first map in the specified epoch. +func (p *Params) firstEpochMap(epoch uint32) uint32 { + return epoch << p.logMapsPerEpoch +} + +// lastEpochMap returns the index of the last map in the specified epoch. +func (p *Params) lastEpochMap(epoch uint32) uint32 { + return (epoch+1)<>(64-hashBits)) ^ uint32(hash)>>(32-hashBits)) } -// maxRowLength returns the maximum length filter rows are populated up to -// when using the given mapping layer. A log value can be marked on the map -// according to a given mapping layer if the row mapping on that layer points -// to a row that has not yet reached the maxRowLength belonging to that layer. +// maxRowLength returns the maximum length filter rows are populated up to when +// using the given mapping layer. +// +// A log value can be marked on the map according to a given mapping layer if +// the row mapping on that layer points to a row that has not yet reached the +// maxRowLength belonging to that layer. +// // This means that a row that is considered full on a given layer may still be // extended further on a higher order layer. +// // Each value is marked on the lowest order layer possible, assuming that marks -// are added in ascending log value index order. -// When searching for a log value one should consider all layers and process -// corresponding rows up until the first one where the row mapped to the given -// layer is not full. +// are added in ascending log value index order. When searching for a log value +// one should consider all layers and process corresponding rows up until the +// first one where the row mapped to the given layer is not full. func (p *Params) maxRowLength(layerIndex uint32) uint32 { logLayerDiff := uint(layerIndex) * p.logLayerDiff if logLayerDiff > p.logMapsPerEpoch { diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index f56ff066e9..f71bbb500b 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -388,7 +388,7 @@ func ReadFilterMapBaseRows(db ethdb.KeyValueReader, mapRowIndex uint64, rowCount headerBits-- } if headerLen+byteLength*entryCount > encLen { - return nil, errors.New("Invalid encoded base filter rows length") + return nil, errors.New("invalid encoded base filter rows length") } if entriesInRow > 0 { rows[rowIndex] = make([]uint32, entriesInRow) @@ -405,8 +405,8 @@ func ReadFilterMapBaseRows(db ethdb.KeyValueReader, mapRowIndex uint64, rowCount return rows, nil } -// WriteFilterMapExtRow stores a filter map row at the given mapRowIndex or deletes -// any existing entry if the row is empty. +// WriteFilterMapExtRow stores an extended filter map row at the given mapRowIndex +// or deletes any existing entry if the row is empty. func WriteFilterMapExtRow(db ethdb.KeyValueWriter, mapRowIndex uint64, row []uint32, bitLength uint) { byteLength := int(bitLength) / 8 if int(bitLength) != byteLength*8 { diff --git a/eth/backend.go b/eth/backend.go index f7105ab79c..80ffd301ce 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -278,7 +278,11 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if fb := eth.blockchain.CurrentFinalBlock(); fb != nil { finalBlock = fb.Number.Uint64() } - eth.filterMaps = filtermaps.NewFilterMaps(chainDb, chainView, historyCutoff, finalBlock, filtermaps.DefaultParams, fmConfig) + filterMaps, err := filtermaps.NewFilterMaps(chainDb, chainView, historyCutoff, finalBlock, filtermaps.DefaultParams, fmConfig) + if err != nil { + return nil, err + } + eth.filterMaps = filterMaps eth.closeFilterMaps = make(chan chan struct{}) // TxPool diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 0839312b70..10f82364b5 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -175,7 +175,7 @@ func (b *testBackend) startFilterMaps(history uint64, disabled bool, params filt Disabled: disabled, ExportFileName: "", } - b.fm = filtermaps.NewFilterMaps(b.db, chainView, 0, 0, params, config) + b.fm, _ = filtermaps.NewFilterMaps(b.db, chainView, 0, 0, params, config) b.fm.Start() b.fm.WaitIdle() }