From 5ff0bbdd747d66b1dc381c45bf3e4fa0b69db2e5 Mon Sep 17 00:00:00 2001 From: Noel Date: Mon, 23 Mar 2026 14:22:40 +0900 Subject: [PATCH 1/3] + Fix local storage issue + Fix too short retry interval issue + lint --- src/coordinator_handler/api.rs | 2 +- src/coordinator_handler/types.rs | 6 ++-- src/prover/builder.rs | 12 ++++++- src/prover/mod.rs | 54 +++++++++++++++++++------------- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/coordinator_handler/api.rs b/src/coordinator_handler/api.rs index bef362c..33802fd 100644 --- a/src/coordinator_handler/api.rs +++ b/src/coordinator_handler/api.rs @@ -22,7 +22,7 @@ impl Api { pub fn new(cfg: CoordinatorConfig) -> eyre::Result { let retry_wait_duration = Duration::from_secs(cfg.retry_wait_time_sec); let retry_policy = ExponentialBackoff::builder() - .retry_bounds(retry_wait_duration / 2, retry_wait_duration) + .retry_bounds(retry_wait_duration, retry_wait_duration * 2) .build_with_max_retries(cfg.retry_count); let client = ClientBuilder::new(reqwest::Client::new()) diff --git a/src/coordinator_handler/types.rs b/src/coordinator_handler/types.rs index f4e28f6..d9c698a 100644 --- a/src/coordinator_handler/types.rs +++ b/src/coordinator_handler/types.rs @@ -288,9 +288,9 @@ mod tests { let prover_types = vec![ProverType::Chunk]; let vks = vec!["mock_vk".to_string()]; let login_message = LoginMessage { - challenge: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjQ4Mzg0ODUsIm9yaWdfaWF0IjoxNzI0ODM0ODg1LCJyYW5kb20iOiJ6QmdNZGstNGc4UzNUNTFrVEFsYk1RTXg2TGJ4SUs4czY3ejM2SlNuSFlJPSJ9.x9PvihhNx2w4_OX5uCrv8QJCNYVQkIi-K2k8XFXYmik".into(), - prover_version: "v4.4.45-37af5ef5-38a68e2-1c5093c".into(), - prover_name: "test".into(), + challenge: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjQ4Mzg0ODUsIm9yaWdfaWF0IjoxNzI0ODM0ODg1LCJyYW5kb20iOiJ6QmdNZGstNGc4UzNUNTFrVEFsYk1RTXg2TGJ4SUs4czY3ejM2SlNuSFlJPSJ9.x9PvihhNx2w4_OX5uCrv8QJCNYVQkIi-K2k8XFXYmik", + prover_version: "v4.4.45-37af5ef5-38a68e2-1c5093c", + prover_name: "test", prover_provider_type: ProverProviderType::Internal, prover_types: ProverTypes(&prover_types), vks: &vks, diff --git a/src/prover/builder.rs b/src/prover/builder.rs index 6de106d..9f350d7 100644 --- a/src/prover/builder.rs +++ b/src/prover/builder.rs @@ -72,8 +72,18 @@ where format_cloud_prover_name(self.cfg.prover_name_prefix.clone(), i) }; + let mut client_cfg = self.cfg.coordinator.clone(); + if client_cfg.retry_wait_time_sec < self.cfg.prover.poll_interval_sec { + tracing::warn!( + "Enforce too short retry wait time ({}) to equal to poll interval ({})", + client_cfg.retry_wait_time_sec, + self.cfg.prover.poll_interval_sec, + ); + client_cfg.retry_wait_time_sec = self.cfg.prover.poll_interval_sec; + } + CoordinatorClient::new( - self.cfg.coordinator.clone(), + client_cfg, self.cfg.coordinator_prover_type(), self.cfg.coordinator.suppress_empty_task_error, get_vk_response.vks.clone(), diff --git a/src/prover/mod.rs b/src/prover/mod.rs index 6844954..649ec57 100644 --- a/src/prover/mod.rs +++ b/src/prover/mod.rs @@ -94,9 +94,6 @@ where let task_str = task.to_string(); let i = work_set.pop().expect("can not be empty"); provers.spawn(async move { - // Soft start delay to stagger the provers - sleep(self_clone.poll_delay()).await; - let coordinator_client = &self_clone.coordinator_clients[i]; let prover_name = &coordinator_client.prover_name; @@ -111,6 +108,9 @@ where } i }); + + // Soft start delay to stagger the provers + sleep(self.poll_delay()).await; } // wait until all tasks has been done @@ -150,11 +150,9 @@ where coordinator_client: &CoordinatorClient, task_spec: Option<(ProofType, &str)>, ) -> eyre::Result<()> { - if let Some((coordinator_task, mut proving_task_id)) = self - .db - .as_ref() - .map(|db| db.get_task(&coordinator_client.key_signer.get_public_key())) - .unwrap_or_default() + let public_key = &coordinator_client.key_signer.get_public_key(); + if let Some((coordinator_task, mut proving_task_id)) = + self.db.as_ref().and_then(|db| db.get_task(public_key)) { let task_id = coordinator_task.clone().task_id; debug!(task_id = %task_id, "got previous task from db"); @@ -165,7 +163,7 @@ where proving_task_id = proving_task.task_id } return self - .handle_proving_progress(coordinator_client, &coordinator_task, proving_task_id) + .handle_proving_progress(coordinator_client, &coordinator_task, &proving_task_id) .await; } @@ -183,10 +181,14 @@ where return Ok(()); }; info!(prover_name = %coordinator_client.prover_name, "Got task from coordinator"); + // cache task to local, just after we have got task, with default proving task id + if let Some(db) = &self.db { + db.set_task(public_key, &coordinator_task, &coordinator_task.task_id); + } let proving_task = self .request_proving(coordinator_client, &coordinator_task) .await?; - self.handle_proving_progress(coordinator_client, &coordinator_task, proving_task.task_id) + self.handle_proving_progress(coordinator_client, &coordinator_task, &proving_task.task_id) .await } @@ -240,6 +242,15 @@ where ); } + if let Some(db) = &self.db { + // update the task id + db.set_task( + &coordinator_client.key_signer.get_public_key(), + coordinator_task, + &proving_task.task_id, + ); + } + Ok(proving_task) } @@ -247,7 +258,7 @@ where &self, coordinator_client: &CoordinatorClient, coordinator_task: &GetTaskResponse, - proving_service_task_id: String, + proving_service_task_id: &str, ) -> eyre::Result<()> { let prover_name = &coordinator_client.prover_name; let public_key = &coordinator_client.key_signer.get_public_key(); @@ -258,13 +269,17 @@ where // Track last observed status to avoid spamming logs when status hasn't changed. let mut last_status: Option = None; + if let Some(db) = &self.db { + db.set_task(public_key, coordinator_task, proving_service_task_id); + } + loop { let task = self .proving_service .write() .await .query_task(QueryTaskRequest { - task_id: proving_service_task_id.clone(), + task_id: proving_service_task_id.to_string(), }) .await; @@ -284,9 +299,6 @@ where ); } last_status.replace(current_status); - if let Some(db) = &self.db { - db.set_task(public_key, coordinator_task, &proving_service_task_id); - } sleep(self.poll_delay()).await; } TaskStatus::Success => { @@ -298,6 +310,9 @@ where ?proving_service_task_id, "Task proved successfully" ); + if let Some(db) = &self.db { + db.delete_task(public_key); + } self.submit_proof( coordinator_client, coordinator_task, @@ -306,9 +321,6 @@ where None, ) .await?; - if let Some(db) = &self.db { - db.delete_task(public_key); - } break; } TaskStatus::Failed => { @@ -322,6 +334,9 @@ where ?task_err, "Task failed" ); + if let Some(db) = &self.db { + db.delete_task(public_key); + } self.submit_proof( coordinator_client, coordinator_task, @@ -330,9 +345,6 @@ where Some(task_err), ) .await?; - if let Some(db) = &self.db { - db.delete_task(public_key); - } break; } } From 1620b84ca08c7ff9a11a9f5fc72e61a3bca7907d Mon Sep 17 00:00:00 2001 From: Noel Date: Mon, 23 Mar 2026 14:37:35 +0900 Subject: [PATCH 2/3] pump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c285048..1323594 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2237,7 +2237,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scroll-proving-sdk" -version = "0.2.0" +version = "0.3.0" dependencies = [ "alloy-rlp", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 040a43b..dde4a36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scroll-proving-sdk" -version = "0.2.0" +version = "0.3.0" edition = "2024" [[bin]] From 4266daae9c127ece8f709e2aa95e432bb1bb072f Mon Sep 17 00:00:00 2001 From: Noel Date: Mon, 23 Mar 2026 16:36:51 +0900 Subject: [PATCH 3/3] prune unnecessary persist action refine retry policy --- src/coordinator_handler/api.rs | 3 ++- src/db.rs | 4 ++++ src/prover/mod.rs | 16 ++-------------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/coordinator_handler/api.rs b/src/coordinator_handler/api.rs index 33802fd..6aa4dc6 100644 --- a/src/coordinator_handler/api.rs +++ b/src/coordinator_handler/api.rs @@ -8,7 +8,7 @@ use eyre::Context; use http::{Method, StatusCode}; use reqwest::{Url, header::CONTENT_TYPE}; use reqwest_middleware::{ClientBuilder, ClientWithMiddleware}; -use reqwest_retry::{RetryTransientMiddleware, policies::ExponentialBackoff}; +use reqwest_retry::{Jitter, RetryTransientMiddleware, policies::ExponentialBackoff}; use serde::{Deserialize, Serialize}; use tracing::Level; @@ -23,6 +23,7 @@ impl Api { let retry_wait_duration = Duration::from_secs(cfg.retry_wait_time_sec); let retry_policy = ExponentialBackoff::builder() .retry_bounds(retry_wait_duration, retry_wait_duration * 2) + .jitter(Jitter::None) .build_with_max_retries(cfg.retry_count); let client = ClientBuilder::new(reqwest::Client::new()) diff --git a/src/db.rs b/src/db.rs index 7af821e..ab2f282 100644 --- a/src/db.rs +++ b/src/db.rs @@ -9,6 +9,10 @@ pub struct Db { impl Db { pub fn new(path: impl AsRef) -> eyre::Result { + tracing::info!( + "Apply locol storage at {}", + path.as_ref().to_str().unwrap_or("WRONG PATH") + ); let db = DB::open_default(path)?; Ok(Self { db }) } diff --git a/src/prover/mod.rs b/src/prover/mod.rs index 649ec57..ef72eff 100644 --- a/src/prover/mod.rs +++ b/src/prover/mod.rs @@ -155,7 +155,7 @@ where self.db.as_ref().and_then(|db| db.get_task(public_key)) { let task_id = coordinator_task.clone().task_id; - debug!(task_id = %task_id, "got previous task from db"); + info!(task_id = %task_id, "got previous task from db"); if self.proving_service.read().await.is_local() { let proving_task = self .request_proving(coordinator_client, &coordinator_task) @@ -181,10 +181,6 @@ where return Ok(()); }; info!(prover_name = %coordinator_client.prover_name, "Got task from coordinator"); - // cache task to local, just after we have got task, with default proving task id - if let Some(db) = &self.db { - db.set_task(public_key, &coordinator_task, &coordinator_task.task_id); - } let proving_task = self .request_proving(coordinator_client, &coordinator_task) .await?; @@ -242,15 +238,6 @@ where ); } - if let Some(db) = &self.db { - // update the task id - db.set_task( - &coordinator_client.key_signer.get_public_key(), - coordinator_task, - &proving_task.task_id, - ); - } - Ok(proving_task) } @@ -270,6 +257,7 @@ where let mut last_status: Option = None; if let Some(db) = &self.db { + info!(task_id = %proving_service_task_id, "store task to local db"); db.set_task(public_key, coordinator_task, proving_service_task_id); }