github.com/okex/exchain@v1.8.0/libs/tendermint/types/evidence.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/pkg/errors"
    10  	amino "github.com/tendermint/go-amino"
    11  
    12  	"github.com/okex/exchain/libs/tendermint/crypto"
    13  	cryptoenc "github.com/okex/exchain/libs/tendermint/crypto/encoding"
    14  	cryptoamino "github.com/okex/exchain/libs/tendermint/crypto/encoding/amino"
    15  	"github.com/okex/exchain/libs/tendermint/crypto/merkle"
    16  	"github.com/okex/exchain/libs/tendermint/crypto/tmhash"
    17  	tmproto "github.com/okex/exchain/libs/tendermint/proto/types"
    18  )
    19  
    20  const (
    21  	// MaxEvidenceBytes is a maximum size of any evidence (including amino overhead).
    22  	MaxEvidenceBytes int64 = 484
    23  
    24  	DuplicateVoteEvidenceName = "tendermint/DuplicateVoteEvidence"
    25  )
    26  
    27  // ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid.
    28  type ErrEvidenceInvalid struct {
    29  	Evidence   Evidence
    30  	ErrorValue error
    31  }
    32  
    33  // NewErrEvidenceInvalid returns a new EvidenceInvalid with the given err.
    34  func NewErrEvidenceInvalid(ev Evidence, err error) *ErrEvidenceInvalid {
    35  	return &ErrEvidenceInvalid{ev, err}
    36  }
    37  
    38  // Error returns a string representation of the error.
    39  func (err *ErrEvidenceInvalid) Error() string {
    40  	return fmt.Sprintf("Invalid evidence: %v. Evidence: %v", err.ErrorValue, err.Evidence)
    41  }
    42  
    43  // ErrEvidenceOverflow is for when there is too much evidence in a block.
    44  type ErrEvidenceOverflow struct {
    45  	MaxNum int64
    46  	GotNum int64
    47  }
    48  
    49  // NewErrEvidenceOverflow returns a new ErrEvidenceOverflow where got > max.
    50  func NewErrEvidenceOverflow(max, got int64) *ErrEvidenceOverflow {
    51  	return &ErrEvidenceOverflow{max, got}
    52  }
    53  
    54  // Error returns a string representation of the error.
    55  func (err *ErrEvidenceOverflow) Error() string {
    56  	return fmt.Sprintf("Too much evidence: Max %d, got %d", err.MaxNum, err.GotNum)
    57  }
    58  
    59  //-------------------------------------------
    60  
    61  // Evidence represents any provable malicious activity by a validator
    62  type Evidence interface {
    63  	Height() int64                                     // height of the equivocation
    64  	Time() time.Time                                   // time of the equivocation
    65  	Address() []byte                                   // address of the equivocating validator
    66  	Bytes() []byte                                     // bytes which comprise the evidence
    67  	Hash() []byte                                      // hash of the evidence
    68  	Verify(chainID string, pubKey crypto.PubKey) error // verify the evidence
    69  	Equal(Evidence) bool                               // check equality of evidence
    70  
    71  	ValidateBasic() error
    72  	String() string
    73  }
    74  
    75  func EvidenceToProto(evidence Evidence) (*tmproto.Evidence, error) {
    76  	if evidence == nil {
    77  		return nil, errors.New("nil evidence")
    78  	}
    79  
    80  	switch evi := evidence.(type) {
    81  	case *DuplicateVoteEvidence:
    82  		voteB := evi.VoteB.ToProto()
    83  		voteA := evi.VoteA.ToProto()
    84  		pk, err := cryptoenc.PubKeyToProto(evi.PubKey)
    85  		if err != nil {
    86  			return nil, err
    87  		}
    88  		tp := &tmproto.Evidence{
    89  			Sum: &tmproto.Evidence_DuplicateVoteEvidence{
    90  				DuplicateVoteEvidence: &tmproto.DuplicateVoteEvidence{
    91  					PubKey: &pk,
    92  					VoteA:  voteA,
    93  					VoteB:  voteB,
    94  				},
    95  			},
    96  		}
    97  		return tp, nil
    98  	case MockEvidence:
    99  		if err := evi.ValidateBasic(); err != nil {
   100  			return nil, err
   101  		}
   102  
   103  		tp := &tmproto.Evidence{
   104  			Sum: &tmproto.Evidence_MockEvidence{
   105  				MockEvidence: &tmproto.MockEvidence{
   106  					EvidenceHeight:  evi.Height(),
   107  					EvidenceTime:    evi.Time(),
   108  					EvidenceAddress: evi.Address(),
   109  				},
   110  			},
   111  		}
   112  
   113  		return tp, nil
   114  	case MockRandomEvidence:
   115  		if err := evi.ValidateBasic(); err != nil {
   116  			return nil, err
   117  		}
   118  
   119  		tp := &tmproto.Evidence{
   120  			Sum: &tmproto.Evidence_MockRandomEvidence{
   121  				MockRandomEvidence: &tmproto.MockRandomEvidence{
   122  					EvidenceHeight:  evi.Height(),
   123  					EvidenceTime:    evi.Time(),
   124  					EvidenceAddress: evi.Address(),
   125  					RandBytes:       evi.randBytes,
   126  				},
   127  			},
   128  		}
   129  		return tp, nil
   130  	default:
   131  		return nil, fmt.Errorf("toproto: evidence is not recognized: %T", evi)
   132  	}
   133  }
   134  
   135  func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) {
   136  	if evidence == nil {
   137  		return nil, errors.New("nil evidence")
   138  	}
   139  
   140  	switch evi := evidence.Sum.(type) {
   141  	case *tmproto.Evidence_DuplicateVoteEvidence:
   142  
   143  		vA, err := VoteFromProto(evi.DuplicateVoteEvidence.VoteA)
   144  		if err != nil {
   145  			return nil, err
   146  		}
   147  
   148  		vB, err := VoteFromProto(evi.DuplicateVoteEvidence.VoteB)
   149  		if err != nil {
   150  			return nil, err
   151  		}
   152  
   153  		pk, _, err := cryptoenc.PubKeyFromProto(evi.DuplicateVoteEvidence.GetPubKey())
   154  		if err != nil {
   155  			return nil, err
   156  		}
   157  
   158  		dve := DuplicateVoteEvidence{
   159  			PubKey: pk,
   160  			VoteA:  vA,
   161  			VoteB:  vB,
   162  		}
   163  
   164  		return &dve, dve.ValidateBasic()
   165  	case *tmproto.Evidence_MockEvidence:
   166  		me := MockEvidence{
   167  			EvidenceHeight:  evi.MockEvidence.GetEvidenceHeight(),
   168  			EvidenceAddress: evi.MockEvidence.GetEvidenceAddress(),
   169  			EvidenceTime:    evi.MockEvidence.GetEvidenceTime(),
   170  		}
   171  		return me, me.ValidateBasic()
   172  	case *tmproto.Evidence_MockRandomEvidence:
   173  		mre := MockRandomEvidence{
   174  			MockEvidence: MockEvidence{
   175  				EvidenceHeight:  evi.MockRandomEvidence.GetEvidenceHeight(),
   176  				EvidenceAddress: evi.MockRandomEvidence.GetEvidenceAddress(),
   177  				EvidenceTime:    evi.MockRandomEvidence.GetEvidenceTime(),
   178  			},
   179  			randBytes: evi.MockRandomEvidence.RandBytes,
   180  		}
   181  		return mre, mre.ValidateBasic()
   182  	default:
   183  		return nil, errors.New("evidence is not recognized")
   184  	}
   185  }
   186  
   187  func RegisterEvidences(cdc *amino.Codec) {
   188  	cdc.RegisterInterface((*Evidence)(nil), nil)
   189  	cdc.RegisterConcrete(&DuplicateVoteEvidence{}, DuplicateVoteEvidenceName, nil)
   190  
   191  	cdc.RegisterConcreteUnmarshaller(DuplicateVoteEvidenceName, func(codec *amino.Codec, data []byte) (interface{}, int, error) {
   192  		var dve DuplicateVoteEvidence
   193  		err := dve.UnmarshalFromAmino(codec, data)
   194  		if err != nil {
   195  			return nil, 0, err
   196  		}
   197  		return &dve, len(data), nil
   198  	})
   199  }
   200  
   201  func RegisterMockEvidences(cdc *amino.Codec) {
   202  	cdc.RegisterConcrete(MockEvidence{}, "tendermint/MockEvidence", nil)
   203  	cdc.RegisterConcrete(MockRandomEvidence{}, "tendermint/MockRandomEvidence", nil)
   204  }
   205  
   206  const (
   207  	MaxEvidenceBytesDenominator = 10
   208  )
   209  
   210  // MaxEvidencePerBlock returns the maximum number of evidences
   211  // allowed in the block and their maximum total size (limitted to 1/10th
   212  // of the maximum block size).
   213  // TODO: change to a constant, or to a fraction of the validator set size.
   214  // See https://github.com/tendermint/tendermint/issues/2590
   215  func MaxEvidencePerBlock(blockMaxBytes int64) (int64, int64) {
   216  	maxBytes := blockMaxBytes / MaxEvidenceBytesDenominator
   217  	maxNum := maxBytes / MaxEvidenceBytes
   218  	return maxNum, maxBytes
   219  }
   220  
   221  //-------------------------------------------
   222  
   223  // DuplicateVoteEvidence contains evidence a validator signed two conflicting
   224  // votes.
   225  type DuplicateVoteEvidence struct {
   226  	PubKey crypto.PubKey
   227  	VoteA  *Vote
   228  	VoteB  *Vote
   229  }
   230  
   231  func (dve DuplicateVoteEvidence) AminoSize(cdc *amino.Codec) int {
   232  	var size = 0
   233  
   234  	if dve.PubKey != nil {
   235  		pubKeySize := cryptoamino.PubKeyAminoSize(dve.PubKey, cdc)
   236  		size += 1 + amino.UvarintSize(uint64(pubKeySize)) + pubKeySize
   237  	}
   238  
   239  	if dve.VoteA != nil {
   240  		voteASize := dve.VoteA.AminoSize(cdc)
   241  		size += 1 + amino.UvarintSize(uint64(voteASize)) + voteASize
   242  	}
   243  
   244  	if dve.VoteB != nil {
   245  		voteBSize := dve.VoteB.AminoSize(cdc)
   246  		size += 1 + amino.UvarintSize(uint64(voteBSize)) + voteBSize
   247  	}
   248  
   249  	return size
   250  }
   251  
   252  func (dve *DuplicateVoteEvidence) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error {
   253  	var dataLen uint64 = 0
   254  	var subData []byte
   255  
   256  	for {
   257  		data = data[dataLen:]
   258  		if len(data) == 0 {
   259  			break
   260  		}
   261  
   262  		pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
   263  		if err != nil {
   264  			return err
   265  		}
   266  		data = data[1:]
   267  
   268  		if pbType == amino.Typ3_ByteLength {
   269  			var n int
   270  			dataLen, n, err = amino.DecodeUvarint(data)
   271  			if err != nil {
   272  				return err
   273  			}
   274  			data = data[n:]
   275  			if len(data) < int(dataLen) {
   276  				return fmt.Errorf("invalid data len")
   277  			}
   278  			subData = data[:dataLen]
   279  		} else {
   280  			return fmt.Errorf("unexpect pb type %d", pbType)
   281  		}
   282  
   283  		switch pos {
   284  		case 1:
   285  			dve.PubKey, err = cryptoamino.UnmarshalPubKeyFromAmino(cdc, subData)
   286  			if err != nil {
   287  				return err
   288  			}
   289  		case 2:
   290  			dve.VoteA = new(Vote)
   291  			err = dve.VoteA.UnmarshalFromAmino(cdc, subData)
   292  			if err != nil {
   293  				return err
   294  			}
   295  		case 3:
   296  			dve.VoteB = new(Vote)
   297  			err = dve.VoteB.UnmarshalFromAmino(cdc, subData)
   298  			if err != nil {
   299  				return err
   300  			}
   301  		default:
   302  			return fmt.Errorf("unexpect feild num %d", pos)
   303  		}
   304  	}
   305  	return nil
   306  }
   307  
   308  var _ Evidence = &DuplicateVoteEvidence{}
   309  
   310  // NewDuplicateVoteEvidence creates DuplicateVoteEvidence with right ordering given
   311  // two conflicting votes. If one of the votes is nil, evidence returned is nil as well
   312  func NewDuplicateVoteEvidence(pubkey crypto.PubKey, vote1 *Vote, vote2 *Vote) *DuplicateVoteEvidence {
   313  	var voteA, voteB *Vote
   314  	if vote1 == nil || vote2 == nil {
   315  		return nil
   316  	}
   317  	if strings.Compare(vote1.BlockID.Key(), vote2.BlockID.Key()) == -1 {
   318  		voteA = vote1
   319  		voteB = vote2
   320  	} else {
   321  		voteA = vote2
   322  		voteB = vote1
   323  	}
   324  	return &DuplicateVoteEvidence{
   325  		PubKey: pubkey,
   326  		VoteA:  voteA,
   327  		VoteB:  voteB,
   328  	}
   329  }
   330  
   331  // String returns a string representation of the evidence.
   332  func (dve *DuplicateVoteEvidence) String() string {
   333  	return fmt.Sprintf("VoteA: %v; VoteB: %v", dve.VoteA, dve.VoteB)
   334  
   335  }
   336  
   337  // Height returns the height this evidence refers to.
   338  func (dve *DuplicateVoteEvidence) Height() int64 {
   339  	return dve.VoteA.Height
   340  }
   341  
   342  // Time return the time the evidence was created
   343  func (dve *DuplicateVoteEvidence) Time() time.Time {
   344  	return dve.VoteA.Timestamp
   345  }
   346  
   347  // Address returns the address of the validator.
   348  func (dve *DuplicateVoteEvidence) Address() []byte {
   349  	return dve.PubKey.Address()
   350  }
   351  
   352  // Hash returns the hash of the evidence.
   353  func (dve *DuplicateVoteEvidence) Bytes() []byte {
   354  	return cdcEncode(dve)
   355  }
   356  
   357  // Hash returns the hash of the evidence.
   358  func (dve *DuplicateVoteEvidence) Hash() []byte {
   359  	return tmhash.Sum(cdcEncode(dve))
   360  }
   361  
   362  // Verify returns an error if the two votes aren't conflicting.
   363  // To be conflicting, they must be from the same validator, for the same H/R/S, but for different blocks.
   364  func (dve *DuplicateVoteEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
   365  	// H/R/S must be the same
   366  	if dve.VoteA.Height != dve.VoteB.Height ||
   367  		dve.VoteA.Round != dve.VoteB.Round ||
   368  		dve.VoteA.Type != dve.VoteB.Type {
   369  		return fmt.Errorf("duplicateVoteEvidence Error: H/R/S does not match. Got %v and %v", dve.VoteA, dve.VoteB)
   370  	}
   371  
   372  	// Address must be the same
   373  	if !bytes.Equal(dve.VoteA.ValidatorAddress, dve.VoteB.ValidatorAddress) {
   374  		return fmt.Errorf(
   375  			"duplicateVoteEvidence Error: Validator addresses do not match. Got %X and %X",
   376  			dve.VoteA.ValidatorAddress,
   377  			dve.VoteB.ValidatorAddress,
   378  		)
   379  	}
   380  
   381  	// Index must be the same
   382  	if dve.VoteA.ValidatorIndex != dve.VoteB.ValidatorIndex {
   383  		return fmt.Errorf(
   384  			"duplicateVoteEvidence Error: Validator indices do not match. Got %d and %d",
   385  			dve.VoteA.ValidatorIndex,
   386  			dve.VoteB.ValidatorIndex,
   387  		)
   388  	}
   389  
   390  	// BlockIDs must be different
   391  	if dve.VoteA.BlockID.Equals(dve.VoteB.BlockID) {
   392  		return fmt.Errorf(
   393  			"duplicateVoteEvidence Error: BlockIDs are the same (%v) - not a real duplicate vote",
   394  			dve.VoteA.BlockID,
   395  		)
   396  	}
   397  
   398  	// pubkey must match address (this should already be true, sanity check)
   399  	addr := dve.VoteA.ValidatorAddress
   400  	if !bytes.Equal(pubKey.Address(), addr) {
   401  		return fmt.Errorf("duplicateVoteEvidence FAILED SANITY CHECK - address (%X) doesn't match pubkey (%v - %X)",
   402  			addr, pubKey, pubKey.Address())
   403  	}
   404  
   405  	// Signatures must be valid
   406  	if !pubKey.VerifyBytes(dve.VoteA.SignBytes(chainID), dve.VoteA.Signature) {
   407  		return fmt.Errorf("duplicateVoteEvidence Error verifying VoteA: %v", ErrVoteInvalidSignature)
   408  	}
   409  	if !pubKey.VerifyBytes(dve.VoteB.SignBytes(chainID), dve.VoteB.Signature) {
   410  		return fmt.Errorf("duplicateVoteEvidence Error verifying VoteB: %v", ErrVoteInvalidSignature)
   411  	}
   412  
   413  	return nil
   414  }
   415  
   416  // Equal checks if two pieces of evidence are equal.
   417  func (dve *DuplicateVoteEvidence) Equal(ev Evidence) bool {
   418  	if _, ok := ev.(*DuplicateVoteEvidence); !ok {
   419  		return false
   420  	}
   421  
   422  	// just check their hashes
   423  	dveHash := tmhash.Sum(cdcEncode(dve))
   424  	evHash := tmhash.Sum(cdcEncode(ev))
   425  	fmt.Println(dveHash, evHash)
   426  	return bytes.Equal(dveHash, evHash)
   427  }
   428  
   429  // ValidateBasic performs basic validation.
   430  func (dve *DuplicateVoteEvidence) ValidateBasic() error {
   431  	if len(dve.PubKey.Bytes()) == 0 {
   432  		return errors.New("empty PubKey")
   433  	}
   434  	if dve.VoteA == nil || dve.VoteB == nil {
   435  		return fmt.Errorf("one or both of the votes are empty %v, %v", dve.VoteA, dve.VoteB)
   436  	}
   437  	if err := dve.VoteA.ValidateBasic(); err != nil {
   438  		return fmt.Errorf("invalid VoteA: %v", err)
   439  	}
   440  	if err := dve.VoteB.ValidateBasic(); err != nil {
   441  		return fmt.Errorf("invalid VoteB: %v", err)
   442  	}
   443  	// Enforce Votes are lexicographically sorted on blockID
   444  	if strings.Compare(dve.VoteA.BlockID.Key(), dve.VoteB.BlockID.Key()) >= 0 {
   445  		return errors.New("duplicate votes in invalid order")
   446  	}
   447  	return nil
   448  }
   449  
   450  //-----------------------------------------------------------------
   451  
   452  // UNSTABLE
   453  type MockRandomEvidence struct {
   454  	MockEvidence
   455  	randBytes []byte
   456  }
   457  
   458  var _ Evidence = &MockRandomEvidence{}
   459  
   460  // UNSTABLE
   461  func NewMockRandomEvidence(height int64, eTime time.Time, address []byte, randBytes []byte) MockRandomEvidence {
   462  	return MockRandomEvidence{
   463  		MockEvidence{
   464  			EvidenceHeight:  height,
   465  			EvidenceTime:    eTime,
   466  			EvidenceAddress: address}, randBytes,
   467  	}
   468  }
   469  
   470  func (e MockRandomEvidence) Hash() []byte {
   471  	return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes))
   472  }
   473  
   474  // UNSTABLE
   475  type MockEvidence struct {
   476  	EvidenceHeight  int64
   477  	EvidenceTime    time.Time
   478  	EvidenceAddress []byte
   479  }
   480  
   481  var _ Evidence = &MockEvidence{}
   482  
   483  // UNSTABLE
   484  func NewMockEvidence(height int64, eTime time.Time, idx int, address []byte) MockEvidence {
   485  	return MockEvidence{
   486  		EvidenceHeight:  height,
   487  		EvidenceTime:    eTime,
   488  		EvidenceAddress: address}
   489  }
   490  
   491  func (e MockEvidence) Height() int64   { return e.EvidenceHeight }
   492  func (e MockEvidence) Time() time.Time { return e.EvidenceTime }
   493  func (e MockEvidence) Address() []byte { return e.EvidenceAddress }
   494  func (e MockEvidence) Hash() []byte {
   495  	return []byte(fmt.Sprintf("%d-%x-%s",
   496  		e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
   497  }
   498  func (e MockEvidence) Bytes() []byte {
   499  	return []byte(fmt.Sprintf("%d-%x-%s",
   500  		e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
   501  }
   502  func (e MockEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil }
   503  func (e MockEvidence) Equal(ev Evidence) bool {
   504  	e2 := ev.(MockEvidence)
   505  	return e.EvidenceHeight == e2.EvidenceHeight &&
   506  		bytes.Equal(e.EvidenceAddress, e2.EvidenceAddress)
   507  }
   508  func (e MockEvidence) ValidateBasic() error { return nil }
   509  func (e MockEvidence) String() string {
   510  	return fmt.Sprintf("Evidence: %d/%s/%s", e.EvidenceHeight, e.Time(), e.EvidenceAddress)
   511  }
   512  
   513  //-------------------------------------------
   514  
   515  // EvidenceList is a list of Evidence. Evidences is not a word.
   516  type EvidenceList []Evidence
   517  
   518  // Hash returns the simple merkle root hash of the EvidenceList.
   519  func (evl EvidenceList) Hash() []byte {
   520  	// These allocations are required because Evidence is not of type Bytes, and
   521  	// golang slices can't be typed cast. This shouldn't be a performance problem since
   522  	// the Evidence size is capped.
   523  	evidenceBzs := make([][]byte, len(evl))
   524  	for i := 0; i < len(evl); i++ {
   525  		evidenceBzs[i] = evl[i].Bytes()
   526  	}
   527  	return merkle.SimpleHashFromByteSlices(evidenceBzs)
   528  }
   529  
   530  func (evl EvidenceList) String() string {
   531  	s := ""
   532  	for _, e := range evl {
   533  		s += fmt.Sprintf("%s\t\t", e)
   534  	}
   535  	return s
   536  }
   537  
   538  // Has returns true if the evidence is in the EvidenceList.
   539  func (evl EvidenceList) Has(evidence Evidence) bool {
   540  	for _, ev := range evl {
   541  		if ev.Equal(evidence) {
   542  			return true
   543  		}
   544  	}
   545  	return false
   546  }