mirror of
https://github.com/wownero/wowlet.git
synced 2026-10-17 07:11:29 +02:00
wowlet: pull the live remote-node list from wownero.org/nodes
The feather websocket is disabled (no WOW backend); replace it with a Tor-routed HTTP poll of https://wownero.org/nodes/api/nodes/wallet (the live, health-checked node-map feed). Builds the managed node list from the feed's plain-http nodes (skips SSL-only nodes feather can't reach), falls back to the bundled nodes.json if the feed is unreachable, refreshes hourly. So users who don't run a local node get a fresh, working remote-node list instead of a stale hardcoded one.
This commit is contained in:
@@ -12,6 +12,10 @@
|
||||
#include "constants.h"
|
||||
#include "utils/WebsocketNotifier.h"
|
||||
#include "utils/TorManager.h"
|
||||
#include "utils/Networking.h"
|
||||
#include <QJsonArray>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
|
||||
bool NodeList::addNode(const QString &node, NetworkType::Type networkType, NodeList::Type source) {
|
||||
// We can't obtain references to QJsonObjects...
|
||||
@@ -108,6 +112,16 @@ Nodes::Nodes(QObject *parent, Wallet *wallet)
|
||||
this->loadConfig();
|
||||
connect(websocketNotifier(), &WebsocketNotifier::NodesReceived, this, &Nodes::onWSNodesReceived);
|
||||
|
||||
// wowlet: the feather websocket is disabled (no WOW backend), so pull the live remote-node list from
|
||||
// wownero.org/nodes instead — routed over Tor when Tor is active, with the bundled list (already loaded
|
||||
// by loadConfig above) as the fallback. Refreshed hourly.
|
||||
if (conf()->get(Config::disableWebsocket).toBool()) {
|
||||
QTimer::singleShot(4000, this, &Nodes::fetchRemoteNodeList);
|
||||
auto *refresh = new QTimer(this);
|
||||
connect(refresh, &QTimer::timeout, this, &Nodes::fetchRemoteNodeList);
|
||||
refresh->start(60 * 60 * 1000);
|
||||
}
|
||||
|
||||
if (m_wallet) {
|
||||
connect(m_wallet, &Wallet::walletRefreshed, this, &Nodes::onWalletRefreshed);
|
||||
}
|
||||
@@ -407,6 +421,45 @@ void Nodes::onWSNodesReceived(QList<FeatherNode> &nodes) {
|
||||
this->updateModels();
|
||||
}
|
||||
|
||||
void Nodes::fetchRemoteNodeList() {
|
||||
if (conf()->get(Config::offlineMode).toBool())
|
||||
return;
|
||||
if (!m_wowNet)
|
||||
m_wowNet = new Networking(this);
|
||||
|
||||
QNetworkReply *reply = m_wowNet->getJson(this, "https://wownero.org/nodes/api/nodes/wallet");
|
||||
if (!reply)
|
||||
return;
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply] {
|
||||
reply->deleteLater();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qWarning() << "wownero node feed unreachable, keeping bundled list:" << reply->errorString();
|
||||
return;
|
||||
}
|
||||
QJsonObject root = QJsonDocument::fromJson(reply->readAll()).object();
|
||||
const int best = root.value("height_best").toInt();
|
||||
QList<FeatherNode> nodes;
|
||||
for (const auto &v : root.value("nodes").toArray()) {
|
||||
QJsonObject o = v.toObject();
|
||||
// wowlet talks plain HTTP to daemons (over Tor); skip SSL-only nodes it can't reach.
|
||||
if (o.value("scheme").toString() == "https")
|
||||
continue;
|
||||
const QString host = o.value("host").toString();
|
||||
if (host.isEmpty())
|
||||
continue;
|
||||
const QString addr = QString("%1:%2").arg(host, QString::number(o.value("port").toInt()));
|
||||
nodes.append(FeatherNode(addr, o.value("height").toInt(), best, true));
|
||||
}
|
||||
if (nodes.isEmpty()) {
|
||||
qWarning() << "wownero node feed returned no usable (http) nodes; keeping bundled list";
|
||||
return;
|
||||
}
|
||||
qInfo() << "wownero node feed: loaded" << nodes.count() << "remote nodes";
|
||||
this->onWSNodesReceived(nodes);
|
||||
});
|
||||
}
|
||||
|
||||
void Nodes::onNodeSourceChanged(NodeSource nodeSource) {
|
||||
this->resetLocalState();
|
||||
this->updateModels();
|
||||
|
||||
@@ -143,6 +143,8 @@ struct FeatherNode {
|
||||
}
|
||||
};
|
||||
|
||||
class Networking;
|
||||
|
||||
class Nodes : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -185,6 +187,7 @@ private:
|
||||
|
||||
QList<FeatherNode> m_customNodes;
|
||||
QList<FeatherNode> m_websocketNodes;
|
||||
Networking *m_wowNet = nullptr; // wowlet: live remote-node feed from wownero.org/nodes
|
||||
|
||||
FeatherNode m_connection; // current active connection, if any
|
||||
|
||||
@@ -194,6 +197,7 @@ private:
|
||||
bool m_allowConnection = false;
|
||||
|
||||
FeatherNode pickEligibleNode();
|
||||
void fetchRemoteNodeList(); // wowlet: pull /nodes/api/nodes/wallet, replacing the disabled websocket
|
||||
|
||||
bool useOnionNodes();
|
||||
bool useI2PNodes();
|
||||
|
||||
Reference in New Issue
Block a user