feat: add invalid headers metrics (#3314)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Dan Cline
2023-06-22 09:36:43 -04:00
committed by GitHub
parent 5cd2148789
commit b0f57bf97b
2 changed files with 73 additions and 33 deletions

View File

@ -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<H256, Arc<Header>>,
/// 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<Header>> {
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<Header>,
) {
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);
}
}
}

View File

@ -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<H256, Arc<Header>>,
}
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<Header>> {
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<Header>) {
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::*;