mirror of
https://github.com/tendermint/tendermint.git
synced 2026-04-25 10:10:30 +00:00
consensus: broadcast evidence tx on ErrVoteConflictingSignature
This commit is contained in:
@@ -11,13 +11,21 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrVoteUnexpectedStep = errors.New("Unexpected step")
|
||||
ErrVoteInvalidAccount = errors.New("Invalid round vote account")
|
||||
ErrVoteInvalidSignature = errors.New("Invalid round vote signature")
|
||||
ErrVoteInvalidBlockHash = errors.New("Invalid block hash")
|
||||
ErrVoteConflictingSignature = errors.New("Conflicting round vote signature")
|
||||
ErrVoteUnexpectedStep = errors.New("Unexpected step")
|
||||
ErrVoteInvalidAccount = errors.New("Invalid round vote account")
|
||||
ErrVoteInvalidSignature = errors.New("Invalid round vote signature")
|
||||
ErrVoteInvalidBlockHash = errors.New("Invalid block hash")
|
||||
)
|
||||
|
||||
type ErrVoteConflictingSignature struct {
|
||||
VoteA *Vote
|
||||
VoteB *Vote
|
||||
}
|
||||
|
||||
func (err *ErrVoteConflictingSignature) Error() string {
|
||||
return "Conflicting round vote signature"
|
||||
}
|
||||
|
||||
// Represents a prevote, precommit, or commit vote from validators for consensus.
|
||||
// Commit votes get aggregated into the next block's Validaiton.
|
||||
// See the whitepaper for details.
|
||||
|
||||
@@ -175,8 +175,21 @@ func (conR *ConsensusReactor) Receive(chId byte, peer *p2p.Peer, msgBytes []byte
|
||||
address, _ := rs.Validators.GetByIndex(validatorIndex)
|
||||
added, index, err := conR.conS.AddVote(address, vote)
|
||||
if err != nil {
|
||||
// Probably an invalid signature. Bad peer.
|
||||
log.Warn("Error attempting to add vote", "error", err)
|
||||
// If conflicting sig, broadcast evidence tx for slashing. Else punish peer.
|
||||
if errDupe, ok := err.(*blk.ErrVoteConflictingSignature); ok {
|
||||
log.Warn("Found conflicting vote. Publish evidence")
|
||||
evidenceTx := &blk.DupeoutTx{
|
||||
Address: address,
|
||||
VoteA: *errDupe.VoteA,
|
||||
VoteB: *errDupe.VoteB,
|
||||
}
|
||||
conR.conS.mempoolReactor.BroadcastTx(evidenceTx) // shouldn't need to check returned err
|
||||
} else {
|
||||
// Probably an invalid signature. Bad peer.
|
||||
log.Warn("Error attempting to add vote", "error", err)
|
||||
|
||||
// TODO: punish peer
|
||||
}
|
||||
}
|
||||
// Initialize Prevotes/Precommits/Commits if needed
|
||||
ps.EnsureVoteBitArrays(rs.Height, rs.Validators.Size())
|
||||
|
||||
@@ -106,7 +106,10 @@ func (voteSet *VoteSet) addVote(valIndex uint, vote *blk.Vote) (bool, uint, erro
|
||||
if bytes.Equal(existingVote.BlockHash, vote.BlockHash) {
|
||||
return false, 0, nil
|
||||
} else {
|
||||
return false, 0, blk.ErrVoteConflictingSignature
|
||||
return false, 0, &blk.ErrVoteConflictingSignature{
|
||||
VoteA: existingVote,
|
||||
VoteB: vote,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ func (s *State) ExecTx(tx_ blk.Tx) error {
|
||||
return errors.New("DupeoutTx heights don't match")
|
||||
}
|
||||
if tx.VoteA.Type == blk.VoteTypeCommit && tx.VoteA.Round < tx.VoteB.Round {
|
||||
// Check special case.
|
||||
// Check special case (not an error, validator must be slashed!)
|
||||
// Validators should not sign another vote after committing.
|
||||
} else {
|
||||
if tx.VoteA.Round != tx.VoteB.Round {
|
||||
|
||||
Reference in New Issue
Block a user