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  }