diff --git a/Cargo.lock b/Cargo.lock index 92911f18e9..8f0a4cac6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3162,6 +3162,7 @@ dependencies = [ "beacon_chain", "ethereum_ssz", "ethereum_ssz_derive", + "lighthouse_metrics", "proto_array", "slog", "state_processing", diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index b6de128dbb..e290b4903a 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -2192,8 +2192,6 @@ impl BeaconChain { &self, verified: &impl VerifiedAttestation, ) -> Result<(), Error> { - let _timer = metrics::start_timer(&metrics::FORK_CHOICE_PROCESS_ATTESTATION_TIMES); - self.canonical_head .fork_choice_write_lock() .on_attestation( @@ -3634,8 +3632,6 @@ impl BeaconChain { // Register the new block with the fork choice service. { - let _fork_choice_block_timer = - metrics::start_timer(&metrics::FORK_CHOICE_PROCESS_BLOCK_TIMES); let block_delay = self .slot_clock .seconds_from_current_slot_start() diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index 832eaccc80..68fccee959 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -1666,9 +1666,6 @@ impl ExecutionPendingBlock { // Register each attestation in the block with fork choice. for (i, attestation) in block.message().body().attestations().enumerate() { - let _fork_choice_attestation_timer = - metrics::start_timer(&metrics::FORK_CHOICE_PROCESS_ATTESTATION_TIMES); - let indexed_attestation = consensus_context .get_indexed_attestation(&state, attestation) .map_err(|e| BlockError::PerBlockProcessingError(e.into_with_index(i)))?; diff --git a/beacon_node/beacon_chain/src/metrics.rs b/beacon_node/beacon_chain/src/metrics.rs index 0309c4995e..9610001be1 100644 --- a/beacon_node/beacon_chain/src/metrics.rs +++ b/beacon_node/beacon_chain/src/metrics.rs @@ -569,19 +569,6 @@ pub static FORK_CHOICE_AFTER_FINALIZATION_TIMES: LazyLock> = exponential_buckets(1e-3, 2.0, 10), ) }); -pub static FORK_CHOICE_PROCESS_BLOCK_TIMES: LazyLock> = LazyLock::new(|| { - try_create_histogram( - "beacon_fork_choice_process_block_seconds", - "Time taken to add a block and all attestations to fork choice", - ) -}); -pub static FORK_CHOICE_PROCESS_ATTESTATION_TIMES: LazyLock> = - LazyLock::new(|| { - try_create_histogram( - "beacon_fork_choice_process_attestation_seconds", - "Time taken to add an attestation to fork choice", - ) - }); pub static FORK_CHOICE_SET_HEAD_LAG_TIMES: LazyLock> = LazyLock::new(|| { try_create_histogram( "beacon_fork_choice_set_head_lag_times", @@ -1955,6 +1942,11 @@ pub fn scrape_for_metrics(beacon_chain: &BeaconChain) { .validator_monitor .read() .scrape_metrics(&beacon_chain.slot_clock, &beacon_chain.spec); + + beacon_chain + .canonical_head + .fork_choice_read_lock() + .scrape_for_metrics(); } /// Scrape the given `state` assuming it's the head state, updating the `DEFAULT_REGISTRY`. diff --git a/consensus/fork_choice/Cargo.toml b/consensus/fork_choice/Cargo.toml index 7a06d7352b..4a4f6e9086 100644 --- a/consensus/fork_choice/Cargo.toml +++ b/consensus/fork_choice/Cargo.toml @@ -12,6 +12,7 @@ state_processing = { workspace = true } proto_array = { workspace = true } ethereum_ssz = { workspace = true } ethereum_ssz_derive = { workspace = true } +lighthouse_metrics = { workspace = true } slog = { workspace = true } [dev-dependencies] diff --git a/consensus/fork_choice/src/fork_choice.rs b/consensus/fork_choice/src/fork_choice.rs index c55219a676..1482e2beb4 100644 --- a/consensus/fork_choice/src/fork_choice.rs +++ b/consensus/fork_choice/src/fork_choice.rs @@ -1,3 +1,4 @@ +use crate::metrics::{self, scrape_for_metrics}; use crate::{ForkChoiceStore, InvalidationOperation}; use proto_array::{ Block as ProtoBlock, DisallowedReOrgOffsets, ExecutionStatus, ProposerHeadError, @@ -262,6 +263,11 @@ fn dequeue_attestations( .unwrap_or(queued_attestations.len()), ); + metrics::inc_counter_by( + &metrics::FORK_CHOICE_DEQUEUED_ATTESTATIONS, + queued_attestations.len() as u64, + ); + std::mem::replace(queued_attestations, remaining) } @@ -649,6 +655,8 @@ where payload_verification_status: PayloadVerificationStatus, spec: &ChainSpec, ) -> Result<(), Error> { + let _timer = metrics::start_timer(&metrics::FORK_CHOICE_ON_BLOCK_TIMES); + // If this block has already been processed we do not need to reprocess it. // We check this immediately in case re-processing the block mutates some property of the // global fork choice store, e.g. the justified checkpoints or the proposer boost root. @@ -1040,6 +1048,8 @@ where attestation: IndexedAttestationRef, is_from_block: AttestationFromBlock, ) -> Result<(), Error> { + let _timer = metrics::start_timer(&metrics::FORK_CHOICE_ON_ATTESTATION_TIMES); + self.update_time(system_time_current_slot)?; // Ignore any attestations to the zero hash. @@ -1087,6 +1097,8 @@ where /// /// We assume that the attester slashing provided to this function has already been verified. pub fn on_attester_slashing(&mut self, slashing: AttesterSlashingRef<'_, E>) { + let _timer = metrics::start_timer(&metrics::FORK_CHOICE_ON_ATTESTER_SLASHING_TIMES); + let attesting_indices_set = |att: IndexedAttestationRef<'_, E>| { att.attesting_indices_iter() .copied() @@ -1502,6 +1514,11 @@ where queued_attestations: self.queued_attestations().to_vec(), } } + + /// Update the global metrics `DEFAULT_REGISTRY` with info from the fork choice + pub fn scrape_for_metrics(&self) { + scrape_for_metrics(self); + } } /// Helper struct that is used to encode/decode the state of the `ForkChoice` as SSZ bytes. diff --git a/consensus/fork_choice/src/lib.rs b/consensus/fork_choice/src/lib.rs index 5e8cfb1ee4..17f1dc38a6 100644 --- a/consensus/fork_choice/src/lib.rs +++ b/consensus/fork_choice/src/lib.rs @@ -1,5 +1,6 @@ mod fork_choice; mod fork_choice_store; +mod metrics; pub use crate::fork_choice::{ AttestationFromBlock, Error, ForkChoice, ForkChoiceView, ForkchoiceUpdateParameters, diff --git a/consensus/fork_choice/src/metrics.rs b/consensus/fork_choice/src/metrics.rs new file mode 100644 index 0000000000..eb0dbf435e --- /dev/null +++ b/consensus/fork_choice/src/metrics.rs @@ -0,0 +1,62 @@ +pub use lighthouse_metrics::*; +use std::sync::LazyLock; +use types::EthSpec; + +use crate::{ForkChoice, ForkChoiceStore}; + +pub static FORK_CHOICE_QUEUED_ATTESTATIONS: LazyLock> = LazyLock::new(|| { + try_create_int_gauge( + "fork_choice_queued_attestations", + "Current count of queued attestations", + ) +}); +pub static FORK_CHOICE_NODES: LazyLock> = LazyLock::new(|| { + try_create_int_gauge("fork_choice_nodes", "Current count of proto array nodes") +}); +pub static FORK_CHOICE_INDICES: LazyLock> = LazyLock::new(|| { + try_create_int_gauge( + "fork_choice_indices", + "Current count of proto array indices", + ) +}); +pub static FORK_CHOICE_DEQUEUED_ATTESTATIONS: LazyLock> = LazyLock::new(|| { + try_create_int_counter( + "fork_choice_dequeued_attestations_total", + "Total count of dequeued attestations", + ) +}); +pub static FORK_CHOICE_ON_BLOCK_TIMES: LazyLock> = LazyLock::new(|| { + try_create_histogram( + "beacon_fork_choice_process_block_seconds", + "The duration in seconds of on_block runs", + ) +}); +pub static FORK_CHOICE_ON_ATTESTATION_TIMES: LazyLock> = LazyLock::new(|| { + try_create_histogram( + "beacon_fork_choice_process_attestation_seconds", + "The duration in seconds of on_attestation runs", + ) +}); +pub static FORK_CHOICE_ON_ATTESTER_SLASHING_TIMES: LazyLock> = + LazyLock::new(|| { + try_create_histogram( + "beacon_fork_choice_on_attester_slashing_seconds", + "The duration in seconds on on_attester_slashing runs", + ) + }); + +/// Update the global metrics `DEFAULT_REGISTRY` with info from the fork choice. +pub fn scrape_for_metrics, E: EthSpec>(fork_choice: &ForkChoice) { + set_gauge( + &FORK_CHOICE_QUEUED_ATTESTATIONS, + fork_choice.queued_attestations().len() as i64, + ); + set_gauge( + &FORK_CHOICE_NODES, + fork_choice.proto_array().core_proto_array().nodes.len() as i64, + ); + set_gauge( + &FORK_CHOICE_INDICES, + fork_choice.proto_array().core_proto_array().indices.len() as i64, + ); +}