Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve height monitoring #2347

Merged
merged 2 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions snow/consensus/metrics/height.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,50 @@

package metrics

import "github.com/prometheus/client_golang/prometheus"
import (
"github.com/prometheus/client_golang/prometheus"

"github.com/ava-labs/avalanchego/utils"
"github.com/ava-labs/avalanchego/utils/math"
)

var _ Height = (*height)(nil)

// Height reports the last accepted height
type Height interface {
Verified(height uint64)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I called this Verified rather than Issued because we're moving verification into the consensus code. We'll probably add Issued as another tracked height later

Accepted(height uint64)
}

type height struct {
// lastAcceptedHeight keeps track of the last accepted height
currentMaxVerifiedHeight uint64
maxVerifiedHeight prometheus.Gauge

lastAcceptedHeight prometheus.Gauge
}

func NewHeight(namespace string, reg prometheus.Registerer) (Height, error) {
h := &height{
maxVerifiedHeight: prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: namespace,
Name: "max_verified_height",
Help: "Highest verified height",
}),
lastAcceptedHeight: prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: namespace,
Name: "last_accepted_height",
Help: "Last height accepted",
}),
}
return h, reg.Register(h.lastAcceptedHeight)
err := utils.Err(
reg.Register(h.lastAcceptedHeight),
reg.Register(h.maxVerifiedHeight),
)
return h, err
}

func (h *height) Verified(height uint64) {
h.currentMaxVerifiedHeight = math.Max(h.currentMaxVerifiedHeight, height)
h.maxVerifiedHeight.Set(float64(h.currentMaxVerifiedHeight))
}

func (h *height) Accepted(height uint64) {
Expand Down
27 changes: 21 additions & 6 deletions snow/consensus/snowman/topological.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func (ts *Topological) Initialize(
ts.tail = rootID

// Initially set the metrics for the last accepted block.
ts.Height.Verified(ts.height)
ts.Height.Accepted(ts.height)
ts.Timestamp.Accepted(rootTime)

Expand All @@ -165,8 +166,10 @@ func (ts *Topological) NumProcessing() int {

func (ts *Topological) Add(ctx context.Context, blk Block) error {
blkID := blk.ID()
height := blk.Height()
ts.ctx.Log.Verbo("adding block",
zap.Stringer("blkID", blkID),
zap.Uint64("height", height),
)

// Make sure a block is not inserted twice. This enforces the invariant that
Expand All @@ -178,13 +181,15 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error {
return errDuplicateAdd
}

ts.Height.Verified(height)
ts.Latency.Issued(blkID, ts.pollNumber)

parentID := blk.Parent()
parentNode, ok := ts.blocks[parentID]
if !ok {
ts.ctx.Log.Verbo("block ancestor is missing, being rejected",
zap.Stringer("blkID", blkID),
zap.Uint64("height", height),
zap.Stringer("parentID", parentID),
)

Expand All @@ -209,11 +214,12 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error {
if ts.tail == parentID {
ts.tail = blkID
ts.preferredIDs.Add(blkID)
ts.preferredHeights[blk.Height()] = blkID
ts.preferredHeights[height] = blkID
}

ts.ctx.Log.Verbo("added block",
zap.Stringer("blkID", blkID),
zap.Uint64("height", height),
zap.Stringer("parentID", parentID),
)
return nil
Expand Down Expand Up @@ -634,23 +640,25 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock
return err
}

height := child.Height()
ts.ctx.Log.Trace("accepting block",
zap.Stringer("blkID", pref),
zap.Uint64("height", height),
)
if err := child.Accept(ctx); err != nil {
return err
}

// Because this is the newest accepted block, this is the new head.
ts.head = pref
ts.height = child.Height()
ts.height = height
// Remove the decided block from the set of processing IDs, as its status
// now implies its preferredness.
ts.preferredIDs.Remove(pref)
delete(ts.preferredHeights, ts.height)
delete(ts.preferredHeights, height)

ts.Latency.Accepted(pref, ts.pollNumber, len(bytes))
ts.Height.Accepted(ts.height)
ts.Height.Accepted(height)
ts.Timestamp.Accepted(child.Timestamp())

// Because ts.blocks contains the last accepted block, we don't delete the
Expand All @@ -665,8 +673,9 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock

ts.ctx.Log.Trace("rejecting block",
zap.String("reason", "conflict with accepted block"),
zap.Stringer("rejectedID", childID),
zap.Stringer("conflictedID", pref),
zap.Stringer("blkID", childID),
zap.Uint64("height", child.Height()),
zap.Stringer("conflictID", pref),
)
if err := child.Reject(ctx); err != nil {
return err
Expand Down Expand Up @@ -696,6 +705,12 @@ func (ts *Topological) rejectTransitively(ctx context.Context, rejected []ids.ID
delete(ts.blocks, rejectedID)

for childID, child := range rejectedNode.children {
ts.ctx.Log.Trace("rejecting block",
zap.String("reason", "rejected ancestor"),
zap.Stringer("blkID", childID),
zap.Uint64("height", child.Height()),
zap.Stringer("parentID", rejectedID),
)
if err := child.Reject(ctx); err != nil {
return err
}
Expand Down
Loading