- package state
-
- import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
-
- "github.com/tendermint/tendermint/crypto/ed25519"
- "github.com/tendermint/tendermint/crypto/tmhash"
- "github.com/tendermint/tendermint/libs/log"
- "github.com/tendermint/tendermint/types"
- )
-
- // TODO(#2589):
- // - generalize this past the first height
- // - add txs and build up full State properly
- // - test block.Time (see #2587 - there are no conditions on time for the first height)
- func TestValidateBlockHeader(t *testing.T) {
- var height int64 = 1 // TODO(#2589): generalize
- state, stateDB := state(1, int(height))
-
- blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), nil, nil, nil)
-
- // A good block passes.
- block := makeBlock(state, height)
- err := blockExec.ValidateBlock(state, block)
- require.NoError(t, err)
-
- // some bad values
- wrongHash := tmhash.Sum([]byte("this hash is wrong"))
- wrongVersion1 := state.Version.Consensus
- wrongVersion1.Block += 1
- wrongVersion2 := state.Version.Consensus
- wrongVersion2.App += 1
-
- // Manipulation of any header field causes failure.
- testCases := []struct {
- name string
- malleateBlock func(block *types.Block)
- }{
- {"Version wrong1", func(block *types.Block) { block.Version = wrongVersion1 }},
- {"Version wrong2", func(block *types.Block) { block.Version = wrongVersion2 }},
- {"ChainID wrong", func(block *types.Block) { block.ChainID = "not-the-real-one" }},
- {"Height wrong", func(block *types.Block) { block.Height += 10 }},
- {"Time wrong", func(block *types.Block) { block.Time = block.Time.Add(-time.Second * 3600 * 24) }},
- {"NumTxs wrong", func(block *types.Block) { block.NumTxs += 10 }},
- {"TotalTxs wrong", func(block *types.Block) { block.TotalTxs += 10 }},
-
- {"LastBlockID wrong", func(block *types.Block) { block.LastBlockID.PartsHeader.Total += 10 }},
- {"LastCommitHash wrong", func(block *types.Block) { block.LastCommitHash = wrongHash }},
- {"DataHash wrong", func(block *types.Block) { block.DataHash = wrongHash }},
-
- {"ValidatorsHash wrong", func(block *types.Block) { block.ValidatorsHash = wrongHash }},
- {"NextValidatorsHash wrong", func(block *types.Block) { block.NextValidatorsHash = wrongHash }},
- {"ConsensusHash wrong", func(block *types.Block) { block.ConsensusHash = wrongHash }},
- {"AppHash wrong", func(block *types.Block) { block.AppHash = wrongHash }},
- {"LastResultsHash wrong", func(block *types.Block) { block.LastResultsHash = wrongHash }},
-
- {"EvidenceHash wrong", func(block *types.Block) { block.EvidenceHash = wrongHash }},
- {"Proposer wrong", func(block *types.Block) { block.ProposerAddress = ed25519.GenPrivKey().PubKey().Address() }},
- {"Proposer invalid", func(block *types.Block) { block.ProposerAddress = []byte("wrong size") }},
- }
-
- for _, tc := range testCases {
- block := makeBlock(state, height)
- tc.malleateBlock(block)
- err := blockExec.ValidateBlock(state, block)
- require.Error(t, err, tc.name)
- }
- }
-
- /*
- TODO(#2589):
- - test Block.Data.Hash() == Block.DataHash
- - test len(Block.Data.Txs) == Block.NumTxs
- */
- func TestValidateBlockData(t *testing.T) {
- }
-
- /*
- TODO(#2589):
- - test len(block.LastCommit.Precommits) == state.LastValidators.Size()
- - test state.LastValidators.VerifyCommit
- */
- func TestValidateBlockCommit(t *testing.T) {
- }
-
- /*
- TODO(#2589):
- - test good/bad evidence in block
- */
- func TestValidateBlockEvidence(t *testing.T) {
- var height int64 = 1 // TODO(#2589): generalize
- state, stateDB := state(1, int(height))
-
- blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), nil, nil, nil)
-
- // make some evidence
- addr, _ := state.Validators.GetByIndex(0)
- goodEvidence := types.NewMockGoodEvidence(height, 0, addr)
-
- // A block with a couple pieces of evidence passes.
- block := makeBlock(state, height)
- block.Evidence.Evidence = []types.Evidence{goodEvidence, goodEvidence}
- block.EvidenceHash = block.Evidence.Hash()
- err := blockExec.ValidateBlock(state, block)
- require.NoError(t, err)
-
- // A block with too much evidence fails.
- maxBlockSize := state.ConsensusParams.BlockSize.MaxBytes
- maxNumEvidence, _ := types.MaxEvidencePerBlock(maxBlockSize)
- require.True(t, maxNumEvidence > 2)
- for i := int64(0); i < maxNumEvidence; i++ {
- block.Evidence.Evidence = append(block.Evidence.Evidence, goodEvidence)
- }
- block.EvidenceHash = block.Evidence.Hash()
- err = blockExec.ValidateBlock(state, block)
- require.Error(t, err)
- _, ok := err.(*types.ErrEvidenceOverflow)
- require.True(t, ok)
- }
-
- // always returns true if asked if any evidence was already committed.
- type mockEvPoolAlwaysCommitted struct{}
-
- func (m mockEvPoolAlwaysCommitted) PendingEvidence(int64) []types.Evidence { return nil }
- func (m mockEvPoolAlwaysCommitted) AddEvidence(types.Evidence) error { return nil }
- func (m mockEvPoolAlwaysCommitted) Update(*types.Block, State) {}
- func (m mockEvPoolAlwaysCommitted) IsCommitted(types.Evidence) bool { return true }
-
- func TestValidateFailBlockOnCommittedEvidence(t *testing.T) {
- var height int64 = 1
- state, stateDB := state(1, int(height))
-
- blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), nil, nil, mockEvPoolAlwaysCommitted{})
- // A block with a couple pieces of evidence passes.
- block := makeBlock(state, height)
- addr, _ := state.Validators.GetByIndex(0)
- alreadyCommittedEvidence := types.NewMockGoodEvidence(height, 0, addr)
- block.Evidence.Evidence = []types.Evidence{alreadyCommittedEvidence}
- block.EvidenceHash = block.Evidence.Hash()
- err := blockExec.ValidateBlock(state, block)
-
- require.Error(t, err)
- require.IsType(t, err, &types.ErrEvidenceInvalid{})
- }
-
- /*
- TODO(#2589):
- - test unmarshalling BlockParts that are too big into a Block that
- (note this logic happens in the consensus, not in the validation here).
- - test making blocks from the types.MaxXXX functions works/fails as expected
- */
- func TestValidateBlockSize(t *testing.T) {
- }
|