mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
core/filtermaps: fix map renderer bug
This commit is contained in:
parent
d40607cfc0
commit
dbf620d365
2 changed files with 19 additions and 25 deletions
|
|
@ -144,7 +144,10 @@ type filterMap []FilterRow
|
||||||
// copies made for snapshots during rendering.
|
// copies made for snapshots during rendering.
|
||||||
func (fm filterMap) copy() filterMap {
|
func (fm filterMap) copy() filterMap {
|
||||||
c := make(filterMap, len(fm))
|
c := make(filterMap, len(fm))
|
||||||
copy(c, fm)
|
for i, row := range fm {
|
||||||
|
c[i] = make(FilterRow, len(row))
|
||||||
|
copy(c[i], row)
|
||||||
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ func (f *FilterMaps) renderMapsBefore(renderBefore uint32) (*mapRenderer, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if snapshot := f.lastCanonicalSnapshotBefore(renderBefore); snapshot != nil && snapshot.mapIndex >= nextMap {
|
if snapshot := f.lastCanonicalSnapshotOfMap(nextMap); snapshot != nil {
|
||||||
return f.renderMapsFromSnapshot(snapshot)
|
return f.renderMapsFromSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
if nextMap >= renderBefore {
|
if nextMap >= renderBefore {
|
||||||
|
|
@ -97,7 +97,7 @@ func (f *FilterMaps) renderMapsBefore(renderBefore uint32) (*mapRenderer, error)
|
||||||
// snapshot made at a block boundary.
|
// snapshot made at a block boundary.
|
||||||
func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, error) {
|
func (f *FilterMaps) renderMapsFromSnapshot(cp *renderedMap) (*mapRenderer, error) {
|
||||||
f.testSnapshotUsed = true
|
f.testSnapshotUsed = true
|
||||||
iter, err := f.newLogIteratorFromBlockDelimiter(cp.lastBlock)
|
iter, err := f.newLogIteratorFromBlockDelimiter(cp.lastBlock, cp.headDelimiter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create log iterator from block delimiter %d: %v", cp.lastBlock, err)
|
return nil, fmt.Errorf("failed to create log iterator from block delimiter %d: %v", cp.lastBlock, err)
|
||||||
}
|
}
|
||||||
|
|
@ -137,14 +137,14 @@ func (f *FilterMaps) renderMapsFromMapBoundary(firstMap, renderBefore uint32, st
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// lastCanonicalSnapshotBefore returns the latest cached snapshot that matches
|
// lastCanonicalSnapshotOfMap returns the latest cached snapshot of the given map
|
||||||
// the current targetView.
|
// that is also consistent with the current targetView.
|
||||||
func (f *FilterMaps) lastCanonicalSnapshotBefore(renderBefore uint32) *renderedMap {
|
func (f *FilterMaps) lastCanonicalSnapshotOfMap(mapIndex uint32) *renderedMap {
|
||||||
var best *renderedMap
|
var best *renderedMap
|
||||||
for _, blockNumber := range f.renderSnapshots.Keys() {
|
for _, blockNumber := range f.renderSnapshots.Keys() {
|
||||||
if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.blocks.AfterLast() &&
|
if cp, _ := f.renderSnapshots.Get(blockNumber); cp != nil && blockNumber < f.indexedRange.blocks.AfterLast() &&
|
||||||
blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId &&
|
blockNumber <= f.targetView.headNumber && f.targetView.getBlockId(blockNumber) == cp.lastBlockId &&
|
||||||
cp.mapIndex < renderBefore && (best == nil || blockNumber > best.lastBlock) {
|
cp.mapIndex == mapIndex && (best == nil || blockNumber > best.lastBlock) {
|
||||||
best = cp
|
best = cp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -171,10 +171,9 @@ func (f *FilterMaps) lastCanonicalMapBoundaryBefore(renderBefore uint32) (nextMa
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, 0, fmt.Errorf("failed to retrieve last block of reverse iterated map %d: %v", mapIndex, err)
|
return 0, 0, 0, fmt.Errorf("failed to retrieve last block of reverse iterated map %d: %v", mapIndex, err)
|
||||||
}
|
}
|
||||||
if lastBlock >= f.indexedView.headNumber || lastBlock >= f.targetView.headNumber ||
|
if (f.indexedRange.headIndexed && mapIndex >= f.indexedRange.maps.Last()) ||
|
||||||
lastBlockId != f.targetView.getBlockId(lastBlock) {
|
lastBlock >= f.targetView.headNumber || lastBlockId != f.targetView.getBlockId(lastBlock) {
|
||||||
// map is not full or inconsistent with targetView; roll back
|
continue // map is not full or inconsistent with targetView; roll back
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
lvPtr, err := f.getBlockLvPointer(lastBlock)
|
lvPtr, err := f.getBlockLvPointer(lastBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -257,10 +256,13 @@ func (f *FilterMaps) loadHeadSnapshot() error {
|
||||||
|
|
||||||
// makeSnapshot creates a snapshot of the current state of the rendered map.
|
// makeSnapshot creates a snapshot of the current state of the rendered map.
|
||||||
func (r *mapRenderer) makeSnapshot() {
|
func (r *mapRenderer) makeSnapshot() {
|
||||||
r.f.renderSnapshots.Add(r.iterator.blockNumber, &renderedMap{
|
if r.iterator.blockNumber != r.currentMap.lastBlock {
|
||||||
|
panic("iterator state inconsistent with last block")
|
||||||
|
}
|
||||||
|
r.f.renderSnapshots.Add(r.currentMap.lastBlock, &renderedMap{
|
||||||
filterMap: r.currentMap.filterMap.copy(),
|
filterMap: r.currentMap.filterMap.copy(),
|
||||||
mapIndex: r.currentMap.mapIndex,
|
mapIndex: r.currentMap.mapIndex,
|
||||||
lastBlock: r.iterator.blockNumber,
|
lastBlock: r.currentMap.lastBlock,
|
||||||
lastBlockId: r.f.targetView.getBlockId(r.currentMap.lastBlock),
|
lastBlockId: r.f.targetView.getBlockId(r.currentMap.lastBlock),
|
||||||
blockLvPtrs: r.currentMap.blockLvPtrs,
|
blockLvPtrs: r.currentMap.blockLvPtrs,
|
||||||
finished: true,
|
finished: true,
|
||||||
|
|
@ -661,24 +663,13 @@ var errUnindexedRange = errors.New("unindexed range")
|
||||||
// newLogIteratorFromBlockDelimiter creates a logIterator starting at the
|
// newLogIteratorFromBlockDelimiter creates a logIterator starting at the
|
||||||
// given block's first log value entry (the block delimiter), according to the
|
// given block's first log value entry (the block delimiter), according to the
|
||||||
// current targetView.
|
// current targetView.
|
||||||
func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber uint64) (*logIterator, error) {
|
func (f *FilterMaps) newLogIteratorFromBlockDelimiter(blockNumber, lvIndex uint64) (*logIterator, error) {
|
||||||
if blockNumber > f.targetView.headNumber {
|
if blockNumber > f.targetView.headNumber {
|
||||||
return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.headNumber)
|
return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", blockNumber, f.targetView.headNumber)
|
||||||
}
|
}
|
||||||
if !f.indexedRange.blocks.Includes(blockNumber) {
|
if !f.indexedRange.blocks.Includes(blockNumber) {
|
||||||
return nil, errUnindexedRange
|
return nil, errUnindexedRange
|
||||||
}
|
}
|
||||||
var lvIndex uint64
|
|
||||||
if f.indexedRange.headIndexed && blockNumber+1 == f.indexedRange.blocks.AfterLast() {
|
|
||||||
lvIndex = f.indexedRange.headDelimiter
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
lvIndex, err = f.getBlockLvPointer(blockNumber + 1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to retrieve log value pointer of block %d after delimiter: %v", blockNumber+1, err)
|
|
||||||
}
|
|
||||||
lvIndex--
|
|
||||||
}
|
|
||||||
finished := blockNumber == f.targetView.headNumber
|
finished := blockNumber == f.targetView.headNumber
|
||||||
l := &logIterator{
|
l := &logIterator{
|
||||||
chainView: f.targetView,
|
chainView: f.targetView,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue