aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorFelföldi Zsolt <zsfelfoldi@gmail.com>2019-07-02 20:30:32 +0800
committerPéter Szilágyi <peterke@gmail.com>2019-07-02 20:30:32 +0800
commit32273df0eafbbd829b7e6b6758730a5bb0ab59cb (patch)
tree0f6ada8d6c5d3a1a10daae2611666d38608ea4b3 /core
parentde6facb966060b4814f5a3c0c3a454602330248e (diff)
downloadgo-tangerine-32273df0eafbbd829b7e6b6758730a5bb0ab59cb.tar
go-tangerine-32273df0eafbbd829b7e6b6758730a5bb0ab59cb.tar.gz
go-tangerine-32273df0eafbbd829b7e6b6758730a5bb0ab59cb.tar.bz2
go-tangerine-32273df0eafbbd829b7e6b6758730a5bb0ab59cb.tar.lz
go-tangerine-32273df0eafbbd829b7e6b6758730a5bb0ab59cb.tar.xz
go-tangerine-32273df0eafbbd829b7e6b6758730a5bb0ab59cb.tar.zst
go-tangerine-32273df0eafbbd829b7e6b6758730a5bb0ab59cb.zip
core: fix chain indexer reorg bug (#19748)
* core: fix chain indexer reorg bug * core: prevent reverting valid section when reorg happens
Diffstat (limited to 'core')
-rw-r--r--core/chain_indexer.go21
1 files changed, 18 insertions, 3 deletions
diff --git a/core/chain_indexer.go b/core/chain_indexer.go
index 80062714a..c82febb54 100644
--- a/core/chain_indexer.go
+++ b/core/chain_indexer.go
@@ -244,7 +244,7 @@ func (c *ChainIndexer) newHead(head uint64, reorg bool) {
// If a reorg happened, invalidate all sections until that point
if reorg {
// Revert the known section number to the reorg point
- known := head / c.sectionSize
+ known := (head + 1) / c.sectionSize
stored := known
if known < c.checkpointSections {
known = 0
@@ -324,6 +324,7 @@ func (c *ChainIndexer) updateLoop() {
updated = time.Now()
}
// Cache the current section count and head to allow unlocking the mutex
+ c.verifyLastHead()
section := c.storedSections
var oldHead common.Hash
if section > 0 {
@@ -343,8 +344,8 @@ func (c *ChainIndexer) updateLoop() {
}
c.lock.Lock()
- // If processing succeeded and no reorgs occcurred, mark the section completed
- if err == nil && oldHead == c.SectionHead(section-1) {
+ // If processing succeeded and no reorgs occurred, mark the section completed
+ if err == nil && (section == 0 || oldHead == c.SectionHead(section-1)) {
c.setSectionHead(section, newHead)
c.setValidSections(section + 1)
if c.storedSections == c.knownSections && updating {
@@ -359,6 +360,7 @@ func (c *ChainIndexer) updateLoop() {
} else {
// If processing failed, don't retry until further notification
c.log.Debug("Chain index processing failed", "section", section, "err", err)
+ c.verifyLastHead()
c.knownSections = c.storedSections
}
}
@@ -412,6 +414,18 @@ func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (com
return lastHead, nil
}
+// verifyLastHead compares last stored section head with the corresponding block hash in the
+// actual canonical chain and rolls back reorged sections if necessary to ensure that stored
+// sections are all valid
+func (c *ChainIndexer) verifyLastHead() {
+ for c.storedSections > 0 {
+ if c.SectionHead(c.storedSections-1) == rawdb.ReadCanonicalHash(c.chainDb, c.storedSections*c.sectionSize-1) {
+ return
+ }
+ c.setValidSections(c.storedSections - 1)
+ }
+}
+
// Sections returns the number of processed sections maintained by the indexer
// and also the information about the last header indexed for potential canonical
// verifications.
@@ -419,6 +433,7 @@ func (c *ChainIndexer) Sections() (uint64, uint64, common.Hash) {
c.lock.Lock()
defer c.lock.Unlock()
+ c.verifyLastHead()
return c.storedSections, c.storedSections*c.sectionSize - 1, c.SectionHead(c.storedSections - 1)
}