chore: add metrics on redundant proof nodes (#14969)

This commit is contained in:
Dan Cline
2025-03-12 19:07:06 -04:00
committed by GitHub
parent a38c991c36
commit 3bebb0a19f
5 changed files with 97 additions and 0 deletions

View File

@@ -26,6 +26,10 @@ alloy-rlp.workspace = true
smallvec = { workspace = true, features = ["const_new"] }
thiserror.workspace = true
# metrics
reth-metrics.workspace = true
metrics.workspace = true
[dev-dependencies]
reth-primitives-traits = { workspace = true, features = ["arbitrary"] }
reth-provider = { workspace = true, features = ["test-utils"] }

View File

@@ -8,6 +8,8 @@ pub use trie::*;
pub mod blinded;
mod metrics;
/// Re-export sparse trie error types.
pub mod errors {
pub use reth_execution_errors::{

View File

@@ -0,0 +1,74 @@
//! Metrics for the sparse state trie
use reth_metrics::{metrics::Histogram, Metrics};
/// Metrics for the sparse state trie
#[derive(Default, Debug)]
pub(crate) struct SparseStateTrieMetrics {
/// Number of account nodes that were skipped during a multiproof reveal due to being redundant
/// (i.e. they were already revealed)
pub(crate) multiproof_skipped_account_nodes: u64,
/// Number of total account nodes, including those that were skipped.
pub(crate) multiproof_total_account_nodes: u64,
/// Number of storage nodes that were skipped during a multiproof reveal due to being redundant
/// (i.e. they were already revealed)
pub(crate) multiproof_skipped_storage_nodes: u64,
/// Number of total storage nodes, including those that were skipped.
pub(crate) multiproof_total_storage_nodes: u64,
/// The actual metrics we will record into the histogram
pub(crate) histograms: SparseStateTrieHistograms,
}
impl SparseStateTrieMetrics {
/// Record the metrics into the histograms
pub(crate) fn record(&self) {
self.histograms
.multiproof_skipped_account_nodes
.record(self.multiproof_skipped_account_nodes as f64);
self.histograms
.multiproof_total_account_nodes
.record(self.multiproof_total_account_nodes as f64);
self.histograms
.multiproof_skipped_storage_nodes
.record(self.multiproof_skipped_storage_nodes as f64);
self.histograms
.multiproof_total_storage_nodes
.record(self.multiproof_total_storage_nodes as f64);
}
/// Increment the skipped account nodes counter
pub(crate) fn increment_skipped_account_nodes(&mut self) {
self.multiproof_skipped_account_nodes += 1;
}
/// Increment the total account nodes counter
pub(crate) fn increment_total_account_nodes(&mut self) {
self.multiproof_total_account_nodes += 1;
}
/// Increment the skipped storage nodes counter
pub(crate) fn increment_skipped_storage_nodes(&mut self) {
self.multiproof_skipped_storage_nodes += 1;
}
/// Increment the total storage nodes counter
pub(crate) fn increment_total_storage_nodes(&mut self) {
self.multiproof_total_storage_nodes += 1;
}
}
/// Metrics for the sparse state trie
#[derive(Metrics)]
#[metrics(scope = "sparse_state_trie")]
pub(crate) struct SparseStateTrieHistograms {
/// Histogram of account nodes that were skipped during a multiproof reveal due to being
/// redundant (i.e. they were already revealed)
pub(crate) multiproof_skipped_account_nodes: Histogram,
/// Histogram of total account nodes, including those that were skipped.
pub(crate) multiproof_total_account_nodes: Histogram,
/// Histogram of storage nodes that were skipped during a multiproof reveal due to being
/// redundant (i.e. they were already revealed)
pub(crate) multiproof_skipped_storage_nodes: Histogram,
/// Histogram of total storage nodes, including those that were skipped.
pub(crate) multiproof_total_storage_nodes: Histogram,
}

View File

@@ -1,5 +1,6 @@
use crate::{
blinded::{BlindedProvider, BlindedProviderFactory, DefaultBlindedProviderFactory},
metrics::SparseStateTrieMetrics,
RevealedSparseTrie, SparseTrie, TrieMasks,
};
use alloy_primitives::{
@@ -34,6 +35,8 @@ pub struct SparseStateTrie<F: BlindedProviderFactory = DefaultBlindedProviderFac
retain_updates: bool,
/// Reusable buffer for RLP encoding of trie accounts.
account_rlp_buf: Vec<u8>,
/// Metrics for the sparse state trie.
metrics: SparseStateTrieMetrics,
}
impl Default for SparseStateTrie {
@@ -46,6 +49,7 @@ impl Default for SparseStateTrie {
revealed_storage_paths: Default::default(),
retain_updates: false,
account_rlp_buf: Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE),
metrics: Default::default(),
}
}
}
@@ -81,6 +85,7 @@ impl<F: BlindedProviderFactory> SparseStateTrie<F> {
revealed_storage_paths: Default::default(),
retain_updates: false,
account_rlp_buf: Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE),
metrics: Default::default(),
}
}
@@ -260,8 +265,10 @@ impl<F: BlindedProviderFactory> SparseStateTrie<F> {
// Reveal the remaining proof nodes.
for (path, bytes) in account_nodes {
self.metrics.increment_total_account_nodes();
// If the node is already revealed, skip it.
if self.revealed_account_paths.contains(&path) {
self.metrics.increment_skipped_account_nodes();
continue
}
let node = TrieNode::decode(&mut &bytes[..])?;
@@ -307,8 +314,10 @@ impl<F: BlindedProviderFactory> SparseStateTrie<F> {
// Reveal the remaining proof nodes.
for (path, bytes) in nodes {
self.metrics.increment_total_storage_nodes();
// If the node is already revealed, skip it.
if revealed_nodes.contains(&path) {
self.metrics.increment_skipped_storage_nodes();
continue
}
let node = TrieNode::decode(&mut &bytes[..])?;
@@ -521,11 +530,17 @@ impl<F: BlindedProviderFactory> SparseStateTrie<F> {
///
/// If the trie has not been revealed, this function reveals the root node and returns its hash.
pub fn root(&mut self) -> SparseStateTrieResult<B256> {
// record revealed node metrics
self.metrics.record();
Ok(self.revealed_trie_mut()?.root())
}
/// Returns sparse trie root and trie updates if the trie has been revealed.
pub fn root_with_updates(&mut self) -> SparseStateTrieResult<(B256, TrieUpdates)> {
// record revealed node metrics
self.metrics.record();
let storage_tries = self.storage_trie_updates();
let revealed = self.revealed_trie_mut()?;