Skip to content

Commit

Permalink
add sp1-prover rust project
Browse files Browse the repository at this point in the history
  • Loading branch information
akonring committed Jul 25, 2024
1 parent 1ed2273 commit a320c1a
Show file tree
Hide file tree
Showing 11 changed files with 6,610 additions and 0 deletions.
6,015 changes: 6,015 additions & 0 deletions sp1-prover/Cargo.lock

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions sp1-prover/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "sp1-prover"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.4", features = ["derive", "env", "string"] }
protobuf = "3.5.0"
anyhow = "1.0.86"
url = "2.3"
tonic = "0.12.1"
tokio = "1.0.0"
tokio-stream = "0.1.15"
prost = "0.13"
rand = "0.8.5"
hex = "0.4.3"
serde_json = "1.0"
# future import of zkrollup-integration utils
fibonacci-script = { git = "ssh://[email protected]/EspressoSystems/zkrollup-integration.git", version = "0.1.0" }

[build-dependencies]
tonic-build = "0.12.1"
6 changes: 6 additions & 0 deletions sp1-prover/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("../proto/src/proto/aggregator/v1/aggregator.proto")?;
tonic_build::compile_protos("../proto/src/proto/executor/v1/executor.proto")?;
tonic_build::compile_protos("../proto/src/proto/hashdb/v1/hashdb.proto")?;
Ok(())
}
241 changes: 241 additions & 0 deletions sp1-prover/src/aggregator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
use std::{collections::HashMap, time::SystemTime};

use aggregator::{
aggregator_message::Request, aggregator_service_client::AggregatorServiceClient,
get_proof_response::Proof, prover_message::Response, FinalProof, GetStatusResponse,
ProverMessage, PublicInputs, PublicInputsExtended,
};
use anyhow::Ok;
use rand::{distributions::Alphanumeric, Rng};
use serde_json::Value;
use tokio::sync::mpsc;
use tokio_stream::StreamExt;

use crate::config::ProverConfig;

pub mod aggregator {
tonic::include_proto!("aggregator.v1");
}

static MOCKED_DATA: &str = include_str!("data/mocked_data.json");

#[allow(dead_code)]
#[derive(Debug, Clone)]
enum RequestType {
None,
GenBatchProof,
GenAggregatedProof,
GenFinalProof,
ProcessBatch,
Execute,
}

pub async fn run_aggregator_client(config: ProverConfig) -> anyhow::Result<()> {
println!(
"Establishing connection to aggregator on: {}",
config.aggregator_url
);
// create aggregator client
let mut aggregator_client =
AggregatorServiceClient::connect(config.aggregator_url.to_string()).await?;

let (tx, rx) = mpsc::unbounded_channel();

let rx_stream = tokio_stream::wrappers::UnboundedReceiverStream::new(rx);

let response_stream = aggregator_client.channel(rx_stream).await?;
let mut response = response_stream.into_inner();

let mut request_type = RequestType::None;
let mut last_generated_uuid = String::new();

while let Some(received) = response.next().await {
if let Result::Ok(agg_msg) = received {
// we return the same ID we got in the aggregator message
let response_id = agg_msg.id;

match agg_msg.request {
Some(v) => match v {
Request::GetStatusRequest(_) => {
println!("Received GetStatusRequest");
let msg = ProverMessage {
id: response_id,
response: Some(Response::GetStatusResponse(gen_response())),
};
_ = tx.send(msg);
}

Request::GenBatchProofRequest(req) => {
println!("Received request: {:?}", req);
request_type = RequestType::GenBatchProof;
let uuid = get_uuid();
last_generated_uuid.clone_from(&uuid);
let response = aggregator::GenBatchProofResponse {
id: uuid.clone(),
result: aggregator::Result::Ok.into(),
};
let msg = ProverMessage {
id: response_id,
response: Some(Response::GenBatchProofResponse(response)),
};
_ = tx.send(msg);
}
Request::GenAggregatedProofRequest(req) => {
println!("Received request: {:?}", req);
request_type = RequestType::GenAggregatedProof;
let uuid = get_uuid();
last_generated_uuid.clone_from(&uuid);
let response = aggregator::GenAggregatedProofResponse {
id: uuid.clone(),
result: aggregator::Result::Ok.into(),
};
let msg = ProverMessage {
id: response_id,
response: Some(Response::GenAggregatedProofResponse(response)),
};
_ = tx.send(msg);
}
Request::GenFinalProofRequest(req) => {
println!("Received request: {:?}", req);
request_type = RequestType::GenFinalProof;
let uuid = get_uuid();
last_generated_uuid.clone_from(&uuid);
let response = aggregator::GenFinalProofResponse {
id: uuid.clone(),
result: aggregator::Result::Ok.into(),
};
let msg = ProverMessage {
id: response_id,
response: Some(Response::GenFinalProofResponse(response)),
};
_ = tx.send(msg);
}

Request::GetProofRequest(req) => {
println!("Received request: {:?}", req);
let req_id = req.id;
if req_id == last_generated_uuid {
let result: i32 =
aggregator::get_proof_response::Result::CompletedOk.into();
let response = aggregator::GetProofResponse {
id: req_id,
result_string: "completed".to_string(),
proof: get_proof(request_type.clone()),
result,
};
let msg = ProverMessage {
id: response_id,
response: Some(Response::GetProofResponse(response)),
};
_ = tx.send(msg);
}
}
_ => {
println!("Received an invalid message type: {:?}", v);
}
},
None => {
println!("Stream to aggregator completed");
}
}
}
}
Ok(())
}

// emulate original (zkevm-prover) aggregator client mock:
// https://github.com/0xPolygonHermez/zkevm-prover/blob/d23715e37e1ceb048babd5a258147bb8f66ccc5e/test/service/aggregator/aggregator_client_mock.cpp#L34
fn get_proof(request_type: RequestType) -> Option<Proof> {
// deserialize mock data
let mock_data: Value = serde_json::from_str(MOCKED_DATA).expect("failed to parse json content");
let mock_string = mock_data["bytes"].as_str().unwrap();
let mock_bytes = hex::decode(mock_string).unwrap();
let mock_root = hex::decode(mock_data["root"].as_str().unwrap()).unwrap();
let mock_proof = mock_data["proof"].as_str().unwrap();
let mock_new_acc_input_hash =
hex::decode(mock_data["new_acc_input_hash"].as_str().unwrap()).unwrap();
let mock_new_local_exit_root =
hex::decode(mock_data["new_local_exit_root"].as_str().unwrap()).unwrap();
let mock_recursive_proof_1 = mock_data["recursive_proof_1"].as_str().unwrap();
let mock_recurisve_proof_2 = mock_data["recursive_proof_2"].as_str().unwrap();

match request_type {
RequestType::GenFinalProof => {
let public_inputs = PublicInputs {
old_state_root: mock_root.clone(),
old_acc_input_hash: mock_root.clone(),
old_batch_num: 1,
chain_id: 1000,
fork_id: 9,
batch_l2_data: mock_bytes.clone(),
l1_info_root: mock_bytes.clone(),
timestamp_limit: 1_000_000,
sequencer_addr: mock_string.to_string(),
forced_blockhash_l1: mock_bytes.clone(),
aggregator_addr: mock_string.to_string(),
l1_info_tree_data: HashMap::new(),
};
let public_inputs_extended = PublicInputsExtended {
public_inputs: Some(public_inputs),
new_state_root: mock_root.clone(),
new_acc_input_hash: mock_new_acc_input_hash,
new_local_exit_root: mock_new_local_exit_root,
new_batch_num: 2,
};
Some(Proof::FinalProof(FinalProof {
proof: mock_proof.to_string(),
public: Some(public_inputs_extended),
}))
}
RequestType::GenBatchProof => {
Some(Proof::RecursiveProof(mock_recursive_proof_1.to_string()))
}
RequestType::GenAggregatedProof => {
Some(Proof::RecursiveProof(mock_recurisve_proof_2.to_string()))
}
_ => {
println!(
"Received GetProof with invalid request type: {:?}",
request_type
);
None
}
}
}

fn gen_response() -> aggregator::GetStatusResponse {
GetStatusResponse {
status: aggregator::get_status_response::Status::Idle.into(),
last_computed_request_id: "".to_string(),
last_computed_end_time: get_current_time(),
current_computing_request_id: "".to_string(),
current_computing_start_time: get_current_time(),
version_proto: "v0_0_1".to_string(),
version_server: "0.0.1".to_string(),
pending_request_queue_ids: vec![get_uuid(), get_uuid(), get_uuid()],
prover_name: "sp1_test_prover".to_string(),
prover_id: get_uuid(),
fork_id: 9, // PROVER_FORK_ID

// below constants should be read from proc or sysctl
number_of_cores: 10,
total_memory: 1_000_000_000,
free_memory: 1_000_000,
}
}

// utils to emulate functionality aggregator client mock
fn get_uuid() -> String {
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(37)
.map(char::from)
.collect()
}

fn get_current_time() -> u64 {
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs()
}
44 changes: 44 additions & 0 deletions sp1-prover/src/bin/prover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use clap::Parser;
use sp1_prover::{
aggregator::run_aggregator_client, config::ProverConfig,
executor_service::run_executor_service, hashdb_service::run_hashdb_service,
};
use url::Url;

#[derive(Parser)]
struct Args {
/// Url of the aggregator
#[clap(long, default_value = "http://localhost:50081", env = "AGGREGATOR_URL")]
aggregator_url: Url,

/// Executor server port
#[clap(long, env = "EXECUTOR_PORT")]
executor_port: Option<u16>,

/// HashDB server port
#[clap(long, env = "HASHDB_PORT")]
hashdb_port: Option<u16>,
}

#[tokio::main]
async fn main() {
let args = Args::parse();
// prepare config for prover
let config = ProverConfig {
aggregator_url: args.aggregator_url,
executor_port: args.executor_port,
hashdb_port: args.hashdb_port,
};

if config.executor_port.is_some() {
run_executor_service(config.clone()).await;
}

if config.hashdb_port.is_some() {
run_hashdb_service(config.clone()).await;
}

run_aggregator_client(config.clone())
.await
.expect("aggregator service failed");
}
12 changes: 12 additions & 0 deletions sp1-prover/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use url::Url;

/// Configuration/Parameters used for SP1 prover
#[derive(Debug, Clone)]
pub struct ProverConfig {
/// URL of the aggregator.
pub aggregator_url: Url,
/// The port of the executor service.
pub executor_port: Option<u16>,
/// The port of the hashdb service
pub hashdb_port: Option<u16>,
}
9 changes: 9 additions & 0 deletions sp1-prover/src/data/mocked_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"bytes": "617b3a3528F9cDd6630fd3301B9c8911F7Bf063D",
"root": "090bcaf734c4f06c93954a827b45a6e8c67b8e0fd1e0a35a1c5982d6961828f9",
"proof": "0x20227cbcef731b6cbdc0edd5850c63dc7fbc27fb58d12cd4d08298799cf66a0512c230867d3375a1f4669e7267dad2c31ebcddbaccea6abd67798ceae35ae7611c665b6069339e6812d015e239594aa71c4e217288e374448c358f6459e057c91ad2ef514570b5dea21508e214430daadabdd23433820000fe98b1c6fa81d5c512b86fbf87bd7102775f8ef1da7e8014dc7aab225503237c7927c032e589e9a01a0eab9fda82ffe834c2a4977f36cc9bcb1f2327bdac5fb48ffbeb9656efcdf70d2656c328903e9fb96e4e3f470c447b3053cc68d68cf0ad317fe10aa7f254222e47ea07f3c1c3aacb74e5926a67262f261c1ed3120576ab877b49a81fb8aac51431858662af6b1a8138a44e9d0812d032340369459ccc98b109347cc874c7202dceecc3dbb09d7f9e5658f1ca3a92d22be1fa28f9945205d853e2c866d9b649301ac9857b07b92e4865283d3d5e2b711ea5f85cb2da71965382ece050508d3d008bbe4df5458f70bd3e1bfcc50b34222b43cd28cbe39a3bab6e464664a742161df99c607638e415ced49d0cd719518539ed5f561f81d07fe40d3ce85508e0332465313e60ad9ae271d580022ffca4fbe4d72d38d18e7a6e20d020a1d1e5a8f411291ab95521386fa538ddfe6a391d4a3669cc64c40f07895f031550b32f7d73205a69c214a8ef3cdf996c495e3fd24c00873f30ea6b2bfabfd38de1c3da357d1fefe203573fdad22f675cb5cfabbec0a041b1b31274f70193da8e90cfc4d6dc054c7cd26d09c1dadd064ec52b6ddcfa0cb144d65d9e131c0c88f8004f90d363034d839aa7760167b5302c36d2c2f6714b41782070b10c51c178bd923182d28502f36e19b079b190008c46d19c399331fd60b6b6bde898bd1dd0a71ee7ec7ff7124cc3d374846614389e7b5975b77c4059bc42b810673dbb6f8b951e5b636bdf24afd2a3cbe96ce8600e8a79731b4a56c697596e0bff7b73f413bdbc75069b002b00d713fae8d6450428246f1b794d56717050fdb77bbe094ac2ee6af54a153e2fb8ce1d31a86c4fdd523783b910bedf7db58a46ba6ce48ac3ca194f3cf2275e",
"new_acc_input_hash": "1afd6eaf13538380d99a245c2acc4a25481b54556ae080cf07d1facc0638cd8e",
"new_local_exit_root": "17c04c3760510b48c6012742c540a81aba4bca2f78b9d14bfd2f123e2e53ea3e",
"recursive_proof_1": "88888670604050723159190639550237390237901487387303122609079617855313706601738",
"recursive_proof_2": "99999670604050723159190639550237390237901487387303122609079617855313706601738"
}
7 changes: 7 additions & 0 deletions sp1-prover/src/data/mocked_sp1_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"bytes": "617b3a3528F9cDd6630fd3301B9c8911F7Bf063D",
"root": "090bcaf734c4f06c93954a827b45a6e8c67b8e0fd1e0a35a1c5982d6961828f9",
"proof": "0x1b24bf0ece10786a2307e121b48c2c90c4b07641f81b773502cb132296a837c61c37e1fb4402606cacf385295f7b4832d2222f9ecd9803d022c09fb159e8af8f0fd2cb1fceb65e32058b0f7e04734682cca35b917098b6e0a95aeb02f69272c4168899e7867a5ddfa8246ec4fe35a0e2d2ac85355a26b2490ed78aea20a2869a115b66835ee849fa9fbd3462138bccb3092b4f4cb8cdd5af495ae5ab06f0e1a00c043787dcda55e88dca9a6b845806f626b29c0d191aaf48ae93d00e02ffda7a2680eaf720b34b00aa4477b6b9b4512e0cc94b2df5a865a6c0cb491bdc834f5800c80881e1ce55a364dcce58fb1daaaf9f5986845036b1831024e03072a3ac56051d6c07a287a27414da42ba86bf42cc9d0ef7f17ebb1226f6b263086c2d77b910466c8d8b6675c0d0fce875f6b594722ad5bdaeeca7d4b673467adf065cf00d2f2ecdf78010fe75f1212dd9c6540c96a6e1eb11530290e966699018c1e41d7b07e3a1a08cb13adcf536851e5f58e33f464321118b67f8c80db338733c3bda72039aa214dfe5015f117b6f876b018199424510024b2946bb5f8027245225ff8b240237bdef147c509f04f33a09da19549a27411430c059cd1376f2706549b6671694bb18973c35c9fe8cc4d40f08c60aca4c277ddf09eb2e095556f3c3156ba51550b6a94fd21d4540764d093fb39e4e6c4517bd4ccc87c21f08fdd4588ff27b032cbbfb8c6a8cd431524521677d40aed6700eac960e2ca5f66c6f19cbcbe1af16f962c9e5eae242aab756079cee9a1419474da4e3f5d531f70738e6dac99dd40858cee714f519e6af127d3c57553c1e3ace3206dc24866f6dce3b6a9fa99ced10ef7440dc5227ab24c05201207fdfeb341fbe716f2a969c9663d6b2188c25271abff2b7c68177be370f2d804306693461a5f749de729433ad45e6eff0b692e216c9216e5596d7a39e5971c5bcfed0cebb520014059ec9ade2c7a1196d967f4121aa5603cda863fbda14a380853fdac1e09de824fc8bb65c29ef2fd78d32aa8e24bef20ab27682cd82dcaee11a478bc5f9da361d87262686b1b2d91f135a10d3120954d3a8f3f5c14c069730d0c9bfc2bb86f7cd6a106e294f1ecddd3543b7110bc67355e1fc211b968f314ebcf9ea8352a01d0b9a1bbaac88457409b49388ac189007a6b62c2839220edd1f012ff5331baec07c4077522fce86fd3b8931e8a4",
"new_acc_hash": "1afd6eaf13538380d99a245c2acc4a25481b54556ae080cf07d1facc0638cd8e",
"new_local_exit_root": "17c04c3760510b48c6012742c540a81aba4bca2f78b9d14bfd2f123e2e53ea3e"
}
Loading

0 comments on commit a320c1a

Please sign in to comment.