diff --git a/rpc/client/http/http.go b/rpc/client/http/http.go index 292609ccb..8fc0c7a91 100644 --- a/rpc/client/http/http.go +++ b/rpc/client/http/http.go @@ -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 { diff --git a/state/validation.go b/state/validation.go index 4bcf11721..694090a5c 100644 --- a/state/validation.go +++ b/state/validation.go @@ -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, diff --git a/state/validation_test.go b/state/validation_test.go index a4b0667c8..717cb715c 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -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) { diff --git a/types/block.go b/types/block.go index 749770768..e52d2b1a3 100644 --- a/types/block.go +++ b/types/block.go @@ -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 diff --git a/types/block_test.go b/types/block_test.go index eb7d29237..6953f2556 100644 --- a/types/block_test.go +++ b/types/block_test.go @@ -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) }) }