make librustzcash_init_zksnark_params idempotent

This commit is contained in:
sasha 2022-03-03 22:21:20 -08:00
parent 13351ff31d
commit 0e6b004a64
1 changed files with 55 additions and 51 deletions

View File

@ -29,6 +29,7 @@ use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::slice; use std::slice;
use std::sync::Once;
use subtle::CtOption; use subtle::CtOption;
use tracing::{error, info}; use tracing::{error, info};
@ -84,6 +85,7 @@ mod test_harness_ffi;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
static PROOF_PARAMETERS_LOADED: Once = Once::new();
static mut SAPLING_SPEND_VK: Option<PreparedVerifyingKey<Bls12>> = None; static mut SAPLING_SPEND_VK: Option<PreparedVerifyingKey<Bls12>> = None;
static mut SAPLING_OUTPUT_VK: Option<PreparedVerifyingKey<Bls12>> = None; static mut SAPLING_OUTPUT_VK: Option<PreparedVerifyingKey<Bls12>> = None;
static mut SPROUT_GROTH16_VK: Option<PreparedVerifyingKey<Bls12>> = None; static mut SPROUT_GROTH16_VK: Option<PreparedVerifyingKey<Bls12>> = None;
@ -127,64 +129,66 @@ pub extern "C" fn librustzcash_init_zksnark_params(
#[cfg(target_os = "windows")] sprout_path: *const u16, #[cfg(target_os = "windows")] sprout_path: *const u16,
sprout_path_len: usize, sprout_path_len: usize,
) { ) {
#[cfg(not(target_os = "windows"))] PROOF_PARAMETERS_LOADED.call_once(|| {
let (spend_path, output_path, sprout_path) = { #[cfg(not(target_os = "windows"))]
( let (spend_path, output_path, sprout_path) = {
OsStr::from_bytes(unsafe { slice::from_raw_parts(spend_path, spend_path_len) }), (
OsStr::from_bytes(unsafe { slice::from_raw_parts(output_path, output_path_len) }), OsStr::from_bytes(unsafe { slice::from_raw_parts(spend_path, spend_path_len) }),
if sprout_path.is_null() { OsStr::from_bytes(unsafe { slice::from_raw_parts(output_path, output_path_len) }),
None if sprout_path.is_null() {
} else { None
Some(OsStr::from_bytes(unsafe { } else {
slice::from_raw_parts(sprout_path, sprout_path_len) Some(OsStr::from_bytes(unsafe {
})) slice::from_raw_parts(sprout_path, sprout_path_len)
}, }))
) },
}; )
};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let (spend_path, output_path, sprout_path) = { let (spend_path, output_path, sprout_path) = {
( (
OsString::from_wide(unsafe { slice::from_raw_parts(spend_path, spend_path_len) }), OsString::from_wide(unsafe { slice::from_raw_parts(spend_path, spend_path_len) }),
OsString::from_wide(unsafe { slice::from_raw_parts(output_path, output_path_len) }), OsString::from_wide(unsafe { slice::from_raw_parts(output_path, output_path_len) }),
if sprout_path.is_null() { if sprout_path.is_null() {
None None
} else { } else {
Some(OsString::from_wide(unsafe { Some(OsString::from_wide(unsafe {
slice::from_raw_parts(sprout_path, sprout_path_len) slice::from_raw_parts(sprout_path, sprout_path_len)
})) }))
}, },
) )
}; };
let (spend_path, output_path, sprout_path) = ( let (spend_path, output_path, sprout_path) = (
Path::new(&spend_path), Path::new(&spend_path),
Path::new(&output_path), Path::new(&output_path),
sprout_path.as_ref().map(Path::new), sprout_path.as_ref().map(Path::new),
); );
// Load params // Load params
let params = load_parameters(spend_path, output_path, sprout_path); let params = load_parameters(spend_path, output_path, sprout_path);
// Generate Orchard parameters. // Generate Orchard parameters.
info!(target: "main", "Loading Orchard parameters"); info!(target: "main", "Loading Orchard parameters");
let orchard_pk = orchard::circuit::ProvingKey::build(); let orchard_pk = orchard::circuit::ProvingKey::build();
let orchard_vk = orchard::circuit::VerifyingKey::build(); let orchard_vk = orchard::circuit::VerifyingKey::build();
// Caller is responsible for calling this function once, so // Caller is responsible for calling this function once, so
// these global mutations are safe. // these global mutations are safe.
unsafe { unsafe {
SAPLING_SPEND_PARAMS = Some(params.spend_params); SAPLING_SPEND_PARAMS = Some(params.spend_params);
SAPLING_OUTPUT_PARAMS = Some(params.output_params); SAPLING_OUTPUT_PARAMS = Some(params.output_params);
SPROUT_GROTH16_PARAMS_PATH = sprout_path.map(|p| p.to_owned()); SPROUT_GROTH16_PARAMS_PATH = sprout_path.map(|p| p.to_owned());
SAPLING_SPEND_VK = Some(params.spend_vk); SAPLING_SPEND_VK = Some(params.spend_vk);
SAPLING_OUTPUT_VK = Some(params.output_vk); SAPLING_OUTPUT_VK = Some(params.output_vk);
SPROUT_GROTH16_VK = params.sprout_vk; SPROUT_GROTH16_VK = params.sprout_vk;
ORCHARD_PK = Some(orchard_pk); ORCHARD_PK = Some(orchard_pk);
ORCHARD_VK = Some(orchard_vk); ORCHARD_VK = Some(orchard_vk);
} }
});
} }
/// Writes the "uncommitted" note value for empty leaves of the Merkle tree. /// Writes the "uncommitted" note value for empty leaves of the Merkle tree.