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.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use bellman::groth16;
|
||||
use bls12_381::Bls12;
|
||||
use zcash_proofs::SaplingParameterPaths;
|
||||
|
||||
use crate::BoxError;
|
||||
|
||||
/// 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.
|
||||
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! {
|
||||
/// Groth16 Zero-Knowledge Proof parameters for the Sapling and Sprout circuits.
|
||||
///
|
||||
|
@ -56,6 +65,8 @@ impl Groth16Parameters {
|
|||
///
|
||||
/// # 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.
|
||||
fn new() -> Groth16Parameters {
|
||||
let params_directory = Groth16Parameters::directory();
|
||||
|
@ -63,36 +74,11 @@ impl Groth16Parameters {
|
|||
let sapling_output_path = params_directory.join(zcash_proofs::SAPLING_OUTPUT_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
|
||||
// (we check them on load anyway)
|
||||
if !sapling_spend_path.exists() || !sapling_output_path.exists() {
|
||||
tracing::info!("downloading Zcash Sapling parameters");
|
||||
let new_sapling_paths =
|
||||
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);
|
||||
}
|
||||
Groth16Parameters::retry_download_sapling_parameters(
|
||||
&sapling_spend_path,
|
||||
&sapling_output_path,
|
||||
);
|
||||
Groth16Parameters::retry_download_sprout_parameters(&sprout_path);
|
||||
|
||||
// TODO: if loading fails, log a message including `failure_hint`
|
||||
tracing::info!("checking and loading Zcash Sapling and Sprout parameters");
|
||||
|
@ -130,4 +116,102 @@ impl Groth16Parameters {
|
|||
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