Skip to content

Commit

Permalink
feat(prover): Add prover_cli stats command (#2362)
Browse files Browse the repository at this point in the history
Adds stats commands, which provides information (batch number, when the
request for proving was created and how long it took) for all L1 Batch
proofs. This speeds up proving time reduction (by giving everyone
visibility into current process) and can serve as further automation in
the future (for instance, emit metrics, or use the tooling for automated
reports).
  • Loading branch information
EmilLuta authored Jul 2, 2024
1 parent fe03d0e commit fe65319
Show file tree
Hide file tree
Showing 17 changed files with 364 additions and 203 deletions.
13 changes: 9 additions & 4 deletions core/lib/basic_types/src/prover_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ use crate::{
L1BatchNumber,
};

// This currently lives in `zksync_prover_types` -- we don't want a dependency between prover types (`zkevm_test_harness`) and DAL.
// This will be gone as part of 1.5.0, when EIP4844 becomes normal jobs, rather than special cased ones.
pub const EIP_4844_CIRCUIT_ID: u8 = 255;

#[derive(Debug, Clone)]
pub struct FriProverJobMetadata {
pub id: u32,
Expand Down Expand Up @@ -382,3 +378,12 @@ pub struct ProofCompressionJobInfo {
pub time_taken: Option<NaiveTime>,
pub picked_by: Option<String>,
}

// Used for transferring information about L1 Batches from DAL to public interfaces (currently prover_cli stats).
/// DTO containing information about L1 Batch Proof.
#[derive(Debug, Clone)]
pub struct ProofGenerationTime {
pub l1_batch_number: L1BatchNumber,
pub time_taken: NaiveTime,
pub created_at: NaiveDateTime,
}
17 changes: 17 additions & 0 deletions core/lib/db_connection/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ pub(crate) struct InternalMarker;

impl DbMarker for InternalMarker {}

const MICROSECONDS_IN_A_SECOND: i64 = 1_000_000;
const MICROSECONDS_IN_A_MINUTE: i64 = MICROSECONDS_IN_A_SECOND * 60;
const MICROSECONDS_IN_AN_HOUR: i64 = MICROSECONDS_IN_A_MINUTE * 60;

pub fn duration_to_naive_time(duration: Duration) -> NaiveTime {
let total_seconds = duration.as_secs() as u32;
NaiveTime::from_hms_opt(
Expand All @@ -26,3 +30,16 @@ pub const fn pg_interval_from_duration(processing_timeout: Duration) -> PgInterv
microseconds: processing_timeout.as_micros() as i64,
}
}

// Note: this conversion purposefully ignores `.days` and `.months` fields of PgInterval.
// The PgIntervals expected are below 24h (represented by `.microseconds`). If that's not the case,
// the function will trim days and months. Use at your own risk.
pub fn naive_time_from_pg_interval(pg_interval: PgInterval) -> NaiveTime {
NaiveTime::from_hms_micro_opt(
(pg_interval.microseconds / MICROSECONDS_IN_AN_HOUR) as u32,
((pg_interval.microseconds / MICROSECONDS_IN_A_MINUTE) % 60) as u32,
((pg_interval.microseconds / MICROSECONDS_IN_A_SECOND) % 60) as u32,
(pg_interval.microseconds as u32) % 1_000_000,
)
.expect("failed to convert PgInterval to NaiveTime")
}
1 change: 1 addition & 0 deletions prover/Cargo.lock

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

1 change: 1 addition & 0 deletions prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ categories = ["cryptography"]
anyhow = "1.0"
async-trait = "0.1"
bincode = "1"
chrono = "0.4.38"
circuit_definitions = { git = "https://github.com/matter-labs/era-zkevm_test_harness.git", branch = "v1.5.0" }
circuit_sequencer_api = { package = "circuit_sequencer_api", git = "https://github.com/matter-labs/era-zkevm_test_harness.git", branch = "v1.5.0" }
clap = "4.4.6"
Expand Down
1 change: 1 addition & 0 deletions prover/prover_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ sqlx.workspace = true
circuit_definitions.workspace = true
serde_json.workspace = true
zkevm_test_harness = { workspace = true, optional = true, features = ["verbose_circuits"] }
chrono.workspace = true

[features]
# enable verbose circuits, if you want to use debug_circuit command (as it is quite heavy dependency).
Expand Down
7 changes: 5 additions & 2 deletions prover/prover_cli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use clap::{command, Args, Parser, Subcommand};
use zksync_types::url::SensitiveUrl;

use crate::commands::{self, config, debug_proof, delete, get_file_info, requeue, restart};
use crate::commands::{self, config, debug_proof, delete, get_file_info, requeue, restart, stats};

pub const VERSION_STRING: &str = env!("CARGO_PKG_VERSION");

#[derive(Parser)]
#[command(name="prover-cli", version=VERSION_STRING, about, long_about = None)]
#[command(name = "prover-cli", version = VERSION_STRING, about, long_about = None)]
struct ProverCLI {
#[command(subcommand)]
command: ProverCommand,
Expand Down Expand Up @@ -35,6 +35,8 @@ enum ProverCommand {
Status(commands::StatusCommand),
Requeue(requeue::Args),
Restart(restart::Args),
#[command(about = "Displays L1 Batch proving stats for a given period")]
Stats(stats::Options),
}

pub async fn start() -> anyhow::Result<()> {
Expand All @@ -47,6 +49,7 @@ pub async fn start() -> anyhow::Result<()> {
ProverCommand::Requeue(args) => requeue::run(args, config).await?,
ProverCommand::Restart(args) => restart::run(args).await?,
ProverCommand::DebugProof(args) => debug_proof::run(args).await?,
ProverCommand::Stats(args) => stats::run(args, config).await?,
};

Ok(())
Expand Down
3 changes: 2 additions & 1 deletion prover/prover_cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
pub(crate) use status::StatusCommand;
pub(crate) mod config;
pub(crate) mod debug_proof;
pub(crate) mod delete;
pub(crate) mod get_file_info;
pub(crate) mod requeue;
pub(crate) mod restart;
pub(crate) mod stats;
pub(crate) mod status;
pub(crate) use status::StatusCommand;
63 changes: 63 additions & 0 deletions prover/prover_cli/src/commands/stats.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use anyhow::Context;
use chrono::{self, NaiveTime};
use clap::{Args, ValueEnum};
use zksync_basic_types::prover_dal::ProofGenerationTime;
use zksync_db_connection::connection_pool::ConnectionPool;
use zksync_prover_dal::{Prover, ProverDal};

use crate::cli::ProverCLIConfig;

#[derive(ValueEnum, Clone)]
enum StatsPeriod {
Day,
Week,
}

#[derive(Args)]
pub(crate) struct Options {
#[clap(
short = 'p',
long = "period",
help = "Specify the time frame to look for stats",
default_value = "day"
)]
period: StatsPeriod,
}

pub(crate) async fn run(opts: Options, config: ProverCLIConfig) -> anyhow::Result<()> {
let prover_connection_pool = ConnectionPool::<Prover>::singleton(config.db_url)
.build()
.await
.context("failed to build a prover_connection_pool")?;
let mut conn = prover_connection_pool
.connection()
.await
.context("failed to get connection from pool")?;

let start_date = match opts.period {
StatsPeriod::Day => chrono::offset::Local::now().date_naive(),
StatsPeriod::Week => {
(chrono::offset::Local::now() - chrono::Duration::days(7)).date_naive()
}
};
let start_date =
start_date.and_time(NaiveTime::from_num_seconds_from_midnight_opt(0, 0).unwrap());
let proof_generation_times = conn
.fri_witness_generator_dal()
.get_proof_generation_times_for_time_frame(start_date)
.await?;
display_proof_generation_time(proof_generation_times);
Ok(())
}

fn display_proof_generation_time(proof_generation_times: Vec<ProofGenerationTime>) {
println!("Batch\tTime Taken\t\tCreated At");
for proof_generation_time in proof_generation_times {
println!(
"{}\t{:?}\t\t{}",
proof_generation_time.l1_batch_number,
proof_generation_time.time_taken,
proof_generation_time.created_at
);
}
}

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

This file was deleted.

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

This file was deleted.

This file was deleted.

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

Loading

0 comments on commit fe65319

Please sign in to comment.