From 08fdd3a2c727f5eac34eac4f9c7b2c48f722e1a7 Mon Sep 17 00:00:00 2001 From: Anthony Bilinski Date: Thu, 3 Mar 2022 13:31:36 -0800 Subject: [PATCH] feat(core): Store default bootstrap list separate from user list Allows qTox to tell the difference between a default list that should be upgraded when defaults are changed, ora user list that should never be changed. --- doc/user_manual_en.md | 7 ++++--- src/net/bootstrapnodeupdater.cpp | 34 +++++++++++++++++++------------- src/persistence/paths.cpp | 7 +++++++ src/persistence/paths.h | 1 + 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/doc/user_manual_en.md b/doc/user_manual_en.md index 46a115dc3..6650c7d2f 100644 --- a/doc/user_manual_en.md +++ b/doc/user_manual_en.md @@ -463,9 +463,10 @@ information. ## Bootstrap Nodes qTox uses bootstrap nodes to find its way in to the DHT. The list of nodes is -stored in `bootstrapNodes.json` and can be found and modified if wanted at -`~/.config/tox/` on Linux, `%APPDATA%\Roaming\tox` on Windows, and -`~/Library/Application Support/Tox` on macOS. +stored in `~/.config/tox/` on Linux, `%APPDATA%\Roaming\tox` on Windows, and +`~/Library/Application Support/Tox` on macOS. `bootstrapNodes.example.json` +stores the default list. If a new list is placed at `bootstrapNodes.json`, it +will be used instead. ## Avoiding Censorship diff --git a/src/net/bootstrapnodeupdater.cpp b/src/net/bootstrapnodeupdater.cpp index 88aeaff6b..dac3ec0d2 100644 --- a/src/net/bootstrapnodeupdater.cpp +++ b/src/net/bootstrapnodeupdater.cpp @@ -201,6 +201,19 @@ QByteArray serialize(QList nodes) QJsonDocument doc{rootObj}; return doc.toJson(QJsonDocument::Indented); } + +void createExampleBootstrapNodesFile(const Paths& paths) +{ + // deserialize and reserialize instead of just copying to strip out any unnecessary json, making it easier for + // users to edit. Overwrite the file on every start to keep it up to date when our internal list updates. + auto buildInNodes = loadNodesFile(builtinNodesFile); + auto serializedNodes = serialize(buildInNodes); + + QFile outFile(paths.getExampleNodesFilePath()); + outFile.open(QIODevice::WriteOnly | QIODevice::Text); + outFile.write(serializedNodes.data(), serializedNodes.size()); + outFile.close(); +} } // namespace /** @@ -211,25 +224,18 @@ BootstrapNodeUpdater::BootstrapNodeUpdater(const QNetworkProxy& proxy, Paths& _p : proxy{proxy} , paths{_paths} , QObject{parent} -{} +{ + createExampleBootstrapNodesFile(_paths); +} QList BootstrapNodeUpdater::getBootstrapnodes() const { auto userFilePath = paths.getUserNodesFilePath(); - if (!QFile(userFilePath).exists()) { - qInfo() << "Bootstrap node list not found, creating one with default nodes."; - // deserialize and reserialize instead of just copying to strip out any unnecessary json, making it easier for - // users to edit - auto buildInNodes = loadNodesFile(builtinNodesFile); - auto serializedNodes = serialize(buildInNodes); - - QFile outFile(userFilePath); - outFile.open(QIODevice::WriteOnly | QIODevice::Text); - outFile.write(serializedNodes.data(), serializedNodes.size()); - outFile.close(); + if (QFile::exists(userFilePath)) { + return loadNodesFile(userFilePath); + } else { + return loadNodesFile(builtinNodesFile); } - - return loadNodesFile(userFilePath); } void BootstrapNodeUpdater::requestBootstrapNodes() diff --git a/src/persistence/paths.cpp b/src/persistence/paths.cpp index 73a168750..ed88b8042 100644 --- a/src/persistence/paths.cpp +++ b/src/persistence/paths.cpp @@ -365,6 +365,13 @@ QString Paths::getAppCacheDirPath() const #endif } +QString Paths::getExampleNodesFilePath() const +{ + QDir dir(getSettingsDirPath()); + constexpr static char nodesFileName[] = "bootstrapNodes.example.json"; + return dir.filePath(nodesFileName); +} + QString Paths::getUserNodesFilePath() const { QDir dir(getSettingsDirPath()); diff --git a/src/persistence/paths.h b/src/persistence/paths.h index c1b33f48e..521b715ef 100644 --- a/src/persistence/paths.h +++ b/src/persistence/paths.h @@ -51,6 +51,7 @@ public: QString getSettingsDirPath() const; QString getAppDataDirPath() const; QString getAppCacheDirPath() const; + QString getExampleNodesFilePath() const; QString getUserNodesFilePath() const; #endif