mina_tree/proofs/
circuit_blobs.rs

1use std::path::Path;
2
3#[cfg(not(target_family = "wasm"))]
4pub fn home_base_dir() -> Option<std::path::PathBuf> {
5    let mut path = std::path::PathBuf::from(std::env::var("HOME").ok()?);
6    path.push(".openmina/circuit-blobs");
7    Some(path)
8}
9
10fn git_release_url(filename: &impl AsRef<Path>) -> String {
11    const RELEASES_PATH: &str = "https://github.com/openmina/circuit-blobs/releases/download";
12    let filename_str = filename.as_ref().to_str().unwrap();
13
14    format!("{RELEASES_PATH}/{filename_str}")
15}
16
17#[cfg(not(target_family = "wasm"))]
18pub fn fetch_blocking(filename: &impl AsRef<Path>) -> std::io::Result<Vec<u8>> {
19    use std::path::PathBuf;
20
21    fn try_base_dir<P: Into<PathBuf>>(base_dir: P, filename: &impl AsRef<Path>) -> Option<PathBuf> {
22        let mut path = base_dir.into();
23        path.push(filename);
24        path.exists().then_some(path)
25    }
26
27    fn to_io_err(err: impl std::fmt::Display) -> std::io::Error {
28        std::io::Error::new(
29            std::io::ErrorKind::Other,
30            format!(
31                "failed to find circuit-blobs locally and to fetch the from github! error: {err}"
32            ),
33        )
34    }
35
36    let home_base_dir = home_base_dir();
37    let found = None
38        .or_else(|| {
39            try_base_dir(
40                std::env::var("OPENMINA_CIRCUIT_BLOBS_BASE_DIR").ok()?,
41                filename,
42            )
43        })
44        .or_else(|| try_base_dir(env!("CARGO_MANIFEST_DIR").to_string(), filename))
45        .or_else(|| try_base_dir(home_base_dir.clone()?, filename))
46        .or_else(|| try_base_dir("/usr/local/lib/openmina/circuit-blobs", filename));
47
48    if let Some(path) = found {
49        return std::fs::read(path);
50    }
51
52    openmina_core::info!(
53        openmina_core::log::system_time();
54        kind = "ledger proofs",
55        message = "circuit-blobs not found locally, so fetching it...",
56        filename = filename.as_ref().to_str().unwrap(),
57    );
58
59    let base_dir = home_base_dir.expect("$HOME env not set!");
60
61    let bytes = reqwest::blocking::get(git_release_url(filename))
62        .map_err(to_io_err)?
63        .bytes()
64        .map_err(to_io_err)?
65        .to_vec();
66
67    // cache it to home dir.
68    let cache_path = base_dir.join(filename);
69    openmina_core::info!(
70        openmina_core::log::system_time();
71        kind = "ledger proofs",
72        message = "caching circuit-blobs",
73        path = cache_path.to_str().unwrap(),
74    );
75    let _ = std::fs::create_dir_all(cache_path.parent().unwrap());
76    let _ = std::fs::write(cache_path, &bytes);
77
78    Ok(bytes)
79}
80
81#[cfg(target_family = "wasm")]
82pub async fn fetch(filename: &impl AsRef<Path>) -> std::io::Result<Vec<u8>> {
83    let prefix =
84        option_env!("CIRCUIT_BLOBS_HTTP_PREFIX").unwrap_or("/assets/webnode/circuit-blobs");
85    let url = format!("{prefix}/{}", filename.as_ref().to_str().unwrap());
86    openmina_core::http::get_bytes(&url).await
87    // http::get_bytes(&git_release_url(filename)).await
88}
89
90#[cfg(target_family = "wasm")]
91pub fn fetch_blocking(filename: &impl AsRef<Path>) -> std::io::Result<Vec<u8>> {
92    let prefix =
93        option_env!("CIRCUIT_BLOBS_HTTP_PREFIX").unwrap_or("/assets/webnode/circuit-blobs");
94    let url = format!("{prefix}/{}", filename.as_ref().to_str().unwrap());
95    openmina_core::http::get_bytes_blocking(&url)
96}