Browse Source

state: more test cases for block validation (#5415)

Closes #2589
pull/5419/head
Anton Kaliaev 4 years ago
committed by GitHub
parent
commit
1635d1339c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 25 deletions
  1. +2
    -1
      rpc/client/http/http.go
  2. +1
    -7
      state/validation.go
  3. +20
    -0
      state/validation_test.go
  4. +6
    -16
      types/block.go
  5. +12
    -1
      types/block_test.go

+ 2
- 1
rpc/client/http/http.go View File

@ -116,7 +116,8 @@ func New(remote, wsEndpoint string) (*HTTP, error) {
return NewWithClient(remote, wsEndpoint, httpClient)
}
// Create timeout enabled http client
// NewWithTimeout does the same thing as New, except you can set a Timeout for
// http.Client. A Timeout of zero means no timeout.
func NewWithTimeout(remote, wsEndpoint string, timeout uint) (*HTTP, error) {
httpClient, err := jsonrpcclient.DefaultHTTPClient(remote)
if err != nil {


+ 1
- 7
state/validation.go View File

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/types"
)
@ -99,12 +98,7 @@ func validateBlock(evidencePool EvidencePool, state State, block *types.Block) e
// NOTE: We can't actually verify it's the right proposer because we don't
// know what round the block was first proposed. So just check that it's
// a legit address and a known validator.
if len(block.ProposerAddress) != crypto.AddressSize {
return fmt.Errorf("expected ProposerAddress size %d, got %d",
crypto.AddressSize,
len(block.ProposerAddress),
)
}
// The length is checked in ValidateBasic above.
if !state.Validators.HasAddress(block.ProposerAddress) {
return fmt.Errorf("block.Header.ProposerAddress %X is not a validator",
block.ProposerAddress,


+ 20
- 0
state/validation_test.go View File

@ -55,6 +55,7 @@ func TestValidateBlockHeader(t *testing.T) {
{"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 * 1) }},
{"Time wrong 2", func(block *types.Block) { block.Time = block.Time.Add(time.Second * 1) }},
{"LastBlockID wrong", func(block *types.Block) { block.LastBlockID.PartSetHeader.Total += 10 }},
{"LastCommitHash wrong", func(block *types.Block) { block.LastCommitHash = wrongHash }},
@ -69,6 +70,11 @@ func TestValidateBlockHeader(t *testing.T) {
{"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") }},
{"first LastCommit contains signatures", func(block *types.Block) {
block.LastCommit = types.NewCommit(0, 0, types.BlockID{}, []types.CommitSig{types.NewCommitSigAbsent()})
block.LastCommitHash = block.LastCommit.Hash()
}},
}
// Build up state for multiple heights
@ -81,6 +87,7 @@ func TestValidateBlockHeader(t *testing.T) {
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, nil, proposerAddr)
tc.malleateBlock(block)
err := blockExec.ValidateBlock(state, block)
t.Logf("%s: %v", tc.name, err)
require.Error(t, err, tc.name)
}
@ -91,6 +98,19 @@ func TestValidateBlockHeader(t *testing.T) {
state, _, lastCommit, err = makeAndCommitGoodBlock(state, height, lastCommit, proposerAddr, blockExec, privVals, nil)
require.NoError(t, err, "height %d", height)
}
nextHeight := validationTestsStopHeight
block, _ := state.MakeBlock(
nextHeight,
makeTxs(nextHeight),
lastCommit,
nil,
state.Validators.GetProposer().Address,
)
state.InitialHeight = nextHeight + 1
err := blockExec.ValidateBlock(state, block)
require.Error(t, err, "expected an error when state is ahead of block")
assert.Contains(t, err.Error(), "lower than initial height")
}
func TestValidateBlockCommit(t *testing.T) {


+ 6
- 16
types/block.go View File

@ -70,20 +70,13 @@ func (b *Block) ValidateBasic() error {
return fmt.Errorf("wrong LastCommit: %v", err)
}
if !bytes.Equal(b.LastCommitHash, b.LastCommit.Hash()) {
return fmt.Errorf("wrong Header.LastCommitHash. Expected %v, got %v",
b.LastCommit.Hash(),
b.LastCommitHash,
)
if w, g := b.LastCommit.Hash(), b.LastCommitHash; !bytes.Equal(w, g) {
return fmt.Errorf("wrong Header.LastCommitHash. Expected %X, got %X", w, g)
}
// NOTE: b.Data.Txs may be nil, but b.Data.Hash() still works fine.
if !bytes.Equal(b.DataHash, b.Data.Hash()) {
return fmt.Errorf(
"wrong Header.DataHash. Expected %v, got %v",
b.Data.Hash(),
b.DataHash,
)
if w, g := b.Data.Hash(), b.DataHash; !bytes.Equal(w, g) {
return fmt.Errorf("wrong Header.DataHash. Expected %X, got %X", w, g)
}
// NOTE: b.Evidence.Evidence may be nil, but we're just looping.
@ -93,11 +86,8 @@ func (b *Block) ValidateBasic() error {
}
}
if !bytes.Equal(b.EvidenceHash, b.Evidence.Hash()) {
return fmt.Errorf("wrong Header.EvidenceHash. Expected %v, got %v",
b.EvidenceHash,
b.Evidence.Hash(),
)
if w, g := b.Evidence.Hash(), b.EvidenceHash; !bytes.Equal(w, g) {
return fmt.Errorf("wrong Header.EvidenceHash. Expected %X, got %X", w, g)
}
return nil


+ 12
- 1
types/block_test.go View File

@ -85,11 +85,21 @@ func TestBlockValidateBasic(t *testing.T) {
blk.DataHash = tmrand.Bytes(len(blk.DataHash))
}, true},
{"Tampered EvidenceHash", func(blk *Block) {
blk.EvidenceHash = []byte("something else")
blk.EvidenceHash = tmrand.Bytes(len(blk.EvidenceHash))
}, true},
{"Incorrect block protocol version", func(blk *Block) {
blk.Version.Block = 1
}, true},
{"Missing LastCommit", func(blk *Block) {
blk.LastCommit = nil
}, true},
{"Invalid LastCommit", func(blk *Block) {
blk.LastCommit = NewCommit(-1, 0, *voteSet.maj23, nil)
}, true},
{"Invalid Evidence", func(blk *Block) {
emptyEv := &DuplicateVoteEvidence{}
blk.Evidence = EvidenceData{Evidence: []Evidence{emptyEv}}
}, true},
}
for i, tc := range testCases {
tc := tc
@ -99,6 +109,7 @@ func TestBlockValidateBasic(t *testing.T) {
block.ProposerAddress = valSet.GetProposer().Address
tc.malleateBlock(block)
err = block.ValidateBasic()
t.Log(err)
assert.Equal(t, tc.expErr, err != nil, "#%d: %v", i, err)
})
}


Loading…
Cancel
Save