diff --git a/lib/src/content_hash.rs b/lib/src/content_hash.rs index a727e4305..619b0c823 100644 --- a/lib/src/content_hash.rs +++ b/lib/src/content_hash.rs @@ -1,3 +1,4 @@ +use blake2::Blake2b512; use itertools::Itertools as _; /// Portable, stable hashing suitable for identifying values @@ -11,6 +12,13 @@ pub trait ContentHash { fn hash(&self, state: &mut impl digest::Update); } +pub fn blake2b_hash(x: &(impl ContentHash + ?Sized)) -> digest::Output { + use digest::Digest; + let mut hasher = Blake2b512::default(); + x.hash(&mut hasher); + hasher.finalize() +} + impl ContentHash for () { fn hash(&self, _: &mut impl digest::Update) {} } @@ -146,7 +154,7 @@ macro_rules! content_hash { mod tests { use std::collections::{BTreeMap, HashMap}; - use blake2::{Blake2b512, Digest}; + use blake2::Blake2b512; use super::*; @@ -220,8 +228,6 @@ mod tests { } fn hash(x: &(impl ContentHash + ?Sized)) -> digest::Output { - let mut hasher = Blake2b512::default(); - x.hash(&mut hasher); - hasher.finalize() + blake2b_hash(x) } } diff --git a/lib/src/local_backend.rs b/lib/src/local_backend.rs index c8d8ff84f..44f350077 100644 --- a/lib/src/local_backend.rs +++ b/lib/src/local_backend.rs @@ -27,7 +27,7 @@ use crate::backend::{ ConflictId, ConflictPart, FileId, MillisSinceEpoch, Signature, SymlinkId, Timestamp, Tree, TreeId, TreeValue, }; -use crate::content_hash::ContentHash; +use crate::content_hash::blake2b_hash; use crate::file_util::persist_content_addressed_temp_file; use crate::repo_path::{RepoPath, RepoPathComponent}; @@ -195,7 +195,7 @@ impl Backend for LocalBackend { let proto = tree_to_proto(tree); proto.write_to_writer(&mut temp_file.as_file())?; - let id = TreeId::new(hash(tree).to_vec()); + let id = TreeId::new(blake2b_hash(tree).to_vec()); persist_content_addressed_temp_file(temp_file, self.tree_path(&id))?; Ok(id) @@ -215,7 +215,7 @@ impl Backend for LocalBackend { let proto = conflict_to_proto(conflict); proto.write_to_writer(&mut temp_file.as_file())?; - let id = ConflictId::new(hash(conflict).to_vec()); + let id = ConflictId::new(blake2b_hash(conflict).to_vec()); persist_content_addressed_temp_file(temp_file, self.conflict_path(&id))?; Ok(id) @@ -239,7 +239,7 @@ impl Backend for LocalBackend { let proto = commit_to_proto(commit); proto.write_to_writer(&mut temp_file.as_file())?; - let id = CommitId::new(hash(commit).to_vec()); + let id = CommitId::new(blake2b_hash(commit).to_vec()); persist_content_addressed_temp_file(temp_file, self.commit_path(&id))?; Ok(id) @@ -406,9 +406,3 @@ fn conflict_part_to_proto(part: &ConflictPart) -> crate::protos::store::conflict proto.content = MessageField::some(tree_value_to_proto(&part.value)); proto } - -fn hash(x: &impl ContentHash) -> digest::Output { - let mut hasher = Blake2b512::default(); - x.hash(&mut hasher); - hasher.finalize() -} diff --git a/lib/src/proto_op_store.rs b/lib/src/proto_op_store.rs index 01b5097cb..e30639f9e 100644 --- a/lib/src/proto_op_store.rs +++ b/lib/src/proto_op_store.rs @@ -18,13 +18,12 @@ use std::fs::File; use std::io::ErrorKind; use std::path::PathBuf; -use blake2::Blake2b512; use itertools::Itertools; use protobuf::{Message, MessageField}; use tempfile::NamedTempFile; use crate::backend::{CommitId, MillisSinceEpoch, Timestamp}; -use crate::content_hash::ContentHash; +use crate::content_hash::blake2b_hash; use crate::file_util::persist_content_addressed_temp_file; use crate::op_store::{ BranchTarget, OpStore, OpStoreError, OpStoreResult, Operation, OperationId, OperationMetadata, @@ -79,7 +78,7 @@ impl OpStore for ProtoOpStore { let proto = view_to_proto(view); proto.write_to_writer(&mut temp_file.as_file())?; - let id = ViewId::new(hash(view).to_vec()); + let id = ViewId::new(blake2b_hash(view).to_vec()); persist_content_addressed_temp_file(temp_file, self.view_path(&id))?; Ok(id) @@ -99,7 +98,7 @@ impl OpStore for ProtoOpStore { let proto = operation_to_proto(operation); proto.write_to_writer(&mut temp_file.as_file())?; - let id = OperationId::new(hash(operation).to_vec()); + let id = OperationId::new(blake2b_hash(operation).to_vec()); persist_content_addressed_temp_file(temp_file, self.operation_path(&id))?; Ok(id) @@ -338,10 +337,3 @@ fn ref_target_from_proto(proto: &crate::protos::op_store::RefTarget) -> RefTarge } } } - -fn hash(x: &impl ContentHash) -> digest::Output { - use digest::Digest; - let mut hasher = Blake2b512::default(); - x.hash(&mut hasher); - hasher.finalize() -} diff --git a/lib/src/simple_op_store.rs b/lib/src/simple_op_store.rs index 8f5d1c46b..656fddedc 100644 --- a/lib/src/simple_op_store.rs +++ b/lib/src/simple_op_store.rs @@ -19,13 +19,12 @@ use std::fs::File; use std::io::{ErrorKind, Read, Write}; use std::path::PathBuf; -use blake2::Blake2b512; use itertools::Itertools; use tempfile::{NamedTempFile, PersistError}; use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol, TSerializable}; use crate::backend::{CommitId, MillisSinceEpoch, Timestamp}; -use crate::content_hash::ContentHash; +use crate::content_hash::blake2b_hash; use crate::file_util::persist_content_addressed_temp_file; use crate::op_store::{ BranchTarget, OpStore, OpStoreError, OpStoreResult, Operation, OperationId, OperationMetadata, @@ -243,7 +242,7 @@ impl OpStore for ThriftOpStore { } fn write_view(&self, view: &View) -> OpStoreResult { - let id = ViewId::new(hash(view).to_vec()); + let id = ViewId::new(blake2b_hash(view).to_vec()); let temp_file = NamedTempFile::new_in(&self.path)?; let thrift_view = simple_op_store_model::View::from(view); write_thrift(&thrift_view, &mut temp_file.as_file())?; @@ -259,7 +258,7 @@ impl OpStore for ThriftOpStore { } fn write_operation(&self, operation: &Operation) -> OpStoreResult { - let id = OperationId::new(hash(operation).to_vec()); + let id = OperationId::new(blake2b_hash(operation).to_vec()); let temp_file = NamedTempFile::new_in(&self.path)?; let thrift_operation = simple_op_store_model::Operation::from(operation); write_thrift(&thrift_operation, &mut temp_file.as_file())?; @@ -268,13 +267,6 @@ impl OpStore for ThriftOpStore { } } -fn hash(x: &impl ContentHash) -> digest::Output { - use digest::Digest; - let mut hasher = Blake2b512::default(); - x.hash(&mut hasher); - hasher.finalize() -} - pub fn read_thrift(input: &mut impl Read) -> OpStoreResult { let mut protocol = TCompactInputProtocol::new(input); Ok(TSerializable::read_from_in_protocol(&mut protocol).unwrap()) @@ -628,7 +620,7 @@ mod tests { fn test_hash_view() { // Test exact output so we detect regressions in compatibility assert_snapshot!( - ViewId::new(hash(&create_view()).to_vec()).hex(), + ViewId::new(blake2b_hash(&create_view()).to_vec()).hex(), @"2a026b6a091219a3d8ca43d822984cf9be0c53438225d76a5ba5e6d3724fab15104579fb08fa949977c4357b1806d240bef28d958cbcd7d786962ac88c15df31" ); } @@ -637,7 +629,7 @@ mod tests { fn test_hash_operation() { // Test exact output so we detect regressions in compatibility assert_snapshot!( - OperationId::new(hash(&create_operation()).to_vec()).hex(), + OperationId::new(blake2b_hash(&create_operation()).to_vec()).hex(), @"3ec986c29ff8eb808ea8f6325d6307cea75ef02987536c8e4645406aba51afc8e229957a6e855170d77a66098c58912309323f5e0b32760caa2b59dc84d45fcf" ); }