Skip to content

Commit 49578a5

Browse files
apollo_proof_manager: add fs directory methods
1 parent 6d302b5 commit 49578a5

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/apollo_proof_manager/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ testing = []
1212
workspace = true
1313

1414
[dependencies]
15+
hex.workspace = true
1516
starknet-types-core = { workspace = true, features = ["hash"] }
1617
starknet_api.workspace = true
18+
tempfile.workspace = true
19+
thiserror.workspace = true
1720

1821

1922
[dev-dependencies]
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,87 @@
11
use std::error::Error;
2+
use std::path::PathBuf;
23

34
use starknet_api::transaction::fields::Proof;
45
use starknet_types_core::felt::Felt;
6+
use thiserror::Error;
57

68
pub trait ProofStorage: Send + Sync {
79
type Error: Error;
810
fn set_proof(&self, facts_hash: Felt, proof: Proof) -> Result<(), Self::Error>;
911
fn get_proof(&self, facts_hash: Felt) -> Result<Option<Proof>, Self::Error>;
1012
fn contains_proof(&self, facts_hash: Felt) -> Result<bool, Self::Error>;
1113
}
14+
15+
#[derive(Debug, Error)]
16+
pub enum FsProofStorageError {
17+
#[error(transparent)]
18+
IoError(#[from] std::io::Error),
19+
#[error("Proof for facts_hash {facts_hash} not found.")]
20+
ProofNotFound { facts_hash: Felt },
21+
}
22+
23+
type FsProofStorageResult<T> = Result<T, FsProofStorageError>;
24+
25+
pub struct FsProofStorage {
26+
persistent_root: PathBuf,
27+
}
28+
29+
impl FsProofStorage {
30+
// TODO(Einat): consider code sharing with class storage.
31+
pub fn new(persistent_root: PathBuf) -> Result<Self, std::io::Error> {
32+
std::fs::create_dir_all(&persistent_root)?;
33+
Ok(Self { persistent_root })
34+
}
35+
36+
/// Returns the directory that will hold the proof of a certain proof facts hash.
37+
/// For a proof facts hash: 0xa1b2c3d4... (rest of hash), the structure is:
38+
/// a1/
39+
/// └── b2/
40+
/// └── a1b2c3d4.../
41+
#[allow(dead_code)]
42+
fn get_proof_dir(&self, facts_hash: Felt) -> PathBuf {
43+
let facts_hash = hex::encode(facts_hash.to_bytes_be());
44+
let (first_msb_byte, second_msb_byte, _rest_of_bytes) =
45+
(&facts_hash[..2], &facts_hash[2..4], &facts_hash[4..]);
46+
PathBuf::from(first_msb_byte).join(second_msb_byte).join(facts_hash)
47+
}
48+
49+
#[allow(dead_code)]
50+
fn get_persistent_dir(&self, facts_hash: Felt) -> PathBuf {
51+
self.persistent_root.join(self.get_proof_dir(facts_hash))
52+
}
53+
54+
#[allow(dead_code)]
55+
fn get_persistent_dir_with_create(&self, facts_hash: Felt) -> FsProofStorageResult<PathBuf> {
56+
let path = self.get_persistent_dir(facts_hash);
57+
if let Some(parent) = path.parent() {
58+
std::fs::create_dir_all(parent)?;
59+
}
60+
61+
Ok(path)
62+
}
63+
64+
#[allow(dead_code)]
65+
fn create_tmp_dir(
66+
&self,
67+
facts_hash: Felt,
68+
) -> FsProofStorageResult<(tempfile::TempDir, PathBuf)> {
69+
// Compute the final persistent directory for this `facts_hash`
70+
let persistent_dir = self.get_persistent_dir(facts_hash);
71+
let parent_dir = persistent_dir
72+
.parent()
73+
.expect("Proof persistent dir should have a parent")
74+
.to_path_buf();
75+
std::fs::create_dir_all(&parent_dir)?;
76+
// Create a temporary directory under the parent of the final persistent directory to ensure
77+
// `rename` will be atomic.
78+
let tmp_root = tempfile::tempdir_in(&parent_dir)?;
79+
// Get the leaf directory name of the final persistent directory.
80+
let leaf = persistent_dir.file_name().expect("Proof dir leaf should exist");
81+
// Create the temporary directory under the temporary root.
82+
let tmp_dir = tmp_root.path().join(leaf);
83+
// Returning `TempDir` since without it the handle would drop immediately and the temp
84+
// directory would be removed before writes/rename.
85+
Ok((tmp_root, tmp_dir))
86+
}
87+
}

0 commit comments

Comments
 (0)