Skip to content

Commit

Permalink
feat(prover): integrate proving-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
yiweichi committed Jan 5, 2025
1 parent 707267a commit 6ba25dc
Show file tree
Hide file tree
Showing 12 changed files with 984 additions and 621 deletions.
389 changes: 384 additions & 5 deletions prover/Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "v1.
snark-verifier-sdk = { git = "https://github.com/scroll-tech/snark-verifier", branch = "develop", default-features = false, features = ["loader_halo2", "loader_evm", "halo2-pse"] }
prover_darwin = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.12.2", package = "prover", default-features = false, features = ["parallel_syn", "scroll"] }
prover_darwin_v2 = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.13.1", package = "prover", default-features = false, features = ["parallel_syn", "scroll"] }
scroll-proving-sdk = { git = "https://github.com/scroll-tech/scroll-proving-sdk.git", rev = "6dd13b6"}
base64 = "0.13.1"
reqwest = { version = "0.12.4", features = ["gzip"] }
reqwest-middleware = "0.3"
Expand All @@ -42,6 +43,7 @@ rand = "0.8.5"
eth-keystore = "0.5.0"
rlp = "0.5.2"
tokio = "1.37.0"
async-trait = "0.1"
sled = "0.34.7"
http = "1.1.0"
clap = { version = "4.5", features = ["derive"] }
Expand Down
194 changes: 194 additions & 0 deletions prover/prover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
use anyhow::{bail, Context, Error, Ok, Result};
use ethers_core::types::U64;

use std::{cell::RefCell, rc::Rc};

use crate::{
config::Config,
coordinator_client::{listener::Listener, types::*, CoordinatorClient},
geth_client::GethClient,
key_signer::KeySigner,
types::{ProofFailureType, ProofStatus, ProverType, TaskType},
utils::{get_prover_type, get_circuit_types},
zk_circuits_handler::{CircuitsHandler, CircuitsHandlerProvider},
};

use super::types::{ProofDetail, Task};

pub struct Prover<'a> {
config: &'a Config,
key_signer: Rc<KeySigner>,
circuits_handler_provider: RefCell<CircuitsHandlerProvider<'a>>,
coordinator_client: RefCell<CoordinatorClient<'a>>,
geth_client: Option<Rc<RefCell<GethClient>>>,
}

impl<'a> Prover<'a> {
pub fn new(config: &'a Config, coordinator_listener: Box<dyn Listener>) -> Result<Self> {
let keystore_path = &config.keystore_path;
let keystore_password = &config.keystore_password;

let geth_client = if config
.prover_types
.iter()
.any(|element| *element == ProverType::Chunk)
{
Some(Rc::new(RefCell::new(
GethClient::new(
&config.prover_name,
&config.l2geth.as_ref().unwrap().endpoint,
)
.context("failed to create l2 geth_client")?,
)))
} else {
None
};

let provider = CircuitsHandlerProvider::new(config, geth_client.clone())
.context("failed to create circuits handler provider")?;

let vks = provider.init_vks(config.prover_types.clone(), config, geth_client.clone());

let key_signer = Rc::new(KeySigner::new(keystore_path, keystore_password)?);
let coordinator_client =
CoordinatorClient::new(config, Rc::clone(&key_signer), coordinator_listener, vks)
.context("failed to create coordinator_client")?;

let prover = Prover {
config,
key_signer: Rc::clone(&key_signer),
circuits_handler_provider: RefCell::new(provider),
coordinator_client: RefCell::new(coordinator_client),
geth_client,
};

Ok(prover)
}

pub fn get_public_key(&self) -> String {
self.key_signer.get_public_key()
}

pub fn fetch_task(&self) -> Result<Task> {
log::info!("[prover] start to fetch_task");

let task_types: Vec<TaskType> =
self.config
.prover_types
.iter()
.fold(Vec::new(), |mut acc, prover_type| {
acc.extend(get_circuit_types(*prover_type));
acc
});

let mut req = GetTaskRequest {
task_types,
prover_height: None,
};

if self
.config
.prover_types
.iter()
.any(|element| *element == ProverType::Chunk)
{
let latest_block_number = self.get_latest_block_number_value()?;
if let Some(v) = latest_block_number {
if v.as_u64() == 0 {
bail!("omit to prove task of the genesis block")
}
req.prover_height = Some(v.as_u64());
} else {
log::error!("[prover] failed to fetch latest confirmed block number, got None");
bail!("failed to fetch latest confirmed block number, got None")
}
}
let resp = self.coordinator_client.borrow_mut().get_task(&req)?;

match resp.data {
Some(d) => Ok(Task::from(d)),
None => {
bail!("data of get_task empty, while error_code is success. there may be something wrong in response data or inner logic.")
}
}
}

pub fn prove_task(&self, task: &Task) -> Result<ProofDetail> {
let prover_type = match get_prover_type(task.task_type) {
Some(pt) => Ok(pt),
None => {
bail!("unsupported prover_type.")
}
}?;
log::info!("[prover] start to prove_task, task id: {}", task.id);
let handler: Rc<Box<dyn CircuitsHandler>> = self
.circuits_handler_provider
.borrow_mut()
.get_circuits_handler(&task.hard_fork_name, prover_type)
.context("failed to get circuit handler")?;
self.do_prove(task, handler)
}

fn do_prove(&self, task: &Task, handler: Rc<Box<dyn CircuitsHandler>>) -> Result<ProofDetail> {
let mut proof_detail = ProofDetail {
id: task.id.clone(),
proof_type: task.task_type,
..Default::default()
};

proof_detail.proof_data = handler.get_proof_data(task.task_type, task)?;
Ok(proof_detail)
}

pub fn submit_proof(&self, proof_detail: ProofDetail, task: &Task) -> Result<()> {
log::info!(
"[prover] start to submit_proof, task id: {}",
proof_detail.id
);

let request = SubmitProofRequest {
uuid: task.uuid.clone(),
task_id: proof_detail.id,
task_type: proof_detail.proof_type,
status: ProofStatus::Ok,
proof: proof_detail.proof_data,
..Default::default()
};

self.do_submit(&request)
}

pub fn submit_error(
&self,
task: &Task,
failure_type: ProofFailureType,
error: Error,
) -> Result<()> {
log::info!("[prover] start to submit_error, task id: {}", task.id);
let request = SubmitProofRequest {
uuid: task.uuid.clone(),
task_id: task.id.clone(),
task_type: task.task_type,
status: ProofStatus::Error,
failure_type: Some(failure_type),
failure_msg: Some(format!("{:#}", error)),
..Default::default()
};
self.do_submit(&request)
}

fn do_submit(&self, request: &SubmitProofRequest) -> Result<()> {
self.coordinator_client.borrow_mut().submit_proof(request)?;
Ok(())
}

fn get_latest_block_number_value(&self) -> Result<Option<U64>> {
let number = self
.geth_client
.as_ref()
.unwrap()
.borrow_mut()
.block_number()?;
Ok(number.as_number())
}
}
9 changes: 5 additions & 4 deletions prover/src/coordinator_client/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::errors::ErrorCode;
use crate::types::{ProofFailureType, ProofStatus, ProverType, TaskType};
use crate::types::{ProofFailureType, ProofStatus, ProverType};
use rlp::{Encodable, RlpStream};
use serde::{Deserialize, Serialize};
use scroll_proving_sdk::prover::types::CircuitType;

#[derive(Deserialize)]
pub struct Response<T> {
Expand Down Expand Up @@ -58,15 +59,15 @@ pub type ChallengeResponseData = LoginResponseData;

#[derive(Default, Serialize, Deserialize)]
pub struct GetTaskRequest {
pub task_types: Vec<TaskType>,
pub task_types: Vec<CircuitType>,
pub prover_height: Option<u64>,
}

#[derive(Serialize, Deserialize)]
pub struct GetTaskResponseData {
pub uuid: String,
pub task_id: String,
pub task_type: TaskType,
pub task_type: CircuitType,
pub task_data: String,
pub hard_fork_name: String,
}
Expand All @@ -75,7 +76,7 @@ pub struct GetTaskResponseData {
pub struct SubmitProofRequest {
pub uuid: String,
pub task_id: String,
pub task_type: TaskType,
pub task_type: CircuitType,
pub status: ProofStatus,
pub proof: String,
pub failure_type: Option<ProofFailureType>,
Expand Down
77 changes: 16 additions & 61 deletions prover/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,82 +5,37 @@ mod config;
mod coordinator_client;
mod geth_client;
mod key_signer;
mod prover;
mod task_cache;
mod task_processor;
mod types;
mod utils;
mod version;
mod zk_circuits_handler;
mod prover;

use anyhow::Result;
use clap::{ArgAction, Parser};
use config::{AssetsDirEnvConfig, Config};
use prover::Prover;
use std::rc::Rc;
use task_cache::{ClearCacheCoordinatorListener, TaskCache};
use task_processor::TaskProcessor;
use clap::Parser;
use scroll_proving_sdk::{config::Config, prover::ProverBuilder, utils::init_tracing};
use prover::LocalProver;

/// Simple program to greet a person
#[derive(Parser, Debug)]
#[clap(disable_version_flag = true)]
struct Args {
/// Path of config file
#[arg(long = "config", default_value = "conf/config.json")]
#[arg(long = "config", default_value = "config.json")]
config_file: String,

/// Version of this prover
#[arg(short, long, action = ArgAction::SetTrue)]
version: bool,

/// Path of log file
#[arg(long = "log.file")]
log_file: Option<String>,
}

fn start() -> Result<()> {
let args = Args::parse();

if args.version {
println!("version is {}", version::get_version());
std::process::exit(0);
}

utils::log_init(args.log_file);

let config: Config = Config::from_file(args.config_file)?;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
init_tracing();

if let Err(e) = AssetsDirEnvConfig::init() {
log::error!("AssetsDirEnvConfig init failed: {:#}", e);
std::process::exit(-2);
}

let task_cache = Rc::new(TaskCache::new(&config.db_path)?);

let coordinator_listener = Box::new(ClearCacheCoordinatorListener {
task_cache: task_cache.clone(),
});

let prover = Prover::new(&config, coordinator_listener)?;

log::info!(
"prover start successfully. name: {}, type: {:?}, publickey: {}, version: {}",
config.prover_name,
config.prover_types,
prover.get_public_key(),
version::get_version(),
);

let task_processor = TaskProcessor::new(&prover, task_cache);
let args = Args::parse();
let cfg: Config = Config::from_file(args.config_file)?;
let local_prover = LocalProver::new(cfg.prover.local.clone().unwrap());
let prover = ProverBuilder::new(cfg)
.with_proving_service(Box::new(local_prover))
.build()
.await?;

task_processor.start();
prover.run().await;

Ok(())
}

fn main() {
let result = start();
if let Err(e) = result {
log::error!("main exit with error {:#}", e)
}
}
Loading

0 comments on commit 6ba25dc

Please sign in to comment.