Skip to content

Commit

Permalink
feat: Refactor metrics/make API use binaries (#2735)
Browse files Browse the repository at this point in the history
## What ❔

Add metric-emitting middleware for ExternalProofIntegrationAPI
Make API return binaries/allow uploading binaries for verification

## Why ❔

For better UX

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [ ] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] Code has been formatted via `zk fmt` and `zk lint`.
  • Loading branch information
Artemka374 authored Aug 28, 2024
1 parent 46a75d4 commit 8ed086a
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 102 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

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

3 changes: 0 additions & 3 deletions core/lib/prover_interface/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ pub enum SubmitProofRequest {
SkippedProofGeneration,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct OptionalProofGenerationDataRequest(pub Option<L1BatchNumber>);

#[derive(Debug, Serialize, Deserialize)]
pub struct VerifyProofRequest(pub Box<L1BatchProofForL1>);

Expand Down
2 changes: 1 addition & 1 deletion core/node/external_proof_integration_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ keywords.workspace = true
categories.workspace = true

[dependencies]
axum.workspace = true
axum = { workspace = true, features = ["multipart"] }
tracing.workspace = true
zksync_prover_interface.workspace = true
zksync_basic_types.workspace = true
Expand Down
57 changes: 43 additions & 14 deletions core/node/external_proof_integration_api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
mod error;
mod metrics;
mod middleware;
mod processor;

use std::{net::SocketAddr, sync::Arc};

use anyhow::Context;
use axum::{extract::Path, routing::post, Json, Router};
use axum::{
extract::{Multipart, Path, Request},
middleware::Next,
routing::{get, post},
Router,
};
use tokio::sync::watch;
use zksync_basic_types::commitment::L1BatchCommitmentMode;
use zksync_config::configs::external_proof_integration_api::ExternalProofIntegrationApiConfig;
use zksync_dal::{ConnectionPool, Core};
use zksync_object_store::ObjectStore;
use zksync_prover_interface::api::{OptionalProofGenerationDataRequest, VerifyProofRequest};

use crate::processor::Processor;
use crate::{
metrics::{CallOutcome, Method},
middleware::MetricsMiddleware,
processor::Processor,
};

pub async fn run_server(
config: ExternalProofIntegrationApiConfig,
Expand All @@ -23,7 +32,7 @@ pub async fn run_server(
mut stop_receiver: watch::Receiver<bool>,
) -> anyhow::Result<()> {
let bind_address = SocketAddr::from(([0, 0, 0, 0], config.http_port));
tracing::debug!("Starting external prover API server on {bind_address}");
tracing::info!("Starting external prover API server on {bind_address}");
let app = create_router(blob_store, connection_pool, commitment_mode).await;

let listener = tokio::net::TcpListener::bind(bind_address)
Expand All @@ -50,25 +59,45 @@ async fn create_router(
let mut processor =
Processor::new(blob_store.clone(), connection_pool.clone(), commitment_mode);
let verify_proof_processor = processor.clone();
let specific_proof_processor = processor.clone();

let middleware_factory = |method: Method| {
axum::middleware::from_fn(move |req: Request, next: Next| async move {
let middleware = MetricsMiddleware::new(method);
let response = next.run(req).await;
let outcome = match response.status().is_success() {
true => CallOutcome::Success,
false => CallOutcome::Failure,
};
middleware.observe(outcome);
response
})
};

Router::new()
.route(
"/proof_generation_data",
post(
// we use post method because the returned data is not idempotent,
// i.e we return different result on each call.
move |payload: Json<OptionalProofGenerationDataRequest>| async move {
processor.get_proof_generation_data(payload).await
},
),
get(move || async move { processor.get_proof_generation_data().await })
.layer(middleware_factory(Method::GetLatestProofGenerationData)),
)
.route(
"/proof_generation_data/:l1_batch_number",
get(move |l1_batch_number: Path<u32>| async move {
specific_proof_processor
.proof_generation_data_for_existing_batch(l1_batch_number)
.await
})
.layer(middleware_factory(Method::GetSpecificProofGenerationData)),
)
.route(
"/verify_proof/:l1_batch_number",
post(
move |l1_batch_number: Path<u32>, payload: Json<VerifyProofRequest>| async move {
move |l1_batch_number: Path<u32>, multipart: Multipart| async move {
verify_proof_processor
.verify_proof(l1_batch_number, payload)
.verify_proof(l1_batch_number, multipart)
.await
},
),
)
.layer(middleware_factory(Method::VerifyProof)),
)
}
27 changes: 0 additions & 27 deletions core/node/external_proof_integration_api/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::time::Duration;

use tokio::time::Instant;
use vise::{EncodeLabelSet, EncodeLabelValue, Histogram, LabeledFamily, Metrics};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EncodeLabelSet, EncodeLabelValue)]
Expand All @@ -25,31 +24,5 @@ pub(crate) struct ProofIntegrationApiMetrics {
pub call_latency: LabeledFamily<(Method, CallOutcome), Histogram<Duration>, 2>,
}

pub(crate) struct MethodCallGuard {
method_type: Method,
outcome: CallOutcome,
started_at: Instant,
}

impl MethodCallGuard {
pub(crate) fn new(method_type: Method) -> Self {
MethodCallGuard {
method_type,
outcome: CallOutcome::Failure,
started_at: Instant::now(),
}
}

pub(crate) fn mark_successful(&mut self) {
self.outcome = CallOutcome::Success;
}
}

impl Drop for MethodCallGuard {
fn drop(&mut self) {
METRICS.call_latency[&(self.method_type, self.outcome)].observe(self.started_at.elapsed());
}
}

#[vise::register]
pub(crate) static METRICS: vise::Global<ProofIntegrationApiMetrics> = vise::Global::new();
22 changes: 22 additions & 0 deletions core/node/external_proof_integration_api/src/middleware.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use tokio::time::Instant;

use crate::metrics::{CallOutcome, Method, METRICS};

#[derive(Debug)]
pub(crate) struct MetricsMiddleware {
method: Method,
started_at: Instant,
}

impl MetricsMiddleware {
pub fn new(method: Method) -> MetricsMiddleware {
MetricsMiddleware {
method,
started_at: Instant::now(),
}
}

pub fn observe(&self, outcome: CallOutcome) {
METRICS.call_latency[&(self.method, outcome)].observe(self.started_at.elapsed());
}
}
Loading

0 comments on commit 8ed086a

Please sign in to comment.