@ -8,8 +8,7 @@ import (
"github.com/pkg/errors"
"github.com/tendermint/go-amino"
amino "github.com/tendermint/go-amino"
cstypes "github.com/tendermint/tendermint/consensus/types"
cmn "github.com/tendermint/tendermint/libs/common"
tmevents "github.com/tendermint/tendermint/libs/events"
@ -205,6 +204,13 @@ func (conR *ConsensusReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
conR . Switch . StopPeerForError ( src , err )
return
}
if err = msg . ValidateBasic ( ) ; err != nil {
conR . Logger . Error ( "Peer sent us invalid msg" , "peer" , src , "msg" , msg , "err" , err )
conR . Switch . StopPeerForError ( src , err )
return
}
conR . Logger . Debug ( "Receive" , "src" , src , "chId" , chID , "msg" , msg )
// Get peer states
@ -242,8 +248,7 @@ func (conR *ConsensusReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
case types . PrecommitType :
ourVotes = votes . Precommits ( msg . Round ) . BitArrayByBlockID ( msg . BlockID )
default :
conR . Logger . Error ( "Bad VoteSetBitsMessage field Type" )
return
panic ( "Bad VoteSetBitsMessage field Type. Forgot to add a check in ValidateBasic?" )
}
src . TrySend ( VoteSetBitsChannel , cdc . MustMarshalBinaryBare ( & VoteSetBitsMessage {
Height : msg . Height ,
@ -322,8 +327,7 @@ func (conR *ConsensusReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
case types . PrecommitType :
ourVotes = votes . Precommits ( msg . Round ) . BitArrayByBlockID ( msg . BlockID )
default :
conR . Logger . Error ( "Bad VoteSetBitsMessage field Type" )
return
panic ( "Bad VoteSetBitsMessage field Type. Forgot to add a check in ValidateBasic?" )
}
ps . ApplyVoteSetBitsMessage ( msg , ourVotes )
} else {
@ -440,9 +444,9 @@ func (conR *ConsensusReactor) broadcastHasVoteMessage(vote *types.Vote) {
func makeRoundStepMessage ( rs * cstypes . RoundState ) ( nrsMsg * NewRoundStepMessage ) {
nrsMsg = & NewRoundStepMessage {
Height : rs . Height ,
Round : rs . Round ,
Step : rs . Step ,
Height : rs . Height ,
Round : rs . Round ,
Step : rs . Step ,
SecondsSinceStartTime : int ( time . Since ( rs . StartTime ) . Seconds ( ) ) ,
LastCommitRound : rs . LastCommit . Round ( ) ,
}
@ -1349,7 +1353,9 @@ func (ps *PeerState) StringIndented(indent string) string {
// Messages
// ConsensusMessage is a message that can be sent and received on the ConsensusReactor
type ConsensusMessage interface { }
type ConsensusMessage interface {
ValidateBasic ( ) error
}
func RegisterConsensusMessages ( cdc * amino . Codec ) {
cdc . RegisterInterface ( ( * ConsensusMessage ) ( nil ) , nil )
@ -1385,6 +1391,27 @@ type NewRoundStepMessage struct {
LastCommitRound int
}
// ValidateBasic performs basic validation.
func ( m * NewRoundStepMessage ) ValidateBasic ( ) error {
if m . Height < 0 {
return errors . New ( "Negative Height" )
}
if m . Round < 0 {
return errors . New ( "Negative Round" )
}
if ! m . Step . IsValid ( ) {
return errors . New ( "Invalid Step" )
}
// NOTE: SecondsSinceStartTime may be negative
if ( m . Height == 1 && m . LastCommitRound != - 1 ) ||
( m . Height > 1 && m . LastCommitRound < - 1 ) { // TODO: #2737 LastCommitRound should always be >= 0 for heights > 1
return errors . New ( "Invalid LastCommitRound (for 1st block: -1, for others: >= 0)" )
}
return nil
}
// String returns a string representation.
func ( m * NewRoundStepMessage ) String ( ) string {
return fmt . Sprintf ( "[NewRoundStep H:%v R:%v S:%v LCR:%v]" ,
@ -1404,6 +1431,25 @@ type NewValidBlockMessage struct {
IsCommit bool
}
// ValidateBasic performs basic validation.
func ( m * NewValidBlockMessage ) ValidateBasic ( ) error {
if m . Height < 0 {
return errors . New ( "Negative Height" )
}
if m . Round < 0 {
return errors . New ( "Negative Round" )
}
if err := m . BlockPartsHeader . ValidateBasic ( ) ; err != nil {
return fmt . Errorf ( "Wrong BlockPartsHeader: %v" , err )
}
if m . BlockParts . Size ( ) != m . BlockPartsHeader . Total {
return fmt . Errorf ( "BlockParts bit array size %d not equal to BlockPartsHeader.Total %d" ,
m . BlockParts . Size ( ) ,
m . BlockPartsHeader . Total )
}
return nil
}
// String returns a string representation.
func ( m * NewValidBlockMessage ) String ( ) string {
return fmt . Sprintf ( "[ValidBlockMessage H:%v R:%v BP:%v BA:%v IsCommit:%v]" ,
@ -1417,6 +1463,11 @@ type ProposalMessage struct {
Proposal * types . Proposal
}
// ValidateBasic performs basic validation.
func ( m * ProposalMessage ) ValidateBasic ( ) error {
return m . Proposal . ValidateBasic ( )
}
// String returns a string representation.
func ( m * ProposalMessage ) String ( ) string {
return fmt . Sprintf ( "[Proposal %v]" , m . Proposal )
@ -1431,6 +1482,20 @@ type ProposalPOLMessage struct {
ProposalPOL * cmn . BitArray
}
// ValidateBasic performs basic validation.
func ( m * ProposalPOLMessage ) ValidateBasic ( ) error {
if m . Height < 0 {
return errors . New ( "Negative Height" )
}
if m . ProposalPOLRound < 0 {
return errors . New ( "Negative ProposalPOLRound" )
}
if m . ProposalPOL . Size ( ) == 0 {
return errors . New ( "Empty ProposalPOL bit array" )
}
return nil
}
// String returns a string representation.
func ( m * ProposalPOLMessage ) String ( ) string {
return fmt . Sprintf ( "[ProposalPOL H:%v POLR:%v POL:%v]" , m . Height , m . ProposalPOLRound , m . ProposalPOL )
@ -1445,6 +1510,20 @@ type BlockPartMessage struct {
Part * types . Part
}
// ValidateBasic performs basic validation.
func ( m * BlockPartMessage ) ValidateBasic ( ) error {
if m . Height < 0 {
return errors . New ( "Negative Height" )
}
if m . Round < 0 {
return errors . New ( "Negative Round" )
}
if err := m . Part . ValidateBasic ( ) ; err != nil {
return fmt . Errorf ( "Wrong Part: %v" , err )
}
return nil
}
// String returns a string representation.
func ( m * BlockPartMessage ) String ( ) string {
return fmt . Sprintf ( "[BlockPart H:%v R:%v P:%v]" , m . Height , m . Round , m . Part )
@ -1457,6 +1536,11 @@ type VoteMessage struct {
Vote * types . Vote
}
// ValidateBasic performs basic validation.
func ( m * VoteMessage ) ValidateBasic ( ) error {
return m . Vote . ValidateBasic ( )
}
// String returns a string representation.
func ( m * VoteMessage ) String ( ) string {
return fmt . Sprintf ( "[Vote %v]" , m . Vote )
@ -1472,6 +1556,23 @@ type HasVoteMessage struct {
Index int
}
// ValidateBasic performs basic validation.
func ( m * HasVoteMessage ) ValidateBasic ( ) error {
if m . Height < 0 {
return errors . New ( "Negative Height" )
}
if m . Round < 0 {
return errors . New ( "Negative Round" )
}
if ! types . IsVoteTypeValid ( m . Type ) {
return errors . New ( "Invalid Type" )
}
if m . Index < 0 {
return errors . New ( "Negative Index" )
}
return nil
}
// String returns a string representation.
func ( m * HasVoteMessage ) String ( ) string {
return fmt . Sprintf ( "[HasVote VI:%v V:{%v/%02d/%v}]" , m . Index , m . Height , m . Round , m . Type )
@ -1487,6 +1588,23 @@ type VoteSetMaj23Message struct {
BlockID types . BlockID
}
// ValidateBasic performs basic validation.
func ( m * VoteSetMaj23Message ) ValidateBasic ( ) error {
if m . Height < 0 {
return errors . New ( "Negative Height" )
}
if m . Round < 0 {
return errors . New ( "Negative Round" )
}
if ! types . IsVoteTypeValid ( m . Type ) {
return errors . New ( "Invalid Type" )
}
if err := m . BlockID . ValidateBasic ( ) ; err != nil {
return fmt . Errorf ( "Wrong BlockID: %v" , err )
}
return nil
}
// String returns a string representation.
func ( m * VoteSetMaj23Message ) String ( ) string {
return fmt . Sprintf ( "[VSM23 %v/%02d/%v %v]" , m . Height , m . Round , m . Type , m . BlockID )
@ -1503,6 +1621,24 @@ type VoteSetBitsMessage struct {
Votes * cmn . BitArray
}
// ValidateBasic performs basic validation.
func ( m * VoteSetBitsMessage ) ValidateBasic ( ) error {
if m . Height < 0 {
return errors . New ( "Negative Height" )
}
if m . Round < 0 {
return errors . New ( "Negative Round" )
}
if ! types . IsVoteTypeValid ( m . Type ) {
return errors . New ( "Invalid Type" )
}
if err := m . BlockID . ValidateBasic ( ) ; err != nil {
return fmt . Errorf ( "Wrong BlockID: %v" , err )
}
// NOTE: Votes.Size() can be zero if the node does not have any
return nil
}
// String returns a string representation.
func ( m * VoteSetBitsMessage ) String ( ) string {
return fmt . Sprintf ( "[VSB %v/%02d/%v %v %v]" , m . Height , m . Round , m . Type , m . BlockID , m . Votes )
@ -1515,6 +1651,11 @@ type ProposalHeartbeatMessage struct {
Heartbeat * types . Heartbeat
}
// ValidateBasic performs basic validation.
func ( m * ProposalHeartbeatMessage ) ValidateBasic ( ) error {
return m . Heartbeat . ValidateBasic ( )
}
// String returns a string representation.
func ( m * ProposalHeartbeatMessage ) String ( ) string {
return fmt . Sprintf ( "[HEARTBEAT %v]" , m . Heartbeat )