-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Git with refs types refactor #53
base: ipfs-develop
Are you sure you want to change the base?
Changes from 17 commits
ffe4112
0d20c9d
7e2133e
f307db3
4287b89
acbda9c
b6249fb
8476d8c
842dd4f
34f000c
e723ced
caac4c4
17e267d
2da7fec
82521a9
4eb4d42
3cb966a
3366d8c
76540c9
3bd223b
db22255
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
#include <variant> | ||
|
||
#include "hash.hh" | ||
#include "ipfs.hh" | ||
#include "path.hh" | ||
|
||
namespace nix { | ||
|
@@ -30,9 +31,10 @@ struct FixedOutputHash { | |
std::string printMethodAlgo() const; | ||
}; | ||
|
||
struct IPFSHash { | ||
Hash hash; | ||
}; | ||
template<template <typename> class Ref> | ||
struct IPFSGitTreeNodeT; | ||
|
||
typedef IPFSGitTreeNodeT<IPFSHashWithOptValue> IPFSGitTreeNode; | ||
|
||
/* | ||
We've accumulated several types of content-addressed paths over the years; | ||
|
@@ -48,7 +50,7 @@ struct IPFSHash { | |
typedef std::variant< | ||
TextHash, // for paths computed by makeTextPath() / addTextToStore | ||
FixedOutputHash, // for path computed by makeFixedOutputPath | ||
IPFSHash | ||
IPFSHash<IPFSGitTreeNode> | ||
> LegacyContentAddress; | ||
|
||
/* Compute the prefix to the hash algorithm which indicates how the files were | ||
|
@@ -139,44 +141,54 @@ struct FixedOutputInfo : FixedOutputHash { | |
PathReferences<StorePath> references; | ||
}; | ||
|
||
// pair of cid and name for ipfs references | ||
typedef std::pair<std::string, std::string> IPFSRef; | ||
template<typename Underlying> | ||
struct ContentAddressT; | ||
|
||
struct IPFSInfo { | ||
Hash hash; | ||
template<template <typename> class Ref> | ||
struct IPFSGitTreeNodeT { | ||
Hash gitTree; | ||
// References for the paths | ||
PathReferences<IPFSRef> references; | ||
PathReferences<ContentAddressT<Ref<IPFSGitTreeNodeT<Ref>>>> references; | ||
}; | ||
|
||
// just the cid, which is a hash of ipfsinfo | ||
struct IPFSCid { | ||
std::string cid; | ||
}; | ||
// FIXME names | ||
typedef std::variant< | ||
TextInfo, | ||
FixedOutputInfo, | ||
IPFSHashWithOptValue<IPFSGitTreeNode> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this duplicate data because IPFSHashWithOptValue has a hash, but we can also compute the hash from IPFSGitTreeNode? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be better to make IPFSHashWithOptValue a variant of either a hash or a value. |
||
> ContentAddressWithoutName; | ||
|
||
struct ContentAddress { | ||
template<typename Underlying> | ||
struct ContentAddressT { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a little duplication here would be much better than doing this. What even is ContentAddressT? If you really want to use it, you should call it something like NameWrapper or something. |
||
std::string name; | ||
std::variant< | ||
TextInfo, | ||
FixedOutputInfo, | ||
IPFSInfo, | ||
IPFSCid | ||
> info; | ||
|
||
bool operator < (const ContentAddress & other) const | ||
Underlying info; | ||
|
||
bool operator < (const ContentAddressT<Underlying> & other) const | ||
{ | ||
return name < other.name; | ||
// FIXME second field | ||
} | ||
}; | ||
|
||
typedef ContentAddressT<ContentAddressWithoutName> ContentAddress; | ||
|
||
std::string renderContentAddress(ContentAddress ca); | ||
|
||
ContentAddress parseContentAddress(std::string_view rawCa); | ||
|
||
void to_json(nlohmann::json& j, const ContentAddress & c); | ||
void from_json(const nlohmann::json& j, ContentAddress & c); | ||
template<template <typename> class Ref> | ||
void to_json(nlohmann::json& j, const IPFSGitTreeNodeT<Ref> & c); | ||
template<template <typename> class Ref> | ||
void from_json(const nlohmann::json& j, IPFSGitTreeNodeT<Ref> & c); | ||
|
||
template<typename T> | ||
void to_json(nlohmann::json& j, const ContentAddressT<T> & c); | ||
template<typename T> | ||
void from_json(const nlohmann::json& j, ContentAddressT<T> & c); | ||
|
||
void to_json(nlohmann::json& j, const PathReferences<IPFSRef> & c); | ||
void from_json(const nlohmann::json& j, PathReferences<IPFSRef> & c); | ||
template<typename T> | ||
void to_json(nlohmann::json& j, const PathReferences<T> & c); | ||
template<typename T> | ||
void from_json(const nlohmann::json& j, PathReferences<T> & c); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include "ipfs.hh" | ||
|
||
namespace nix::untyped { | ||
|
||
// "f01711220" base-16, sha-256 | ||
// "f01781114" base-16, sha-1 | ||
|
||
std::string toString(Hash hash) { | ||
std::string prefix; | ||
switch (hash.type) { | ||
case htSHA1: prefix = "f01711220"; | ||
case htSHA256: prefix = "f01781114"; | ||
default: throw Error("hash type '%s' we don't yet export to IPFS", printHashType(hash.type)); | ||
} | ||
return prefix + hash.to_string(Base16, false); | ||
} | ||
|
||
Hash fromString(std::string_view cid) { | ||
auto prefix = cid.substr(0, 9); | ||
HashType algo = prefix == "f01711220" ? htSHA256 | ||
: prefix == "f01781114" ? htSHA1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. f0178 means it's the git codec, which should be an error for the "full" content address at least |
||
: throw Error("cid '%s' is wrong type for ipfs hash", cid); | ||
return Hash::parseNonSRIUnprefixed(cid.substr(9), algo); | ||
} | ||
|
||
std::vector<uint8_t> pack(Hash hash) | ||
{ | ||
auto cid = toString(hash); | ||
std::vector<uint8_t> result; | ||
assert(cid[0] == 'f'); | ||
result.push_back(0x00); | ||
result.push_back(std::stoi(cid.substr(1, 2), nullptr, 16)); | ||
result.push_back(std::stoi(cid.substr(3, 2), nullptr, 16)); | ||
result.push_back(std::stoi(cid.substr(5, 2), nullptr, 16)); | ||
result.push_back(std::stoi(cid.substr(7, 2), nullptr, 16)); | ||
for (unsigned int i = 0; i < hash.hashSize; i++) | ||
result.push_back(hash.hash[i]); | ||
return result; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you ever need more than one level of PathReferences? We can always query the daemon once we have the cid of a reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More importantly, when would we ever fill in more than one layer of references? We handle each path on its own, so no room to share information like this between queryPathInfo calls.