From ed782e7508f430c2ece4fb2ebce82e2d4c2a6623 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Thu, 29 Mar 2018 13:39:15 +0200 Subject: [PATCH] include validator's voting power in /status Refs #581 --- CHANGELOG.md | 1 + rpc/core/status.go | 49 ++++++++++++++++++++++++++++++++++--- rpc/core/types/responses.go | 19 ++++++++------ types/validator_set.go | 3 +-- 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7c61489c..cf01bdbb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ BUG FIXES: IMPROVEMENTS: - [rpc] `/tx` and `/tx_search` responses now include the transaction hash +- [rpc] include validator power in `/status` ## 0.17.1 (March 27th, 2018) diff --git a/rpc/core/status.go b/rpc/core/status.go index a8771c8f7..b4543a61c 100644 --- a/rpc/core/status.go +++ b/rpc/core/status.go @@ -1,9 +1,11 @@ package core import ( + "bytes" "time" ctypes "github.com/tendermint/tendermint/rpc/core/types" + sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" cmn "github.com/tendermint/tmlibs/common" ) @@ -48,7 +50,10 @@ import ( // "remote_addr": "", // "network": "test-chain-qhVCa2", // "moniker": "vagrant-ubuntu-trusty-64", -// "pub_key": "844981FE99ABB19F7816F2D5E94E8A74276AB1153760A7799E925C75401856C6" +// "pub_key": "844981FE99ABB19F7816F2D5E94E8A74276AB1153760A7799E925C75401856C6", +// "validator_status": { +// "voting_power": 10 +// } // } // }, // "id": "", @@ -72,12 +77,50 @@ func Status() (*ctypes.ResultStatus, error) { latestBlockTime := time.Unix(0, latestBlockTimeNano) - return &ctypes.ResultStatus{ + result := &ctypes.ResultStatus{ NodeInfo: p2pSwitch.NodeInfo(), PubKey: pubKey, LatestBlockHash: latestBlockHash, LatestAppHash: latestAppHash, LatestBlockHeight: latestHeight, LatestBlockTime: latestBlockTime, - Syncing: consensusReactor.FastSync()}, nil + Syncing: consensusReactor.FastSync(), + } + + // add ValidatorStatus if node is a validator + if val := validatorAtHeight(latestHeight); val != nil { + result.ValidatorStatus = ctypes.ValidatorStatus{ + VotingPower: val.VotingPower, + } + } + + return result, nil +} + +func validatorAtHeight(h int64) *types.Validator { + lastBlockHeight, vals := consensusState.GetValidators() + + privValAddress := pubKey.Address() + + // if we're still at height h, search in the current validator set + if lastBlockHeight == h { + for _, val := range vals { + if bytes.Equal(val.Address, privValAddress) { + return val + } + } + } + + // if we've moved to the next height, retrieve the validator set from DB + if lastBlockHeight > h { + vals, err := sm.LoadValidators(stateDB, h) + if err != nil { + // should not happen + return nil + } + _, val := vals.GetByAddress(privValAddress) + return val + } + + return nil } diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index 5b49e1af6..48f8723d6 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -54,14 +54,19 @@ func NewResultCommit(header *types.Header, commit *types.Commit, } } +type ValidatorStatus struct { + VotingPower int64 `json:"voting_power"` +} + type ResultStatus struct { - NodeInfo p2p.NodeInfo `json:"node_info"` - PubKey crypto.PubKey `json:"pub_key"` - LatestBlockHash cmn.HexBytes `json:"latest_block_hash"` - LatestAppHash cmn.HexBytes `json:"latest_app_hash"` - LatestBlockHeight int64 `json:"latest_block_height"` - LatestBlockTime time.Time `json:"latest_block_time"` - Syncing bool `json:"syncing"` + NodeInfo p2p.NodeInfo `json:"node_info"` + PubKey crypto.PubKey `json:"pub_key"` + LatestBlockHash cmn.HexBytes `json:"latest_block_hash"` + LatestAppHash cmn.HexBytes `json:"latest_app_hash"` + LatestBlockHeight int64 `json:"latest_block_height"` + LatestBlockTime time.Time `json:"latest_block_time"` + Syncing bool `json:"syncing"` + ValidatorStatus ValidatorStatus `json:"validator_status,omitempty"` } func (s *ResultStatus) TxIndexEnabled() bool { diff --git a/types/validator_set.go b/types/validator_set.go index 887580d69..4b84f85d7 100644 --- a/types/validator_set.go +++ b/types/validator_set.go @@ -100,9 +100,8 @@ func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Valida }) if idx < len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) { return idx, valSet.Validators[idx].Copy() - } else { - return -1, nil } + return -1, nil } // GetByIndex returns the validator's address and validator itself by index.