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  }