Browse Source

rpc: add voting power totals to vote bitarrays

pull/1564/head
Ethan Buchman 6 years ago
parent
commit
658060150c
4 changed files with 66 additions and 19 deletions
  1. +1
    -0
      consensus/state.go
  2. +14
    -9
      consensus/types/height_vote_set.go
  3. +2
    -1
      rpc/core/types/responses.go
  4. +49
    -9
      types/vote_set.go

+ 1
- 0
consensus/state.go View File

@ -1279,6 +1279,7 @@ func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error {
cs.Proposal = proposal
cs.ProposalBlockParts = types.NewPartSetFromHeader(proposal.BlockPartsHeader)
cs.Logger.Info("Received proposal", "proposal", proposal)
return nil
}


+ 14
- 9
consensus/types/height_vote_set.go View File

@ -207,23 +207,28 @@ func (hvs *HeightVoteSet) StringIndented(indent string) string {
indent)
}
type roundVoteBitArrays struct {
Round int `json:"round"`
Prevotes *cmn.BitArray `json:"prevotes"`
Precommits *cmn.BitArray `json:"precommits"`
// `"__xx_xx____x:46/100:0.46"`
type roundVotes struct {
Round int `json:"round"`
Prevotes []string `json:"prevotes"`
PrevotesBitArray string `json:"prevotes_bit_array"`
Precommits []string `json:"precommits"`
PrecommitsBitArray string `json:"precommits_bit_array"`
}
func (hvs *HeightVoteSet) MarshalJSON() ([]byte, error) {
hvs.mtx.Lock()
defer hvs.mtx.Unlock()
totalRounds := hvs.round + 1
roundsVotes := make([]roundVoteBitArrays, totalRounds)
roundsVotes := make([]roundVotes, totalRounds)
// rounds 0 ~ hvs.round inclusive
for round := 0; round < totalRounds; round++ {
roundsVotes[round] = roundVoteBitArrays{
Round: round,
Prevotes: hvs.roundVoteSets[round].Prevotes.BitArray(),
Precommits: hvs.roundVoteSets[round].Precommits.BitArray(),
roundsVotes[round] = roundVotes{
Round: round,
Prevotes: hvs.roundVoteSets[round].Prevotes.VoteStrings(),
PrevotesBitArray: hvs.roundVoteSets[round].Prevotes.BitArrayString(),
Precommits: hvs.roundVoteSets[round].Precommits.VoteStrings(),
PrecommitsBitArray: hvs.roundVoteSets[round].Precommits.BitArrayString(),
}
}
// TODO: all other peer catchup rounds


+ 2
- 1
rpc/core/types/responses.go View File

@ -128,12 +128,13 @@ type ResultValidators struct {
}
// Info about the consensus state.
// Unstable
// UNSTABLE
type ResultDumpConsensusState struct {
RoundState json.RawMessage `json:"round_state"`
Peers []PeerStateInfo `json:"peers"`
}
// UNSTABLE
type PeerStateInfo struct {
NodeAddress string `json:"node_address"`
PeerState json.RawMessage `json:"peer_state"`


+ 49
- 9
types/vote_set.go View File

@ -454,6 +454,44 @@ func (voteSet *VoteSet) StringIndented(indent string) string {
func (voteSet *VoteSet) MarshalJSON() ([]byte, error) {
voteSet.mtx.Lock()
defer voteSet.mtx.Unlock()
return cdc.MarshalJSON(VoteSetJSON{
voteSet.voteStrings(),
voteSet.bitArrayString(),
voteSet.peerMaj23s,
})
}
// More human readable JSON of the vote set
// NOTE: insufficient for unmarshalling from (compressed votes)
// TODO: make the peerMaj23s nicer to read (eg just the block hash)
type VoteSetJSON struct {
Votes []string `json:"votes"`
VotesBitArray string `json:"votes_bit_array"`
PeerMaj23s map[P2PID]BlockID `json:"peer_maj_23s"`
}
// Return the bit-array of votes including the fraction of power
// that has voted eg. "__x_xxx_:6/20 = 0.3".
func (voteSet *VoteSet) BitArrayString() string {
voteSet.mtx.Lock()
defer voteSet.mtx.Unlock()
return voteSet.bitArrayString()
}
func (voteSet *VoteSet) bitArrayString() string {
bAString := voteSet.votesBitArray.String()
voted, total, fracVoted := voteSet.sumTotalFrac()
return fmt.Sprintf("%s %d/%d = %.2f", bAString, voted, total, fracVoted)
}
// Returns a list of votes compressed to more readable strings.
func (voteSet *VoteSet) VoteStrings() []string {
voteSet.mtx.Lock()
defer voteSet.mtx.Unlock()
return voteSet.voteStrings()
}
func (voteSet *VoteSet) voteStrings() []string {
voteStrings := make([]string, len(voteSet.votes))
for i, vote := range voteSet.votes {
if vote == nil {
@ -462,13 +500,7 @@ func (voteSet *VoteSet) MarshalJSON() ([]byte, error) {
voteStrings[i] = vote.String()
}
}
return cdc.MarshalJSON(struct {
Votes []string `json:"votes"`
VotesBitArray *cmn.BitArray `json:"votes_bit_array"`
PeerMaj23s map[P2PID]BlockID `json:"peer_maj_23s"`
}{
voteStrings, voteSet.votesBitArray, voteSet.peerMaj23s,
})
return voteStrings
}
func (voteSet *VoteSet) StringShort() string {
@ -477,8 +509,16 @@ func (voteSet *VoteSet) StringShort() string {
}
voteSet.mtx.Lock()
defer voteSet.mtx.Unlock()
return fmt.Sprintf(`VoteSet{H:%v R:%v T:%v +2/3:%v %v %v}`,
voteSet.height, voteSet.round, voteSet.type_, voteSet.maj23, voteSet.votesBitArray, voteSet.peerMaj23s)
_, _, frac := voteSet.sumTotalFrac()
return fmt.Sprintf(`VoteSet{H:%v R:%v T:%v +2/3:%v(%v) %v %v}`,
voteSet.height, voteSet.round, voteSet.type_, voteSet.maj23, frac, voteSet.votesBitArray, voteSet.peerMaj23s)
}
// return the power voted, the total, and the fraction
func (voteSet *VoteSet) sumTotalFrac() (int64, int64, float64) {
voted, total := voteSet.sum, voteSet.valSet.TotalVotingPower()
fracVoted := float64(voted) / float64(total)
return voted, total, fracVoted
}
//--------------------------------------------------------------------------------


Loading…
Cancel
Save