forked from Flowee/registry
Add trust inherited from authchain
This commit is contained in:
+22
-4
@@ -53,14 +53,32 @@ The file is very simple name/value pairs in standard unix line-endings.
|
|||||||
Fields are read from top to bottom, you can mention the same field various
|
Fields are read from top to bottom, you can mention the same field various
|
||||||
times such that the item is processed in order.
|
times such that the item is processed in order.
|
||||||
|
|
||||||
* trust=ultimate
|
* trust=good
|
||||||
The trust level is given. none, marginal, good, high, ultimate
|
The trust level is given. absent, marginal, good, high
|
||||||
* domain=bitcoincash.org
|
* domain=bitcoincash.org
|
||||||
Provides the source of the metadata in dns form.
|
Provides the source of the metadata in dns form.
|
||||||
* category=deadbeef0124
|
* category=deadbeef0124
|
||||||
A 64 character, hex-encoded token category. Which will then inherit
|
A 64 character, hex-encoded token category. Which will then inherit
|
||||||
the most recently set trust.
|
the most recently set trust.
|
||||||
* authbase=deadbeef0124
|
* authbase=deadbeef0124
|
||||||
A 64 character, hex-encoded authbase (txid). Which will then inherit
|
A 64 character, hex-encoded authbase (txid). Which will then inherit
|
||||||
the most recently set trust. Allowing for all metadata files indicated
|
the most recently set trust. Allowing for all metadata files indicated
|
||||||
by it to likewise inherit this trust.
|
by it to likewise inherit this trust.
|
||||||
|
|
||||||
|
|
||||||
|
Trust levels
|
||||||
|
|
||||||
|
+---+---+
|
||||||
|
|Level|Description|
|
||||||
|
+---+---+
|
||||||
|
| absent | Trust has been violated, this is likely a scam or spam. |
|
||||||
|
| marginal | [Default] No trust could be established |
|
||||||
|
| good | Minimal checking has been done, likely an honest party |
|
||||||
|
| high | The party is trusted by the registry owner |
|
||||||
|
| ultimate | We know that the content comes from the party they say they are.|
|
||||||
|
|
||||||
|
Notice that the ultimate trust is really only used to describe confidence
|
||||||
|
level of the metadata file being published by who they say they are. Or
|
||||||
|
really if you are publishing your own metadata on your own registry this
|
||||||
|
way.
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -49,7 +49,7 @@ void DownloadJob::start()
|
|||||||
else {
|
else {
|
||||||
auto data = reply->readAll();
|
auto data = reply->readAll();
|
||||||
if (checkHash(data)) {
|
if (checkHash(data)) {
|
||||||
out.write(reply->readAll());
|
out.write(data);
|
||||||
out.flush();
|
out.flush();
|
||||||
} else {
|
} else {
|
||||||
logWarning() << "Download failed hash-check" << m_sourceUrl.toString();
|
logWarning() << "Download failed hash-check" << m_sourceUrl.toString();
|
||||||
@@ -116,12 +116,12 @@ bool DownloadJob::checkHash(const QByteArray &contents) const
|
|||||||
{
|
{
|
||||||
if (m_targetHash.isEmpty())
|
if (m_targetHash.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
|
static_assert(CSHA256::OUTPUT_SIZE == 32);
|
||||||
assert(m_targetHash.size() == 32);
|
assert(m_targetHash.size() == 32);
|
||||||
|
|
||||||
CSHA256 hasher;
|
CSHA256 hasher;
|
||||||
hasher.write(contents.constData(), contents.size());
|
hasher.write(contents.constData(), contents.size());
|
||||||
char hash[CSHA256::OUTPUT_SIZE];
|
char hash[CSHA256::OUTPUT_SIZE];
|
||||||
static_assert(CSHA256::OUTPUT_SIZE == 32);
|
|
||||||
hasher.finalize(hash);
|
hasher.finalize(hash);
|
||||||
return memcmp(hash, m_targetHash.begin(), 32) == 0;
|
return memcmp(hash, m_targetHash.begin(), 32) == 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-10
@@ -31,7 +31,7 @@ static bool walk(QJsonObject &item, const QStringList &steps) {
|
|||||||
|
|
||||||
static Processor::Trust trustFromString(const QString &string) {
|
static Processor::Trust trustFromString(const QString &string) {
|
||||||
auto lc = string.toLower();
|
auto lc = string.toLower();
|
||||||
if (lc == "none")
|
if (lc == "absent")
|
||||||
return Processor::NoTrust;
|
return Processor::NoTrust;
|
||||||
if (lc == "marginal")
|
if (lc == "marginal")
|
||||||
return Processor::MarginalTrust;
|
return Processor::MarginalTrust;
|
||||||
@@ -42,13 +42,13 @@ static Processor::Trust trustFromString(const QString &string) {
|
|||||||
if (lc == "ultimate")
|
if (lc == "ultimate")
|
||||||
return Processor::UltimateTrust;
|
return Processor::UltimateTrust;
|
||||||
logWarning() << "Unrecognized trust passed:" << string;
|
logWarning() << "Unrecognized trust passed:" << string;
|
||||||
return Processor::NoTrust;
|
return Processor::MarginalTrust;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString trustToString(Processor::Trust trust) {
|
static QString trustToString(Processor::Trust trust) {
|
||||||
switch (trust) {
|
switch (trust) {
|
||||||
case Processor::NoTrust:
|
case Processor::NoTrust:
|
||||||
return "none";
|
return "absent";
|
||||||
case Processor::MarginalTrust:
|
case Processor::MarginalTrust:
|
||||||
return "marginal";
|
return "marginal";
|
||||||
case Processor::GoodTrust:
|
case Processor::GoodTrust:
|
||||||
@@ -113,6 +113,24 @@ void Processor::run2()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto iter = m_transactions.begin(); iter != m_transactions.end(); ++iter) {
|
||||||
|
// create placeholder bcmr data objects in order to inherit trust from
|
||||||
|
// the authchain group.
|
||||||
|
Transaction *d = iter->second;
|
||||||
|
auto gId = d->authbase();
|
||||||
|
auto gIter = m_groups.find(gId);
|
||||||
|
if (gIter != m_groups.end()) {
|
||||||
|
MetaGroup *g = gIter->second;
|
||||||
|
if (g->trust != MarginalTrust) {
|
||||||
|
// the transaction, and any bcmrs it might contain would inherit
|
||||||
|
// the trust from that group. Lets create a placeholder to mark that.
|
||||||
|
QFileInfo target(m_inDir + "bcmrs/downloaded/"
|
||||||
|
+ QString::fromStdString(d->txid.ToString()) + ".json");
|
||||||
|
auto *meta = fetchOrCreate(target.absoluteFilePath());
|
||||||
|
meta->trust = g->trust;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QDirIterator iter(m_inDir + "bcmrs", QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDirIterator::Subdirectories);
|
QDirIterator iter(m_inDir + "bcmrs", QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDirIterator::Subdirectories);
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
@@ -365,7 +383,9 @@ void Processor::parseBCMR(const QString &path)
|
|||||||
id->category = cat;
|
id->category = cat;
|
||||||
MetaGroup *mg = fetchOrCreate(cat, Category);
|
MetaGroup *mg = fetchOrCreate(cat, Category);
|
||||||
id->tokens.push_back(mg);
|
id->tokens.push_back(mg);
|
||||||
mg->trust = std::max(mg->trust, me->trust);
|
// identities inherit trust from the bcmr
|
||||||
|
if (me->trust != MarginalTrust)
|
||||||
|
mg->trust = me->trust;
|
||||||
mg->owners.insert(me);
|
mg->owners.insert(me);
|
||||||
// walk all nfts and extract image and icon resource urls
|
// walk all nfts and extract image and icon resource urls
|
||||||
auto types = token;
|
auto types = token;
|
||||||
@@ -394,6 +414,10 @@ void Processor::parseBCMR(const QString &path)
|
|||||||
// we conclude it was an authbase
|
// we conclude it was an authbase
|
||||||
auto *group = fetchOrCreate(id->identity, AuthBase);
|
auto *group = fetchOrCreate(id->identity, AuthBase);
|
||||||
group->owners.insert(me);
|
group->owners.insert(me);
|
||||||
|
|
||||||
|
logFatal() << "xxxx" << in.fileName();
|
||||||
|
|
||||||
|
|
||||||
group->trust = me->trust;
|
group->trust = me->trust;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -407,11 +431,11 @@ void Processor::parseTrustFile(const QString &path)
|
|||||||
logCritical() << "Failed to read" << path;
|
logCritical() << "Failed to read" << path;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Trust trust = NoTrust;
|
Trust trust = MarginalTrust;
|
||||||
for (const QString &line : QString::fromUtf8(in.readAll()).split('\n')) {
|
for (const QString &line : QString::fromUtf8(in.readAll()).split('\n')) {
|
||||||
if (line.startsWith("domain=")) {
|
if (line.startsWith("domain=")) {
|
||||||
QFileInfo cache(m_inDir + "bcmrs/downloaded/" + me.fileName());
|
QFileInfo cache(m_inDir + "bcmrs/downloaded/" + me.fileName());
|
||||||
if (trust != NoTrust)
|
if (trust != MarginalTrust)
|
||||||
fetchOrCreate(cache.absoluteFilePath())->trust = trust;
|
fetchOrCreate(cache.absoluteFilePath())->trust = trust;
|
||||||
|
|
||||||
if (cache.exists()) {
|
if (cache.exists()) {
|
||||||
@@ -440,7 +464,7 @@ void Processor::parseTrustFile(const QString &path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trust != NoTrust)
|
if (trust != MarginalTrust)
|
||||||
fetchOrCreate(cat, Category)->trust = trust;
|
fetchOrCreate(cat, Category)->trust = trust;
|
||||||
}
|
}
|
||||||
else if (line.startsWith("authbase=")) {
|
else if (line.startsWith("authbase=")) {
|
||||||
@@ -450,7 +474,7 @@ void Processor::parseTrustFile(const QString &path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trust != NoTrust)
|
if (trust != MarginalTrust)
|
||||||
fetchOrCreate(ab, AuthBase)->trust = trust;
|
fetchOrCreate(ab, AuthBase)->trust = trust;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -459,7 +483,13 @@ void Processor::parseTrustFile(const QString &path)
|
|||||||
void Processor::parseBCHTx(QFile &file)
|
void Processor::parseBCHTx(QFile &file)
|
||||||
{
|
{
|
||||||
if (file.size() < 65) {
|
if (file.size() < 65) {
|
||||||
logWarning() << "Skipping file, it's too small"<< file.fileName();
|
// downloading a bcmr from a transaction may fail to match the hash
|
||||||
|
// and then we create an empty file to avoid downloading it again
|
||||||
|
// in the future. So don't complain about those.
|
||||||
|
// (scenario is not weird, maybe bcmr owners don't host new files
|
||||||
|
// when they update the on-chain reference to them, so old ones fail)
|
||||||
|
if (file.size() > 0)
|
||||||
|
logWarning() << "Skipping file, it's too small"<< file.fileName();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_pool.reserve(file.size());
|
m_pool.reserve(file.size());
|
||||||
@@ -486,8 +516,10 @@ void Processor::parseBCHTx(QFile &file)
|
|||||||
&& output.outputScript[6] == 0x20) { // space
|
&& output.outputScript[6] == 0x20) { // space
|
||||||
auto hash = output.outputScript.mid(7, 32);
|
auto hash = output.outputScript.mid(7, 32);
|
||||||
|
|
||||||
|
// filename is the original transaction id, so we can figure out
|
||||||
|
// who owns it.
|
||||||
QFileInfo target(m_inDir + "bcmrs/downloaded/"
|
QFileInfo target(m_inDir + "bcmrs/downloaded/"
|
||||||
+ QString::fromStdString(hash.toHex()) + ".json");
|
+ QString::fromStdString(tx.createHash().ToString()) + ".json");
|
||||||
if (target.exists())
|
if (target.exists())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -579,3 +611,16 @@ void Processor::addJob(DownloadJob *job)
|
|||||||
});
|
});
|
||||||
m_downloadJobs.append(job);
|
m_downloadJobs.append(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString Processor::Transaction::authbase() const
|
||||||
|
{
|
||||||
|
auto *root = this;
|
||||||
|
while (true) {
|
||||||
|
if (root->previous)
|
||||||
|
root = root->previous;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QString::fromStdString(root->txid.ToString());
|
||||||
|
}
|
||||||
|
|||||||
+3
-3
@@ -59,7 +59,7 @@ private:
|
|||||||
QSet<QString> resources;
|
QSet<QString> resources;
|
||||||
};
|
};
|
||||||
struct MetaBCMR {
|
struct MetaBCMR {
|
||||||
Trust trust = NoTrust;
|
Trust trust = MarginalTrust;
|
||||||
QString hash;
|
QString hash;
|
||||||
QString origFilename;
|
QString origFilename;
|
||||||
std::vector<MetaIdentity*> identities;
|
std::vector<MetaIdentity*> identities;
|
||||||
@@ -71,7 +71,7 @@ private:
|
|||||||
struct MetaGroup {
|
struct MetaGroup {
|
||||||
GroupType type;
|
GroupType type;
|
||||||
QString id;
|
QString id;
|
||||||
Trust trust = NoTrust;
|
Trust trust = MarginalTrust;
|
||||||
std::set<MetaBCMR*> owners;
|
std::set<MetaBCMR*> owners;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ private:
|
|||||||
GroupMap m_groups;
|
GroupMap m_groups;
|
||||||
|
|
||||||
struct Transaction {
|
struct Transaction {
|
||||||
uint256 authbase() const;
|
QString authbase() const;
|
||||||
Tx transaction;
|
Tx transaction;
|
||||||
uint256 txid;
|
uint256 txid;
|
||||||
Transaction *previous = nullptr;
|
Transaction *previous = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user