github.com/line/ostracon@v1.0.10-0.20230328032236-7f20145f065d/rpc/client/evidence_test.go (about)

     1  package client_test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	abci "github.com/tendermint/tendermint/abci/types"
    13  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    14  
    15  	"github.com/line/ostracon/abci/example/kvstore"
    16  	ocabci "github.com/line/ostracon/abci/types"
    17  	"github.com/line/ostracon/crypto/ed25519"
    18  	cryptoenc "github.com/line/ostracon/crypto/encoding"
    19  	"github.com/line/ostracon/crypto/tmhash"
    20  	tmrand "github.com/line/ostracon/libs/rand"
    21  	"github.com/line/ostracon/privval"
    22  	"github.com/line/ostracon/rpc/client"
    23  	rpctest "github.com/line/ostracon/rpc/test"
    24  	"github.com/line/ostracon/types"
    25  )
    26  
    27  // For some reason the empty node used in tests has a time of
    28  // 2018-10-10 08:20:13.695936996 +0000 UTC
    29  // this is because the test genesis time is set here
    30  // so in order to validate evidence we need evidence to be the same time
    31  var defaultTestTime = time.Date(2018, 10, 10, 8, 20, 13, 695936996, time.UTC)
    32  
    33  func newEvidence(t *testing.T, val *privval.FilePV,
    34  	vote *types.Vote, vote2 *types.Vote,
    35  	chainID string) *types.DuplicateVoteEvidence {
    36  
    37  	var err error
    38  
    39  	v := vote.ToProto()
    40  	v2 := vote2.ToProto()
    41  
    42  	vote.Signature, err = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v))
    43  	require.NoError(t, err)
    44  
    45  	vote2.Signature, err = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v2))
    46  	require.NoError(t, err)
    47  
    48  	validator := types.NewValidator(val.Key.PubKey, 10)
    49  	valSet := types.NewValidatorSet([]*types.Validator{validator})
    50  
    51  	return types.NewDuplicateVoteEvidence(vote, vote2, defaultTestTime, valSet)
    52  }
    53  
    54  func makeEvidences(
    55  	t *testing.T,
    56  	val *privval.FilePV,
    57  	chainID string,
    58  ) (correct *types.DuplicateVoteEvidence, fakes []*types.DuplicateVoteEvidence) {
    59  	vote := types.Vote{
    60  		ValidatorAddress: val.Key.Address,
    61  		ValidatorIndex:   0,
    62  		Height:           1,
    63  		Round:            0,
    64  		Type:             tmproto.PrevoteType,
    65  		Timestamp:        defaultTestTime,
    66  		BlockID: types.BlockID{
    67  			Hash: tmhash.Sum(tmrand.Bytes(tmhash.Size)),
    68  			PartSetHeader: types.PartSetHeader{
    69  				Total: 1000,
    70  				Hash:  tmhash.Sum([]byte("partset")),
    71  			},
    72  		},
    73  	}
    74  
    75  	vote2 := vote
    76  	vote2.BlockID.Hash = tmhash.Sum([]byte("blockhash2"))
    77  	correct = newEvidence(t, val, &vote, &vote2, chainID)
    78  
    79  	fakes = make([]*types.DuplicateVoteEvidence, 0)
    80  
    81  	// different address
    82  	{
    83  		v := vote2
    84  		v.ValidatorAddress = []byte("some_address")
    85  		fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
    86  	}
    87  
    88  	// different height
    89  	{
    90  		v := vote2
    91  		v.Height = vote.Height + 1
    92  		fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
    93  	}
    94  
    95  	// different round
    96  	{
    97  		v := vote2
    98  		v.Round = vote.Round + 1
    99  		fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
   100  	}
   101  
   102  	// different type
   103  	{
   104  		v := vote2
   105  		v.Type = tmproto.PrecommitType
   106  		fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
   107  	}
   108  
   109  	// exactly same vote
   110  	{
   111  		v := vote
   112  		fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
   113  	}
   114  
   115  	return correct, fakes
   116  }
   117  
   118  func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
   119  	// https://github.com/tendermint/tendermint/pull/6678
   120  	// previous versions of this test used a shared fixture with
   121  	// other tests, and in this version we give it a little time
   122  	// for the node to make progress before running the test
   123  	time.Sleep(100 * time.Millisecond)
   124  	var (
   125  		config  = rpctest.GetConfig()
   126  		chainID = config.ChainID()
   127  		pv      = privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
   128  	)
   129  
   130  	for i, c := range GetClients() {
   131  		correct, fakes := makeEvidences(t, pv, chainID)
   132  		t.Logf("client %d", i)
   133  
   134  		result, err := c.BroadcastEvidence(context.Background(), correct)
   135  		require.NoError(t, err, "BroadcastEvidence(%s) failed", correct)
   136  		assert.Equal(t, correct.Hash(), result.Hash, "expected result hash to match evidence hash")
   137  
   138  		status, err := c.Status(context.Background())
   139  		require.NoError(t, err)
   140  		err = client.WaitForHeight(c, status.SyncInfo.LatestBlockHeight+2, nil)
   141  		require.NoError(t, err)
   142  
   143  		ed25519pub := pv.Key.PubKey.(ed25519.PubKey)
   144  		rawpub := ed25519pub.Bytes()
   145  		publicKey, err := cryptoenc.PubKeyToProto(pv.Key.PubKey)
   146  		assert.NoError(t, err)
   147  		pubStr, _ := kvstore.MakeValSetChangeTxAndMore(publicKey, 10)
   148  		// See kvstore.PersistentKVStoreApplication#Query
   149  		result2, err := c.ABCIQuery(context.Background(), "/val", []byte(pubStr))
   150  		require.NoError(t, err)
   151  		qres := result2.Response
   152  		require.True(t, qres.IsOK())
   153  
   154  		var v abci.ValidatorUpdate
   155  		err = ocabci.ReadMessage(bytes.NewReader(qres.Value), &v)
   156  		require.NoError(t, err, "Error reading query result, value %v", qres.Value)
   157  
   158  		pk, err := cryptoenc.PubKeyFromProto(&v.PubKey)
   159  		require.NoError(t, err)
   160  
   161  		require.EqualValues(t, rawpub, pk, "Stored PubKey not equal with expected, value %v", string(qres.Value))
   162  		require.Equal(t, int64(9), v.Power, "Stored Power not equal with expected, value %v", string(qres.Value))
   163  
   164  		for _, fake := range fakes {
   165  			_, err := c.BroadcastEvidence(context.Background(), fake)
   166  			require.Error(t, err, "BroadcastEvidence(%s) succeeded, but the evidence was fake", fake)
   167  		}
   168  	}
   169  }
   170  
   171  func TestBroadcastEmptyEvidence(t *testing.T) {
   172  	for _, c := range GetClients() {
   173  		_, err := c.BroadcastEvidence(context.Background(), nil)
   174  		assert.Error(t, err)
   175  	}
   176  }