github.com/iotexproject/iotex-core@v1.14.1-rc1/consensus/scheme/rolldpos/consensusvote.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package rolldpos 7 8 import ( 9 blake2b "github.com/minio/blake2b-simd" 10 "github.com/pkg/errors" 11 "google.golang.org/protobuf/proto" 12 13 "github.com/iotexproject/iotex-proto/golang/iotextypes" 14 ) 15 16 // ConsensusVoteTopic defines the topic of an consensus vote 17 type ConsensusVoteTopic uint8 18 19 const ( 20 // PROPOSAL stands for an consensus vote to endorse a block proposal 21 PROPOSAL ConsensusVoteTopic = 0 22 // LOCK stands for an consensus vote to endorse a lock on a proposed block 23 LOCK ConsensusVoteTopic = 1 24 // COMMIT stands for an consensus vote to endorse a block commit 25 COMMIT ConsensusVoteTopic = 2 26 ) 27 28 // ConsensusVote is a vote on a given topic for a block on a specific height 29 type ConsensusVote struct { 30 blkHash []byte 31 topic ConsensusVoteTopic 32 } 33 34 // NewConsensusVote creates a consensus vote 35 func NewConsensusVote( 36 blkHash []byte, 37 topic ConsensusVoteTopic, 38 ) *ConsensusVote { 39 return &ConsensusVote{ 40 blkHash: blkHash, 41 topic: topic, 42 } 43 } 44 45 // BlockHash returns the block hash of the consensus vote 46 func (v *ConsensusVote) BlockHash() []byte { 47 retval := make([]byte, len(v.blkHash)) 48 copy(retval, v.blkHash) 49 50 return retval 51 } 52 53 // Topic returns the topic of the consensus vote 54 func (v *ConsensusVote) Topic() ConsensusVoteTopic { 55 return v.topic 56 } 57 58 // Proto converts to a protobuf message 59 func (v *ConsensusVote) Proto() (*iotextypes.ConsensusVote, error) { 60 var topic iotextypes.ConsensusVote_Topic 61 switch v.topic { 62 case PROPOSAL: 63 topic = iotextypes.ConsensusVote_PROPOSAL 64 case LOCK: 65 topic = iotextypes.ConsensusVote_LOCK 66 case COMMIT: 67 topic = iotextypes.ConsensusVote_COMMIT 68 default: 69 return nil, errors.Errorf("unsupported topic %d", v.topic) 70 } 71 hash := make([]byte, len(v.blkHash)) 72 copy(hash, v.blkHash) 73 return &iotextypes.ConsensusVote{ 74 BlockHash: hash, 75 Topic: topic, 76 }, nil 77 } 78 79 // LoadProto loads from a protobuf message 80 func (v *ConsensusVote) LoadProto(msg *iotextypes.ConsensusVote) error { 81 switch msg.Topic { 82 case iotextypes.ConsensusVote_PROPOSAL: 83 v.topic = PROPOSAL 84 case iotextypes.ConsensusVote_LOCK: 85 v.topic = LOCK 86 case iotextypes.ConsensusVote_COMMIT: 87 v.topic = COMMIT 88 default: 89 return errors.Errorf("invalid topic %d", msg.Topic) 90 } 91 v.blkHash = make([]byte, len(msg.BlockHash)) 92 copy(v.blkHash, msg.BlockHash) 93 return nil 94 } 95 96 // Hash returns the hash of this vote 97 func (v *ConsensusVote) Hash() ([]byte, error) { 98 msg, err := v.Proto() 99 if err != nil { 100 return nil, err 101 } 102 ser, err := proto.Marshal(msg) 103 if err != nil { 104 return nil, err 105 } 106 hash := blake2b.Sum256(ser) 107 return hash[:], nil 108 }