@ -586,6 +586,7 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) {
// if the proposal is complete, we'll enterPrevote or tryFinalizeCommit
_ , err = cs . addProposalBlockPart ( msg . Height , msg . Part )
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
}
case * VoteMessage :
@ -610,7 +611,7 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) {
cs . Logger . Error ( "Unknown msg type" , reflect . TypeOf ( msg ) )
}
if err != nil {
cs . Logger . Error ( "Error with msg" , "type" , reflect . TypeOf ( msg ) , "peer" , peerID , "err" , err , "msg" , msg )
cs . Logger . Error ( "Error with msg" , "height" , cs . Height , "round" , cs . Round , " type" , reflect . TypeOf ( msg ) , "peer" , peerID , "err" , err , "msg" , msg )
}
}
@ -667,16 +668,18 @@ func (cs *ConsensusState) handleTxsAvailable(height int64) {
// Enter: +2/3 prevotes any or +2/3 precommits for block or any from (height, round)
// NOTE: cs.StartTime was already set for height.
func ( cs * ConsensusState ) enterNewRound ( height int64 , round int ) {
logger := cs . Logger . With ( "height" , height , "round" , round )
if cs . Height != height || round < cs . Round || ( cs . Round == round && cs . Step != cstypes . RoundStepNewHeight ) {
cs . Logger . Debug ( cmn . Fmt ( "enterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Debug ( cmn . Fmt ( "enterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
return
}
if now := time . Now ( ) ; cs . StartTime . After ( now ) {
cs . L ogger. Info ( "Need to set a buffer and log message here for sanity." , "startTime" , cs . StartTime , "now" , now )
l ogger. Info ( "Need to set a buffer and log message here for sanity." , "startTime" , cs . StartTime , "now" , now )
}
cs . L ogger. Info ( cmn . Fmt ( "enterNewRound(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Info ( cmn . Fmt ( "enterNewRound(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
// Increment validators if necessary
validators := cs . Validators
@ -695,6 +698,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
// and meanwhile we might have received a proposal
// for round 0.
} else {
logger . Info ( "Resetting Proposal info" )
cs . Proposal = nil
cs . ProposalBlock = nil
cs . ProposalBlockParts = nil
@ -757,11 +761,13 @@ func (cs *ConsensusState) proposalHeartbeat(height int64, round int) {
// Enter (CreateEmptyBlocks, CreateEmptyBlocksInterval > 0 ): after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval
// Enter (!CreateEmptyBlocks) : after enterNewRound(height,round), once txs are in the mempool
func ( cs * ConsensusState ) enterPropose ( height int64 , round int ) {
logger := cs . Logger . With ( "height" , height , "round" , round )
if cs . Height != height || round < cs . Round || ( cs . Round == round && cstypes . RoundStepPropose <= cs . Step ) {
cs . Logger . Debug ( cmn . Fmt ( "enterPropose(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Debug ( cmn . Fmt ( "enterPropose(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
return
}
cs . L ogger. Info ( cmn . Fmt ( "enterPropose(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Info ( cmn . Fmt ( "enterPropose(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
defer func ( ) {
// Done enterPropose:
@ -781,22 +787,22 @@ func (cs *ConsensusState) enterPropose(height int64, round int) {
// Nothing more to do if we're not a validator
if cs . privValidator == nil {
cs . L ogger. Debug ( "This node is not a validator" )
l ogger. Debug ( "This node is not a validator" )
return
}
// if not a validator, we're done
if ! cs . Validators . HasAddress ( cs . privValidator . GetAddress ( ) ) {
cs . L ogger. Debug ( "This node is not a validator" , "addr" , cs . privValidator . GetAddress ( ) , "vals" , cs . Validators )
l ogger. Debug ( "This node is not a validator" , "addr" , cs . privValidator . GetAddress ( ) , "vals" , cs . Validators )
return
}
cs . L ogger. Debug ( "This node is a validator" )
l ogger. Debug ( "This node is a validator" )
if cs . isProposer ( ) {
cs . L ogger. Info ( "enterPropose: Our turn to propose" , "proposer" , cs . Validators . GetProposer ( ) . Address , "privValidator" , cs . privValidator )
l ogger. Info ( "enterPropose: Our turn to propose" , "proposer" , cs . Validators . GetProposer ( ) . Address , "privValidator" , cs . privValidator )
cs . decideProposal ( height , round )
} else {
cs . L ogger. Info ( "enterPropose: Not our turn to propose" , "proposer" , cs . Validators . GetProposer ( ) . Address , "privValidator" , cs . privValidator )
l ogger. Info ( "enterPropose: Not our turn to propose" , "proposer" , cs . Validators . GetProposer ( ) . Address , "privValidator" , cs . privValidator )
}
}
@ -959,14 +965,16 @@ func (cs *ConsensusState) defaultDoPrevote(height int64, round int) {
// Enter: any +2/3 prevotes at next round.
func ( cs * ConsensusState ) enterPrevoteWait ( height int64 , round int ) {
logger := cs . Logger . With ( "height" , height , "round" , round )
if cs . Height != height || round < cs . Round || ( cs . Round == round && cstypes . RoundStepPrevoteWait <= cs . Step ) {
cs . Logger . Debug ( cmn . Fmt ( "enterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Debug ( cmn . Fmt ( "enterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
return
}
if ! cs . Votes . Prevotes ( round ) . HasTwoThirdsAny ( ) {
cmn . PanicSanity ( cmn . Fmt ( "enterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes" , height , round ) )
}
cs . L ogger. Info ( cmn . Fmt ( "enterPrevoteWait(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Info ( cmn . Fmt ( "enterPrevoteWait(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
defer func ( ) {
// Done enterPrevoteWait:
@ -985,12 +993,14 @@ func (cs *ConsensusState) enterPrevoteWait(height int64, round int) {
// else, unlock an existing lock and precommit nil if +2/3 of prevotes were nil,
// else, precommit nil otherwise.
func ( cs * ConsensusState ) enterPrecommit ( height int64 , round int ) {
logger := cs . Logger . With ( "height" , height , "round" , round )
if cs . Height != height || round < cs . Round || ( cs . Round == round && cstypes . RoundStepPrecommit <= cs . Step ) {
cs . Logger . Debug ( cmn . Fmt ( "enterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Debug ( cmn . Fmt ( "enterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
return
}
cs . L ogger. Info ( cmn . Fmt ( "enterPrecommit(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Info ( cmn . Fmt ( "enterPrecommit(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
defer func ( ) {
// Done enterPrecommit:
@ -1004,9 +1014,9 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
// If we don't have a polka, we must precommit nil.
if ! ok {
if cs . LockedBlock != nil {
cs . L ogger. Info ( "enterPrecommit: No +2/3 prevotes during enterPrecommit while we're locked. Precommitting nil" )
l ogger. Info ( "enterPrecommit: No +2/3 prevotes during enterPrecommit while we're locked. Precommitting nil" )
} else {
cs . L ogger. Info ( "enterPrecommit: No +2/3 prevotes during enterPrecommit. Precommitting nil." )
l ogger. Info ( "enterPrecommit: No +2/3 prevotes during enterPrecommit. Precommitting nil." )
}
cs . signAddVote ( types . VoteTypePrecommit , nil , types . PartSetHeader { } )
return
@ -1024,9 +1034,9 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
// +2/3 prevoted nil. Unlock and precommit nil.
if len ( blockID . Hash ) == 0 {
if cs . LockedBlock == nil {
cs . L ogger. Info ( "enterPrecommit: +2/3 prevoted for nil." )
l ogger. Info ( "enterPrecommit: +2/3 prevoted for nil." )
} else {
cs . L ogger. Info ( "enterPrecommit: +2/3 prevoted for nil. Unlocking" )
l ogger. Info ( "enterPrecommit: +2/3 prevoted for nil. Unlocking" )
cs . LockedRound = 0
cs . LockedBlock = nil
cs . LockedBlockParts = nil
@ -1040,7 +1050,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
// If we're already locked on that block, precommit it, and update the LockedRound
if cs . LockedBlock . HashesTo ( blockID . Hash ) {
cs . L ogger. Info ( "enterPrecommit: +2/3 prevoted locked block. Relocking" )
l ogger. Info ( "enterPrecommit: +2/3 prevoted locked block. Relocking" )
cs . LockedRound = round
cs . eventBus . PublishEventRelock ( cs . RoundStateEvent ( ) )
cs . signAddVote ( types . VoteTypePrecommit , blockID . Hash , blockID . PartsHeader )
@ -1049,7 +1059,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
// If +2/3 prevoted for proposal block, stage and precommit it
if cs . ProposalBlock . HashesTo ( blockID . Hash ) {
cs . L ogger. Info ( "enterPrecommit: +2/3 prevoted proposal block. Locking" , "hash" , blockID . Hash )
l ogger. Info ( "enterPrecommit: +2/3 prevoted proposal block. Locking" , "hash" , blockID . Hash )
// Validate the block.
if err := cs . blockExec . ValidateBlock ( cs . state , cs . ProposalBlock ) ; err != nil {
cmn . PanicConsensus ( cmn . Fmt ( "enterPrecommit: +2/3 prevoted for an invalid block: %v" , err ) )
@ -1079,14 +1089,16 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
// Enter: any +2/3 precommits for next round.
func ( cs * ConsensusState ) enterPrecommitWait ( height int64 , round int ) {
logger := cs . Logger . With ( "height" , height , "round" , round )
if cs . Height != height || round < cs . Round || ( cs . Round == round && cstypes . RoundStepPrecommitWait <= cs . Step ) {
cs . Logger . Debug ( cmn . Fmt ( "enterPrecommitWait(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Debug ( cmn . Fmt ( "enterPrecommitWait(%v/%v): Invalid args. Current step: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
return
}
if ! cs . Votes . Precommits ( round ) . HasTwoThirdsAny ( ) {
cmn . PanicSanity ( cmn . Fmt ( "enterPrecommitWait(%v/%v), but Precommits does not have any +2/3 votes" , height , round ) )
}
cs . L ogger. Info ( cmn . Fmt ( "enterPrecommitWait(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
l ogger. Info ( cmn . Fmt ( "enterPrecommitWait(%v/%v). Current: %v/%v/%v" , height , round , cs . Height , cs . Round , cs . Step ) )
defer func ( ) {
// Done enterPrecommitWait:
@ -1101,11 +1113,13 @@ func (cs *ConsensusState) enterPrecommitWait(height int64, round int) {
// Enter: +2/3 precommits for block
func ( cs * ConsensusState ) enterCommit ( height int64 , commitRound int ) {
logger := cs . Logger . With ( "height" , height , "round" , round )
if cs . Height != height || cstypes . RoundStepCommit <= cs . Step {
cs . Logger . Debug ( cmn . Fmt ( "enterCommit(%v/%v): Invalid args. Current step: %v/%v/%v" , height , commitRound , cs . Height , cs . Round , cs . Step ) )
l ogger. Debug ( cmn . Fmt ( "enterCommit(%v/%v): Invalid args. Current step: %v/%v/%v" , height , commitRound , cs . Height , cs . Round , cs . Step ) )
return
}
cs . L ogger. Info ( cmn . Fmt ( "enterCommit(%v/%v). Current: %v/%v/%v" , height , commitRound , cs . Height , cs . Round , cs . Step ) )
l ogger. Info ( cmn . Fmt ( "enterCommit(%v/%v). Current: %v/%v/%v" , height , commitRound , cs . Height , cs . Round , cs . Step ) )
defer func ( ) {
// Done enterCommit:
@ -1128,6 +1142,7 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) {
// Move them over to ProposalBlock if they match the commit hash,
// otherwise they'll be cleared in updateToState.
if cs . LockedBlock . HashesTo ( blockID . Hash ) {
l . Info ( "Commit is for locked block. Set ProposalBlock=LockedBlock" , "blockHash" , blockID . Hash )
cs . ProposalBlock = cs . LockedBlock
cs . ProposalBlockParts = cs . LockedBlockParts
}
@ -1135,6 +1150,7 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) {
// If we don't have the block being committed, set up to get it.
if ! cs . ProposalBlock . HashesTo ( blockID . Hash ) {
if ! cs . ProposalBlockParts . HasHeader ( blockID . PartsHeader ) {
l . Info ( "Commit is for a block we don't know about. Set ProposalBlock=nil" , "proposal" , cs . ProposalBlock . Hash ( ) , "commit" , blockID . Hash )
// We're getting the wrong block.
// Set up ProposalBlockParts and keep waiting.
cs . ProposalBlock = nil
@ -1147,19 +1163,21 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) {
// If we have the block AND +2/3 commits for it, finalize.
func ( cs * ConsensusState ) tryFinalizeCommit ( height int64 ) {
logger := cs . Logger . With ( "height" , height )
if cs . Height != height {
cmn . PanicSanity ( cmn . Fmt ( "tryFinalizeCommit() cs.Height: %v vs height: %v" , cs . Height , height ) )
}
blockID , ok := cs . Votes . Precommits ( cs . CommitRound ) . TwoThirdsMajority ( )
if ! ok || len ( blockID . Hash ) == 0 {
cs . L ogger. Error ( "Attempt to finalize failed. There was no +2/3 majority, or +2/3 was for <nil>." , "height" , height )
l ogger. Error ( "Attempt to finalize failed. There was no +2/3 majority, or +2/3 was for <nil>." )
return
}
if ! cs . ProposalBlock . HashesTo ( blockID . Hash ) {
// TODO: this happens every time if we're not a validator (ugly logs)
// TODO: ^^ wait, why does it matter that we're a validator?
cs . L ogger. Info ( "Attempt to finalize failed. We don't have the commit block." , "height" , height , "proposal-block" , cs . ProposalBlock . Hash ( ) , "commit-block" , blockID . Hash )
l ogger. Info ( "Attempt to finalize failed. We don't have the commit block." , "proposal-block" , cs . ProposalBlock . Hash ( ) , "commit-block" , blockID . Hash )
return
}
@ -1301,11 +1319,13 @@ func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error {
func ( cs * ConsensusState ) addProposalBlockPart ( height int64 , part * types . Part ) ( added bool , err error ) {
// Blocks might be reused, so round mismatch is OK
if cs . Height != height {
cs . Logger . Debug ( "Received block part from wrong height" , "height" , height )
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?
}
@ -1327,6 +1347,8 @@ func (cs *ConsensusState) addProposalBlockPart(height int64, part *types.Part) (
blockID , hasTwoThirds := prevotes . TwoThirdsMajority ( )
if hasTwoThirds && ! blockID . IsZero ( ) && ( cs . ValidRound < cs . Round ) {
if cs . ProposalBlock . HashesTo ( blockID . Hash ) {
cs . Logger . Info ( "Updating valid block to new proposal block" ,
"valid-round" , cs . Round , "valid-block-hash" , cs . ProposalBlock . Hash ( ) )
cs . ValidRound = cs . Round
cs . ValidBlock = cs . ProposalBlock
cs . ValidBlockParts = cs . ProposalBlockParts
@ -1458,6 +1480,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool,
( vote . Round <= cs . Round ) &&
cs . ProposalBlock . HashesTo ( blockID . Hash ) {
cs . Logger . Info ( "Updating ValidBlock because of POL." , "validRound" , cs . ValidRound , "POLRound" , vote . Round )
cs . ValidRound = vote . Round
cs . ValidBlock = cs . ProposalBlock
cs . ValidBlockParts = cs . ProposalBlockParts