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.

188 lines
5.2 KiB

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