diff --git a/consensus/metrics.go b/consensus/metrics.go index 06df7e35..c4cd0334 100644 --- a/consensus/metrics.go +++ b/consensus/metrics.go @@ -7,11 +7,20 @@ import "github.com/go-kit/kit/metrics/discard" type Metrics struct { // height of the chain Height metrics.Counter + // number of validators who signed + Validators metrics.Gauge + // number of validators who did not sign + MissingValidators metrics.Gauge + // number of validators who tried to double sign + ByzantineValidators metrics.Gauge } // NopMetrics returns no-op Metrics. func NopMetrics() *Metrics { return &Metrics{ - Height: discard.NewCounter(), + Height: discard.NewCounter(), + Validators: discard.NewGauge(), + MissingValidators: discard.NewGauge(), + ByzantineValidators: discard.NewGauge(), } } diff --git a/consensus/state.go b/consensus/state.go index 3b6c029f..de424718 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -1281,6 +1281,8 @@ func (cs *ConsensusState) finalizeCommit(height int64) { fail.Fail() // XXX + cs.recordValidatorMetrics(height, block) + // NewHeightStep! cs.updateToState(stateCopy) @@ -1296,6 +1298,26 @@ func (cs *ConsensusState) finalizeCommit(height int64) { // * cs.StartTime is set to when we will start round0. } +func (cs *ConsensusState) recordValidatorMetrics(height int64, block *types.Block) { + heightStr := fmt.Sprintf("%d", height) + + cs.metrics.Validators.With("height", heightStr).Set(float64(cs.Validators.Size())) + + missingValidators := 0 + for i := range cs.Validators.Validators { + var vote *types.Vote + if i < len(block.LastCommit.Precommits) { + vote = block.LastCommit.Precommits[i] + } + if vote == nil { + missingValidators++ + } + } + cs.metrics.MissingValidators.With("height", heightStr).Set(float64(missingValidators)) + + cs.metrics.ByzantineValidators.With("height", heightStr).Set(float64(len(block.Evidence.Evidence))) +} + //----------------------------------------------------------------------------- func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { diff --git a/node/node.go b/node/node.go index 538055a8..0ca6f777 100644 --- a/node/node.go +++ b/node/node.go @@ -246,11 +246,27 @@ func NewNode(config *cfg.Config, // Make ConsensusReactor // TODO: extract to provider metrics := &cs.Metrics{ - Height: prometheus.NewCounter(stdprometheus.NewCounterVec(stdprometheus.CounterOpts{ - Name: "height", - }, []string{})), + Height: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + Subsystem: "consensus", + Name: "height", + Help: "Height of the chain.", + }, []string{}), + Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Subsystem: "consensus", + Name: "validators", + Help: "Number of validators who signed, partitioned by height.", + }, []string{"height"}), + MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Subsystem: "consensus", + Name: "missing_validators", + Help: "Number of validators who did not sign, partitioned by height.", + }, []string{"height"}), + ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Subsystem: "consensus", + Name: "byzantine_validators", + Help: "Number of validators who tried to double sign, partitioned by height.", + }, []string{"height"}), } - stdprometheus.MustRegister(metrics.Height) consensusState := cs.NewConsensusState(config.Consensus, state.Copy(), blockExec, blockStore, mempool, evidencePool, metrics) consensusState.SetLogger(consensusLogger)