forked from Flowee/registry
Fixes.
This commit is contained in:
+2
-7
@@ -54,7 +54,7 @@ Fields are read from top to bottom, you can mention the same field various
|
||||
times such that the item is processed in order.
|
||||
|
||||
* trust=good
|
||||
The trust level is given. absent, marginal, good, high
|
||||
The trust level is given. absent, marginal, good, high, ultimate
|
||||
* domain=bitcoincash.org
|
||||
Provides the source of the metadata in dns form.
|
||||
* category=deadbeef0124
|
||||
@@ -75,10 +75,5 @@ Trust levels
|
||||
| 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.
|
||||
| ultimate | You own this one! |
|
||||
|
||||
|
||||
+38
-39
@@ -93,6 +93,25 @@ bool Processor::run()
|
||||
|
||||
void Processor::run2()
|
||||
{
|
||||
// check all files (jsons and transactions) in the bcmrs subdir.
|
||||
QDirIterator iter(m_inDir + "transactions", QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDirIterator::Subdirectories);
|
||||
while (iter.hasNext()) {
|
||||
auto fi = iter.nextFileInfo();
|
||||
if (fi.isFile()) {
|
||||
try {
|
||||
parseBCHTx(fi.absoluteFilePath());
|
||||
} catch (const std::exception &e) {
|
||||
logWarning() << "Parsing of tx stopped with:" << e;
|
||||
logWarning() << " + " << fi.absoluteFilePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
QTimer::singleShot(1, this, SLOT(runDownloadQueue()));
|
||||
}
|
||||
|
||||
void Processor::run3()
|
||||
{
|
||||
|
||||
// make sure the transactions turn into auth-chains.
|
||||
// this is useful when establishing trust of a tx-induced bcmr file is found
|
||||
for (auto iter = m_transactions.begin(); iter != m_transactions.end(); ++iter) {
|
||||
@@ -176,9 +195,13 @@ void Processor::run2()
|
||||
logInfo() << "num groups found:" << m_groups.size();
|
||||
for (auto i = m_groups.begin(); i != m_groups.end(); ++i) {
|
||||
MetaGroup *mg = i->second;
|
||||
if (mg->owners.empty())
|
||||
continue;
|
||||
QJsonArray sources;
|
||||
auto owners = std::vector<MetaBCMR*>(mg->owners.begin(), mg->owners.end());
|
||||
std::sort(owners.begin(), owners.end(), [mg](MetaBCMR *a, MetaBCMR *b) {
|
||||
if (a->trust != b->trust)
|
||||
return a->trust > b->trust;
|
||||
// we're sorting the bcmr itself, but we only really care about a
|
||||
// single identity inside each of them. THAT is what we'll compare.
|
||||
MetaIdentity *ai = a->idForGroupId(mg->id);
|
||||
@@ -243,7 +266,12 @@ void Processor::runDownloadQueue()
|
||||
QTimer::singleShot(1, this, SLOT(run2()));
|
||||
return;
|
||||
}
|
||||
if ((m_offline || m_downloadJobs.isEmpty()) && m_phase == Run2) {
|
||||
if (m_phase == Run2 && (m_downloadJobs.isEmpty() || m_offline)) {
|
||||
m_phase = Run3;
|
||||
QTimer::singleShot(1, this, SLOT(run3()));
|
||||
return;
|
||||
}
|
||||
if ((m_offline || m_downloadJobs.isEmpty()) && m_phase == Run3) {
|
||||
QCoreApplication::quit();
|
||||
return;
|
||||
}
|
||||
@@ -287,44 +315,10 @@ void Processor::runDownloadQueue()
|
||||
void Processor::parseBCMR(const QString &path)
|
||||
{
|
||||
QFile in(path);
|
||||
if (in.open(QIODevice::ReadOnly)) {
|
||||
char signature[4];
|
||||
in.read(signature, 4);
|
||||
bool isTx = true;
|
||||
int isJson = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
uint8_t k = static_cast<uint8_t>(signature[i]);
|
||||
if (k < 10) {
|
||||
isTx = isTx && true;
|
||||
isJson = 10;
|
||||
}
|
||||
if (k == ' ' || k == '\n' || k == '\r' || k == '\t') {
|
||||
if (isJson < 1)
|
||||
isJson = 1;
|
||||
} else if (isJson < 2 && k == '{') {
|
||||
isJson = 2;
|
||||
}
|
||||
else if (isJson == 2 && (k < 34 || k > 'z')) {
|
||||
isJson = 10; // fail
|
||||
}
|
||||
}
|
||||
if ((isJson == 0 || isJson == 10) && isTx) {
|
||||
in.seek(0);
|
||||
try {
|
||||
parseBCHTx(in);
|
||||
} catch (const std::exception &e) {
|
||||
logWarning() << "Parsing of tx stopped with:" << e;
|
||||
logWarning() << " + " << path;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (isJson != 2) {
|
||||
logCritical() << "Magic detection of file:" << path << "failed. What is it?";
|
||||
return;
|
||||
}
|
||||
if (!in.open(QIODevice::ReadOnly)) {
|
||||
logWarning() << "Failed to read file" << path;
|
||||
return;
|
||||
}
|
||||
// still here, then it is a json.
|
||||
in.seek(0);
|
||||
auto data = in.readAll();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||
in.close();
|
||||
@@ -480,8 +474,13 @@ void Processor::parseTrustFile(const QString &path)
|
||||
}
|
||||
}
|
||||
|
||||
void Processor::parseBCHTx(QFile &file)
|
||||
void Processor::parseBCHTx(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
logCritical() << "Failed to read" << path;
|
||||
return;
|
||||
}
|
||||
if (file.size() < 65) {
|
||||
// downloading a bcmr from a transaction may fail to match the hash
|
||||
// and then we create an empty file to avoid downloading it again
|
||||
|
||||
+4
-2
@@ -35,12 +35,13 @@ public:
|
||||
private slots:
|
||||
void runDownloadQueue();
|
||||
void run2();
|
||||
void run3();
|
||||
|
||||
private:
|
||||
void addJob(DownloadJob *job);
|
||||
void parseBCMR(const QString &path);
|
||||
void parseTrustFile(const QString &path);
|
||||
void parseBCHTx(QFile &file);
|
||||
void parseBCHTx(const QString &path);
|
||||
struct MetaGroup;
|
||||
enum GroupType {
|
||||
Category,
|
||||
@@ -96,7 +97,8 @@ private:
|
||||
|
||||
enum Phase {
|
||||
Run1,
|
||||
Run2
|
||||
Run2,
|
||||
Run3
|
||||
};
|
||||
Phase m_phase = Run1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user