Browse Source

cs: set missing_validators(_power) metrics to 0 for 1st block (#4194)

also

    - do not send any LastCommitInfo.Votes for 1st block.
    - use cs.LastValidators (not cs.Validators) in recordMetrics when counting missing validators

note:

remember that the first LastCommit is intentionally empty, so it makes
sense for LastCommitInfo.Votes to also be empty. Because we can't really
tell if validator signed or not. Similar for ^ metrics, we can't say if
particular validator was missing or not.

Closes #4192
pull/4268/head
Anton Kaliaev 5 years ago
committed by GitHub
parent
commit
fff7f450be
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 36 deletions
  1. +26
    -9
      consensus/state.go
  2. +21
    -27
      state/execution.go

+ 26
- 9
consensus/state.go View File

@ -1464,20 +1464,37 @@ func (cs *State) finalizeCommit(height int64) {
func (cs *State) recordMetrics(height int64, block *types.Block) {
cs.metrics.Validators.Set(float64(cs.Validators.Size()))
cs.metrics.ValidatorsPower.Set(float64(cs.Validators.TotalVotingPower()))
missingValidators := 0
missingValidatorsPower := int64(0)
for i, val := range cs.Validators.Validators {
if i >= len(block.LastCommit.Signatures) {
break
var (
missingValidators int
missingValidatorsPower int64
)
// height=0 -> MissingValidators and MissingValidatorsPower are both 0.
// Remember that the first LastCommit is intentionally empty, so it's not
// fair to increment missing validators number.
if height > 1 {
// Sanity check that commit size matches validator set size - only applies
// after first block.
var (
commitSize = block.LastCommit.Size()
valSetLen = len(cs.LastValidators.Validators)
)
if commitSize != valSetLen {
panic(fmt.Sprintf("commit size (%d) doesn't match valset length (%d) at height %d\n\n%v\n\n%v",
commitSize, valSetLen, block.Height, block.LastCommit.Signatures, cs.LastValidators.Validators))
}
commitSig := block.LastCommit.Signatures[i]
if commitSig.Absent() {
missingValidators++
missingValidatorsPower += val.VotingPower
for i, val := range cs.LastValidators.Validators {
commitSig := block.LastCommit.Signatures[i]
if commitSig.Absent() {
missingValidators++
missingValidatorsPower += val.VotingPower
}
}
}
cs.metrics.MissingValidators.Set(float64(missingValidators))
cs.metrics.MissingValidatorsPower.Set(float64(missingValidatorsPower))
cs.metrics.ByzantineValidators.Set(float64(len(block.Evidence.Evidence)))
byzantineValidatorsPower := int64(0)
for _, ev := range block.Evidence.Evidence {


+ 21
- 27
state/execution.go View File

@ -310,57 +310,51 @@ func execBlockOnProxyApp(
func getBeginBlockValidatorInfo(block *types.Block, stateDB dbm.DB) (abci.LastCommitInfo, []abci.Evidence) {
voteInfos := make([]abci.VoteInfo, block.LastCommit.Size())
byzVals := make([]abci.Evidence, len(block.Evidence.Evidence))
var lastValSet *types.ValidatorSet
var err error
// block.Height=1 -> LastCommitInfo.Votes are empty.
// Remember that the first LastCommit is intentionally empty, so it makes
// sense for LastCommitInfo.Votes to also be empty.
if block.Height > 1 {
lastValSet, err = LoadValidators(stateDB, block.Height-1)
lastValSet, err := LoadValidators(stateDB, block.Height-1)
if err != nil {
panic(err) // shouldn't happen
panic(err)
}
// Sanity check that commit size matches validator set size -
// only applies after first block
commitSize := block.LastCommit.Size()
valSetLen := len(lastValSet.Validators)
// Sanity check that commit size matches validator set size - only applies
// after first block.
var (
commitSize = block.LastCommit.Size()
valSetLen = len(lastValSet.Validators)
)
if commitSize != valSetLen {
// sanity check
panic(fmt.Sprintf("commit size (%d) doesn't match valset length (%d) at height %d\n\n%v\n\n%v",
commitSize, valSetLen, block.Height, block.LastCommit.Signatures, lastValSet.Validators))
}
} else {
lastValSet = types.NewValidatorSet(nil)
}
for i, val := range lastValSet.Validators {
if i >= len(block.LastCommit.Signatures) {
break
}
commitSig := block.LastCommit.Signatures[i]
voteInfo := abci.VoteInfo{
Validator: types.TM2PB.Validator(val),
SignedLastBlock: !commitSig.Absent(),
for i, val := range lastValSet.Validators {
commitSig := block.LastCommit.Signatures[i]
voteInfos[i] = abci.VoteInfo{
Validator: types.TM2PB.Validator(val),
SignedLastBlock: !commitSig.Absent(),
}
}
voteInfos[i] = voteInfo
}
byzVals := make([]abci.Evidence, len(block.Evidence.Evidence))
for i, ev := range block.Evidence.Evidence {
// We need the validator set. We already did this in validateBlock.
// TODO: Should we instead cache the valset in the evidence itself and add
// `SetValidatorSet()` and `ToABCI` methods ?
valset, err := LoadValidators(stateDB, ev.Height())
if err != nil {
panic(err) // shouldn't happen
panic(err)
}
byzVals[i] = types.TM2PB.Evidence(ev, valset, block.Time)
}
commitInfo := abci.LastCommitInfo{
return abci.LastCommitInfo{
Round: int32(block.LastCommit.Round),
Votes: voteInfos,
}
return commitInfo, byzVals
}, byzVals
}
func validateValidatorUpdates(abciUpdates []abci.ValidatorUpdate,


Loading…
Cancel
Save