Skip to content

Commit

Permalink
feat: count proposed blocks by validators (#72)
Browse files Browse the repository at this point in the history
Close #6
  • Loading branch information
MattKetmo authored Jun 6, 2024
1 parent d6945ee commit 1ec20cc
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 13 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ Metrics (without prefix) | Description
`node_block_height` | Latest fetched block height for each node
`node_synced` | Set to 1 is the node is synced (ie. not catching-up)
`proposal_end_time` | Timestamp of the voting end time of a proposal
`proposed_blocks` | Number of proposed blocks per validator (for a bonded validator)
`rank` | Rank of the validator
`seat_price` | Min seat price to be in the active set (ie. bonded tokens of the latest validator)
`skipped_blocks` | Number of blocks skipped (ie. not tracked) since start
Expand Down
10 changes: 10 additions & 0 deletions pkg/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Metrics struct {

// Validator metrics
Rank *prometheus.GaugeVec
ProposedBlocks *prometheus.CounterVec
ValidatedBlocks *prometheus.CounterVec
MissedBlocks *prometheus.CounterVec
SoloMissedBlocks *prometheus.CounterVec
Expand Down Expand Up @@ -69,6 +70,14 @@ func New(namespace string) *Metrics {
},
[]string{"chain_id", "address", "name"},
),
ProposedBlocks: prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Name: "proposed_blocks",
Help: "Number of proposed blocks per validator (for a bonded validator)",
},
[]string{"chain_id", "address", "name"},
),
ValidatedBlocks: prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Expand Down Expand Up @@ -202,6 +211,7 @@ func (m *Metrics) Register() {
m.Registry.MustRegister(m.ActiveSet)
m.Registry.MustRegister(m.SeatPrice)
m.Registry.MustRegister(m.Rank)
m.Registry.MustRegister(m.ProposedBlocks)
m.Registry.MustRegister(m.ValidatedBlocks)
m.Registry.MustRegister(m.MissedBlocks)
m.Registry.MustRegister(m.SoloMissedBlocks)
Expand Down
24 changes: 15 additions & 9 deletions pkg/watcher/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import (
)

type BlockWatcher struct {
trackedValidators []TrackedValidator
metrics *metrics.Metrics
writer io.Writer
blockChan chan *BlockInfo
validatorSet atomic.Value // []*types.Validator
latestBlockHeight int64
trackedValidators []TrackedValidator
metrics *metrics.Metrics
writer io.Writer
blockChan chan *BlockInfo
validatorSet atomic.Value // []*types.Validator
latestBlockHeight int64
latestBlockProposer string
}

func NewBlockWatcher(validators []TrackedValidator, metrics *metrics.Metrics, writer io.Writer) *BlockWatcher {
Expand All @@ -32,7 +33,6 @@ func NewBlockWatcher(validators []TrackedValidator, metrics *metrics.Metrics, wr
metrics: metrics,
writer: writer,
blockChan: make(chan *BlockInfo),
latestBlockHeight: 0,
}
}

Expand Down Expand Up @@ -181,7 +181,6 @@ func (w *BlockWatcher) handleBlockInfo(block *BlockInfo) {
w.metrics.SkippedBlocks.WithLabelValues(chainId).Add(float64(blockDiff))
}

w.latestBlockHeight = block.Height
w.metrics.BlockHeight.WithLabelValues(chainId).Set(float64(block.Height))
w.metrics.ActiveSet.WithLabelValues(chainId).Set(float64(block.TotalValidators))
w.metrics.TrackedBlocks.WithLabelValues(chainId).Inc()
Expand All @@ -191,7 +190,11 @@ func (w *BlockWatcher) handleBlockInfo(block *BlockInfo) {
validatorStatus := []string{}
for _, res := range block.ValidatorStatus {
icon := "⚪️"
if res.Signed {
if w.latestBlockProposer == res.Address {
icon = "👑"
w.metrics.ProposedBlocks.WithLabelValues(block.ChainID, res.Address, res.Label).Inc()
w.metrics.ValidatedBlocks.WithLabelValues(block.ChainID, res.Address, res.Label).Inc()
} else if res.Signed {
icon = "✅"
w.metrics.ValidatedBlocks.WithLabelValues(block.ChainID, res.Address, res.Label).Inc()
} else if res.Bonded {
Expand All @@ -212,6 +215,9 @@ func (w *BlockWatcher) handleBlockInfo(block *BlockInfo) {
color.CyanString(fmt.Sprintf("%3d/%d validators", block.SignedValidators, block.TotalValidators)),
strings.Join(validatorStatus, " "),
)

w.latestBlockHeight = block.Height
w.latestBlockProposer = block.ProposerAddress
}

func (w *BlockWatcher) computeValidatorStatus(block *types.Block) []ValidatorStatus {
Expand Down
27 changes: 23 additions & 4 deletions pkg/watcher/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ func TestBlockWatcher(t *testing.T) {
Transactions: 7,
TotalValidators: 2,
SignedValidators: 2,
ProposerAddress: kilnAddress,
ValidatorStatus: []ValidatorStatus{
{
Address: kilnAddress,
Label: kilnName,
Bonded: true,
Signed: true,
Rank: 2,
},
},
},
{
ChainID: chainID,
Height: 44,
Transactions: 7,
TotalValidators: 2,
SignedValidators: 2,
ValidatorStatus: []ValidatorStatus{
{
Address: kilnAddress,
Expand All @@ -106,20 +123,22 @@ func TestBlockWatcher(t *testing.T) {
`#40 0/1 validators ❌ Kiln`,
`#41 1/2 validators ✅ Kiln`,
`#42 2/2 validators ✅ Kiln`,
`#43 2/2 validators 👑 Kiln`,
}, "\n")+"\n",
blockWatcher.writer.(*bytes.Buffer).String(),
)

assert.Equal(t, float64(43), testutil.ToFloat64(blockWatcher.metrics.BlockHeight.WithLabelValues(chainID)))
assert.Equal(t, float64(22), testutil.ToFloat64(blockWatcher.metrics.Transactions.WithLabelValues(chainID)))
assert.Equal(t, float64(44), testutil.ToFloat64(blockWatcher.metrics.BlockHeight.WithLabelValues(chainID)))
assert.Equal(t, float64(29), testutil.ToFloat64(blockWatcher.metrics.Transactions.WithLabelValues(chainID)))
assert.Equal(t, float64(2), testutil.ToFloat64(blockWatcher.metrics.ActiveSet.WithLabelValues(chainID)))
assert.Equal(t, float64(4), testutil.ToFloat64(blockWatcher.metrics.TrackedBlocks.WithLabelValues(chainID)))
assert.Equal(t, float64(5), testutil.ToFloat64(blockWatcher.metrics.TrackedBlocks.WithLabelValues(chainID)))
assert.Equal(t, float64(5), testutil.ToFloat64(blockWatcher.metrics.SkippedBlocks.WithLabelValues(chainID)))

assert.Equal(t, 1, testutil.CollectAndCount(blockWatcher.metrics.ValidatedBlocks))
assert.Equal(t, 1, testutil.CollectAndCount(blockWatcher.metrics.MissedBlocks))
assert.Equal(t, 1, testutil.CollectAndCount(blockWatcher.metrics.SoloMissedBlocks))
assert.Equal(t, float64(2), testutil.ToFloat64(blockWatcher.metrics.ValidatedBlocks.WithLabelValues(chainID, kilnAddress, kilnName)))
assert.Equal(t, float64(1), testutil.ToFloat64(blockWatcher.metrics.ProposedBlocks.WithLabelValues(chainID, kilnAddress, kilnName)))
assert.Equal(t, float64(3), testutil.ToFloat64(blockWatcher.metrics.ValidatedBlocks.WithLabelValues(chainID, kilnAddress, kilnName)))
assert.Equal(t, float64(1), testutil.ToFloat64(blockWatcher.metrics.MissedBlocks.WithLabelValues(chainID, kilnAddress, kilnName)))
assert.Equal(t, float64(0), testutil.ToFloat64(blockWatcher.metrics.SoloMissedBlocks.WithLabelValues(chainID, kilnAddress, kilnName)))
})
Expand Down
2 changes: 2 additions & 0 deletions pkg/watcher/block_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type BlockInfo struct {
Transactions int
TotalValidators int
SignedValidators int
ProposerAddress string
ValidatorStatus []ValidatorStatus
}

Expand All @@ -30,6 +31,7 @@ func NewBlockInfo(block *types.Block, validatorStatus []ValidatorStatus) *BlockI
TotalValidators: len(block.LastCommit.Signatures),
SignedValidators: signedValidators,
ValidatorStatus: validatorStatus,
ProposerAddress: block.Header.ProposerAddress.String(),
}
}

Expand Down

0 comments on commit 1ec20cc

Please sign in to comment.