Merge pull request #1391 from tendermint/581-include-validator-power
Include validator power in /status
This commit is contained in:
commit
c23d907f12
|
@ -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)
|
||||
|
||||
|
|
|
@ -720,11 +720,7 @@ func (cs *ConsensusState) needProofBlock(height int64) bool {
|
|||
func (cs *ConsensusState) proposalHeartbeat(height int64, round int) {
|
||||
counter := 0
|
||||
addr := cs.privValidator.GetAddress()
|
||||
valIndex, v := cs.Validators.GetByAddress(addr)
|
||||
if v == nil {
|
||||
// not a validator
|
||||
valIndex = -1
|
||||
}
|
||||
valIndex, _ := cs.Validators.GetByAddress(addr)
|
||||
chainID := cs.state.ChainID
|
||||
for {
|
||||
rs := cs.GetRoundState()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -83,26 +83,30 @@ func (valSet *ValidatorSet) Copy() *ValidatorSet {
|
|||
}
|
||||
}
|
||||
|
||||
// HasAddress returns true if address given is in the validator set, false -
|
||||
// otherwise.
|
||||
func (valSet *ValidatorSet) HasAddress(address []byte) bool {
|
||||
idx := sort.Search(len(valSet.Validators), func(i int) bool {
|
||||
return bytes.Compare(address, valSet.Validators[i].Address) <= 0
|
||||
})
|
||||
return idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address)
|
||||
return idx < len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address)
|
||||
}
|
||||
|
||||
// GetByAddress returns an index of the validator with address and validator
|
||||
// itself if found. Otherwise, -1 and nil are returned.
|
||||
func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) {
|
||||
idx := sort.Search(len(valSet.Validators), func(i int) bool {
|
||||
return bytes.Compare(address, valSet.Validators[i].Address) <= 0
|
||||
})
|
||||
if idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) {
|
||||
if idx < len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) {
|
||||
return idx, valSet.Validators[idx].Copy()
|
||||
}
|
||||
return 0, nil
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// GetByIndex returns the validator by index.
|
||||
// It returns nil values if index < 0 or
|
||||
// index >= len(ValidatorSet.Validators)
|
||||
// GetByIndex returns the validator's address and validator itself by index.
|
||||
// It returns nil values if index is less than 0 or greater or equal to
|
||||
// len(ValidatorSet.Validators).
|
||||
func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) {
|
||||
if index < 0 || index >= len(valSet.Validators) {
|
||||
return nil, nil
|
||||
|
@ -111,10 +115,12 @@ func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validato
|
|||
return val.Address, val.Copy()
|
||||
}
|
||||
|
||||
// Size returns the length of the validator set.
|
||||
func (valSet *ValidatorSet) Size() int {
|
||||
return len(valSet.Validators)
|
||||
}
|
||||
|
||||
// TotalVotingPower returns the sum of the voting powers of all validators.
|
||||
func (valSet *ValidatorSet) TotalVotingPower() int64 {
|
||||
if valSet.totalVotingPower == 0 {
|
||||
for _, val := range valSet.Validators {
|
||||
|
@ -125,6 +131,8 @@ func (valSet *ValidatorSet) TotalVotingPower() int64 {
|
|||
return valSet.totalVotingPower
|
||||
}
|
||||
|
||||
// GetProposer returns the current proposer. If the validator set is empty, nil
|
||||
// is returned.
|
||||
func (valSet *ValidatorSet) GetProposer() (proposer *Validator) {
|
||||
if len(valSet.Validators) == 0 {
|
||||
return nil
|
||||
|
@ -145,6 +153,8 @@ func (valSet *ValidatorSet) findProposer() *Validator {
|
|||
return proposer
|
||||
}
|
||||
|
||||
// Hash returns the Merkle root hash build using validators (as leaves) in the
|
||||
// set.
|
||||
func (valSet *ValidatorSet) Hash() []byte {
|
||||
if len(valSet.Validators) == 0 {
|
||||
return nil
|
||||
|
@ -156,12 +166,14 @@ func (valSet *ValidatorSet) Hash() []byte {
|
|||
return merkle.SimpleHashFromHashers(hashers)
|
||||
}
|
||||
|
||||
// Add adds val to the validator set and returns true. It returns false if val
|
||||
// is already in the set.
|
||||
func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
|
||||
val = val.Copy()
|
||||
idx := sort.Search(len(valSet.Validators), func(i int) bool {
|
||||
return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0
|
||||
})
|
||||
if idx == len(valSet.Validators) {
|
||||
if idx >= len(valSet.Validators) {
|
||||
valSet.Validators = append(valSet.Validators, val)
|
||||
// Invalidate cache
|
||||
valSet.Proposer = nil
|
||||
|
@ -182,6 +194,8 @@ func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// Update updates val and returns true. It returns false if val is not present
|
||||
// in the set.
|
||||
func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
|
||||
index, sameVal := valSet.GetByAddress(val.Address)
|
||||
if sameVal == nil {
|
||||
|
@ -194,11 +208,13 @@ func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
|
|||
return true
|
||||
}
|
||||
|
||||
// Remove deletes the validator with address. It returns the validator removed
|
||||
// and true. If returns nil and false if validator is not present in the set.
|
||||
func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
|
||||
idx := sort.Search(len(valSet.Validators), func(i int) bool {
|
||||
return bytes.Compare(address, valSet.Validators[i].Address) <= 0
|
||||
})
|
||||
if idx == len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) {
|
||||
if idx >= len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) {
|
||||
return nil, false
|
||||
}
|
||||
removedVal := valSet.Validators[idx]
|
||||
|
@ -213,6 +229,7 @@ func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool
|
|||
return removedVal, true
|
||||
}
|
||||
|
||||
// Iterate will run the given function over the set.
|
||||
func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
|
||||
for i, val := range valSet.Validators {
|
||||
stop := fn(i, val.Copy())
|
||||
|
|
Loading…
Reference in New Issue