fe1f34fa60
This adds a new store operation 'addMultipleToStore' that reads a number of NARs and ValidPathInfos from a Source, allowing any number of store paths to be copied in a single call. This is much faster on high-latency links when copying a lot of small files, like .drv closures. For example, on a connection with an 50 ms delay: Before: $ nix copy --to 'unix:///tmp/proxy-socket?root=/tmp/dest-chroot' \ /nix/store/90jjw94xiyg5drj70whm9yll6xjj0ca9-hello-2.10.drv \ --derivation --no-check-sigs real 0m57.868s user 0m0.103s sys 0m0.056s After: real 0m0.690s user 0m0.017s sys 0m0.011s
118 lines
4.1 KiB
C++
118 lines
4.1 KiB
C++
#pragma once
|
||
|
||
#include "crypto.hh"
|
||
#include "path.hh"
|
||
#include "hash.hh"
|
||
#include "content-address.hh"
|
||
|
||
#include <string>
|
||
#include <optional>
|
||
|
||
namespace nix {
|
||
|
||
|
||
class Store;
|
||
|
||
|
||
struct SubstitutablePathInfo
|
||
{
|
||
std::optional<StorePath> deriver;
|
||
StorePathSet references;
|
||
uint64_t downloadSize; /* 0 = unknown or inapplicable */
|
||
uint64_t narSize; /* 0 = unknown */
|
||
};
|
||
|
||
typedef std::map<StorePath, SubstitutablePathInfo> SubstitutablePathInfos;
|
||
|
||
|
||
struct ValidPathInfo
|
||
{
|
||
StorePath path;
|
||
std::optional<StorePath> deriver;
|
||
// TODO document this
|
||
Hash narHash;
|
||
StorePathSet references;
|
||
time_t registrationTime = 0;
|
||
uint64_t narSize = 0; // 0 = unknown
|
||
uint64_t id; // internal use only
|
||
|
||
/* Whether the path is ultimately trusted, that is, it's a
|
||
derivation output that was built locally. */
|
||
bool ultimate = false;
|
||
|
||
StringSet sigs; // note: not necessarily verified
|
||
|
||
/* If non-empty, an assertion that the path is content-addressed,
|
||
i.e., that the store path is computed from a cryptographic hash
|
||
of the contents of the path, plus some other bits of data like
|
||
the "name" part of the path. Such a path doesn't need
|
||
signatures, since we don't have to trust anybody's claim that
|
||
the path is the output of a particular derivation. (In the
|
||
extensional store model, we have to trust that the *contents*
|
||
of an output path of a derivation were actually produced by
|
||
that derivation. In the intensional model, we have to trust
|
||
that a particular output path was produced by a derivation; the
|
||
path then implies the contents.)
|
||
|
||
Ideally, the content-addressability assertion would just be a Boolean,
|
||
and the store path would be computed from the name component, ‘narHash’
|
||
and ‘references’. However, we support many types of content addresses.
|
||
*/
|
||
std::optional<ContentAddress> ca;
|
||
|
||
bool operator == (const ValidPathInfo & i) const
|
||
{
|
||
return
|
||
path == i.path
|
||
&& narHash == i.narHash
|
||
&& references == i.references;
|
||
}
|
||
|
||
/* Return a fingerprint of the store path to be used in binary
|
||
cache signatures. It contains the store path, the base-32
|
||
SHA-256 hash of the NAR serialisation of the path, the size of
|
||
the NAR, and the sorted references. The size field is strictly
|
||
speaking superfluous, but might prevent endless/excessive data
|
||
attacks. */
|
||
std::string fingerprint(const Store & store) const;
|
||
|
||
void sign(const Store & store, const SecretKey & secretKey);
|
||
|
||
/* Return true iff the path is verifiably content-addressed. */
|
||
bool isContentAddressed(const Store & store) const;
|
||
|
||
/* Functions to view references + hasSelfReference as one set, mainly for
|
||
compatibility's sake. */
|
||
StorePathSet referencesPossiblyToSelf() const;
|
||
void insertReferencePossiblyToSelf(StorePath && ref);
|
||
void setReferencesPossiblyToSelf(StorePathSet && refs);
|
||
|
||
static const size_t maxSigs = std::numeric_limits<size_t>::max();
|
||
|
||
/* Return the number of signatures on this .narinfo that were
|
||
produced by one of the specified keys, or maxSigs if the path
|
||
is content-addressed. */
|
||
size_t checkSignatures(const Store & store, const PublicKeys & publicKeys) const;
|
||
|
||
/* Verify a single signature. */
|
||
bool checkSignature(const Store & store, const PublicKeys & publicKeys, const std::string & sig) const;
|
||
|
||
Strings shortRefs() const;
|
||
|
||
ValidPathInfo(const ValidPathInfo & other) = default;
|
||
|
||
ValidPathInfo(StorePath && path, Hash narHash) : path(std::move(path)), narHash(narHash) { };
|
||
ValidPathInfo(const StorePath & path, Hash narHash) : path(path), narHash(narHash) { };
|
||
|
||
virtual ~ValidPathInfo() { }
|
||
|
||
static ValidPathInfo read(Source & source, const Store & store, unsigned int format);
|
||
static ValidPathInfo read(Source & source, const Store & store, unsigned int format, StorePath && path);
|
||
|
||
void write(Sink & sink, const Store & store, unsigned int format, bool includePath = true) const;
|
||
};
|
||
|
||
typedef std::map<StorePath, ValidPathInfo> ValidPathInfos;
|
||
|
||
}
|