Skip to content

Commit 0762618

Browse files
keroro520smtmfft
andauthored
feat: impl zkvm support for pacaya (#526)
* feat(provers): add zkvm support for batch requests * chore(provers): update elf * feat(host): enable zk_any for batch API * chore: cargo fmt * fix(host): remove zk_any opts from request * chore(host): add logs * fix(reqactor): return early for wip,success task * feat(provers/sp1): hardcode sp1_proof_mode * feat(host): fill batch_id into response of batch-request * fix(host): remove fulfill_sp1_params * chore(host/config): deprecate sp1_params.recursion --------- Co-authored-by: smtmfft <[email protected]>
1 parent 72aa660 commit 0762618

28 files changed

+454
-93
lines changed

host/config/config.devnet.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@
3030
"execution_po2": 20
3131
},
3232
"sp1": {
33-
"recursion": "core",
3433
"prover": "network",
3534
"verify": false
3635
},
3736
"native": {
3837
"json_guest_input": null
3938
}
40-
}
39+
}

host/config/config.json

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
"execution_po2": 20
2121
},
2222
"sp1": {
23-
"recursion": "core",
2423
"prover": "network",
2524
"verify": false
2625
},

host/config/config.sgx.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@
3030
"verify": true
3131
},
3232
"sp1": {
33-
"recursion": "core",
3433
"prover": "network",
3534
"verify": true
3635
},
3736
"native": {
3837
"json_guest_input": null
3938
}
40-
}
39+
}

host/config/config.taiko_hekla.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"execution_po2": 20
1818
},
1919
"sp1": {
20-
"recursion": "core",
2120
"prover": "network",
2221
"verify": true
2322
},
@@ -33,4 +32,4 @@
3332
"native": {
3433
"json_guest_input": null
3534
}
36-
}
35+
}

host/config/config.taiko_mainnet.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"execution_po2": 20
1818
},
1919
"sp1": {
20-
"recursion": "core",
2120
"prover": "network",
2221
"verify": true
2322
},
@@ -33,4 +32,4 @@
3332
"native": {
3433
"json_guest_input": null
3534
}
36-
}
35+
}

host/src/server/api/v2/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ pub enum Status {
6969
Ok {
7070
#[serde(with = "raiko_lib::proof_type::lowercase")]
7171
proof_type: ProofType,
72+
#[serde(skip_serializing_if = "Option::is_none")]
73+
batch_id: Option<u64>,
7274
data: ProofResponse,
7375
},
7476
Error {

host/src/server/api/v2/proof/mod.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use raiko_tasks::TaskStatus;
99
use serde_json::Value;
1010
use utoipa::OpenApi;
1111

12-
use crate::server::utils::{draw_for_zk_any_request, fulfill_sp1_params, is_zk_any_request};
12+
use crate::server::utils::{draw_for_zk_any_request, is_zk_any_request};
1313
use crate::{
1414
interfaces::HostResult,
1515
metrics::{inc_current_req, inc_guest_req_count, inc_host_req_count},
@@ -39,16 +39,9 @@ pub mod report;
3939
/// - sgx - uses the sgx environment to construct a block and produce proof of execution
4040
/// - sp1 - uses the sp1 prover
4141
/// - risc0 - uses the risc0 prover
42-
async fn proof_handler(
43-
State(actor): State<Actor>,
44-
Json(mut req): Json<Value>,
45-
) -> HostResult<Status> {
42+
async fn proof_handler(State(actor): State<Actor>, Json(req): Json<Value>) -> HostResult<Status> {
4643
inc_current_req();
4744

48-
if is_zk_any_request(&req) {
49-
fulfill_sp1_params(&mut req);
50-
}
51-
5245
// Override the existing proof request config from the config file and command line
5346
// options with the request from the client.
5447
let mut config = actor.default_request_config().clone();
@@ -61,6 +54,7 @@ async fn proof_handler(
6154
None => {
6255
return Ok(Status::Ok {
6356
proof_type: ProofType::Native,
57+
batch_id: None,
6458
data: ProofResponse::Status {
6559
status: TaskStatus::ZKAnyNotDrawn,
6660
},
@@ -126,10 +120,10 @@ async fn proof_handler(
126120
.into();
127121

128122
let result = crate::server::prove(&actor, request_key, request_entity).await;
129-
Ok(to_v2_status(proof_type, result))
123+
Ok(to_v2_status(proof_type, None, result))
130124
}
131-
Ok(_) => Ok(to_v2_status(proof_type, result)),
132-
Err(_) => Ok(to_v2_status(proof_type, result)),
125+
Ok(_) => Ok(to_v2_status(proof_type, None, result)),
126+
Err(_) => Ok(to_v2_status(proof_type, None, result)),
133127
}
134128
}
135129

host/src/server/api/v3/proof/aggregate/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ async fn aggregation_handler(
6767
.into();
6868

6969
let result = crate::server::prove(&actor, agg_request_key, agg_request_entity).await;
70-
Ok(to_v3_status(proof_type, result))
70+
Ok(to_v3_status(proof_type, None, result))
7171
}
7272

7373
#[derive(OpenApi)]

host/src/server/api/v3/proof/batch.rs

+42-11
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ use crate::{
44
api::v3::{ProofResponse, Status},
55
handler::prove_many,
66
prove_aggregation,
7-
utils::{is_zk_any_request, to_v3_status},
7+
utils::{draw_for_zk_any_batch_request, is_zk_any_request, to_v3_status},
88
},
99
};
1010
use axum::{extract::State, routing::post, Json, Router};
1111
use raiko_core::{
12-
interfaces::{BatchMetadata, BatchProofRequest, BatchProofRequestOpt},
12+
interfaces::{BatchMetadata, BatchProofRequest, BatchProofRequestOpt, RaikoError},
1313
merge,
1414
};
1515
use raiko_lib::{proof_type::ProofType, prover::Proof};
@@ -41,20 +41,46 @@ async fn batch_handler(
4141
State(actor): State<Actor>,
4242
Json(batch_request_opt): Json<Value>,
4343
) -> HostResult<Status> {
44-
if is_zk_any_request(&batch_request_opt) {
45-
return Ok(Status::Ok {
46-
proof_type: ProofType::Native,
47-
data: ProofResponse::Status {
48-
status: TaskStatus::ZKAnyNotDrawn,
49-
},
50-
});
51-
}
44+
tracing::debug!(
45+
"Received batch request: {}",
46+
serde_json::to_string(&batch_request_opt)?
47+
);
5248

5349
let batch_request = {
5450
// Override the existing proof request config from the config file and command line
5551
// options with the request from the client, and convert to a BatchProofRequest.
5652
let mut opts = serde_json::to_value(actor.default_request_config())?;
5753
merge(&mut opts, &batch_request_opt);
54+
55+
let first_batch_id = {
56+
let batches = opts["batches"]
57+
.as_array()
58+
.ok_or(RaikoError::InvalidRequestConfig(
59+
"Missing batches".to_string(),
60+
))?;
61+
let first_batch = batches.first().ok_or(RaikoError::InvalidRequestConfig(
62+
"batches is empty".to_string(),
63+
))?;
64+
let first_batch_id = first_batch["batch_id"].as_u64().expect("checked above");
65+
first_batch_id
66+
};
67+
68+
// For zk_any request, draw zk proof type based on the block hash.
69+
if is_zk_any_request(&opts) {
70+
match draw_for_zk_any_batch_request(&actor, &opts).await? {
71+
Some(proof_type) => opts["proof_type"] = serde_json::to_value(proof_type).unwrap(),
72+
None => {
73+
return Ok(Status::Ok {
74+
proof_type: ProofType::Native,
75+
batch_id: Some(first_batch_id),
76+
data: ProofResponse::Status {
77+
status: TaskStatus::ZKAnyNotDrawn,
78+
},
79+
});
80+
}
81+
}
82+
}
83+
5884
let batch_request_opt: BatchProofRequestOpt = serde_json::from_value(opts)?;
5985
let batch_request: BatchProofRequest = batch_request_opt.try_into()?;
6086

@@ -188,7 +214,12 @@ async fn batch_handler(
188214
})
189215
}
190216
};
191-
Ok(to_v3_status(batch_request.proof_type, result))
217+
tracing::debug!("Batch proof result: {}", serde_json::to_string(&result)?);
218+
Ok(to_v3_status(
219+
batch_request.proof_type,
220+
Some(batch_request.batches.first().unwrap().batch_id),
221+
result,
222+
))
192223
}
193224

194225
#[derive(OpenApi)]

host/src/server/api/v3/proof/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ async fn proof_handler(
115115
sub_request_entities,
116116
)
117117
.await;
118-
Ok(to_v3_status(proof_type, result))
118+
Ok(to_v3_status(proof_type, None, result))
119119
}
120120

121121
#[derive(OpenApi)]

host/src/server/utils.rs

+37-28
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ use raiko_reqpool::Status;
99
use raiko_tasks::TaskStatus;
1010
use serde_json::Value;
1111

12-
pub fn to_v2_status(proof_type: ProofType, result: Result<Status, String>) -> v2::Status {
12+
pub fn to_v2_status(
13+
proof_type: ProofType,
14+
batch_id: Option<u64>,
15+
result: Result<Status, String>,
16+
) -> v2::Status {
1317
match result {
1418
Ok(status) => v2::Status::Ok {
1519
proof_type,
20+
batch_id,
1621
data: {
1722
match status {
1823
Status::Registered => v2::ProofResponse::Status {
@@ -57,8 +62,12 @@ pub fn to_v2_cancel_status(result: Result<Status, String>) -> v2::CancelStatus {
5762
}
5863

5964
// TODO: remove the staled interface
60-
pub fn to_v3_status(proof_type: ProofType, result: Result<Status, String>) -> v3::Status {
61-
to_v2_status(proof_type, result)
65+
pub fn to_v3_status(
66+
proof_type: ProofType,
67+
batch_id: Option<u64>,
68+
result: Result<Status, String>,
69+
) -> v3::Status {
70+
to_v2_status(proof_type, batch_id, result)
6271
}
6372

6473
pub fn to_v3_cancel_status(result: Result<Status, String>) -> v3::CancelStatus {
@@ -90,29 +99,29 @@ pub async fn draw_for_zk_any_request(
9099
Ok(actor.draw(&blockhash))
91100
}
92101

93-
pub fn fulfill_sp1_params(req: &mut Value) {
94-
let zk_any_opts = req["zk_any"].as_object().clone();
95-
let sp1_recursion = match zk_any_opts {
96-
None => serde_json::Value::String("plonk".to_string()),
97-
Some(zk_any) => {
98-
let aggregation = zk_any["aggregation"].as_bool().unwrap_or(false);
99-
if aggregation {
100-
serde_json::Value::String("compressed".to_string())
101-
} else {
102-
serde_json::Value::String("plonk".to_string())
103-
}
104-
}
105-
};
106-
107-
let sp1_opts = req["sp1"].as_object_mut();
108-
match sp1_opts {
109-
None => {
110-
let mut sp1_opts = serde_json::Map::new();
111-
sp1_opts.insert("recursion".to_string(), sp1_recursion);
112-
req["sp1"] = serde_json::Value::Object(sp1_opts);
113-
}
114-
Some(sp1_opts) => {
115-
sp1_opts.insert("recursion".to_string(), sp1_recursion);
116-
}
117-
}
102+
pub async fn draw_for_zk_any_batch_request(
103+
actor: &Actor,
104+
batch_proof_request_opt: &Value,
105+
) -> HostResult<Option<ProofType>> {
106+
let l1_network =
107+
batch_proof_request_opt["l1_network"]
108+
.as_str()
109+
.ok_or(RaikoError::InvalidRequestConfig(
110+
"Missing network".to_string(),
111+
))?;
112+
let batches =
113+
batch_proof_request_opt["batches"]
114+
.as_array()
115+
.ok_or(RaikoError::InvalidRequestConfig(
116+
"Missing batches".to_string(),
117+
))?;
118+
let first_batch = batches.first().ok_or(RaikoError::InvalidRequestConfig(
119+
"batches is empty".to_string(),
120+
))?;
121+
let l1_inclusion_block_number = first_batch["l1_inclusion_block_number"].as_u64().ok_or(
122+
RaikoError::InvalidRequestConfig("Missing l1_inclusion_block_number".to_string()),
123+
)?;
124+
let (_, blockhash) =
125+
get_task_data(&l1_network, l1_inclusion_block_number, actor.chain_specs()).await?;
126+
Ok(actor.draw(&blockhash))
118127
}

provers/risc0/builder/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::path::PathBuf;
66
fn main() {
77
let pipeline = Risc0Pipeline::new("provers/risc0/guest", "release");
88
pipeline.bins(
9-
&["risc0-guest", "risc0-aggregation"],
9+
&["risc0-guest", "risc0-aggregation", "risc0-batch"],
1010
"provers/risc0/driver/src/methods",
1111
);
1212
#[cfg(feature = "test")]

provers/risc0/driver/src/bonsai.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::{
2-
methods::risc0_guest::RISC0_GUEST_ID,
32
snarks::{stark2snark, verify_groth16_from_snark_receipt},
43
Risc0Response,
54
};
@@ -313,8 +312,10 @@ pub async fn bonsai_stark_to_snark(
313312
stark_uuid: String,
314313
stark_receipt: Receipt,
315314
input: B256,
315+
elf: &[u8],
316316
) -> ProverResult<Risc0Response> {
317-
let image_id = Digest::from(RISC0_GUEST_ID);
317+
let image_id = risc0_zkvm::compute_image_id(elf)
318+
.map_err(|e| ProverError::GuestError(format!("Failed to compute image id: {e:?}")))?;
318319
let (snark_uuid, snark_receipt) = stark2snark(
319320
image_id,
320321
stark_uuid.clone(),

0 commit comments

Comments
 (0)