Skip to content
Merged
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
2 changes: 1 addition & 1 deletion crates/adapters/sp1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ native = [
"rand",
"sp1-sdk/network",
"sov-rollup-interface/native",
"sov-metrics?/native",
"sov-metrics/native",
"sov-sp1-adapter/native",
]
bench = [
Expand Down
2 changes: 1 addition & 1 deletion crates/adapters/sp1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub mod host;
#[cfg(feature = "native")]
pub mod network;

#[cfg(all(feature = "native", feature = "bench"))]
#[cfg(feature = "native")]
pub mod metrics;

/// Uniquely identifies a SP1 binary. Stored as a serialized version of `SP1VerifyingKey`.
Expand Down
55 changes: 55 additions & 0 deletions crates/adapters/sp1/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,68 @@
//! Defines utilities for collecting runtime metrics from inside a SP1 VM
use std::io::Write;

use sov_metrics::Metric;

#[cfg(feature = "bench")]
use sp1_sdk::HookEnv;

/// A custom callback for extracting metrics from the SP1 zkvm.
///
/// When the "bench" feature is enabled, this callback is registered as a syscall
/// in the SP1 VM and invoked whenever a function annotated with the `cycle_tracker`
/// macro is invoked.
#[cfg(feature = "bench")]
pub fn metrics_hook(_env: HookEnv, buf: &[u8]) -> Vec<Vec<u8>> {
Comment thread
bkolad marked this conversation as resolved.
let _ = sov_metrics::cycle_utils::deserialize_metrics_call(buf).unwrap();

vec![]
}

/// The type of SP1 prover that generated a proof.
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) enum ProverType {
/// Local CPU prover.
Cpu,
/// Succinct proving network.
Network,
}

impl ProverType {
/// Returns the string representation for use in metrics serialization.
pub fn as_str(&self) -> &'static str {
match self {
ProverType::Cpu => "cpu",
ProverType::Network => "network",
}
}
}

/// Metrics emitted when the SP1 proving network fulfills a proof request.
#[derive(Debug)]
pub(crate) struct SP1ProofFulfillmentMetrics {
/// The type of prover emitting the metric.
pub prover_type: ProverType,
/// The hex-encoded proof request ID.
pub request_id: String,
/// Time from proof request creation to fulfillment, in seconds, as reported by the SP1
/// network.
pub fulfillment_duration_secs: u64,
}

impl Metric for SP1ProofFulfillmentMetrics {
fn measurement_name(&self) -> &'static str {
"sov_rollup_sp1_proof_fulfillment"
}

fn serialize_for_telegraf(&self, buffer: &mut Vec<u8>) -> std::io::Result<()> {
write!(
buffer,
"{},prover_type={} request_id=\"{}\",fulfillment_duration_secs={}i",
self.measurement_name(),
self.prover_type.as_str(),
self.request_id,
self.fulfillment_duration_secs,
)
}
}
27 changes: 26 additions & 1 deletion crates/adapters/sp1/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ impl SP1Network {
}
}

impl SP1Network {
async fn emit_fulfillment_metric(&self, request_id: B256) {
let proof_request = match self.prover.get_proof_request(request_id).await {
Ok(Some(req)) => req,
// Best-effort: silently skip metric if request details are unavailable.
Ok(None) | Err(_) => return,
};

if let Some(fulfilled_at) = proof_request.fulfilled_at {
let fulfillment_duration_secs = fulfilled_at - proof_request.created_at;
sov_metrics::track_metrics(|tracker| {
tracker.submit(crate::metrics::SP1ProofFulfillmentMetrics {
prover_type: crate::metrics::ProverType::Network,
request_id: format!("{request_id}"),
fulfillment_duration_secs,
});
});
}
}
}

impl ZkvmNetwork for SP1Network {
type Guest = SP1Guest;
type ProofHandle = ProofHandle;
Expand Down Expand Up @@ -68,7 +89,11 @@ impl ZkvmNetwork for SP1Network {
}

match maybe_proof {
Some(proof) => Ok(Some(bincode::serialize(&proof)?)),
Some(proof) => {
self.emit_fulfillment_metric(*handle).await;

Ok(Some(bincode::serialize(&proof)?))
}
None => Ok(None),
}
}
Expand Down
Loading