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.

156 lines
5.7 KiB

  1. package state
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/stretchr/testify/require"
  6. "github.com/tendermint/tendermint/crypto/ed25519"
  7. "github.com/tendermint/tendermint/crypto/tmhash"
  8. "github.com/tendermint/tendermint/libs/log"
  9. "github.com/tendermint/tendermint/types"
  10. )
  11. // TODO(#2589):
  12. // - generalize this past the first height
  13. // - add txs and build up full State properly
  14. // - test block.Time (see #2587 - there are no conditions on time for the first height)
  15. func TestValidateBlockHeader(t *testing.T) {
  16. var height int64 = 1 // TODO(#2589): generalize
  17. state, stateDB := state(1, int(height))
  18. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), nil, nil, nil)
  19. // A good block passes.
  20. block := makeBlock(state, height)
  21. err := blockExec.ValidateBlock(state, block)
  22. require.NoError(t, err)
  23. // some bad values
  24. wrongHash := tmhash.Sum([]byte("this hash is wrong"))
  25. wrongVersion1 := state.Version.Consensus
  26. wrongVersion1.Block += 1
  27. wrongVersion2 := state.Version.Consensus
  28. wrongVersion2.App += 1
  29. // Manipulation of any header field causes failure.
  30. testCases := []struct {
  31. name string
  32. malleateBlock func(block *types.Block)
  33. }{
  34. {"Version wrong1", func(block *types.Block) { block.Version = wrongVersion1 }},
  35. {"Version wrong2", func(block *types.Block) { block.Version = wrongVersion2 }},
  36. {"ChainID wrong", func(block *types.Block) { block.ChainID = "not-the-real-one" }},
  37. {"Height wrong", func(block *types.Block) { block.Height += 10 }},
  38. {"Time wrong", func(block *types.Block) { block.Time = block.Time.Add(-time.Second * 3600 * 24) }},
  39. {"NumTxs wrong", func(block *types.Block) { block.NumTxs += 10 }},
  40. {"TotalTxs wrong", func(block *types.Block) { block.TotalTxs += 10 }},
  41. {"LastBlockID wrong", func(block *types.Block) { block.LastBlockID.PartsHeader.Total += 10 }},
  42. {"LastCommitHash wrong", func(block *types.Block) { block.LastCommitHash = wrongHash }},
  43. {"DataHash wrong", func(block *types.Block) { block.DataHash = wrongHash }},
  44. {"ValidatorsHash wrong", func(block *types.Block) { block.ValidatorsHash = wrongHash }},
  45. {"NextValidatorsHash wrong", func(block *types.Block) { block.NextValidatorsHash = wrongHash }},
  46. {"ConsensusHash wrong", func(block *types.Block) { block.ConsensusHash = wrongHash }},
  47. {"AppHash wrong", func(block *types.Block) { block.AppHash = wrongHash }},
  48. {"LastResultsHash wrong", func(block *types.Block) { block.LastResultsHash = wrongHash }},
  49. {"EvidenceHash wrong", func(block *types.Block) { block.EvidenceHash = wrongHash }},
  50. {"Proposer wrong", func(block *types.Block) { block.ProposerAddress = ed25519.GenPrivKey().PubKey().Address() }},
  51. {"Proposer invalid", func(block *types.Block) { block.ProposerAddress = []byte("wrong size") }},
  52. }
  53. for _, tc := range testCases {
  54. block := makeBlock(state, height)
  55. tc.malleateBlock(block)
  56. err := blockExec.ValidateBlock(state, block)
  57. require.Error(t, err, tc.name)
  58. }
  59. }
  60. /*
  61. TODO(#2589):
  62. - test Block.Data.Hash() == Block.DataHash
  63. - test len(Block.Data.Txs) == Block.NumTxs
  64. */
  65. func TestValidateBlockData(t *testing.T) {
  66. }
  67. /*
  68. TODO(#2589):
  69. - test len(block.LastCommit.Precommits) == state.LastValidators.Size()
  70. - test state.LastValidators.VerifyCommit
  71. */
  72. func TestValidateBlockCommit(t *testing.T) {
  73. }
  74. /*
  75. TODO(#2589):
  76. - test good/bad evidence in block
  77. */
  78. func TestValidateBlockEvidence(t *testing.T) {
  79. var height int64 = 1 // TODO(#2589): generalize
  80. state, stateDB := state(1, int(height))
  81. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), nil, nil, nil)
  82. // make some evidence
  83. addr, _ := state.Validators.GetByIndex(0)
  84. goodEvidence := types.NewMockGoodEvidence(height, 0, addr)
  85. // A block with a couple pieces of evidence passes.
  86. block := makeBlock(state, height)
  87. block.Evidence.Evidence = []types.Evidence{goodEvidence, goodEvidence}
  88. block.EvidenceHash = block.Evidence.Hash()
  89. err := blockExec.ValidateBlock(state, block)
  90. require.NoError(t, err)
  91. // A block with too much evidence fails.
  92. maxBlockSize := state.ConsensusParams.Block.MaxBytes
  93. maxNumEvidence, _ := types.MaxEvidencePerBlock(maxBlockSize)
  94. require.True(t, maxNumEvidence > 2)
  95. for i := int64(0); i < maxNumEvidence; i++ {
  96. block.Evidence.Evidence = append(block.Evidence.Evidence, goodEvidence)
  97. }
  98. block.EvidenceHash = block.Evidence.Hash()
  99. err = blockExec.ValidateBlock(state, block)
  100. require.Error(t, err)
  101. _, ok := err.(*types.ErrEvidenceOverflow)
  102. require.True(t, ok)
  103. }
  104. // always returns true if asked if any evidence was already committed.
  105. type mockEvPoolAlwaysCommitted struct{}
  106. func (m mockEvPoolAlwaysCommitted) PendingEvidence(int64) []types.Evidence { return nil }
  107. func (m mockEvPoolAlwaysCommitted) AddEvidence(types.Evidence) error { return nil }
  108. func (m mockEvPoolAlwaysCommitted) Update(*types.Block, State) {}
  109. func (m mockEvPoolAlwaysCommitted) IsCommitted(types.Evidence) bool { return true }
  110. func TestValidateFailBlockOnCommittedEvidence(t *testing.T) {
  111. var height int64 = 1
  112. state, stateDB := state(1, int(height))
  113. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), nil, nil, mockEvPoolAlwaysCommitted{})
  114. // A block with a couple pieces of evidence passes.
  115. block := makeBlock(state, height)
  116. addr, _ := state.Validators.GetByIndex(0)
  117. alreadyCommittedEvidence := types.NewMockGoodEvidence(height, 0, addr)
  118. block.Evidence.Evidence = []types.Evidence{alreadyCommittedEvidence}
  119. block.EvidenceHash = block.Evidence.Hash()
  120. err := blockExec.ValidateBlock(state, block)
  121. require.Error(t, err)
  122. require.IsType(t, err, &types.ErrEvidenceInvalid{})
  123. }
  124. /*
  125. TODO(#2589):
  126. - test unmarshalling BlockParts that are too big into a Block that
  127. (note this logic happens in the consensus, not in the validation here).
  128. - test making blocks from the types.MaxXXX functions works/fails as expected
  129. */
  130. func TestValidateBlockSize(t *testing.T) {
  131. }