-
Notifications
You must be signed in to change notification settings - Fork 20.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: fix chain indexer reorg bug #19748
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@@ -358,6 +359,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() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary to put the statement here? Since we will verify the validity of stored sections before processing anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, it does not matter really but still I would prefer not leaving the indexer in a bad state after detecting an error.
Could you please also fix the issue here https://github.com/ethereum/go-ethereum/blob/master/core/chain_indexer.go#L246 ?. The |
The chain_indexer_test seems to be broken due to this changes, weird thing is that the test breaks only when executed alone, but works when running the complete core tests...
It seems that when reverting:
Any ideas ? |
we met the same issue, the chain_indexer_test failed #20497 |
This PR fixes a bug in the chain indexer that caused repeated "chain reorged during section processing" errors under some rare circumstances.
https://github.com/ethereum/go-ethereum/blob/master/core/chain_indexer.go#L400
Here processSection checks for each processed header whether is parentHash equals the last block hash. The parent of the first block in a section is compared against the last section head which is passed as a parameter.
https://github.com/ethereum/go-ethereum/blob/master/core/chain_indexer.go#L333
The last section head is passed here which is assumed to be canonical bacause a reorg should theoretically trigger a rollback of stored sections. The problem is that this is not guaranteed to happen before the new section processing begins. If there is a stored section whose head does not match the most recent canonical hash at this point then processSection will fail but the invalid last stored section is never rolled back so processSection will try and fail again and again, assuming a wrong lastHead and failing on the first parent check.
In this fix verifyLastHead() always verifies whether the last stored section is still canonical and rolls it back if necessary. This prevents being stuck in this invalid state and as an extra bonus it always makes sure that the result of Sections() is up to date.
Fixes
#15169
#17227
#19711
#19720