Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ utoipa = { version = "5.3", optional = true }
kzg = { path = "../kzg" }
mock_elf = { path = "../mock_elf", optional = true }
avail-rust = { git = "https://github.com/availproject/avail-rust.git", branch = "toufeeq/scalable-da-2", optional = true }
opentelemetry = { version = "0.24.0", features = [
"metrics",
"logs",
], optional = true }

[features]
native = [
Expand All @@ -64,6 +68,7 @@ native = [
"dep:tracing",
"utoipa",
"avail-rust",
"dep:opentelemetry",
]
zkvm = [ "sparse-merkle-tree/arch-32", "sparse-merkle-tree/std" ]
native-sp1 = [ "sp1-sdk", "sp1-zkvm/verify", "native", "mock_elf/sp1" ]
Expand Down
2 changes: 2 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ pub mod db;
mod h256;
#[cfg(any(feature = "native"))]
pub mod mempool;
#[cfg(any(feature = "native"))]
pub mod metrics;
#[cfg(not(feature = "native"))]
pub mod nexus_guest;
pub mod state;
Expand Down
11 changes: 11 additions & 0 deletions core/src/mempool.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
db::NodeDB,
metrics::MempoolMetrics,
traits::NexusTransaction,
types::{Transaction, TransactionStatus, TransactionWithStatus},
};
Expand All @@ -12,6 +13,7 @@ use tracing::{debug, error, event, info, instrument, span, warn, Level};
pub struct Mempool {
tx_list: Arc<Mutex<Vec<Transaction>>>,
node_db: Arc<Mutex<NodeDB>>,
mempool_metrics: MempoolMetrics,
}

impl Mempool {
Expand All @@ -21,6 +23,7 @@ impl Mempool {
Self {
tx_list: Arc::new(Mutex::new(vec![])),
node_db,
mempool_metrics: MempoolMetrics::init(),
}
}

Expand All @@ -41,6 +44,7 @@ impl Mempool {
#[instrument(level = "debug", skip(self))]
pub async fn clear_upto_tx(&self, index: usize) -> () {
debug!("Clearing transactions up to index {} from mempool", index);
let (_, len) = self.get_current_txs().await;
let mut tx_list = self.tx_list.lock().await;
// Clear transactions up to the specified index
if index < tx_list.len() {
Expand All @@ -49,6 +53,10 @@ impl Mempool {
// Handle case where index exceeds the length of tx_list
tx_list.clear();
}
if let Some(len) = len {
self.mempool_metrics.mempool_txn_count_gauge.record((len - index) as u64, &[]);
self.mempool_metrics.mempool_txn_count_histogram.record((len - index) as u64, &[]);
}
}

#[instrument(level = "debug", skip(self))]
Expand All @@ -74,6 +82,9 @@ impl Mempool {

tx_list.push(tx);

self.mempool_metrics.mempool_txn_count_gauge.record(tx_list.len() as u64, &[]);
self.mempool_metrics.mempool_txn_count_histogram.record(tx_list.len() as u64, &[]);

info!("Transaction successfully added to mempool");
Ok(())
}
Expand Down
249 changes: 249 additions & 0 deletions core/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
use opentelemetry::global;
use opentelemetry::metrics::{Counter, Gauge, Histogram};
use std::time::Instant;

#[derive(Clone)]
pub struct MempoolMetrics {
pub mempool_txn_count_gauge: Gauge<u64>,
pub mempool_txn_count_histogram: Histogram<u64>,
}
impl MempoolMetrics {
pub fn init() -> Self {
let metrics_meter = global::meter("nexus-metrics");
let mempool_txn_count_gauge = metrics_meter.u64_gauge("mempool_txn_count").with_unit("Transactions").init();
let mempool_txn_count_histogram = metrics_meter
.u64_histogram("mempool_txn_count_histogram")
.with_unit("Transactions")
.init();
Self {
mempool_txn_count_gauge,
mempool_txn_count_histogram,
}
}
}

#[derive(Clone, Debug)]
pub struct ExecutionMetrics {
pub batch_execution_time: Histogram<u64>,
pub total_batch_execution_time: Histogram<u64>,
pub batch_number_counter: Counter<u64>,
pub number_of_transactions_batch: Histogram<u64>,
}
impl ExecutionMetrics {
pub fn init() -> Self {
let metrics_meter = global::meter("nexus-metrics");
let batch_execution_time = metrics_meter.u64_histogram("batch_execution_time").init();
let total_batch_execution_time = metrics_meter.u64_histogram("total_batch_execution_time").init();
let batch_number_counter = metrics_meter.u64_counter("block_number").with_unit("Blocks").init();
let number_of_transactions_batch = metrics_meter.u64_histogram("number_of_transactions").init();
Self {
batch_execution_time,
total_batch_execution_time,
batch_number_counter,
number_of_transactions_batch,
}
}
}

#[derive(Clone, Debug)]
pub struct ProvingMetrics {
pub batch_proving_time: Histogram<u64>,
}
impl ProvingMetrics {
pub fn init() -> Self {
let metrics_meter = global::meter("nexus-prover-metrics");
let batch_proving_time = metrics_meter.u64_histogram("batch_proving_time").init();
Self { batch_proving_time }
}
}

#[derive(Clone)]
pub struct ApiMetrics {
submit_tx_counter: Counter<u64>,
tx_status_counter: Counter<u64>,
get_block_counter: Counter<u64>,
get_state_counter: Counter<u64>,
get_state_hex_counter: Counter<u64>,
get_header_counter: Counter<u64>,
range_counter: Counter<u64>,
block_proof_counter: Counter<u64>,

submit_tx_response_time: Histogram<f64>,
tx_status_response_time: Histogram<f64>,
get_block_response_time: Histogram<f64>,
get_state_response_time: Histogram<f64>,
get_state_hex_response_time: Histogram<f64>,
get_header_response_time: Histogram<f64>,
range_response_time: Histogram<f64>,
block_proof_response_time: Histogram<f64>,
}

impl ApiMetrics {
pub fn new() -> Self {
let meter = global::meter("nexus_api");

let submit_tx_counter = meter
.u64_counter("nexus_api_submit_tx_requests")
.with_description("Number of transaction submission requests")
.init();

let tx_status_counter = meter
.u64_counter("nexus_api_tx_status_requests")
.with_description("Number of transaction status requests")
.init();

let get_block_counter = meter
.u64_counter("nexus_api_get_block_requests")
.with_description("Number of block retrieval requests")
.init();

let get_state_counter = meter
.u64_counter("nexus_api_get_state_requests")
.with_description("Number of account state requests")
.init();

let get_state_hex_counter = meter
.u64_counter("nexus_api_get_state_hex_requests")
.with_description("Number of hex account state requests")
.init();

let get_header_counter = meter
.u64_counter("nexus_api_get_header_requests")
.with_description("Number of header requests")
.init();

let range_counter = meter
.u64_counter("nexus_api_range_requests")
.with_description("Number of block range requests")
.init();

let block_proof_counter = meter
.u64_counter("nexus_api_get_block_proof_requests")
.with_description("Number of block proof requests")
.init();

// Create histograms for response times (in milliseconds)
let submit_tx_response_time = meter
.f64_histogram("nexus_api_submit_tx_response_time")
.with_description("Response time for transaction submission")
.with_unit("ms")
.init();

let tx_status_response_time = meter
.f64_histogram("nexus_api_tx_status_response_time")
.with_description("Response time for transaction status requests")
.with_unit("ms")
.init();

let get_block_response_time = meter
.f64_histogram("nexus_api_get_block_response_time")
.with_description("Response time for block retrieval")
.with_unit("ms")
.init();

let get_state_response_time = meter
.f64_histogram("nexus_api_get_state_response_time")
.with_description("Response time for account state requests")
.with_unit("ms")
.init();

let get_state_hex_response_time = meter
.f64_histogram("nexus_api_get_state_hex_response_time")
.with_description("Response time for hex account state requests")
.with_unit("ms")
.init();

let get_header_response_time = meter
.f64_histogram("nexus_api_get_header_response_time")
.with_description("Response time for header requests")
.with_unit("ms")
.init();

let range_response_time = meter
.f64_histogram("nexus_api_range_response_time")
.with_description("Response time for block range requests")
.with_unit("ms")
.init();

let block_proof_response_time = meter
.f64_histogram("nexus_api_block_proof_response_time")
.with_description("Response time for block proof requests")
.init();

Self {
submit_tx_counter,
tx_status_counter,
get_block_counter,
get_state_counter,
get_state_hex_counter,
get_header_counter,
range_counter,
block_proof_counter,

submit_tx_response_time,
tx_status_response_time,
get_block_response_time,
get_state_response_time,
get_state_hex_response_time,
get_header_response_time,
range_response_time,
block_proof_response_time,
}
}

// Measure response time and increment counter for submit_tx endpoint
pub fn record_submit_tx_request(&self, start_time: Instant) {
self.submit_tx_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.submit_tx_response_time.record(duration, &[]);
}

// Measure response time and increment counter for tx_status endpoint
pub fn record_tx_status_request(&self, start_time: Instant) {
self.tx_status_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.tx_status_response_time.record(duration, &[]);
}

// Measure response time and increment counter for get_block endpoint
pub fn record_get_block_request(&self, start_time: Instant) {
self.get_block_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.get_block_response_time.record(duration, &[]);
}

// Measure response time and increment counter for get_state endpoint
pub fn record_get_state_request(&self, start_time: Instant) {
self.get_state_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.get_state_response_time.record(duration, &[]);
}

// Measure response time and increment counter for get_state_hex endpoint
pub fn record_get_state_hex_request(&self, start_time: Instant) {
self.get_state_hex_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.get_state_hex_response_time.record(duration, &[]);
}

// Measure response time and increment counter for get_header endpoint
pub fn record_get_header_request(&self, start_time: Instant) {
self.get_header_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.get_header_response_time.record(duration, &[]);
}

// Measure response time and increment counter for range endpoint
pub fn record_range_request(&self, start_time: Instant) {
self.range_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.range_response_time.record(duration, &[]);
}

// Measure response time and increment counter for block_proof endpoint
pub fn record_block_proof_request(&self, start_time: Instant) {
self.range_counter.add(1, &[]);
let duration = start_time.elapsed().as_millis() as f64;
self.block_proof_response_time.record(duration, &[]);
}
}
9 changes: 9 additions & 0 deletions examples/zksync_adapter/host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ primitive-types = "0.12"
env_logger = "0.11.5"
log = "0.4.22"
zksync_basic_types = { git = "https://github.com/vibhurajeev/zksync-era" }
# OTEL
opentelemetry = { version = "0.24.0", features = [ "metrics", "logs" ] }
opentelemetry_sdk = { version = "0.24.0", features = [ "rt-tokio", "logs" ] }
opentelemetry-otlp = { version = "0.17.0", features = [
"tonic",
"metrics",
"logs",
] }
opentelemetry-semantic-conventions = { version = "0.25.0" }

[features]
default = [ "risc0" ]
Expand Down
Loading
Loading