github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/consensus/neatcon/types/vote.go (about) 1 package types 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 8 "github.com/neatlab/neatio/utilities/rlp" 9 . "github.com/neatlib/common-go" 10 "github.com/neatlib/crypto-go" 11 "github.com/neatlib/wire-go" 12 ) 13 14 var ( 15 ErrVoteUnexpectedStep = errors.New("Unexpected step") 16 ErrVoteInvalidValidatorIndex = errors.New("Invalid round vote validator index") 17 ErrVoteInvalidValidatorAddress = errors.New("Invalid round vote validator address") 18 ErrVoteInvalidSignature = errors.New("Invalid round vote signature") 19 ErrVoteInvalidBlockHash = errors.New("Invalid block hash") 20 ) 21 22 type ErrVoteConflictingVotes struct { 23 VoteA *Vote 24 VoteB *Vote 25 } 26 27 func (err *ErrVoteConflictingVotes) Error() string { 28 return "Conflicting votes" 29 } 30 31 const ( 32 VoteTypePrevote = byte(0x01) 33 VoteTypePrecommit = byte(0x02) 34 ) 35 36 func IsVoteTypeValid(type_ byte) bool { 37 switch type_ { 38 case VoteTypePrevote: 39 return true 40 case VoteTypePrecommit: 41 return true 42 default: 43 return false 44 } 45 } 46 47 type Vote struct { 48 ValidatorAddress []byte `json:"validator_address"` 49 ValidatorIndex uint64 `json:"validator_index"` 50 Height uint64 `json:"height"` 51 Round uint64 `json:"round"` 52 Type byte `json:"type"` 53 BlockID BlockID `json:"block_id"` 54 Signature crypto.Signature `json:"signature"` 55 SignBytes []byte `json:"sign_bytes"` 56 } 57 58 func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { 59 wire.WriteJSON(CanonicalJSONOnceVote{ 60 chainID, 61 CanonicalVote(vote), 62 }, w, n, err) 63 } 64 65 func (vote *Vote) EncodeRLP(w io.Writer) error { 66 return rlp.Encode(w, []interface{}{ 67 vote.ValidatorAddress, 68 vote.ValidatorIndex, 69 vote.Height, 70 vote.Round, 71 vote.Type, 72 vote.BlockID, 73 vote.Signature.Bytes(), 74 }) 75 } 76 77 func (vote *Vote) DecodeRLP(s *rlp.Stream) error { 78 var vt struct { 79 ValidatorAddress []byte 80 ValidatorIndex uint64 81 Height uint64 82 Round uint64 83 Type byte 84 BlockID BlockID 85 Signature []byte 86 } 87 88 if err := s.Decode(&vt); err != nil { 89 return err 90 } 91 92 vote.ValidatorAddress = vt.ValidatorAddress 93 vote.ValidatorIndex = vt.ValidatorIndex 94 vote.Height = vt.Height 95 vote.Round = vt.Round 96 vote.Type = vt.Type 97 vote.BlockID = vt.BlockID 98 99 sig, err := crypto.SignatureFromBytes(vt.Signature) 100 if err != nil { 101 return err 102 } 103 vote.Signature = sig 104 105 if err != nil { 106 return err 107 } 108 109 return nil 110 } 111 112 func (vote *Vote) Copy() *Vote { 113 voteCopy := *vote 114 return &voteCopy 115 } 116 117 func (vote *Vote) String() string { 118 if vote == nil { 119 return "nil-Vote" 120 } 121 var typeString string 122 switch vote.Type { 123 case VoteTypePrevote: 124 typeString = "Prevote" 125 case VoteTypePrecommit: 126 typeString = "Precommit" 127 default: 128 PanicSanity("Unknown vote type") 129 } 130 131 return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%v) %X %v}", 132 vote.ValidatorIndex, Fingerprint(vote.ValidatorAddress), 133 vote.Height, vote.Round, vote.Type, typeString, 134 Fingerprint(vote.BlockID.Hash), vote.Signature) 135 }