From b0f57bf97b044f880178dfcd80cff0080a83b0fe Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Thu, 22 Jun 2023 09:36:43 -0400 Subject: [PATCH] feat: add invalid headers metrics (#3314) Co-authored-by: Matthias Seitz --- .../beacon/src/engine/invalid_headers.rs | 70 +++++++++++++++++++ crates/consensus/beacon/src/engine/mod.rs | 36 +--------- 2 files changed, 73 insertions(+), 33 deletions(-) create mode 100644 crates/consensus/beacon/src/engine/invalid_headers.rs diff --git a/crates/consensus/beacon/src/engine/invalid_headers.rs b/crates/consensus/beacon/src/engine/invalid_headers.rs new file mode 100644 index 0000000000..129cfefa6f --- /dev/null +++ b/crates/consensus/beacon/src/engine/invalid_headers.rs @@ -0,0 +1,70 @@ +use std::sync::Arc; + +use reth_metrics::{ + metrics::{self, Counter, Gauge}, + Metrics, +}; +use reth_primitives::{Header, SealedHeader, H256}; +use schnellru::{ByLength, LruMap}; +use tracing::warn; + +/// Metrics for the invalid headers cache. +#[derive(Metrics)] +#[metrics(scope = "invalid_header_cache")] +struct InvalidHeaderCacheMetrics { + /// The total number of invalid headers in the cache. + invalid_headers: Gauge, + /// The number of inserts with a known ancestor. + known_ancestor_inserts: Counter, + /// The number of unique invalid header inserts (i.e. without a known ancestor). + unique_inserts: Counter, +} + +/// Keeps track of invalid headers. +pub(crate) struct InvalidHeaderCache { + /// This maps a header hash to a reference to its invalid ancestor. + headers: LruMap>, + /// Metrics for the cache. + metrics: InvalidHeaderCacheMetrics, +} + +impl InvalidHeaderCache { + pub(crate) fn new(max_length: u32) -> Self { + Self { headers: LruMap::new(ByLength::new(max_length)), metrics: Default::default() } + } + + /// Returns the invalid ancestor's header if it exists in the cache. + pub(crate) fn get(&mut self, hash: &H256) -> Option<&mut Arc
> { + self.headers.get(hash) + } + + /// Inserts an invalid block into the cache, with a given invalid ancestor. + pub(crate) fn insert_with_invalid_ancestor( + &mut self, + header_hash: H256, + invalid_ancestor: Arc
, + ) { + if self.headers.get(&header_hash).is_none() { + warn!(target: "consensus::engine", hash=?header_hash, ?invalid_ancestor, "Bad block with existing invalid ancestor"); + self.headers.insert(header_hash, invalid_ancestor); + + // update metrics + self.metrics.known_ancestor_inserts.increment(1); + self.metrics.invalid_headers.set(self.headers.len() as f64); + } + } + + /// Inserts an invalid ancestor into the map. + pub(crate) fn insert(&mut self, invalid_ancestor: SealedHeader) { + if self.headers.get(&invalid_ancestor.hash).is_none() { + let hash = invalid_ancestor.hash; + let header = invalid_ancestor.unseal(); + warn!(target: "consensus::engine", ?hash, ?header, "Bad block with hash"); + self.headers.insert(hash, Arc::new(header)); + + // update metrics + self.metrics.unique_inserts.increment(1); + self.metrics.invalid_headers.set(self.headers.len() as f64); + } + } +} diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 7f1bc1749d..ceb022a4a9 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -18,7 +18,7 @@ use reth_interfaces::{ use reth_payload_builder::{PayloadBuilderAttributes, PayloadBuilderHandle}; use reth_primitives::{ listener::EventListeners, stage::StageId, BlockNumHash, BlockNumber, Head, Header, SealedBlock, - SealedHeader, H256, U256, + H256, U256, }; use reth_provider::{ BlockProvider, BlockSource, CanonChainTracker, ProviderError, StageCheckpointReader, @@ -29,7 +29,6 @@ use reth_rpc_types::engine::{ }; use reth_stages::{ControlFlow, Pipeline}; use reth_tasks::TaskSpawner; -use schnellru::{ByLength, LruMap}; use std::{ pin::Pin, sync::Arc, @@ -52,6 +51,8 @@ pub use error::{ BeaconOnNewPayloadError, }; +mod invalid_headers; +use invalid_headers::InvalidHeaderCache; mod metrics; mod event; @@ -1350,37 +1351,6 @@ where } } -/// Keeps track of invalid headers. -struct InvalidHeaderCache { - /// This maps a header hash to a reference to its invalid ancestor. - headers: LruMap>, -} - -impl InvalidHeaderCache { - fn new(max_length: u32) -> Self { - Self { headers: LruMap::new(ByLength::new(max_length)) } - } - - /// Returns the invalid ancestor's header if it exists in the cache. - fn get(&mut self, hash: &H256) -> Option<&mut Arc
> { - self.headers.get(hash) - } - - /// Inserts an invalid block into the cache, with a given invalid ancestor. - fn insert_with_invalid_ancestor(&mut self, header_hash: H256, invalid_ancestor: Arc
) { - warn!(target: "consensus::engine", hash=?header_hash, ?invalid_ancestor, "Bad block with existing invalid ancestor"); - self.headers.insert(header_hash, invalid_ancestor); - } - - /// Inserts an invalid ancestor into the map. - fn insert(&mut self, invalid_ancestor: SealedHeader) { - let hash = invalid_ancestor.hash; - let header = invalid_ancestor.unseal(); - warn!(target: "consensus::engine", ?hash, ?header, "Bad block with hash"); - self.headers.insert(hash, Arc::new(header)); - } -} - #[cfg(test)] mod tests { use super::*;