diff --git a/consensus/types/height_vote_set.go b/consensus/types/height_vote_set.go index a155bce08..f65f365b8 100644 --- a/consensus/types/height_vote_set.go +++ b/consensus/types/height_vote_set.go @@ -207,6 +207,30 @@ 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"` +} + +func (hvs *HeightVoteSet) MarshalJSON() ([]byte, error) { + hvs.mtx.Lock() + defer hvs.mtx.Unlock() + totalRounds := hvs.round + 1 + roundsVotes := make([]roundVoteBitArrays, 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(), + } + } + // TODO: all other peer catchup rounds + + return cdc.MarshalJSON(roundsVotes) +} + // If a peer claims that it has 2/3 majority for given blockKey, call this. // NOTE: if there are too many peers, or too much peer churn, // this can cause memory issues. diff --git a/types/part_set.go b/types/part_set.go index 749943291..e4f2b9e97 100644 --- a/types/part_set.go +++ b/types/part_set.go @@ -264,3 +264,20 @@ func (ps *PartSet) StringShort() string { defer ps.mtx.Unlock() return fmt.Sprintf("(%v of %v)", ps.Count(), ps.Total()) } + +func (ps *PartSet) MarshalJSON() ([]byte, error) { + if ps == nil { + return []byte("nil-PartSet"), nil + } + + ps.mtx.Lock() + defer ps.mtx.Unlock() + + return cdc.MarshalJSON(struct { + CountTotal string `json:"count/total"` + PartsBitArray *cmn.BitArray `json:"parts_bit_array"` + }{ + fmt.Sprintf("%d/%d", ps.Count(), ps.Total()), + ps.partsBitArray.Copy(), + }) +} diff --git a/types/vote_set.go b/types/vote_set.go index e255488d6..07ef60ec6 100644 --- a/types/vote_set.go +++ b/types/vote_set.go @@ -445,6 +445,26 @@ func (voteSet *VoteSet) StringIndented(indent string) string { indent) } +// Marshal the VoteSet to JSON. Same as String(), just in JSON, +// and without the height/round/type_ (since its already included in the votes). +func (voteSet *VoteSet) MarshalJSON() ([]byte, error) { + voteStrings := make([]string, len(voteSet.votes)) + for i, vote := range voteSet.votes { + if vote == nil { + voteStrings[i] = "nil-Vote" + } else { + 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, + }) +} + func (voteSet *VoteSet) StringShort() string { if voteSet == nil { return "nil-VoteSet"