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 }