-
Notifications
You must be signed in to change notification settings - Fork 0
/
vote.go
119 lines (107 loc) · 3.62 KB
/
vote.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package types
import (
"bytes"
"errors"
"fmt"
"github.com/taiyuechain/taiyuechain/consensus/tbft/crypto"
"github.com/taiyuechain/taiyuechain/consensus/tbft/help"
"time"
)
var (
//ErrVoteUnexpectedStep is Error Unexpected step
ErrVoteUnexpectedStep = errors.New("unexpected step")
//ErrVoteInvalidValidatorIndex is Error Invalid validator index
ErrVoteInvalidValidatorIndex = errors.New("invalid validator index")
// ErrVoteInvalidValidatorAddress is Error Invalid validator address
ErrVoteInvalidValidatorAddress = errors.New("invalid validator address")
//ErrVoteInvalidSignature is Error Invalid signature
ErrVoteInvalidSignature = errors.New("invalid signature")
//ErrVoteInvalidBlockHash is Error Invalid block hash
//ErrVoteInvalidBlockHash = errors.New("invalid block hash")
//ErrVoteNonDeterministicSignature is Error Non-deterministic signature
ErrVoteNonDeterministicSignature = errors.New("non-deterministic signature")
//ErrVoteConflictingVotes is Error Conflicting votes from validator
ErrVoteConflictingVotes = errors.New("conflicting votes from validator")
//ErrVoteNil is Error Nil vote
ErrVoteNil = errors.New("nil vote")
)
// Types of votes
// TODO Make a new type "VoteType"
const (
VoteTypePrevote = byte(0x01)
VoteTypePrecommit = byte(0x02)
)
//IsVoteTypeValid return typeB is vote
func IsVoteTypeValid(typeB byte) bool {
switch typeB {
case VoteTypePrevote:
return true
case VoteTypePrecommit:
return true
default:
return false
}
}
//Vote Represents a prevote, precommit, or commit vote from validators for consensus.
type Vote struct {
ValidatorAddress help.Address `json:"validator_address"`
ValidatorIndex uint `json:"validator_index"`
Height uint64 `json:"height"`
Round uint `json:"round"`
Result uint `json:"result"`
Timestamp time.Time `json:"timestamp"`
Type byte `json:"type"`
BlockID BlockID `json:"block_id"` // zero if vote is nil.
Signature []byte `json:"signature"`
ResultSign []byte `json:"reuslt_signature"`
}
//SignBytes is sign CanonicalVote and return rlpHash
func (vote *Vote) SignBytes(chainID string) []byte {
bz, err := cdc.MarshalJSON(CanonicalVote(chainID, vote))
if err != nil {
panic(err)
}
signBytes := help.RlpHash([]interface{}{bz})
return signBytes[:]
}
// Copy return a vote Copy
func (vote *Vote) Copy() *Vote {
voteCopy := *vote
return &voteCopy
}
func (vote *Vote) String() string {
if vote == nil {
return "nil-Vote"
}
var typeString string
switch vote.Type {
case VoteTypePrevote:
typeString = "Prevote"
case VoteTypePrecommit:
typeString = "Precommit"
default:
help.PanicSanity("Unknown vote type")
}
return fmt.Sprintf("Vote{%02d %v/%02d/%d/%v(%v) H:%X %s}",
vote.ValidatorIndex,
vote.Height, vote.Round, vote.Result, vote.Type, typeString,
help.Fingerprint(vote.BlockID.Hash),
vote.Timestamp.Format("15:04:05.000"))
//return fmt.Sprintf("Vote{%v:%X %v/%02d/%d/%v(%v) H:%X S1:%X S2:%X @ %s}",
// vote.ValidatorIndex, help.Fingerprint(vote.ValidatorAddress),
// vote.Height, vote.Round, vote.Result, vote.Type, typeString,
// help.Fingerprint(vote.BlockID.Hash),
// help.Fingerprint(vote.Signature),
// help.Fingerprint(vote.ResultSign),
// CanonicalTime(vote.Timestamp))
}
//Verify is Verify Signature and ValidatorAddress
func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
if !bytes.Equal(pubKey.Address(), vote.ValidatorAddress) {
return ErrVoteInvalidValidatorAddress
}
if !pubKey.VerifyBytes(vote.SignBytes(chainID), vote.Signature) {
return ErrVoteInvalidSignature
}
return nil
}