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