Skip to content

Commit

Permalink
fix(consensus): ValidBlock must be equal LockedBlock
Browse files Browse the repository at this point in the history
  • Loading branch information
lklimek committed Jan 15, 2024
1 parent f75ae58 commit 51317c5
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 22 deletions.
31 changes: 26 additions & 5 deletions internal/consensus/state_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,30 @@ func (s *StateData) proposalIsTimely() bool {
}

func (s *StateData) updateValidBlock() {
// we only update valid block if it's not set already; otherwise we might overwrite the recv time
if !s.ValidBlock.HashesTo(s.ProposalBlock.Hash()) {
s.ValidBlock = s.ProposalBlock
s.ValidBlockRecvTime = s.ProposalReceiveTime
s.ValidBlockParts = s.ProposalBlockParts
} else {
s.logger.Debug("valid block is already up to date, not updating",
"proposal_block", s.ProposalBlock.Hash(),
"proposal_round", s.Round,
"valid_block", s.ValidBlock.Hash(),
"valid_block_round", s.ValidRound,
)
}

s.ValidRound = s.Round
s.ValidBlock = s.ProposalBlock
s.ValidBlockRecvTime = s.ProposalReceiveTime
s.ValidBlockParts = s.ProposalBlockParts
}

// Locks the proposed block. Note that it also updates ValidBlock.
func (s *StateData) updateLockedBlock() {
s.LockedRound = s.Round
s.LockedBlock = s.ProposalBlock
s.LockedBlockParts = s.ProposalBlockParts

s.updateValidBlock()
}

func (s *StateData) verifyCommit(commit *types.Commit, peerID types.NodeID, ignoreProposalBlock bool) (verified bool, err error) {
Expand Down Expand Up @@ -458,10 +478,11 @@ func (s *StateData) isValidForPrevote() error {
if !s.Proposal.Timestamp.Equal(s.ProposalBlock.Header.Time) {
return errPrevoteTimestampNotEqual
}
//TODO: Remove this temporary fix when the complete solution is ready. See #8739
if !s.replayMode && s.Proposal.POLRound == -1 && s.LockedRound == -1 && !s.proposalIsTimely() {

if !s.replayMode && !s.proposalIsTimely() {
return errPrevoteProposalNotTimely
}

// Validate proposal core chain lock
err := sm.ValidateBlockChainLock(s.state, s.ProposalBlock)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions internal/consensus/state_enter_precommit.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ func (c *EnterPrecommitAction) Execute(ctx context.Context, stateEvent StateEven
// Validate the block.
c.blockExec.mustValidate(ctx, stateData)

stateData.LockedRound = round
stateData.LockedBlock = stateData.ProposalBlock
stateData.LockedBlockParts = stateData.ProposalBlockParts
stateData.updateLockedBlock()

c.eventPublisher.PublishLockEvent(stateData.RoundState)
c.voteSigner.signAddVote(ctx, stateData, tmproto.PrecommitType, blockID)

stateData.updateValidBlock()
return nil
}

Expand Down
19 changes: 5 additions & 14 deletions internal/consensus/state_proposaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,12 @@ func (p *Proposaler) Set(proposal *types.Proposal, receivedAt time.Time, rs *cst

// Create creates, sings and sends a created proposal to the queue
//
// We prioritize LockedBlock. If it's not set, then we use ValidBlock.
// To create a proposal is used RoundState.ValidBlock if it isn't nil and valid, otherwise create a new one
func (p *Proposaler) Create(ctx context.Context, height int64, round int32, rs *cstypes.RoundState) error {
create := false
// If we are locked on some block, propose that.
// We don't check the timestamp in this case, as the block is already valid
block, blockParts := rs.LockedBlock, rs.LockedBlockParts
// when no locked block, use valid block
if block == nil || blockParts == nil {
block, blockParts = rs.ValidBlock, rs.ValidBlockParts
create = !p.checkValidBlock(rs)
}

// Create a block
if create {
// Create a block.
// Note that we only create a block if we don't have a valid block already.
block, blockParts := rs.ValidBlock, rs.ValidBlockParts
if !p.checkValidBlock(rs) {
var err error
start := time.Now()
block, blockParts, err = p.createProposalBlock(ctx, round, rs)
Expand Down Expand Up @@ -183,7 +174,7 @@ func (p *Proposaler) checkValidBlock(rs *cstypes.RoundState) bool {
}
if !rs.ValidBlock.IsTimely(rs.ValidBlockRecvTime, sp, rs.ValidRound) {
p.logger.Error(
"proposal block is outdated",
"proposal block is not timely",
"height", rs.Height,
"round", rs.ValidRound,
"received", rs.ValidBlockRecvTime,
Expand Down

0 comments on commit 51317c5

Please sign in to comment.