mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-22 07:54:17 +00:00
Merge branch 'master' into jae/verifyingcachineprovider
This commit is contained in:
+1
-20
@@ -41,25 +41,6 @@ type Block struct {
|
||||
LastCommit *Commit `json:"last_commit"`
|
||||
}
|
||||
|
||||
// MakeBlock returns a new block with an empty header, except what can be
|
||||
// computed from itself.
|
||||
// It populates the same set of fields validated by ValidateBasic.
|
||||
func MakeBlock(height int64, txs []Tx, lastCommit *Commit, evidence []Evidence) *Block {
|
||||
block := &Block{
|
||||
Header: Header{
|
||||
Height: height,
|
||||
NumTxs: int64(len(txs)),
|
||||
},
|
||||
Data: Data{
|
||||
Txs: txs,
|
||||
},
|
||||
Evidence: EvidenceData{Evidence: evidence},
|
||||
LastCommit: lastCommit,
|
||||
}
|
||||
block.fillHeader()
|
||||
return block
|
||||
}
|
||||
|
||||
// ValidateBasic performs basic validation that doesn't involve state data.
|
||||
// It checks the internal consistency of the block.
|
||||
// Further validation is done using state#ValidateBlock.
|
||||
@@ -800,7 +781,7 @@ func (sh SignedHeader) ValidateBasic(chainID string) error {
|
||||
// ValidateBasic on the Commit.
|
||||
err := sh.Commit.ValidateBasic()
|
||||
if err != nil {
|
||||
return cmn.ErrorWrap(err, "commit.ValidateBasic failed during SignedHeader.ValidateBasic")
|
||||
return errors.Wrap(err, "commit.ValidateBasic failed during SignedHeader.ValidateBasic")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -366,3 +366,91 @@ func TestCommitToVoteSet(t *testing.T) {
|
||||
assert.Equal(t, vote1bz, vote3bz)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignedHeaderValidateBasic(t *testing.T) {
|
||||
commit := randCommit()
|
||||
chainID := "𠜎"
|
||||
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
|
||||
h := Header{
|
||||
Version: version.Consensus{Block: math.MaxInt64, App: math.MaxInt64},
|
||||
ChainID: chainID,
|
||||
Height: commit.Height(),
|
||||
Time: timestamp,
|
||||
NumTxs: math.MaxInt64,
|
||||
TotalTxs: math.MaxInt64,
|
||||
LastBlockID: commit.BlockID,
|
||||
LastCommitHash: commit.Hash(),
|
||||
DataHash: commit.Hash(),
|
||||
ValidatorsHash: commit.Hash(),
|
||||
NextValidatorsHash: commit.Hash(),
|
||||
ConsensusHash: commit.Hash(),
|
||||
AppHash: commit.Hash(),
|
||||
LastResultsHash: commit.Hash(),
|
||||
EvidenceHash: commit.Hash(),
|
||||
ProposerAddress: crypto.AddressHash([]byte("proposer_address")),
|
||||
}
|
||||
|
||||
validSignedHeader := SignedHeader{Header: &h, Commit: commit}
|
||||
validSignedHeader.Commit.BlockID.Hash = validSignedHeader.Hash()
|
||||
invalidSignedHeader := SignedHeader{}
|
||||
|
||||
testCases := []struct {
|
||||
testName string
|
||||
shHeader *Header
|
||||
shCommit *Commit
|
||||
expectErr bool
|
||||
}{
|
||||
{"Valid Signed Header", validSignedHeader.Header, validSignedHeader.Commit, false},
|
||||
{"Invalid Signed Header", invalidSignedHeader.Header, validSignedHeader.Commit, true},
|
||||
{"Invalid Signed Header", validSignedHeader.Header, invalidSignedHeader.Commit, true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
sh := SignedHeader{
|
||||
Header: tc.shHeader,
|
||||
Commit: tc.shCommit,
|
||||
}
|
||||
assert.Equal(t, tc.expectErr, sh.ValidateBasic(validSignedHeader.Header.ChainID) != nil, "Validate Basic had an unexpected result")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockIDValidateBasic(t *testing.T) {
|
||||
validBlockID := BlockID{
|
||||
Hash: cmn.HexBytes{},
|
||||
PartsHeader: PartSetHeader{
|
||||
Total: 1,
|
||||
Hash: cmn.HexBytes{},
|
||||
},
|
||||
}
|
||||
|
||||
invalidBlockID := BlockID{
|
||||
Hash: []byte{0},
|
||||
PartsHeader: PartSetHeader{
|
||||
Total: -1,
|
||||
Hash: cmn.HexBytes{},
|
||||
},
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
testName string
|
||||
blockIDHash cmn.HexBytes
|
||||
blockIDPartsHeader PartSetHeader
|
||||
expectErr bool
|
||||
}{
|
||||
{"Valid BlockID", validBlockID.Hash, validBlockID.PartsHeader, false},
|
||||
{"Invalid BlockID", invalidBlockID.Hash, validBlockID.PartsHeader, true},
|
||||
{"Invalid BlockID", validBlockID.Hash, invalidBlockID.PartsHeader, true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
blockID := BlockID{
|
||||
Hash: tc.blockIDHash,
|
||||
PartsHeader: tc.blockIDPartsHeader,
|
||||
}
|
||||
assert.Equal(t, tc.expectErr, blockID.ValidateBasic() != nil, "Validate Basic had an unexpected result")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,3 +157,13 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMockGoodEvidenceValidateBasic(t *testing.T) {
|
||||
goodEvidence := NewMockGoodEvidence(int64(1), 1, []byte{1})
|
||||
assert.Nil(t, goodEvidence.ValidateBasic())
|
||||
}
|
||||
|
||||
func TestMockBadEvidenceValidateBasic(t *testing.T) {
|
||||
badEvidence := MockBadEvidence{MockGoodEvidence: NewMockGoodEvidence(int64(1), 1, []byte{1})}
|
||||
assert.Nil(t, badEvidence.ValidateBasic())
|
||||
}
|
||||
|
||||
+10
-10
@@ -7,6 +7,8 @@ import (
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
@@ -64,26 +66,24 @@ func (genDoc *GenesisDoc) ValidatorHash() []byte {
|
||||
// and fills in defaults for optional fields left empty
|
||||
func (genDoc *GenesisDoc) ValidateAndComplete() error {
|
||||
if genDoc.ChainID == "" {
|
||||
return cmn.NewError("Genesis doc must include non-empty chain_id")
|
||||
return errors.New("Genesis doc must include non-empty chain_id")
|
||||
}
|
||||
if len(genDoc.ChainID) > MaxChainIDLen {
|
||||
return cmn.NewError("chain_id in genesis doc is too long (max: %d)", MaxChainIDLen)
|
||||
return errors.Errorf("chain_id in genesis doc is too long (max: %d)", MaxChainIDLen)
|
||||
}
|
||||
|
||||
if genDoc.ConsensusParams == nil {
|
||||
genDoc.ConsensusParams = DefaultConsensusParams()
|
||||
} else {
|
||||
if err := genDoc.ConsensusParams.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := genDoc.ConsensusParams.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, v := range genDoc.Validators {
|
||||
if v.Power == 0 {
|
||||
return cmn.NewError("The genesis file cannot contain validators with no voting power: %v", v)
|
||||
return errors.Errorf("The genesis file cannot contain validators with no voting power: %v", v)
|
||||
}
|
||||
if len(v.Address) > 0 && !bytes.Equal(v.PubKey.Address(), v.Address) {
|
||||
return cmn.NewError("Incorrect address for validator %v in the genesis file, should be %v", v, v.PubKey.Address())
|
||||
return errors.Errorf("Incorrect address for validator %v in the genesis file, should be %v", v, v.PubKey.Address())
|
||||
}
|
||||
if len(v.Address) == 0 {
|
||||
genDoc.Validators[i].Address = v.PubKey.Address()
|
||||
@@ -119,11 +119,11 @@ func GenesisDocFromJSON(jsonBlob []byte) (*GenesisDoc, error) {
|
||||
func GenesisDocFromFile(genDocFile string) (*GenesisDoc, error) {
|
||||
jsonBlob, err := ioutil.ReadFile(genDocFile)
|
||||
if err != nil {
|
||||
return nil, cmn.ErrorWrap(err, "Couldn't read GenesisDoc file")
|
||||
return nil, errors.Wrap(err, "Couldn't read GenesisDoc file")
|
||||
}
|
||||
genDoc, err := GenesisDocFromJSON(jsonBlob)
|
||||
if err != nil {
|
||||
return nil, cmn.ErrorWrap(err, fmt.Sprintf("Error reading GenesisDoc at %v", genDocFile))
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("Error reading GenesisDoc at %v", genDocFile))
|
||||
}
|
||||
return genDoc, nil
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestGenesisGood(t *testing.T) {
|
||||
genDoc.ConsensusParams.Block.MaxBytes = 0
|
||||
genDocBytes, err = cdc.MarshalJSON(genDoc)
|
||||
assert.NoError(t, err, "error marshalling genDoc")
|
||||
genDoc, err = GenesisDocFromJSON(genDocBytes)
|
||||
_, err = GenesisDocFromJSON(genDocBytes)
|
||||
assert.Error(t, err, "expected error for genDoc json with block size of 0")
|
||||
|
||||
// Genesis doc from raw json
|
||||
|
||||
+9
-7
@@ -1,6 +1,8 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
@@ -95,38 +97,38 @@ func (params *ValidatorParams) IsValidPubkeyType(pubkeyType string) bool {
|
||||
// allowed limits, and returns an error if they are not.
|
||||
func (params *ConsensusParams) Validate() error {
|
||||
if params.Block.MaxBytes <= 0 {
|
||||
return cmn.NewError("Block.MaxBytes must be greater than 0. Got %d",
|
||||
return errors.Errorf("Block.MaxBytes must be greater than 0. Got %d",
|
||||
params.Block.MaxBytes)
|
||||
}
|
||||
if params.Block.MaxBytes > MaxBlockSizeBytes {
|
||||
return cmn.NewError("Block.MaxBytes is too big. %d > %d",
|
||||
return errors.Errorf("Block.MaxBytes is too big. %d > %d",
|
||||
params.Block.MaxBytes, MaxBlockSizeBytes)
|
||||
}
|
||||
|
||||
if params.Block.MaxGas < -1 {
|
||||
return cmn.NewError("Block.MaxGas must be greater or equal to -1. Got %d",
|
||||
return errors.Errorf("Block.MaxGas must be greater or equal to -1. Got %d",
|
||||
params.Block.MaxGas)
|
||||
}
|
||||
|
||||
if params.Block.TimeIotaMs <= 0 {
|
||||
return cmn.NewError("Block.TimeIotaMs must be greater than 0. Got %v",
|
||||
return errors.Errorf("Block.TimeIotaMs must be greater than 0. Got %v",
|
||||
params.Block.TimeIotaMs)
|
||||
}
|
||||
|
||||
if params.Evidence.MaxAge <= 0 {
|
||||
return cmn.NewError("EvidenceParams.MaxAge must be greater than 0. Got %d",
|
||||
return errors.Errorf("EvidenceParams.MaxAge must be greater than 0. Got %d",
|
||||
params.Evidence.MaxAge)
|
||||
}
|
||||
|
||||
if len(params.Validator.PubKeyTypes) == 0 {
|
||||
return cmn.NewError("len(Validator.PubKeyTypes) must be greater than 0")
|
||||
return errors.New("len(Validator.PubKeyTypes) must be greater than 0")
|
||||
}
|
||||
|
||||
// Check if keyType is a known ABCIPubKeyType
|
||||
for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
|
||||
keyType := params.Validator.PubKeyTypes[i]
|
||||
if _, ok := ABCIPubKeyTypesToAminoNames[keyType]; !ok {
|
||||
return cmn.NewError("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
|
||||
return errors.Errorf("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
|
||||
i, keyType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
// PrivValidator defines the functionality of a local Tendermint validator
|
||||
// that signs votes and proposals, and never double signs.
|
||||
type PrivValidator interface {
|
||||
// TODO: Extend the interface to return errors too. Issue: https://github.com/tendermint/tendermint/issues/3602
|
||||
GetPubKey() crypto.PubKey
|
||||
|
||||
SignVote(chainID string, vote *Vote) error
|
||||
|
||||
+38
-2
@@ -5,8 +5,7 @@ import (
|
||||
)
|
||||
|
||||
func MakeCommit(blockID BlockID, height int64, round int,
|
||||
voteSet *VoteSet,
|
||||
validators []PrivValidator) (*Commit, error) {
|
||||
voteSet *VoteSet, validators []PrivValidator) (*Commit, error) {
|
||||
|
||||
// all sign
|
||||
for i := 0; i < len(validators); i++ {
|
||||
@@ -37,3 +36,40 @@ func signAddVote(privVal PrivValidator, vote *Vote, voteSet *VoteSet) (signed bo
|
||||
}
|
||||
return voteSet.AddVote(vote)
|
||||
}
|
||||
|
||||
func MakeVote(height int64, blockID BlockID, valSet *ValidatorSet, privVal PrivValidator, chainID string) (*Vote, error) {
|
||||
addr := privVal.GetPubKey().Address()
|
||||
idx, _ := valSet.GetByAddress(addr)
|
||||
vote := &Vote{
|
||||
ValidatorAddress: addr,
|
||||
ValidatorIndex: idx,
|
||||
Height: height,
|
||||
Round: 0,
|
||||
Timestamp: tmtime.Now(),
|
||||
Type: PrecommitType,
|
||||
BlockID: blockID,
|
||||
}
|
||||
if err := privVal.SignVote(chainID, vote); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return vote, nil
|
||||
}
|
||||
|
||||
// MakeBlock returns a new block with an empty header, except what can be
|
||||
// computed from itself.
|
||||
// It populates the same set of fields validated by ValidateBasic.
|
||||
func MakeBlock(height int64, txs []Tx, lastCommit *Commit, evidence []Evidence) *Block {
|
||||
block := &Block{
|
||||
Header: Header{
|
||||
Height: height,
|
||||
NumTxs: int64(len(txs)),
|
||||
},
|
||||
Data: Data{
|
||||
Txs: txs,
|
||||
},
|
||||
Evidence: EvidenceData{Evidence: evidence},
|
||||
LastCommit: lastCommit,
|
||||
}
|
||||
block.fillHeader()
|
||||
return block
|
||||
}
|
||||
|
||||
+8
-6
@@ -41,17 +41,19 @@ func (v *Validator) CompareProposerPriority(other *Validator) *Validator {
|
||||
if v == nil {
|
||||
return other
|
||||
}
|
||||
if v.ProposerPriority > other.ProposerPriority {
|
||||
switch {
|
||||
case v.ProposerPriority > other.ProposerPriority:
|
||||
return v
|
||||
} else if v.ProposerPriority < other.ProposerPriority {
|
||||
case v.ProposerPriority < other.ProposerPriority:
|
||||
return other
|
||||
} else {
|
||||
default:
|
||||
result := bytes.Compare(v.Address, other.Address)
|
||||
if result < 0 {
|
||||
switch {
|
||||
case result < 0:
|
||||
return v
|
||||
} else if result > 0 {
|
||||
case result > 0:
|
||||
return other
|
||||
} else {
|
||||
default:
|
||||
panic("Cannot compare identical validators")
|
||||
}
|
||||
}
|
||||
|
||||
+8
-14
@@ -2,15 +2,15 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
// MaxTotalVotingPower - the maximum allowed total voting power.
|
||||
@@ -121,7 +121,7 @@ func (vals *ValidatorSet) RescalePriorities(diffMax int64) {
|
||||
ratio := (diff + diffMax - 1) / diffMax
|
||||
if diff > diffMax {
|
||||
for _, val := range vals.Validators {
|
||||
val.ProposerPriority = val.ProposerPriority / ratio
|
||||
val.ProposerPriority /= ratio
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -525,7 +525,7 @@ func (vals *ValidatorSet) applyRemovals(deletes []*Validator) {
|
||||
// The 'allowDeletes' flag is set to false by NewValidatorSet() and to true by UpdateWithChangeSet().
|
||||
func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes bool) error {
|
||||
|
||||
if len(changes) <= 0 {
|
||||
if len(changes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -626,9 +626,10 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height i
|
||||
if blockID.Equals(precommit.BlockID) {
|
||||
talliedVotingPower += val.VotingPower
|
||||
}
|
||||
|
||||
// else {
|
||||
// It's OK that the BlockID doesn't match. We include stray
|
||||
// precommits to measure validator availability.
|
||||
// }
|
||||
}
|
||||
|
||||
if talliedVotingPower > vals.TotalVotingPower()*2/3 {
|
||||
@@ -642,15 +643,8 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height i
|
||||
|
||||
// IsErrTooMuchChange
|
||||
func IsErrTooMuchChange(err error) bool {
|
||||
switch err_ := err.(type) {
|
||||
case cmn.Error:
|
||||
_, ok := err_.Data().(errTooMuchChange)
|
||||
return ok
|
||||
case errTooMuchChange:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
_, ok := errors.Cause(err).(errTooMuchChange)
|
||||
return ok
|
||||
}
|
||||
|
||||
type errTooMuchChange struct {
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
tst "github.com/tendermint/tendermint/libs/test"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
)
|
||||
|
||||
@@ -490,7 +491,7 @@ func TestMakeCommit(t *testing.T) {
|
||||
}
|
||||
|
||||
// MakeCommit should fail.
|
||||
tst.AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeCommit() })
|
||||
assert.Panics(t, func() { voteSet.MakeCommit() }, "Doesn't have +2/3 majority")
|
||||
|
||||
// 7th voted for some other block.
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
Reference in New Issue
Block a user