Retry Zcash sprout and sapling parameters download (#3306)
* retry download parameters a few times before giving up * separate sapling and sprout params download to methods * simpify the new created methods * Assert the parameters were downloaded to the expected paths Co-authored-by: teor <teor@riseup.net>
This commit is contained in:
parent
5f772ebf65
commit
46a505b68e
|
@ -1,9 +1,12 @@
|
||||||
//! Downloading, checking, and loading Groth16 Sapling and Sprout parameters.
|
//! Downloading, checking, and loading Groth16 Sapling and Sprout parameters.
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use bellman::groth16;
|
use bellman::groth16;
|
||||||
use bls12_381::Bls12;
|
use bls12_381::Bls12;
|
||||||
|
use zcash_proofs::SaplingParameterPaths;
|
||||||
|
|
||||||
|
use crate::BoxError;
|
||||||
|
|
||||||
/// The timeout for each parameter file download, in seconds.
|
/// The timeout for each parameter file download, in seconds.
|
||||||
///
|
///
|
||||||
|
@ -12,6 +15,12 @@ use bls12_381::Bls12;
|
||||||
/// But `zebrad start` downloads blocks at the same time, so we allow some extra time.
|
/// But `zebrad start` downloads blocks at the same time, so we allow some extra time.
|
||||||
pub const PARAMETER_DOWNLOAD_TIMEOUT: u64 = 60 * 60;
|
pub const PARAMETER_DOWNLOAD_TIMEOUT: u64 = 60 * 60;
|
||||||
|
|
||||||
|
/// The maximum number of times to retry download parameters.
|
||||||
|
///
|
||||||
|
/// Zebra will retry to download Sprout of Sapling parameters only if they
|
||||||
|
/// failed for whatever reason.
|
||||||
|
pub const PARAMETER_DOWNLOAD_MAX_RETRIES: usize = 3;
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
/// Groth16 Zero-Knowledge Proof parameters for the Sapling and Sprout circuits.
|
/// Groth16 Zero-Knowledge Proof parameters for the Sapling and Sprout circuits.
|
||||||
///
|
///
|
||||||
|
@ -56,6 +65,8 @@ impl Groth16Parameters {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
|
/// If the parameters were downloaded to the wrong path.
|
||||||
|
/// After `PARAMETER_DOWNLOAD_MAX_RETRIES` failed download attempts.
|
||||||
/// If the downloaded or pre-existing parameter files are invalid.
|
/// If the downloaded or pre-existing parameter files are invalid.
|
||||||
fn new() -> Groth16Parameters {
|
fn new() -> Groth16Parameters {
|
||||||
let params_directory = Groth16Parameters::directory();
|
let params_directory = Groth16Parameters::directory();
|
||||||
|
@ -63,36 +74,11 @@ impl Groth16Parameters {
|
||||||
let sapling_output_path = params_directory.join(zcash_proofs::SAPLING_OUTPUT_NAME);
|
let sapling_output_path = params_directory.join(zcash_proofs::SAPLING_OUTPUT_NAME);
|
||||||
let sprout_path = params_directory.join(zcash_proofs::SPROUT_NAME);
|
let sprout_path = params_directory.join(zcash_proofs::SPROUT_NAME);
|
||||||
|
|
||||||
// TODO: instead of the path check, add a zcash_proofs argument to skip hashing existing files
|
Groth16Parameters::retry_download_sapling_parameters(
|
||||||
// (we check them on load anyway)
|
&sapling_spend_path,
|
||||||
if !sapling_spend_path.exists() || !sapling_output_path.exists() {
|
&sapling_output_path,
|
||||||
tracing::info!("downloading Zcash Sapling parameters");
|
);
|
||||||
let new_sapling_paths =
|
Groth16Parameters::retry_download_sprout_parameters(&sprout_path);
|
||||||
zcash_proofs::download_sapling_parameters(Some(PARAMETER_DOWNLOAD_TIMEOUT))
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!(
|
|
||||||
"error downloading Sapling parameter files: {:?}. {}",
|
|
||||||
error,
|
|
||||||
Groth16Parameters::failure_hint()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
assert_eq!(sapling_spend_path, new_sapling_paths.spend);
|
|
||||||
assert_eq!(sapling_output_path, new_sapling_paths.output);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !sprout_path.exists() {
|
|
||||||
tracing::info!("downloading Zcash Sprout parameters");
|
|
||||||
let new_sprout_path =
|
|
||||||
zcash_proofs::download_sprout_parameters(Some(PARAMETER_DOWNLOAD_TIMEOUT))
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!(
|
|
||||||
"error downloading Sprout parameter files: {:?}. {}",
|
|
||||||
error,
|
|
||||||
Groth16Parameters::failure_hint()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
assert_eq!(sprout_path, new_sprout_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: if loading fails, log a message including `failure_hint`
|
// TODO: if loading fails, log a message including `failure_hint`
|
||||||
tracing::info!("checking and loading Zcash Sapling and Sprout parameters");
|
tracing::info!("checking and loading Zcash Sapling and Sprout parameters");
|
||||||
|
@ -130,4 +116,102 @@ impl Groth16Parameters {
|
||||||
Groth16Parameters::directory(),
|
Groth16Parameters::directory(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Download Sapling parameters and retry [`PARAMETER_DOWNLOAD_MAX_RETRIES`] if it fails.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If the parameters were downloaded to the wrong path.
|
||||||
|
/// After `PARAMETER_DOWNLOAD_MAX_RETRIES` failed download attempts.
|
||||||
|
fn retry_download_sapling_parameters(sapling_spend_path: &Path, sapling_output_path: &Path) {
|
||||||
|
// TODO: instead of the path check, add a zcash_proofs argument to skip hashing existing files
|
||||||
|
// (we check them on load anyway)
|
||||||
|
if !sapling_spend_path.exists() || !sapling_output_path.exists() {
|
||||||
|
tracing::info!("downloading Zcash Sapling parameters");
|
||||||
|
|
||||||
|
let mut retries = 0;
|
||||||
|
while let Err(error) = Groth16Parameters::download_sapling_parameters_once(
|
||||||
|
sapling_spend_path,
|
||||||
|
sapling_output_path,
|
||||||
|
) {
|
||||||
|
retries += 1;
|
||||||
|
if retries >= PARAMETER_DOWNLOAD_MAX_RETRIES {
|
||||||
|
panic!(
|
||||||
|
"error downloading Sapling parameter files after {} retries. {:?} {}",
|
||||||
|
PARAMETER_DOWNLOAD_MAX_RETRIES,
|
||||||
|
error,
|
||||||
|
Groth16Parameters::failure_hint(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
tracing::info!(
|
||||||
|
?error,
|
||||||
|
"error downloading Zcash Sapling parameters, retrying"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to download the Sapling parameters once, and return the result.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If the parameters were downloaded to different paths to `sapling_spend_path`
|
||||||
|
/// or `sapling_output_path`.
|
||||||
|
fn download_sapling_parameters_once(
|
||||||
|
sapling_spend_path: &Path,
|
||||||
|
sapling_output_path: &Path,
|
||||||
|
) -> Result<SaplingParameterPaths, BoxError> {
|
||||||
|
let new_sapling_paths =
|
||||||
|
zcash_proofs::download_sapling_parameters(Some(PARAMETER_DOWNLOAD_TIMEOUT))?;
|
||||||
|
|
||||||
|
assert_eq!(sapling_spend_path, new_sapling_paths.spend);
|
||||||
|
assert_eq!(sapling_output_path, new_sapling_paths.output);
|
||||||
|
|
||||||
|
Ok(new_sapling_paths)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Download Sprout parameters and retry [`PARAMETER_DOWNLOAD_MAX_RETRIES`] if it fails.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If the parameters were downloaded to the wrong path.
|
||||||
|
/// After `PARAMETER_DOWNLOAD_MAX_RETRIES` failed download attempts.
|
||||||
|
fn retry_download_sprout_parameters(sprout_path: &Path) {
|
||||||
|
if !sprout_path.exists() {
|
||||||
|
tracing::info!("downloading Zcash Sprout parameters");
|
||||||
|
|
||||||
|
let mut retries = 0;
|
||||||
|
while let Err(error) = Groth16Parameters::download_sprout_parameters_once(sprout_path) {
|
||||||
|
retries += 1;
|
||||||
|
if retries >= PARAMETER_DOWNLOAD_MAX_RETRIES {
|
||||||
|
panic!(
|
||||||
|
"error downloading Sprout parameter files after {} retries. {:?} {}",
|
||||||
|
PARAMETER_DOWNLOAD_MAX_RETRIES,
|
||||||
|
error,
|
||||||
|
Groth16Parameters::failure_hint(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
tracing::info!(
|
||||||
|
?error,
|
||||||
|
"error downloading Zcash Sprout parameters, retrying"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to download the Sprout parameters once, and return the result.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If the parameters were downloaded to a different path to `sprout_path`.
|
||||||
|
fn download_sprout_parameters_once(sprout_path: &Path) -> Result<PathBuf, BoxError> {
|
||||||
|
let new_sprout_path =
|
||||||
|
zcash_proofs::download_sprout_parameters(Some(PARAMETER_DOWNLOAD_TIMEOUT))?;
|
||||||
|
|
||||||
|
assert_eq!(sprout_path, new_sprout_path);
|
||||||
|
|
||||||
|
Ok(new_sprout_path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue