Add back sample output in rpc/core/consensus.go; Tweak DumpConsensusState output for peers

This commit is contained in:
Jae Kwon
2018-05-12 15:39:30 -07:00
parent edbec10f9e
commit 56c9e0da7e
4 changed files with 238 additions and 105 deletions

View File

@ -846,17 +846,17 @@ type PeerState struct {
peer p2p.Peer peer p2p.Peer
logger log.Logger logger log.Logger
mtx sync.Mutex // mtx sync.Mutex `json:"-"` // NOTE: Modify below using setters, never directly.
cstypes.PeerRoundState // Exposed. PRS cstypes.PeerRoundState `json:"round_state"` // Exposed.
Stats *peerStateStats // Stats *peerStateStats `json:"stats"` // Exposed.
} }
// peerStateStats holds internal statistics for a peer. // peerStateStats holds internal statistics for a peer.
type peerStateStats struct { type peerStateStats struct {
LastVoteHeight int64 LastVoteHeight int64 `json:"last_vote_height"`
Votes int Votes int `json:"votes"`
LastBlockPartHeight int64 LastBlockPartHeight int64 `json:"last_block_part_height"`
BlockParts int BlockParts int `json:"block_parts"`
} }
func (pss peerStateStats) String() string { func (pss peerStateStats) String() string {
@ -869,7 +869,7 @@ func NewPeerState(peer p2p.Peer) *PeerState {
return &PeerState{ return &PeerState{
peer: peer, peer: peer,
logger: log.NewNopLogger(), logger: log.NewNopLogger(),
PeerRoundState: cstypes.PeerRoundState{ PRS: cstypes.PeerRoundState{
Round: -1, Round: -1,
ProposalPOLRound: -1, ProposalPOLRound: -1,
LastCommitRound: -1, LastCommitRound: -1,
@ -892,16 +892,16 @@ func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
prs := ps.PeerRoundState // copy prs := ps.PRS // copy
return &prs return &prs
} }
// GetRoundStateJSON returns a json of PeerRoundState, marshalled using go-amino. // ToJSON returns a json of PeerState, marshalled using go-amino.
func (ps *PeerState) GetRoundStateJSON() ([]byte, error) { func (ps *PeerState) ToJSON() ([]byte, error) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
return cdc.MarshalJSON(ps.PeerRoundState) return cdc.MarshalJSON(ps)
} }
// GetHeight returns an atomic snapshot of the PeerRoundState's height // GetHeight returns an atomic snapshot of the PeerRoundState's height
@ -909,7 +909,7 @@ func (ps *PeerState) GetRoundStateJSON() ([]byte, error) {
func (ps *PeerState) GetHeight() int64 { func (ps *PeerState) GetHeight() int64 {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
return ps.PeerRoundState.Height return ps.PRS.Height
} }
// SetHasProposal sets the given proposal as known for the peer. // SetHasProposal sets the given proposal as known for the peer.
@ -917,18 +917,18 @@ func (ps *PeerState) SetHasProposal(proposal *types.Proposal) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.Height != proposal.Height || ps.Round != proposal.Round { if ps.PRS.Height != proposal.Height || ps.PRS.Round != proposal.Round {
return return
} }
if ps.Proposal { if ps.PRS.Proposal {
return return
} }
ps.Proposal = true ps.PRS.Proposal = true
ps.ProposalBlockPartsHeader = proposal.BlockPartsHeader ps.PRS.ProposalBlockPartsHeader = proposal.BlockPartsHeader
ps.ProposalBlockParts = cmn.NewBitArray(proposal.BlockPartsHeader.Total) ps.PRS.ProposalBlockParts = cmn.NewBitArray(proposal.BlockPartsHeader.Total)
ps.ProposalPOLRound = proposal.POLRound ps.PRS.ProposalPOLRound = proposal.POLRound
ps.ProposalPOL = nil // Nil until ProposalPOLMessage received. ps.PRS.ProposalPOL = nil // Nil until ProposalPOLMessage received.
} }
// InitProposalBlockParts initializes the peer's proposal block parts header and bit array. // InitProposalBlockParts initializes the peer's proposal block parts header and bit array.
@ -936,12 +936,12 @@ func (ps *PeerState) InitProposalBlockParts(partsHeader types.PartSetHeader) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.ProposalBlockParts != nil { if ps.PRS.ProposalBlockParts != nil {
return return
} }
ps.ProposalBlockPartsHeader = partsHeader ps.PRS.ProposalBlockPartsHeader = partsHeader
ps.ProposalBlockParts = cmn.NewBitArray(partsHeader.Total) ps.PRS.ProposalBlockParts = cmn.NewBitArray(partsHeader.Total)
} }
// SetHasProposalBlockPart sets the given block part index as known for the peer. // SetHasProposalBlockPart sets the given block part index as known for the peer.
@ -949,11 +949,11 @@ func (ps *PeerState) SetHasProposalBlockPart(height int64, round int, index int)
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.Height != height || ps.Round != round { if ps.PRS.Height != height || ps.PRS.Round != round {
return return
} }
ps.ProposalBlockParts.SetIndex(index, true) ps.PRS.ProposalBlockParts.SetIndex(index, true)
} }
// PickSendVote picks a vote and sends it to the peer. // PickSendVote picks a vote and sends it to the peer.
@ -1002,40 +1002,40 @@ func (ps *PeerState) getVoteBitArray(height int64, round int, type_ byte) *cmn.B
return nil return nil
} }
if ps.Height == height { if ps.PRS.Height == height {
if ps.Round == round { if ps.PRS.Round == round {
switch type_ { switch type_ {
case types.VoteTypePrevote: case types.VoteTypePrevote:
return ps.Prevotes return ps.PRS.Prevotes
case types.VoteTypePrecommit: case types.VoteTypePrecommit:
return ps.Precommits return ps.PRS.Precommits
} }
} }
if ps.CatchupCommitRound == round { if ps.PRS.CatchupCommitRound == round {
switch type_ { switch type_ {
case types.VoteTypePrevote: case types.VoteTypePrevote:
return nil return nil
case types.VoteTypePrecommit: case types.VoteTypePrecommit:
return ps.CatchupCommit return ps.PRS.CatchupCommit
} }
} }
if ps.ProposalPOLRound == round { if ps.PRS.ProposalPOLRound == round {
switch type_ { switch type_ {
case types.VoteTypePrevote: case types.VoteTypePrevote:
return ps.ProposalPOL return ps.PRS.ProposalPOL
case types.VoteTypePrecommit: case types.VoteTypePrecommit:
return nil return nil
} }
} }
return nil return nil
} }
if ps.Height == height+1 { if ps.PRS.Height == height+1 {
if ps.LastCommitRound == round { if ps.PRS.LastCommitRound == round {
switch type_ { switch type_ {
case types.VoteTypePrevote: case types.VoteTypePrevote:
return nil return nil
case types.VoteTypePrecommit: case types.VoteTypePrecommit:
return ps.LastCommit return ps.PRS.LastCommit
} }
} }
return nil return nil
@ -1045,7 +1045,7 @@ func (ps *PeerState) getVoteBitArray(height int64, round int, type_ byte) *cmn.B
// 'round': A round for which we have a +2/3 commit. // 'round': A round for which we have a +2/3 commit.
func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValidators int) { func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValidators int) {
if ps.Height != height { if ps.PRS.Height != height {
return return
} }
/* /*
@ -1055,14 +1055,14 @@ func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValida
cmn.PanicSanity(cmn.Fmt("Conflicting CatchupCommitRound. Height: %v, Orig: %v, New: %v", height, ps.CatchupCommitRound, round)) cmn.PanicSanity(cmn.Fmt("Conflicting CatchupCommitRound. Height: %v, Orig: %v, New: %v", height, ps.CatchupCommitRound, round))
} }
*/ */
if ps.CatchupCommitRound == round { if ps.PRS.CatchupCommitRound == round {
return // Nothing to do! return // Nothing to do!
} }
ps.CatchupCommitRound = round ps.PRS.CatchupCommitRound = round
if round == ps.Round { if round == ps.PRS.Round {
ps.CatchupCommit = ps.Precommits ps.PRS.CatchupCommit = ps.PRS.Precommits
} else { } else {
ps.CatchupCommit = cmn.NewBitArray(numValidators) ps.PRS.CatchupCommit = cmn.NewBitArray(numValidators)
} }
} }
@ -1077,22 +1077,22 @@ func (ps *PeerState) EnsureVoteBitArrays(height int64, numValidators int) {
} }
func (ps *PeerState) ensureVoteBitArrays(height int64, numValidators int) { func (ps *PeerState) ensureVoteBitArrays(height int64, numValidators int) {
if ps.Height == height { if ps.PRS.Height == height {
if ps.Prevotes == nil { if ps.PRS.Prevotes == nil {
ps.Prevotes = cmn.NewBitArray(numValidators) ps.PRS.Prevotes = cmn.NewBitArray(numValidators)
} }
if ps.Precommits == nil { if ps.PRS.Precommits == nil {
ps.Precommits = cmn.NewBitArray(numValidators) ps.PRS.Precommits = cmn.NewBitArray(numValidators)
} }
if ps.CatchupCommit == nil { if ps.PRS.CatchupCommit == nil {
ps.CatchupCommit = cmn.NewBitArray(numValidators) ps.PRS.CatchupCommit = cmn.NewBitArray(numValidators)
} }
if ps.ProposalPOL == nil { if ps.PRS.ProposalPOL == nil {
ps.ProposalPOL = cmn.NewBitArray(numValidators) ps.PRS.ProposalPOL = cmn.NewBitArray(numValidators)
} }
} else if ps.Height == height+1 { } else if ps.PRS.Height == height+1 {
if ps.LastCommit == nil { if ps.PRS.LastCommit == nil {
ps.LastCommit = cmn.NewBitArray(numValidators) ps.PRS.LastCommit = cmn.NewBitArray(numValidators)
} }
} }
} }
@ -1156,7 +1156,7 @@ func (ps *PeerState) SetHasVote(vote *types.Vote) {
} }
func (ps *PeerState) setHasVote(height int64, round int, type_ byte, index int) { func (ps *PeerState) setHasVote(height int64, round int, type_ byte, index int) {
logger := ps.logger.With("peerH/R", cmn.Fmt("%d/%d", ps.Height, ps.Round), "H/R", cmn.Fmt("%d/%d", height, round)) logger := ps.logger.With("peerH/R", cmn.Fmt("%d/%d", ps.PRS.Height, ps.PRS.Round), "H/R", cmn.Fmt("%d/%d", height, round))
logger.Debug("setHasVote", "type", type_, "index", index) logger.Debug("setHasVote", "type", type_, "index", index)
// NOTE: some may be nil BitArrays -> no side effects. // NOTE: some may be nil BitArrays -> no side effects.
@ -1172,51 +1172,51 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) {
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
// Ignore duplicates or decreases // Ignore duplicates or decreases
if CompareHRS(msg.Height, msg.Round, msg.Step, ps.Height, ps.Round, ps.Step) <= 0 { if CompareHRS(msg.Height, msg.Round, msg.Step, ps.PRS.Height, ps.PRS.Round, ps.PRS.Step) <= 0 {
return return
} }
// Just remember these values. // Just remember these values.
psHeight := ps.Height psHeight := ps.PRS.Height
psRound := ps.Round psRound := ps.PRS.Round
//psStep := ps.Step //psStep := ps.PRS.Step
psCatchupCommitRound := ps.CatchupCommitRound psCatchupCommitRound := ps.PRS.CatchupCommitRound
psCatchupCommit := ps.CatchupCommit psCatchupCommit := ps.PRS.CatchupCommit
startTime := time.Now().Add(-1 * time.Duration(msg.SecondsSinceStartTime) * time.Second) startTime := time.Now().Add(-1 * time.Duration(msg.SecondsSinceStartTime) * time.Second)
ps.Height = msg.Height ps.PRS.Height = msg.Height
ps.Round = msg.Round ps.PRS.Round = msg.Round
ps.Step = msg.Step ps.PRS.Step = msg.Step
ps.StartTime = startTime ps.PRS.StartTime = startTime
if psHeight != msg.Height || psRound != msg.Round { if psHeight != msg.Height || psRound != msg.Round {
ps.Proposal = false ps.PRS.Proposal = false
ps.ProposalBlockPartsHeader = types.PartSetHeader{} ps.PRS.ProposalBlockPartsHeader = types.PartSetHeader{}
ps.ProposalBlockParts = nil ps.PRS.ProposalBlockParts = nil
ps.ProposalPOLRound = -1 ps.PRS.ProposalPOLRound = -1
ps.ProposalPOL = nil ps.PRS.ProposalPOL = nil
// We'll update the BitArray capacity later. // We'll update the BitArray capacity later.
ps.Prevotes = nil ps.PRS.Prevotes = nil
ps.Precommits = nil ps.PRS.Precommits = nil
} }
if psHeight == msg.Height && psRound != msg.Round && msg.Round == psCatchupCommitRound { if psHeight == msg.Height && psRound != msg.Round && msg.Round == psCatchupCommitRound {
// Peer caught up to CatchupCommitRound. // Peer caught up to CatchupCommitRound.
// Preserve psCatchupCommit! // Preserve psCatchupCommit!
// NOTE: We prefer to use prs.Precommits if // NOTE: We prefer to use prs.Precommits if
// pr.Round matches pr.CatchupCommitRound. // pr.Round matches pr.CatchupCommitRound.
ps.Precommits = psCatchupCommit ps.PRS.Precommits = psCatchupCommit
} }
if psHeight != msg.Height { if psHeight != msg.Height {
// Shift Precommits to LastCommit. // Shift Precommits to LastCommit.
if psHeight+1 == msg.Height && psRound == msg.LastCommitRound { if psHeight+1 == msg.Height && psRound == msg.LastCommitRound {
ps.LastCommitRound = msg.LastCommitRound ps.PRS.LastCommitRound = msg.LastCommitRound
ps.LastCommit = ps.Precommits ps.PRS.LastCommit = ps.PRS.Precommits
} else { } else {
ps.LastCommitRound = msg.LastCommitRound ps.PRS.LastCommitRound = msg.LastCommitRound
ps.LastCommit = nil ps.PRS.LastCommit = nil
} }
// We'll update the BitArray capacity later. // We'll update the BitArray capacity later.
ps.CatchupCommitRound = -1 ps.PRS.CatchupCommitRound = -1
ps.CatchupCommit = nil ps.PRS.CatchupCommit = nil
} }
} }
@ -1225,12 +1225,12 @@ func (ps *PeerState) ApplyCommitStepMessage(msg *CommitStepMessage) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.Height != msg.Height { if ps.PRS.Height != msg.Height {
return return
} }
ps.ProposalBlockPartsHeader = msg.BlockPartsHeader ps.PRS.ProposalBlockPartsHeader = msg.BlockPartsHeader
ps.ProposalBlockParts = msg.BlockParts ps.PRS.ProposalBlockParts = msg.BlockParts
} }
// ApplyProposalPOLMessage updates the peer state for the new proposal POL. // ApplyProposalPOLMessage updates the peer state for the new proposal POL.
@ -1238,16 +1238,16 @@ func (ps *PeerState) ApplyProposalPOLMessage(msg *ProposalPOLMessage) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.Height != msg.Height { if ps.PRS.Height != msg.Height {
return return
} }
if ps.ProposalPOLRound != msg.ProposalPOLRound { if ps.PRS.ProposalPOLRound != msg.ProposalPOLRound {
return return
} }
// TODO: Merge onto existing ps.ProposalPOL? // TODO: Merge onto existing ps.PRS.ProposalPOL?
// We might have sent some prevotes in the meantime. // We might have sent some prevotes in the meantime.
ps.ProposalPOL = msg.ProposalPOL ps.PRS.ProposalPOL = msg.ProposalPOL
} }
// ApplyHasVoteMessage updates the peer state for the new vote. // ApplyHasVoteMessage updates the peer state for the new vote.
@ -1255,7 +1255,7 @@ func (ps *PeerState) ApplyHasVoteMessage(msg *HasVoteMessage) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.Height != msg.Height { if ps.PRS.Height != msg.Height {
return return
} }
@ -1298,7 +1298,7 @@ func (ps *PeerState) StringIndented(indent string) string {
%s Stats %v %s Stats %v
%s}`, %s}`,
indent, ps.peer.ID(), indent, ps.peer.ID(),
indent, ps.PeerRoundState.StringIndented(indent+" "), indent, ps.PRS.StringIndented(indent+" "),
indent, ps.Stats, indent, ps.Stats,
indent) indent)
} }

View File

@ -1,5 +1,7 @@
package client
/* /*
package client provides a general purpose interface (Client) for connecting The client package provides a general purpose interface (Client) for connecting
to a tendermint node, as well as higher-level functionality. to a tendermint node, as well as higher-level functionality.
The main implementation for production code is client.HTTP, which The main implementation for production code is client.HTTP, which
@ -17,7 +19,6 @@ for maximum flexibility and testability, and two implementations,
this package also provides helper functions that work on any Client this package also provides helper functions that work on any Client
implementation. implementation.
*/ */
package client
import ( import (
ctypes "github.com/tendermint/tendermint/rpc/core/types" ctypes "github.com/tendermint/tendermint/rpc/core/types"
@ -29,13 +30,13 @@ import (
// affects the ABCI app. In many cases this will be all we want, // affects the ABCI app. In many cases this will be all we want,
// so we can accept an interface which is easier to mock // so we can accept an interface which is easier to mock
type ABCIClient interface { type ABCIClient interface {
// reading from abci app // Reading from abci app
ABCIInfo() (*ctypes.ResultABCIInfo, error) ABCIInfo() (*ctypes.ResultABCIInfo, error)
ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQuery, error) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQuery, error)
ABCIQueryWithOptions(path string, data cmn.HexBytes, ABCIQueryWithOptions(path string, data cmn.HexBytes,
opts ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) opts ABCIQueryOptions) (*ctypes.ResultABCIQuery, error)
// writing to abci app // Writing to abci app
BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error)
BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error)
BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error)
@ -59,7 +60,7 @@ type HistoryClient interface {
} }
type StatusClient interface { type StatusClient interface {
// general chain info // General chain info
Status() (*ctypes.ResultStatus, error) Status() (*ctypes.ResultStatus, error)
} }

View File

@ -20,7 +20,7 @@ import (
// state, err := client.Validators() // state, err := client.Validators()
// ``` // ```
// //
// > The above command returns JSON structured like this: // The above command returns JSON structured like this:
// //
// ```json // ```json
// { // {
@ -59,23 +59,155 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
// DumpConsensusState dumps consensus state. // DumpConsensusState dumps consensus state.
// UNSTABLE // UNSTABLE
//
// ```shell
// curl 'localhost:46657/dump_consensus_state'
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// state, err := client.DumpConsensusState()
// ```
//
// The above command returns JSON structured like this:
//
// ```json
// {
// "jsonrpc": "2.0",
// "id": "",
// "result": {
// "round_state": {
// "height": 7185,
// "round": 0,
// "step": 1,
// "start_time": "2018-05-12T13:57:28.440293621-07:00",
// "commit_time": "2018-05-12T13:57:27.440293621-07:00",
// "validators": {
// "validators": [
// {
// "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
// "pub_key": {
// "type": "AC26791624DE60",
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// },
// "voting_power": 10,
// "accum": 0
// }
// ],
// "proposer": {
// "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
// "pub_key": {
// "type": "AC26791624DE60",
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// },
// "voting_power": 10,
// "accum": 0
// }
// },
// "proposal": null,
// "proposal_block": null,
// "proposal_block_parts": null,
// "locked_round": 0,
// "locked_block": null,
// "locked_block_parts": null,
// "valid_round": 0,
// "valid_block": null,
// "valid_block_parts": null,
// "votes": [
// {
// "round": 0,
// "prevotes": "_",
// "precommits": "_"
// }
// ],
// "commit_round": -1,
// "last_commit": {
// "votes": [
// "Vote{0:B5B3D40BE539 7184/00/2(Precommit) 14F946FA7EF0 /702B1B1A602A.../ @ 2018-05-12T20:57:27.342Z}"
// ],
// "votes_bit_array": "x",
// "peer_maj_23s": {}
// },
// "last_validators": {
// "validators": [
// {
// "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
// "pub_key": {
// "type": "AC26791624DE60",
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// },
// "voting_power": 10,
// "accum": 0
// }
// ],
// "proposer": {
// "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244",
// "pub_key": {
// "type": "AC26791624DE60",
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// },
// "voting_power": 10,
// "accum": 0
// }
// }
// },
// "peers": [
// {
// "node_address": "30ad1854af22506383c3f0e57fb3c7f90984c5e8@172.16.63.221:46656",
// "peer_state": {
// "round_state": {
// "height": 7185,
// "round": 0,
// "step": 1,
// "start_time": "2018-05-12T13:57:27.438039872-07:00",
// "proposal": false,
// "proposal_block_parts_header": {
// "total": 0,
// "hash": ""
// },
// "proposal_block_parts": null,
// "proposal_pol_round": -1,
// "proposal_pol": "_",
// "prevotes": "_",
// "precommits": "_",
// "last_commit_round": 0,
// "last_commit": "x",
// "catchup_commit_round": -1,
// "catchup_commit": "_"
// },
// "stats": {
// "last_vote_height": 7184,
// "votes": 255,
// "last_block_part_height": 7184,
// "block_parts": 255
// }
// }
// }
// ]
// }
// }
// ```
func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
// Get Peer consensus states.
peers := p2pSwitch.Peers().List() peers := p2pSwitch.Peers().List()
peerRoundStates := make([]ctypes.PeerRoundStateInfo, len(peers)) peerStates := make([]ctypes.PeerStateInfo, len(peers))
for i, peer := range peers { for i, peer := range peers {
peerState := peer.Get(types.PeerStateKey).(*cm.PeerState) peerState := peer.Get(types.PeerStateKey).(*cm.PeerState)
peerRoundState, err := peerState.GetRoundStateJSON() peerStateJSON, err := peerState.ToJSON()
if err != nil { if err != nil {
return nil, err return nil, err
} }
peerRoundStates[i] = ctypes.PeerRoundStateInfo{ peerStates[i] = ctypes.PeerStateInfo{
// Peer basic info.
NodeAddress: p2p.IDAddressString(peer.ID(), peer.NodeInfo().ListenAddr), NodeAddress: p2p.IDAddressString(peer.ID(), peer.NodeInfo().ListenAddr),
PeerRoundState: peerRoundState, // Peer consensus state.
PeerState: peerStateJSON,
} }
} }
// Get self round state.
roundState, err := consensusState.GetRoundStateJSON() roundState, err := consensusState.GetRoundStateJSON()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &ctypes.ResultDumpConsensusState{roundState, peerRoundStates}, nil return &ctypes.ResultDumpConsensusState{roundState, peerStates}, nil
} }

View File

@ -131,12 +131,12 @@ type ResultValidators struct {
// Unstable // Unstable
type ResultDumpConsensusState struct { type ResultDumpConsensusState struct {
RoundState json.RawMessage `json:"round_state"` RoundState json.RawMessage `json:"round_state"`
Peers []PeerRoundStateInfo `json:"peers"` Peers []PeerStateInfo `json:"peers"`
} }
type PeerRoundStateInfo struct { type PeerStateInfo struct {
NodeAddress string `json:"node_address"` NodeAddress string `json:"node_address"`
PeerRoundState json.RawMessage `json:"peer_round_state"` PeerState json.RawMessage `json:"peer_state"`
} }
// CheckTx result // CheckTx result