|
| 1 | +use std::convert::TryInto; |
1 | 2 | use std::error::Error; |
2 | | -use std::path::PathBuf; |
| 3 | +use std::fs::OpenOptions; |
| 4 | +use std::io::{BufWriter, Read, Write}; |
| 5 | +use std::path::{Path, PathBuf}; |
| 6 | +use std::sync::Arc; |
3 | 7 |
|
4 | 8 | use starknet_api::transaction::fields::Proof; |
5 | 9 | use starknet_types_core::felt::Felt; |
@@ -84,4 +88,56 @@ impl FsProofStorage { |
84 | 88 | // directory would be removed before writes/rename. |
85 | 89 | Ok((tmp_root, tmp_dir)) |
86 | 90 | } |
| 91 | + |
| 92 | + /// Writes a proof to a file in binary format. |
| 93 | + /// The file is named `proof` inside the given directory. |
| 94 | + #[allow(dead_code)] |
| 95 | + fn write_proof_to_file(&self, path: &Path, proof: &Proof) -> FsProofStorageResult<()> { |
| 96 | + let path = path.join("proof"); |
| 97 | + if let Some(parent) = path.parent() { |
| 98 | + std::fs::create_dir_all(parent)?; |
| 99 | + } |
| 100 | + |
| 101 | + // Open a file for writing, deleting any existing content. |
| 102 | + let file = OpenOptions::new() |
| 103 | + .create(true) |
| 104 | + .write(true) |
| 105 | + .truncate(true) |
| 106 | + .open(path) |
| 107 | + .expect("Failing to open file with given options is impossible"); |
| 108 | + |
| 109 | + let mut writer = BufWriter::new(file); |
| 110 | + // Pre-allocate exactly enough space, 4 bytes per u32. |
| 111 | + let mut buf: Vec<u8> = Vec::with_capacity(proof.len() * std::mem::size_of::<u32>()); |
| 112 | + |
| 113 | + for &value in proof.iter() { |
| 114 | + buf.extend_from_slice(&value.to_be_bytes()); |
| 115 | + } |
| 116 | + |
| 117 | + // Single write. |
| 118 | + writer.write_all(&buf)?; |
| 119 | + writer.flush()?; |
| 120 | + Ok(()) |
| 121 | + } |
| 122 | + |
| 123 | + /// Reads a proof from a file in binary format. |
| 124 | + #[allow(dead_code)] |
| 125 | + fn read_proof_from_file(&self, facts_hash: Felt) -> FsProofStorageResult<Proof> { |
| 126 | + let file_path = self.get_persistent_dir(facts_hash).join("proof"); |
| 127 | + let mut file = std::fs::File::open(file_path)?; |
| 128 | + |
| 129 | + let mut buffer = Vec::new(); |
| 130 | + file.read_to_end(&mut buffer)?; |
| 131 | + |
| 132 | + if buffer.len() % 4 != 0 { |
| 133 | + return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Corrupt file").into()); |
| 134 | + } |
| 135 | + |
| 136 | + let proof_data = buffer |
| 137 | + .chunks_exact(4) |
| 138 | + .map(|c| u32::from_be_bytes(c.try_into().expect("4 bytes should fit in a u32"))) |
| 139 | + .collect(); |
| 140 | + |
| 141 | + Ok(Proof(Arc::new(proof_data))) |
| 142 | + } |
87 | 143 | } |
0 commit comments