about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-03-30T23·32-0400
committerJohn Ericson <git@johnericson.me>2023-03-31T18·46+0000
commita8bd926e0fc22c706d01fe44db2d9f6ea2a552a4 (patch)
tree7f9ba21888cb27b9dd75b31292681bc66a68788b
parentb932cf2d85af64a383f8020394301889f5df04c5 (diff)
refactor(nix-compat): Avoid encoding round trip r/6069
When building store paths we can just construct the thing.

Change-Id: Ife5d461d6a440ecbb22f32a86a6d51d212a2035b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8409
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
-rw-r--r--tvix/nix-compat/src/store_path/utils.rs16
1 files changed, 10 insertions, 6 deletions
diff --git a/tvix/nix-compat/src/store_path/utils.rs b/tvix/nix-compat/src/store_path/utils.rs
index 4491177172..fa1908ee35 100644
--- a/tvix/nix-compat/src/store_path/utils.rs
+++ b/tvix/nix-compat/src/store_path/utils.rs
@@ -7,7 +7,7 @@ use super::Error;
 
 /// compress_hash takes an arbitrarily long sequence of bytes (usually
 /// a hash digest), and returns a sequence of bytes of length
-/// output_size.
+/// OUTPUT_SIZE.
 ///
 /// It's calculated by rotating through the bytes in the output buffer
 /// (zero- initialized), and XOR'ing with each byte of the passed
@@ -15,11 +15,11 @@ use super::Error;
 /// value in the output buffer.
 ///
 /// This mimics equivalent functionality in C++ Nix.
-pub fn compress_hash(input: &[u8], output_size: usize) -> Vec<u8> {
-    let mut output: Vec<u8> = vec![0; output_size];
+pub fn compress_hash<const OUTPUT_SIZE: usize>(input: &[u8]) -> [u8; OUTPUT_SIZE] {
+    let mut output = [0; OUTPUT_SIZE];
 
     for (ii, ch) in input.iter().enumerate() {
-        output[ii % output_size] ^= ch;
+        output[ii % OUTPUT_SIZE] ^= ch;
     }
 
     output
@@ -56,8 +56,12 @@ pub fn build_store_path_from_fingerprint(
         let hasher = Sha256::new_with_prefix(fingerprint);
         hasher.finalize()
     };
-    let compressed = compress_hash(&digest, 20);
-    StorePath::from_string(format!("{}-{}", nixbase32::encode(&compressed), name).as_str())
+    let compressed = compress_hash::<20>(&digest);
+    StorePath::validate_name(name)?;
+    Ok(StorePath {
+        digest: compressed,
+        name: name.to_string(),
+    })
 }
 
 /// This contains the Nix logic to create "text hash strings", which are used