mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core: fix chain indexer reorg bug
This commit is contained in:
parent
25c3282cf1
commit
48c9d284c1
1 changed files with 17 additions and 2 deletions
|
|
@ -323,6 +323,7 @@ func (c *ChainIndexer) updateLoop() {
|
||||||
updated = time.Now()
|
updated = time.Now()
|
||||||
}
|
}
|
||||||
// Cache the current section count and head to allow unlocking the mutex
|
// Cache the current section count and head to allow unlocking the mutex
|
||||||
|
c.verifyLastHead()
|
||||||
section := c.storedSections
|
section := c.storedSections
|
||||||
var oldHead common.Hash
|
var oldHead common.Hash
|
||||||
if section > 0 {
|
if section > 0 {
|
||||||
|
|
@ -342,8 +343,8 @@ func (c *ChainIndexer) updateLoop() {
|
||||||
}
|
}
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
|
|
||||||
// If processing succeeded and no reorgs occcurred, mark the section completed
|
// If processing succeeded and no reorgs occurred, mark the section completed
|
||||||
if err == nil && oldHead == c.SectionHead(section-1) {
|
if err == nil && (section == 0 || oldHead == c.SectionHead(section-1)) {
|
||||||
c.setSectionHead(section, newHead)
|
c.setSectionHead(section, newHead)
|
||||||
c.setValidSections(section + 1)
|
c.setValidSections(section + 1)
|
||||||
if c.storedSections == c.knownSections && updating {
|
if c.storedSections == c.knownSections && updating {
|
||||||
|
|
@ -358,6 +359,7 @@ func (c *ChainIndexer) updateLoop() {
|
||||||
} else {
|
} else {
|
||||||
// If processing failed, don't retry until further notification
|
// If processing failed, don't retry until further notification
|
||||||
c.log.Debug("Chain index processing failed", "section", section, "err", err)
|
c.log.Debug("Chain index processing failed", "section", section, "err", err)
|
||||||
|
c.verifyLastHead()
|
||||||
c.knownSections = c.storedSections
|
c.knownSections = c.storedSections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -411,6 +413,18 @@ func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (com
|
||||||
return lastHead, nil
|
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
|
// Sections returns the number of processed sections maintained by the indexer
|
||||||
// and also the information about the last header indexed for potential canonical
|
// and also the information about the last header indexed for potential canonical
|
||||||
// verifications.
|
// verifications.
|
||||||
|
|
@ -418,6 +432,7 @@ func (c *ChainIndexer) Sections() (uint64, uint64, common.Hash) {
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
|
c.verifyLastHead()
|
||||||
return c.storedSections, c.storedSections*c.sectionSize - 1, c.SectionHead(c.storedSections - 1)
|
return c.storedSections, c.storedSections*c.sectionSize - 1, c.SectionHead(c.storedSections - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue