dapps-fetcher: calculate keccak in-flight while reading the response (#8294)

* dapps-fetcher: calculate keccak in-flight while reading the response

* Rename keccak_buffer_and_write -> keccak_pipe

* Fix file read bug by creating another file handle as the return value
This commit is contained in:
Wei Tang 2018-04-03 20:58:55 +08:00 committed by Rando
parent 99a13c4e66
commit 5e7d42e4a4
2 changed files with 18 additions and 7 deletions

View File

@ -21,7 +21,7 @@ use std::path::PathBuf;
use ethereum_types::H256; use ethereum_types::H256;
use fetch; use fetch;
use futures_cpupool::CpuPool; use futures_cpupool::CpuPool;
use hash::keccak_buffer; use hash::keccak_pipe;
use mime_guess::Mime; use mime_guess::Mime;
use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest, serialize_manifest, Manifest}; use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest, serialize_manifest, Manifest};
@ -55,15 +55,15 @@ fn write_response_and_check_hash(
// Now write the response // Now write the response
let mut file = io::BufWriter::new(fs::File::create(&content_path)?); let mut file = io::BufWriter::new(fs::File::create(&content_path)?);
let mut reader = io::BufReader::new(fetch::BodyReader::new(response)); let mut reader = io::BufReader::new(fetch::BodyReader::new(response));
io::copy(&mut reader, &mut file)?; let hash = keccak_pipe(&mut reader, &mut file)?;
let mut file = file.into_inner()?;
file.flush()?; file.flush()?;
// Validate hash // Validate hash
// TODO [ToDr] calculate keccak in-flight while reading the response
let mut file = io::BufReader::new(fs::File::open(&content_path)?);
let hash = keccak_buffer(&mut file)?;
if id == hash { if id == hash {
Ok((file.into_inner(), content_path)) // The writing above changed the file Read position, which we need later. So we just create a new file handle
// here.
Ok((fs::File::open(&content_path)?, content_path))
} else { } else {
Err(ValidationError::HashMismatch { Err(ValidationError::HashMismatch {
expected: id, expected: id,
@ -266,3 +266,9 @@ impl From<zip::result::ZipError> for ValidationError {
ValidationError::Zip(err) ValidationError::Zip(err)
} }
} }
impl From<io::IntoInnerError<io::BufWriter<fs::File>>> for ValidationError {
fn from(err: io::IntoInnerError<io::BufWriter<fs::File>>) -> Self {
ValidationError::Io(err.into())
}
}

View File

@ -52,7 +52,7 @@ pub fn write_keccak<T: AsRef<[u8]>>(s: T, dest: &mut [u8]) {
} }
} }
pub fn keccak_buffer(r: &mut io::BufRead) -> Result<H256, io::Error> { pub fn keccak_pipe(r: &mut io::BufRead, w: &mut io::Write) -> Result<H256, io::Error> {
let mut output = [0u8; 32]; let mut output = [0u8; 32];
let mut input = [0u8; 1024]; let mut input = [0u8; 1024];
let mut keccak = Keccak::new_keccak256(); let mut keccak = Keccak::new_keccak256();
@ -64,12 +64,17 @@ pub fn keccak_buffer(r: &mut io::BufRead) -> Result<H256, io::Error> {
break; break;
} }
keccak.update(&input[0..some]); keccak.update(&input[0..some]);
w.write_all(&input[0..some])?;
} }
keccak.finalize(&mut output); keccak.finalize(&mut output);
Ok(output.into()) Ok(output.into())
} }
pub fn keccak_buffer(r: &mut io::BufRead) -> Result<H256, io::Error> {
keccak_pipe(r, &mut io::sink())
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
extern crate tempdir; extern crate tempdir;