diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 829119238..b6476e006 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1292,8 +1292,11 @@ drvName, Bindings * attrs, Value & v) auto method = ingestionMethod.value_or(FileIngestionMethod::Flat); DerivationOutput::CAFixed dof { - // FIXME non-trivial fixed refs set - .ca = contentAddressFromMethodHashAndRefs(method, std::move(h), {}), + .ca = ContentAddressWithReferences::fromParts( + std::move(method), + std::move(h), + // FIXME non-trivial fixed refs set + {}), }; drv.env["out"] = state.store->printStorePath(dof.path(*state.store, drvName, "out")); @@ -1315,13 +1318,13 @@ drvName, Bindings * attrs, Value & v) if (isImpure) drv.outputs.insert_or_assign(i, DerivationOutput::Impure { - .method = method, + .method = method.raw, .hashType = ht, }); else drv.outputs.insert_or_assign(i, DerivationOutput::CAFloating { - .method = method, + .method = method.raw, .hashType = ht, }); } diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 449ff13e8..7cb80977d 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -2451,12 +2451,12 @@ DrvOutputs LocalDerivationGoal::registerOutputs() break; } }, - }, outputHash.method); + }, outputHash.method.raw); auto got = caSink.finish().first; ValidPathInfo newInfo0 { worker.store, outputPathName(drv->name, outputName), - contentAddressFromMethodHashAndRefs( + ContentAddressWithReferences::fromParts( outputHash.method, std::move(got), rewriteRefs()), @@ -2506,16 +2506,16 @@ DrvOutputs LocalDerivationGoal::registerOutputs() }, [&](const DerivationOutput::CAFixed & dof) { - auto wanted = getContentAddressHash(dof.ca); + auto wanted = dof.ca.getHash(); auto newInfo0 = newInfoFromCA(DerivationOutputCAFloating { - .method = getContentAddressMethod(dof.ca), + .method = dof.ca.getMethod(), .hashType = wanted.type, }); /* Check wanted hash */ assert(newInfo0.ca); - auto got = getContentAddressHash(*newInfo0.ca); + auto got = newInfo0.ca->getHash(); if (wanted != got) { /* Throw an error after registering the path as valid. */ diff --git a/src/libstore/build/substitution-goal.cc b/src/libstore/build/substitution-goal.cc index 87fed495c..190fb455a 100644 --- a/src/libstore/build/substitution-goal.cc +++ b/src/libstore/build/substitution-goal.cc @@ -97,7 +97,7 @@ void PathSubstitutionGoal::tryNext() if (ca) { subPath = sub->makeFixedOutputPathFromCA( std::string { storePath.name() }, - caWithoutRefs(*ca)); + ContentAddressWithReferences::withoutRefs(*ca)); if (sub->storeDir == worker.store.storeDir) assert(subPath == storePath); } else if (sub->storeDir != worker.store.storeDir) { diff --git a/src/libstore/content-address.cc b/src/libstore/content-address.cc index 2cec4fe05..8c04dd285 100644 --- a/src/libstore/content-address.cc +++ b/src/libstore/content-address.cc @@ -9,7 +9,6 @@ std::string FixedOutputHash::printMethodAlgo() const return makeFileIngestionPrefix(method) + printHashType(hash.type); } - std::string makeFileIngestionPrefix(FileIngestionMethod m) { switch (m) { @@ -22,17 +21,17 @@ std::string makeFileIngestionPrefix(FileIngestionMethod m) } } -std::string makeContentAddressingPrefix(ContentAddressMethod m) { +std::string ContentAddressMethod::renderPrefix() const { return std::visit(overloaded { [](TextHashMethod) -> std::string { return "text:"; }, [](FileIngestionMethod m2) { /* Not prefixed for back compat with things that couldn't produce text before. */ return makeFileIngestionPrefix(m2); }, - }, m); + }, raw); } -ContentAddressMethod parseContentAddressingPrefix(std::string_view & m) +ContentAddressMethod ContentAddressMethod::parsePrefix(std::string_view & m) { ContentAddressMethod method = FileIngestionMethod::Flat; if (splitPrefix(m, "r:")) @@ -42,35 +41,35 @@ ContentAddressMethod parseContentAddressingPrefix(std::string_view & m) return method; } -std::string renderContentAddress(ContentAddress ca) +std::string ContentAddress::render() const { return std::visit(overloaded { - [](TextHash & th) { + [](const TextHash & th) { return "text:" + th.hash.to_string(Base32, true); }, - [](FixedOutputHash & fsh) { + [](const FixedOutputHash & fsh) { return "fixed:" + makeFileIngestionPrefix(fsh.method) + fsh.hash.to_string(Base32, true); } - }, ca); + }, raw); } -std::string renderContentAddressMethodAndHash(ContentAddressMethod cam, HashType ht) +std::string ContentAddressMethod::render(HashType ht) const { return std::visit(overloaded { - [&](TextHashMethod & th) { + [&](const TextHashMethod & th) { return std::string{"text:"} + printHashType(ht); }, - [&](FileIngestionMethod & fim) { + [&](const FileIngestionMethod & fim) { return "fixed:" + makeFileIngestionPrefix(fim) + printHashType(ht); } - }, cam); + }, raw); } -/* - Parses content address strings up to the hash. +/** + * Parses content address strings up to the hash. */ static std::pair parseContentAddressMethodPrefix(std::string_view & rest) { @@ -114,7 +113,7 @@ static std::pair parseContentAddressMethodPrefix throw UsageError("content address prefix '%s' is unrecognized. Recogonized prefixes are 'text' or 'fixed'", prefix); } -ContentAddress parseContentAddress(std::string_view rawCa) { +ContentAddress ContentAddress::parse(std::string_view rawCa) { auto rest = rawCa; auto [caMethod, hashType_] = parseContentAddressMethodPrefix(rest); @@ -132,10 +131,10 @@ ContentAddress parseContentAddress(std::string_view rawCa) { .hash = Hash::parseNonSRIUnprefixed(rest, hashType), }); }, - }, caMethod); + }, caMethod.raw); } -std::pair parseContentAddressMethod(std::string_view caMethod) +std::pair ContentAddressMethod::parse(std::string_view caMethod) { std::string asPrefix = std::string{caMethod} + ":"; // parseContentAddressMethodPrefix takes its argument by reference @@ -143,18 +142,20 @@ std::pair parseContentAddressMethod(std::string_ return parseContentAddressMethodPrefix(asPrefixView); } -std::optional parseContentAddressOpt(std::string_view rawCaOpt) +std::optional ContentAddress::parseOpt(std::string_view rawCaOpt) { - return rawCaOpt == "" ? std::optional() : parseContentAddress(rawCaOpt); + return rawCaOpt == "" + ? std::nullopt + : std::optional { ContentAddress::parse(rawCaOpt) }; }; std::string renderContentAddress(std::optional ca) { - return ca ? renderContentAddress(*ca) : ""; + return ca ? ca->render() : ""; } -ContentAddressWithReferences contentAddressFromMethodHashAndRefs( - ContentAddressMethod method, Hash && hash, StoreReferences && refs) +ContentAddressWithReferences ContentAddressWithReferences::fromParts( + ContentAddressMethod method, Hash hash, StoreReferences refs) { return std::visit(overloaded { [&](TextHashMethod _) -> ContentAddressWithReferences { @@ -174,10 +175,10 @@ ContentAddressWithReferences contentAddressFromMethodHashAndRefs( .references = std::move(refs), }; }, - }, method); + }, method.raw); } -ContentAddressMethod getContentAddressMethod(const ContentAddressWithReferences & ca) +ContentAddressMethod ContentAddressWithReferences::getMethod() const { return std::visit(overloaded { [](const TextInfo & th) -> ContentAddressMethod { @@ -186,19 +187,19 @@ ContentAddressMethod getContentAddressMethod(const ContentAddressWithReferences [](const FixedOutputInfo & fsh) -> ContentAddressMethod { return fsh.hash.method; }, - }, ca); + }, raw); } -Hash getContentAddressHash(const ContentAddress & ca) +const Hash & ContentAddress::getHash() const { return std::visit(overloaded { - [](const TextHash & th) { + [](const TextHash & th) -> auto & { return th.hash; }, - [](const FixedOutputHash & fsh) { + [](const FixedOutputHash & fsh) -> auto & { return fsh.hash; }, - }, ca); + }, raw); } bool StoreReferences::empty() const @@ -211,7 +212,7 @@ size_t StoreReferences::size() const return (self ? 1 : 0) + others.size(); } -ContentAddressWithReferences caWithoutRefs(const ContentAddress & ca) { +ContentAddressWithReferences ContentAddressWithReferences::withoutRefs(const ContentAddress & ca) { return std::visit(overloaded { [&](const TextHash & h) -> ContentAddressWithReferences { return TextInfo { @@ -225,10 +226,10 @@ ContentAddressWithReferences caWithoutRefs(const ContentAddress & ca) { .references = {}, }; }, - }, ca); + }, ca.raw); } -Hash getContentAddressHash(const ContentAddressWithReferences & ca) +Hash ContentAddressWithReferences::getHash() const { return std::visit(overloaded { [](const TextInfo & th) { @@ -237,12 +238,12 @@ Hash getContentAddressHash(const ContentAddressWithReferences & ca) [](const FixedOutputInfo & fsh) { return fsh.hash.hash; }, - }, ca); + }, raw); } -std::string printMethodAlgo(const ContentAddressWithReferences & ca) { - return makeContentAddressingPrefix(getContentAddressMethod(ca)) - + printHashType(getContentAddressHash(ca).type); +std::string ContentAddressWithReferences::printMethodAlgo() const { + return getMethod().renderPrefix() + + printHashType(getHash().type); } } diff --git a/src/libstore/content-address.hh b/src/libstore/content-address.hh index d173f6027..7704d2f00 100644 --- a/src/libstore/content-address.hh +++ b/src/libstore/content-address.hh @@ -45,7 +45,6 @@ enum struct FileIngestionMethod : uint8_t { */ std::string makeFileIngestionPrefix(FileIngestionMethod m); - /** * An enumeration of all the ways we can serialize file system objects. * @@ -54,25 +53,40 @@ std::string makeFileIngestionPrefix(FileIngestionMethod m); * with info on references, and we have `ContentAddressWithReferences`, * as defined further below. */ -typedef std::variant< - TextHashMethod, - FileIngestionMethod -> ContentAddressMethod; +struct ContentAddressMethod +{ + typedef std::variant< + TextHashMethod, + FileIngestionMethod + > Raw; -/* Parse and pretty print the algorithm which indicates how the files - were ingested, with the the fixed output case not prefixed for back - compat. */ + Raw raw; -std::string makeContentAddressingPrefix(ContentAddressMethod m); + GENERATE_CMP(ContentAddressMethod, me->raw); -ContentAddressMethod parseContentAddressingPrefix(std::string_view & m); + /* The moral equivalent of `using Raw::Raw;` */ + ContentAddressMethod(auto &&... arg) + : raw(std::forward(arg)...) + { } -/* Parse and pretty print a content addressing method and hash in a - nicer way, prefixing both cases. */ -std::string renderContentAddressMethodAndHash(ContentAddressMethod cam, HashType ht); + /** + * Parse and pretty print the algorithm which indicates how the files + * were ingested, with the the fixed output case not prefixed for back + * compat. + */ + static ContentAddressMethod parsePrefix(std::string_view & m); -std::pair parseContentAddressMethod(std::string_view caMethod); + std::string renderPrefix() const; + + /** + * Parse and pretty print a content addressing method and hash type in a + * nicer way, prefixing both cases. + */ + static std::pair parse(std::string_view rawCaMethod); + + std::string render(HashType ht) const; +}; /* @@ -122,25 +136,43 @@ struct FixedOutputHash { * - ‘fixed:::’: For paths computed by * Store::makeFixedOutputPath() / Store::addToStore(). */ -typedef std::variant< - TextHash, - FixedOutputHash -> ContentAddress; +struct ContentAddress +{ + typedef std::variant< + TextHash, + FixedOutputHash + > Raw; -/** - * Compute the content-addressability assertion (ValidPathInfo::ca) for - * paths created by Store::makeFixedOutputPath() / Store::addToStore(). - */ -std::string renderContentAddress(ContentAddress ca); + Raw raw; + + GENERATE_CMP(ContentAddress, me->raw); + + /* The moral equivalent of `using Raw::Raw;` */ + ContentAddress(auto &&... arg) + : raw(std::forward(arg)...) + { } + + /** + * Compute the content-addressability assertion (ValidPathInfo::ca) for + * paths created by Store::makeFixedOutputPath() / Store::addToStore(). + */ + std::string render() const; + + static ContentAddress parse(std::string_view rawCa); + + static std::optional parseOpt(std::string_view rawCaOpt); + + const Hash & getHash() const; +}; std::string renderContentAddress(std::optional ca); -ContentAddress parseContentAddress(std::string_view rawCa); - -std::optional parseContentAddressOpt(std::string_view rawCaOpt); - -Hash getContentAddressHash(const ContentAddress & ca); +/* + * Full content address + * + * See the schema for store paths in store-api.cc + */ /** * A set of references to other store objects. @@ -174,12 +206,6 @@ struct StoreReferences { GENERATE_CMP(StoreReferences, me->self, me->others); }; -/* - * Full content address - * - * See the schema for store paths in store-api.cc - */ - // This matches the additional info that we need for makeTextPath struct TextInfo { TextHash hash; @@ -207,23 +233,47 @@ struct FixedOutputInfo { * * A ContentAddress without a Hash. */ -typedef std::variant< - TextInfo, - FixedOutputInfo -> ContentAddressWithReferences; +struct ContentAddressWithReferences +{ + typedef std::variant< + TextInfo, + FixedOutputInfo + > Raw; -/** - * Create a ContentAddressWithReferences from a mere ContentAddress, by - * assuming no references in all cases. - */ -ContentAddressWithReferences caWithoutRefs(const ContentAddress &); + Raw raw; -ContentAddressWithReferences contentAddressFromMethodHashAndRefs( - ContentAddressMethod method, Hash && hash, StoreReferences && refs); + GENERATE_CMP(ContentAddressWithReferences, me->raw); -ContentAddressMethod getContentAddressMethod(const ContentAddressWithReferences & ca); -Hash getContentAddressHash(const ContentAddressWithReferences & ca); + /* The moral equivalent of `using Raw::Raw;` */ + ContentAddressWithReferences(auto &&... arg) + : raw(std::forward(arg)...) + { } -std::string printMethodAlgo(const ContentAddressWithReferences &); + /** + * Create a ContentAddressWithReferences from a mere ContentAddress, by + * assuming no references in all cases. + */ + static ContentAddressWithReferences withoutRefs(const ContentAddress &); + + /** + * Create a ContentAddressWithReferences from 3 parts: + * + * @param method Way ingesting the file system data. + * + * @param hash Hash of ingested file system data. + * + * @param refs References to other store objects or oneself. + * + * Do note that not all combinations are supported. + */ + static ContentAddressWithReferences fromParts( + ContentAddressMethod method, Hash hash, StoreReferences refs); + + ContentAddressMethod getMethod() const; + + Hash getHash() const; + + std::string printMethodAlgo() const; +}; } diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 7cb378e12..0e2169035 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -401,12 +401,12 @@ static void performOp(TunnelLogger * logger, ref store, logger->startWork(); auto pathInfo = [&]() { // NB: FramedSource must be out of scope before logger->stopWork(); - auto [contentAddressMethod, hashType_] = parseContentAddressMethod(camStr); + auto [contentAddressMethod, hashType_] = ContentAddressMethod::parse(camStr); auto hashType = hashType_; // work around clang bug FramedSource source(from); // TODO this is essentially RemoteStore::addCAToStore. Move it up to Store. return std::visit(overloaded { - [&](TextHashMethod &) { + [&](const TextHashMethod &) { if (hashType != htSHA256) throw UnimplementedError("Only SHA-256 is supported for adding text-hashed data, but '%1' was given", printHashType(hashType)); @@ -415,11 +415,11 @@ static void performOp(TunnelLogger * logger, ref store, auto path = store->addTextToStore(name, contents, refs, repair); return store->queryPathInfo(path); }, - [&](FileIngestionMethod & fim) { + [&](const FileIngestionMethod & fim) { auto path = store->addToStoreFromDump(source, name, fim, hashType, repair, refs); return store->queryPathInfo(path); }, - }, contentAddressMethod); + }, contentAddressMethod.raw); }(); logger->stopWork(); @@ -884,7 +884,7 @@ static void performOp(TunnelLogger * logger, ref store, info.references = worker_proto::read(*store, from, Phantom {}); from >> info.registrationTime >> info.narSize >> info.ultimate; info.sigs = readStrings(from); - info.ca = parseContentAddressOpt(readString(from)); + info.ca = ContentAddress::parseOpt(readString(from)); from >> repair >> dontCheckSigs; if (!trusted && dontCheckSigs) dontCheckSigs = false; diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 6a3a904e2..aaae864f4 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -215,7 +215,7 @@ static DerivationOutput parseDerivationOutput(const Store & store, std::string_view pathS, std::string_view hashAlgo, std::string_view hashS) { if (hashAlgo != "") { - ContentAddressMethod method = parseContentAddressingPrefix(hashAlgo); + ContentAddressMethod method = ContentAddressMethod::parsePrefix(hashAlgo); const auto hashType = parseHashType(hashAlgo); if (hashS == "impure") { experimentalFeatureSettings.require(Xp::ImpureDerivations); @@ -228,9 +228,11 @@ static DerivationOutput parseDerivationOutput(const Store & store, validatePath(pathS); auto hash = Hash::parseNonSRIUnprefixed(hashS, hashType); return DerivationOutput::CAFixed { - // FIXME non-trivial fixed refs set - .ca = contentAddressFromMethodHashAndRefs( - method, std::move(hash), {}), + .ca = ContentAddressWithReferences::fromParts( + std::move(method), + std::move(hash), + // FIXME non-trivial fixed refs set + {}), }; } else { experimentalFeatureSettings.require(Xp::CaDerivations); @@ -381,12 +383,12 @@ std::string Derivation::unparse(const Store & store, bool maskOutputs, }, [&](const DerivationOutput::CAFixed & dof) { s += ','; printUnquotedString(s, maskOutputs ? "" : store.printStorePath(dof.path(store, name, i.first))); - s += ','; printUnquotedString(s, printMethodAlgo(dof.ca)); - s += ','; printUnquotedString(s, getContentAddressHash(dof.ca).to_string(Base16, false)); + s += ','; printUnquotedString(s, dof.ca.printMethodAlgo()); + s += ','; printUnquotedString(s, dof.ca.getHash().to_string(Base16, false)); }, [&](const DerivationOutput::CAFloating & dof) { s += ','; printUnquotedString(s, ""); - s += ','; printUnquotedString(s, makeContentAddressingPrefix(dof.method) + printHashType(dof.hashType)); + s += ','; printUnquotedString(s, dof.method.renderPrefix() + printHashType(dof.hashType)); s += ','; printUnquotedString(s, ""); }, [&](const DerivationOutput::Deferred &) { @@ -397,7 +399,7 @@ std::string Derivation::unparse(const Store & store, bool maskOutputs, [&](const DerivationOutputImpure & doi) { // FIXME s += ','; printUnquotedString(s, ""); - s += ','; printUnquotedString(s, makeContentAddressingPrefix(doi.method) + printHashType(doi.hashType)); + s += ','; printUnquotedString(s, doi.method.renderPrefix() + printHashType(doi.hashType)); s += ','; printUnquotedString(s, "impure"); } }, i.second.raw()); @@ -614,8 +616,8 @@ DrvHash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOut for (const auto & i : drv.outputs) { auto & dof = std::get(i.second.raw()); auto hash = hashString(htSHA256, "fixed:out:" - + printMethodAlgo(dof.ca) + ":" - + getContentAddressHash(dof.ca).to_string(Base16, false) + ":" + + dof.ca.printMethodAlgo() + ":" + + dof.ca.getHash().to_string(Base16, false) + ":" + store.printStorePath(dof.path(store, drv.name, i.first))); outputHashes.insert_or_assign(i.first, std::move(hash)); } @@ -765,12 +767,12 @@ void writeDerivation(Sink & out, const Store & store, const BasicDerivation & dr }, [&](const DerivationOutput::CAFixed & dof) { out << store.printStorePath(dof.path(store, drv.name, i.first)) - << printMethodAlgo(dof.ca) - << getContentAddressHash(dof.ca).to_string(Base16, false); + << dof.ca.printMethodAlgo() + << dof.ca.getHash().to_string(Base16, false); }, [&](const DerivationOutput::CAFloating & dof) { out << "" - << (makeContentAddressingPrefix(dof.method) + printHashType(dof.hashType)) + << (dof.method.renderPrefix() + printHashType(dof.hashType)) << ""; }, [&](const DerivationOutput::Deferred &) { @@ -780,7 +782,7 @@ void writeDerivation(Sink & out, const Store & store, const BasicDerivation & dr }, [&](const DerivationOutput::Impure & doi) { out << "" - << (makeContentAddressingPrefix(doi.method) + printHashType(doi.hashType)) + << (doi.method.renderPrefix() + printHashType(doi.hashType)) << "impure"; }, }, i.second.raw()); @@ -898,16 +900,16 @@ nlohmann::json DerivationOutput::toJSON( }, [&](const DerivationOutput::CAFixed & dof) { res["path"] = store.printStorePath(dof.path(store, drvName, outputName)); - res["hashAlgo"] = printMethodAlgo(dof.ca); - res["hash"] = getContentAddressHash(dof.ca).to_string(Base16, false); + res["hashAlgo"] = dof.ca.printMethodAlgo(); + res["hash"] = dof.ca.getHash().to_string(Base16, false); // FIXME print refs? }, [&](const DerivationOutput::CAFloating & dof) { - res["hashAlgo"] = makeContentAddressingPrefix(dof.method) + printHashType(dof.hashType); + res["hashAlgo"] = dof.method.renderPrefix() + printHashType(dof.hashType); }, [&](const DerivationOutput::Deferred &) {}, [&](const DerivationOutput::Impure & doi) { - res["hashAlgo"] = makeContentAddressingPrefix(doi.method) + printHashType(doi.hashType); + res["hashAlgo"] = doi.method.renderPrefix() + printHashType(doi.hashType); res["impure"] = true; }, }, raw()); diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 98322b045..a1c38d180 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -156,7 +156,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor throw Error("NAR hash is now mandatory"); info->narHash = Hash::parseAnyPrefixed(s); } - info->ca = parseContentAddressOpt(readString(conn->from)); + info->ca = ContentAddress::parseOpt(readString(conn->from)); info->sigs = readStrings(conn->from); auto s = readString(conn->from); diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index d31d2d130..63039e6ad 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -944,7 +944,7 @@ std::shared_ptr LocalStore::queryPathInfoInternal(State & s if (s) info->sigs = tokenizeString(s, " "); s = (const char *) sqlite3_column_text(state.stmts->QueryPathInfo, 7); - if (s) info->ca = parseContentAddressOpt(s); + if (s) info->ca = ContentAddress::parseOpt(s); /* Get the references. */ auto useQueryReferences(state.stmts->QueryReferences.use()(info->id)); @@ -1150,7 +1150,7 @@ void LocalStore::querySubstitutablePathInfos(const StorePathCAMap & paths, Subst if (path.second) { subPath = makeFixedOutputPathFromCA( path.first.name(), - caWithoutRefs(*path.second)); + ContentAddressWithReferences::withoutRefs(*path.second)); if (sub->storeDir == storeDir) assert(subPath == path.first); if (subPath != path.first) @@ -1329,7 +1329,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, printStorePath(info.path), info.narSize, hashResult.second); if (info.ca) { - if (auto foHash = std::get_if(&*info.ca)) { + if (auto foHash = std::get_if(&info.ca->raw)) { auto actualFoHash = hashCAPath( foHash->method, foHash->hash.type, @@ -1342,7 +1342,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, actualFoHash.hash.to_string(Base32, true)); } } - if (auto textHash = std::get_if(&*info.ca)) { + if (auto textHash = std::get_if(&info.ca->raw)) { auto actualTextHash = hashString(htSHA256, readFile(realPath)); if (textHash->hash != actualTextHash) { throw Error("ca hash mismatch importing path '%s';\n specified: %s\n got: %s", diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 63bbe5491..39bdfec6e 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -100,7 +100,7 @@ std::optional getDerivationCA(const BasicDerivation & drv) return std::nullopt; return fi.hash; }, - }, dof->ca); + }, dof->ca.raw); } return std::nullopt; } diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index 2645f468b..c7176d30f 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -273,7 +273,7 @@ public: narInfo->deriver = StorePath(queryNAR.getStr(9)); for (auto & sig : tokenizeString(queryNAR.getStr(10), " ")) narInfo->sigs.insert(sig); - narInfo->ca = parseContentAddressOpt(queryNAR.getStr(11)); + narInfo->ca = ContentAddress::parseOpt(queryNAR.getStr(11)); return {oValid, narInfo}; }); diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index 071d8355e..274cd861c 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -74,7 +74,7 @@ NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & else if (name == "CA") { if (ca) throw corrupt(); // FIXME: allow blank ca or require skipping field? - ca = parseContentAddressOpt(value); + ca = ContentAddress::parseOpt(value); } pos = eol + 1; diff --git a/src/libstore/path-info.cc b/src/libstore/path-info.cc index 76cab63e0..e60d7abe0 100644 --- a/src/libstore/path-info.cc +++ b/src/libstore/path-info.cc @@ -49,7 +49,7 @@ std::optional ValidPathInfo::contentAddressWithRef }, }; }, - }, *ca); + }, ca->raw); } bool ValidPathInfo::isContentAddressed(const Store & store) const @@ -116,7 +116,7 @@ ValidPathInfo::ValidPathInfo( this->references.insert(path); this->ca = std::move((FixedOutputHash &&) foi); }, - }, std::move(ca)); + }, std::move(ca).raw); } @@ -136,7 +136,7 @@ ValidPathInfo ValidPathInfo::read(Source & source, const Store & store, unsigned if (format >= 16) { source >> info.ultimate; info.sigs = readStrings(source); - info.ca = parseContentAddressOpt(readString(source)); + info.ca = ContentAddress::parseOpt(readString(source)); } return info; } diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 6336044b5..1c6b8530d 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -44,7 +44,7 @@ void write(const Store & store, Sink & out, const StorePath & storePath) ContentAddress read(const Store & store, Source & from, Phantom _) { - return parseContentAddress(readString(from)); + return ContentAddress::parse(readString(from)); } void write(const Store & store, Sink & out, const ContentAddress & ca) @@ -134,7 +134,7 @@ void write(const Store & store, Sink & out, const std::optional & sto std::optional read(const Store & store, Source & from, Phantom> _) { - return parseContentAddressOpt(readString(from)); + return ContentAddress::parseOpt(readString(from)); } void write(const Store & store, Sink & out, const std::optional & caOpt) @@ -546,7 +546,7 @@ ref RemoteStore::addCAToStore( conn->to << wopAddToStore << name - << renderContentAddressMethodAndHash(caMethod, hashType); + << caMethod.render(hashType); worker_proto::write(*this, conn->to, references); conn->to << repair; @@ -607,7 +607,7 @@ ref RemoteStore::addCAToStore( } } - }, caMethod); + }, caMethod.raw); auto path = parseStorePath(readString(conn->from)); // Release our connection to prevent a deadlock in queryPathInfo(). conn_.reset(); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index fed38e2dd..78b0d907e 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -221,7 +221,7 @@ StorePath Store::makeFixedOutputPathFromCA(std::string_view name, const ContentA [&](const FixedOutputInfo & foi) { return makeFixedOutputPath(name, foi); } - }, ca); + }, ca.raw); } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 26febb6e3..3d2dc49fd 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -970,7 +970,7 @@ static void opServe(Strings opFlags, Strings opArgs) info.references = worker_proto::read(*store, in, Phantom {}); in >> info.registrationTime >> info.narSize >> info.ultimate; info.sigs = readStrings(in); - info.ca = parseContentAddressOpt(readString(in)); + info.ca = ContentAddress::parseOpt(readString(in)); if (info.narSize == 0) throw Error("narInfo is too old and missing the narSize field"); diff --git a/src/nix/prefetch.cc b/src/nix/prefetch.cc index b06b8a320..56e7bbb6e 100644 --- a/src/nix/prefetch.cc +++ b/src/nix/prefetch.cc @@ -124,7 +124,7 @@ std::tuple prefetchFile( auto info = store->addToStoreSlow(*name, tmpFile, ingestionMethod, hashType, expectedHash); storePath = info.path; assert(info.ca); - hash = getContentAddressHash(*info.ca); + hash = info.ca->getHash(); } return {storePath.value(), hash.value()};