Move VerifyCommitAny into the types package
This commit is contained in:
parent
b4fd6e876e
commit
94b36bb65e
|
@ -1,8 +1,6 @@
|
|||
package certifiers
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
certerr "github.com/tendermint/tendermint/certifiers/errors"
|
||||
|
@ -78,7 +76,7 @@ func (c *Dynamic) Update(fc FullCommit) error {
|
|||
// would be approved by the currently known validator set
|
||||
// as well as the new set
|
||||
commit := fc.Commit.Commit
|
||||
err = VerifyCommitAny(c.Validators(), fc.Validators, c.ChainID(),
|
||||
err = c.Validators().VerifyCommitAny(fc.Validators, c.ChainID(),
|
||||
commit.BlockID, h, commit)
|
||||
if err != nil {
|
||||
return certerr.ErrTooMuchChange()
|
||||
|
@ -89,85 +87,3 @@ func (c *Dynamic) Update(fc FullCommit) error {
|
|||
c.lastHeight = h
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyCommitAny will check to see if the set would
|
||||
// be valid with a different validator set.
|
||||
//
|
||||
// old is the validator set that we know
|
||||
// * over 2/3 of the power in old signed this block
|
||||
//
|
||||
// cur is the validator set that signed this block
|
||||
// * only votes from old are sufficient for 2/3 majority
|
||||
// in the new set as well
|
||||
//
|
||||
// That means that:
|
||||
// * 10% of the valset can't just declare themselves kings
|
||||
// * If the validator set is 3x old size, we need more proof to trust
|
||||
//
|
||||
// *** TODO: move this.
|
||||
// It belongs in tendermint/types/validator_set.go: VerifyCommitAny
|
||||
func VerifyCommitAny(old, cur *types.ValidatorSet, chainID string,
|
||||
blockID types.BlockID, height int, commit *types.Commit) error {
|
||||
|
||||
if cur.Size() != len(commit.Precommits) {
|
||||
return errors.Errorf("Invalid commit -- wrong set size: %v vs %v", cur.Size(), len(commit.Precommits))
|
||||
}
|
||||
if height != commit.Height() {
|
||||
return errors.Errorf("Invalid commit -- wrong height: %v vs %v", height, commit.Height())
|
||||
}
|
||||
|
||||
oldVotingPower := int64(0)
|
||||
curVotingPower := int64(0)
|
||||
seen := map[int]bool{}
|
||||
round := commit.Round()
|
||||
|
||||
for idx, precommit := range commit.Precommits {
|
||||
// first check as in VerifyCommit
|
||||
if precommit == nil {
|
||||
continue
|
||||
}
|
||||
if precommit.Height != height {
|
||||
return certerr.ErrHeightMismatch(height, precommit.Height)
|
||||
}
|
||||
if precommit.Round != round {
|
||||
return errors.Errorf("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
|
||||
}
|
||||
if precommit.Type != types.VoteTypePrecommit {
|
||||
return errors.Errorf("Invalid commit -- not precommit @ index %v", idx)
|
||||
}
|
||||
if !blockID.Equals(precommit.BlockID) {
|
||||
continue // Not an error, but doesn't count
|
||||
}
|
||||
|
||||
// we only grab by address, ignoring unknown validators
|
||||
vi, ov := old.GetByAddress(precommit.ValidatorAddress)
|
||||
if ov == nil || seen[vi] {
|
||||
continue // missing or double vote...
|
||||
}
|
||||
seen[vi] = true
|
||||
|
||||
// Validate signature old school
|
||||
precommitSignBytes := types.SignBytes(chainID, precommit)
|
||||
if !ov.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
|
||||
return errors.Errorf("Invalid commit -- invalid signature: %v", precommit)
|
||||
}
|
||||
// Good precommit!
|
||||
oldVotingPower += ov.VotingPower
|
||||
|
||||
// check new school
|
||||
_, cv := cur.GetByIndex(idx)
|
||||
if cv.PubKey.Equals(ov.PubKey) {
|
||||
// make sure this is properly set in the current block as well
|
||||
curVotingPower += cv.VotingPower
|
||||
}
|
||||
}
|
||||
|
||||
if oldVotingPower <= old.TotalVotingPower()*2/3 {
|
||||
return errors.Errorf("Invalid commit -- insufficient old voting power: got %v, needed %v",
|
||||
oldVotingPower, (old.TotalVotingPower()*2/3 + 1))
|
||||
} else if curVotingPower <= cur.TotalVotingPower()*2/3 {
|
||||
return errors.Errorf("Invalid commit -- insufficient cur voting power: got %v, needed %v",
|
||||
curVotingPower, (cur.TotalVotingPower()*2/3 + 1))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tendermint/go-wire"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
|
@ -268,30 +269,84 @@ func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height
|
|||
}
|
||||
}
|
||||
|
||||
// Verify that +2/3 of this set had signed the given signBytes.
|
||||
// Unlike VerifyCommit(), this function can verify commits with differeent sets.
|
||||
func (valSet *ValidatorSet) VerifyCommitAny(chainID string, blockID BlockID, height int, commit *Commit) error {
|
||||
panic("Not yet implemented")
|
||||
/*
|
||||
Start like:
|
||||
// VerifyCommitAny will check to see if the set would
|
||||
// be valid with a different validator set.
|
||||
//
|
||||
// valSet is the validator set that we know
|
||||
// * over 2/3 of the power in old signed this block
|
||||
//
|
||||
// newSet is the validator set that signed this block
|
||||
// * only votes from old are sufficient for 2/3 majority
|
||||
// in the new set as well
|
||||
//
|
||||
// That means that:
|
||||
// * 10% of the valset can't just declare themselves kings
|
||||
// * If the validator set is 3x old size, we need more proof to trust
|
||||
func (valSet *ValidatorSet) VerifyCommitAny(newSet *ValidatorSet, chainID string,
|
||||
blockID BlockID, height int, commit *Commit) error {
|
||||
|
||||
FOR_LOOP:
|
||||
for _, val := range vals {
|
||||
if len(precommits) == 0 {
|
||||
break FOR_LOOP
|
||||
}
|
||||
next := precommits[0]
|
||||
switch bytes.Compare(val.Address(), next.ValidatorAddress) {
|
||||
case -1:
|
||||
continue FOR_LOOP
|
||||
case 0:
|
||||
signBytes := tm.SignBytes(next)
|
||||
...
|
||||
case 1:
|
||||
... // error?
|
||||
}
|
||||
}
|
||||
*/
|
||||
if newSet.Size() != len(commit.Precommits) {
|
||||
return errors.Errorf("Invalid commit -- wrong set size: %v vs %v", newSet.Size(), len(commit.Precommits))
|
||||
}
|
||||
if height != commit.Height() {
|
||||
return errors.Errorf("Invalid commit -- wrong height: %v vs %v", height, commit.Height())
|
||||
}
|
||||
|
||||
oldVotingPower := int64(0)
|
||||
newVotingPower := int64(0)
|
||||
seen := map[int]bool{}
|
||||
round := commit.Round()
|
||||
|
||||
for idx, precommit := range commit.Precommits {
|
||||
// first check as in VerifyCommit
|
||||
if precommit == nil {
|
||||
continue
|
||||
}
|
||||
if precommit.Height != height {
|
||||
// return certerr.ErrHeightMismatch(height, precommit.Height)
|
||||
return errors.Errorf("Blocks don't match - %d vs %d", round, precommit.Round)
|
||||
}
|
||||
if precommit.Round != round {
|
||||
return errors.Errorf("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
|
||||
}
|
||||
if precommit.Type != VoteTypePrecommit {
|
||||
return errors.Errorf("Invalid commit -- not precommit @ index %v", idx)
|
||||
}
|
||||
if !blockID.Equals(precommit.BlockID) {
|
||||
continue // Not an error, but doesn't count
|
||||
}
|
||||
|
||||
// we only grab by address, ignoring unknown validators
|
||||
vi, ov := valSet.GetByAddress(precommit.ValidatorAddress)
|
||||
if ov == nil || seen[vi] {
|
||||
continue // missing or double vote...
|
||||
}
|
||||
seen[vi] = true
|
||||
|
||||
// Validate signature old school
|
||||
precommitSignBytes := SignBytes(chainID, precommit)
|
||||
if !ov.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
|
||||
return errors.Errorf("Invalid commit -- invalid signature: %v", precommit)
|
||||
}
|
||||
// Good precommit!
|
||||
oldVotingPower += ov.VotingPower
|
||||
|
||||
// check new school
|
||||
_, cv := newSet.GetByIndex(idx)
|
||||
if cv.PubKey.Equals(ov.PubKey) {
|
||||
// make sure this is properly set in the current block as well
|
||||
newVotingPower += cv.VotingPower
|
||||
}
|
||||
}
|
||||
|
||||
if oldVotingPower <= valSet.TotalVotingPower()*2/3 {
|
||||
return errors.Errorf("Invalid commit -- insufficient old voting power: got %v, needed %v",
|
||||
oldVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
|
||||
} else if newVotingPower <= newSet.TotalVotingPower()*2/3 {
|
||||
return errors.Errorf("Invalid commit -- insufficient cur voting power: got %v, needed %v",
|
||||
newVotingPower, (newSet.TotalVotingPower()*2/3 + 1))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (valSet *ValidatorSet) ToBytes() []byte {
|
||||
|
|
Loading…
Reference in New Issue