use sha2::{Digest, Sha256};
use std::{env, fs::File, io::Write, path::Path};
const TARGET_FILE: &str = "context.rs";
const MAX_MERKLE_TREE_DEPTH: usize = 64;
const BYTES_PER_CHUNK: usize = 32;
fn hash_nodes(hasher: &mut Sha256, a: &[u8], b: &[u8], out: &mut [u8]) {
hasher.update(a);
hasher.update(b);
out.copy_from_slice(&hasher.finalize_reset());
}
fn compute_zero_hashes() -> [u8; MAX_MERKLE_TREE_DEPTH * BYTES_PER_CHUNK] {
let mut hasher = Sha256::new();
let mut buffer = [0u8; MAX_MERKLE_TREE_DEPTH * BYTES_PER_CHUNK];
for i in 0..MAX_MERKLE_TREE_DEPTH - 1 {
let focus_range = i * BYTES_PER_CHUNK..(i + 2) * BYTES_PER_CHUNK;
let focus = &mut buffer[focus_range];
let (source, target) = focus.split_at_mut(BYTES_PER_CHUNK);
hash_nodes(&mut hasher, source, source, target);
}
buffer
}
fn generate() -> std::io::Result<()> {
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join(TARGET_FILE);
let mut f = File::create(dest_path)?;
let data = compute_zero_hashes();
write!(
f,
"
// Generated by build.rs
static CONTEXT: Context = Context {{
zero_hashes: {data:?},
}};",
)
.unwrap();
Ok(())
}
fn main() -> std::io::Result<()> {
generate()?;
println!("cargo:rerun-if-changed=build.rs");
Ok(())
}