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

Disable signature rule in IBD #579

Merged
merged 9 commits into from
Jun 18, 2021

Conversation

quantumagi
Copy link
Contributor

@quantumagi quantumagi commented Jun 16, 2021

@quantumagi quantumagi requested a review from fassadlr June 16, 2021 06:43
@fassadlr
Copy link
Contributor

@quantumagi please check as the solution doesnt build :)

Copy link
Contributor

@fassadlr fassadlr left a comment

Choose a reason for hiding this comment

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

Please fix build

@fassadlr
Copy link
Contributor

@noescape00 I believe you mentioned that this will suffice for us to increase the the sync speed a bit? Can we have your comments?

@noescape00
Copy link
Contributor

I'm against removing signature rule since this rule is the only thing that secures poa network.
However we can skip this rule prior to last checkpoint.

@fassadlr
Copy link
Contributor

@noescape00 what about skipping until the node is out of IBD?

@noescape00
Copy link
Contributor

noescape00 commented Jun 16, 2021

@noescape00 what about skipping until the node is out of IBD?

Yes. IBD is syncing prior to last checkpoint.

upd
it's incorrect, in our case ibd is also after last checkpoint

Copy link
Contributor

@noescape00 noescape00 left a comment

Choose a reason for hiding this comment

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

Instead of checking IsIBD check just if below last checkpoint.

if (this.chainState.ConsensusTip.Header.BlockTime < (this.dateTimeProvider.GetUtcNow().AddSeconds(-this.consensusSettings.MaxTipAge)))
            {
                if (!this.network.IsRegTest())
                    return true;

                // RegTest networks may experience long periods of no mining.
                // If this happens we don't want to be in IBD because we can't
                // mine new blocks in IBD and our nodes will be frozen at the
                // current height. Also note that in RegTest its typical for one
                // machine to control all (local) nodes and hence we are in control
                // of any side-effects that may arise from returning false here.
            }

Because of this code in IsInitialBlockDownload method we would be skipping signature rule after last checkpoint

Doing so will result in vulnerability when attacker provides chain that is correct prior to last checkpoint and then has more blocks than the correct chain but those are invalid.

@quantumagi
Copy link
Contributor Author

@noescape00 , i've made some changes based on your comment.

}

public override async Task RunAsync(RuleContext context)
{
// Only start validating at the last checkpoint block.
if (this.initialBlockDownloadState.IsInitialBlockDownload() && context.ValidationContext.ChainedHeaderToValidate.Height <= (this.lastCheckPoint?.Height ?? 0))
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to check IBD anymore if we are only checking the last checkpoint?

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO this if can be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's the better of the two options when one considers that a Guard.Assert(this.initialBlockDownloadState.IsInitialBlockDownload()) would be appropriate. We have to be sure that this is all happening in IBD as expected.

return;

// Ensure we're getting the right block at the last checkpoint height.
if (context.ValidationContext.ChainedHeaderToValidate.HashBlock != this.lastCheckPoint.Hash)
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this should be if the current block's height being validated matches the last checkpoint height, THEN check the hash?

@noescape00 can you confirm?

Copy link
Contributor Author

@quantumagi quantumagi Jun 17, 2021

Choose a reason for hiding this comment

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

This is already implicitly being checked by the preceding ifs - i.e. <= except <.

Copy link
Contributor

Choose a reason for hiding this comment

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

ChainedHeaderToValidate here might be any block below last checkpoint. So most of the time it wont be equal to last checkpoint hash.

Also no need to throw invalid header signature since it might be valid, just the block is not checkpointed.

So probably just ignore the sig validation rule below last checkpoint, everything else is not needed.

Copy link
Contributor Author

@quantumagi quantumagi Jun 17, 2021

Choose a reason for hiding this comment

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

ChainedHeaderToValidate here might be any block below last checkpoint. So most of the time it wont be equal to last checkpoint hash.

The code takes that into account by only checking the last checkpoint block. Look carefully: First I look at <= and then I return on the < case. Thereafter the code is only executing for the = case.

Note that blocks following the last checkpoint block can only be deemed valid if we fully validate the checkpoint block when we encounter it. Not only its height must match but also its hash. This way we know 100% we are not validating signatures on some fake chain perhaps built by a small subset of miners. I.e. it definitely won't hurt doing this check.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure why we need to do it here since there is a rule already that checks checkpoints

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you point me at which rule that is? I was trying to find a file named XXXRule.cs that contains "Checkpoint" and only found PosCoinviewRule - but that's not it, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

@quantumagi this is the code @noescape00 is referring to in CHT:

        private ConnectNewHeadersResult HandleCheckpointsHeader(ChainedHeader chainedHeader, ChainedHeader latestNewHeader, CheckpointInfo checkpoint, int peerId)
        {
            if (checkpoint.Hash != chainedHeader.HashBlock)
            {
                // Make sure that chain with invalid checkpoint in it is removed from the tree.
                // Otherwise a new peer may connect and present headers on top of invalid chain and we wouldn't recognize it.
                this.RemovePeerClaim(peerId, latestNewHeader);

                this.logger.LogDebug("Chained header '{0}' does not match checkpoint '{1}'.", chainedHeader, checkpoint.Hash);
                this.logger.LogTrace("(-)[INVALID_HEADER_NOT_MATCHING_CHECKPOINT]");
                throw new CheckpointMismatchException();
            }

Copy link
Contributor

@fassadlr fassadlr left a comment

Choose a reason for hiding this comment

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

2 small changes and then we good to go once build passes

fassadlr added a commit that referenced this pull request Aug 26, 2021
* Update PoAHeaderSignatureRule.cs

* Fix Build
fassadlr added a commit that referenced this pull request Aug 31, 2021
* Better collateral address checking (#670)

* Add collateral address check to GetModifiedFederation (#671)

* Remove logging from federation build logic

* Update all versions to 1.0.9.3

* Add null check in IdleMemberKicker (#673)

* Add null check in IdleMemberKicker

* Update IdleFederationMembersKicker.cs

* Bump version

* Add null check in IdleMemberKicker (#673) (#674)

* Add null check in IdleMemberKicker

* Update IdleFederationMembersKicker.cs

* Update all project versions to 1.0.9.4

* Bump SC versions

* Validate ChainStore tip on load (#600)

* Validate ChainStore tip on load

* Change comment

* Update tests

* Dispose IChainStore

* Bump version

* CirrusMain checkpoint 2_827_550 (#680)

* Bump version to 1.0.9.5

* Merge Disable signature rule in IBD #579 from release/1.1.0.0

Co-authored-by: quantumagi <someguy.fromafrica@gmail.com>
fassadlr added a commit that referenced this pull request Aug 31, 2021
* Better collateral address checking (#670)

* Add collateral address check to GetModifiedFederation (#671)

* Remove logging from federation build logic

* Update all versions to 1.0.9.3

* Add null check in IdleMemberKicker (#673)

* Add null check in IdleMemberKicker

* Update IdleFederationMembersKicker.cs

* Bump version

* Add null check in IdleMemberKicker (#673) (#674)

* Add null check in IdleMemberKicker

* Update IdleFederationMembersKicker.cs

* Update all project versions to 1.0.9.4

* Bump SC versions

* Validate ChainStore tip on load (#600)

* Validate ChainStore tip on load

* Change comment

* Update tests

* Dispose IChainStore

* Bump version

* CirrusMain checkpoint 2_827_550 (#680)

* Bump version to 1.0.9.5

* Merge Disable signature rule in IBD #579 from release/1.1.0.0

* UI SignalR improvements / Move UI notification outside of loop blocks (#686)

Co-authored-by: quantumagi <someguy.fromafrica@gmail.com>
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.

None yet

3 participants