1use std::{
2 fs::{create_dir_all, read, write, File},
3 path::Path,
4};
5
6use eyre::Result;
7use openvm_circuit::arch::{instructions::exe::VmExe, ContinuationVmProof, VmConfig};
8use openvm_continuations::verifier::root::types::RootVmVerifierInput;
9use openvm_native_recursion::halo2::wrapper::{EvmVerifier, EvmVerifierByteCode};
10use serde::{de::DeserializeOwned, Serialize};
11
12use crate::{
13 codec::{Decode, Encode},
14 keygen::{AggProvingKey, AppProvingKey, AppVerifyingKey},
15 types::EvmProof,
16 F, SC,
17};
18
19pub const EVM_VERIFIER_SOL_FILENAME: &str = "verifier.sol";
20pub const EVM_VERIFIER_ARTIFACT_FILENAME: &str = "verifier.bytecode.json";
21
22pub fn read_exe_from_file<P: AsRef<Path>>(path: P) -> Result<VmExe<F>> {
23 read_from_file_bitcode(path)
24}
25
26pub fn write_exe_to_file<P: AsRef<Path>>(exe: VmExe<F>, path: P) -> Result<()> {
27 write_to_file_bitcode(path, exe)
28}
29
30pub fn read_app_pk_from_file<VC: VmConfig<F>, P: AsRef<Path>>(
31 path: P,
32) -> Result<AppProvingKey<VC>> {
33 read_from_file_bitcode(path)
34}
35
36pub fn write_app_pk_to_file<VC: VmConfig<F>, P: AsRef<Path>>(
37 app_pk: AppProvingKey<VC>,
38 path: P,
39) -> Result<()> {
40 write_to_file_bitcode(path, app_pk)
41}
42
43pub fn read_app_vk_from_file<P: AsRef<Path>>(path: P) -> Result<AppVerifyingKey> {
44 read_from_file_bitcode(path)
45}
46
47pub fn write_app_vk_to_file<P: AsRef<Path>>(app_vk: AppVerifyingKey, path: P) -> Result<()> {
48 write_to_file_bitcode(path, app_vk)
49}
50
51pub fn read_app_proof_from_file<P: AsRef<Path>>(path: P) -> Result<ContinuationVmProof<SC>> {
52 decode_from_file(path)
53}
54
55pub fn write_app_proof_to_file<P: AsRef<Path>>(
56 proof: ContinuationVmProof<SC>,
57 path: P,
58) -> Result<()> {
59 encode_to_file(path, proof)
60}
61
62pub fn read_root_verifier_input_from_file<P: AsRef<Path>>(
63 path: P,
64) -> Result<RootVmVerifierInput<SC>> {
65 decode_from_file(path)
66}
67
68pub fn write_root_verifier_input_to_file<P: AsRef<Path>>(
69 input: RootVmVerifierInput<SC>,
70 path: P,
71) -> Result<()> {
72 encode_to_file(path, input)
73}
74
75pub fn read_agg_pk_from_file<P: AsRef<Path>>(path: P) -> Result<AggProvingKey> {
76 read_from_file_bitcode(path)
77}
78
79pub fn write_agg_pk_to_file<P: AsRef<Path>>(agg_pk: AggProvingKey, path: P) -> Result<()> {
80 write_to_file_bitcode(path, agg_pk)
81}
82
83pub fn read_evm_proof_from_file<P: AsRef<Path>>(path: P) -> Result<EvmProof> {
84 let proof: EvmProof = serde_json::from_reader(File::open(path)?)?;
85 Ok(proof)
86}
87
88pub fn write_evm_proof_to_file<P: AsRef<Path>>(proof: EvmProof, path: P) -> Result<()> {
89 serde_json::to_writer(File::create(path)?, &proof)?;
90 Ok(())
91}
92
93pub fn read_evm_verifier_from_folder<P: AsRef<Path>>(folder: P) -> Result<EvmVerifier> {
94 let sol_code_path = folder.as_ref().join(EVM_VERIFIER_SOL_FILENAME);
95 let sol_code = std::fs::read_to_string(sol_code_path)?;
96 let artifact_path = folder.as_ref().join(EVM_VERIFIER_ARTIFACT_FILENAME);
97 let artifact: EvmVerifierByteCode = serde_json::from_reader(File::open(artifact_path)?)?;
98 Ok(EvmVerifier { sol_code, artifact })
99}
100
101pub fn write_evm_verifier_to_folder<P: AsRef<Path>>(
102 verifier: EvmVerifier,
103 folder: P,
104) -> Result<()> {
105 let sol_code_path = folder.as_ref().join(EVM_VERIFIER_SOL_FILENAME);
106 std::fs::write(sol_code_path, verifier.sol_code)?;
107 let artifact_path = folder.as_ref().join(EVM_VERIFIER_ARTIFACT_FILENAME);
108 serde_json::to_writer(File::create(artifact_path)?, &verifier.artifact)?;
109 Ok(())
110}
111
112pub fn read_object_from_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T> {
113 read_from_file_bitcode(path)
114}
115
116pub fn write_object_to_file<T: Serialize, P: AsRef<Path>>(path: P, data: T) -> Result<()> {
117 write_to_file_bitcode(path, data)
118}
119
120pub(crate) fn read_from_file_bitcode<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T> {
121 let data = std::fs::read(path)?;
122 let ret = bitcode::deserialize(&data)?;
123 Ok(ret)
124}
125
126pub(crate) fn write_to_file_bitcode<T: Serialize, P: AsRef<Path>>(path: P, data: T) -> Result<()> {
127 let bytes = bitcode::serialize(&data)?;
128 if let Some(parent) = path.as_ref().parent() {
129 create_dir_all(parent)?;
130 }
131 write(path, bytes)?;
132 Ok(())
133}
134
135pub fn read_from_file_bytes<T: From<Vec<u8>>, P: AsRef<Path>>(path: P) -> Result<T> {
136 let bytes = read(path)?;
137 Ok(T::from(bytes))
138}
139
140pub fn write_to_file_bytes<T: Into<Vec<u8>>, P: AsRef<Path>>(path: P, data: T) -> Result<()> {
141 if let Some(parent) = path.as_ref().parent() {
142 create_dir_all(parent)?;
143 }
144 write(path, data.into())?;
145 Ok(())
146}
147
148pub fn decode_from_file<T: Decode, P: AsRef<Path>>(path: P) -> Result<T> {
149 let reader = &mut File::open(path)?;
150 let ret = T::decode(reader)?;
151 Ok(ret)
152}
153
154pub fn encode_to_file<T: Encode, P: AsRef<Path>>(path: P, data: T) -> Result<()> {
155 if let Some(parent) = path.as_ref().parent() {
156 create_dir_all(parent)?;
157 }
158 let writer = &mut File::create(path)?;
159 data.encode(writer)?;
160 Ok(())
161}