Change Commit to hold signatures+timestamps instead of votes

This commit is contained in:
Jeremiah Andrews 2018-08-07 16:17:15 -07:00
parent debe56326f
commit e47a8939f9
13 changed files with 141 additions and 156 deletions

View File

@ -69,8 +69,11 @@ var (
partSet = block.MakePartSet(2) partSet = block.MakePartSet(2)
part1 = partSet.GetPart(0) part1 = partSet.GetPart(0)
part2 = partSet.GetPart(1) part2 = partSet.GetPart(1)
seenCommit1 = &types.Commit{Precommits: []*types.Vote{{Height: 10, seenCommit1 = &types.Commit{
Timestamp: time.Now().UTC()}}} Precommits: []*types.CommitSig{{
Timestamp: time.Now().UTC()}},
HeightNum: 10,
}
) )
// TODO: This test should be simplified ... // TODO: This test should be simplified ...
@ -90,8 +93,11 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) {
// save a block // save a block
block := makeBlock(bs.Height()+1, state) block := makeBlock(bs.Height()+1, state)
validPartSet := block.MakePartSet(2) validPartSet := block.MakePartSet(2)
seenCommit := &types.Commit{Precommits: []*types.Vote{{Height: 10, seenCommit := &types.Commit{
Timestamp: time.Now().UTC()}}} Precommits: []*types.CommitSig{{
Timestamp: time.Now().UTC()}},
HeightNum: 10,
}
bs.SaveBlock(block, partSet, seenCommit) bs.SaveBlock(block, partSet, seenCommit)
require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed") require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed")
@ -110,8 +116,11 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) {
// End of setup, test data // End of setup, test data
commitAtH10 := &types.Commit{Precommits: []*types.Vote{{Height: 10, commitAtH10 := &types.Commit{
Timestamp: time.Now().UTC()}}} Precommits: []*types.CommitSig{{
Timestamp: time.Now().UTC()}},
HeightNum: 10,
}
tuples := []struct { tuples := []struct {
block *types.Block block *types.Block
parts *types.PartSet parts *types.PartSet
@ -334,8 +343,11 @@ func TestBlockFetchAtHeight(t *testing.T) {
block := makeBlock(bs.Height()+1, state) block := makeBlock(bs.Height()+1, state)
partSet := block.MakePartSet(2) partSet := block.MakePartSet(2)
seenCommit := &types.Commit{Precommits: []*types.Vote{{Height: 10, seenCommit := &types.Commit{
Timestamp: time.Now().UTC()}}} Precommits: []*types.CommitSig{{
Timestamp: time.Now().UTC()}},
HeightNum: 10,
}
bs.SaveBlock(block, partSet, seenCommit) bs.SaveBlock(block, partSet, seenCommit)
require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed") require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed")

View File

@ -607,12 +607,6 @@ func validateBlock(block *types.Block, activeVals map[string]struct{}) error {
if block.LastCommit.Size() != len(activeVals) { if block.LastCommit.Size() != len(activeVals) {
return fmt.Errorf("Commit size doesn't match number of active validators. Got %d, expected %d", block.LastCommit.Size(), len(activeVals)) return fmt.Errorf("Commit size doesn't match number of active validators. Got %d, expected %d", block.LastCommit.Size(), len(activeVals))
} }
for _, vote := range block.LastCommit.Precommits {
if _, ok := activeVals[string(vote.ValidatorAddress)]; !ok {
return fmt.Errorf("Found vote for unactive validator %X", vote.ValidatorAddress)
}
}
return nil return nil
} }

View File

@ -531,7 +531,7 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
if block.Height != height+1 { if block.Height != height+1 {
panic(fmt.Sprintf("read bad block from wal. got height %d, expected %d", block.Height, height+1)) panic(fmt.Sprintf("read bad block from wal. got height %d, expected %d", block.Height, height+1))
} }
commitHeight := thisBlockCommit.Precommits[0].Height commitHeight := thisBlockCommit.Height()
if commitHeight != height+1 { if commitHeight != height+1 {
panic(fmt.Sprintf("commit doesnt match. got height %d, expected %d", commitHeight, height+1)) panic(fmt.Sprintf("commit doesnt match. got height %d, expected %d", commitHeight, height+1))
} }
@ -550,7 +550,14 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
if p.Type == types.VoteTypePrecommit { if p.Type == types.VoteTypePrecommit {
thisBlockCommit = &types.Commit{ thisBlockCommit = &types.Commit{
BlockID: p.BlockID, BlockID: p.BlockID,
Precommits: []*types.Vote{p}, Precommits: []*types.CommitSig{
&types.CommitSig{
Signature: p.Signature,
Timestamp: p.Timestamp,
},
},
HeightNum: p.Height,
RoundNum: p.Round,
} }
} }
} }
@ -564,7 +571,7 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
if block.Height != height+1 { if block.Height != height+1 {
panic(fmt.Sprintf("read bad block from wal. got height %d, expected %d", block.Height, height+1)) panic(fmt.Sprintf("read bad block from wal. got height %d, expected %d", block.Height, height+1))
} }
commitHeight := thisBlockCommit.Precommits[0].Height commitHeight := thisBlockCommit.Height()
if commitHeight != height+1 { if commitHeight != height+1 {
panic(fmt.Sprintf("commit doesnt match. got height %d, expected %d", commitHeight, height+1)) panic(fmt.Sprintf("commit doesnt match. got height %d, expected %d", commitHeight, height+1))
} }

View File

@ -453,11 +453,14 @@ func (cs *ConsensusState) reconstructLastCommit(state sm.State) {
} }
seenCommit := cs.blockStore.LoadSeenCommit(state.LastBlockHeight) seenCommit := cs.blockStore.LoadSeenCommit(state.LastBlockHeight)
lastPrecommits := types.NewVoteSet(state.ChainID, state.LastBlockHeight, seenCommit.Round(), types.VoteTypePrecommit, state.LastValidators) lastPrecommits := types.NewVoteSet(state.ChainID, state.LastBlockHeight, seenCommit.Round(), types.VoteTypePrecommit, state.LastValidators)
for _, precommit := range seenCommit.Precommits { for idx := 0; idx < len(seenCommit.Precommits); idx++ {
if precommit == nil { if seenCommit.Precommits[idx] == nil {
continue continue
} }
added, err := lastPrecommits.AddVote(precommit) addr, _ := state.LastValidators.GetByIndex(idx)
vote := seenCommit.GetByIndex(idx)
vote.ValidatorAddress = addr
added, err := lastPrecommits.AddVote(vote)
if !added || err != nil { if !added || err != nil {
cmn.PanicCrisis(fmt.Sprintf("Failed to reconstruct LastCommit: %v", err)) cmn.PanicCrisis(fmt.Sprintf("Failed to reconstruct LastCommit: %v", err))
} }
@ -1344,7 +1347,7 @@ func (cs *ConsensusState) recordMetrics(height int64, block *types.Block) {
missingValidators := 0 missingValidators := 0
missingValidatorsPower := int64(0) missingValidatorsPower := int64(0)
for i, val := range cs.Validators.Validators { for i, val := range cs.Validators.Validators {
var vote *types.Vote var vote *types.CommitSig
if i < len(block.LastCommit.Precommits) { if i < len(block.LastCommit.Precommits) {
vote = block.LastCommit.Precommits[i] vote = block.LastCommit.Precommits[i]
} }

View File

@ -16,7 +16,7 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) {
// Random validators // Random validators
nval, ntxs := 100, 100 nval, ntxs := 100, 100
vset, _ := types.RandValidatorSet(nval, 1) vset, _ := types.RandValidatorSet(nval, 1)
precommits := make([]*types.Vote, nval) precommits := make([]*types.CommitSig, nval)
blockID := types.BlockID{ blockID := types.BlockID{
Hash: cmn.RandBytes(20), Hash: cmn.RandBytes(20),
PartsHeader: types.PartSetHeader{ PartsHeader: types.PartSetHeader{
@ -25,10 +25,8 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) {
} }
sig := make([]byte, ed25519.SignatureSize) sig := make([]byte, ed25519.SignatureSize)
for i := 0; i < nval; i++ { for i := 0; i < nval; i++ {
precommits[i] = &types.Vote{ precommits[i] = &types.CommitSig{
ValidatorAddress: types.Address(cmn.RandBytes(20)),
Timestamp: time.Now(), Timestamp: time.Now(),
BlockID: blockID,
Signature: sig, Signature: sig,
} }
} }

View File

@ -71,7 +71,7 @@ func (pkz privKeys) ToValidators(init, inc int64) *types.ValidatorSet {
// signHeader properly signs the header with all keys from first to last exclusive. // signHeader properly signs the header with all keys from first to last exclusive.
func (pkz privKeys) signHeader(header *types.Header, first, last int) *types.Commit { func (pkz privKeys) signHeader(header *types.Header, first, last int) *types.Commit {
votes := make([]*types.Vote, len(pkz)) cs := make([]*types.CommitSig, len(pkz))
// We need this list to keep the ordering. // We need this list to keep the ordering.
vset := pkz.ToValidators(1, 0) vset := pkz.ToValidators(1, 0)
@ -79,12 +79,17 @@ func (pkz privKeys) signHeader(header *types.Header, first, last int) *types.Com
// Fill in the votes we want. // Fill in the votes we want.
for i := first; i < last && i < len(pkz); i++ { for i := first; i < last && i < len(pkz); i++ {
vote := makeVote(header, vset, pkz[i]) vote := makeVote(header, vset, pkz[i])
votes[vote.ValidatorIndex] = vote cs[vote.ValidatorIndex] = &types.CommitSig{
Signature: vote.Signature,
Timestamp: vote.Timestamp,
}
} }
res := &types.Commit{ res := &types.Commit{
BlockID: types.BlockID{Hash: header.Hash()}, BlockID: types.BlockID{Hash: header.Hash()},
Precommits: votes, Precommits: cs,
RoundNum: 1,
HeightNum: header.Height,
} }
return res return res
} }

View File

@ -241,7 +241,7 @@ func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorS
// Collect the vote info (list of validators and whether or not they signed). // Collect the vote info (list of validators and whether or not they signed).
voteInfos := make([]abci.VoteInfo, len(lastValSet.Validators)) voteInfos := make([]abci.VoteInfo, len(lastValSet.Validators))
for i, val := range lastValSet.Validators { for i, val := range lastValSet.Validators {
var vote *types.Vote var vote *types.CommitSig
if i < len(block.LastCommit.Precommits) { if i < len(block.LastCommit.Precommits) {
vote = block.LastCommit.Precommits[i] vote = block.LastCommit.Precommits[i]
} }

View File

@ -63,17 +63,17 @@ func TestBeginBlockValidators(t *testing.T) {
prevBlockID := types.BlockID{prevHash, prevParts} prevBlockID := types.BlockID{prevHash, prevParts}
now := time.Now().UTC() now := time.Now().UTC()
vote0 := &types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit} vote0 := &types.CommitSig{Timestamp: now}
vote1 := &types.Vote{ValidatorIndex: 1, Timestamp: now} vote1 := &types.CommitSig{Timestamp: now}
testCases := []struct { testCases := []struct {
desc string desc string
lastCommitPrecommits []*types.Vote lastCommitPrecommits []*types.CommitSig
expectedAbsentValidators []int expectedAbsentValidators []int
}{ }{
{"none absent", []*types.Vote{vote0, vote1}, []int{}}, {"none absent", []*types.CommitSig{vote0, vote1}, []int{}},
{"one absent", []*types.Vote{vote0, nil}, []int{1}}, {"one absent", []*types.CommitSig{vote0, nil}, []int{1}},
{"multiple absent", []*types.Vote{nil, nil}, []int{0, 1}}, {"multiple absent", []*types.CommitSig{nil, nil}, []int{0, 1}},
} }
for _, tc := range testCases { for _, tc := range testCases {
@ -133,9 +133,9 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
types.TM2PB.Evidence(ev2, valSet, now)}}, types.TM2PB.Evidence(ev2, valSet, now)}},
} }
vote0 := &types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit} vote0 := &types.CommitSig{Timestamp: now}
vote1 := &types.Vote{ValidatorIndex: 1, Timestamp: now} vote1 := &types.CommitSig{Timestamp: now}
votes := []*types.Vote{vote0, vote1} votes := []*types.CommitSig{vote0, vote1}
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes} lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes}
for _, tc := range testCases { for _, tc := range testCases {

View File

@ -297,48 +297,37 @@ type Commit struct {
// Any peer with a block can gossip precommits by index with a peer without recalculating the // Any peer with a block can gossip precommits by index with a peer without recalculating the
// active ValidatorSet. // active ValidatorSet.
BlockID BlockID `json:"block_id"` BlockID BlockID `json:"block_id"`
Precommits []*Vote `json:"precommits"` Precommits []*CommitSig `json:"precommits"`
RoundNum int
HeightNum int64
// Volatile // Volatile
firstPrecommit *Vote
hash cmn.HexBytes hash cmn.HexBytes
bitArray *cmn.BitArray bitArray *cmn.BitArray
} }
// FirstPrecommit returns the first non-nil precommit in the commit. type CommitSig struct {
// If all precommits are nil, it returns an empty precommit with height 0. Signature []byte
func (commit *Commit) FirstPrecommit() *Vote { Timestamp time.Time
if len(commit.Precommits) == 0 { }
return nil
} func (cs *CommitSig) String(index int, address Address, height int64, round int, blockID BlockID) string {
if commit.firstPrecommit != nil { return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%v) %X %X @ %s}",
return commit.firstPrecommit index, cmn.Fingerprint(address),
} height, round, VoteTypePrecommit, "Precommit",
for _, precommit := range commit.Precommits { cmn.Fingerprint(blockID.Hash),
if precommit != nil { cmn.Fingerprint(cs.Signature),
commit.firstPrecommit = precommit CanonicalTime(cs.Timestamp))
return precommit
}
}
return &Vote{
Type: VoteTypePrecommit,
}
} }
// Height returns the height of the commit // Height returns the height of the commit
func (commit *Commit) Height() int64 { func (commit *Commit) Height() int64 {
if len(commit.Precommits) == 0 { return commit.HeightNum
return 0
}
return commit.FirstPrecommit().Height
} }
// Round returns the round of the commit // Round returns the round of the commit
func (commit *Commit) Round() int { func (commit *Commit) Round() int {
if len(commit.Precommits) == 0 { return commit.RoundNum
return 0
}
return commit.FirstPrecommit().Round
} }
// Type returns the vote type of the commit, which is always VoteTypePrecommit // Type returns the vote type of the commit, which is always VoteTypePrecommit
@ -368,8 +357,16 @@ func (commit *Commit) BitArray() *cmn.BitArray {
} }
// GetByIndex returns the vote corresponding to a given validator index // GetByIndex returns the vote corresponding to a given validator index
func (commit *Commit) GetByIndex(index int) *Vote { func (com *Commit) GetByIndex(index int) *Vote {
return commit.Precommits[index] return &Vote{
ValidatorIndex: index,
Height: com.HeightNum,
Round: com.RoundNum,
Timestamp: com.Precommits[index].Timestamp,
Type: VoteTypePrecommit,
BlockID: com.BlockID,
Signature: com.Precommits[index].Signature,
}
} }
// IsCommit returns true if there is at least one vote // IsCommit returns true if there is at least one vote
@ -386,30 +383,6 @@ func (commit *Commit) ValidateBasic() error {
if len(commit.Precommits) == 0 { if len(commit.Precommits) == 0 {
return errors.New("No precommits in commit") return errors.New("No precommits in commit")
} }
height, round := commit.Height(), commit.Round()
// Validate the precommits.
for _, precommit := range commit.Precommits {
// It's OK for precommits to be missing.
if precommit == nil {
continue
}
// Ensure that all votes are precommits.
if precommit.Type != VoteTypePrecommit {
return fmt.Errorf("Invalid commit vote. Expected precommit, got %v",
precommit.Type)
}
// Ensure that all heights are the same.
if precommit.Height != height {
return fmt.Errorf("Invalid commit precommit height. Expected %v, got %v",
height, precommit.Height)
}
// Ensure that all rounds are the same.
if precommit.Round != round {
return fmt.Errorf("Invalid commit precommit round. Expected %v, got %v",
round, precommit.Round)
}
}
return nil return nil
} }
@ -435,7 +408,8 @@ func (commit *Commit) StringIndented(indent string) string {
} }
precommitStrings := make([]string, len(commit.Precommits)) precommitStrings := make([]string, len(commit.Precommits))
for i, precommit := range commit.Precommits { for i, precommit := range commit.Precommits {
precommitStrings[i] = precommit.String() precommitStrings[i] = precommit.String(i, []byte("---"),
commit.HeightNum, commit.RoundNum, commit.BlockID)
} }
return fmt.Sprintf(`Commit{ return fmt.Sprintf(`Commit{
%s BlockID: %v %s BlockID: %v

View File

@ -118,7 +118,7 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
partSet := MakeBlock(h, txs, commit, evList).MakePartSet(1024) partSet := MakeBlock(h, txs, commit, evList).MakePartSet(1024)
assert.NotNil(t, partSet) assert.NotNil(t, partSet)
assert.Equal(t, 3, partSet.Total()) assert.Equal(t, 2, partSet.Total())
} }
func TestBlockHashesTo(t *testing.T) { func TestBlockHashesTo(t *testing.T) {
@ -193,7 +193,6 @@ func TestCommit(t *testing.T) {
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals) commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
require.NoError(t, err) require.NoError(t, err)
assert.NotNil(t, commit.FirstPrecommit())
assert.Equal(t, h-1, commit.Height()) assert.Equal(t, h-1, commit.Height())
assert.Equal(t, 1, commit.Round()) assert.Equal(t, 1, commit.Round())
assert.Equal(t, VoteTypePrecommit, commit.Type()) assert.Equal(t, VoteTypePrecommit, commit.Type())
@ -204,7 +203,9 @@ func TestCommit(t *testing.T) {
require.NotNil(t, commit.BitArray()) require.NotNil(t, commit.BitArray())
assert.Equal(t, cmn.NewBitArray(10).Size(), commit.BitArray().Size()) assert.Equal(t, cmn.NewBitArray(10).Size(), commit.BitArray().Size())
assert.Equal(t, voteSet.GetByIndex(0), commit.GetByIndex(0)) cv := commit.GetByIndex(0)
cv.ValidatorAddress = voteSet.GetByIndex(0).ValidatorAddress
assert.Equal(t, voteSet.GetByIndex(0), cv)
assert.True(t, commit.IsCommit()) assert.True(t, commit.IsCommit())
} }
@ -216,21 +217,6 @@ func TestCommitValidateBasic(t *testing.T) {
commit = randCommit() commit = randCommit()
commit.Precommits[0] = nil commit.Precommits[0] = nil
assert.NoError(t, commit.ValidateBasic()) assert.NoError(t, commit.ValidateBasic())
// tamper with types
commit = randCommit()
commit.Precommits[0].Type = VoteTypePrevote
assert.Error(t, commit.ValidateBasic())
// tamper with height
commit = randCommit()
commit.Precommits[0].Height = int64(100)
assert.Error(t, commit.ValidateBasic())
// tamper with round
commit = randCommit()
commit.Precommits[0].Round = 100
assert.Error(t, commit.ValidateBasic())
} }
func randCommit() *Commit { func randCommit() *Commit {

View File

@ -270,34 +270,27 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height i
} }
talliedVotingPower := int64(0) talliedVotingPower := int64(0)
round := commit.Round()
baseVote := Vote{
Height: height,
Round: commit.Round(),
Type: VoteTypePrecommit,
BlockID: blockID,
}
for idx, precommit := range commit.Precommits { for idx, precommit := range commit.Precommits {
if precommit == nil { if precommit == nil {
continue // OK, some precommits can be missing. continue // OK, some precommits can be missing.
} }
if precommit.Height != height {
return fmt.Errorf("Invalid commit -- wrong height: want %v got %v", height, precommit.Height)
}
if precommit.Round != round {
return fmt.Errorf("Invalid commit -- wrong round: want %v got %v", round, precommit.Round)
}
if precommit.Type != VoteTypePrecommit {
return fmt.Errorf("Invalid commit -- not precommit @ index %v", idx)
}
_, val := vals.GetByIndex(idx) _, val := vals.GetByIndex(idx)
baseVote.Timestamp = precommit.Timestamp
// Validate signature. // Validate signature.
precommitSignBytes := precommit.SignBytes(chainID) precommitSignBytes := baseVote.SignBytes(chainID)
if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) { if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
return fmt.Errorf("Invalid commit -- invalid signature: %v", precommit) return fmt.Errorf("Invalid commit -- invalid signature: %v", precommit)
} }
// Good precommit! // Good precommit!
if blockID.Equals(precommit.BlockID) {
talliedVotingPower += val.VotingPower 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 { if talliedVotingPower > vals.TotalVotingPower()*2/3 {
@ -349,40 +342,33 @@ func (vals *ValidatorSet) VerifyFutureCommit(newSet *ValidatorSet, chainID strin
// Check old voting power. // Check old voting power.
oldVotingPower := int64(0) oldVotingPower := int64(0)
seen := map[int]bool{} seen := map[int]bool{}
round := commit.Round() baseVote := Vote{
Height: height,
Round: commit.Round(),
Type: VoteTypePrecommit,
BlockID: blockID,
}
for idx, precommit := range commit.Precommits { for idx, precommit := range commit.Precommits {
if precommit == nil { if precommit == nil {
continue continue
} }
if precommit.Height != height {
return cmn.NewError("Blocks don't match - %d vs %d", round, precommit.Round)
}
if precommit.Round != round {
return cmn.NewError("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
}
if precommit.Type != VoteTypePrecommit {
return cmn.NewError("Invalid commit -- not precommit @ index %v", idx)
}
// See if this validator is in oldVals. // See if this validator is in oldVals.
idx, val := oldVals.GetByAddress(precommit.ValidatorAddress) adr, _ := newSet.GetByIndex(idx)
idx, val := oldVals.GetByAddress(adr)
if val == nil || seen[idx] { if val == nil || seen[idx] {
continue // missing or double vote... continue // missing or double vote...
} }
seen[idx] = true seen[idx] = true
// Validate signature. // Validate signature.
precommitSignBytes := precommit.SignBytes(chainID) baseVote.Timestamp = precommit.Timestamp
precommitSignBytes := baseVote.SignBytes(chainID)
if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) { if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
return cmn.NewError("Invalid commit -- invalid signature: %v", precommit) return cmn.NewError("Invalid commit -- invalid signature: %v", precommit)
} }
// Good precommit! // Good precommit!
if blockID.Equals(precommit.BlockID) {
oldVotingPower += val.VotingPower oldVotingPower += val.VotingPower
} else {
// It's OK that the BlockID doesn't match. We include stray
// precommits to measure validator availability.
}
} }
if oldVotingPower <= oldVals.TotalVotingPower()*2/3 { if oldVotingPower <= oldVals.TotalVotingPower()*2/3 {

View File

@ -393,7 +393,14 @@ func TestValidatorSetVerifyCommit(t *testing.T) {
vote.Signature = sig vote.Signature = sig
commit := &Commit{ commit := &Commit{
BlockID: blockID, BlockID: blockID,
Precommits: []*Vote{vote}, Precommits: []*CommitSig{
&CommitSig{
Signature: sig,
Timestamp: vote.Timestamp,
},
},
HeightNum: height,
RoundNum: 0,
} }
badChainID := "notmychainID" badChainID := "notmychainID"
@ -401,7 +408,9 @@ func TestValidatorSetVerifyCommit(t *testing.T) {
badHeight := height + 1 badHeight := height + 1
badCommit := &Commit{ badCommit := &Commit{
BlockID: blockID, BlockID: blockID,
Precommits: []*Vote{nil}, Precommits: []*CommitSig{nil},
HeightNum: height,
RoundNum: 0,
} }
// test some error cases // test some error cases

View File

@ -543,9 +543,20 @@ func (voteSet *VoteSet) MakeCommit() *Commit {
// For every validator, get the precommit // For every validator, get the precommit
votesCopy := make([]*Vote, len(voteSet.votes)) votesCopy := make([]*Vote, len(voteSet.votes))
copy(votesCopy, voteSet.votes) copy(votesCopy, voteSet.votes)
precommits := make([]*CommitSig, len(voteSet.votes))
for i, v := range votesCopy {
if v != nil {
precommits[i] = &CommitSig{
Signature: v.Signature,
Timestamp: v.Timestamp,
}
}
}
return &Commit{ return &Commit{
BlockID: *voteSet.maj23, BlockID: *voteSet.maj23,
Precommits: votesCopy, Precommits: precommits,
RoundNum: voteSet.round,
HeightNum: voteSet.height,
} }
} }