fix broken metrics during replay (#2090)

* move metrics out of state transition
* add validator count metric
* remove expensive beacon_current_validators, beacon_previous_validators
metrics (they should be reimplemented with cache), add cheap
beacon_active_validators to approximate
* remove unused validator count metrics
* tidy imports/defects
This commit is contained in:
Jacek Sieka 2020-11-27 23:16:13 +01:00 committed by GitHub
parent d98f3ab948
commit e7f2735271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 184 additions and 134 deletions

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[deques, strformat, tables, hashes],
@ -206,22 +208,31 @@ template validator_keys*(e: EpochRef): untyped = e.validator_key_store[1][]
template head*(v: ChainDagRef): BlockRef = v.headState.blck
func shortLog*(v: BlockSlot): string =
if v.blck.slot == v.slot:
&"{v.blck.root.data.toOpenArray(0, 3).toHex()}:{v.blck.slot}"
else: # There was a gap - log it
&"{v.blck.root.data.toOpenArray(0, 3).toHex()}:{v.blck.slot}@{v.slot}"
try:
if v.blck.slot == v.slot:
&"{v.blck.root.data.toOpenArray(0, 3).toHex()}:{v.blck.slot}"
else: # There was a gap - log it
&"{v.blck.root.data.toOpenArray(0, 3).toHex()}:{v.blck.slot}@{v.slot}"
except ValueError as err:
err.msg # Shouldn't happen - but also shouldn't crash!
func shortLog*(v: BlockRef): string =
if v == nil:
"BlockRef(nil)"
else:
&"{v.root.data.toOpenArray(0, 3).toHex()}:{v.slot}"
try:
if v == nil:
"BlockRef(nil)"
else:
&"{v.root.data.toOpenArray(0, 3).toHex()}:{v.slot}"
except ValueError as err:
err.msg # Shouldn't happen - but also shouldn't crash!
func shortLog*(v: EpochRef): string =
if v == nil:
"EpochRef(nil)"
else:
&"(epoch ref: {v.epoch})"
try:
if v == nil:
"EpochRef(nil)"
else:
&"(epoch ref: {v.epoch})"
except ValueError as err:
err.msg # Shouldn't happen - but also shouldn't crash!
chronicles.formatIt BlockSlot: shortLog(it)
chronicles.formatIt BlockRef: shortLog(it)

View File

@ -14,15 +14,28 @@ import
../spec/[
crypto, datatypes, digest, helpers, validator, state_transition,
beaconstate],
block_pools_types, quarantine
./block_pools_types, ./quarantine
export block_pools_types, helpers
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#interop-metrics
declareGauge beacon_head_root, "Root of the head block of the beacon chain"
declareGauge beacon_head_slot, "Slot of the head block of the beacon chain"
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#interop-metrics
declareGauge beacon_finalized_epoch, "Current finalized epoch" # On epoch transition
declareGauge beacon_finalized_root, "Current finalized root" # On epoch transition
declareGauge beacon_current_justified_epoch, "Current justified epoch" # On epoch transition
declareGauge beacon_current_justified_root, "Current justified root" # On epoch transition
declareGauge beacon_previous_justified_epoch, "Current previously justified epoch" # On epoch transition
declareGauge beacon_previous_justified_root, "Current previously justified root" # On epoch transition
declareCounter beacon_reorgs_total, "Total occurrences of reorganizations of the chain" # On fork choice
declareCounter beacon_state_data_cache_hits, "EpochRef hits"
declareCounter beacon_state_data_cache_misses, "EpochRef misses"
declareCounter beacon_state_rewinds, "State database rewinds"
declareGauge beacon_active_validators, "Number of validators in the active validator set"
declareGauge beacon_pending_deposits, "Number of pending deposits (state.eth1_data.deposit_count - state.eth1_deposit_index)" # On block
declareGauge beacon_processed_deposits_total, "Number of total deposits included on chain" # On block
@ -810,7 +823,6 @@ proc updateHead*(
let
lastHead = dag.head
dag.db.putHeadBlock(newHead.root)
# Start off by making sure we have the right state - updateStateData will try
# to use existing in-memory states to make this smooth
@ -818,6 +830,15 @@ proc updateHead*(
updateStateData(
dag, dag.headState, newHead.atSlot(newHead.slot), false, cache)
dag.db.putHeadBlock(newHead.root)
let
finalizedHead = newHead.atEpochStart(
dag.headState.data.data.finalized_checkpoint.epoch)
doAssert (not finalizedHead.blck.isNil),
"Block graph should always lead to a finalized block"
if not lastHead.isAncestorOf(newHead):
notice "Updated head block with chain reorg",
lastHead = shortLog(lastHead),
@ -838,9 +859,6 @@ proc updateHead*(
stateSlot = shortLog(dag.headState.data.data.slot),
justified = shortLog(dag.headState.data.data.current_justified_checkpoint),
finalized = shortLog(dag.headState.data.data.finalized_checkpoint)
let
finalizedHead = newHead.atEpochStart(
dag.headState.data.data.finalized_checkpoint.epoch)
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#additional-metrics
if dag.headState.data.data.eth1_data.deposit_count < high(int64).uint64:
@ -850,12 +868,28 @@ proc updateHead*(
beacon_processed_deposits_total.set(
dag.headState.data.data.eth1_deposit_index.int64)
doAssert (not finalizedHead.blck.isNil),
"Block graph should always lead to a finalized block"
beacon_head_root.set newHead.root.toGaugeValue
beacon_head_slot.set newHead.slot.int64
if lastHead.slot.epoch != newHead.slot.epoch:
# Epoch updated - in theory, these could happen when the wall clock
# changes epoch, even if there is no new block / head, but we'll delay
# updating them until a block confirms the change
beacon_current_justified_epoch.set(
dag.headState.data.data.current_justified_checkpoint.epoch.int64)
beacon_current_justified_root.set(
dag.headState.data.data.current_justified_checkpoint.root.toGaugeValue)
beacon_previous_justified_epoch.set(
dag.headState.data.data.previous_justified_checkpoint.epoch.int64)
beacon_previous_justified_root.set(
dag.headState.data.data.previous_justified_checkpoint.root.toGaugeValue)
let epochRef = getEpochRef(dag, newHead, newHead.slot.epoch)
beacon_active_validators.set(
epochRef.shuffled_active_validator_indices.lenu64().int64)
if finalizedHead != dag.finalizedHead:
block: # Remove states, walking slot by slot
discard
var cur = finalizedHead
while cur != dag.finalizedHead:
# TODO This is a quick fix to prune some states from the database, but
@ -912,6 +946,11 @@ proc updateHead*(
finalizedHead = shortLog(finalizedHead),
heads = dag.heads.len
beacon_finalized_epoch.set(
dag.headState.data.data.finalized_checkpoint.epoch.int64)
beacon_finalized_root.set(
dag.headState.data.data.finalized_checkpoint.root.toGaugeValue)
proc isInitialized*(T: type ChainDAGRef, db: BeaconChainDB): bool =
let
headBlockRoot = db.getHeadBlock()

View File

@ -10,7 +10,7 @@
import
std/tables,
chronicles,
metrics, stew/results,
stew/results,
../extras, ../time,
../spec/[crypto, datatypes, digest, helpers, signatures, state_transition],
./block_pools_types, ./chain_dag, ./quarantine

View File

@ -5,20 +5,20 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
chronicles, tables, options,
std/[tables, options],
chronicles,
stew/bitops2,
metrics,
../spec/[crypto, datatypes, digest],
block_pools_types
./block_pools_types
export options, block_pools_types
logScope:
topics = "quarant"
{.push raises: [Defect].}
func checkMissing*(quarantine: var QuarantineRef): seq[FetchRecord] =
## Return a list of blocks that we should try to resolve from other client -
## to be called periodically but not too often (once per slot?)

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[algorithm, sequtils, sets],
chronicles,

View File

@ -36,10 +36,6 @@ declareHistogram beacon_block_delay,
declareHistogram beacon_store_block_duration_seconds,
"storeBlock() duration", buckets = [0.25, 0.5, 1, 2, 4, 8, Inf]
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#interop-metrics
declareGauge beacon_head_root, "Root of the head block of the beacon chain"
declareGauge beacon_head_slot, "Slot of the head block of the beacon chain"
type
GetWallTimeFn* = proc(): BeaconTime {.gcsafe, raises: [Defect].}
@ -81,14 +77,15 @@ proc updateHead*(self: var Eth2Processor, wallSlot: Slot) =
# Store the new head in the chain DAG - this may cause epochs to be
# justified and finalized
let oldFinalized = self.chainDag.finalizedHead.blck
let
oldFinalized = self.chainDag.finalizedHead.blck
oldHead = self.chainDag.head
self.chainDag.updateHead(newHead, self.quarantine)
beacon_head_root.set newHead.root.toGaugeValue
beacon_head_slot.set newHead.slot.int64
# Cleanup the fork choice v2 if we have a finalized head
if oldFinalized != self.chainDag.finalizedHead.blck:
self.attestationPool[].prune()
proc dumpBlock[T](

View File

@ -45,8 +45,8 @@ template init(T: type RpcHttpServer, ip: ValidIpAddress, port: Port): T =
newRpcHttpServer([initTAddress(ip, port)])
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#interop-metrics
declareGauge beacon_slot,
"Latest slot of the beacon chain state"
declareGauge beacon_slot, "Latest slot of the beacon chain state"
declareGauge beacon_current_epoch, "Current epoch"
# Finalization tracking
declareGauge finalization_delay,
@ -540,6 +540,8 @@ proc onSlotStart(node: BeaconNode, lastSlot, scheduledSlot: Slot) {.async.} =
nextSlot = slot + 1
beacon_slot.set slot.int64
beacon_current_epoch.set slot.epoch.int64
finalization_delay.set scheduledSlot.epoch.int64 - finalizedEpoch.int64
if node.config.verifyFinalization:

View File

@ -8,8 +8,9 @@
{.push raises: [Defect].}
import
tables, algorithm, math, sequtils, options,
json_serialization/std/sets, chronicles,
std/[tables, algorithm, math, sequtils, options],
json_serialization/std/sets,
chronicles,
../extras, ../ssz/merkleization,
./crypto, ./datatypes, ./digest, ./helpers, ./signatures, ./validator,
../../nbench/bench_lab

View File

@ -25,7 +25,7 @@
import
# Standard library
std/[options, tables],
std/[options, hashes, tables],
# Internal
./digest,
# Status
@ -33,9 +33,7 @@ import
blscurve,
chronicles,
json_serialization,
nimcrypto/utils as ncrutils,
# Standard library
hashes
nimcrypto/utils as ncrutils
export results, json_serialization

View File

@ -25,7 +25,7 @@
{.push raises: [Defect].}
import
macros, hashes, json, strutils, tables, typetraits,
std/[macros, hashes, json, strutils, tables, typetraits],
stew/[byteutils], chronicles,
json_serialization/types as jsonTypes,
../version, ../ssz/types as sszTypes, ./crypto, ./digest, ./presets

View File

@ -28,7 +28,6 @@ import
chronicles,
nimcrypto/[sha2, hash],
stew/byteutils,
hashes,
eth/common/eth_types_json_serialization,
blscurve

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[algorithm, math, parseutils, strformat, strutils, typetraits, unicode],
@ -24,7 +26,6 @@ import nimcrypto/utils as ncrutils
export
results, burnMem, writeValue, readValue
{.push raises: [Defect].}
{.localPassC: "-fno-lto".} # no LTO for crypto
type

View File

@ -1,10 +1,17 @@
import
macros, strutils, parseutils, tables,
stew/endians2,
preset_values
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[macros, strutils, parseutils, tables],
stew/endians2,
preset_values
export
PresetValue, toBytesBE

View File

@ -20,40 +20,14 @@
{.push raises: [Defect].}
import
tables,
std/tables,
chronicles,
stew/results,
../extras, ../ssz/merkleization, metrics,
datatypes, crypto, digest, helpers, signatures, validator,
state_transition_block, state_transition_epoch,
./datatypes, ./crypto, ./digest, ./helpers, ./signatures, ./validator,
./state_transition_block, ./state_transition_epoch,
../../nbench/bench_lab
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#additional-metrics
declareGauge beacon_current_validators, """Number of status="pending|active|exited|withdrawable" validators in current epoch""" # On epoch transition
declareGauge beacon_previous_validators, """Number of status="pending|active|exited|withdrawable" validators in previous epoch""" # On epoch transition
func get_epoch_validator_count(state: BeaconState): int64 {.nbench.} =
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#additional-metrics
#
# This O(n) loop doesn't add to the algorithmic complexity of the epoch
# transition -- registry update already does this. It is not great, but
# isn't new, either. If profiling shows issues some of this can be loop
# fusion'ed.
for index, validator in state.validators:
# These work primarily for the `beacon_current_validators` metric defined
# as 'Number of status="pending|active|exited|withdrawable" validators in
# current epoch'. This is, in principle, equivalent to checking whether a
# validator's either at less than MAX_EFFECTIVE_BALANCE, or has withdrawn
# already because withdrawable_epoch has passed, which more precisely has
# intuitive meaning of all-the-current-relevant-validators. So, check for
# not-(either (not-even-pending) or withdrawn). That is validators change
# from not-even-pending to pending to active to exited to withdrawable to
# withdrawn, and this avoids bugs on potential edge cases and off-by-1's.
if (validator.activation_epoch != FAR_FUTURE_EPOCH or
validator.effective_balance > MAX_EFFECTIVE_BALANCE) and
validator.withdrawable_epoch > get_current_epoch(state):
result += 1
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function
proc verify_block_signature*(
state: BeaconState, signed_block: SomeSignedBeaconBlock): bool {.nbench.} =
@ -134,14 +108,11 @@ proc advance_slot(
let is_epoch_transition = (state.data.slot + 1).isEpoch
if is_epoch_transition:
# Note: Genesis epoch = 0, no need to test if before Genesis
beacon_previous_validators.set(get_epoch_validator_count(state.data))
process_epoch(state.data, updateFlags, epochCache)
clear_epoch_from_cache(
epochCache, (state.data.slot + 1).compute_epoch_at_slot)
state.data.slot += 1
if is_epoch_transition:
beacon_current_validators.set(get_epoch_validator_count(state.data))
# The root must be updated on every slot update, or the next `process_slot`
# will be incorrect

View File

@ -20,7 +20,8 @@
{.push raises: [Defect].}
import
algorithm, collections/sets, chronicles, options, sequtils, sets,
std/[algorithm, collections/sets, options, sequtils, sets],
chronicles,
../extras, ../ssz/merkleization, metrics,
./beaconstate, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
./signatures, ./presets,

View File

@ -21,7 +21,7 @@
import
std/[math, sequtils, tables, algorithm],
stew/[bitops2], chronicles, metrics,
stew/[bitops2], chronicles,
../extras,
../ssz/merkleization,
./beaconstate, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
@ -32,22 +32,6 @@ import
logScope: topics = "consens"
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#interop-metrics
declareGauge beacon_finalized_epoch, "Current finalized epoch" # On epoch transition
declareGauge beacon_finalized_root, "Current finalized root" # On epoch transition
declareGauge beacon_current_justified_epoch, "Current justified epoch" # On epoch transition
declareGauge beacon_current_justified_root, "Current justified root" # On epoch transition
declareGauge beacon_previous_justified_epoch, "Current previously justified epoch" # On epoch transition
declareGauge beacon_previous_justified_root, "Current previously justified root" # On epoch transition
# Non-spec
declareGauge epoch_transition_justification_and_finalization, "Epoch transition justification and finalization time"
declareGauge epoch_transition_times_rewards_and_penalties, "Epoch transition reward and penalty time"
declareGauge epoch_transition_registry_updates, "Epoch transition registry updates time"
declareGauge epoch_transition_slashings, "Epoch transition slashings time"
declareGauge epoch_transition_final_updates, "Epoch transition final updates time"
declareGauge beacon_current_epoch, "Current epoch"
type
# Caches for computing justificiation, rewards and penalties - based on
# implementation in Lighthouse:
@ -633,16 +617,3 @@ proc process_epoch*(state: var BeaconState, updateFlags: UpdateFlags,
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#final-updates
process_final_updates(state)
# Once per epoch metrics
beacon_current_epoch.set(currentEpoch.int64)
beacon_finalized_epoch.set(state.finalized_checkpoint.epoch.int64)
beacon_finalized_root.set(state.finalized_checkpoint.root.toGaugeValue)
beacon_current_justified_epoch.set(
state.current_justified_checkpoint.epoch.int64)
beacon_current_justified_root.set(
state.current_justified_checkpoint.root.toGaugeValue)
beacon_previous_justified_epoch.set(
state.previous_justified_checkpoint.epoch.int64)
beacon_previous_justified_root.set(
state.previous_justified_checkpoint.root.toGaugeValue)

View File

@ -9,7 +9,7 @@
{.push raises: [Defect].}
import
options, math, tables,
std/[options, math, tables],
./datatypes, ./digest, ./helpers
const

View File

@ -1,8 +1,15 @@
import
datatypes, digest, helpers
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
./datatypes, ./digest, ./helpers
const
SAFETY_DECAY* = 10'u64

View File

@ -1,8 +1,16 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
{.pragma: raisesssz, raises: [Defect, MalformedSszError, SszSizeMismatchError].}
import
typetraits, options,
std/[typetraits, options],
stew/[bitops2, endians2, objects],
../spec/[digest, datatypes], ./types, ./spec_types, ./merkleization

View File

@ -1,8 +1,15 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
{.pragma: raisesssz, raises: [Defect, IOError, MalformedSszError, SszSizeMismatchError].}
import
strutils, parseutils,
std/[strutils, parseutils],
stew/objects, faststreams/outputs, json_serialization/writer,
../spec/datatypes,
./bytes_reader, ./types, ./navigator, ./spec_types

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
{.pragma: raisesssz, raises: [Defect, MalformedSszError, SszSizeMismatchError].}

View File

@ -1,5 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
typetraits,
std/[typetraits],
../spec/[crypto, digest]
# Eth2-spec-specific type handling that is not generic to SSZ

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
# TODO Cannot override push, even though the function is annotated
# nimbus-eth2/beacon_chain/ssz.nim(212, 18) Error: can raise an unlisted exception: IOError
# {.push raises: [Defect].}
@ -7,7 +14,7 @@
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/ssz/simple-serialize.md#serialization
import
typetraits, options,
std/[typetraits, options],
stew/[bitops2, endians2, objects],
serialization, serialization/testing/tracing,
../spec/[digest, datatypes],

View File

@ -1,7 +1,14 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
tables, options, typetraits, strformat,
std/[tables, options, typetraits, strformat],
stew/shims/macros, stew/[byteutils, bitops2, objects],
serialization/[object_serialization, errors],
./spec_types, ./bitseqs,
@ -14,7 +21,7 @@ const
bytesPerChunk* = 32
type
UintN* = SomeUnsignedInt # TODO: Add StUint here
UintN* = SomeUnsignedInt
BasicType* = bool|UintN
Limit* = int64

View File

@ -1,11 +1,13 @@
import
tables, json, streams,
chronos, chronicles,
spec/[datatypes, crypto, digest, signatures, helpers],
beacon_node_types,
std/[tables, json, streams],
chronos, chronicles, metrics,
json_serialization/std/[sets, net],
validator_slashing_protection,
eth/db/[kvstore, kvstore_sqlite3]
eth/db/[kvstore, kvstore_sqlite3],
./spec/[datatypes, crypto, digest, signatures, helpers],
./beacon_node_types, validator_slashing_protection
declareGauge validators,
"Number of validators attached to the beacon node"
func init*(T: type ValidatorPool,
slashingProtectionDB: SlashingProtectionDB): T =
@ -28,12 +30,16 @@ proc addLocalValidator*(pool: var ValidatorPool,
pool.validators[pubKey] = v
notice "Local validator attached", pubKey, validator = shortLog(v)
validators.set(pool.count().int64)
proc addRemoteValidator*(pool: var ValidatorPool,
pubKey: ValidatorPubKey,
v: AttachedValidator) =
pool.validators[pubKey] = v
notice "Remote validator attached", pubKey, validator = shortLog(v)
validators.set(pool.count().int64)
proc getValidator*(pool: ValidatorPool,
validatorKey: ValidatorPubKey): AttachedValidator =
pool.validators.getOrDefault(validatorKey.initPubKey)

View File

@ -316,16 +316,10 @@
"steppedLine": false,
"targets": [
{
"expr": "beacon_current_validators{node=\"${node}\"}",
"expr": "beacon_active_validators{node=\"${node}\"}",
"interval": "",
"legendFormat": "current validators",
"refId": "A"
},
{
"expr": "beacon_current_live_validators{node=\"${node}\"}",
"interval": "",
"legendFormat": "current live validators",
"refId": "B"
}
],
"thresholds": [],