|
| 1 | +pub mod proofs; |
| 2 | +pub mod tasks; |
| 3 | +pub mod verifier; |
| 4 | +pub use verifier::{TaskType, VerifierConfig}; |
1 | 5 | mod utils; |
2 | | -mod verifier; |
3 | | - |
4 | | -use std::{ |
5 | | - ffi::{c_char, c_int, CString}, |
6 | | - path::Path, |
7 | | -}; |
8 | | - |
9 | | -use crate::utils::{c_char_to_str, c_char_to_vec}; |
10 | | -use verifier::{TaskType, VerifierConfig}; |
11 | | - |
12 | | -/// # Safety |
13 | | -#[no_mangle] |
14 | | -pub unsafe extern "C" fn init_verifier(config: *const c_char) { |
15 | | - let config_str = c_char_to_str(config); |
16 | | - let verifier_config = serde_json::from_str::<VerifierConfig>(config_str).unwrap(); |
17 | | - verifier::init(verifier_config); |
18 | | -} |
19 | 6 |
|
20 | | -/// # Safety |
21 | | -#[no_mangle] |
22 | | -pub unsafe extern "C" fn verify_chunk_proof( |
23 | | - proof: *const c_char, |
24 | | - fork_name: *const c_char, |
25 | | -) -> c_char { |
26 | | - verify_proof(proof, fork_name, TaskType::Chunk) |
| 7 | +use sbv_primitives::B256; |
| 8 | +use scroll_zkvm_types::util::vec_as_base64; |
| 9 | +use serde::{Deserialize, Serialize}; |
| 10 | +use serde_json::value::RawValue; |
| 11 | +use std::path::Path; |
| 12 | +use tasks::chunk_interpreter::{ChunkInterpreter, TryFromWithInterpreter}; |
| 13 | + |
| 14 | +/// Turn the coordinator's chunk task into a json string for formal chunk proving |
| 15 | +/// task (with full witnesses) |
| 16 | +pub fn checkout_chunk_task( |
| 17 | + task_json: &str, |
| 18 | + interpreter: impl ChunkInterpreter, |
| 19 | +) -> eyre::Result<String> { |
| 20 | + let chunk_task = serde_json::from_str::<tasks::ChunkTask>(task_json)?; |
| 21 | + let ret = serde_json::to_string(&tasks::ChunkProvingTask::try_from_with_interpret( |
| 22 | + chunk_task, |
| 23 | + interpreter, |
| 24 | + )?)?; |
| 25 | + Ok(ret) |
27 | 26 | } |
28 | 27 |
|
29 | | -fn verify_proof(proof: *const c_char, fork_name: *const c_char, task_type: TaskType) -> c_char { |
30 | | - let fork_name_str = c_char_to_str(fork_name); |
31 | | - let proof = c_char_to_vec(proof); |
32 | | - let verifier = verifier::get_verifier(fork_name_str); |
33 | | - |
34 | | - if let Err(e) = verifier { |
35 | | - log::warn!("failed to get verifier, error: {:#}", e); |
36 | | - return 0 as c_char; |
| 28 | +/// Generate required staff for proving tasks |
| 29 | +pub fn gen_universal_task( |
| 30 | + task_type: i32, |
| 31 | + task_json: &str, |
| 32 | + fork_name: &str, |
| 33 | + interpreter: Option<impl ChunkInterpreter>, |
| 34 | +) -> eyre::Result<(B256, String, String)> { |
| 35 | + use proofs::*; |
| 36 | + use tasks::*; |
| 37 | + |
| 38 | + /// Wrapper for metadata |
| 39 | + #[derive(Clone, Debug, Serialize, Deserialize)] |
| 40 | + #[serde(untagged)] |
| 41 | + enum AnyMetaData { |
| 42 | + Chunk(ChunkProofMetadata), |
| 43 | + Batch(BatchProofMetadata), |
| 44 | + Bundle(BundleProofMetadata), |
37 | 45 | } |
38 | | - match verifier.unwrap().verify(task_type, proof) { |
39 | | - Err(e) => { |
40 | | - log::error!("{:?} verify failed, error: {:#}", task_type, e); |
41 | | - false as c_char |
42 | | - } |
43 | | - Ok(result) => result as c_char, |
44 | | - } |
45 | | -} |
46 | 46 |
|
47 | | -/// # Safety |
48 | | -#[no_mangle] |
49 | | -pub unsafe extern "C" fn verify_batch_proof( |
50 | | - proof: *const c_char, |
51 | | - fork_name: *const c_char, |
52 | | -) -> c_char { |
53 | | - verify_proof(proof, fork_name, TaskType::Batch) |
54 | | -} |
55 | | - |
56 | | -/// # Safety |
57 | | -#[no_mangle] |
58 | | -pub unsafe extern "C" fn verify_bundle_proof( |
59 | | - proof: *const c_char, |
60 | | - fork_name: *const c_char, |
61 | | -) -> c_char { |
62 | | - verify_proof(proof, fork_name, TaskType::Bundle) |
| 47 | + let (pi_hash, metadata, u_task) = match task_type { |
| 48 | + x if x == TaskType::Chunk as i32 => { |
| 49 | + let task = serde_json::from_str::<ChunkProvingTask>(task_json)?; |
| 50 | + let (pi_hash, metadata, u_task) = |
| 51 | + gen_universal_chunk_task(task, fork_name.into(), interpreter)?; |
| 52 | + (pi_hash, AnyMetaData::Chunk(metadata), u_task) |
| 53 | + } |
| 54 | + x if x == TaskType::Batch as i32 => { |
| 55 | + let task = serde_json::from_str::<BatchProvingTask>(task_json)?; |
| 56 | + let (pi_hash, metadata, u_task) = gen_universal_batch_task(task, fork_name.into())?; |
| 57 | + (pi_hash, AnyMetaData::Batch(metadata), u_task) |
| 58 | + } |
| 59 | + x if x == TaskType::Bundle as i32 => { |
| 60 | + let task = serde_json::from_str::<BundleProvingTask>(task_json)?; |
| 61 | + let (pi_hash, metadata, u_task) = gen_universal_bundle_task(task, fork_name.into())?; |
| 62 | + (pi_hash, AnyMetaData::Bundle(metadata), u_task) |
| 63 | + } |
| 64 | + _ => return Err(eyre::eyre!("unrecognized task type {task_type}")), |
| 65 | + }; |
| 66 | + |
| 67 | + Ok(( |
| 68 | + pi_hash, |
| 69 | + serde_json::to_string(&metadata)?, |
| 70 | + serde_json::to_string(&u_task)?, |
| 71 | + )) |
63 | 72 | } |
64 | 73 |
|
65 | | -/// # Safety |
66 | | -#[no_mangle] |
67 | | -pub unsafe extern "C" fn dump_vk(fork_name: *const c_char, file: *const c_char) { |
68 | | - _dump_vk(fork_name, file); |
69 | | -} |
| 74 | +/// helper to rearrange the proof return by universal prover into corresponding wrapped proof |
| 75 | +pub fn gen_wrapped_proof(proof_json: &str, metadata: &str, vk: &[u8]) -> eyre::Result<String> { |
| 76 | + #[derive(Serialize)] |
| 77 | + struct RearrangeWrappedProofJson<'a> { |
| 78 | + #[serde(borrow)] |
| 79 | + pub metadata: &'a RawValue, |
| 80 | + #[serde(borrow)] |
| 81 | + pub proof: &'a RawValue, |
| 82 | + #[serde(with = "vec_as_base64", default)] |
| 83 | + pub vk: Vec<u8>, |
| 84 | + pub git_version: String, |
| 85 | + } |
70 | 86 |
|
71 | | -fn _dump_vk(fork_name: *const c_char, file: *const c_char) { |
72 | | - let fork_name_str = c_char_to_str(fork_name); |
73 | | - let verifier = verifier::get_verifier(fork_name_str); |
| 87 | + let re_arrange = RearrangeWrappedProofJson { |
| 88 | + metadata: serde_json::from_str(metadata)?, |
| 89 | + proof: serde_json::from_str(proof_json)?, |
| 90 | + vk: vk.to_vec(), |
| 91 | + git_version: utils::short_git_version(), |
| 92 | + }; |
74 | 93 |
|
75 | | - if let Ok(verifier) = verifier { |
76 | | - verifier.as_ref().dump_vk(Path::new(c_char_to_str(file))); |
77 | | - } |
| 94 | + let ret = serde_json::to_string(&re_arrange)?; |
| 95 | + Ok(ret) |
78 | 96 | } |
79 | 97 |
|
80 | | -/// Represents the result of generating a universal task |
81 | | -#[repr(C)] |
82 | | -pub struct HandlingResult { |
83 | | - pub ok: bool, |
84 | | - pub universal_task: *mut c_char, |
85 | | - pub metadata: *mut c_char, |
86 | | - pub expected_pi_hash: [u8; 32], |
| 98 | +/// init verifier |
| 99 | +pub fn verifier_init(config: &str) -> eyre::Result<()> { |
| 100 | + let cfg: VerifierConfig = serde_json::from_str(config)?; |
| 101 | + verifier::init(cfg); |
| 102 | + Ok(()) |
87 | 103 | } |
88 | 104 |
|
89 | | -/// # Safety |
90 | | -#[no_mangle] |
91 | | -pub unsafe extern "C" fn gen_universal_task( |
92 | | - _task_type: c_int, |
93 | | - _task: *const c_char, |
94 | | - _fork_name: *const c_char, |
95 | | -) -> HandlingResult { |
96 | | - unimplemented!("implementation will be added in later PRs"); |
97 | | -} |
| 105 | +/// verify proof |
| 106 | +pub fn verify_proof(proof: Vec<u8>, fork_name: &str, task_type: TaskType) -> eyre::Result<bool> { |
| 107 | + let verifier = verifier::get_verifier(fork_name)?; |
98 | 108 |
|
99 | | -/// # Safety |
100 | | -#[no_mangle] |
101 | | -pub unsafe extern "C" fn release_task_result(result: HandlingResult) { |
102 | | - // Free the allocated strings |
103 | | - if !result.universal_task.is_null() { |
104 | | - let _ = CString::from_raw(result.universal_task); |
105 | | - } |
| 109 | + let ret = verifier.verify(task_type, proof)?; |
106 | 110 |
|
107 | | - if !result.metadata.is_null() { |
108 | | - let _ = CString::from_raw(result.metadata); |
109 | | - } |
| 111 | + Ok(ret) |
110 | 112 | } |
111 | 113 |
|
112 | | -/// # Safety |
113 | | -#[no_mangle] |
114 | | -pub unsafe extern "C" fn gen_wrapped_proof( |
115 | | - _proof_json: *const c_char, |
116 | | - _metadata: *const c_char, |
117 | | - _vk: *const c_char, |
118 | | - _vk_len: usize, |
119 | | -) -> *mut c_char { |
120 | | - unimplemented!("implementation will be added in later PRs"); |
121 | | -} |
| 114 | +/// dump vk |
| 115 | +pub fn dump_vk(fork_name: &str, file: &str) -> eyre::Result<()> { |
| 116 | + let verifier = verifier::get_verifier(fork_name)?; |
122 | 117 |
|
123 | | -/// # Safety |
124 | | -#[no_mangle] |
125 | | -pub unsafe extern "C" fn release_string(string_ptr: *mut c_char) { |
126 | | - if !string_ptr.is_null() { |
127 | | - let _ = CString::from_raw(string_ptr); |
128 | | - } |
129 | | -} |
| 118 | + verifier.dump_vk(Path::new(file)); |
130 | 119 |
|
131 | | -/// # Safety |
132 | | -#[no_mangle] |
133 | | -pub unsafe extern "C" fn init_l2geth(_config: *const c_char) { |
134 | | - unimplemented!("implementation will be added in later PRs"); |
| 120 | + Ok(()) |
135 | 121 | } |
0 commit comments