github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/types/evidence_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  	"github.com/franono/tendermint/crypto"
    11  	"github.com/franono/tendermint/crypto/ed25519"
    12  	"github.com/franono/tendermint/crypto/tmhash"
    13  	tmrand "github.com/franono/tendermint/libs/rand"
    14  )
    15  
    16  type voteData struct {
    17  	vote1 *Vote
    18  	vote2 *Vote
    19  	valid bool
    20  }
    21  
    22  var defaultVoteTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
    23  
    24  func makeVote(
    25  	t *testing.T, val PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID BlockID,
    26  	time time.Time) *Vote {
    27  	pubKey, err := val.GetPubKey()
    28  	require.NoError(t, err)
    29  	v := &Vote{
    30  		ValidatorAddress: pubKey.Address(),
    31  		ValidatorIndex:   valIndex,
    32  		Height:           height,
    33  		Round:            round,
    34  		Type:             SignedMsgType(step),
    35  		Timestamp:        time,
    36  		BlockID:          blockID,
    37  	}
    38  	err = val.SignVote(chainID, v)
    39  	if err != nil {
    40  		panic(err)
    41  	}
    42  	return v
    43  }
    44  
    45  func TestEvidence(t *testing.T) {
    46  	val := NewMockPV()
    47  	val2 := NewMockPV()
    48  
    49  	blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
    50  	blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
    51  	blockID3 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash"))
    52  	blockID4 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash2"))
    53  
    54  	const chainID = "mychain"
    55  
    56  	vote1 := makeVote(t, val, chainID, 0, 10, 2, 1, blockID, defaultVoteTime)
    57  	err := val.SignVote(chainID, vote1)
    58  	require.NoError(t, err)
    59  	badVote := makeVote(t, val, chainID, 0, 10, 2, 1, blockID, defaultVoteTime)
    60  	err = val2.SignVote(chainID, badVote)
    61  	require.NoError(t, err)
    62  
    63  	cases := []voteData{
    64  		{vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID2, defaultVoteTime), true}, // different block ids
    65  		{vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID3, defaultVoteTime), true},
    66  		{vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID4, defaultVoteTime), true},
    67  		{vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID, defaultVoteTime), false},     // wrong block id
    68  		{vote1, makeVote(t, val, "mychain2", 0, 10, 2, 1, blockID2, defaultVoteTime), false}, // wrong chain id
    69  		{vote1, makeVote(t, val, chainID, 1, 10, 2, 1, blockID2, defaultVoteTime), false},    // wrong val index
    70  		{vote1, makeVote(t, val, chainID, 0, 11, 2, 1, blockID2, defaultVoteTime), false},    // wrong height
    71  		{vote1, makeVote(t, val, chainID, 0, 10, 3, 1, blockID2, defaultVoteTime), false},    // wrong round
    72  		{vote1, makeVote(t, val, chainID, 0, 10, 2, 2, blockID2, defaultVoteTime), false},    // wrong step
    73  		{vote1, makeVote(t, val2, chainID, 0, 10, 2, 1, blockID, defaultVoteTime), false},    // wrong validator
    74  		{vote1, makeVote(t, val2, chainID, 0, 10, 2, 1, blockID, time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)), false},
    75  		{vote1, badVote, false}, // signed by wrong key
    76  	}
    77  
    78  	pubKey, err := val.GetPubKey()
    79  	require.NoError(t, err)
    80  	for _, c := range cases {
    81  		ev := &DuplicateVoteEvidence{
    82  			VoteA: c.vote1,
    83  			VoteB: c.vote2,
    84  		}
    85  		if c.valid {
    86  			assert.Nil(t, ev.Verify(chainID, pubKey), "evidence should be valid")
    87  		} else {
    88  			assert.NotNil(t, ev.Verify(chainID, pubKey), "evidence should be invalid")
    89  		}
    90  	}
    91  }
    92  
    93  func TestDuplicatedVoteEvidence(t *testing.T) {
    94  	ev := randomDuplicatedVoteEvidence(t)
    95  
    96  	assert.True(t, ev.Equal(ev))
    97  	assert.False(t, ev.Equal(&DuplicateVoteEvidence{}))
    98  }
    99  
   100  func TestEvidenceList(t *testing.T) {
   101  	ev := randomDuplicatedVoteEvidence(t)
   102  	evl := EvidenceList([]Evidence{ev})
   103  
   104  	assert.NotNil(t, evl.Hash())
   105  	assert.True(t, evl.Has(ev))
   106  	assert.False(t, evl.Has(&DuplicateVoteEvidence{}))
   107  }
   108  
   109  func TestMaxEvidenceBytes(t *testing.T) {
   110  	val := NewMockPV()
   111  	blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   112  	blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   113  	maxTime := time.Date(9999, 0, 0, 0, 0, 0, 0, time.UTC)
   114  	const chainID = "mychain"
   115  	ev := &DuplicateVoteEvidence{
   116  		VoteA: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID, maxTime),
   117  		VoteB: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2, maxTime),
   118  	}
   119  
   120  	//TODO: Add other types of evidence to test and set MaxEvidenceBytes accordingly
   121  
   122  	// evl := &LunaticValidatorEvidence{
   123  	// Header: makeHeaderRandom(),
   124  	// Vote:   makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2),
   125  
   126  	// 	InvalidHeaderField: "",
   127  	// }
   128  
   129  	// evp := &PhantomValidatorEvidence{
   130  	// 	Header: makeHeaderRandom(),
   131  	// 	Vote:   makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2),
   132  
   133  	// 	LastHeightValidatorWasInSet: math.MaxInt64,
   134  	// }
   135  
   136  	// signedHeader := SignedHeader{Header: makeHeaderRandom(), Commit: randCommit(time.Now())}
   137  	// evc := &ConflictingHeadersEvidence{
   138  	// 	H1: &signedHeader,
   139  	// 	H2: &signedHeader,
   140  	// }
   141  
   142  	testCases := []struct {
   143  		testName string
   144  		evidence Evidence
   145  	}{
   146  		{"DuplicateVote", ev},
   147  		// {"LunaticValidatorEvidence", evl},
   148  		// {"PhantomValidatorEvidence", evp},
   149  		// {"ConflictingHeadersEvidence", evc},
   150  	}
   151  
   152  	for _, tt := range testCases {
   153  		bz, err := cdc.MarshalBinaryLengthPrefixed(tt.evidence)
   154  		require.NoError(t, err, tt.testName)
   155  
   156  		assert.LessOrEqual(t, int64(len(bz)), MaxEvidenceBytes, tt.testName)
   157  	}
   158  
   159  }
   160  
   161  func randomDuplicatedVoteEvidence(t *testing.T) *DuplicateVoteEvidence {
   162  	val := NewMockPV()
   163  	blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
   164  	blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
   165  	const chainID = "mychain"
   166  	return &DuplicateVoteEvidence{
   167  		VoteA: makeVote(t, val, chainID, 0, 10, 2, 1, blockID, defaultVoteTime),
   168  		VoteB: makeVote(t, val, chainID, 0, 10, 2, 1, blockID2, defaultVoteTime),
   169  	}
   170  }
   171  
   172  func TestDuplicateVoteEvidenceValidation(t *testing.T) {
   173  	val := NewMockPV()
   174  	blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   175  	blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   176  	const chainID = "mychain"
   177  
   178  	testCases := []struct {
   179  		testName         string
   180  		malleateEvidence func(*DuplicateVoteEvidence)
   181  		expectErr        bool
   182  	}{
   183  		{"Good DuplicateVoteEvidence", func(ev *DuplicateVoteEvidence) {}, false},
   184  		{"Nil vote A", func(ev *DuplicateVoteEvidence) { ev.VoteA = nil }, true},
   185  		{"Nil vote B", func(ev *DuplicateVoteEvidence) { ev.VoteB = nil }, true},
   186  		{"Nil votes", func(ev *DuplicateVoteEvidence) {
   187  			ev.VoteA = nil
   188  			ev.VoteB = nil
   189  		}, true},
   190  		{"Invalid vote type", func(ev *DuplicateVoteEvidence) {
   191  			ev.VoteA = makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0, blockID2, defaultVoteTime)
   192  		}, true},
   193  		{"Invalid vote order", func(ev *DuplicateVoteEvidence) {
   194  			swap := ev.VoteA.Copy()
   195  			ev.VoteA = ev.VoteB.Copy()
   196  			ev.VoteB = swap
   197  		}, true},
   198  	}
   199  	for _, tc := range testCases {
   200  		tc := tc
   201  		t.Run(tc.testName, func(t *testing.T) {
   202  			vote1 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID, defaultVoteTime)
   203  			vote2 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID2, defaultVoteTime)
   204  			ev := NewDuplicateVoteEvidence(vote1, vote2)
   205  			tc.malleateEvidence(ev)
   206  			assert.Equal(t, tc.expectErr, ev.ValidateBasic() != nil, "Validate Basic had an unexpected result")
   207  		})
   208  	}
   209  }
   210  
   211  func TestMockGoodEvidenceValidateBasic(t *testing.T) {
   212  	goodEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
   213  	assert.Nil(t, goodEvidence.ValidateBasic())
   214  }
   215  
   216  func TestMockBadEvidenceValidateBasic(t *testing.T) {
   217  	badEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
   218  	assert.Nil(t, badEvidence.ValidateBasic())
   219  }
   220  
   221  func TestLunaticValidatorEvidence(t *testing.T) {
   222  	var (
   223  		blockID  = makeBlockIDRandom()
   224  		header   = makeHeaderRandom()
   225  		bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
   226  		val      = NewMockPV()
   227  		vote     = makeVote(t, val, header.ChainID, 0, header.Height, 0, 2, blockID, defaultVoteTime)
   228  	)
   229  
   230  	header.Time = bTime
   231  
   232  	ev := &LunaticValidatorEvidence{
   233  		Header:             header,
   234  		Vote:               vote,
   235  		InvalidHeaderField: "AppHash",
   236  	}
   237  
   238  	assert.Equal(t, header.Height, ev.Height())
   239  	assert.Equal(t, bTime, ev.Time())
   240  	assert.EqualValues(t, vote.ValidatorAddress, ev.Address())
   241  	assert.NotEmpty(t, ev.Hash())
   242  	assert.NotEmpty(t, ev.Bytes())
   243  	pubKey, err := val.GetPubKey()
   244  	require.NoError(t, err)
   245  	assert.NoError(t, ev.Verify(header.ChainID, pubKey))
   246  	assert.Error(t, ev.Verify("other", pubKey))
   247  	privKey2 := ed25519.GenPrivKey()
   248  	pubKey2 := privKey2.PubKey()
   249  	assert.Error(t, ev.Verify("other", pubKey2))
   250  	assert.True(t, ev.Equal(ev))
   251  	assert.NoError(t, ev.ValidateBasic())
   252  	assert.NotEmpty(t, ev.String())
   253  }
   254  
   255  func TestPhantomValidatorEvidence(t *testing.T) {
   256  	var (
   257  		blockID = makeBlockIDRandom()
   258  		header  = makeHeaderRandom()
   259  		val     = NewMockPV()
   260  		vote    = makeVote(t, val, header.ChainID, 0, header.Height, 0, 2, blockID, defaultVoteTime)
   261  	)
   262  
   263  	ev := &PhantomValidatorEvidence{
   264  		Vote:                        vote,
   265  		LastHeightValidatorWasInSet: header.Height - 1,
   266  	}
   267  
   268  	assert.Equal(t, header.Height, ev.Height())
   269  	assert.Equal(t, defaultVoteTime, ev.Time())
   270  	assert.EqualValues(t, vote.ValidatorAddress, ev.Address())
   271  	assert.NotEmpty(t, ev.Hash())
   272  	assert.NotEmpty(t, ev.Bytes())
   273  	pubKey, err := val.GetPubKey()
   274  	require.NoError(t, err)
   275  	assert.NoError(t, ev.Verify(header.ChainID, pubKey))
   276  	assert.Error(t, ev.Verify("other", pubKey))
   277  	privKey2 := ed25519.GenPrivKey()
   278  	pubKey2 := privKey2.PubKey()
   279  	assert.Error(t, ev.Verify("other", pubKey2))
   280  	assert.True(t, ev.Equal(ev))
   281  	assert.NoError(t, ev.ValidateBasic())
   282  	assert.NotEmpty(t, ev.String())
   283  }
   284  
   285  func TestConflictingHeadersEvidence(t *testing.T) {
   286  	const (
   287  		chainID       = "TestConflictingHeadersEvidence"
   288  		height  int64 = 37
   289  	)
   290  
   291  	var (
   292  		blockID = makeBlockIDRandom()
   293  		header1 = makeHeaderRandom()
   294  		header2 = makeHeaderRandom()
   295  	)
   296  
   297  	header1.Height = height
   298  	header1.LastBlockID = blockID
   299  	header1.ChainID = chainID
   300  
   301  	header2.Height = height
   302  	header2.LastBlockID = blockID
   303  	header2.ChainID = chainID
   304  
   305  	voteSet1, valSet, vals := randVoteSet(height, 1, PrecommitType, 10, 1)
   306  	voteSet2 := NewVoteSet(chainID, height, 1, PrecommitType, valSet)
   307  
   308  	commit1, err := MakeCommit(BlockID{
   309  		Hash: header1.Hash(),
   310  		PartsHeader: PartSetHeader{
   311  			Total: 100,
   312  			Hash:  crypto.CRandBytes(tmhash.Size),
   313  		},
   314  	}, height, 1, voteSet1, vals, time.Now())
   315  	require.NoError(t, err)
   316  	commit2, err := MakeCommit(BlockID{
   317  		Hash: header2.Hash(),
   318  		PartsHeader: PartSetHeader{
   319  			Total: 100,
   320  			Hash:  crypto.CRandBytes(tmhash.Size),
   321  		},
   322  	}, height, 1, voteSet2, vals, time.Now())
   323  	require.NoError(t, err)
   324  
   325  	ev := &ConflictingHeadersEvidence{
   326  		H1: &SignedHeader{
   327  			Header: header1,
   328  			Commit: commit1,
   329  		},
   330  		H2: &SignedHeader{
   331  			Header: header2,
   332  			Commit: commit2,
   333  		},
   334  	}
   335  
   336  	assert.Panics(t, func() {
   337  		ev.Address()
   338  	})
   339  
   340  	assert.Panics(t, func() {
   341  		pubKey, _ := vals[0].GetPubKey()
   342  		ev.Verify(chainID, pubKey)
   343  	})
   344  
   345  	assert.Equal(t, height, ev.Height())
   346  	// assert.Equal(t, bTime, ev.Time())
   347  	assert.NotEmpty(t, ev.Hash())
   348  	assert.NotEmpty(t, ev.Bytes())
   349  	assert.NoError(t, ev.VerifyComposite(header1, valSet))
   350  	assert.True(t, ev.Equal(ev))
   351  	assert.NoError(t, ev.ValidateBasic())
   352  	assert.NotEmpty(t, ev.String())
   353  }
   354  
   355  func TestPotentialAmnesiaEvidence(t *testing.T) {
   356  	const (
   357  		chainID       = "TestPotentialAmnesiaEvidence"
   358  		height  int64 = 37
   359  	)
   360  
   361  	var (
   362  		val      = NewMockPV()
   363  		blockID  = makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   364  		blockID2 = makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   365  		vote1    = makeVote(t, val, chainID, 0, height, 0, 2, blockID, defaultVoteTime)
   366  		vote2    = makeVote(t, val, chainID, 0, height, 1, 2, blockID2, defaultVoteTime)
   367  	)
   368  
   369  	ev := &PotentialAmnesiaEvidence{
   370  		VoteA: vote2,
   371  		VoteB: vote1,
   372  	}
   373  
   374  	assert.Equal(t, height, ev.Height())
   375  	// assert.Equal(t, bTime, ev.Time())
   376  	assert.EqualValues(t, vote1.ValidatorAddress, ev.Address())
   377  	assert.NotEmpty(t, ev.Hash())
   378  	assert.NotEmpty(t, ev.Bytes())
   379  	pubKey, err := val.GetPubKey()
   380  	require.NoError(t, err)
   381  	assert.NoError(t, ev.Verify(chainID, pubKey))
   382  	assert.Error(t, ev.Verify("other", pubKey))
   383  	privKey2 := ed25519.GenPrivKey()
   384  	pubKey2 := privKey2.PubKey()
   385  	assert.Error(t, ev.Verify("other", pubKey2))
   386  	assert.True(t, ev.Equal(ev))
   387  	assert.NoError(t, ev.ValidateBasic())
   388  	assert.NotEmpty(t, ev.String())
   389  }
   390  
   391  func TestProofOfLockChange(t *testing.T) {
   392  	const (
   393  		chainID       = "TestProofOfLockChange"
   394  		height  int64 = 37
   395  	)
   396  	// 1: valid POLC - nothing should fail
   397  	voteSet, valSet, privValidators, blockID := buildVoteSet(height, 1, 3, 7, 0, PrecommitType)
   398  	pubKey, err := privValidators[7].GetPubKey()
   399  	require.NoError(t, err)
   400  	polc := makePOLCFromVoteSet(voteSet, pubKey, blockID)
   401  
   402  	assert.Equal(t, height, polc.Height())
   403  	assert.NoError(t, polc.ValidateBasic())
   404  	assert.True(t, polc.MajorityOfVotes(valSet))
   405  	assert.NotEmpty(t, polc.String())
   406  
   407  	// test validate basic on a set of bad cases
   408  	var badPOLCs []ProofOfLockChange
   409  	// 2: node has already voted in next round
   410  	pubKey, err = privValidators[0].GetPubKey()
   411  	require.NoError(t, err)
   412  	polc2 := makePOLCFromVoteSet(voteSet, pubKey, blockID)
   413  	badPOLCs = append(badPOLCs, polc2)
   414  	// 3: one vote was from a different round
   415  	voteSet, _, privValidators, blockID = buildVoteSet(height, 1, 3, 7, 0, PrecommitType)
   416  	pubKey, err = privValidators[7].GetPubKey()
   417  	require.NoError(t, err)
   418  	polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
   419  	badVote := makeVote(t, privValidators[8], chainID, 8, height, 2, 2, blockID, defaultVoteTime)
   420  	polc.Votes = append(polc.Votes, *badVote)
   421  	badPOLCs = append(badPOLCs, polc)
   422  	// 4: one vote was from a different height
   423  	polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
   424  	badVote = makeVote(t, privValidators[8], chainID, 8, height+1, 1, 2, blockID, defaultVoteTime)
   425  	polc.Votes = append(polc.Votes, *badVote)
   426  	badPOLCs = append(badPOLCs, polc)
   427  	// 5: one vote was from a different vote type
   428  	polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
   429  	badVote = makeVote(t, privValidators[8], chainID, 8, height, 1, 1, blockID, defaultVoteTime)
   430  	polc.Votes = append(polc.Votes, *badVote)
   431  	badPOLCs = append(badPOLCs, polc)
   432  	// 5: one of the votes was for a nil block
   433  	polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
   434  	badVote = makeVote(t, privValidators[8], chainID, 8, height, 1, 2, BlockID{}, defaultVoteTime)
   435  	polc.Votes = append(polc.Votes, *badVote)
   436  	badPOLCs = append(badPOLCs, polc)
   437  
   438  	for idx, polc := range badPOLCs {
   439  		err := polc.ValidateBasic()
   440  		assert.Error(t, err)
   441  		if err == nil {
   442  			t.Errorf("test no. %d failed", idx+2)
   443  		}
   444  	}
   445  
   446  }
   447  
   448  func makeHeaderRandom() *Header {
   449  	return &Header{
   450  		ChainID:            tmrand.Str(12),
   451  		Height:             int64(tmrand.Uint16()) + 1,
   452  		Time:               time.Now(),
   453  		LastBlockID:        makeBlockIDRandom(),
   454  		LastCommitHash:     crypto.CRandBytes(tmhash.Size),
   455  		DataHash:           crypto.CRandBytes(tmhash.Size),
   456  		ValidatorsHash:     crypto.CRandBytes(tmhash.Size),
   457  		NextValidatorsHash: crypto.CRandBytes(tmhash.Size),
   458  		ConsensusHash:      crypto.CRandBytes(tmhash.Size),
   459  		AppHash:            crypto.CRandBytes(tmhash.Size),
   460  		LastResultsHash:    crypto.CRandBytes(tmhash.Size),
   461  		EvidenceHash:       crypto.CRandBytes(tmhash.Size),
   462  		ProposerAddress:    crypto.CRandBytes(crypto.AddressSize),
   463  	}
   464  }
   465  
   466  func TestEvidenceProto(t *testing.T) {
   467  	// -------- Votes --------
   468  	val := NewMockPV()
   469  	blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   470  	blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
   471  	const chainID = "mychain"
   472  	v := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, 1, 0x01, blockID, defaultVoteTime)
   473  	v2 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, 2, 0x01, blockID2, defaultVoteTime)
   474  
   475  	// -------- SignedHeaders --------
   476  	const height int64 = 37
   477  
   478  	var (
   479  		header1 = makeHeaderRandom()
   480  		header2 = makeHeaderRandom()
   481  	)
   482  
   483  	header1.Height = height
   484  	header1.LastBlockID = blockID
   485  	header1.ChainID = chainID
   486  
   487  	header2.Height = height
   488  	header2.LastBlockID = blockID
   489  	header2.ChainID = chainID
   490  
   491  	voteSet1, valSet, vals := randVoteSet(height, 1, PrecommitType, 10, 1)
   492  	voteSet2 := NewVoteSet(chainID, height, 1, PrecommitType, valSet)
   493  
   494  	commit1, err := MakeCommit(BlockID{
   495  		Hash: header1.Hash(),
   496  		PartsHeader: PartSetHeader{
   497  			Total: 100,
   498  			Hash:  crypto.CRandBytes(tmhash.Size),
   499  		},
   500  	}, height, 1, voteSet1, vals, time.Now())
   501  	require.NoError(t, err)
   502  	commit2, err := MakeCommit(BlockID{
   503  		Hash: header2.Hash(),
   504  		PartsHeader: PartSetHeader{
   505  			Total: 100,
   506  			Hash:  crypto.CRandBytes(tmhash.Size),
   507  		},
   508  	}, height, 1, voteSet2, vals, time.Now())
   509  	require.NoError(t, err)
   510  
   511  	h1 := &SignedHeader{
   512  		Header: header1,
   513  		Commit: commit1,
   514  	}
   515  	h2 := &SignedHeader{
   516  		Header: header2,
   517  		Commit: commit2,
   518  	}
   519  
   520  	tests := []struct {
   521  		testName string
   522  		evidence Evidence
   523  		wantErr  bool
   524  		wantErr2 bool
   525  	}{
   526  		{"&DuplicateVoteEvidence empty fail", &DuplicateVoteEvidence{}, false, true},
   527  		{"&DuplicateVoteEvidence nil voteB", &DuplicateVoteEvidence{VoteA: v, VoteB: nil}, false, true},
   528  		{"&DuplicateVoteEvidence nil voteA", &DuplicateVoteEvidence{VoteA: nil, VoteB: v}, false, true},
   529  		{"&DuplicateVoteEvidence success", &DuplicateVoteEvidence{VoteA: v2, VoteB: v}, false, false},
   530  		{"&ConflictingHeadersEvidence empty fail", &ConflictingHeadersEvidence{}, false, true},
   531  		{"&ConflictingHeadersEvidence nil H2", &ConflictingHeadersEvidence{H1: h1, H2: nil}, false, true},
   532  		{"&ConflictingHeadersEvidence nil H1", &ConflictingHeadersEvidence{H1: nil, H2: h2}, false, true},
   533  		{"ConflictingHeadersEvidence empty fail", ConflictingHeadersEvidence{}, false, true},
   534  		{"ConflictingHeadersEvidence nil H2", ConflictingHeadersEvidence{H1: h1, H2: nil}, false, true},
   535  		{"ConflictingHeadersEvidence nil H1", ConflictingHeadersEvidence{H1: nil, H2: h2}, false, true},
   536  		{"ConflictingHeadersEvidence success", ConflictingHeadersEvidence{H1: h1, H2: h2}, false, false},
   537  		{"LunaticValidatorEvidence empty fail", LunaticValidatorEvidence{}, false, true},
   538  		{"LunaticValidatorEvidence only header fail", LunaticValidatorEvidence{Header: header1}, false, true},
   539  		{"LunaticValidatorEvidence only vote fail", LunaticValidatorEvidence{Vote: v}, false, true},
   540  		{"LunaticValidatorEvidence header & vote fail", LunaticValidatorEvidence{Header: header1, Vote: v}, false, true},
   541  		{"LunaticValidatorEvidence success", LunaticValidatorEvidence{Header: header1,
   542  			Vote: v, InvalidHeaderField: "ValidatorsHash"}, false, true},
   543  		{"&LunaticValidatorEvidence empty fail", &LunaticValidatorEvidence{}, false, true},
   544  		{"LunaticValidatorEvidence only header fail", &LunaticValidatorEvidence{Header: header1}, false, true},
   545  		{"LunaticValidatorEvidence only vote fail", &LunaticValidatorEvidence{Vote: v}, false, true},
   546  		{"LunaticValidatorEvidence header & vote fail", &LunaticValidatorEvidence{Header: header1, Vote: v}, false, true},
   547  		{"&LunaticValidatorEvidence empty fail", &LunaticValidatorEvidence{}, false, true},
   548  		{"PotentialAmnesiaEvidence empty fail", PotentialAmnesiaEvidence{}, false, true},
   549  		{"PotentialAmnesiaEvidence nil VoteB", PotentialAmnesiaEvidence{VoteA: v, VoteB: nil}, false, true},
   550  		{"PotentialAmnesiaEvidence nil VoteA", PotentialAmnesiaEvidence{VoteA: nil, VoteB: v2}, false, true},
   551  		{"&PotentialAmnesiaEvidence empty fail", &PotentialAmnesiaEvidence{}, false, true},
   552  		{"&PotentialAmnesiaEvidence nil VoteB", &PotentialAmnesiaEvidence{VoteA: v, VoteB: nil}, false, true},
   553  		{"&PotentialAmnesiaEvidence nil VoteA", &PotentialAmnesiaEvidence{VoteA: nil, VoteB: v2}, false, true},
   554  		{"&PotentialAmnesiaEvidence success", &PotentialAmnesiaEvidence{VoteA: v2, VoteB: v}, false, false},
   555  	}
   556  	for _, tt := range tests {
   557  		tt := tt
   558  		t.Run(tt.testName, func(t *testing.T) {
   559  			pb, err := EvidenceToProto(tt.evidence)
   560  			if tt.wantErr {
   561  				assert.Error(t, err, tt.testName)
   562  				return
   563  			}
   564  			assert.NoError(t, err, tt.testName)
   565  
   566  			evi, err := EvidenceFromProto(pb)
   567  			if tt.wantErr2 {
   568  				assert.Error(t, err, tt.testName)
   569  				return
   570  			}
   571  			require.Equal(t, tt.evidence, evi, tt.testName)
   572  		})
   573  	}
   574  }