Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download sprout parameters in zcash_proofs #459

Merged
merged 29 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6e4a3c5
Add a missing feature dependency: download_params -> directories
teor2345 Nov 22, 2021
d79e9d8
Make the parameter file names public
teor2345 Nov 22, 2021
3894326
Download sprout parameters in-memory
teor2345 Nov 22, 2021
5b3d419
Add download_sapling_parameters and deprecate download_parameters
teor2345 Nov 22, 2021
0abeac0
Tweak deprecation warning
teor2345 Nov 23, 2021
cbc3770
Download a single file, rather than parts
teor2345 Nov 23, 2021
a46b2bf
Only download files if needed, but always check the hashes
teor2345 Nov 23, 2021
59bf587
Allow the caller to specify a response timeout
teor2345 Nov 23, 2021
ea1926f
Stream downloads from server to disk
teor2345 Nov 23, 2021
19df7ed
Refactor file loads to use the same verifying function as downloads
teor2345 Nov 23, 2021
6c67dc3
Add missing docs
teor2345 Nov 23, 2021
33a83df
Download parameters in parts, so we hit the Cloudflare cache
teor2345 Nov 24, 2021
641c52f
Add a byte count to verification errors
teor2345 Nov 24, 2021
3f3116e
Check file sizes to help debug parameter load failures
teor2345 Nov 24, 2021
12ad782
Remove downloaded files on error (but leave existing files alone)
teor2345 Nov 24, 2021
fa901f8
Add a sprout and sapling download example
teor2345 Nov 24, 2021
3a005fd
Improve example downloaders
teor2345 Nov 25, 2021
e50cce2
Fix missing docs
teor2345 Nov 25, 2021
2737d6d
Launch the second download request once the first finishes
teor2345 Nov 25, 2021
5ece02d
Move the download Read impl into its own module
teor2345 Nov 25, 2021
7fb35bf
Derive standard traits on SaplingParameterPaths
teor2345 Dec 30, 2021
6f53798
Fix error log argument order
teor2345 Jan 6, 2022
6d75718
Fix clippy::format_push_string
teor2345 May 11, 2022
512a785
Fix hashreader comments
teor2345 Jul 28, 2022
9c33179
Replace wildcard import
teor2345 Jul 28, 2022
d407b90
Add a missing import
teor2345 Jul 29, 2022
1c7cd39
Require features for the load parameters method
teor2345 Jul 29, 2022
40d9115
Fix up conditional compilation and imports
teor2345 Jul 31, 2022
c0f20b3
Revert unnecessary changes
teor2345 Jul 31, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion zcash_proofs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pprof = { version = "0.8", features = ["criterion", "flamegraph"] } # MSRV 1.56
[features]
default = ["local-prover", "multicore"]
bundled-prover = ["wagyu-zcash-parameters"]
download-params = ["minreq"]
download-params = ["minreq", "directories"]
local-prover = ["directories"]
multicore = ["bellman/multicore"]

Expand All @@ -60,5 +60,9 @@ required-features = ["directories"]
name = "download-params"
required-features = ["download-params"]

[[example]]
name = "download-sprout-and-sapling-params"
required-features = ["download-params"]

[badges]
maintenance = { status = "actively-developed" }
1 change: 1 addition & 0 deletions zcash_proofs/examples/download-params.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
fn main() -> Result<(), minreq::Error> {
#[allow(deprecated)]
zcash_proofs::download_parameters()
}
26 changes: 26 additions & 0 deletions zcash_proofs/examples/download-sprout-and-sapling-params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
fn main() -> Result<(), minreq::Error> {
const DOWNLOAD_TIMEOUT_SECONDS: u64 = 3600;

#[allow(unused_mut, unused_assignments)]
let mut params_folder =
zcash_proofs::default_params_folder().expect("unexpected missing HOME env var");

// Always do a download to /tmp, if compiled with `RUSTFLAGS="--cfg always_download"`
nuttycom marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(always_download)]
{
std::env::set_var("HOME", "/tmp");
params_folder =
zcash_proofs::default_params_folder().expect("unexpected missing HOME env var");

println!("removing temporary parameters folder: {:?}", params_folder);
let _ = std::fs::remove_dir_all(&params_folder);
}

println!("downloading sapling parameters to: {:?}", params_folder);
zcash_proofs::download_sapling_parameters(Some(DOWNLOAD_TIMEOUT_SECONDS))?;
daira marked this conversation as resolved.
Show resolved Hide resolved

println!("downloading sprout parameters to: {:?}", params_folder);
zcash_proofs::download_sprout_parameters(Some(DOWNLOAD_TIMEOUT_SECONDS))?;

Ok(())
}
79 changes: 79 additions & 0 deletions zcash_proofs/src/downloadreader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! [`io::Read`] implementations for [`minreq`].

use std::io;

/// A wrapper that implements [`io::Read`] on a [`minreq::ResponseLazy`].
pub enum ResponseLazyReader {
Request(minreq::Request),
Response(minreq::ResponseLazy),
Complete(Result<(), String>),
}

impl From<minreq::Request> for ResponseLazyReader {
fn from(request: minreq::Request) -> ResponseLazyReader {
ResponseLazyReader::Request(request)
}
}

impl From<minreq::ResponseLazy> for ResponseLazyReader {
fn from(response: minreq::ResponseLazy) -> ResponseLazyReader {
ResponseLazyReader::Response(response)
}
}

impl io::Read for ResponseLazyReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
use ResponseLazyReader::{Complete, Request, Response};

// Zero-sized buffer. This should never happen.
if buf.is_empty() {
return Ok(0);
}

loop {
match self {
// Launch a lazy response for this request
Request(request) => match request.clone().send_lazy() {
Ok(response) => *self = Response(response),
Err(error) => {
let error = Err(format!("download request failed: {:?}", error));

*self = Complete(error);
}
},

// Read from the response
Response(response) => {
// minreq has a very limited lazy reading interface.
match &mut response.next() {
// Read one byte into the buffer.
// We ignore the expected length, because we have no way of telling the BufReader.
Some(Ok((byte, _length))) => {
buf[0] = *byte;
return Ok(1);
}

// Reading failed.
Some(Err(error)) => {
let error = Err(format!("download response failed: {:?}", error));

*self = Complete(error);
}

// Finished reading.
None => *self = Complete(Ok(())),
}
}

Complete(result) => {
return match result {
// Return a zero-byte read for download success and EOF.
Ok(()) => Ok(0),
// Keep returning the download error,
Err(error) => Err(io::Error::new(io::ErrorKind::Other, error.clone())),
};
}
}
}
}
}
16 changes: 14 additions & 2 deletions zcash_proofs/src/hashreader.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use std::{
fmt::Write,
io::{self, Read},
};

use blake2b_simd::State;
use std::io::{self, Read};

/// Abstraction over a reader which hashes the data being read.
pub struct HashReader<R: Read> {
reader: R,
hasher: State,
byte_count: usize,
}

impl<R: Read> HashReader<R> {
Expand All @@ -13,6 +18,7 @@ impl<R: Read> HashReader<R> {
HashReader {
reader,
hasher: State::new(),
byte_count: 0,
}
}

Expand All @@ -22,11 +28,16 @@ impl<R: Read> HashReader<R> {

let mut s = String::new();
for c in hash.as_bytes().iter() {
s += &format!("{:02x}", c);
write!(&mut s, "{:02x}", c).expect("writing to a string never fails");
}

s
}

/// Return the number of bytes read so far.
pub fn byte_count(&self) -> usize {
self.byte_count
}
}

impl<R: Read> Read for HashReader<R> {
Expand All @@ -35,6 +46,7 @@ impl<R: Read> Read for HashReader<R> {

if bytes > 0 {
self.hasher.update(&buf[0..bytes]);
self.byte_count += bytes;
}

Ok(bytes)
Expand Down
Loading