Skip to content
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

Validate header chain in downloader #1222

Merged
merged 6 commits into from
Nov 8, 2018
Merged

Conversation

mkalinin
Copy link
Contributor

What's done

Fixes a problem that has been discovered on Ropsten net during the mess happened around Constantinople HF. The fix is covered with unit tests and ready for merge. Testing on Ropsten's data went well.

The problem

BlockDownloader didn't run header validations that depends on parent block (like difficulty check). These validations used to be run in BlockchainImpl before block started to be imported. Thus, if there is a peer with invalid chain in a list of active peers, BlockDownloader could stick to that chain and never do a re-branch and the sync gets stuck as a result.

The fix

Parent header checks have been moved to BlockDownloader and now all checks are run there. Hence, preventing BlockDownloader from going down the wrong chain.

@coveralls
Copy link

coveralls commented Oct 26, 2018

Coverage Status

Coverage decreased (-0.03%) to 56.764% when pulling 1166301 on fix/validate-header-chain into 561582b on develop.

Copy link
Collaborator

@zilm13 zilm13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.
Have you tested FastSync too?


private boolean isParentValid(BlockHeader header) {
Block parent = blockchain.getBlockByHash(header.getParentHash());
if (parent == null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we were getting exception in this case before
is it ok we will pass it since this change?
the only case when it's ok that we don't have parent is genesis.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure the block parent is in the blockchain already here? If it is still 'on the way' wouldn't this skip parent validation completely?

* Runs parent header validation and returns after first occurrence of invalid header
*/
ValidatedHeaders validateChain(List<HeaderElement> chain) {
if (chain.size() <= MAX_CHAIN_LEN || parentHeaderValidator == null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you, please, add comment why we could pass <= MAX_CHAIN_LEN

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add a comment. But this is a result of a trade off between bad design and changes in legacy code. And I think I've found the way out.

@@ -726,7 +726,6 @@ private boolean isValid(Repository repo, Block block) {
boolean isValid = true;

if (!block.isGenesis()) {
isValid = isValid(block.getHeader());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be it makes sense to leave this check if it's not too heavy?
Or leave it here by default and add a flag to skip the check as soon as it is not needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, I think I'll leave it here and revert related changes made in BlockLoader.

@mkalinin
Copy link
Contributor Author

mkalinin commented Nov 7, 2018

@Nashatyrev please, take a look again

@Nashatyrev
Copy link
Member

I like this variant much more.
Just added minor change to avoid a == null || a.isEmpty() pattern

@mkalinin mkalinin merged commit 7e3b9dd into develop Nov 8, 2018
@mkalinin mkalinin added this to the 1.9.0-Constantinople milestone Nov 8, 2018
@mkalinin mkalinin deleted the fix/validate-header-chain branch December 26, 2018 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants