diff --git a/circuits/proof-builder/src/lib.rs b/circuits/proof-builder/src/lib.rs index 5d76ffea..114f0b60 100644 --- a/circuits/proof-builder/src/lib.rs +++ b/circuits/proof-builder/src/lib.rs @@ -72,6 +72,22 @@ pub enum ProofRequest { }, } +/// Latest EL block time in the state-chain batch (max header timestamp), Unix seconds. +/// +/// Used for `total_time_to_proof` as (time when proving completes) − (latest proved block time); +/// see . +pub fn state_chain_el_anchor_unix_secs(ctx: &ProofRequest) -> anyhow::Result { + let ProofRequest::StateChainProofRequest { blocks, .. } = ctx else { + anyhow::bail!("expected state chain proof request"); + }; + let max_ts = blocks + .iter() + .map(|b| b.evm_block.current_block.header.timestamp) + .max() + .ok_or_else(|| anyhow::anyhow!("state chain batch has no blocks"))?; + i64::try_from(max_ts).map_err(|_| anyhow::anyhow!("EL block timestamp out of range for i64")) +} + #[derive(Error, Debug, Clone)] pub enum ProofError { #[error("Retry after {0} seconds")] diff --git a/proof-builder-rpc/src/task/mod.rs b/proof-builder-rpc/src/task/mod.rs index fbbd07e0..cd816f08 100644 --- a/proof-builder-rpc/src/task/mod.rs +++ b/proof-builder-rpc/src/task/mod.rs @@ -632,6 +632,8 @@ pub(crate) async fn update_long_running_task( chain_name: String, proving_time: i64, zkm_version: String, + // Unix seconds of the latest EL block in the proved batch (chain time anchor for issue #366). + el_block_anchor_unix_secs: i64, ) -> anyhow::Result { let mut storage_processor = local_db.acquire().await?; let task = storage_processor diff --git a/proof-builder-rpc/src/task/state_chain_proof.rs b/proof-builder-rpc/src/task/state_chain_proof.rs index 61c92e71..371d22e2 100644 --- a/proof-builder-rpc/src/task/state_chain_proof.rs +++ b/proof-builder-rpc/src/task/state_chain_proof.rs @@ -2,7 +2,7 @@ use crate::task::ProofState::{Failed, New, Proven, Proving}; use crate::task::fetch_latest_long_running_task_by_state; use crate::task::{create_long_running_task, update_long_running_task}; use crate::{ProofBuilderConfig, task::fetch_latest_long_running_task}; -use proof_builder::{ProofBuilder, ProofRequest}; +use proof_builder::{state_chain_el_anchor_unix_secs, ProofBuilder, ProofRequest}; use state_chain_proof::{StateChainProofBuilder, fetch_state_chain}; use std::time::Duration; use store::localdb::LocalDB; @@ -165,6 +165,14 @@ async fn spawn_state_chain_prover( } }; + let el_anchor = match state_chain_el_anchor_unix_secs(&ctx) { + Ok(s) => s, + Err(e) => { + tracing::error!("EL block anchor for total_time_to_proof: {e:?}"); + continue; + } + }; + let affteced = match update_long_running_task( &local_db, start_index as i64, @@ -177,6 +185,7 @@ async fn spawn_state_chain_prover( StateChainProofBuilder::name(), 0, "".to_string(), + el_anchor, ).await { Ok(affected) => affected, Err(e) => { @@ -213,8 +222,21 @@ async fn spawn_state_chain_prover( } else { "failed" }; - metrics_state.record_attempt(STATE_CHAIN_PROOF, outcome, attempt_start.elapsed()); - let affected = match attempt { + + let affteced = match update_long_running_task( + &local_db, + start_index as i64, + batch_size as i64, + args.output_proof.clone(), + public_value_hex, + proof_size as i64, + cycles, + Proven, + StateChainProofBuilder::name(), + proving_time as i64, + zkm_version, + el_anchor, + ).await { Ok(affected) => affected, Err(error) => { tracing::error!("State chain proof attempt failed: {error}");