Browse Source

Merge branch 'master' into version

pull/45/head
Duke Leto 5 years ago
parent
commit
9b8cbd4194
  1. 19
      README.md
  2. 89
      src/connection.cpp
  3. 2
      src/connection.h
  4. 16
      src/mainwindow.cpp
  5. 2
      src/mainwindow.ui
  6. 6
      src/rpc.cpp
  7. 6
      src/rpc.h
  8. 14
      src/settings.cpp

19
README.md

@ -17,17 +17,17 @@ Pass `--no-embedded` to disable the embedded hushd and force SilentDragon to con
## Compiling from source
SilentDragon is written in C++ 14, and can be compiled with g++/clang++/visual c++. It also depends on Qt5, which you can get from [here](https://www.qt.io/download). Note that if you are compiling from source, you won't get the embedded hushd by default. You can either run an external hushd, or compile hushd as well.
See detailed build instructions [on the wiki](https://github.com/MyHush/SilentDragon/wiki/Compiling-from-source-code)
### Building on Linux
```
sudo apt-get install qt5-default qt5-qmake libqt5websockets5-dev
git clone https://github.com/MyHush/SilentDragon.git
cd SilentDragon
qmake silentdragon.pro CONFIG+=debug
make -j$(nproc)
./SilentDragon
./silentdragon
```
### Building on Windows
@ -60,6 +60,21 @@ make
./SilentDragon.app/Contents/MacOS/SilentDragon
```
### Emulating the embedded node
In binary releases, SilentDragon will use node binaries in the current directory to sync a node from scratch.
It does not attempt to download them, it bundles them. To simulate this from a developer setup, you can symlink
these four files in your Git repo:
```
ln -s ../hush3/src/hushd
ln -s ../hush3/src/hush-cli
ln -s ../hush3/src/komodod
ln -s ../hush3/src/komodo-cli
```
The above assumes silentdragon and hush3 git repos are in the same directory. File names on Windows will need to be tweaked.
### Support
For support or other questions, Join [Discord](https://myhush.org/discord), or tweet at [@MyHushTeam](https://twitter.com/MyHushTeam) or [file an issue](https://github.com/MyHush/SilentDragon/issues).

89
src/connection.cpp

@ -14,6 +14,7 @@ ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) {
this->rpc = rpc;
d = new QDialog(main);
d->setWindowFlags(d->windowFlags() & ~(Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint));
connD = new Ui_ConnectionDialog();
connD->setupUi(d);
QPixmap logo(":/img/res/logobig.gif");
@ -51,29 +52,29 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) {
// Refused connection. So try and start embedded zcashd
if (Settings::getInstance()->useEmbedded()) {
if (tryEzcashdStart) {
this->showInformation(QObject::tr("Starting embedded zcashd"));
this->showInformation(QObject::tr("Starting embedded hushd"));
if (this->startEmbeddedZcashd()) {
// Embedded zcashd started up. Wait a second and then refresh the connection
main->logger->write("Embedded zcashd started up, trying autoconnect in 1 sec");
main->logger->write("Embedded hushd started up, trying autoconnect in 1 sec");
QTimer::singleShot(1000, [=]() { doAutoConnect(); } );
} else {
if (config->zcashDaemon) {
// zcashd is configured to run as a daemon, so we must wait for a few seconds
// hushd is configured to run as a daemon, so we must wait for a few seconds
// to let it start up.
main->logger->write("zcashd is daemon=1. Waiting for it to start up");
this->showInformation(QObject::tr("zcashd is set to run as daemon"), QObject::tr("Waiting for zcashd"));
QTimer::singleShot(5000, [=]() { doAutoConnect(/* don't attempt to start ezcashd */ false); });
main->logger->write("hushd is daemon=1. Waiting for it to start up");
this->showInformation(QObject::tr("hushd is set to run as daemon"), QObject::tr("Waiting for hushd"));
QTimer::singleShot(5000, [=]() { doAutoConnect(/* don't attempt to start ehushd */ false); });
} else {
// Something is wrong.
// 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
main->logger->write("Unknown problem while trying to start zcashd");
main->logger->write("Unknown problem while trying to start hushd!");
QTimer::singleShot(2000, [=]() { doAutoConnect(/* don't attempt to start ezcashd */ false); });
}
}
} else {
// 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");
main->logger->write("Couldn't start embedded hushd for unknown reason");
QString explanation;
if (config->zcashDaemon) {
explanation = QString() % QObject::tr("You have komodod set to start as a daemon, which can cause problems "
@ -81,9 +82,9 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) {
"Please remove the following line from your HUSH3.conf and restart SilentDragon\n"
"daemon=1");
} else {
explanation = QString() % QObject::tr("Couldn't start the embedded komodod.\n\n"
explanation = QString() % QObject::tr("Couldn't start the embedded hushd.\n\n"
"Please try restarting.\n\nIf you previously started komodod with custom arguments, you might need to reset HUSH3.conf.\n\n"
"If all else fails, please run zcashd manually.") %
"If all else fails, please run hushd manually.") %
(ezcashd ? QObject::tr("The process returned") + ":\n\n" % ezcashd->errorString() : QString(""));
}
@ -178,15 +179,23 @@ void ConnectionLoader::createZcashConf() {
QFile file(confLocation);
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
main->logger->write("Could not create HUSH3.conf, returning");
QString explanation = QString() % QObject::tr("Could not create HUSH3.conf.");
this->showError(explanation);
return;
}
QTextStream out(&file);
out << "# Autogenerated by Silent Dragon\n";
out << "server=1\n";
out << "rpcuser=hush\n";
out << "rpcpassword=" % randomPassword() << "\n";
out << "rpcport=18031\n";
out << "txindex=1\n";
out << "addressindex=1\n";
out << "spentindex=1\n";
out << "timestampindex=1\n";
out << "rpcworkqueue=256\n";
out << "rpcallowip=127.0.0.1\n";
@ -209,11 +218,9 @@ void ConnectionLoader::downloadParams(std::function<void(void)> cb) {
// Add all the files to the download queue
downloadQueue = new QQueue<QUrl>();
client = new QNetworkAccessManager(main);
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-output.params"));
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-spend.params"));
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sprout-proving.key"));
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sprout-verifying.key"));
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-spend.params"));
downloadQueue->enqueue(QUrl("https://z.cash/downloads/sprout-groth16.params"));
doNextDownload(cb);
@ -333,39 +340,44 @@ bool ConnectionLoader::startEmbeddedZcashd() {
// Finally, start zcashd
QDir appPath(QCoreApplication::applicationDirPath());
#ifdef Q_OS_LINUX
auto zcashdProgram = appPath.absoluteFilePath("komodod");
auto zcashdProgram = appPath.absoluteFilePath("hushd");
if (!QFile(zcashdProgram).exists()) {
zcashdProgram = appPath.absoluteFilePath("komodod");
zcashdProgram = appPath.absoluteFilePath("hushd");
}
#elif defined(Q_OS_DARWIN)
auto zcashdProgram = appPath.absoluteFilePath("komodod");
auto zcashdProgram = appPath.absoluteFilePath("hushd");
#elif defined(Q_OS_WIN64)
auto zcashdProgram = appPath.absoluteFilePath("hushd.bat");
#else
auto zcashdProgram = appPath.absoluteFilePath("komodod.exe");
//TODO: Not Linux + not darwin DOES NOT EQUAL windows!!!
auto zcashdProgram = appPath.absoluteFilePath("hushd");
#endif
if (!QFile(zcashdProgram).exists()) {
qDebug() << "Can't find zcashd at " << zcashdProgram;
main->logger->write("Can't find zcashd at " + zcashdProgram);
qDebug() << "Can't find hushd at " << zcashdProgram;
main->logger->write("Can't find hushd at " + zcashdProgram);
return false;
}
ezcashd = new QProcess(main);
QObject::connect(ezcashd, &QProcess::started, [=] () {
//qDebug() << "zcashd started";
ezcashd = std::shared_ptr<QProcess>(new QProcess(main));
QObject::connect(ezcashd.get(), &QProcess::started, [=] () {
qDebug() << "Embedded hushd started";
});
QObject::connect(ezcashd, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
[=](int, QProcess::ExitStatus) {
//qDebug() << "zcashd finished with code " << exitCode << "," << exitStatus;
QObject::connect(ezcashd.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
[=](int exitCode, QProcess::ExitStatus exitStatus) {
qDebug() << "hushd finished with code " << exitCode << "," << exitStatus;
});
QObject::connect(ezcashd, &QProcess::errorOccurred, [&] (auto) {
//qDebug() << "Couldn't start zcashd: " << error;
QObject::connect(ezcashd.get(), &QProcess::errorOccurred, [&] (QProcess::ProcessError error) {
qDebug() << "Couldn't start hushd: " << error;
});
QObject::connect(ezcashd, &QProcess::readyReadStandardError, [=]() {
auto output = ezcashd->readAllStandardError();
main->logger->write("hushd stderr:" + output);
std::weak_ptr<QProcess> weak_obj(ezcashd);
auto ptr_main(main);
QObject::connect(ezcashd.get(), &QProcess::readyReadStandardError, [weak_obj, ptr_main]() {
auto output = weak_obj.lock()->readAllStandardError();
ptr_main->logger->write("hushd stderr:" + output);
processStdErrOutput.append(output);
});
@ -375,7 +387,7 @@ bool ConnectionLoader::startEmbeddedZcashd() {
ezcashd->start(zcashdProgram);
#else
ezcashd->setWorkingDirectory(appPath.absolutePath());
ezcashd->start("komodo.exe");
ezcashd->start(zcashdProgram);
#endif // Q_OS_LINUX
@ -448,10 +460,10 @@ void ConnectionLoader::refreshZcashdState(Connection* connection, std::function<
};
connection->doRPC(payload,
[=] (auto) {
// Success, hide the dialog if it was shown.
d->hide();
// Success
main->logger->write("hushd is online.");
this->doRPCSetConnection(connection);
// Delay 1 second to ensure loading (splash) is seen at least 1 second.
QTimer::singleShot(1000, [=]() { this->doRPCSetConnection(connection); });
},
[=] (auto reply, auto res) {
// Failed, see what it is.
@ -563,13 +575,14 @@ QString ConnectionLoader::zcashParamsDir() {
bool ConnectionLoader::verifyParams() {
QDir paramsDir(zcashParamsDir());
qDebug() << "Verifying param files exist";
if (!QFile(paramsDir.filePath("sapling-output.params")).exists()) return false;
if (!QFile(paramsDir.filePath("sapling-spend.params")).exists()) return false;
//TODO: sprout probably not needed
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;
qDebug() << "All param files found!";
return true;
}

2
src/connection.h

@ -64,7 +64,7 @@ private:
void doRPCSetConnection(Connection* conn);
QProcess* ezcashd = nullptr;
std::shared_ptr<QProcess> ezcashd;
QDialog* d;
Ui_ConnectionDialog* connD;

16
src/mainwindow.cpp

@ -601,16 +601,14 @@ void MainWindow::addressBook() {
void MainWindow::donate() {
// Set up a donation to me :)
removeExtraAddresses();
ui->Address1->setText(Settings::getDonationAddr(
Settings::getInstance()->isSaplingAddress(ui->inputsCombo->currentText())));
ui->Address1->setText(Settings::getDonationAddr(true));
ui->Address1->setCursorPosition(0);
ui->Amount1->setText("0.01");
ui->MemoTxt1->setText(tr("Thanks for supporting SilentDragon!"));
ui->Amount1->setText("0.00");
ui->MemoTxt1->setText(tr("Some feedback about SilentDragon or Hush..."));
ui->statusBar->showMessage(tr("Donate 0.01 ") % Settings::getTokenName() % tr(" to support SilentDragon"));
ui->statusBar->showMessage(tr("Send Duke some private and shielded feedback about ") % Settings::getTokenName() % tr(" or SilentDragon"));
// And switch to the send tab.
ui->tabWidget->setCurrentIndex(1);
@ -855,7 +853,7 @@ void MainWindow::importPrivKey() {
pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(false);
pui.helpLbl->setText(QString() %
tr("Please paste your private keys here, one per line") % ".\n" %
tr("The keys will be imported into your connected komodod node"));
tr("The keys will be imported into your connected Hush node"));
if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) {
auto rawkeys = pui.privKeyTxt->toPlainText().trimmed().split("\n");
@ -876,7 +874,7 @@ void MainWindow::importPrivKey() {
// Show the dialog that keys will be imported.
QMessageBox::information(this,
"Imported", tr("The keys were imported. It may take several minutes to rescan the blockchain. Until then, functionality may be limited"),
"Imported", tr("The keys were imported! It may take several minutes to rescan the blockchain. Until then, functionality may be limited"),
QMessageBox::Ok);
}
}
@ -967,7 +965,7 @@ void MainWindow::exportKeys(QString addr) {
// Wire up save button
QObject::connect(pui.buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=] () {
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
allKeys ? "zcash-all-privatekeys.txt" : "zcash-privatekey.txt");
allKeys ? "hush-all-privatekeys.txt" : "hush-privatekey.txt");
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("Unable to open file"), file.errorString());

2
src/mainwindow.ui

@ -1213,7 +1213,7 @@
</action>
<action name="actionDonate">
<property name="text">
<string>&amp;Donate</string>
<string>&amp;Send Duke Feedback</string>
</property>
</action>
<action name="actionCheck_for_Updates">

6
src/rpc.cpp

@ -73,7 +73,7 @@ RPC::~RPC() {
delete conn;
}
void RPC::setEZcashd(QProcess* p) {
void RPC::setEZcashd(std::shared_ptr<QProcess> p) {
ezcashd = p;
if (ezcashd && ui->tabWidget->widget(4) == nullptr) {
@ -1127,6 +1127,7 @@ void RPC::shutdownZcashd() {
conn->shutdown();
QDialog d(main);
d.setWindowFlags(d.windowFlags() & ~(Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint));
Ui_ConnectionDialog connD;
connD.setupUi(&d);
connD.topIcon->setBasePixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256));
@ -1142,7 +1143,8 @@ void RPC::shutdownZcashd() {
waitCount++;
if ((ezcashd->atEnd() && ezcashd->processId() == 0) ||
waitCount > 30 ||
ezcashd->state() == QProcess::NotRunning ||
waitCount > 30 ||
conn->config->zcashDaemon) { // If zcashd is daemon, then we don't have to do anything else
qDebug() << "Ended";
waiter.stop();

6
src/rpc.h

@ -38,8 +38,8 @@ public:
~RPC();
void setConnection(Connection* c);
void setEZcashd(QProcess* p);
const QProcess* getEZcashD() { return ezcashd; }
void setEZcashd(std::shared_ptr<QProcess> p);
const QProcess* getEZcashD() { return ezcashd.get(); }
void refresh(bool force = false);
@ -109,7 +109,7 @@ private:
void getTAddresses (const std::function<void(json)>& cb);
Connection* conn = nullptr;
QProcess* ezcashd = nullptr;
std::shared_ptr<QProcess> ezcashd = nullptr;
QList<UnspentOutput>* utxos = nullptr;
QMap<QString, double>* allBalances = nullptr;

14
src/settings.cpp

@ -199,16 +199,10 @@ QString Settings::getTokenName() {
}
QString Settings::getDonationAddr(bool sapling) {
if (Settings::getInstance()->isTestnet())
if (sapling)
return "ztestsapling1wn6889vznyu42wzmkakl2effhllhpe4azhu696edg2x6me4kfsnmqwpglaxzs7tmqsq7kudemp5";
else
return "ztn6fYKBii4Fp4vbGhkPgrtLU4XjXp4ZBMZgShtopmDGbn1L2JLTYbBp2b7SSkNr9F3rQeNZ9idmoR7s4JCVUZ7iiM5byhF";
else
if (sapling)
return "zs1knmre6w5dyy2mjdxw2g8v93adr3fh9jtwqx76863557sjunlqq563cftxaz05saskyyn72xm2hv";
else
return "zcEgrceTwvoiFdEvPWcsJHAMrpLsprMF6aRJiQa3fan5ZphyXLPuHghnEPrEPRoEVzUy65GnMVyCTRdkT6BYBepnXh6NBYs";
if (Settings::getInstance()->isTestnet()) {
return "ztestsaplingXXX";
}
return "zs1aq4xnrkjlnxx0zesqye7jz3dfrf3rjh7q5z6u8l6mwyqqaam3gx3j2fkqakp33v93yavq46j83q";
}
bool Settings::addToZcashConf(QString confLocation, QString line) {

Loading…
Cancel
Save