mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-16 06:41:19 +00:00
Refactor consensus/vote_set_test.go
This commit is contained in:
@ -33,7 +33,7 @@ func NewNode() *Node {
|
|||||||
stateDB := db_.NewMemDB() // TODO configurable db.
|
stateDB := db_.NewMemDB() // TODO configurable db.
|
||||||
state := state_.LoadState(stateDB)
|
state := state_.LoadState(stateDB)
|
||||||
if state == nil {
|
if state == nil {
|
||||||
state = state_.GenesisStateFromFile(stateDB, config.GenesisFile())
|
state = state_.MakeGenesisStateFromFile(stateDB, config.GenesisFile())
|
||||||
state.Save()
|
state.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,54 @@ import (
|
|||||||
. "github.com/tendermint/tendermint/block"
|
. "github.com/tendermint/tendermint/block"
|
||||||
. "github.com/tendermint/tendermint/common"
|
. "github.com/tendermint/tendermint/common"
|
||||||
. "github.com/tendermint/tendermint/common/test"
|
. "github.com/tendermint/tendermint/common/test"
|
||||||
|
"github.com/tendermint/tendermint/state"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: see consensus/test.go for common test methods.
|
// NOTE: see consensus/test.go for common test methods.
|
||||||
|
|
||||||
|
// Convenience: Return new vote with different height
|
||||||
|
func withHeight(vote *Vote, height uint) *Vote {
|
||||||
|
vote = vote.Copy()
|
||||||
|
vote.Height = height
|
||||||
|
return vote
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience: Return new vote with different round
|
||||||
|
func withRound(vote *Vote, round uint) *Vote {
|
||||||
|
vote = vote.Copy()
|
||||||
|
vote.Round = round
|
||||||
|
return vote
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience: Return new vote with different type
|
||||||
|
func withType(vote *Vote, type_ byte) *Vote {
|
||||||
|
vote = vote.Copy()
|
||||||
|
vote.Type = type_
|
||||||
|
return vote
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience: Return new vote with different blockHash
|
||||||
|
func withBlockHash(vote *Vote, blockHash []byte) *Vote {
|
||||||
|
vote = vote.Copy()
|
||||||
|
vote.BlockHash = blockHash
|
||||||
|
return vote
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience: Return new vote with different blockParts
|
||||||
|
func withBlockParts(vote *Vote, blockParts PartSetHeader) *Vote {
|
||||||
|
vote = vote.Copy()
|
||||||
|
vote.BlockParts = blockParts
|
||||||
|
return vote
|
||||||
|
}
|
||||||
|
|
||||||
|
func signAddVote(privVal *state.PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) {
|
||||||
|
vote.Signature = privVal.SignVoteUnsafe(vote)
|
||||||
|
added, _, err := voteSet.Add(privVal.Address, vote)
|
||||||
|
return added, err
|
||||||
|
}
|
||||||
|
|
||||||
func TestAddVote(t *testing.T) {
|
func TestAddVote(t *testing.T) {
|
||||||
height, round := uint(1), uint(0)
|
height, round := uint(1), uint(0)
|
||||||
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
|
||||||
@ -31,8 +73,7 @@ func TestAddVote(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
||||||
vote.Signature = val0.SignVoteUnsafe(vote)
|
signAddVote(val0, vote, voteSet)
|
||||||
voteSet.Add(val0.Address, vote)
|
|
||||||
|
|
||||||
if voteSet.GetByAddress(val0.Address) == nil {
|
if voteSet.GetByAddress(val0.Address) == nil {
|
||||||
t.Errorf("Expected GetByAddress(val0.Address) to be present")
|
t.Errorf("Expected GetByAddress(val0.Address) to be present")
|
||||||
@ -50,12 +91,11 @@ func Test2_3Majority(t *testing.T) {
|
|||||||
height, round := uint(1), uint(0)
|
height, round := uint(1), uint(0)
|
||||||
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
|
||||||
|
|
||||||
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
||||||
|
|
||||||
// 6 out of 10 voted for nil.
|
// 6 out of 10 voted for nil.
|
||||||
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
|
||||||
for i := 0; i < 6; i++ {
|
for i := 0; i < 6; i++ {
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[i], vote, voteSet)
|
||||||
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[i].Address, vote)
|
|
||||||
}
|
}
|
||||||
hash, header, ok := voteSet.TwoThirdsMajority()
|
hash, header, ok := voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
@ -64,10 +104,7 @@ func Test2_3Majority(t *testing.T) {
|
|||||||
|
|
||||||
// 7th validator voted for some blockhash
|
// 7th validator voted for some blockhash
|
||||||
{
|
{
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[6], withBlockHash(vote, RandBytes(32)), voteSet)
|
||||||
vote.BlockHash = CRandBytes(32)
|
|
||||||
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[6].Address, vote)
|
|
||||||
hash, header, ok = voteSet.TwoThirdsMajority()
|
hash, header, ok = voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
t.Errorf("There should be no 2/3 majority")
|
t.Errorf("There should be no 2/3 majority")
|
||||||
@ -76,10 +113,7 @@ func Test2_3Majority(t *testing.T) {
|
|||||||
|
|
||||||
// 8th validator voted for nil.
|
// 8th validator voted for nil.
|
||||||
{
|
{
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[7], vote, voteSet)
|
||||||
vote.BlockHash = nil
|
|
||||||
vote.Signature = privValidators[7].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[7].Address, vote)
|
|
||||||
hash, header, ok = voteSet.TwoThirdsMajority()
|
hash, header, ok = voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || !ok {
|
if hash != nil || !header.IsZero() || !ok {
|
||||||
t.Errorf("There should be 2/3 majority for nil")
|
t.Errorf("There should be 2/3 majority for nil")
|
||||||
@ -95,12 +129,11 @@ func Test2_3MajorityRedux(t *testing.T) {
|
|||||||
blockPartsTotal := uint(123)
|
blockPartsTotal := uint(123)
|
||||||
blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)}
|
blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)}
|
||||||
|
|
||||||
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: blockParts}
|
||||||
|
|
||||||
// 66 out of 100 voted for nil.
|
// 66 out of 100 voted for nil.
|
||||||
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: blockParts}
|
|
||||||
for i := 0; i < 66; i++ {
|
for i := 0; i < 66; i++ {
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[i], vote, voteSet)
|
||||||
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[i].Address, vote)
|
|
||||||
}
|
}
|
||||||
hash, header, ok := voteSet.TwoThirdsMajority()
|
hash, header, ok := voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
@ -109,9 +142,7 @@ func Test2_3MajorityRedux(t *testing.T) {
|
|||||||
|
|
||||||
// 67th validator voted for nil
|
// 67th validator voted for nil
|
||||||
{
|
{
|
||||||
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil, BlockParts: PartSetHeader{}}
|
signAddVote(privValidators[66], withBlockHash(vote, nil), voteSet)
|
||||||
vote.Signature = privValidators[66].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[66].Address, vote)
|
|
||||||
hash, header, ok = voteSet.TwoThirdsMajority()
|
hash, header, ok = voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
t.Errorf("There should be no 2/3 majority: last vote added was nil")
|
t.Errorf("There should be no 2/3 majority: last vote added was nil")
|
||||||
@ -120,9 +151,8 @@ func Test2_3MajorityRedux(t *testing.T) {
|
|||||||
|
|
||||||
// 68th validator voted for a different BlockParts PartSetHeader
|
// 68th validator voted for a different BlockParts PartSetHeader
|
||||||
{
|
{
|
||||||
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal, CRandBytes(32)}}
|
blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)}
|
||||||
vote.Signature = privValidators[67].SignVoteUnsafe(vote)
|
signAddVote(privValidators[67], withBlockParts(vote, blockParts), voteSet)
|
||||||
voteSet.Add(privValidators[67].Address, vote)
|
|
||||||
hash, header, ok = voteSet.TwoThirdsMajority()
|
hash, header, ok = voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Hash")
|
t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Hash")
|
||||||
@ -131,9 +161,8 @@ func Test2_3MajorityRedux(t *testing.T) {
|
|||||||
|
|
||||||
// 69th validator voted for different BlockParts Total
|
// 69th validator voted for different BlockParts Total
|
||||||
{
|
{
|
||||||
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal + 1, blockParts.Hash}}
|
blockParts := PartSetHeader{blockPartsTotal + 1, blockParts.Hash}
|
||||||
vote.Signature = privValidators[68].SignVoteUnsafe(vote)
|
signAddVote(privValidators[68], withBlockParts(vote, blockParts), voteSet)
|
||||||
voteSet.Add(privValidators[68].Address, vote)
|
|
||||||
hash, header, ok = voteSet.TwoThirdsMajority()
|
hash, header, ok = voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Total")
|
t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Total")
|
||||||
@ -142,9 +171,7 @@ func Test2_3MajorityRedux(t *testing.T) {
|
|||||||
|
|
||||||
// 70th validator voted for different BlockHash
|
// 70th validator voted for different BlockHash
|
||||||
{
|
{
|
||||||
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32), BlockParts: blockParts}
|
signAddVote(privValidators[69], withBlockHash(vote, RandBytes(32)), voteSet)
|
||||||
vote.Signature = privValidators[69].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[69].Address, vote)
|
|
||||||
hash, header, ok = voteSet.TwoThirdsMajority()
|
hash, header, ok = voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash")
|
t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash")
|
||||||
@ -153,9 +180,7 @@ func Test2_3MajorityRedux(t *testing.T) {
|
|||||||
|
|
||||||
// 71st validator voted for the right BlockHash & BlockParts
|
// 71st validator voted for the right BlockHash & BlockParts
|
||||||
{
|
{
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[70], vote, voteSet)
|
||||||
vote.Signature = privValidators[70].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[70].Address, vote)
|
|
||||||
hash, header, ok = voteSet.TwoThirdsMajority()
|
hash, header, ok = voteSet.TwoThirdsMajority()
|
||||||
if !bytes.Equal(hash, blockHash) || !header.Equals(blockParts) || !ok {
|
if !bytes.Equal(hash, blockHash) || !header.Equals(blockParts) || !ok {
|
||||||
t.Errorf("There should be 2/3 majority")
|
t.Errorf("There should be 2/3 majority")
|
||||||
@ -169,40 +194,31 @@ func TestBadVotes(t *testing.T) {
|
|||||||
|
|
||||||
// val0 votes for nil.
|
// val0 votes for nil.
|
||||||
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
||||||
vote.Signature = privValidators[0].SignVoteUnsafe(vote)
|
added, err := signAddVote(privValidators[0], vote, voteSet)
|
||||||
added, _, err := voteSet.Add(privValidators[0].Address, vote)
|
|
||||||
if !added || err != nil {
|
if !added || err != nil {
|
||||||
t.Errorf("Expected Add() to succeed")
|
t.Errorf("Expected Add() to succeed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// val0 votes again for some block.
|
// val0 votes again for some block.
|
||||||
vote = &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32)}
|
added, err = signAddVote(privValidators[0], withBlockHash(vote, RandBytes(32)), voteSet)
|
||||||
vote.Signature = privValidators[0].SignVoteUnsafe(vote)
|
|
||||||
added, _, err = voteSet.Add(privValidators[0].Address, vote)
|
|
||||||
if added || err == nil {
|
if added || err == nil {
|
||||||
t.Errorf("Expected Add() to fail, dupeout.")
|
t.Errorf("Expected Add() to fail, dupeout.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// val1 votes on another height
|
// val1 votes on another height
|
||||||
vote = &Vote{Height: height + 1, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
added, err = signAddVote(privValidators[1], withHeight(vote, height+1), voteSet)
|
||||||
vote.Signature = privValidators[1].SignVoteUnsafe(vote)
|
|
||||||
added, _, err = voteSet.Add(privValidators[1].Address, vote)
|
|
||||||
if added {
|
if added {
|
||||||
t.Errorf("Expected Add() to fail, wrong height")
|
t.Errorf("Expected Add() to fail, wrong height")
|
||||||
}
|
}
|
||||||
|
|
||||||
// val2 votes on another round
|
// val2 votes on another round
|
||||||
vote = &Vote{Height: height, Round: round + 1, Type: VoteTypePrevote, BlockHash: nil}
|
added, err = signAddVote(privValidators[2], withRound(vote, round+1), voteSet)
|
||||||
vote.Signature = privValidators[2].SignVoteUnsafe(vote)
|
|
||||||
added, _, err = voteSet.Add(privValidators[2].Address, vote)
|
|
||||||
if added {
|
if added {
|
||||||
t.Errorf("Expected Add() to fail, wrong round")
|
t.Errorf("Expected Add() to fail, wrong round")
|
||||||
}
|
}
|
||||||
|
|
||||||
// val3 votes of another type.
|
// val3 votes of another type.
|
||||||
vote = &Vote{Height: height, Round: round, Type: VoteTypePrecommit, BlockHash: nil}
|
added, err = signAddVote(privValidators[3], withType(vote, VoteTypePrecommit), voteSet)
|
||||||
vote.Signature = privValidators[3].SignVoteUnsafe(vote)
|
|
||||||
added, _, err = voteSet.Add(privValidators[3].Address, vote)
|
|
||||||
if added {
|
if added {
|
||||||
t.Errorf("Expected Add() to fail, wrong type")
|
t.Errorf("Expected Add() to fail, wrong type")
|
||||||
}
|
}
|
||||||
@ -213,11 +229,9 @@ func TestAddCommitsToPrevoteVotes(t *testing.T) {
|
|||||||
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
|
||||||
|
|
||||||
// val0, val1, val2, val3, val4, val5 vote for nil.
|
// val0, val1, val2, val3, val4, val5 vote for nil.
|
||||||
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
|
||||||
for i := 0; i < 6; i++ {
|
for i := 0; i < 6; i++ {
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[i], vote, voteSet)
|
||||||
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[i].Address, vote)
|
|
||||||
}
|
}
|
||||||
hash, header, ok := voteSet.TwoThirdsMajority()
|
hash, header, ok := voteSet.TwoThirdsMajority()
|
||||||
if hash != nil || !header.IsZero() || ok {
|
if hash != nil || !header.IsZero() || ok {
|
||||||
@ -225,41 +239,36 @@ func TestAddCommitsToPrevoteVotes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to add a commit from val6 at a previous height
|
// Attempt to add a commit from val6 at a previous height
|
||||||
vote := &Vote{Height: height - 1, Round: round, Type: VoteTypeCommit, BlockHash: nil}
|
vote = &Vote{Height: height - 1, Round: round, Type: VoteTypeCommit, BlockHash: nil}
|
||||||
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
|
added, _ := signAddVote(privValidators[6], vote, voteSet)
|
||||||
added, _, _ := voteSet.Add(privValidators[6].Address, vote)
|
|
||||||
if added {
|
if added {
|
||||||
t.Errorf("Expected Add() to fail, wrong height.")
|
t.Errorf("Expected Add() to fail, wrong height.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to add a commit from val6 at a later round
|
// Attempt to add a commit from val6 at a later round
|
||||||
vote = &Vote{Height: height, Round: round + 1, Type: VoteTypeCommit, BlockHash: nil}
|
vote = &Vote{Height: height, Round: round + 1, Type: VoteTypeCommit, BlockHash: nil}
|
||||||
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
|
added, _ = signAddVote(privValidators[6], vote, voteSet)
|
||||||
added, _, _ = voteSet.Add(privValidators[6].Address, vote)
|
|
||||||
if added {
|
if added {
|
||||||
t.Errorf("Expected Add() to fail, cannot add future round vote.")
|
t.Errorf("Expected Add() to fail, cannot add future round vote.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to add a commit from val6 for currrent height/round.
|
// Attempt to add a commit from val6 for currrent height/round.
|
||||||
vote = &Vote{Height: height, Round: round, Type: VoteTypeCommit, BlockHash: nil}
|
vote = &Vote{Height: height, Round: round, Type: VoteTypeCommit, BlockHash: nil}
|
||||||
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
|
added, err := signAddVote(privValidators[6], vote, voteSet)
|
||||||
added, _, err := voteSet.Add(privValidators[6].Address, vote)
|
|
||||||
if added || err == nil {
|
if added || err == nil {
|
||||||
t.Errorf("Expected Add() to fail, only prior round commits can be added.")
|
t.Errorf("Expected Add() to fail, only prior round commits can be added.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add commit from val6 at a previous round
|
// Add commit from val6 at a previous round
|
||||||
vote = &Vote{Height: height, Round: round - 1, Type: VoteTypeCommit, BlockHash: nil}
|
vote = &Vote{Height: height, Round: round - 1, Type: VoteTypeCommit, BlockHash: nil}
|
||||||
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
|
added, err = signAddVote(privValidators[6], vote, voteSet)
|
||||||
added, _, err = voteSet.Add(privValidators[6].Address, vote)
|
|
||||||
if !added || err != nil {
|
if !added || err != nil {
|
||||||
t.Errorf("Expected Add() to succeed, commit for prior rounds are relevant.")
|
t.Errorf("Expected Add() to succeed, commit for prior rounds are relevant.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also add commit from val7 for previous round.
|
// Also add commit from val7 for previous round.
|
||||||
vote = &Vote{Height: height, Round: round - 2, Type: VoteTypeCommit, BlockHash: nil}
|
vote = &Vote{Height: height, Round: round - 2, Type: VoteTypeCommit, BlockHash: nil}
|
||||||
vote.Signature = privValidators[7].SignVoteUnsafe(vote)
|
added, err = signAddVote(privValidators[7], vote, voteSet)
|
||||||
added, _, err = voteSet.Add(privValidators[7].Address, vote)
|
|
||||||
if !added || err != nil {
|
if !added || err != nil {
|
||||||
t.Errorf("Expected Add() to succeed. err: %v", err)
|
t.Errorf("Expected Add() to succeed. err: %v", err)
|
||||||
}
|
}
|
||||||
@ -277,13 +286,12 @@ func TestMakeValidation(t *testing.T) {
|
|||||||
voteSet, _, privValidators := randVoteSet(height, round, VoteTypeCommit, 10, 1)
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypeCommit, 10, 1)
|
||||||
blockHash, blockParts := CRandBytes(32), PartSetHeader{123, CRandBytes(32)}
|
blockHash, blockParts := CRandBytes(32), PartSetHeader{123, CRandBytes(32)}
|
||||||
|
|
||||||
// 6 out of 10 voted for some block.
|
vote := &Vote{Height: height, Round: round, Type: VoteTypeCommit,
|
||||||
voteProto := &Vote{Height: height, Round: round, Type: VoteTypeCommit,
|
|
||||||
BlockHash: blockHash, BlockParts: blockParts}
|
BlockHash: blockHash, BlockParts: blockParts}
|
||||||
|
|
||||||
|
// 6 out of 10 voted for some block.
|
||||||
for i := 0; i < 6; i++ {
|
for i := 0; i < 6; i++ {
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[i], vote, voteSet)
|
||||||
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[i].Address, vote)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeValidation should fail.
|
// MakeValidation should fail.
|
||||||
@ -291,18 +299,14 @@ func TestMakeValidation(t *testing.T) {
|
|||||||
|
|
||||||
// 7th voted for some other block.
|
// 7th voted for some other block.
|
||||||
{
|
{
|
||||||
vote := &Vote{Height: height, Round: round, Type: VoteTypeCommit,
|
vote := withBlockHash(vote, RandBytes(32))
|
||||||
BlockHash: CRandBytes(32),
|
vote = withBlockParts(vote, PartSetHeader{123, RandBytes(32)})
|
||||||
BlockParts: PartSetHeader{123, CRandBytes(32)}}
|
signAddVote(privValidators[6], vote, voteSet)
|
||||||
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[6].Address, vote)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The 8th voted like everyone else.
|
// The 8th voted like everyone else.
|
||||||
{
|
{
|
||||||
vote := voteProto.Copy()
|
signAddVote(privValidators[7], vote, voteSet)
|
||||||
vote.Signature = privValidators[7].SignVoteUnsafe(vote)
|
|
||||||
voteSet.Add(privValidators[7].Address, vote)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validation := voteSet.MakeValidation()
|
validation := voteSet.MakeValidation()
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
Mempool receives new transactions and applies them to the latest committed state.
|
Mempool receives new transactions and applies them to the latest committed state.
|
||||||
If the transaction is acceptable, then it broadcasts the tx to peers.
|
If the transaction is acceptable, then it broadcasts the tx to peers.
|
||||||
|
|
||||||
When this node happens to be the next proposer, it simply takes the recently
|
When this node happens to be the next proposer, it simply uses the recently
|
||||||
modified state (and the associated transactions) and use that as the proposal.
|
modified state (and the associated transactions) to construct a proposal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package mempool
|
package mempool
|
||||||
|
@ -27,16 +27,16 @@ func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenesisStateFromFile(db db_.DB, genDocFile string) *State {
|
func MakeGenesisStateFromFile(db db_.DB, genDocFile string) *State {
|
||||||
jsonBlob, err := ioutil.ReadFile(genDocFile)
|
jsonBlob, err := ioutil.ReadFile(genDocFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Panicf("Couldn't read GenesisDoc file: %v", err)
|
Panicf("Couldn't read GenesisDoc file: %v", err)
|
||||||
}
|
}
|
||||||
genDoc := GenesisDocFromJSON(jsonBlob)
|
genDoc := GenesisDocFromJSON(jsonBlob)
|
||||||
return GenesisState(db, genDoc)
|
return MakeGenesisState(db, genDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenesisState(db db_.DB, genDoc *GenesisDoc) *State {
|
func MakeGenesisState(db db_.DB, genDoc *GenesisDoc) *State {
|
||||||
if len(genDoc.Validators) == 0 {
|
if len(genDoc.Validators) == 0 {
|
||||||
panic("Must have some validators")
|
panic("Must have some validators")
|
||||||
}
|
}
|
||||||
|
@ -629,6 +629,7 @@ func (s *State) Hash() []byte {
|
|||||||
s.BondedValidators,
|
s.BondedValidators,
|
||||||
s.UnbondingValidators,
|
s.UnbondingValidators,
|
||||||
s.accounts,
|
s.accounts,
|
||||||
|
s.validatorInfos,
|
||||||
}
|
}
|
||||||
return merkle.HashFromHashables(hashables)
|
return merkle.HashFromHashables(hashables)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCopyState(t *testing.T) {
|
func TestCopyState(t *testing.T) {
|
||||||
// Generate a state
|
// Generate a random state
|
||||||
s0, privAccounts, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
|
s0, privAccounts, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
|
||||||
s0Hash := s0.Hash()
|
s0Hash := s0.Hash()
|
||||||
if len(s0Hash) == 0 {
|
if len(s0Hash) == 0 {
|
||||||
@ -29,19 +29,23 @@ func TestCopyState(t *testing.T) {
|
|||||||
acc0Address := privAccounts[0].PubKey.Address()
|
acc0Address := privAccounts[0].PubKey.Address()
|
||||||
acc := s0.GetAccount(acc0Address)
|
acc := s0.GetAccount(acc0Address)
|
||||||
acc.Balance += 1
|
acc.Balance += 1
|
||||||
|
|
||||||
// The account balance shouldn't have changed yet.
|
// The account balance shouldn't have changed yet.
|
||||||
if s0.GetAccount(acc0Address).Balance == acc.Balance {
|
if s0.GetAccount(acc0Address).Balance == acc.Balance {
|
||||||
t.Error("Account balance changed unexpectedly")
|
t.Error("Account balance changed unexpectedly")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting, however, should change the balance.
|
// Setting, however, should change the balance.
|
||||||
s0.SetAccount(acc)
|
s0.SetAccount(acc)
|
||||||
if s0.GetAccount(acc0Address).Balance != acc.Balance {
|
if s0.GetAccount(acc0Address).Balance != acc.Balance {
|
||||||
t.Error("Account balance wasn't set")
|
t.Error("Account balance wasn't set")
|
||||||
}
|
}
|
||||||
// How that the state changed, the hash should change too.
|
|
||||||
|
// Now that the state changed, the hash should change too.
|
||||||
if bytes.Equal(s0Hash, s0.Hash()) {
|
if bytes.Equal(s0Hash, s0.Hash()) {
|
||||||
t.Error("Expected state hash to have changed")
|
t.Error("Expected state hash to have changed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// The s0Copy shouldn't have changed though.
|
// The s0Copy shouldn't have changed though.
|
||||||
if !bytes.Equal(s0Hash, s0Copy.Hash()) {
|
if !bytes.Equal(s0Hash, s0Copy.Hash()) {
|
||||||
t.Error("Expected state copy hash to have not changed")
|
t.Error("Expected state copy hash to have not changed")
|
||||||
@ -52,6 +56,7 @@ func TestGenesisSaveLoad(t *testing.T) {
|
|||||||
|
|
||||||
// Generate a state, save & load it.
|
// Generate a state, save & load it.
|
||||||
s0, _, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
|
s0, _, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
|
||||||
|
|
||||||
// Mutate the state to append one empty block.
|
// Mutate the state to append one empty block.
|
||||||
block := &Block{
|
block := &Block{
|
||||||
Header: &Header{
|
Header: &Header{
|
||||||
@ -70,7 +75,8 @@ func TestGenesisSaveLoad(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
blockParts := NewPartSetFromData(BinaryBytes(block))
|
blockParts := NewPartSetFromData(BinaryBytes(block))
|
||||||
// The second argument to AppendBlock() is false,
|
|
||||||
|
// The last argument to AppendBlock() is `false`,
|
||||||
// which sets Block.Header.StateHash.
|
// which sets Block.Header.StateHash.
|
||||||
err := s0.Copy().AppendBlock(block, blockParts.Header(), false)
|
err := s0.Copy().AppendBlock(block, blockParts.Header(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -79,6 +85,7 @@ func TestGenesisSaveLoad(t *testing.T) {
|
|||||||
if len(block.Header.StateHash) == 0 {
|
if len(block.Header.StateHash) == 0 {
|
||||||
t.Error("Expected StateHash but got nothing.")
|
t.Error("Expected StateHash but got nothing.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now append the block to s0.
|
// Now append the block to s0.
|
||||||
// This time we also check the StateHash (as computed above).
|
// This time we also check the StateHash (as computed above).
|
||||||
err = s0.AppendBlock(block, blockParts.Header(), true)
|
err = s0.AppendBlock(block, blockParts.Header(), true)
|
||||||
@ -108,6 +115,7 @@ func TestGenesisSaveLoad(t *testing.T) {
|
|||||||
if !bytes.Equal(s0.LastBlockHash, s1.LastBlockHash) {
|
if !bytes.Equal(s0.LastBlockHash, s1.LastBlockHash) {
|
||||||
t.Error("LastBlockHash mismatch")
|
t.Error("LastBlockHash mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare state merkle trees
|
// Compare state merkle trees
|
||||||
if s0.BondedValidators.Size() != s1.BondedValidators.Size() {
|
if s0.BondedValidators.Size() != s1.BondedValidators.Size() {
|
||||||
t.Error("BondedValidators Size mismatch")
|
t.Error("BondedValidators Size mismatch")
|
||||||
@ -130,6 +138,9 @@ func TestGenesisSaveLoad(t *testing.T) {
|
|||||||
if !bytes.Equal(s0.accounts.Hash(), s1.accounts.Hash()) {
|
if !bytes.Equal(s0.accounts.Hash(), s1.accounts.Hash()) {
|
||||||
t.Error("Accounts mismatch")
|
t.Error("Accounts mismatch")
|
||||||
}
|
}
|
||||||
|
if !bytes.Equal(s0.validatorInfos.Hash(), s1.validatorInfos.Hash()) {
|
||||||
|
t.Error("Accounts mismatch")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTxSequence(t *testing.T) {
|
func TestTxSequence(t *testing.T) {
|
||||||
@ -285,6 +296,5 @@ func TestTxs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO UnbondTx.
|
// TODO UnbondTx.
|
||||||
// TODO NameTx.
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func RandGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV
|
|||||||
privValidators[i] = privVal
|
privValidators[i] = privVal
|
||||||
}
|
}
|
||||||
sort.Sort(PrivValidatorsByAddress(privValidators))
|
sort.Sort(PrivValidatorsByAddress(privValidators))
|
||||||
s0 := GenesisState(db, &GenesisDoc{
|
s0 := MakeGenesisState(db, &GenesisDoc{
|
||||||
GenesisTime: time.Now(),
|
GenesisTime: time.Now(),
|
||||||
Accounts: accounts,
|
Accounts: accounts,
|
||||||
Validators: validators,
|
Validators: validators,
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
. "github.com/tendermint/tendermint/block"
|
. "github.com/tendermint/tendermint/block"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Persistent static data for each Validator
|
// Persistent (mostly) static data for each Validator
|
||||||
type ValidatorInfo struct {
|
type ValidatorInfo struct {
|
||||||
Address []byte
|
Address []byte
|
||||||
PubKey PubKeyEd25519
|
PubKey PubKeyEd25519
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// ValidatorSet represent a set of *Validator at a given height.
|
// ValidatorSet represent a set of *Validator at a given height.
|
||||||
// The validators can be fetched by address or index.
|
// The validators can be fetched by address or index.
|
||||||
// The index is in order of .Address, so the index are the same
|
// The index is in order of .Address, so the indices are fixed
|
||||||
// for all rounds of a given blockchain height.
|
// for all rounds of a given blockchain height.
|
||||||
// On the other hand, the .AccumPower of each validator and
|
// On the other hand, the .AccumPower of each validator and
|
||||||
// the designated .Proposer() of a set changes every round,
|
// the designated .Proposer() of a set changes every round,
|
||||||
|
Reference in New Issue
Block a user