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

consensus: correctly save reference to previous height precommits #9760

Merged
merged 3 commits into from
Nov 28, 2022

Conversation

williambanfield
Copy link
Contributor

@williambanfield williambanfield commented Nov 23, 2022

This change reduces the number of Precommit messages sent to peers by 50%.

During the ApplyNewRoundStepMessage, we update the known state of the peer sending us the message.

We set the value of ps.PRS.Precommits to nil in this method if the peer is entering a new height or round.

ps.PRS.Precommits = nil

We then assign ps.PRS.LastCommit = ps.PRS.Precommits if the peer is entering a new height only - this does not happen during just a round change. This therefore results in ps.PRS.LastCommit having the value nil.

When the LastCommit bit field is seen as nil in the reactor, an empty bit field is initialized.

ps.PRS.LastCommit = bits.NewBitArray(numValidators)

The code responsible for gossiping votes from the previous height uses this LastCommit value and, seeing an empty LastCommit will resend every Precommit from the previous height since it lost the information it previously had detailing which precommits from the previous height the peer had.

This can be seen in the code responsible for gossiping precommits from the previous height:

if ps.PickSendVote(rs.LastCommit) {

Where this code grabs the, previously nil, LastCommit bit field:

if ps.PRS.Height == height+1 {
if ps.PRS.LastCommitRound == round {
switch votesType {
case tmproto.PrevoteType:
return nil
case tmproto.PrecommitType:
return ps.PRS.LastCommit
}
}


PR checklist

  • Tests written/updated, or no tests needed
  • CHANGELOG_PENDING.md updated, or no changelog entry needed
  • Updated relevant documentation (docs/) and code comments, or no
    documentation updates needed

@williambanfield williambanfield requested a review from a team November 23, 2022 23:52
@williambanfield williambanfield changed the title consensus: correctly save reference to previous round precommits consensus: correctly save reference to previous height precommits Nov 24, 2022
Copy link
Contributor

@cmwaters cmwaters left a comment

Choose a reason for hiding this comment

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

Nice catch 🎉

We should definitely backport this as well (and add a changelog)

@thanethomson thanethomson added S:backport-to-v0.34.x Tell mergify to backport the PR to v0.34.x S:backport-to-v0.37.x Tell mergify to backport the PR to v0.37.x labels Nov 24, 2022
@williambanfield williambanfield added the S:automerge Automatically merge PR when requirements pass label Nov 28, 2022
@mergify mergify bot merged commit da204d3 into main Nov 28, 2022
@mergify mergify bot deleted the wb/reduce-precommit-sends branch November 28, 2022 20:13
mergify bot pushed a commit that referenced this pull request Nov 28, 2022
)

This change reduces the number of Precommit messages sent to peers by 50%.

During the `ApplyNewRoundStepMessage`, we update the known state of the peer sending us the message.

We set the value of `ps.PRS.Precommits` to nil in this method if the peer is entering a new height or round.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1368

We then assign `ps.PRS.LastCommit = ps.PRS.Precommits` if the peer is entering a new height only - this does not happen during just a round change. This therefore results in `ps.PRS.LastCommit` having the value `nil`.

When the `LastCommit` bit field is seen as `nil` in the reactor, an empty bit field is initialized.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1273

The code responsible for gossiping votes from the previous height uses this `LastCommit` value and, seeing an empty `LastCommit` will resend every `Precommit` from the previous height since it lost the information it previously had detailing which precommits from the previous height the peer had.

This can be seen in the code responsible for gossiping precommits from the previous height:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L773

Where this code grabs the, previously `nil`, `LastCommit` bit field:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1204-L1212

---

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed

(cherry picked from commit da204d3)

# Conflicts:
#	CHANGELOG_PENDING.md
mergify bot pushed a commit that referenced this pull request Nov 28, 2022
)

This change reduces the number of Precommit messages sent to peers by 50%.

During the `ApplyNewRoundStepMessage`, we update the known state of the peer sending us the message.

We set the value of `ps.PRS.Precommits` to nil in this method if the peer is entering a new height or round.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1368

We then assign `ps.PRS.LastCommit = ps.PRS.Precommits` if the peer is entering a new height only - this does not happen during just a round change. This therefore results in `ps.PRS.LastCommit` having the value `nil`.

When the `LastCommit` bit field is seen as `nil` in the reactor, an empty bit field is initialized.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1273

The code responsible for gossiping votes from the previous height uses this `LastCommit` value and, seeing an empty `LastCommit` will resend every `Precommit` from the previous height since it lost the information it previously had detailing which precommits from the previous height the peer had.

This can be seen in the code responsible for gossiping precommits from the previous height:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L773

Where this code grabs the, previously `nil`, `LastCommit` bit field:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1204-L1212

---

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed

(cherry picked from commit da204d3)

# Conflicts:
#	CHANGELOG_PENDING.md
williambanfield added a commit that referenced this pull request Nov 28, 2022
…ckport #9760) (#9775)

* consensus: correctly save reference to previous height precommits (#9760)

This change reduces the number of Precommit messages sent to peers by 50%.

During the `ApplyNewRoundStepMessage`, we update the known state of the peer sending us the message.

We set the value of `ps.PRS.Precommits` to nil in this method if the peer is entering a new height or round.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1368

We then assign `ps.PRS.LastCommit = ps.PRS.Precommits` if the peer is entering a new height only - this does not happen during just a round change. This therefore results in `ps.PRS.LastCommit` having the value `nil`.

When the `LastCommit` bit field is seen as `nil` in the reactor, an empty bit field is initialized.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1273

The code responsible for gossiping votes from the previous height uses this `LastCommit` value and, seeing an empty `LastCommit` will resend every `Precommit` from the previous height since it lost the information it previously had detailing which precommits from the previous height the peer had.

This can be seen in the code responsible for gossiping precommits from the previous height:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L773

Where this code grabs the, previously `nil`, `LastCommit` bit field:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1204-L1212

---

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed

(cherry picked from commit da204d3)

# Conflicts:
#	CHANGELOG_PENDING.md

* changelog

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: William Banfield <wbanfield@gmail.com>
williambanfield added a commit that referenced this pull request Nov 28, 2022
…ckport #9760) (#9776)

* consensus: correctly save reference to previous height precommits (#9760)

This change reduces the number of Precommit messages sent to peers by 50%.

During the `ApplyNewRoundStepMessage`, we update the known state of the peer sending us the message.

We set the value of `ps.PRS.Precommits` to nil in this method if the peer is entering a new height or round.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1368

We then assign `ps.PRS.LastCommit = ps.PRS.Precommits` if the peer is entering a new height only - this does not happen during just a round change. This therefore results in `ps.PRS.LastCommit` having the value `nil`.

When the `LastCommit` bit field is seen as `nil` in the reactor, an empty bit field is initialized.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1273

The code responsible for gossiping votes from the previous height uses this `LastCommit` value and, seeing an empty `LastCommit` will resend every `Precommit` from the previous height since it lost the information it previously had detailing which precommits from the previous height the peer had.

This can be seen in the code responsible for gossiping precommits from the previous height:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L773

Where this code grabs the, previously `nil`, `LastCommit` bit field:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1204-L1212

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: William Banfield <wbanfield@gmail.com>
@ValarDragon
Copy link
Contributor

Awesome, nice job!

@thanethomson thanethomson mentioned this pull request Dec 14, 2022
16 tasks
thanethomson added a commit that referenced this pull request Dec 21, 2022
thanethomson added a commit that referenced this pull request Dec 22, 2022
thanethomson added a commit to informalsystems/tendermint that referenced this pull request Feb 3, 2023
* Revert "Fixed ordering of match.events in light client RPC (tendermint#9877)"

* Revert "state/kvindexer: associate event attributes with events (tendermint#9759)"

* Revert "consensus: correctly save reference to previous height precommits (backport tendermint#9760) (tendermint#9776)"

* add peer gossip sleep (tendermint#241) (tendermint#245)

* add peer gossip sleep

* add changelog

* Update .changelog/unreleased/bug-fixes/4-busy-loop-send-block-part.md

Co-authored-by: Jasmina Malicevic <jasmina.dustinac@gmail.com>

* Update .changelog/unreleased/bug-fixes/4-busy-loop-send-block-part.md

---------

Co-authored-by: jhernandezb <contact@jhernandez.me>
Co-authored-by: Jasmina Malicevic <jasmina.dustinac@gmail.com>
(cherry picked from commit 5954e75)

Co-authored-by: Sergio Mena <sergio@informal.systems>

* Build changelog for v0.34.25 release

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Bump version

---------

Signed-off-by: Thane Thomson <connect@thanethomson.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Thane Thomson <connect@thanethomson.com>
adrianbrink pushed a commit to heliaxdev/tendermint that referenced this pull request May 23, 2023
…ckport tendermint#9760) (#214)

* consensus: correctly save reference to previous height precommits (backport tendermint#9760) (tendermint#9775)

* consensus: correctly save reference to previous height precommits (tendermint#9760)

This change reduces the number of Precommit messages sent to peers by 50%.

During the `ApplyNewRoundStepMessage`, we update the known state of the peer sending us the message.

We set the value of `ps.PRS.Precommits` to nil in this method if the peer is entering a new height or round.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1368

We then assign `ps.PRS.LastCommit = ps.PRS.Precommits` if the peer is entering a new height only - this does not happen during just a round change. This therefore results in `ps.PRS.LastCommit` having the value `nil`.

When the `LastCommit` bit field is seen as `nil` in the reactor, an empty bit field is initialized.
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1273

The code responsible for gossiping votes from the previous height uses this `LastCommit` value and, seeing an empty `LastCommit` will resend every `Precommit` from the previous height since it lost the information it previously had detailing which precommits from the previous height the peer had.

This can be seen in the code responsible for gossiping precommits from the previous height:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L773

Where this code grabs the, previously `nil`, `LastCommit` bit field:
https://github.com/tendermint/tendermint/blob/34ca3fb4741cdb205a4714d345218a0d5e9fefd0/consensus/reactor.go#L1204-L1212

---

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed

(cherry picked from commit da204d3)

* changelog

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: William Banfield <wbanfield@gmail.com>

* Applied changes from 9760

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: William Banfield <wbanfield@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S:automerge Automatically merge PR when requirements pass S:backport-to-v0.34.x Tell mergify to backport the PR to v0.34.x S:backport-to-v0.37.x Tell mergify to backport the PR to v0.37.x
Projects
Status: Done/Merged
Development

Successfully merging this pull request may close these issues.

4 participants