feat: add initial blockchain tree metrics (#3289)

This commit is contained in:
Dan Cline
2023-06-21 15:36:20 -04:00
committed by GitHub
parent 2596934464
commit 44da381591
7 changed files with 68 additions and 6 deletions

1
Cargo.lock generated
View File

@ -5071,6 +5071,7 @@ dependencies = [
"parking_lot 0.12.1", "parking_lot 0.12.1",
"reth-db", "reth-db",
"reth-interfaces", "reth-interfaces",
"reth-metrics",
"reth-primitives", "reth-primitives",
"reth-provider", "reth-provider",
"tokio", "tokio",

View File

@ -18,6 +18,7 @@ normal = [
reth-primitives = { workspace = true } reth-primitives = { workspace = true }
reth-interfaces = { workspace = true } reth-interfaces = { workspace = true }
reth-db = { path = "../storage/db" } reth-db = { path = "../storage/db" }
reth-metrics = { workspace = true, features = ["common"] }
reth-provider = { workspace = true } reth-provider = { workspace = true }
# common # common

View File

@ -4,6 +4,8 @@ use std::{
collections::{btree_map::Entry, hash_map, BTreeMap, HashMap, HashSet}, collections::{btree_map::Entry, hash_map, BTreeMap, HashMap, HashSet},
num::NonZeroUsize, num::NonZeroUsize,
}; };
use crate::metrics::BlockBufferMetrics;
/// Type that contains blocks by number and hash. /// Type that contains blocks by number and hash.
pub type BufferedBlocks = BTreeMap<BlockNumber, HashMap<BlockHash, SealedBlockWithSenders>>; pub type BufferedBlocks = BTreeMap<BlockNumber, HashMap<BlockHash, SealedBlockWithSenders>>;
@ -35,6 +37,8 @@ pub struct BlockBuffer {
/// ///
/// Used as counter of amount of blocks inside buffer. /// Used as counter of amount of blocks inside buffer.
pub(crate) lru: LruCache<BlockNumHash, ()>, pub(crate) lru: LruCache<BlockNumHash, ()>,
/// Various metrics for the block buffer.
pub(crate) metrics: BlockBufferMetrics,
} }
impl BlockBuffer { impl BlockBuffer {
@ -45,6 +49,7 @@ impl BlockBuffer {
parent_to_child: Default::default(), parent_to_child: Default::default(),
hash_to_num: Default::default(), hash_to_num: Default::default(),
lru: LruCache::new(NonZeroUsize::new(limit).unwrap()), lru: LruCache::new(NonZeroUsize::new(limit).unwrap()),
metrics: Default::default(),
} }
} }
@ -65,6 +70,7 @@ impl BlockBuffer {
self.remove_from_parent(evicted_block.parent_hash, &evicted_num_hash); self.remove_from_parent(evicted_block.parent_hash, &evicted_num_hash);
} }
} }
self.metrics.blocks.set(self.len() as f64);
} }
/// Removes the given block from the buffer and also all the children of the block. /// Removes the given block from the buffer and also all the children of the block.
@ -81,6 +87,7 @@ impl BlockBuffer {
} }
taken.extend(self.remove_children(vec![parent]).into_iter()); taken.extend(self.remove_children(vec![parent]).into_iter());
self.metrics.blocks.set(self.len() as f64);
taken taken
} }
@ -105,6 +112,7 @@ impl BlockBuffer {
} }
self.remove_children(remove_parent_children); self.remove_children(remove_parent_children);
self.metrics.blocks.set(self.len() as f64);
} }
/// Return reference to buffered blocks /// Return reference to buffered blocks

View File

@ -2,6 +2,7 @@
use crate::{ use crate::{
canonical_chain::CanonicalChain, canonical_chain::CanonicalChain,
chain::{BlockChainId, BlockKind}, chain::{BlockChainId, BlockKind},
metrics::TreeMetrics,
AppendableChain, BlockBuffer, BlockIndices, BlockchainTreeConfig, PostStateData, TreeExternals, AppendableChain, BlockBuffer, BlockIndices, BlockchainTreeConfig, PostStateData, TreeExternals,
}; };
use reth_db::{cursor::DbCursorRO, database::Database, tables, transaction::DbTx}; use reth_db::{cursor::DbCursorRO, database::Database, tables, transaction::DbTx};
@ -87,6 +88,8 @@ pub struct BlockchainTree<DB: Database, C: Consensus, EF: ExecutorFactory> {
config: BlockchainTreeConfig, config: BlockchainTreeConfig,
/// Broadcast channel for canon state changes notifications. /// Broadcast channel for canon state changes notifications.
canon_state_notification_sender: CanonStateNotificationSender, canon_state_notification_sender: CanonStateNotificationSender,
/// Metrics for the blockchain tree.
metrics: TreeMetrics,
} }
/// A container that wraps chains and block indices to allow searching for block hashes across all /// A container that wraps chains and block indices to allow searching for block hashes across all
@ -137,6 +140,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
), ),
config, config,
canon_state_notification_sender, canon_state_notification_sender,
metrics: Default::default(),
}) })
} }
@ -1058,6 +1062,12 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
Ok(Some(Chain::new(blocks_and_execution))) Ok(Some(Chain::new(blocks_and_execution)))
} }
} }
/// Update blockchain tree metrics
pub(crate) fn update_tree_metrics(&self) {
self.metrics.sidechains.set(self.chains.len() as f64);
self.metrics.canonical_chain_height.set(self.canonical_chain().tip().number as f64);
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -44,4 +44,7 @@ pub use post_state_data::{PostStateData, PostStateDataRef};
pub mod block_buffer; pub mod block_buffer;
mod canonical_chain; mod canonical_chain;
/// Common blockchain tree metrics.
pub mod metrics;
pub use block_buffer::BlockBuffer; pub use block_buffer::BlockBuffer;

View File

@ -0,0 +1,22 @@
use reth_metrics::{
metrics::{self, Gauge},
Metrics,
};
/// Metrics for the entire blockchain tree
#[derive(Metrics)]
#[metrics(scope = "blockchain_tree")]
pub struct TreeMetrics {
/// Total number of sidechains (not including the canonical chain)
pub sidechains: Gauge,
/// The highest block number in the canonical chain
pub canonical_chain_height: Gauge,
}
/// Metrics for the blockchain tree block buffer
#[derive(Metrics)]
#[metrics(scope = "blockchain_tree.block_buffer")]
pub struct BlockBufferMetrics {
/// Total blocks in the block buffer
pub blocks: Gauge,
}

View File

@ -41,7 +41,10 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreeEngine
for ShareableBlockchainTree<DB, C, EF> for ShareableBlockchainTree<DB, C, EF>
{ {
fn buffer_block(&self, block: SealedBlockWithSenders) -> Result<(), InsertBlockError> { fn buffer_block(&self, block: SealedBlockWithSenders) -> Result<(), InsertBlockError> {
self.tree.write().buffer_block(block) let mut tree = self.tree.write();
let res = tree.buffer_block(block);
tree.update_tree_metrics();
res
} }
fn insert_block( fn insert_block(
@ -49,27 +52,41 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreeEngine
block: SealedBlockWithSenders, block: SealedBlockWithSenders,
) -> Result<InsertPayloadOk, InsertBlockError> { ) -> Result<InsertPayloadOk, InsertBlockError> {
trace!(target: "blockchain_tree", hash=?block.hash, number=block.number, parent_hash=?block.parent_hash, "Inserting block"); trace!(target: "blockchain_tree", hash=?block.hash, number=block.number, parent_hash=?block.parent_hash, "Inserting block");
self.tree.write().insert_block(block) let mut tree = self.tree.write();
let res = tree.insert_block(block);
tree.update_tree_metrics();
res
} }
fn finalize_block(&self, finalized_block: BlockNumber) { fn finalize_block(&self, finalized_block: BlockNumber) {
trace!(target: "blockchain_tree", ?finalized_block, "Finalizing block"); trace!(target: "blockchain_tree", ?finalized_block, "Finalizing block");
self.tree.write().finalize_block(finalized_block) let mut tree = self.tree.write();
tree.finalize_block(finalized_block);
tree.update_tree_metrics();
} }
fn restore_canonical_hashes(&self, last_finalized_block: BlockNumber) -> Result<(), Error> { fn restore_canonical_hashes(&self, last_finalized_block: BlockNumber) -> Result<(), Error> {
trace!(target: "blockchain_tree", ?last_finalized_block, "Restoring canonical hashes for last finalized block"); trace!(target: "blockchain_tree", ?last_finalized_block, "Restoring canonical hashes for last finalized block");
self.tree.write().restore_canonical_hashes(last_finalized_block) let mut tree = self.tree.write();
let res = tree.restore_canonical_hashes(last_finalized_block);
tree.update_tree_metrics();
res
} }
fn make_canonical(&self, block_hash: &BlockHash) -> Result<CanonicalOutcome, Error> { fn make_canonical(&self, block_hash: &BlockHash) -> Result<CanonicalOutcome, Error> {
trace!(target: "blockchain_tree", ?block_hash, "Making block canonical"); trace!(target: "blockchain_tree", ?block_hash, "Making block canonical");
self.tree.write().make_canonical(block_hash) let mut tree = self.tree.write();
let res = tree.make_canonical(block_hash);
tree.update_tree_metrics();
res
} }
fn unwind(&self, unwind_to: BlockNumber) -> Result<(), Error> { fn unwind(&self, unwind_to: BlockNumber) -> Result<(), Error> {
trace!(target: "blockchain_tree", ?unwind_to, "Unwinding to block number"); trace!(target: "blockchain_tree", ?unwind_to, "Unwinding to block number");
self.tree.write().unwind(unwind_to) let mut tree = self.tree.write();
let res = tree.unwind(unwind_to);
tree.update_tree_metrics();
res
} }
} }