mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-13 21:31:23 +00:00
Pretty print Vote, VoteSet
This commit is contained in:
@ -2,6 +2,7 @@ package blocks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
. "github.com/tendermint/tendermint/binary"
|
. "github.com/tendermint/tendermint/binary"
|
||||||
@ -56,3 +57,20 @@ func (v *Vote) GetSignature() Signature {
|
|||||||
func (v *Vote) SetSignature(sig Signature) {
|
func (v *Vote) SetSignature(sig Signature) {
|
||||||
v.Signature = sig
|
v.Signature = sig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Vote) String() string {
|
||||||
|
blockHash := v.BlockHash
|
||||||
|
if len(v.BlockHash) == 0 {
|
||||||
|
blockHash = make([]byte, 6) // for printing
|
||||||
|
}
|
||||||
|
switch v.Type {
|
||||||
|
case VoteTypeBare:
|
||||||
|
return fmt.Sprintf("Vote{%v/%v:%X:%v}", v.Height, v.Round, blockHash, v.SignerId)
|
||||||
|
case VoteTypePrecommit:
|
||||||
|
return fmt.Sprintf("Precommit{%v/%v:%X:%v}", v.Height, v.Round, blockHash, v.SignerId)
|
||||||
|
case VoteTypeCommit:
|
||||||
|
return fmt.Sprintf("Commit{%v/%v:%X:%v}", v.Height, v.Round, v.BlockHash[:6], v.SignerId)
|
||||||
|
default:
|
||||||
|
panic("Unknown vote type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/tendermint/tendermint/binary"
|
. "github.com/tendermint/tendermint/binary"
|
||||||
)
|
)
|
||||||
@ -153,3 +154,33 @@ func (bA BitArray) PickRarest(counts []int) (rarest int, ok bool) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bA BitArray) String() string {
|
||||||
|
return bA.StringWithIndent("")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bA BitArray) StringWithIndent(indent string) string {
|
||||||
|
lines := []string{}
|
||||||
|
bits := ""
|
||||||
|
for i := 0; i < len(bA)*64; i++ {
|
||||||
|
if bA.GetIndex(uint(i)) {
|
||||||
|
bits += "X"
|
||||||
|
} else {
|
||||||
|
bits += "_"
|
||||||
|
}
|
||||||
|
if i%100 == 99 {
|
||||||
|
lines = append(lines, bits)
|
||||||
|
bits = ""
|
||||||
|
}
|
||||||
|
if i%10 == 9 {
|
||||||
|
bits += " "
|
||||||
|
}
|
||||||
|
if i%50 == 49 {
|
||||||
|
bits += " "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(bits) > 0 {
|
||||||
|
lines = append(lines, bits)
|
||||||
|
}
|
||||||
|
return strings.Join(lines, indent)
|
||||||
|
}
|
||||||
|
@ -142,9 +142,9 @@ func (cs *ConsensusState) setupRound(round uint16) {
|
|||||||
cs.ProposalPOL = nil
|
cs.ProposalPOL = nil
|
||||||
cs.ProposalPOLPartSet = nil
|
cs.ProposalPOLPartSet = nil
|
||||||
cs.Votes = NewVoteSet(cs.Height, round, VoteTypeBare, validators)
|
cs.Votes = NewVoteSet(cs.Height, round, VoteTypeBare, validators)
|
||||||
cs.Votes.AddVotesFromCommits(cs.Commits)
|
cs.Votes.AddFromCommits(cs.Commits)
|
||||||
cs.Precommits = NewVoteSet(cs.Height, round, VoteTypePrecommit, validators)
|
cs.Precommits = NewVoteSet(cs.Height, round, VoteTypePrecommit, validators)
|
||||||
cs.Precommits.AddVotesFromCommits(cs.Commits)
|
cs.Precommits.AddFromCommits(cs.Commits)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ConsensusState) SetStep(step byte) {
|
func (cs *ConsensusState) SetStep(step byte) {
|
||||||
@ -289,15 +289,15 @@ func (cs *ConsensusState) AddVote(vote *Vote) (added bool, err error) {
|
|||||||
switch vote.Type {
|
switch vote.Type {
|
||||||
case VoteTypeBare:
|
case VoteTypeBare:
|
||||||
// Votes checks for height+round match.
|
// Votes checks for height+round match.
|
||||||
return cs.Votes.AddVote(vote)
|
return cs.Votes.Add(vote)
|
||||||
case VoteTypePrecommit:
|
case VoteTypePrecommit:
|
||||||
// Precommits checks for height+round match.
|
// Precommits checks for height+round match.
|
||||||
return cs.Precommits.AddVote(vote)
|
return cs.Precommits.Add(vote)
|
||||||
case VoteTypeCommit:
|
case VoteTypeCommit:
|
||||||
// Commits checks for height match.
|
// Commits checks for height match.
|
||||||
cs.Votes.AddVote(vote)
|
cs.Votes.Add(vote)
|
||||||
cs.Precommits.AddVote(vote)
|
cs.Precommits.Add(vote)
|
||||||
return cs.Commits.AddVote(vote)
|
return cs.Commits.Add(vote)
|
||||||
default:
|
default:
|
||||||
panic("Unknown vote type")
|
panic("Unknown vote type")
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@ package consensus
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ func NewVoteSet(height uint32, round uint16, type_ byte, vset *ValidatorSet) *Vo
|
|||||||
|
|
||||||
// True if added, false if not.
|
// True if added, false if not.
|
||||||
// Returns ErrVote[UnexpectedPhase|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature]
|
// Returns ErrVote[UnexpectedPhase|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature]
|
||||||
func (vs *VoteSet) AddVote(vote *Vote) (bool, error) {
|
func (vs *VoteSet) Add(vote *Vote) (bool, error) {
|
||||||
vs.mtx.Lock()
|
vs.mtx.Lock()
|
||||||
defer vs.mtx.Unlock()
|
defer vs.mtx.Unlock()
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ func (vs *VoteSet) addVote(vote *Vote) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Assumes that commits VoteSet is valid.
|
// Assumes that commits VoteSet is valid.
|
||||||
func (vs *VoteSet) AddVotesFromCommits(commits *VoteSet) {
|
func (vs *VoteSet) AddFromCommits(commits *VoteSet) {
|
||||||
commitVotes := commits.AllVotes()
|
commitVotes := commits.AllVotes()
|
||||||
for _, commit := range commitVotes {
|
for _, commit := range commitVotes {
|
||||||
if commit.Round < vs.round {
|
if commit.Round < vs.round {
|
||||||
@ -177,3 +178,26 @@ func (vs *VoteSet) MakePOL() *POL {
|
|||||||
}
|
}
|
||||||
return pol
|
return pol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vs *VoteSet) String() string {
|
||||||
|
return vs.StringWithIndent("")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vs *VoteSet) StringWithIndent(indent string) string {
|
||||||
|
vs.mtx.Lock()
|
||||||
|
defer vs.mtx.Unlock()
|
||||||
|
|
||||||
|
voteStrings := make([]string, len(vs.votes))
|
||||||
|
for _, vote := range vs.votes {
|
||||||
|
voteStrings[vote.SignerId] = vote.String()
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`VoteSet{
|
||||||
|
%s H:%v R:%v T:%v
|
||||||
|
%s %v
|
||||||
|
%s %v
|
||||||
|
%s}`,
|
||||||
|
indent, vs.height, vs.round, vs.type_,
|
||||||
|
indent, strings.Join(voteStrings, "\n"+indent+" "),
|
||||||
|
indent, vs.votesBitArray,
|
||||||
|
indent)
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
. "github.com/tendermint/tendermint/blocks"
|
||||||
. "github.com/tendermint/tendermint/state"
|
. "github.com/tendermint/tendermint/state"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
@ -15,8 +16,33 @@ func makeValidator(id uint64, votingPower uint64) (*Validator, *PrivAccount) {
|
|||||||
}, privAccount
|
}, privAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeVoteSet(numValidators int, votingPower uint64) (*VoteSet, *ValidatorSet, []*PrivAccount) {
|
||||||
|
vals := make([]*Validator, numValidators)
|
||||||
|
privAccounts := make([]*PrivAccount, numValidators)
|
||||||
|
for i := 0; i < numValidators; i++ {
|
||||||
|
val, privAccount := makeValidator(uint64(i), votingPower)
|
||||||
|
vals[i] = val
|
||||||
|
privAccounts[i] = privAccount
|
||||||
|
}
|
||||||
|
valSet := NewValidatorSet(vals)
|
||||||
|
return NewVoteSet(0, 0, VoteTypeBare, valSet), valSet, privAccounts
|
||||||
|
}
|
||||||
|
|
||||||
func TestAddVote(t *testing.T) {
|
func TestAddVote(t *testing.T) {
|
||||||
// XXX
|
voteSet, valSet, privAccounts := makeVoteSet(10, 1)
|
||||||
|
vote := &Vote{Height: 0, Round: 0, Type: VoteTypeBare, BlockHash: nil}
|
||||||
|
|
||||||
|
t.Logf(">> %v", voteSet)
|
||||||
|
t.Logf(">> %v", valSet)
|
||||||
|
t.Logf(">> %v", privAccounts)
|
||||||
|
|
||||||
|
privAccounts[0].Sign(vote)
|
||||||
|
voteSet.Add(vote)
|
||||||
|
|
||||||
|
t.Logf(">> %v", voteSet)
|
||||||
|
t.Logf(">> %v", valSet)
|
||||||
|
t.Logf(">> %v", privAccounts)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test2_3Majority(t *testing.T) {
|
func Test2_3Majority(t *testing.T) {
|
||||||
|
@ -39,6 +39,9 @@ func (account Account) VerifyBytes(msg []byte, sig Signature) bool {
|
|||||||
if sig.SignerId != account.Id {
|
if sig.SignerId != account.Id {
|
||||||
panic("account.id doesn't match sig.signerid")
|
panic("account.id doesn't match sig.signerid")
|
||||||
}
|
}
|
||||||
|
if len(sig.Bytes) == 0 {
|
||||||
|
panic("signature is empty")
|
||||||
|
}
|
||||||
v1 := &crypto.Verify{
|
v1 := &crypto.Verify{
|
||||||
Message: msg,
|
Message: msg,
|
||||||
PubKey: account.PubKey,
|
PubKey: account.PubKey,
|
||||||
@ -57,7 +60,7 @@ func (account Account) Verify(o Signable) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (account Account) String() string {
|
func (account Account) String() string {
|
||||||
return fmt.Sprintf("Account{%v:%X}", account.Id, account.PubKey)
|
return fmt.Sprintf("Account{%v:%X}", account.Id, account.PubKey[:6])
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user