| 52 | }; |
| 53 | |
| 54 | pub fn prove() { |
| 55 | // Parse command-line arguments |
| 56 | let args: Vec<String> = env::args().collect(); |
| 57 | if args.len() < 4 { |
| 58 | eprintln!("Usage: <program> <input_proof> <output_file_path> <batch_size>"); |
| 59 | return; |
| 60 | } |
| 61 | |
| 62 | let input_proof = &args[1]; |
| 63 | let output_file_path = &args[2]; |
| 64 | let batch_size: usize = args[3].parse().expect("Batch size should be a number"); |
| 65 | |
| 66 | let headers = HEADERS |
| 67 | .chunks(80) |
| 68 | .map(|header| CircuitBlockHeader::try_from_slice(header).unwrap()) |
| 69 | .collect::<Vec<CircuitBlockHeader>>(); |
| 70 | |
| 71 | let HEADER_CHAIN_GUEST_ID: [u32; 8] = compute_image_id(HEADER_CHAIN_GUEST_ELF) |
| 72 | .unwrap() |
| 73 | .as_words() |
| 74 | .try_into() |
| 75 | .unwrap(); |
| 76 | |
| 77 | // Set the previous proof type based on input_proof argument |
| 78 | let prev_receipt = if input_proof.to_lowercase() == "none" { |
| 79 | None |
| 80 | } else { |
| 81 | let proof_bytes = fs::read(input_proof).expect("Failed to read input proof file"); |
| 82 | let receipt: Receipt = Receipt::try_from_slice(&proof_bytes).unwrap(); |
| 83 | Some(receipt) |
| 84 | }; |
| 85 | |
| 86 | let mut start = 0; |
| 87 | let prev_proof = match prev_receipt.clone() { |
| 88 | Some(receipt) => { |
| 89 | let output = |
| 90 | BlockHeaderCircuitOutput::try_from_slice(&receipt.journal.bytes.clone()).unwrap(); |
| 91 | start = output.chain_state.block_height as usize + 1; |
| 92 | HeaderChainPrevProofType::PrevProof(output) |
| 93 | } |
| 94 | None => HeaderChainPrevProofType::GenesisBlock, |
| 95 | }; |
| 96 | |
| 97 | // Prepare the input for the circuit |
| 98 | let input = HeaderChainCircuitInput { |
| 99 | method_id: HEADER_CHAIN_GUEST_ID, |
| 100 | prev_proof, |
| 101 | block_headers: headers[start..start + batch_size].to_vec(), |
| 102 | }; |
| 103 | |
| 104 | // Build ENV |
| 105 | let mut binding = ExecutorEnv::builder(); |
| 106 | let mut env = binding.write_slice(&borsh::to_vec(&input).unwrap()); |
| 107 | if let Some(receipt) = prev_receipt { |
| 108 | env = env.add_assumption(receipt); |
| 109 | } |
| 110 | let env = env.build().unwrap(); |
| 111 | |