-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Force consensus loss for parent block if its hash mismatches parent_hash #1657
Conversation
44b2ddd
to
5b0618c
Compare
SELECT b0.number - 1 FROM "blocks" AS b0 | ||
LEFT JOIN "blocks" AS b1 ON (b0."parent_hash" = b1."hash") AND b1."consensus" | ||
WHERE b0."number" > 0 AND b0."consensus" AND b1."hash" IS NULL | ||
); |
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.
@goodsoft
I think we should add at the end and consensus = true;
clause to be sure that b0.number - 1
has not already marked as non-consensus before. Otherwise, the where
query will return non-empty list every time
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.
And I believe we should also update updated_at
in the query above
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.
Done.
initial = from(b in Block, where: false) | ||
|
||
Enum.reduce(blocks_changes, initial, fn %{consensus: consensus, parent_hash: parent_hash, number: number}, acc -> | ||
case consensus do |
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.
I think it is much cleaner to use if
instead of case
here
if consensus do
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.
I like copy-pasting code from neighboring functions :D
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.
one style comment. otherwise looks good
8e93c6a
to
5b03ebc
Compare
Fixes #1644 When reorg occurs and the older of new blocks fails to be imported, the old consensus block remains in the database. Catchup fetcher ignores it, and we get a discontinuity in the main chain. This commit adds an additional consensus loss step during block import: the parent block with hash not matching parent_hash of current block is marked non-consensus, thus creating a hole in main chain, forcing catchup fetcher to retry fetching it.
5b03ebc
to
f5268fc
Compare
As a result of #1657 out-of-place parent blocks are marked as non-consensus more reliably, i.e. they will eventually be fetched even if first attempt is unsuccessful. The `ConsensusEnsurer` module, on the contrary, only tried refetching block once, and left it as-is if the refetch failed. Now it is not needed anymore.
As a result of #1657 out-of-place parent blocks are marked as non-consensus more reliably, i.e. they will eventually be fetched even if first attempt is unsuccessful. The `ConsensusEnsurer` module, on the contrary, only tried refetching block once, and left it as-is if the refetch failed. Now it is not needed anymore.
As a result of #1657 out-of-place parent blocks are marked as non-consensus more reliably, i.e. they will eventually be fetched even if first attempt is unsuccessful. The `ConsensusEnsurer` module, on the contrary, only tried refetching block once, and left it as-is if the refetch failed. Now it is not needed anymore.
As a result of #1657 out-of-place parent blocks are marked as non-consensus more reliably, i.e. they will eventually be fetched even if first attempt is unsuccessful. The `ConsensusEnsurer` module, on the contrary, only tried refetching block once, and left it as-is if the refetch failed. Now it is not needed anymore.
As a result of #1657 out-of-place parent blocks are marked as non-consensus more reliably, i.e. they will eventually be fetched even if first attempt is unsuccessful. The `ConsensusEnsurer` module, on the contrary, only tried refetching block once, and left it as-is if the refetch failed. Now it is not needed anymore.
Fixes #1644
When reorg occurs and the older of new blocks fails to be imported, the old consensus block remains in the database. Catchup fetcher ignores it, and we get a discontinuity in the main chain.
This commit adds an additional consensus loss step during block import: the parent block with hash not matching parent_hash of current block is marked non-consensus, thus creating a hole in main chain, forcing catchup fetcher to retry fetching it.
Upgrading
A query from
scripts/20190326202921_lose_consensus_for_invalid_blocks.sql
should be run to mark existing invalid blocks as non-consensus.