change(consensus): Build Sprout and Sapling parameters into the zebrad binary, so a download server isn't needed (#7800)

* Build sapling parameters into zebrad

* Load the sapling parameters from wagyu-zcash-parameters

* Reword logs

* wget https://github.com/zcash/zcash/raw/master/src/rust/src/sprout-groth16.vk

* Load sprout from binary and remove download code

* Remove download examples binaries

* Remove unused features and dependencies

* Remove docs and comments about downloading parameters

* Add CHANGELOG entry

* Remove parameter cache steps in workflows

* Update comment about downloading

Co-authored-by: Marek <mail@marek.onl>

* Fix outdated timeout comments and short timeouts

---------

Co-authored-by: Marek <mail@marek.onl>
This commit is contained in:
teor 2023-10-25 09:27:24 +10:00 committed by GitHub
parent bb7eeb6f76
commit aad883b68a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 122 additions and 366 deletions

View File

@ -17,10 +17,6 @@ on:
jobs:
coverage:
name: Coverage on stable
# The large timeout is to accommodate:
# - nightly builds (75 minutes, typically 30-50 minutes)
# - parameter downloads (40 minutes, but only when the cache expires)
timeout-minutes: 115
runs-on: ubuntu-latest
steps:

View File

@ -9,6 +9,10 @@ concurrency:
on:
workflow_dispatch:
# we build Rust caches on main,
# so they can be shared by all branches:
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
push:
branches:
- main
@ -28,6 +32,7 @@ on:
# workflow definitions
- 'codecov.yml'
- '.github/workflows/ci-coverage.yml'
pull_request:
paths:
- '**/*.rs'
@ -51,9 +56,8 @@ jobs:
coverage:
name: Coverage on stable
# The large timeout is to accommodate:
# - stable builds (typically 30-50 minutes), and
# - parameter downloads (an extra 90 minutes, but only when the cache expires)
timeout-minutes: 140
# - stable builds (typically 50-90 minutes), and
timeout-minutes: 120
runs-on: ubuntu-latest-xl
steps:
@ -84,24 +88,6 @@ jobs:
echo "PROPTEST_CASES=1" >> $GITHUB_ENV
echo "PROPTEST_MAX_SHRINK_ITERS=0" >> $GITHUB_ENV
# Modified from:
# https://github.com/zcash/librustzcash/blob/c48bb4def2e122289843ddb3cb2984c325c03ca0/.github/workflows/ci.yml#L20-L33
- name: Fetch path to Zcash parameters
working-directory: ./zebra-consensus
shell: bash
# cargo-llvm-cov doesn't have a silent mode, so we have to extract the path from stderr
run: echo "ZCASH_PARAMS=$(cargo llvm-cov --lcov --no-report run --example get-params-path 2>&1 >/dev/null | tail -1)" >> $GITHUB_ENV
- name: Cache Zcash parameters
id: cache-params
uses: actions/cache@v3
with:
path: ${{ env.ZCASH_PARAMS }}
key: ${{ runner.os }}-sprout-and-sapling-params
- name: Fetch Zcash parameters
if: steps.cache-params.outputs.cache-hit != 'true'
working-directory: ./zebra-consensus
run: cargo llvm-cov --lcov --no-report run --example download-params
- name: Run Zebra tests
run: cargo llvm-cov --lcov --no-report

View File

@ -9,9 +9,6 @@ concurrency:
on:
workflow_dispatch:
# we build Rust and Zcash parameter caches on main,
# so they can be shared by all branches:
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
pull_request:
paths:
@ -31,6 +28,9 @@ on:
# workflow definitions
- '.github/workflows/ci-unit-tests-os.yml'
# we build Rust caches on main,
# so they can be shared by all branches:
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
push:
branches:
- main
@ -67,9 +67,8 @@ jobs:
test:
name: Test ${{ matrix.rust }} on ${{ matrix.os }}${{ matrix.features }}
# The large timeout is to accommodate:
# - macOS and Windows builds (90 minutes, typically 30-70 minutes), and
# - parameter downloads (an extra 100 minutes, but only when the cache expires)
timeout-minutes: 190
# - macOS and Windows builds (typically 50-90 minutes), and
timeout-minutes: 120
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@ -159,29 +158,6 @@ jobs:
echo "PROPTEST_CASES=1" >> $GITHUB_ENV
echo "PROPTEST_MAX_SHRINK_ITERS=1024" >> $GITHUB_ENV
# Modified from:
# https://github.com/zcash/librustzcash/blob/c48bb4def2e122289843ddb3cb2984c325c03ca0/.github/workflows/ci.yml#L20-L33
#
# TODO:
# - split Fetch/Cache Zcash parameters into their own job,
# and use `concurrency:` to limit it to one job per OS
# - split get-params-path and download-params examples into their own crate,
# to speed up compilation
- name: Fetch path to Zcash parameters
working-directory: ./zebra-consensus
shell: bash
run: echo "ZCASH_PARAMS=$(cargo run --release --example get-params-path)" >> $GITHUB_ENV
- name: Cache Zcash parameters
id: cache-params
uses: actions/cache@v3
with:
path: ${{ env.ZCASH_PARAMS }}
key: ${{ runner.os }}-sprout-and-sapling-params
- name: Fetch Zcash parameters
if: steps.cache-params.outputs.cache-hit != 'true'
working-directory: ./zebra-consensus
run: cargo run --release --example download-params
# Run unit and basic acceptance tests, only showing command output if the test fails.
#
# If some tests hang, add "-- --nocapture" for just that test, or for all the tests.

View File

@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
Zebra's mining RPCs are now available in release builds. TODO: rest of intro
This release contains the following changes:
### Mining RPCs in Production Builds
Zebra's mining RPCs are now available in release builds (#7740). Any Zebra instance can be used
@ -21,6 +21,25 @@ read our [mining blog post](https://zfnd.org/experimental-mining-support-in-zebr
Please [let us know](https://github.com/ZcashFoundation/zebra/issues/new?assignees=&labels=C-enhancement%2CS-needs-triage&projects=&template=feature_request.yml&title=feature%3A+)
if your mining pool needs extra RPC methods or fields.
### Parameters in Binary
`zebrad` now bundles zk-SNARK parameters directly into its binary. This increases the binary size
by a few megabytes, but these parameters do not need to be downloaded or stored separately.
Previously, parameters were stored by default in these locations:
* `~/.zcash-params` (on Linux); or
* `~/Library/Application Support/ZcashParams` (on Mac); or
* `C:\Users\Username\AppData\Roaming\ZcashParams` (on Windows)
If you have upgraded `zebrad` to 1.4.0 or later, and `zcashd` to 5.7.0 or later, you can delete the
parameter files in these directories to save approximately 700 MB disk space.
[`zcashd` have deprecated their `fetch-params.sh` script](https://github.com/zcash/zcash/blob/master/doc/release-notes/release-notes-5.7.0.md#deprecation-of-fetch-paramssh),
so it can't be used to retry failed downloads in `zebrad` 1.3.0 and earlier.
We recommend upgrading to the latest Zebra release to avoid download issues in new installs.
### Security
TODO: rest of changelog
@ -32,9 +51,9 @@ and fixes performance issues and bugs in the mining solution rate RPCs. Progress
bars can now be enabled using a config, please help us test them!
It contains the following updates:
### User Testing: Progress Bars
Zebra has progress bars! When progress bars are enabled, you can see Zebra's blocks,
transactions, and peer connections in your terminal. We're asking Zebra users to test this
feature, and give us [feedback on the forums](https://forum.zcashcommunity.com/t/zebra-progress-bars/44485).

View File

@ -2486,19 +2486,6 @@ dependencies = [
"adler",
]
[[package]]
name = "minreq"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb3371dfc7b772c540da1380123674a8e20583aca99907087d990ca58cf44203"
dependencies = [
"log",
"once_cell",
"rustls",
"rustls-webpki",
"webpki-roots",
]
[[package]]
name = "mio"
version = "0.8.8"
@ -4916,6 +4903,56 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "wagyu-zcash-parameters"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c904628658374e651288f000934c33ef738b2d8b3e65d4100b70b395dbe2bb"
dependencies = [
"wagyu-zcash-parameters-1",
"wagyu-zcash-parameters-2",
"wagyu-zcash-parameters-3",
"wagyu-zcash-parameters-4",
"wagyu-zcash-parameters-5",
"wagyu-zcash-parameters-6",
]
[[package]]
name = "wagyu-zcash-parameters-1"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bf2e21bb027d3f8428c60d6a720b54a08bf6ce4e6f834ef8e0d38bb5695da8"
[[package]]
name = "wagyu-zcash-parameters-2"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a616ab2e51e74cc48995d476e94de810fb16fc73815f390bf2941b046cc9ba2c"
[[package]]
name = "wagyu-zcash-parameters-3"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14da1e2e958ff93c0830ee68e91884069253bf3462a67831b02b367be75d6147"
[[package]]
name = "wagyu-zcash-parameters-4"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f058aeef03a2070e8666ffb5d1057d8bb10313b204a254a6e6103eb958e9a6d6"
[[package]]
name = "wagyu-zcash-parameters-5"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ffe916b30e608c032ae1b734f02574a3e12ec19ab5cc5562208d679efe4969d"
[[package]]
name = "wagyu-zcash-parameters-6"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7b6d5a78adc3e8f198e9cd730f219a695431467f7ec29dcfc63ade885feebe1"
[[package]]
name = "wait-timeout"
version = "0.2.0"
@ -5373,7 +5410,6 @@ dependencies = [
"jubjub",
"known-folders",
"lazy_static",
"minreq",
"rand_core 0.6.4",
"redjubjub",
"tracing",
@ -5516,6 +5552,7 @@ dependencies = [
"tracing-error",
"tracing-futures",
"tracing-subscriber",
"wagyu-zcash-parameters",
"zcash_proofs",
"zebra-chain",
"zebra-node-services",

View File

@ -47,17 +47,9 @@ opt-level = 3
[profile.dev.package.bls12_381]
opt-level = 3
# Cryptographic and parameter download crates
[profile.dev.package.zcash_proofs]
opt-level = 3
[profile.dev.package.minreq]
opt-level = 3
[profile.dev.package.rustls]
opt-level = 3
[profile.dev.package.ring]
opt-level = 3

View File

@ -163,8 +163,6 @@ There are a few bugs in Zebra that we're still working on fixing:
- Zebra currently gossips and connects to [private IP addresses](https://en.wikipedia.org/wiki/IP_address#Private_addresses), we want to [disable private IPs but provide a config (#3117)](https://github.com/ZcashFoundation/zebra/issues/3117) in an upcoming release
- If Zebra fails downloading the Zcash parameters, use [the Zcash parameters download script](https://github.com/zcash/zcash/blob/master/zcutil/fetch-params.sh) instead.
- Block download and verification sometimes times out during Zebra's initial sync [#5709](https://github.com/ZcashFoundation/zebra/issues/5709). The full sync still finishes reasonably quickly.
- Rust 1.70 [causes crashes during shutdown on macOS x86_64 (#6812)](https://github.com/ZcashFoundation/zebra/issues/6812). The state cache should stay valid despite the crash.

View File

@ -178,14 +178,13 @@ To fix duplicate dependencies, follow these steps until the duplicate dependenci
2. If there are any "skip tree root was not found in the dependency graph" warnings, delete those versions from `deny.toml`
### Fixing Disk Full Errors and Zcash Parameter Errors
### Fixing Disk Full Errors
If the Docker cached state disks are full, increase the disk sizes in:
- [deploy-gcp-tests.yml](https://github.com/ZcashFoundation/zebra/blob/main/.github/workflows/deploy-gcp-tests.yml)
- [continous-delivery.yml](https://github.com/ZcashFoundation/zebra/blob/main/.github/workflows/continous-delivery.yml)
If the GitHub Actions disks are full, or the Zcash parameter downloads time out without any network messages or errors,
follow these steps until the errors are fixed:
If the GitHub Actions disks are full, follow these steps until the errors are fixed:
0. Check if error is also happening on the `main` branch. If it is, skip the next step.
1. Update your branch to the latest `main` branch, this builds with all the latest dependencies in the `main` branch cache.
@ -194,11 +193,6 @@ follow these steps until the errors are fixed:
These errors often happen after a new compiler version is released, because the caches can end up with files from both compiler versions.
If the Zcash Parameter downloads have an error loading the parameters:
1. Clear the Zcash parameter caches for all branches, including `main`
The correct `*-sprout-and-sapling-params` caches should be around 765 MB.
You can find a list of caches using:
```sh
gh api -H "Accept: application/vnd.github+json" repos/ZcashFoundation/Zebra/actions/caches

View File

@ -8,83 +8,15 @@ https://zips.z.cash/protocol/protocol.pdf#groth
The Groth16 proving system requires a trusted setup, this is a set of predefined parameters that every node should possess to verify the proofs that will show up in the blockchain.
These parameters are in the form of files, they are basically predefined keys that will allow verification of the circuits. They were initially obtained by [this process](https://eprint.iacr.org/2017/1050.pdf).
These parameters are built into the `zebrad` binary. They are predefined keys that will allow verification of the circuits. They were initially obtained by [this process](https://eprint.iacr.org/2017/1050.pdf).
3 files are needed, one for each circuit, this is part of the Zcash consensus protocol:
3 parameters are needed, one for each circuit, this is part of the Zcash consensus protocol:
https://zips.z.cash/protocol/protocol.pdf#grothparameters
In Zebra, these 3 public files are mapped into 2 structures:
```rust
/// Groth16 Zero-Knowledge Proof spend and output parameters for the Sapling circuit.
pub struct SaplingParameters {
pub spend: groth16::Parameters<Bls12>,
pub spend_prepared_verifying_key: groth16::PreparedVerifyingKey<Bls12>,
pub output: groth16::Parameters<Bls12>,
pub output_prepared_verifying_key: groth16::PreparedVerifyingKey<Bls12>,
}
/// Groth16 Zero-Knowledge Proof spend parameters for the Sprout circuit.
///
/// New Sprout outputs were disabled by the Canopy network upgrade.
pub struct SproutParameters {
pub joinsplit_prepared_verifying_key: groth16::PreparedVerifyingKey<Bls12>,
}
```
Zebra uses the [bellman crate groth16 implementation](https://github.com/zkcrypto/bellman/blob/main/src/groth16/mod.rs) for all groth16 types.
Each time a transaction has any sprout joinsplit, sapling spend or sapling output these loaded parameters will be used for the verification process. Zebra verifies in parallel and by batches, these parameters are used on each verification done.
There are 2 different zebrad commands to get these parameters from the internet and load them into zebra:
## zebrad download
When this command is executed Zebra will create a path for each parameter file. For example, in linux, parameter files will be at:
- `/home/$USER/.zcash-params/sapling-output.params`
- `/home/$USER/.zcash-params/sapling-spend.params`
- `/home/$USER/.zcash-params/sprout-groth16.params`
These are the same parameter paths used by `zcashd` and [fetch-params.sh](https://github.com/zcash/zcash/blob/master/zcutil/fetch-params.sh).
These files are available for [download](https://download.z.cash/downloads/) and their hash for verification is part of the Zcash protocol:
https://zips.z.cash/protocol/protocol.pdf#grothparameters
Zebra will next use the [zcash_proofs](https://github.com/zcash/librustzcash/tree/main/zcash_proofs) crate to call a function with the 3 paths as arguments.
Function `zcash_proofs::load_parameters()` will take the 3 paths, check if the data is already there, verify the hashes and download the content if needed.
```sh
$ ./target/release/zebrad download
2022-12-29T16:54:50.273253Z INFO zebrad::components::tracing::component: started tracing component filter="info" TRACING_STATIC_MAX_LEVEL=LevelFilter::TRACE LOG_STATIC_MAX_LEVEL=Trace
2022-12-29T16:54:50.274611Z INFO {zebrad="535d0ad" net="Main"}: zebrad::application: initialized rayon thread pool for CPU-bound tasks num_threads=12
2022-12-29T16:54:50.275486Z INFO {zebrad="535d0ad" net="Main"}: zebrad::commands::download: checking if Zcash Sapling and Sprout parameters have been downloaded
2022-12-29T16:54:50.312716Z INFO {zebrad="535d0ad" net="Main"}: zebra_consensus::primitives::groth16::params: checking and loading Zcash Sapling and Sprout parameters
2022-12-29T16:54:56.865148Z INFO {zebrad="535d0ad" net="Main"}: zebra_consensus::primitives::groth16::params: Zcash Sapling and Sprout parameters downloaded and/or verified
$
```
## zebrad start
The alternative way is to let zebra do the above process at startup.
Before Zebra attempts to verify any of the 3 mentioned circuits it needs to have the parameters in place. For this reason zebra start will check for the parameters and download them if needed each time it is started.
At zebra startup, when initializing the verifiers, a separate task is created to do the same as the `zebra download` command. This allows Zebra sync to make progress before having the parameters. Note that these parameters are needed after Sapling activation which happens at block `419_200` in the Mainnet and block `15` in the Testnet. Zebra will wait for the parameters to download before verifying those blocks and above.
If the parameters were already downloaded and they are already in place the same function `zcash_proofs::load_parameters()` will verify them against the consensus hashes. If they are not there or the hash is not the same then `zcash_proofs::load_parameters()` will download.
```sh
$ ./target/release/zebrad start
...
2022-12-29T17:04:21.948096Z INFO {zebrad="535d0ad" net="Main"}: zebrad::commands::start: initializing verifiers
...
zebra_consensus::primitives::groth16::params: checking and loading Zcash Sapling and Sprout parameters
...
zebra_consensus::primitives::groth16::params: Zcash Sapling and Sprout parameters downloaded and/or verified
...
debug_skip_parameter_preload=false}: zebra_consensus::chain: Groth16 pre-download and check task finished
...
```
The first time any parameters are used, Zebra automatically parses all of the parameters. This work
is only done once.

View File

@ -60,7 +60,8 @@ tracing-futures = "0.2.5"
orchard = "0.6.0"
zcash_proofs = { version = "0.13.0-rc.1", features = ["local-prover", "multicore", "download-params"] }
zcash_proofs = { version = "0.13.0-rc.1", features = ["multicore" ] }
wagyu-zcash-parameters = "0.2.0"
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.6" }
tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.6" }

View File

@ -1,11 +0,0 @@
//! Download the Sapling and Sprout Groth16 parameters if needed,
//! check they were downloaded correctly, and load them into Zebra.
// Has the same functionality as:
// https://github.com/zcash/librustzcash/blob/c48bb4def2e122289843ddb3cb2984c325c03ca0/zcash_proofs/examples/download-params.rs
fn main() {
// The lazy static initializer does the download, if needed,
// and the file hash checks.
lazy_static::initialize(&zebra_consensus::groth16::GROTH16_PARAMETERS);
}

View File

@ -1,12 +0,0 @@
//! Print the Zcash parameter directory path to standard output.
// Modified from:
// https://github.com/zcash/librustzcash/blob/c48bb4def2e122289843ddb3cb2984c325c03ca0/zcash_proofs/examples/get-params-path.rs
#[allow(clippy::print_stdout)]
fn main() {
let path = zebra_consensus::groth16::Groth16Parameters::directory();
if let Some(path) = path.to_str() {
println!("{path}");
}
}

View File

@ -4,18 +4,6 @@ use serde::{Deserialize, Serialize};
/// Configuration for parallel semantic verification:
/// <https://zebra.zfnd.org/dev/rfcs/0002-parallel-verification.html#definitions>
///
/// Automatically downloads the Zcash Sprout and Sapling parameters to the default directory:
/// - Linux: `$HOME/.zcash-params`
/// - macOS: `$HOME/Library/Application Support/ZcashParams`
/// - Windows: `%APPDATA%\ZcashParams` or `C:\Users\%USERNAME%\AppData\ZcashParams`
///
/// # Security
///
/// If you are running Zebra with elevated permissions ("root"), create the
/// parameters directory before running Zebra, and make sure the Zebra user
/// account has exclusive access to that directory, and other users can't modify
/// its parent directories.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields, default)]
pub struct Config {

View File

@ -1,37 +1,16 @@
//! Downloading, checking, and loading Groth16 Sapling and Sprout parameters.
use std::path::{Path, PathBuf};
//! Loading and checking correctness of Groth16 Sapling and Sprout parameters.
use bellman::groth16;
use bls12_381::Bls12;
use zcash_proofs::SaplingParameterPaths;
use crate::BoxError;
/// The timeout for each parameter file download, in seconds.
///
/// Zebra assumes that it's running on at least a 10 Mbps connection.
/// So the parameter files should download in about 15 minutes using `zebrad download`.
/// 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 Zebra retries to download the parameters.
///
/// Zebra will retry the download only if the previous attempt fails.
pub const PARAMETER_DOWNLOAD_MAX_RETRIES: usize = 2;
lazy_static::lazy_static! {
/// Groth16 Zero-Knowledge Proof parameters for the Sapling and Sprout circuits.
///
/// This static is accessed when Zebra:
///
/// - needs to download and cache the parameters to a shared directory, or
/// - checks the file hashes for both newly downloaded and previously cached files, or
/// - loads the parameters.
/// This static is accessed when Zebra needs to use these parameters for verification.
///
/// # Panics
///
/// If the downloaded or pre-existing parameter files are invalid.
/// If the parameter data in the `zebrad` binary is invalid.
pub static ref GROTH16_PARAMETERS: Groth16Parameters = Groth16Parameters::new();
}
@ -55,164 +34,54 @@ pub struct SaplingParameters {
/// Groth16 Zero-Knowledge Proof spend parameters for the Sprout circuit.
///
/// New Sprout outputs were disabled by the Canopy network upgrade.
/// Adding value to the Sprout pool was disabled by the Canopy network upgrade.
pub struct SproutParameters {
pub joinsplit_prepared_verifying_key: groth16::PreparedVerifyingKey<Bls12>,
}
impl Groth16Parameters {
/// Loads the Sprout and Sapling Groth16 parameters, checking the sizes and hashes of the files.
///
/// If the parameters are not present, they are automatically downloaded and cached.
/// Loads the Sprout and Sapling Groth16 parameters from the `zebrad` binary, and checks that
/// the data is valid.
///
/// # Panics
///
/// - If the parameters were downloaded to a wrong path.
/// - After [`PARAMETER_DOWNLOAD_MAX_RETRIES`] failed download retries.
/// - If the downloaded or pre-existing parameter files are invalid.
/// If the parameter data in the `zebrad` binary is invalid.
fn new() -> Groth16Parameters {
let params_directory = Groth16Parameters::directory();
let sapling_spend_path = params_directory.join(zcash_proofs::SAPLING_SPEND_NAME);
let sapling_output_path = params_directory.join(zcash_proofs::SAPLING_OUTPUT_NAME);
let sprout_path = params_directory.join(zcash_proofs::SPROUT_NAME);
Groth16Parameters::download_sapling_parameters(&sapling_spend_path, &sapling_output_path);
Groth16Parameters::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");
let parameters = zcash_proofs::load_parameters(
&sapling_spend_path,
&sapling_output_path,
Some(&sprout_path),
let (sapling_spend_bytes, sapling_output_bytes) =
wagyu_zcash_parameters::load_sapling_parameters();
let sprout_vk_bytes = include_bytes!("sprout-groth16.vk");
let sapling_parameters = zcash_proofs::parse_parameters(
sapling_spend_bytes.as_slice(),
sapling_output_bytes.as_slice(),
// This API expects the full sprout parameter file, not just the verifying key.
None,
);
let sapling = SaplingParameters {
spend: parameters.spend_params,
spend_prepared_verifying_key: parameters.spend_vk,
output: parameters.output_params,
output_prepared_verifying_key: parameters.output_vk,
spend: sapling_parameters.spend_params,
spend_prepared_verifying_key: sapling_parameters.spend_vk,
output: sapling_parameters.output_params,
output_prepared_verifying_key: sapling_parameters.output_vk,
};
let sprout_vk = groth16::VerifyingKey::<Bls12>::read(&sprout_vk_bytes[..])
.expect("should be able to parse Sprout verification key");
let sprout_vk = groth16::prepare_verifying_key(&sprout_vk);
let sprout = SproutParameters {
joinsplit_prepared_verifying_key: parameters
.sprout_vk
.expect("unreachable code: sprout loader panics on failure"),
joinsplit_prepared_verifying_key: sprout_vk,
};
tracing::info!("Zcash Sapling and Sprout parameters downloaded and/or verified");
tracing::info!("Zcash Sapling and Sprout parameters loaded and verified");
Groth16Parameters { sapling, sprout }
}
/// Returns the path to the Groth16 parameters directory.
pub fn directory() -> PathBuf {
zcash_proofs::default_params_folder().expect("unable to find user home directory")
}
/// Returns a hint that helps users recover from parameter download failures.
/// Returns a hint that helps users recover from parameter loading failures.
pub fn failure_hint() -> String {
format!(
"Hint: try deleting {:?}, then running 'zebrad download' to re-download the parameters",
Groth16Parameters::directory(),
)
}
/// Downloads the Sapling parameters.
///
/// # Panics
///
/// - If the parameters were downloaded to a wrong path.
/// - After [`PARAMETER_DOWNLOAD_MAX_RETRIES`] failed download retries.
fn 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"
);
}
}
}
}
/// Tries to download the Sapling parameters once and returns the result.
///
/// # Panics
///
/// If the parameters were downloaded to paths different 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)
}
/// Downloads the Sprout parameters.
///
/// # Panics
///
/// - If the parameters were downloaded to a wrong path.
/// - After [`PARAMETER_DOWNLOAD_MAX_RETRIES`] failed download retries.
fn 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"
);
}
}
}
}
/// Tries to download the Sprout parameters once and returns the result.
///
/// # Panics
///
/// If the parameters were downloaded to a path different 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)
"Hint: re-run `zebrad` or re-install it from a trusted source".to_string()
}
}

View File

@ -23,12 +23,6 @@ cargo build --bin zebrad || exit $?
EXIT_STATUS=0
while [ $EXIT_STATUS -eq 0 ] && [ $SHUTDOWN_DELAY -le $SHUTDOWN_DELAY_LIMIT ]; do
# remove previously downloaded Zcash parameter files
#
# if you don't have these downloaded already, the killed downloads will be incomplete,
# which causes an error in Zebra
# rm -r ~/.zcash-params
echo
echo "Running Zebra for $SHUTDOWN_DELAY seconds"
echo

View File

@ -22,9 +22,6 @@
//! * verifies blocks using zebra-chain, then stores verified blocks in zebra-state
//! * verifies mempool and block transactions using zebra-chain and zebra-script,
//! and returns verified mempool transactions for mempool storage
//! * Groth16 Parameters Download Task
//! * downloads the Sprout and Sapling Groth16 circuit parameter files
//! * finishes when the download is complete and the download file hashes have been checked
//! * Inbound Service
//! * primary external interface for inbound peer requests to this node
//! * handles requests from peers for network data, chain data, and mempool transactions