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

Add certificates to Istanbul BFT messages for liveness #200

Closed
wants to merge 32 commits into from

Conversation

asaj
Copy link
Contributor

@asaj asaj commented May 20, 2019

Description

This PR removes the locking mechanism in IBFT and adds:

  • Optional PREPARED certificates to ROUND CHANGE messages, which are included when the node has seen 2F+1 PREPARE/COMMIT messages or a PREPARED certificate for this sequence.
  • ROUND CHANGE certificates to PREPREPARE messages, which are required for rounds > 0. If any of the messages in this certificate contain a PREPARED certificate, the PREPREPARE must propose the PREPARED block.

This addresses a bug in which F nodes could lock onto block A, while 2F nodes could lock onto block B, causing a permanent loss of liveness.

Tested

Unit tests

Other changes

  • Verify the CommittedSeal included in COMMIT messages

Related issues

Copy link
Contributor

@nambrot nambrot left a comment

Choose a reason for hiding this comment

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

Amazing!

consensus/istanbul/core/preprepare.go Outdated Show resolved Hide resolved
var num int
if rc.HasPreparedCertificate() {
if err := c.handlePreparedCertificate(rc.PreparedCertificate); err != nil {
// TODO(asa): Should we still accept the round change message without the certificate if this fails?
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's probably find to ignore, as the round change message itself is technically invalid?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My hunch is that it's fine either way

consensus/istanbul/core/roundchange.go Show resolved Hide resolved
}

func (s *roundState) GetLockedHash() common.Hash {
// TODO(asa): Should we use COMMITs as well in the prepared certificate if they're available?
Copy link
Contributor

Choose a reason for hiding this comment

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

I think so because they form the basis for why a validator themselves would have sent out a COMMIT? Otherwise faulty validators could send out COMMIT, causing f+1 validators to advance, without ever producing a valid prepareCertificate?

consensus/istanbul/core/roundchange.go Show resolved Hide resolved
consensus/istanbul/core/prepare.go Show resolved Hide resolved
}

seen := make(map[common.Address]bool)
for _, message := range preparedCertificate.PrepareMessages {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we skip the processing if the current prepareCertificate has the same proposal as this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe? It's possible you have a PREPARED certificate already because you heard 2f+1 PREPARE/COMMIT messages but no one else did, and the next proposer put out a PREPREPARE with an invalid PREPARED certificate but with the same proposal. With your proposal, you would still accept, while everyone else would reject, which I suppose could be okay but it feels safer to reject PREPREPAREs with invalid PREPARED certificates

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah great point. I guess I wonder how big the processing burden is anyways, my first intuition was that checking O(n) round changes messages that contain the same O(n) PREPARE certificates would be wasteful, but maybe it doesn't matter. If it does, i guess we could dedupe against the hash of the certificate?

consensus/istanbul/core/roundchange.go Outdated Show resolved Hide resolved
@nambrot nambrot removed their assignment May 21, 2019
@asaj asaj self-assigned this May 21, 2019
@asaj asaj assigned nambrot and unassigned asaj May 21, 2019
@asaj
Copy link
Contributor Author

asaj commented May 21, 2019

Note the addition of:

  • Verify the CommittedSeal included in COMMIT messages

Copy link
Contributor

@nambrot nambrot left a comment

Choose a reason for hiding this comment

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

What a feat! It looks good to me, but given the nature of the change of course it is highly recommended for someone else to take a look as well

@nambrot nambrot assigned asaj and unassigned nambrot May 24, 2019
@asaj
Copy link
Contributor Author

asaj commented May 24, 2019

What a feat! It looks good to me, but given the nature of the change of course it is highly recommended for someone else to take a look as well

+1 to this. The plan is to merge it with Tim's changes and throw a bunch of faulty nodes at it and make sure everything runs smoothly

@asaj asaj removed their assignment May 24, 2019
@codecov
Copy link

codecov bot commented May 28, 2019

Codecov Report

Merging #200 into master will decrease coverage by <.01%.
The diff coverage is 52.24%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #200      +/-   ##
==========================================
- Coverage   52.88%   52.87%   -0.01%     
==========================================
  Files         580      580              
  Lines       69931    70098     +167     
==========================================
+ Hits        36982    37064      +82     
- Misses      29960    30025      +65     
- Partials     2989     3009      +20
Impacted Files Coverage Δ
consensus/istanbul/core/types.go 73.68% <ø> (-10.53%) ⬇️
consensus/istanbul/types.go 4.72% <0%> (-10.28%) ⬇️
consensus/istanbul/backend/backend.go 44.44% <0%> (-2.34%) ⬇️
consensus/istanbul/core/preprepare.go 70.76% <100%> (+1.41%) ⬆️
consensus/istanbul/core/handler.go 83.17% <100%> (+10.28%) ⬆️
consensus/istanbul/core/request.go 73.46% <100%> (ø) ⬆️
consensus/istanbul/core/message_set.go 71.11% <100%> (ø) ⬆️
consensus/istanbul/core/backlog.go 86.2% <100%> (ø) ⬆️
consensus/istanbul/core/commit.go 63.15% <55.55%> (-7.96%) ⬇️
consensus/istanbul/core/prepare.go 64.47% <56.81%> (-15.53%) ⬇️
... and 21 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d3f631b...debd957. Read the comment docs.

@asaj asaj assigned asaj and unassigned timmoreton and kevjue Jun 12, 2019
@asaj asaj mentioned this pull request Jun 14, 2019
@asaj
Copy link
Contributor Author

asaj commented Aug 16, 2019

Closing as this has been replaced by #366

@asaj asaj closed this Aug 16, 2019
@mcortesi mcortesi deleted the asaj/liveness branch December 4, 2019 23: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.

Devs SBAT be sure of Istanbul liveness
4 participants