You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.4 KiB

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