From 8d465a7d8c24afd67f95abbbb6952d77e0e01f35 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Tue, 20 Feb 2024 05:40:18 +0100 Subject: [PATCH] vmon: Missed block metric (#5913) Validator monitoring gained 2 new metrics for tracking when blocks are included or not on the head chain. Similar to attestations, if the block is produced in epoch N, reporting will use the state when switching to epoch N+2 to do the reporting (so as to reasonably stabilise the block inclusion in the face of reorgs). --- .../consensus_object_pools/blockchain_dag.nim | 9 +- beacon_chain/validators/validator_monitor.nim | 30 ++- grafana/beacon_nodes_Grafana_dashboard.json | 171 +++++++++++++++--- 3 files changed, 178 insertions(+), 32 deletions(-) diff --git a/beacon_chain/consensus_object_pools/blockchain_dag.nim b/beacon_chain/consensus_object_pools/blockchain_dag.nim index 9c437edd7..b3d044b9a 100644 --- a/beacon_chain/consensus_object_pools/blockchain_dag.nim +++ b/beacon_chain/consensus_object_pools/blockchain_dag.nim @@ -956,9 +956,14 @@ proc advanceSlots*( # which is an acceptable tradeoff for monitoring. withState(state): let postEpoch = forkyState.data.slot.epoch - if preEpoch != postEpoch: + if preEpoch != postEpoch and postEpoch >= 2: + var proposers: array[SLOTS_PER_EPOCH, Opt[ValidatorIndex]] + let epochRef = dag.findEpochRef(stateBid, postEpoch - 2) + if epochRef.isSome(): + proposers = epochRef[][].beacon_proposers + dag.validatorMonitor[].registerEpochInfo( - postEpoch, info, forkyState.data) + forkyState.data, proposers, info) proc applyBlock( dag: ChainDAGRef, state: var ForkedHashedBeaconState, bid: BlockId, diff --git a/beacon_chain/validators/validator_monitor.nim b/beacon_chain/validators/validator_monitor.nim index 059b10f9f..58672a197 100644 --- a/beacon_chain/validators/validator_monitor.nim +++ b/beacon_chain/validators/validator_monitor.nim @@ -149,6 +149,11 @@ declareCounter validator_monitor_proposer_slashing, declareCounter validator_monitor_attester_slashing, "Number of attester slashings seen", labels = ["src", "validator"] +declareCounter validator_monitor_block_hit, + "Number of times a block proposed by the validator was included an epoch later", labels = ["validator"] +declareCounter validator_monitor_block_miss, + "Number of times the validator was expected to propose a block but no block was included", labels = ["validator"] + const total = "total" # what we use for label when using "totals" mode @@ -405,12 +410,15 @@ func is_active_unslashed_in_previous_epoch(status: ParticipationInfo): bool = ParticipationFlag.eligible in status.flags proc registerEpochInfo*( - self: var ValidatorMonitor, epoch: Epoch, info: ForkedEpochInfo, - state: ForkyBeaconState) = + self: var ValidatorMonitor, state: ForkyBeaconState, + proposers: array[SLOTS_PER_EPOCH, Opt[ValidatorIndex]], + info: ForkedEpochInfo) = # Register rewards, as computed during the epoch transition that lands in # `epoch` - the rewards will be from attestations that were created at # `epoch - 2`. + let epoch = state.slot.epoch + if epoch < 2 or self.monitors.len == 0: return @@ -442,6 +450,24 @@ proc registerEpochInfo*( # attestations. continue + # Check that block proposals are sticky an epoch later + for i in 0..