mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
core/filtermaps: add history cutoff point
This commit is contained in:
parent
a5df454723
commit
7a057bffae
3 changed files with 48 additions and 41 deletions
|
|
@ -95,11 +95,11 @@ type FilterMaps struct {
|
||||||
|
|
||||||
targetView *ChainView
|
targetView *ChainView
|
||||||
matcherSyncRequest *FilterMapsMatcherBackend
|
matcherSyncRequest *FilterMapsMatcherBackend
|
||||||
|
historyCutoff uint64
|
||||||
finalBlock, lastFinal uint64
|
finalBlock, lastFinal uint64
|
||||||
lastFinalEpoch uint32
|
lastFinalEpoch uint32
|
||||||
stop bool
|
stop bool
|
||||||
targetViewCh chan *ChainView
|
targetCh chan targetUpdate
|
||||||
finalBlockCh chan uint64
|
|
||||||
blockProcessingCh chan bool
|
blockProcessingCh chan bool
|
||||||
blockProcessing bool
|
blockProcessing bool
|
||||||
matcherSyncCh chan *FilterMapsMatcherBackend
|
matcherSyncCh chan *FilterMapsMatcherBackend
|
||||||
|
|
@ -183,7 +183,7 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFilterMaps creates a new FilterMaps and starts the indexer.
|
// NewFilterMaps creates a new FilterMaps and starts the indexer.
|
||||||
func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, params Params, config Config) *FilterMaps {
|
func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) *FilterMaps {
|
||||||
rs, initialized, err := rawdb.ReadFilterMapsRange(db)
|
rs, initialized, err := rawdb.ReadFilterMapsRange(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error reading log index range", "error", err)
|
log.Error("Error reading log index range", "error", err)
|
||||||
|
|
@ -193,8 +193,7 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, params Params, c
|
||||||
db: db,
|
db: db,
|
||||||
closeCh: make(chan struct{}),
|
closeCh: make(chan struct{}),
|
||||||
waitIdleCh: make(chan chan bool),
|
waitIdleCh: make(chan chan bool),
|
||||||
targetViewCh: make(chan *ChainView, 1),
|
targetCh: make(chan targetUpdate, 1),
|
||||||
finalBlockCh: make(chan uint64, 1),
|
|
||||||
blockProcessingCh: make(chan bool, 1),
|
blockProcessingCh: make(chan bool, 1),
|
||||||
history: config.History,
|
history: config.History,
|
||||||
disabled: config.Disabled,
|
disabled: config.Disabled,
|
||||||
|
|
|
||||||
|
|
@ -66,28 +66,25 @@ func (f *FilterMaps) indexerLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type targetUpdate struct {
|
||||||
|
targetView *ChainView
|
||||||
|
historyCutoff, finalBlock uint64
|
||||||
|
}
|
||||||
|
|
||||||
// SetTargetView sets a new target chain view for the indexer to render.
|
// SetTargetView sets a new target chain view for the indexer to render.
|
||||||
// Note that SetTargetView never blocks.
|
// Note that SetTargetView never blocks.
|
||||||
func (f *FilterMaps) SetTargetView(targetView *ChainView) {
|
func (f *FilterMaps) SetTarget(targetView *ChainView, historyCutoff, finalBlock uint64) {
|
||||||
if targetView == nil {
|
if targetView == nil {
|
||||||
panic("nil targetView")
|
panic("nil targetView")
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-f.targetViewCh:
|
case <-f.targetCh:
|
||||||
case f.targetViewCh <- targetView:
|
case f.targetCh <- targetUpdate{
|
||||||
return
|
targetView: targetView,
|
||||||
}
|
historyCutoff: historyCutoff,
|
||||||
}
|
finalBlock: finalBlock,
|
||||||
}
|
}:
|
||||||
|
|
||||||
// SetFinalBlock sets the finalized block number used for exporting checkpoints.
|
|
||||||
// Note that SetFinalBlock never blocks.
|
|
||||||
func (f *FilterMaps) SetFinalBlock(finalBlock uint64) {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-f.finalBlockCh:
|
|
||||||
case f.finalBlockCh <- finalBlock:
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -145,26 +142,24 @@ func (f *FilterMaps) processSingleEvent(blocking bool) bool {
|
||||||
}
|
}
|
||||||
if blocking {
|
if blocking {
|
||||||
select {
|
select {
|
||||||
case targetView := <-f.targetViewCh:
|
case target := <-f.targetCh:
|
||||||
f.setTargetView(targetView)
|
f.setTarget(target)
|
||||||
case f.finalBlock = <-f.finalBlockCh:
|
|
||||||
case f.matcherSyncRequest = <-f.matcherSyncCh:
|
case f.matcherSyncRequest = <-f.matcherSyncCh:
|
||||||
case f.blockProcessing = <-f.blockProcessingCh:
|
case f.blockProcessing = <-f.blockProcessingCh:
|
||||||
case <-f.closeCh:
|
case <-f.closeCh:
|
||||||
f.stop = true
|
f.stop = true
|
||||||
case ch := <-f.waitIdleCh:
|
case ch := <-f.waitIdleCh:
|
||||||
select {
|
select {
|
||||||
case targetView := <-f.targetViewCh:
|
case target := <-f.targetCh:
|
||||||
f.setTargetView(targetView)
|
f.setTarget(target)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
ch <- !f.blockProcessing && f.targetHeadIndexed()
|
ch <- !f.blockProcessing && f.targetHeadIndexed()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
select {
|
select {
|
||||||
case targetView := <-f.targetViewCh:
|
case target := <-f.targetCh:
|
||||||
f.setTargetView(targetView)
|
f.setTarget(target)
|
||||||
case f.finalBlock = <-f.finalBlockCh:
|
|
||||||
case f.matcherSyncRequest = <-f.matcherSyncCh:
|
case f.matcherSyncRequest = <-f.matcherSyncCh:
|
||||||
case f.blockProcessing = <-f.blockProcessingCh:
|
case f.blockProcessing = <-f.blockProcessingCh:
|
||||||
case <-f.closeCh:
|
case <-f.closeCh:
|
||||||
|
|
@ -177,8 +172,10 @@ func (f *FilterMaps) processSingleEvent(blocking bool) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTargetView updates the target chain view of the iterator.
|
// setTargetView updates the target chain view of the iterator.
|
||||||
func (f *FilterMaps) setTargetView(targetView *ChainView) {
|
func (f *FilterMaps) setTarget(target targetUpdate) {
|
||||||
f.targetView = targetView
|
f.targetView = target.targetView
|
||||||
|
f.historyCutoff = target.historyCutoff
|
||||||
|
f.finalBlock = target.finalBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
// tryIndexHead tries to render head maps according to the current targetView
|
// tryIndexHead tries to render head maps according to the current targetView
|
||||||
|
|
@ -234,7 +231,11 @@ func (f *FilterMaps) tryIndexHead() bool {
|
||||||
// rendered according to targetView and is suspended as soon as the targetView
|
// rendered according to targetView and is suspended as soon as the targetView
|
||||||
// is changed.
|
// is changed.
|
||||||
func (f *FilterMaps) tryIndexTail() bool {
|
func (f *FilterMaps) tryIndexTail() bool {
|
||||||
for firstEpoch := f.indexedRange.firstRenderedMap >> f.logMapsPerEpoch; firstEpoch > 0 && f.needTailEpoch(firstEpoch-1); {
|
for {
|
||||||
|
firstEpoch := f.indexedRange.firstRenderedMap >> f.logMapsPerEpoch
|
||||||
|
if firstEpoch == 0 || !f.needTailEpoch(firstEpoch-1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
f.processEvents()
|
f.processEvents()
|
||||||
if f.stop || !f.targetHeadIndexed() {
|
if f.stop || !f.targetHeadIndexed() {
|
||||||
return false
|
return false
|
||||||
|
|
@ -283,7 +284,8 @@ func (f *FilterMaps) tryIndexTail() bool {
|
||||||
f.lastLogTailIndex = time.Now()
|
f.lastLogTailIndex = time.Now()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil && f.needTailEpoch(firstEpoch-1) {
|
||||||
|
// stop silently if cutoff point has move beyond epoch boundary while rendering
|
||||||
log.Error("Log index tail rendering failed", "error", err)
|
log.Error("Log index tail rendering failed", "error", err)
|
||||||
}
|
}
|
||||||
if !done {
|
if !done {
|
||||||
|
|
@ -347,16 +349,22 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool {
|
||||||
if epoch+1 < firstEpoch {
|
if epoch+1 < firstEpoch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
tailTarget := f.tailTargetBlock()
|
if epoch > 0 {
|
||||||
if tailTarget < f.indexedRange.firstIndexedBlock {
|
lastBlockOfPrevEpoch, _, err := f.getLastBlockOfMap(epoch<<f.logMapsPerEpoch - 1)
|
||||||
return true
|
if err != nil {
|
||||||
|
log.Error("Could not get last block of previous epoch", "epoch", epoch-1, "error", err)
|
||||||
|
return epoch >= firstEpoch
|
||||||
|
}
|
||||||
|
if f.historyCutoff > lastBlockOfPrevEpoch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tailLvIndex, err := f.getBlockLvPointer(tailTarget)
|
lastBlockOfEpoch, _, err := f.getLastBlockOfMap((epoch+1)<<f.logMapsPerEpoch - 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Could not get log value index of tail block", "error", err)
|
log.Error("Could not get last block of epoch", "epoch", epoch, "error", err)
|
||||||
return true
|
return epoch >= firstEpoch
|
||||||
}
|
}
|
||||||
return uint64(epoch+1)<<(f.logValuesPerMap+f.logMapsPerEpoch) >= tailLvIndex
|
return f.tailTargetBlock() <= lastBlockOfEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
// tailTargetBlock returns the target value for the tail block number according
|
// tailTargetBlock returns the target value for the tail block number according
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ func (ts *testSetup) setHistory(history uint64, noHistory bool) {
|
||||||
History: history,
|
History: history,
|
||||||
Disabled: noHistory,
|
Disabled: noHistory,
|
||||||
}
|
}
|
||||||
ts.fm = NewFilterMaps(ts.db, view, ts.params, config)
|
ts.fm = NewFilterMaps(ts.db, view, 0, 0, ts.params, config)
|
||||||
ts.fm.testDisableSnapshots = ts.testDisableSnapshots
|
ts.fm.testDisableSnapshots = ts.testDisableSnapshots
|
||||||
ts.fm.Start()
|
ts.fm.Start()
|
||||||
}
|
}
|
||||||
|
|
@ -420,7 +420,7 @@ func (tc *testChain) setTargetHead() {
|
||||||
if tc.ts.fm != nil {
|
if tc.ts.fm != nil {
|
||||||
if !tc.ts.fm.disabled {
|
if !tc.ts.fm.disabled {
|
||||||
//tc.ts.fm.targetViewCh <- NewChainView(tc, head.Number.Uint64(), head.Hash())
|
//tc.ts.fm.targetViewCh <- NewChainView(tc, head.Number.Uint64(), head.Hash())
|
||||||
tc.ts.fm.SetTargetView(NewChainView(tc, head.Number.Uint64(), head.Hash()))
|
tc.ts.fm.SetTarget(NewChainView(tc, head.Number.Uint64(), head.Hash()), 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue