Browse Source

Check if getrescaninfo exists and improved error handling

pull/112/head
Duke Leto 2 years ago
parent
commit
706689f86b
  1. 27
      src/connection.cpp
  2. 38
      src/mainwindow.cpp
  3. 77
      src/rpc.cpp
  4. 5
      src/rpc.h

27
src/connection.cpp

@ -10,6 +10,7 @@
#include "version.h" #include "version.h"
ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) { ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) {
qDebug() << __func__;
this->main = main; this->main = main;
this->rpc = rpc; this->rpc = rpc;
@ -37,12 +38,14 @@ ConnectionLoader::~ConnectionLoader() {
} }
void ConnectionLoader::loadConnection() { void ConnectionLoader::loadConnection() {
qDebug() << __func__;
QTimer::singleShot(1, [=]() { this->doAutoConnect(); }); QTimer::singleShot(1, [=]() { this->doAutoConnect(); });
if (!Settings::getInstance()->isHeadless()) if (!Settings::getInstance()->isHeadless())
d->exec(); d->exec();
} }
void ConnectionLoader::doAutoConnect(bool tryEhushdStart) { void ConnectionLoader::doAutoConnect(bool tryEhushdStart) {
qDebug() << __func__;
// Priority 1: Ensure all params are present. // Priority 1: Ensure all params are present.
if (!verifyParams()) { if (!verifyParams()) {
qDebug() << "Cannot find sapling params!"; qDebug() << "Cannot find sapling params!";
@ -474,7 +477,7 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> c
} }
void ConnectionLoader::refreshHushdState(Connection* connection, std::function<void(void)> refused) { void ConnectionLoader::refreshHushdState(Connection* connection, std::function<void(void)> refused) {
main->logger->write("refreshing state"); qDebug() << __func__ << ": refreshing state";
QJsonObject payload = { QJsonObject payload = {
{"jsonrpc", "1.0"}, {"jsonrpc", "1.0"},
@ -484,11 +487,12 @@ void ConnectionLoader::refreshHushdState(Connection* connection, std::function<v
connection->doRPC(payload, connection->doRPC(payload,
[=] (auto) { [=] (auto) {
// Success // Success
main->logger->write("hushd is online!"); qDebug() << __func__ << ": hushd is online!";
// Delay 1 second to ensure loading (splash) is seen at least 1 second. // Delay 1 second to ensure loading (splash) is seen at least 1 second.
QTimer::singleShot(1000, [=]() { this->doRPCSetConnection(connection); }); QTimer::singleShot(1000, [=]() { this->doRPCSetConnection(connection); });
}, },
[=] (QNetworkReply* reply, const QJsonValue &res) { [=] (QNetworkReply* reply, const QJsonValue &res) {
qDebug() << __func__ << ": failed to connect to hushd!";
// Failed, see what it is. // Failed, see what it is.
auto err = reply->error(); auto err = reply->error();
//qDebug() << err << res; //qDebug() << err << res;
@ -741,7 +745,7 @@ std::shared_ptr<ConnectionConfig> ConnectionLoader::autoDetectHushConf() {
// Load connection settings from the UI, which indicates an unknown, external hushd // Load connection settings from the UI, which indicates an unknown, external hushd
std::shared_ptr<ConnectionConfig> ConnectionLoader::loadFromSettings() { std::shared_ptr<ConnectionConfig> ConnectionLoader::loadFromSettings() {
// Load from the QT Settings. qDebug() << __func__ <<": Load data from the QT Settings";
QSettings s; QSettings s;
auto host = s.value("connection/host").toString(); auto host = s.value("connection/host").toString();
@ -749,18 +753,16 @@ std::shared_ptr<ConnectionConfig> ConnectionLoader::loadFromSettings() {
auto username = s.value("connection/rpcuser").toString(); auto username = s.value("connection/rpcuser").toString();
auto password = s.value("connection/rpcpassword").toString(); auto password = s.value("connection/rpcpassword").toString();
if (username.isEmpty() || password.isEmpty()) if (username.isEmpty() || password.isEmpty()) {
qDebug() << __func__ <<": username or password empty, returning null!";
return nullptr; return nullptr;
}
auto uiConfig = new ConnectionConfig{ host, port, username, password, false, false,"","", "", "","", ConnectionType::UISettingsZCashD}; auto uiConfig = new ConnectionConfig{ host, port, username, password, false, false,"","", "", "","", ConnectionType::UISettingsZCashD};
return std::shared_ptr<ConnectionConfig>(uiConfig); return std::shared_ptr<ConnectionConfig>(uiConfig);
} }
/*********************************************************************************** /***********************************************************************************
* Connection Class * Connection Class
************************************************************************************/ ************************************************************************************/
@ -780,11 +782,16 @@ Connection::~Connection() {
void Connection::doRPC(const QJsonValue& payload, const std::function<void(QJsonValue)>& cb, void Connection::doRPC(const QJsonValue& payload, const std::function<void(QJsonValue)>& cb,
const std::function<void(QNetworkReply*, const QJsonValue&)>& ne) { const std::function<void(QNetworkReply*, const QJsonValue&)>& ne) {
if (shutdownInProgress) { if (shutdownInProgress) {
// Ignoring RPC because shutdown in progress qDebug() << __func__ << ": Ignoring RPC because shutdown in progress";
return; return;
} }
qDebug() << "RPC:" << payload["method"].toString() << payload; if(payload.isNull() || payload.isUndefined()) {
qDebug() << "no payload! ignoring";
return;
} else {
qDebug() << __func__ << ": " << payload["method"].toString() << payload;
}
QJsonDocument jd_rpc_call(payload.toObject()); QJsonDocument jd_rpc_call(payload.toObject());
QByteArray ba_rpc_call = jd_rpc_call.toJson(); QByteArray ba_rpc_call = jd_rpc_call.toJson();

38
src/mainwindow.cpp

@ -412,7 +412,7 @@ void MainWindow::setupSettingsModal() {
} }
}); });
// Setup rescan button qDebug() << __func__ << ": Setup rescan button";
QObject::connect(settings.rescanButton, &QPushButton::clicked, [=] () { QObject::connect(settings.rescanButton, &QPushButton::clicked, [=] () {
this->rescanButtonClicked(1); this->rescanButtonClicked(1);
}); });
@ -2204,16 +2204,16 @@ void MainWindow::slot_change_theme(QString& theme_name)
} }
void MainWindow::rescanButtonClicked(int number) { void MainWindow::rescanButtonClicked(int number) {
qDebug() << __func__ << ": " << number;
qDebug() << "rescanButtonClicked" << number;
// Setup rescan dialog // Setup rescan dialog
Ui_RescanDialog rescanDialog; Ui_RescanDialog rescanDialog;
QDialog dialog(this); QDialog dialog(this);
rescanDialog.setupUi(&dialog); rescanDialog.setupUi(&dialog);
// TODO: Maybe set to current blockheight by default
rescanDialog.rescanBlockheight->setFocus(); rescanDialog.rescanBlockheight->setFocus();
// Default to full rescan
rescanDialog.rescanBlockheight->setText("1");
// Add validator for block height // Add validator for block height
QRegExpValidator* heightValidator = new QRegExpValidator(QRegExp("\\d*"), this); QRegExpValidator* heightValidator = new QRegExpValidator(QRegExp("\\d*"), this);
@ -2221,7 +2221,6 @@ void MainWindow::rescanButtonClicked(int number) {
// Check if OK clicked // Check if OK clicked
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
// Show message in status bar // Show message in status bar
ui->statusBar->showMessage(tr("Rescanning...")); ui->statusBar->showMessage(tr("Rescanning..."));
@ -2232,38 +2231,17 @@ void MainWindow::rescanButtonClicked(int number) {
// Get submitted rescan height // Get submitted rescan height
int rescanHeight = rescanDialog.rescanBlockheight->text().toInt(); int rescanHeight = rescanDialog.rescanBlockheight->text().toInt();
qDebug() << "rescan height = " << rescanHeight; qDebug() << __func__ << ": rescan height = " << rescanHeight;
// Call rescan RPC // Call rescan RPC
rpc->rescan(rescanHeight, [=] (QJsonValue response){ rpc->rescan(rescanHeight, [=] (QJsonValue response){
qDebug() << "rescanning finished" << response; qDebug() << __func__ << ":rescanning finished" << response;
ui->statusBar->showMessage(tr("Rescanning finished"), 3000); ui->statusBar->showMessage(tr("Rescanning finished"), 3000);
}); });
// Get rescan info qDebug() << __func__ << ": force refresh of rescan data";
QTimer *rescanTimer = new QTimer(this); rpc->refreshRescan();
QObject::connect(rescanTimer, &QTimer::timeout, [=]() {
rpc->getRescanInfo([=] (QJsonValue response){
auto rescanning = response.toObject().value("rescanning").toBool();
auto rescan_progress = response.toObject().value("rescan_progress").toString();
auto rescan_start_height = (qint64)response.toObject().value("rescan_start_height").toInt();
auto rescan_height = (qint64)response.toObject().value("rescan_height").toInt();
double percent = QString(rescan_progress).toDouble() * 100;
qDebug() << "getrescaninfo" << rescanning << " " << percent << " " << rescan_start_height << " " << rescan_height;
if(rescanning){
qDebug() << "Rescanning...";
ui->statusBar->showMessage(tr("Rescanning... ") + QString::number(percent)+ "% " + QObject::tr("at height") + " " + QString::number(rescan_height));
}
else{
qDebug() << "rescanTimer Stop";
rescanTimer->stop();
}
});
});
rescanTimer->start(1000);
} }
} }

77
src/rpc.cpp

@ -39,21 +39,33 @@ RPC::RPC(MainWindow* main) {
// Set up timer to refresh Price // Set up timer to refresh Price
priceTimer = new QTimer(main); priceTimer = new QTimer(main);
QObject::connect(priceTimer, &QTimer::timeout, [=]() { QObject::connect(priceTimer, &QTimer::timeout, [=]() {
qDebug() << "Refreshing price data";
refreshPrice(); refreshPrice();
}); });
priceTimer->start(Settings::priceRefreshSpeed); priceTimer->start(Settings::priceRefreshSpeed);
qDebug() << __func__ << ": started price refresh at speed=" << Settings::priceRefreshSpeed; qDebug() << __func__ << ": started price refresh at speed=" << Settings::priceRefreshSpeed;
// Set up a timer to refresh the UI every few seconds qDebug() << "setting up timer for rescan data";
rescanTimer = new QTimer(main);
QObject::connect(rescanTimer, &QTimer::timeout, [=]() {
qDebug() << "Refreshing rescan data";
refreshRescan();
});
qDebug() << __func__ << ": started rescanTimer";
rescanTimer->start(Settings::updateSpeed);
qDebug() << __func__ << ": Setting up a timer to refresh the UI every few seconds";
timer = new QTimer(main); timer = new QTimer(main);
QObject::connect(timer, &QTimer::timeout, [=]() { QObject::connect(timer, &QTimer::timeout, [=]() {
//qDebug() << "Refreshing main UI"; qDebug() << "Refreshing main UI";
refresh(); refresh();
}); });
timer->start(Settings::updateSpeed); timer->start(Settings::updateSpeed);
qDebug() << __func__ << ": Set up the timer to watch for tx status";
// Set up the timer to watch for tx status
txTimer = new QTimer(main); txTimer = new QTimer(main);
QObject::connect(txTimer, &QTimer::timeout, [=]() { QObject::connect(txTimer, &QTimer::timeout, [=]() {
//qDebug() << "Watching tx status"; //qDebug() << "Watching tx status";
@ -71,8 +83,10 @@ RPC::RPC(MainWindow* main) {
} }
RPC::~RPC() { RPC::~RPC() {
qDebug() << "Deleting stuff";
delete timer; delete timer;
delete txTimer; delete txTimer;
delete priceTimer;
delete transactionsTableModel; delete transactionsTableModel;
delete balancesTableModel; delete balancesTableModel;
@ -92,6 +106,16 @@ void RPC::setEHushd(std::shared_ptr<QProcess> p) {
ehushd = p; ehushd = p;
} }
void RPC::pauseTimer() {
qDebug() << "pausing main timer";
timer->stop();
}
void RPC::restartTimer() {
qDebug() << "restarting main timer";
timer->start(Settings::updateSpeed);
}
// Called when a connection to hushd is available. // Called when a connection to hushd is available.
void RPC::setConnection(Connection* c) { void RPC::setConnection(Connection* c) {
if (c == nullptr) return; if (c == nullptr) return;
@ -116,6 +140,7 @@ void RPC::setConnection(Connection* c) {
} }
QJsonValue RPC::makePayload(QString method, QString param, QString param2) { QJsonValue RPC::makePayload(QString method, QString param, QString param2) {
// qDebug() << __func__ << ": method=" << method << " payload=" << param << ", " << param2;
QJsonObject payload = { QJsonObject payload = {
{"jsonrpc", "1.0"}, {"jsonrpc", "1.0"},
{"id", "42" }, {"id", "42" },
@ -126,6 +151,7 @@ QJsonValue RPC::makePayload(QString method, QString param, QString param2) {
} }
QJsonValue RPC::makePayload(QString method, QString param) { QJsonValue RPC::makePayload(QString method, QString param) {
// qDebug() << __func__ << ": method=" << method << " " << "payload=" << param;
QJsonObject payload = { QJsonObject payload = {
{"jsonrpc", "1.0"}, {"jsonrpc", "1.0"},
{"id", "42" }, {"id", "42" },
@ -136,6 +162,7 @@ QJsonValue RPC::makePayload(QString method, QString param) {
} }
QJsonValue RPC::makePayload(QString method, int param) { QJsonValue RPC::makePayload(QString method, int param) {
// qDebug() << __func__ << ": method=" << method << " payload=" << param;
QJsonObject payload = { QJsonObject payload = {
{"jsonrpc", "1.0"}, {"jsonrpc", "1.0"},
{"id", "42" }, {"id", "42" },
@ -146,6 +173,7 @@ QJsonValue RPC::makePayload(QString method, int param) {
} }
QJsonValue RPC::makePayload(QString method) { QJsonValue RPC::makePayload(QString method) {
// qDebug() << __func__ << ": method=" << method << " with no payload";
QJsonObject payload = { QJsonObject payload = {
{"jsonrpc", "1.0"}, {"jsonrpc", "1.0"},
{"id", "42" }, {"id", "42" },
@ -173,6 +201,12 @@ void RPC::getRescanInfo(const std::function<void(QJsonValue)>& cb){
conn->doRPCWithDefaultErrorHandling(makePayload(method), cb); conn->doRPCWithDefaultErrorHandling(makePayload(method), cb);
} }
// get help
void RPC::help(const std::function<void(QJsonValue)>& cb){
QString method = "help";
conn->doRPCWithDefaultErrorHandling(makePayload(method), cb);
}
// add/remove a banned node. ip can include an optional netmask // add/remove a banned node. ip can include an optional netmask
void RPC::setban(QString ip, QString command, const std::function<void(QJsonValue)>& cb) { void RPC::setban(QString ip, QString command, const std::function<void(QJsonValue)>& cb) {
QString method = "setban"; QString method = "setban";
@ -965,6 +999,41 @@ void RPC::refreshBalances() {
}); });
} }
void RPC::refreshRescan() {
qDebug() << __func__;
if (conn == nullptr) {
return noConnection();
}
conn->doRPC(makePayload("help", "getrescaninfo"), [=] (const QJsonValue& reply) {
qDebug() << __func__ << ": found getrescaninfo: reply=" << reply;
// Get rescan info
QObject::connect(rescanTimer, &QTimer::timeout, [=]() {
qDebug() << "setting callback for getrescaninfo";
getRescanInfo([=] (QJsonValue response){
qDebug() << "got getrescaninfo json";
auto rescanning = response.toObject().value("rescanning").toBool();
auto rescan_progress = response.toObject().value("rescan_progress").toString();
auto rescan_start_height = (qint64)response.toObject().value("rescan_start_height").toInt();
auto rescan_height = (qint64)response.toObject().value("rescan_height").toInt();
double percent = QString(rescan_progress).toDouble() * 100;
qDebug() << __func__ << ": getrescaninfo" << rescanning << " " << percent << " " << rescan_start_height << " " << rescan_height;
if(rescanning){
pauseTimer();
qDebug() << __func__ << ": Rescanning at " << percent << " %";
ui->statusBar->showMessage(QObject::tr("Rescanning... ") + QString::number(percent)+ "% " + QObject::tr("at height") + " " + QString::number(rescan_height));
} else{
qDebug() << __func__ << ": not rescanning";
}
});
});
}, [=](QNetworkReply* reply, const QJsonValue&) {
qDebug() << __func__ << ": missing getrescaninfo, no rescan progress will be shown: reply=" << reply;
});
}
void RPC::refreshPeers() { void RPC::refreshPeers() {
qDebug() << __func__; qDebug() << __func__;
if (conn == nullptr) if (conn == nullptr)

5
src/rpc.h

@ -65,8 +65,11 @@ public:
const QProcess* getEHushD() { return ehushd.get(); } const QProcess* getEHushD() { return ehushd.get(); }
void refresh(bool force = false); void refresh(bool force = false);
void pauseTimer();
void restartTimer();
void refreshAddresses(); void refreshAddresses();
void refreshRescan();
void refreshPeers(); void refreshPeers();
void setban(QString ip, QString command, const std::function<void(QJsonValue)>& cb); void setban(QString ip, QString command, const std::function<void(QJsonValue)>& cb);
void clearBanned(const std::function<void(QJsonValue)>& cb); void clearBanned(const std::function<void(QJsonValue)>& cb);
@ -120,6 +123,7 @@ public:
void rescan(qint64 height, const std::function<void(QJsonValue)>& cb); void rescan(qint64 height, const std::function<void(QJsonValue)>& cb);
void getRescanInfo(const std::function<void(QJsonValue)>& cb); void getRescanInfo(const std::function<void(QJsonValue)>& cb);
void help(const std::function<void(QJsonValue)>& cb);
private: private:
void refreshBalances(); void refreshBalances();
@ -167,6 +171,7 @@ private:
QTimer* timer; QTimer* timer;
QTimer* txTimer; QTimer* txTimer;
QTimer* priceTimer; QTimer* priceTimer;
QTimer* rescanTimer;
Ui::MainWindow* ui; Ui::MainWindow* ui;
MainWindow* main; MainWindow* main;

Loading…
Cancel
Save