core/filtermaps: fixed tail pointer bug, added more failing checks

pull/30370/head
Zsolt Felfoldi 2 months ago
parent f8e98ae974
commit ab5e582acf
  1. 6
      core/filtermaps/indexer.go
  2. 32
      core/filtermaps/indexer_test.go

@ -664,7 +664,7 @@ func (u *updateBatch) addBlockToTail(header *types.Header, receipts types.Receip
return errors.New("addBlockToTail parent mismatch") return errors.New("addBlockToTail parent mismatch")
} }
number := header.Number.Uint64() number := header.Number.Uint64()
stopMap := uint32((u.tailLvPointer + u.f.valuesPerMap - 1) >> u.f.logValuesPerMap) stopMap := uint32((u.tailBlockLvPointer + u.f.valuesPerMap - 1) >> u.f.logValuesPerMap)
var cnt int var cnt int
if err := iterateReceiptsReverse(receipts, func(lv common.Hash) error { if err := iterateReceiptsReverse(receipts, func(lv common.Hash) error {
cnt++ cnt++
@ -672,11 +672,11 @@ func (u *updateBatch) addBlockToTail(header *types.Header, receipts types.Receip
}); err != nil { }); err != nil {
return err return err
} }
startMap := uint32(u.tailLvPointer >> u.f.logValuesPerMap) startMap := uint32(u.tailBlockLvPointer >> u.f.logValuesPerMap)
for m := startMap; m < stopMap; m++ { for m := startMap; m < stopMap; m++ {
u.mapBlockPtr[m] = number u.mapBlockPtr[m] = number
} }
u.blockLvPointer[number] = u.tailLvPointer u.blockLvPointer[number] = u.tailBlockLvPointer
u.tailBlockNumber, u.tailParentHash = number, header.ParentHash u.tailBlockNumber, u.tailParentHash = number, header.ParentHash
return nil return nil
} }

@ -40,6 +40,7 @@ func TestIndexerSetHistory(t *testing.T) {
ts.setHistory(0, false) ts.setHistory(0, false)
ts.chain.addBlocks(1000, 5, 2, 4, false) // 50 log values per block ts.chain.addBlocks(1000, 5, 2, 4, false) // 50 log values per block
ts.runUntilWait() ts.runUntilWait()
ts.checkLvRange(50)
ts.setHistory(100, false) ts.setHistory(100, false)
ts.runUntil(func() bool { ts.runUntil(func() bool {
l := ts.lastRange.headLvPointer - ts.lastRange.tailLvPointer l := ts.lastRange.headLvPointer - ts.lastRange.tailLvPointer
@ -47,11 +48,10 @@ func TestIndexerSetHistory(t *testing.T) {
}) })
ts.setHistory(200, false) ts.setHistory(200, false)
ts.runUntilWait() ts.runUntilWait()
ts.checkLvRange(50)
ts.setHistory(0, false) ts.setHistory(0, false)
ts.runUntilWait() ts.runUntilWait()
if ts.lastRange.headLvPointer-ts.lastRange.tailLvPointer != 50000 { ts.checkLvRange(50)
t.Fatalf("Invalid number of log values in the final state (expected %d, got %d)", 50000, ts.lastRange.headLvPointer-ts.lastRange.tailLvPointer)
}
} }
func TestIndexerRandomSetHistory(t *testing.T) { func TestIndexerRandomSetHistory(t *testing.T) {
@ -63,12 +63,13 @@ func TestIndexerRandomSetHistory(t *testing.T) {
for rand.Intn(20) != 0 && ts.lastEvent != testHookWait { for rand.Intn(20) != 0 && ts.lastEvent != testHookWait {
ts.nextEvent() ts.nextEvent()
} }
if ts.lastEvent == testHookWait {
ts.checkLvRange(50)
}
} }
ts.setHistory(0, false) ts.setHistory(0, false)
ts.runUntilWait() ts.runUntilWait()
if ts.lastRange.headLvPointer-ts.lastRange.tailLvPointer != 5000 { ts.checkLvRange(50)
t.Fatalf("Invalid number of log values in the final state (expected %d, got %d)", 5000, ts.lastRange.headLvPointer-ts.lastRange.tailLvPointer)
}
} }
type testSetup struct { type testSetup struct {
@ -76,6 +77,7 @@ type testSetup struct {
fm *FilterMaps fm *FilterMaps
db ethdb.Database db ethdb.Database
chain *testChain chain *testChain
params Params
eventCh chan int eventCh chan int
resumeCh chan struct{} resumeCh chan struct{}
lastEvent int lastEvent int
@ -83,10 +85,13 @@ type testSetup struct {
} }
func newTestSetup(t *testing.T) *testSetup { func newTestSetup(t *testing.T) *testSetup {
params := testParams
params.deriveFields()
return &testSetup{ return &testSetup{
t: t, t: t,
chain: newTestChain(), chain: newTestChain(),
db: rawdb.NewMemoryDatabase(), db: rawdb.NewMemoryDatabase(),
params: params,
eventCh: make(chan int), eventCh: make(chan int),
resumeCh: make(chan struct{}), resumeCh: make(chan struct{}),
} }
@ -108,11 +113,24 @@ func (ts *testSetup) runUntilWait() {
} }
} }
func (ts *testSetup) checkLvRange(lvPerBlock uint64) {
expBlockCount := uint64(len(ts.chain.canonical) - 1)
if ts.fm.history != 0 && ts.fm.history < expBlockCount {
expBlockCount = ts.fm.history
}
if ts.lastRange.headLvPointer-ts.lastRange.tailBlockLvPointer != expBlockCount*lvPerBlock {
ts.t.Fatalf("Invalid number of log values (expected %d, got %d)", expBlockCount*lvPerBlock, ts.lastRange.headLvPointer-ts.lastRange.tailLvPointer)
}
if ts.lastRange.tailBlockLvPointer-ts.lastRange.tailLvPointer >= ts.params.valuesPerMap {
ts.t.Fatalf("Invalid number of leftover tail log values (expected < %d, got %d)", ts.params.valuesPerMap, ts.lastRange.tailBlockLvPointer-ts.lastRange.tailLvPointer)
}
}
func (ts *testSetup) setHistory(history uint64, noHistory bool) { func (ts *testSetup) setHistory(history uint64, noHistory bool) {
if ts.fm != nil { if ts.fm != nil {
ts.stopFm() ts.stopFm()
} }
ts.fm = NewFilterMaps(ts.db, ts.chain, testParams, history, noHistory) ts.fm = NewFilterMaps(ts.db, ts.chain, ts.params, history, noHistory)
ts.fm.testHook = ts.testHook ts.fm.testHook = ts.testHook
ts.fm.Start() ts.fm.Start()
ts.lastEvent = <-ts.eventCh ts.lastEvent = <-ts.eventCh

Loading…
Cancel
Save