diff --git a/Cargo.toml b/Cargo.toml index a2c27e2..b8ab0d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.11.2" +version = "0.11.4" edition = "2024" rust-version = "1.88" authors = ["init4"] @@ -105,10 +105,12 @@ parking_lot = "0.12" chrono = "0.4.38" clap = "4" eyre = "0.6.12" +futures-util = "0.3.31" hex = { package = "const-hex", version = "1.10", default-features = false, features = [ "alloc", ] } itertools = "0.14.0" +metrics = "0.24.2" openssl = { version = "0.10", features = ["vendored"] } proptest = "1.6.0" reqwest = "0.12.9" diff --git a/crates/block-processor/Cargo.toml b/crates/block-processor/Cargo.toml index da0e12b..f1ac842 100644 --- a/crates/block-processor/Cargo.toml +++ b/crates/block-processor/Cargo.toml @@ -10,23 +10,27 @@ homepage.workspace = true repository.workspace = true [dependencies] +signet-constants.workspace = true signet-evm.workspace = true signet-extract.workspace = true signet-journal.workspace = true +signet-types.workspace = true init4-bin-base.workspace = true +trevm.workspace = true + signet-blobber.workspace = true signet-db.workspace = true signet-node-types.workspace = true +alloy.workspace = true + reth.workspace = true reth-exex.workspace = true reth-node-api.workspace = true +reth-chainspec.workspace = true -tracing.workspace = true eyre.workspace = true -alloy.workspace = true -signet-constants.workspace = true -trevm.workspace = true -reth-chainspec.workspace = true +metrics.workspace = true +tracing.workspace = true diff --git a/crates/block-processor/src/lib.rs b/crates/block-processor/src/lib.rs index 36d0ee5..818077d 100644 --- a/crates/block-processor/src/lib.rs +++ b/crates/block-processor/src/lib.rs @@ -11,6 +11,8 @@ #![deny(unused_must_use, rust_2018_idioms)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +pub(crate) mod metrics; + mod v1; pub use v1::SignetBlockProcessor as SignetBlockProcessorV1; diff --git a/crates/block-processor/src/metrics.rs b/crates/block-processor/src/metrics.rs new file mode 100644 index 0000000..601af62 --- /dev/null +++ b/crates/block-processor/src/metrics.rs @@ -0,0 +1,219 @@ +//! Metrics to track +//! +//! - Counters: +//! - Number of builder blocks extracted +//! - Number of builder blocks processed +//! - Number of transactions processed +//! - Host blocks without builder blocks +//! - Histograms: +//! - enter events extracted per block +//! - enter token events extracted per block +//! - transact events extracted per block +//! - enter events processed per block +//! - enter token events processed per block +//! - transact events processed +//! - Transaction counts per builder block + +use metrics::{Counter, Histogram, counter, describe_counter, describe_histogram, histogram}; +use signet_evm::BlockResult; +use signet_extract::{Extractable, Extracts, HasTxns}; +use signet_types::{MagicSig, MagicSigInfo}; +use std::sync::LazyLock; + +const BUILDER_BLOCKS_EXTRACTED: &str = "signet.block_processor.builder_blocks.extracted"; +const BUILDER_BLOCKS_EXTRACTED_HELP: &str = "Number of builder blocks extracted from host"; + +const BLOCKS_PROCESSED: &str = "signet.block_processor.processed"; +const BLOCKS_PROCESSED_HELP: &str = "Number of signet blocks processed"; + +const TRANSACTIONS_PROCESSED: &str = "signet.block_processor.transactions_processed"; +const TRANSACTIONS_PROCESSED_HELP: &str = "Number of transactions processed in signet blocks"; + +const HOST_WITHOUT_BUILDER_BLOCK: &str = "signet.block_processor.host_without_builder_block"; +const HOST_WITHOUT_BUILDER_BLOCK_HELP: &str = "Number of host blocks without builder blocks"; + +const TRANSACTIONS_PER_BUILDER_BLOCK: &str = "signet.block_processor.txns_per_builder_block"; +const TRANSACTIONS_PER_BUILDER_BLOCK_HELP: &str = + "Histogram of number of transactions per builder block"; + +const TRANSACT_EXTRACTS: &str = "signet.block_processor.transact_events.extracted"; +const TRANSACT_EXTRACTS_HELP: &str = "Transact events extracted from host per block"; + +const ENTER_EXTRACTS: &str = "signet.block_processor.enter_events.extracted"; +const ENTER_EXTRACTS_HELP: &str = "Enter events extracted from host per block"; + +const ENTER_TOKEN_EXTRACTS: &str = "signet.block_processor.enter_token_events.extracted"; +const ENTER_TOKEN_EXTRACTS_HELP: &str = + "Enter token events extracted from host per block, labeled by token"; + +const ENTER_PROCESSED: &str = "signet.block_processor.enter_events.processed"; +const ENTER_PROCESSED_HELP: &str = "Histogram of number of enter events processed per block"; + +const ENTER_TOKEN_PROCESSED: &str = "signet.block_processor.enter_token_events.processed"; +const ENTER_TOKEN_PROCESSED_HELP: &str = + "Histogram of number of enter token events processed per block"; + +const TRANSACT_PROCESSED: &str = "signet.block_processor.transact_events.processed"; +const TRANSACT_PROCESSED_HELP: &str = "Histogram of number of transact events processed per block"; + +static DESCRIBE: LazyLock<()> = LazyLock::new(|| { + describe_counter!(BUILDER_BLOCKS_EXTRACTED, BUILDER_BLOCKS_EXTRACTED_HELP); + describe_counter!(BLOCKS_PROCESSED, BLOCKS_PROCESSED_HELP); + describe_counter!(TRANSACTIONS_PROCESSED, TRANSACTIONS_PROCESSED_HELP); + describe_counter!(HOST_WITHOUT_BUILDER_BLOCK, HOST_WITHOUT_BUILDER_BLOCK_HELP); + + describe_histogram!(TRANSACTIONS_PER_BUILDER_BLOCK, TRANSACTIONS_PER_BUILDER_BLOCK_HELP); + describe_histogram!(TRANSACT_EXTRACTS, TRANSACT_EXTRACTS_HELP); + describe_histogram!(ENTER_EXTRACTS, ENTER_EXTRACTS_HELP); + describe_histogram!(ENTER_TOKEN_EXTRACTS, ENTER_TOKEN_EXTRACTS_HELP); + describe_histogram!(ENTER_PROCESSED, ENTER_PROCESSED_HELP); + describe_histogram!(ENTER_TOKEN_PROCESSED, ENTER_TOKEN_PROCESSED_HELP); + describe_histogram!(TRANSACT_PROCESSED, TRANSACT_PROCESSED_HELP); +}); + +fn blocks_extracted() -> Counter { + LazyLock::force(&DESCRIBE); + counter!(BUILDER_BLOCKS_EXTRACTED) +} + +fn inc_blocks_extracted() { + blocks_extracted().increment(1); +} + +fn blocks_processed() -> Counter { + LazyLock::force(&DESCRIBE); + counter!(BLOCKS_PROCESSED) +} + +fn inc_blocks_processed() { + blocks_processed().increment(1); +} + +fn transactions_processed() -> Counter { + LazyLock::force(&DESCRIBE); + counter!(TRANSACTIONS_PROCESSED) +} + +fn inc_transactions_processed(value: u64) { + transactions_processed().increment(value); +} + +fn host_without_builder_block() -> Counter { + LazyLock::force(&DESCRIBE); + counter!(HOST_WITHOUT_BUILDER_BLOCK) +} + +fn inc_host_without_builder_block() { + host_without_builder_block().increment(1); +} + +fn transactions_per_builder_block() -> Histogram { + LazyLock::force(&DESCRIBE); + histogram!(TRANSACTIONS_PER_BUILDER_BLOCK) +} + +fn record_transactions_per_builder_block(value: u64) { + transactions_per_builder_block().record(value as f64); +} + +fn transact_extracts() -> Histogram { + LazyLock::force(&DESCRIBE); + histogram!(TRANSACT_EXTRACTS) +} + +fn record_transact_extracts(value: u64) { + transact_extracts().record(value as f64); +} + +fn enter_extracts() -> Histogram { + LazyLock::force(&DESCRIBE); + histogram!(ENTER_EXTRACTS) +} + +fn record_enter_extracts(value: u64) { + enter_extracts().record(value as f64); +} + +fn enter_token_extracts() -> Histogram { + LazyLock::force(&DESCRIBE); + histogram!(ENTER_TOKEN_EXTRACTS) +} + +fn record_enter_token_events(value: u64) { + enter_token_extracts().record(value as f64); +} + +fn enters_processed() -> Histogram { + LazyLock::force(&DESCRIBE); + histogram!(ENTER_PROCESSED) +} + +fn record_enters_processed(value: u64) { + enters_processed().record(value as f64); +} + +fn enter_token_processed() -> Histogram { + LazyLock::force(&DESCRIBE); + histogram!(ENTER_TOKEN_PROCESSED) +} + +fn record_enter_token_processed(value: u64) { + enter_token_processed().record(value as f64); +} + +fn transacts_processed() -> Histogram { + LazyLock::force(&DESCRIBE); + histogram!(TRANSACT_PROCESSED) +} + +fn record_transacts_processed(value: u64) { + transacts_processed().record(value as f64); +} + +pub(crate) fn record_extracts(extracts: &Extracts<'_, T>) { + record_enter_extracts(extracts.enters.len() as u64); + record_enter_token_events(extracts.enter_tokens.len() as u64); + record_transact_extracts(extracts.transacts.len() as u64); + if extracts.events.submitted.is_some() { + inc_blocks_extracted(); + } else { + inc_host_without_builder_block(); + } +} + +pub(crate) fn record_block_result(block: &BlockResult) { + inc_blocks_processed(); + inc_transactions_processed(block.sealed_block.transactions().len() as u64); + + // find the index of the first magic sig transaction + // That index is the count of builder block transactions + let txns = block.sealed_block.transactions(); + + let txns_processed = + txns.partition_point(|tx| MagicSig::try_from_signature(tx.signature()).is_none()); + + let sys_txns = &txns[txns_processed..]; + + let mut enters = 0; + let mut enter_tokens = 0; + let mut transacts = 0; + for tx in sys_txns.iter() { + match MagicSig::try_from_signature(tx.signature()) { + Some(MagicSig { ty: MagicSigInfo::Enter, .. }) => { + enters += 1; + } + Some(MagicSig { ty: MagicSigInfo::EnterToken, .. }) => { + enter_tokens += 1; + } + Some(MagicSig { ty: MagicSigInfo::Transact { .. }, .. }) => { + transacts += 1; + } + Some(_) | None => unreachable!(), + }; + } + + record_transactions_per_builder_block(txns_processed as u64); + record_enters_processed(enters); + record_enter_token_processed(enter_tokens); + record_transacts_processed(transacts); +} diff --git a/crates/block-processor/src/v1/processor.rs b/crates/block-processor/src/v1/processor.rs index 3177d15..9a5212f 100644 --- a/crates/block-processor/src/v1/processor.rs +++ b/crates/block-processor/src/v1/processor.rs @@ -1,4 +1,4 @@ -use crate::Chain; +use crate::{Chain, metrics}; use alloy::{consensus::BlockHeader, primitives::B256}; use eyre::ContextCompat; use init4_bin_base::utils::calc::SlotCalculator; @@ -146,6 +146,8 @@ where } start = Some(new_ru_height); } + + metrics::record_extracts(&block_extracts); current = block_extracts.ru_height; let spec_id = self.spec_id(block_extracts.host_block.timestamp()); @@ -159,6 +161,8 @@ where tracing::trace!("Running EVM"); let block_result = self.run_evm(&block_extracts, spec_id).instrument(span).await?; + metrics::record_block_result(&block_result); + tracing::trace!("Committing EVM results"); let journal = self.commit_evm_results(&block_extracts, &block_result, prev_block_journal)?; diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index aa5c404..d1219d0 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -9,23 +9,28 @@ homepage.workspace = true repository.workspace = true [dependencies] -alloy.workspace = true -eyre.workspace = true -futures-util = "0.3.31" -reqwest.workspace = true -reth.workspace = true -reth-chainspec.workspace = true -reth-db.workspace = true -reth-db-common.workspace = true -reth-exex.workspace = true -reth-node-api.workspace = true -signet-blobber.workspace = true signet-block-processor.workspace = true signet-db.workspace = true signet-node-config.workspace = true signet-node-types.workspace = true signet-rpc.workspace = true + +signet-blobber.workspace = true signet-tx-cache.workspace = true signet-types.workspace = true + +alloy.workspace = true + +reth.workspace = true +reth-chainspec.workspace = true +reth-db.workspace = true +reth-db-common.workspace = true +reth-exex.workspace = true +reth-node-api.workspace = true + +eyre.workspace = true +futures-util.workspace = true +metrics.workspace = true +reqwest.workspace = true tokio.workspace = true tracing.workspace = true diff --git a/crates/node/src/lib.rs b/crates/node/src/lib.rs index 8504b57..325913f 100644 --- a/crates/node/src/lib.rs +++ b/crates/node/src/lib.rs @@ -11,6 +11,8 @@ #![deny(unused_must_use, rust_2018_idioms)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +mod metrics; + mod node; pub use node::{GENESIS_JOURNAL_HASH, SignetNode}; diff --git a/crates/node/src/metrics.rs b/crates/node/src/metrics.rs new file mode 100644 index 0000000..7623d73 --- /dev/null +++ b/crates/node/src/metrics.rs @@ -0,0 +1,62 @@ +//! Metrics to track +//! +//! - Counters +//! - Number of notifications received +//! - Number of reorgs received +//! - Number of notifications processed +//! - Number of reorgs processed + +use metrics::{Counter, counter, describe_counter}; +use reth_exex::ExExNotification; +use std::sync::LazyLock; + +const NOTIFICATION_RECEIVED: &str = "signet.node.notification_received"; +const NOTIFICATION_RECEIVED_HELP: &str = "Number of notifications received"; + +const REORGS_RECEIVED: &str = "signet.node.reorgs_received"; +const REORGS_RECEIVED_HELP: &str = "Number of reorgs received"; + +const NOTIFICATIONS_PROCESSED: &str = "signet.node.notifications_processed"; +const NOTIFICATIONS_PROCESSED_HELP: &str = "Number of notifications processed"; + +const REORGS_PROCESSED: &str = "signet.node.reorgs_processed"; +const REORGS_PROCESSED_HELP: &str = "Number of reorgs processed"; + +static DESCRIBE: LazyLock<()> = LazyLock::new(|| { + describe_counter!(NOTIFICATION_RECEIVED, NOTIFICATION_RECEIVED_HELP); + describe_counter!(REORGS_RECEIVED, REORGS_RECEIVED_HELP); + describe_counter!(NOTIFICATIONS_PROCESSED, NOTIFICATIONS_PROCESSED_HELP); + describe_counter!(REORGS_PROCESSED, REORGS_PROCESSED_HELP); +}); + +fn reorgs_processed() -> Counter { + LazyLock::force(&DESCRIBE); + counter!(REORGS_PROCESSED) +} + +fn inc_reorgs_processed() { + reorgs_processed().increment(1); +} + +fn notifications_processed() -> Counter { + LazyLock::force(&DESCRIBE); + counter!(NOTIFICATIONS_PROCESSED) +} + +fn inc_notifications_processed() { + notifications_processed().increment(1); +} + +pub(crate) fn record_notification_received(notification: &ExExNotification) { + inc_notifications_processed(); + if notification.reverted_chain().is_some() { + inc_reorgs_processed(); + } +} + +pub(crate) fn record_notification_processed(notification: &ExExNotification) { + inc_notifications_processed(); + if notification.reverted_chain().is_some() { + inc_reorgs_processed(); + } +} diff --git a/crates/node/src/node.rs b/crates/node/src/node.rs index a1730e0..b1dbd8a 100644 --- a/crates/node/src/node.rs +++ b/crates/node/src/node.rs @@ -1,3 +1,4 @@ +use crate::metrics; use alloy::{ consensus::BlockHeader, eips::NumHash, @@ -314,6 +315,8 @@ where committed = notification.committed_chain().map(|c| c.len()).unwrap_or_default(), ))] pub async fn on_notification(&self, notification: ExExNotification) -> eyre::Result<()> { + metrics::record_notification_received(¬ification); + // NB: REVERTS MUST RUN FIRST let mut reverted = None; if let Some(chain) = notification.reverted_chain() { @@ -335,6 +338,7 @@ where self.update_status(committed, reverted)?; } + metrics::record_notification_processed(¬ification); Ok(()) }