From 971080c9120725c0bec21ea2e5e14847b0e996e6 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Thu, 30 Mar 2023 13:27:23 +0200 Subject: refactor(tvix/nix-compat): add text_hash_string function Use it to calculate the text_hash_string, which is then used in the calculate_derivation_path and path_with_references functions. Relates to b/263. Change-Id: I7478825e2a23a11224212fea5e3fd06daa97d5e5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/8364 Autosubmit: flokli Reviewed-by: tazjin Tested-by: BuildkiteCI --- tvix/nix-compat/src/derivation/mod.rs | 46 ++++++++------------------------- tvix/nix-compat/src/derivation/utils.rs | 29 +++------------------ 2 files changed, 15 insertions(+), 60 deletions(-) (limited to 'tvix/nix-compat/src/derivation') diff --git a/tvix/nix-compat/src/derivation/mod.rs b/tvix/nix-compat/src/derivation/mod.rs index 281fe3a3c875..53bdccef6dce 100644 --- a/tvix/nix-compat/src/derivation/mod.rs +++ b/tvix/nix-compat/src/derivation/mod.rs @@ -1,6 +1,7 @@ use crate::{ nixhash::HashAlgo, store_path::{self, StorePath}, + texthash::text_hash_string, }; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -78,26 +79,17 @@ impl Derivation { /// Returns the drv path of a Derivation struct. /// - /// The drv path is calculated like this: - /// - Write the fingerprint of the Derivation to the sha256 hash function. - /// This is: `text:`, - /// all d.InputDerivations and d.InputSources (sorted, separated by a `:`), - /// a `:`, - /// the nix string representation of the sha256 sum of the ATerm representation - /// a `:`, - /// the storeDir, followed by a `:`, - /// the name of a derivation, - /// a `.drv`. - /// - Write the .drv A-Term contents to a hash function - /// - Take the digest, run hash.CompressHash(digest, 20) on it. - /// - Encode it with nixbase32 - /// - Use it (and the name) to construct a [StorePath]. + /// The drv path is calculated by calculating the [text_hash_string], using + /// the `name` with a `.drv` suffix as name, all d.InputDerivations and d.InputSources as references, + /// and the ATerm representation of the Derivation as contents. + /// The text_hash_string is then passed to the build_store_path function. pub fn calculate_derivation_path(&self, name: &str) -> Result { - let mut s = String::from("text:"); + // append .drv to the name + let name_with_suffix = &format!("{}.drv", name); // collect the list of paths from input_sources and input_derivations - // into a (sorted, guaranteed by BTreeSet) list, and join them by : - let concat_inputs: BTreeSet = { + // into a (sorted, guaranteed by BTreeSet) list of references + let references: BTreeSet = { let mut inputs = self.input_sources.clone(); let input_derivation_keys: Vec = self.input_derivations.keys().cloned().collect(); @@ -105,25 +97,9 @@ impl Derivation { inputs }; - for input in concat_inputs { - s.push_str(&input); - s.push(':'); - } - - // calculate the sha256 hash of the ATerm representation, and represent - // it as a hex-encoded string (prefixed with sha256:). - let aterm_digest = Sha256::new_with_prefix(self.to_aterm_string()) - .finalize() - .to_vec(); - - s.push_str(&format!( - "{}:{}:{}.drv", - NixHash::new(HashAlgo::Sha256, aterm_digest).to_nix_hash_string(), - store_path::STORE_DIR, - name, - )); + let text_hash_str = &text_hash_string(name_with_suffix, self.to_aterm_string(), references); - utils::build_store_path(true, &s, name) + utils::build_store_path(true, text_hash_str, name) } /// Returns the FOD digest, if the derivation is fixed-output, or None if diff --git a/tvix/nix-compat/src/derivation/utils.rs b/tvix/nix-compat/src/derivation/utils.rs index cbb5d02a2180..68ab3e23c94b 100644 --- a/tvix/nix-compat/src/derivation/utils.rs +++ b/tvix/nix-compat/src/derivation/utils.rs @@ -1,7 +1,7 @@ use crate::derivation::DerivationError; use crate::nixbase32; -use crate::nixhash::NixHash; -use crate::store_path::{self, StorePath}; +use crate::store_path::StorePath; +use crate::texthash::text_hash_string; use sha2::{Digest, Sha256}; /// compress_hash takes an arbitrarily long sequence of bytes (usually @@ -55,27 +55,6 @@ pub fn path_with_references, I: IntoIterator, C: AsRef<[ content: C, references: I, ) -> Result { - let mut s = String::from("text"); - - for reference in references { - s.push(':'); - s.push_str(reference.as_ref()); - } - - let content_digest = { - let mut hasher = Sha256::new(); - hasher.update(content); - hasher.finalize() - }; - - let h = NixHash::new(crate::nixhash::HashAlgo::Sha256, content_digest.to_vec()); - - s.push_str(&format!( - ":{}:{}:{}", - h.to_nix_hash_string(), - store_path::STORE_DIR, - name - )); - - build_store_path(false, &s, name) + let text_hash_str = text_hash_string(name, content, references); + build_store_path(false, &text_hash_str, name) } -- cgit 1.4.1