consensus: fix addProposalBlockPart
* When create_empty_blocks=false, we don't enterPropose until we * receive a transaction, but if we then receive a complete proposal, * we should enterPrevote. A guard in addProposalBlockPart was checking if * step==Propose before calling enterPrevote, but we need it to be step<=Propose, * since we may not have seen a tx. * This was discovered by disabling mempool broadcast, sending txs to * peers one a time, and observing their consensus logs.
This commit is contained in:
parent
fa3bd05d44
commit
70d314312c
|
@ -624,7 +624,7 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) {
|
|||
err = cs.setProposal(msg.Proposal)
|
||||
case *BlockPartMessage:
|
||||
// if the proposal is complete, we'll enterPrevote or tryFinalizeCommit
|
||||
_, err = cs.addProposalBlockPart(msg.Height, msg.Part)
|
||||
_, err = cs.addProposalBlockPart(msg, peerID)
|
||||
if err != nil && msg.Round != cs.Round {
|
||||
cs.Logger.Debug("Received block part from wrong round", "height", cs.Height, "csRound", cs.Round, "blockRound", msg.Round)
|
||||
err = nil
|
||||
|
@ -1399,17 +1399,22 @@ func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error {
|
|||
|
||||
// NOTE: block is not necessarily valid.
|
||||
// Asynchronously triggers either enterPrevote (before we timeout of propose) or tryFinalizeCommit, once we have the full block.
|
||||
func (cs *ConsensusState) addProposalBlockPart(height int64, part *types.Part) (added bool, err error) {
|
||||
func (cs *ConsensusState) addProposalBlockPart(msg *BlockPartMessage, peerID p2p.ID) (added bool, err error) {
|
||||
height, round, part := msg.Height, msg.Round, msg.Part
|
||||
|
||||
// Blocks might be reused, so round mismatch is OK
|
||||
if cs.Height != height {
|
||||
cs.Logger.Debug("Received block part from wrong height", "height", height)
|
||||
cs.Logger.Debug("Received block part from wrong height", "height", height, "round", round)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// We're not expecting a block part.
|
||||
if cs.ProposalBlockParts == nil {
|
||||
cs.Logger.Info("Received a block part when we're not expecting any", "height", height)
|
||||
return false, nil // TODO: bad peer? Return error?
|
||||
// NOTE: this can happen when we've gone to a higher round and
|
||||
// then receive parts from the previous round - not necessarily a bad peer.
|
||||
cs.Logger.Info("Received a block part when we're not expecting any",
|
||||
"height", height, "round", round, "index", part.Index, "peer", peerID)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
added, err = cs.ProposalBlockParts.AddPart(part)
|
||||
|
@ -1443,7 +1448,7 @@ func (cs *ConsensusState) addProposalBlockPart(height int64, part *types.Part) (
|
|||
// procedure at this point.
|
||||
}
|
||||
|
||||
if cs.Step == cstypes.RoundStepPropose && cs.isProposalComplete() {
|
||||
if cs.Step <= cstypes.RoundStepPropose && cs.isProposalComplete() {
|
||||
// Move onto the next step
|
||||
cs.enterPrevote(height, cs.Round)
|
||||
} else if cs.Step == cstypes.RoundStepCommit {
|
||||
|
|
Loading…
Reference in New Issue