#58 - Verify params on startup
This commit is contained in:
+66
-28
@@ -30,8 +30,15 @@ void ConnectionLoader::loadConnection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) {
|
void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) {
|
||||||
// Priority 1: Try to connect to detect zcash.conf and connect to it.
|
// Priority 1: Ensure all params are present.
|
||||||
|
if (!verifyParams()) {
|
||||||
|
downloadParams([=]() { this->doAutoConnect(); });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Priority 2: Try to connect to detect zcash.conf and connect to it.
|
||||||
auto config = autoDetectZcashConf();
|
auto config = autoDetectZcashConf();
|
||||||
|
main->logger->write("Attempting autoconnect");
|
||||||
|
|
||||||
if (config.get() != nullptr) {
|
if (config.get() != nullptr) {
|
||||||
auto connection = makeConnection(config);
|
auto connection = makeConnection(config);
|
||||||
@@ -43,6 +50,7 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) {
|
|||||||
this->showInformation("Starting embedded zcashd");
|
this->showInformation("Starting embedded zcashd");
|
||||||
if (this->startEmbeddedZcashd()) {
|
if (this->startEmbeddedZcashd()) {
|
||||||
// Embedded zcashd started up. Wait a second and then refresh the connection
|
// Embedded zcashd started up. Wait a second and then refresh the connection
|
||||||
|
main->logger->write("Embedded zcashd started up, trying autoconnect in 1 sec");
|
||||||
QTimer::singleShot(1000, [=]() { doAutoConnect(); } );
|
QTimer::singleShot(1000, [=]() { doAutoConnect(); } );
|
||||||
} else {
|
} else {
|
||||||
// Something is wrong. This is happenening intermittently on Mac platforms.
|
// Something is wrong. This is happenening intermittently on Mac platforms.
|
||||||
@@ -51,10 +59,12 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) {
|
|||||||
// - QProcess ended, but the embedded zcashd is still in the background.
|
// - QProcess ended, but the embedded zcashd is still in the background.
|
||||||
// We're going to attempt to connect to the one in the background one last time
|
// We're going to attempt to connect to the one in the background one last time
|
||||||
// and see if that works, else throw an error
|
// and see if that works, else throw an error
|
||||||
|
main->logger->write("Something is wrong, trying no-retry autoconnect in 2 sec");
|
||||||
QTimer::singleShot(2000, [=]() { doAutoConnect(/* don't attempt to start ezcashd */ false); });
|
QTimer::singleShot(2000, [=]() { doAutoConnect(/* don't attempt to start ezcashd */ false); });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We tried to start ezcashd previously, and it didn't work. So, show the error.
|
// We tried to start ezcashd previously, and it didn't work. So, show the error.
|
||||||
|
main->logger->write("Couldn't start embedded zcashd for unknown reason");
|
||||||
QString explanation = QString() % "Couldn't start the embedded zcashd.\n\n" %
|
QString explanation = QString() % "Couldn't start the embedded zcashd.\n\n" %
|
||||||
"Please try restarting.\n\nIfIf you previously started zcashd with custom arguments, you might need to reset zcash.conf.\n\n" %
|
"Please try restarting.\n\nIfIf you previously started zcashd with custom arguments, you might need to reset zcash.conf.\n\n" %
|
||||||
"If all else fails, please run zcashd manually." %
|
"If all else fails, please run zcashd manually." %
|
||||||
@@ -64,6 +74,7 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// zcash.conf exists, there's no connection, and the user asked us not to start zcashd. Error!
|
// zcash.conf exists, there's no connection, and the user asked us not to start zcashd. Error!
|
||||||
|
main->logger->write("Not using embedded and couldn't connect to zcashd");
|
||||||
QString explanation = QString() % "Couldn't connect to zcashd configured in zcash.conf.\n\n" %
|
QString explanation = QString() % "Couldn't connect to zcashd configured in zcash.conf.\n\n" %
|
||||||
"Not starting embedded zcashd because --no-embedded was passed";
|
"Not starting embedded zcashd because --no-embedded was passed";
|
||||||
this->showError(explanation);
|
this->showError(explanation);
|
||||||
@@ -101,35 +112,35 @@ QString randomPassword() {
|
|||||||
* This will create a new zcash.conf, download Zcash parameters.
|
* This will create a new zcash.conf, download Zcash parameters.
|
||||||
*/
|
*/
|
||||||
void ConnectionLoader::createZcashConf() {
|
void ConnectionLoader::createZcashConf() {
|
||||||
// Fetch params. After params are fetched, create the zcash.conf file and
|
main->logger->write("createZcashConf");
|
||||||
// try loading the connection again
|
|
||||||
downloadParams([=] () {
|
|
||||||
auto confLocation = zcashConfWritableLocation();
|
|
||||||
qDebug() << "Creating file " << confLocation;
|
|
||||||
|
|
||||||
QFileInfo fi(confLocation);
|
auto confLocation = zcashConfWritableLocation();
|
||||||
QDir().mkdir(fi.dir().absolutePath());
|
main->logger->write("Creating file " + confLocation);
|
||||||
|
|
||||||
QFile file(confLocation);
|
QFileInfo fi(confLocation);
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
|
QDir().mkdir(fi.dir().absolutePath());
|
||||||
qDebug() << "Could not create zcash.conf, returning";
|
|
||||||
return;
|
QFile file(confLocation);
|
||||||
}
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
|
||||||
|
main->logger->write("Could not create zcash.conf, returning");
|
||||||
QTextStream out(&file);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
out << "server=1\n";
|
QTextStream out(&file);
|
||||||
out << "addnode=mainnet.z.cash\n";
|
|
||||||
out << "rpcuser=zec-qt-wallet\n";
|
out << "server=1\n";
|
||||||
out << "rpcpassword=" % randomPassword() << "\n";
|
out << "addnode=mainnet.z.cash\n";
|
||||||
file.close();
|
out << "rpcuser=zec-qt-wallet\n";
|
||||||
|
out << "rpcpassword=" % randomPassword() << "\n";
|
||||||
|
file.close();
|
||||||
|
|
||||||
this->doAutoConnect();
|
// Now that zcash.conf exists, try to autoconnect again
|
||||||
});
|
this->doAutoConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ConnectionLoader::downloadParams(std::function<void(void)> cb) {
|
void ConnectionLoader::downloadParams(std::function<void(void)> cb) {
|
||||||
|
main->logger->write("Adding params to download queue");
|
||||||
// Add all the files to the download queue
|
// Add all the files to the download queue
|
||||||
downloadQueue = new QQueue<QUrl>();
|
downloadQueue = new QQueue<QUrl>();
|
||||||
client = new QNetworkAccessManager(main);
|
client = new QNetworkAccessManager(main);
|
||||||
@@ -155,6 +166,7 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
|
|||||||
delete downloadQueue;
|
delete downloadQueue;
|
||||||
client->deleteLater();
|
client->deleteLater();
|
||||||
|
|
||||||
|
main->logger->write("All Downloads done");
|
||||||
this->showInformation("All Downloads Finished Successfully!");
|
this->showInformation("All Downloads Finished Successfully!");
|
||||||
cb();
|
cb();
|
||||||
return;
|
return;
|
||||||
@@ -167,7 +179,7 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
|
|||||||
QString paramsDir = zcashParamsDir();
|
QString paramsDir = zcashParamsDir();
|
||||||
|
|
||||||
if (QFile(QDir(paramsDir).filePath(filename)).exists()) {
|
if (QFile(QDir(paramsDir).filePath(filename)).exists()) {
|
||||||
qDebug() << filename << " already exists, skipping ";
|
main->logger->write(filename + " already exists, skipping");
|
||||||
doNextDownload(cb);
|
doNextDownload(cb);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -177,8 +189,10 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
|
|||||||
currentOutput = new QFile(QDir(paramsDir).filePath(filename + ".part"));
|
currentOutput = new QFile(QDir(paramsDir).filePath(filename + ".part"));
|
||||||
|
|
||||||
if (!currentOutput->open(QIODevice::WriteOnly)) {
|
if (!currentOutput->open(QIODevice::WriteOnly)) {
|
||||||
|
main->logger->write("Couldn't open " + currentOutput->fileName() + " for writing");
|
||||||
this->showError("Couldn't download params. Please check the help site for more info.");
|
this->showError("Couldn't download params. Please check the help site for more info.");
|
||||||
}
|
}
|
||||||
|
main->logger->write("Downloading to " + filename);
|
||||||
qDebug() << "Downloading " << url << " to " << filename;
|
qDebug() << "Downloading " << url << " to " << filename;
|
||||||
|
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
@@ -209,6 +223,7 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
|
|||||||
// Download Finished
|
// Download Finished
|
||||||
QObject::connect(currentDownload, &QNetworkReply::finished, [=] () {
|
QObject::connect(currentDownload, &QNetworkReply::finished, [=] () {
|
||||||
// Rename file
|
// Rename file
|
||||||
|
main->logger->write("Finished downloading " + filename);
|
||||||
currentOutput->rename(QDir(paramsDir).filePath(filename));
|
currentOutput->rename(QDir(paramsDir).filePath(filename));
|
||||||
|
|
||||||
currentOutput->close();
|
currentOutput->close();
|
||||||
@@ -216,7 +231,8 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
|
|||||||
currentOutput->deleteLater();
|
currentOutput->deleteLater();
|
||||||
|
|
||||||
if (currentDownload->error()) {
|
if (currentDownload->error()) {
|
||||||
this->showError("Downloading " + filename + " failed/ Please check the help site for more info");
|
main->logger->write("Downloading " + filename + " failed");
|
||||||
|
this->showError("Downloading " + filename + " failed. Please check the help site for more info");
|
||||||
} else {
|
} else {
|
||||||
doNextDownload(cb);
|
doNextDownload(cb);
|
||||||
}
|
}
|
||||||
@@ -231,6 +247,8 @@ void ConnectionLoader::doNextDownload(std::function<void(void)> cb) {
|
|||||||
bool ConnectionLoader::startEmbeddedZcashd() {
|
bool ConnectionLoader::startEmbeddedZcashd() {
|
||||||
if (!Settings::getInstance()->useEmbedded())
|
if (!Settings::getInstance()->useEmbedded())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
main->logger->write("Trying to start embedded zcashd");
|
||||||
|
|
||||||
// Static because it needs to survive even after this method returns.
|
// Static because it needs to survive even after this method returns.
|
||||||
static QString processStdErrOutput;
|
static QString processStdErrOutput;
|
||||||
@@ -263,6 +281,7 @@ bool ConnectionLoader::startEmbeddedZcashd() {
|
|||||||
|
|
||||||
if (!QFile(zcashdProgram).exists()) {
|
if (!QFile(zcashdProgram).exists()) {
|
||||||
qDebug() << "Can't find zcashd at " << zcashdProgram;
|
qDebug() << "Can't find zcashd at " << zcashdProgram;
|
||||||
|
main->logger->write("Can't find zcashd at " + zcashdProgram);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +301,7 @@ bool ConnectionLoader::startEmbeddedZcashd() {
|
|||||||
|
|
||||||
QObject::connect(ezcashd, &QProcess::readyReadStandardError, [=]() {
|
QObject::connect(ezcashd, &QProcess::readyReadStandardError, [=]() {
|
||||||
auto output = ezcashd->readAllStandardError();
|
auto output = ezcashd->readAllStandardError();
|
||||||
qDebug() << "zcashd stderr:" << output;
|
main->logger->write("zcashd stderr:" + output);
|
||||||
processStdErrOutput.append(output);
|
processStdErrOutput.append(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -375,6 +394,7 @@ void ConnectionLoader::refreshZcashdState(Connection* connection, std::function<
|
|||||||
if (err == QNetworkReply::NetworkError::ConnectionRefusedError) {
|
if (err == QNetworkReply::NetworkError::ConnectionRefusedError) {
|
||||||
refused();
|
refused();
|
||||||
} else if (err == QNetworkReply::NetworkError::AuthenticationRequiredError) {
|
} else if (err == QNetworkReply::NetworkError::AuthenticationRequiredError) {
|
||||||
|
main->logger->write("Authentication failed");
|
||||||
QString explanation = QString()
|
QString explanation = QString()
|
||||||
% "Authentication failed. The username / password you specified was "
|
% "Authentication failed. The username / password you specified was "
|
||||||
% "not accepted by zcashd. Try changing it in the Edit->Settings menu";
|
% "not accepted by zcashd. Try changing it in the Edit->Settings menu";
|
||||||
@@ -392,7 +412,7 @@ void ConnectionLoader::refreshZcashdState(Connection* connection, std::function<
|
|||||||
dots = 0;
|
dots = 0;
|
||||||
}
|
}
|
||||||
this->showInformation("Your zcashd is starting up. Please wait.", status);
|
this->showInformation("Your zcashd is starting up. Please wait.", status);
|
||||||
|
main->logger->write("Waiting to zcashd to come online.");
|
||||||
// Refresh after one second
|
// Refresh after one second
|
||||||
QTimer::singleShot(1000, [=]() { this->refreshZcashdState(connection, refused); });
|
QTimer::singleShot(1000, [=]() { this->refreshZcashdState(connection, refused); });
|
||||||
}
|
}
|
||||||
@@ -424,6 +444,8 @@ QString ConnectionLoader::locateZcashConfFile() {
|
|||||||
#else
|
#else
|
||||||
auto confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Zcash/zcash.conf");
|
auto confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Zcash/zcash.conf");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
main->logger->write("Found zcashconf at " + QDir::cleanPath(confLocation));
|
||||||
return QDir::cleanPath(confLocation);
|
return QDir::cleanPath(confLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +458,8 @@ QString ConnectionLoader::zcashConfWritableLocation() {
|
|||||||
auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("../../Zcash/zcash.conf");
|
auto confLocation = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("../../Zcash/zcash.conf");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return confLocation;
|
main->logger->write("Found zcashconf at " + QDir::cleanPath(confLocation));
|
||||||
|
return QDir::cleanPath(confLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionLoader::zcashParamsDir() {
|
QString ConnectionLoader::zcashParamsDir() {
|
||||||
@@ -449,12 +472,26 @@ QString ConnectionLoader::zcashParamsDir() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!paramsLocation.exists()) {
|
if (!paramsLocation.exists()) {
|
||||||
|
main->logger->write("Creating params location at " + paramsLocation.absolutePath());
|
||||||
QDir().mkpath(paramsLocation.absolutePath());
|
QDir().mkpath(paramsLocation.absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main->logger->write("Found zcash params directory at " + paramsLocation.absolutePath());
|
||||||
return paramsLocation.absolutePath();
|
return paramsLocation.absolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConnectionLoader::verifyParams() {
|
||||||
|
QDir paramsDir(zcashParamsDir());
|
||||||
|
|
||||||
|
if (!QFile(paramsDir.filePath("sapling-output.params")).exists()) return false;
|
||||||
|
if (!QFile(paramsDir.filePath("sapling-spend.params")).exists()) return false;
|
||||||
|
if (!QFile(paramsDir.filePath("sprout-proving.key")).exists()) return false;
|
||||||
|
if (!QFile(paramsDir.filePath("sprout-verifying.key")).exists()) return false;
|
||||||
|
if (!QFile(paramsDir.filePath("sprout-groth16.params")).exists()) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to automatically detect a zcash.conf file in the correct location and load parameters
|
* Try to automatically detect a zcash.conf file in the correct location and load parameters
|
||||||
*/
|
*/
|
||||||
@@ -506,9 +543,10 @@ std::shared_ptr<ConnectionConfig> ConnectionLoader::autoDetectZcashConf() {
|
|||||||
|
|
||||||
// If rpcport is not in the file, and it was not set by the testnet=1 flag, then go to default
|
// If rpcport is not in the file, and it was not set by the testnet=1 flag, then go to default
|
||||||
if (zcashconf->port.isEmpty()) zcashconf->port = "8232";
|
if (zcashconf->port.isEmpty()) zcashconf->port = "8232";
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
// In addition to the zcash.conf file, also double check the params.
|
||||||
|
|
||||||
return std::shared_ptr<ConnectionConfig>(zcashconf);
|
return std::shared_ptr<ConnectionConfig>(zcashconf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ private:
|
|||||||
QString zcashConfWritableLocation();
|
QString zcashConfWritableLocation();
|
||||||
QString zcashParamsDir();
|
QString zcashParamsDir();
|
||||||
|
|
||||||
|
bool verifyParams();
|
||||||
void downloadParams(std::function<void(void)> cb);
|
void downloadParams(std::function<void(void)> cb);
|
||||||
void doNextDownload(std::function<void(void)> cb);
|
void doNextDownload(std::function<void(void)> cb);
|
||||||
bool startEmbeddedZcashd();
|
bool startEmbeddedZcashd();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
ui(new Ui::MainWindow)
|
ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("zec-qt-wallet.log"));
|
||||||
|
|
||||||
// Status Bar
|
// Status Bar
|
||||||
setupStatusBar();
|
setupStatusBar();
|
||||||
@@ -1040,4 +1041,5 @@ MainWindow::~MainWindow()
|
|||||||
delete labelCompleter;
|
delete labelCompleter;
|
||||||
|
|
||||||
delete loadingMovie;
|
delete loadingMovie;
|
||||||
|
delete logger;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
// Forward declare to break circular dependency.
|
// Forward declare to break circular dependency.
|
||||||
class RPC;
|
class RPC;
|
||||||
@@ -45,6 +46,7 @@ public:
|
|||||||
QLabel* loadingLabel;
|
QLabel* loadingLabel;
|
||||||
QWidget* zcashdtab;
|
QWidget* zcashdtab;
|
||||||
|
|
||||||
|
Logger* logger;
|
||||||
private:
|
private:
|
||||||
void closeEvent(QCloseEvent* event);
|
void closeEvent(QCloseEvent* event);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user