1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
use anyhow::bail;
use anyhow::Result;
use std::env;
use std::fs::read;
use std::time::Instant;
use zkm_sdk::{prover::ClientCfg, prover::{ProverInput, ProverResult} , ProverClient};
use zkvms_host_io::{read_args, RunType::{ Execute, Prove, Verify }};
async fn get_proof(
prover_client: &mut ProverClient,
prover_input: &mut ProverInput,
) -> ProverResult {
let proving_result = prover_client.prover.prove(&prover_input, None).await;
if let Ok(Some(prover_result)) = proving_result {
prover_result
}
else {
panic!("Failed to generate proof!");
}
}
async fn execute(
prover_client: &mut ProverClient,
prover_input: &mut ProverInput,
) {
prover_input.execute_only = true;
let prover_result = get_proof(prover_client, prover_input).await;
prover_client
.print_guest_execution_output(false, &prover_result)
.expect("print guest program excution's output false.")
}
async fn prove(
prover_client: &mut ProverClient,
prover_input: &mut ProverInput,
vk_path: &String,
proof_results_path: &String,
) {
prover_input.execute_only = false;
match prover_client
.setup_and_generate_sol_verifier("local", &vk_path, &prover_input)
.await
{
Ok(()) => println!("Succussfully setup_and_generate_sol_verifier."),
Err(e) => panic!("Error during setup_and_generate_sol_verifier: {}", e),
}
let prover_result = get_proof(prover_client, prover_input).await;
prover_client
.process_proof_results(
&prover_result,
&prover_input,
&proof_results_path,
"local",
)
.expect("process proof results error");
}
#[tokio::main]
async fn main() -> Result<()> {
let run_info = read_args();
if run_info.run_type == Verify {
panic!("Off-chain verification is not supported!");
}
let seg_size = env::var("SEG_SIZE")
.ok()
.and_then(|seg| seg.parse::<u32>().ok())
.unwrap_or(8192);
let elf_path = env::var("ELF_PATH").expect("ELF PATH is missing");
let proof_results_path = env::var("PROOF_RESULTS_PATH").unwrap_or("/tmp/contracts".to_string());
let vk_path = env::var("VERIFYING_KEY_PATH").unwrap_or("/tmp/input".to_string());
let mut client_config: ClientCfg =
ClientCfg::new("local".to_string(), vk_path.to_owned());
let mut prover_client = ProverClient::new(&client_config).await;
// Set input
let mut public_inputstream = Vec::new();
bincode::serialize_into(&mut public_inputstream, &run_info.input)
.expect("private_input serialization failed");
let mut prover_input = ProverInput {
elf: read(elf_path).unwrap(),
seg_size,
public_inputstream,
..Default::default()
};
let start = Instant::now();
match run_info.run_type {
// only excute the guest program without generating the proof.
Execute => execute(&mut prover_client, &mut prover_input).await,
// excute the guest program and generate the proof
Prove => prove(&mut prover_client, &mut prover_input, &vk_path, &proof_results_path).await,
Verify => unreachable!(),
}
let end = Instant::now();
let elapsed = end.duration_since(start);
println!("Elapsed time: {:?} secs", elapsed.as_secs());
Ok(())
}
|