mirror of
https://github.com/tendermint/tendermint.git
synced 2026-05-23 07:31:29 +00:00
consensus: calculate prevote message delay metric
This commit is contained in:
@@ -64,6 +64,21 @@ type Metrics struct {
|
||||
|
||||
// Histogram of time taken per step annotated with reason that the step proceeded.
|
||||
StepTime metrics.Histogram
|
||||
|
||||
// QuroumPrevoteMessageDelay is the difference in seconds between the proposal
|
||||
// timestamp and the timestamp of the prevote that achieved a quorum in the prevote step.
|
||||
// The prevote that achieved a quorum in the prevote step is determined by first
|
||||
// sorting all of the collected prevotes in a round in ascending order of
|
||||
// timestamp and iterating over this list from lowest timestamp to highest.
|
||||
// During iteration, the total represented by iterated prevotes is kept track of.
|
||||
// The prevote that achieved a quorum is the prevote that brings the summed
|
||||
// voting power in this iteration to above 2/3 of the power on the network.
|
||||
QuorumPrevoteMessageDelay metrics.Gauge
|
||||
|
||||
// FullPrevoteMessageDelay is the difference in seconds between the proposal
|
||||
// timestamp and the timestamp of the prevote that achieved 100% of the voting
|
||||
// power on the network in the prevote step when prevotes are ordered by timestamp.
|
||||
FullPrevoteMessageDelay metrics.Gauge
|
||||
}
|
||||
|
||||
// PrometheusMetrics returns Metrics build using Prometheus client library.
|
||||
@@ -196,6 +211,20 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
|
||||
Name: "step_time",
|
||||
Help: "Time spent per step.",
|
||||
}, append(labels, "step", "reason")).With(labelsAndValues...),
|
||||
QuorumPrevoteMessageDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: MetricsSubsystem,
|
||||
Name: "quorum_prevote_message_delay",
|
||||
Help: "Difference in seconds between the proposal timestamp and the timestamp " +
|
||||
"of the prevote that achieved a quorum in the prevote step.",
|
||||
}, labels).With(labelsAndValues...),
|
||||
FullPrevoteMessageDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: MetricsSubsystem,
|
||||
Name: "complete_prevote_message_delay",
|
||||
Help: "Difference in seconds between the proposal timestamp and the timestamp " +
|
||||
"of the prevote that achieved 100% of the voting power in the prevote step.",
|
||||
}, labels).With(labelsAndValues...),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -1680,6 +1681,8 @@ func (cs *State) finalizeCommit(ctx context.Context, height int64) {
|
||||
return
|
||||
}
|
||||
|
||||
cs.calculatePrevoteMessageDelayMetrics()
|
||||
|
||||
blockID, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority()
|
||||
block, blockParts := cs.ProposalBlock, cs.ProposalBlockParts
|
||||
|
||||
@@ -2414,6 +2417,26 @@ func (cs *State) checkDoubleSigningRisk(height int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cs *State) calculatePrevoteMessageDelayMetrics() {
|
||||
ps := cs.Votes.Prevotes(cs.Round)
|
||||
pl := ps.List()
|
||||
sort.Slice(pl, func(i, j int) bool {
|
||||
return pl[i].Timestamp.Before(pl[j].Timestamp)
|
||||
})
|
||||
var votingPowerSeen int64
|
||||
for _, v := range pl {
|
||||
_, val := cs.Validators.GetByAddress(v.ValidatorAddress)
|
||||
votingPowerSeen += val.VotingPower
|
||||
if votingPowerSeen >= cs.Validators.TotalVotingPower()*(2/3+1) {
|
||||
cs.metrics.QuorumPrevoteMessageDelay.Set(v.Timestamp.Sub(cs.Proposal.Timestamp).Seconds())
|
||||
break
|
||||
}
|
||||
}
|
||||
if ps.HasAll() {
|
||||
cs.metrics.FullPrevoteMessageDelay.Set(pl[len(pl)-1].Timestamp.Sub(cs.Proposal.Timestamp).Seconds())
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
func CompareHRS(h1 int64, r1 int32, s1 cstypes.RoundStepType, h2 int64, r2 int32, s2 cstypes.RoundStepType) int {
|
||||
|
||||
@@ -378,6 +378,15 @@ func (voteSet *VoteSet) GetByIndex(valIndex int32) *Vote {
|
||||
return voteSet.votes[valIndex]
|
||||
}
|
||||
|
||||
// List returns a copy of the list of votes stored by the VoteSet.
|
||||
func (voteSet *VoteSet) List() []Vote {
|
||||
votes := make([]Vote, len(voteSet.votes))
|
||||
for i := range voteSet.votes {
|
||||
votes[i] = *voteSet.votes[i]
|
||||
}
|
||||
return votes
|
||||
}
|
||||
|
||||
func (voteSet *VoteSet) GetByAddress(address []byte) *Vote {
|
||||
if voteSet == nil {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user