From 4eea97a04e6828ad808b194a6367bb402ab80e3e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 9 Sep 2020 16:21:58 -0400 Subject: [PATCH] WIP to fix crazy bugs --- src/connection.cpp | 63 +++++++++++----------- src/connection.h | 23 +++++--- src/mainwindow.cpp | 10 +++- src/rpc.cpp | 132 +++++++++++++++++++++++++-------------------- src/rpc.h | 10 ++-- 5 files changed, 138 insertions(+), 100 deletions(-) diff --git a/src/connection.cpp b/src/connection.cpp index 8989107..5bdcd39 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -1,5 +1,5 @@ // Copyright 2019-2020 The Hush developers -// GPLv3 +// Released under the GPLv3 #include "connection.h" #include "mainwindow.h" #include "settings.h" @@ -44,12 +44,14 @@ ConnectionLoader::~ConnectionLoader() { } void ConnectionLoader::loadConnection() { + qDebug() << __func__; QTimer::singleShot(1, [=]() { this->doAutoConnect(); }); if (!Settings::getInstance()->isHeadless()) d->exec(); } void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) { + qDebug() << __func__; // Priority 1: Ensure all params are present. if (!verifyParams()) { downloadParams([=]() { this->doAutoConnect(); }); @@ -63,7 +65,7 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) { if (config.get() != nullptr) { auto connection = makeConnection(config); - refreshZcashdState(connection, [=] () { + refreshHushdState(connection, [=] () { // Refused connection. So try and start embedded zcashd if (Settings::getInstance()->useEmbedded()) { if (tryEzcashdStart) { @@ -84,11 +86,11 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) { // 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 hushd!"); - QTimer::singleShot(2000, [=]() { doAutoConnect(/* don't attempt to start ezcashd */ false); }); + QTimer::singleShot(2000, [=]() { doAutoConnect(/* don't attempt to start ehushd */ false); }); } } } else { - // We tried to start ezcashd previously, and it didn't work. So, show the error. + // We tried to start ehushd previously, and it didn't work. So, show the error. main->logger->write("Couldn't start embedded hushd for unknown reason"); QString explanation; if (config->zcashDaemon) { @@ -100,7 +102,7 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) { explanation = QString() % QObject::tr("Couldn't start the embedded hushd.\n\n" "Please try restarting.\n\nIf you previously started hushd with custom arguments, you might need to reset HUSH3.conf.\n\n" "If all else fails, please run hushd manually.") % - (ezcashd ? QObject::tr("The process returned") + ":\n\n" % ezcashd->errorString() : QString("")); + (ehushd ? QObject::tr("The process returned") + ":\n\n" % ehushd->errorString() : QString("")); } this->showError(explanation); @@ -116,6 +118,7 @@ void ConnectionLoader::doAutoConnect(bool tryEzcashdStart) { } else { if (Settings::getInstance()->useEmbedded()) { // HUSH3.conf was not found, so create one + qDebug() << "Creating HUSH3.conf"; createZcashConf(); } else { // Fall back to manual connect @@ -217,6 +220,9 @@ void ConnectionLoader::createZcashConf() { // Consolidation is now defaulted to ON for new wallets out << "consolidation=1\n"; + // Deletetx has some perfomance issues for large wallets, still in testing + //out << "deletetx=1\n"; + if (!datadir.isEmpty()) { out << "datadir=" % datadir % "\n"; } @@ -225,6 +231,7 @@ void ConnectionLoader::createZcashConf() { } file.close(); + qDebug() << "HUSH3.conf finished being written to disk"; // Now that HUSH3.conf exists, try to autoconnect again this->doAutoConnect(); @@ -232,14 +239,14 @@ void ConnectionLoader::createZcashConf() { void ConnectionLoader::downloadParams(std::function cb) { - main->logger->write("Adding params to download queue"); + main->logger->write("Adding params to download queue, wtfbbqlol?"); // Add all the files to the download queue downloadQueue = new QQueue(); client = new QNetworkAccessManager(main); //Currently we fallback to this in rare edgecases, it's not normally executed - downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-output.params")); - downloadQueue->enqueue(QUrl("https://z.cash/downloads/sapling-spend.params")); + downloadQueue->enqueue(QUrl("https://github.com/MyHush/hush3/raw/master/sapling-output.params")); + downloadQueue->enqueue(QUrl("https://github.com/MyHush/hush3/raw/master/sapling-spend.params")); doNextDownload(cb); } @@ -343,8 +350,8 @@ bool ConnectionLoader::startEmbeddedZcashd() { // Static because it needs to survive even after this method returns. static QString processStdErrOutput; - if (ezcashd != nullptr) { - if (ezcashd->state() == QProcess::NotRunning) { + if (ehushd != nullptr) { + if (ehushd->state() == QProcess::NotRunning) { if (!processStdErrOutput.isEmpty()) { QMessageBox::critical(main, QObject::tr("hushd error"), "hushd said: " + processStdErrOutput, QMessageBox::Ok); @@ -372,23 +379,23 @@ bool ConnectionLoader::startEmbeddedZcashd() { main->logger->write("Found hushd at " + hushdProgram); } - ezcashd = std::shared_ptr(new QProcess(main)); - QObject::connect(ezcashd.get(), &QProcess::started, [=] () { + ehushd = std::shared_ptr(new QProcess(main)); + QObject::connect(ehushd.get(), &QProcess::started, [=] () { qDebug() << "Embedded hushd started via " << hushdProgram; }); - QObject::connect(ezcashd.get(), QOverload::of(&QProcess::finished), + QObject::connect(ehushd.get(), QOverload::of(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus) { qDebug() << "hushd finished with code " << exitCode << "," << exitStatus; }); - QObject::connect(ezcashd.get(), &QProcess::errorOccurred, [&] (QProcess::ProcessError error) { + QObject::connect(ehushd.get(), &QProcess::errorOccurred, [&] (QProcess::ProcessError error) { qDebug() << "Couldn't start hushd at " << hushdProgram << ":" << error; }); - std::weak_ptr weak_obj(ezcashd); + std::weak_ptr weak_obj(ehushd); auto ptr_main(main); - QObject::connect(ezcashd.get(), &QProcess::readyReadStandardError, [weak_obj, ptr_main]() { + QObject::connect(ehushd.get(), &QProcess::readyReadStandardError, [weak_obj, ptr_main]() { auto output = weak_obj.lock()->readAllStandardError(); ptr_main->logger->write("hushd stderr:" + output); processStdErrOutput.append(output); @@ -402,18 +409,18 @@ bool ConnectionLoader::startEmbeddedZcashd() { #ifdef Q_OS_LINUX qDebug() << "Starting on Linux: " + hushdProgram + " " + params; - ezcashd->start(hushdProgram, arguments); + ehushd->start(hushdProgram, arguments); #elif defined(Q_OS_DARWIN) qDebug() << "Starting on Darwin: " + hushdProgram + " " + params; - ezcashd->start(hushdProgram, arguments); + ehushd->start(hushdProgram, arguments); #elif defined(Q_OS_WIN64) qDebug() << "Starting on Win64: " + hushdProgram + " " + params; - ezcashd->setWorkingDirectory(appPath.absolutePath()); - ezcashd->start(hushdProgram, arguments); + ehushd->setWorkingDirectory(appPath.absolutePath()); + ehushd->start(hushdProgram, arguments); #else qDebug() << "Starting on Unknown OS(!): " + hushdProgram + " " + params; - ezcashd->setWorkingDirectory(appPath.absolutePath()); - ezcashd->start(hushdProgram, arguments); + ehushd->setWorkingDirectory(appPath.absolutePath()); + ehushd->start(hushdProgram, arguments); #endif // Q_OS_LINUX main->logger->write("Started via " + hushdProgram + " " + params); @@ -436,7 +443,7 @@ void ConnectionLoader::doManualConnect() { } auto connection = makeConnection(config); - refreshZcashdState(connection, [=] () { + refreshHushdState(connection, [=] () { QString explanation = QString() % QObject::tr("Could not connect to hushd configured in settings.\n\n" "Please set the host/port and user/password in the Edit->Settings menu."); @@ -475,14 +482,10 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr c return new Connection(main, client, request, config); } -void ConnectionLoader::refreshZcashdState(Connection* connection, std::function refused) { +void ConnectionLoader::refreshHushdState(Connection* connection, std::function refused) { main->logger->write("refreshing state"); - QJsonObject payload = { - {"jsonrpc", "1.0"}, - {"id", "someid"}, - {"method", "getinfo"} - }; + auto payload = rpc->makePayload("getinfo"); connection->doRPC(payload, [=] (auto) { // Success @@ -518,7 +521,7 @@ void ConnectionLoader::refreshZcashdState(Connection* connection, std::function< this->showInformation(QObject::tr("Your hushd is starting up. Please wait."), status); main->logger->write("Waiting for hushd to come online."); // Refresh after one second - QTimer::singleShot(1000, [=]() { this->refreshZcashdState(connection, refused); }); + QTimer::singleShot(1000, [=]() { this->refreshHushdState(connection, refused); }); } } ); diff --git a/src/connection.h b/src/connection.h index 5f5cd32..9830ad9 100644 --- a/src/connection.h +++ b/src/connection.h @@ -45,7 +45,7 @@ private: Connection* makeConnection(std::shared_ptr config); - void doAutoConnect(bool tryEzcashdStart = true); + void doAutoConnect(bool tryEhushdStart = true); void doManualConnect(); void createZcashConf(); @@ -58,14 +58,14 @@ private: void doNextDownload(std::function cb); bool startEmbeddedZcashd(); - void refreshZcashdState(Connection* connection, std::function refused); + void refreshHushdState(Connection* connection, std::function refused); void showError(QString explanation); void showInformation(QString info, QString detail = ""); void doRPCSetConnection(Connection* conn); - std::shared_ptr ezcashd; + std::shared_ptr ehushd; QDialog* d; Ui_ConnectionDialog* connD; @@ -82,7 +82,7 @@ private: }; /** - * Represents a connection to a zcashd. It may even start a new zcashd if needed. + * Represents a connection to a hushd. It may even start a new hushd if needed. * This is also a UI class, so it may show a dialog waiting for the connection. */ class Connection { @@ -119,6 +119,7 @@ public: static QMap inProgress; QString method = payloadGenerator(payloads[0])["method"].toString(); + qDebug() << __func__ << "(" << method << ") totalSize=" << totalSize << " at " << QDateTime::currentSecsSinceEpoch(); //if (inProgress.value(method, false)) { // qDebug() << "In progress batch, skipping"; @@ -126,6 +127,7 @@ public: //} for (auto item: payloads) { + qDebug() << __func__ << ": payload " << item; QJsonValue payload = payloadGenerator(item); inProgress[method] = true; @@ -137,22 +139,25 @@ public: QObject::connect(reply, &QNetworkReply::finished, [=] { reply->deleteLater(); if (shutdownInProgress) { - // Ignoring callback because shutdown in progress + qDebug() << __func__ << ": Ignoring callback because shutdown in progress"; return; } auto all = reply->readAll(); auto parsed = QJsonDocument::fromJson(all); + if (reply->error() != QNetworkReply::NoError) { - qDebug() << parsed.toJson(); + qDebug() << "Error JSON response: " << parsed.toJson(); qDebug() << reply->errorString(); (*responses)[item] = {}; // Empty object } else { if (parsed.isEmpty()) { + qDebug() << __func__ << ": got empty response"; (*responses)[item] = {}; // Empty object } else { + qDebug() << "Got network reply from RPC " << method << "(" << payload << ")" << " of " << parsed["result"].toString().size() << " bytes"; (*responses)[item] = parsed["result"]; } } @@ -162,14 +167,18 @@ public: auto waitTimer = new QTimer(main); QObject::connect(waitTimer, &QTimer::timeout, [=]() { if (shutdownInProgress) { + qDebug() << "Shutdown in progress, aborting"; waitTimer->stop(); waitTimer->deleteLater(); return; } + //qDebug() << "."; + // If all responses have arrived, return if (responses->size() == totalSize) { + qDebug() << __func__ << ": stopping timer"; waitTimer->stop(); cb(responses); @@ -178,7 +187,9 @@ public: waitTimer->deleteLater(); } }); + qDebug() << __func__ << ": starting timer"<< QDateTime::currentSecsSinceEpoch(); waitTimer->start(100); + qDebug() << __func__ << ": finished at " << QDateTime::currentSecsSinceEpoch(); } private: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8a7d3bc..036b66e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -118,9 +118,10 @@ MainWindow::MainWindow(QWidget *parent) : // Initialize to the balances tab ui->tabWidget->setCurrentIndex(0); - setupSendTab(); - setupTransactionsTab(); setupReceiveTab(); + + setupTransactionsTab(); + setupSendTab(); setupBalancesTab(); setupMarketTab(); //setupChatTab(); @@ -253,6 +254,7 @@ void MainWindow::setupStatusBar() { } menu.addAction("Refresh", [=]() { + qDebug() << "Manual refresh"; rpc->refresh(true); }); QPoint gpos(mapToGlobal(pos).x(), mapToGlobal(pos).y() + this->height() - ui->statusBar->height()); @@ -1180,8 +1182,10 @@ void MainWindow::setupMarketTab() { } void MainWindow::setupTransactionsTab() { + qDebug() << __func__; // Double click opens up memo if one exists QObject::connect(ui->transactionsTable, &QTableView::doubleClicked, [=] (auto index) { + qDebug() << "Tx double clicked, showing memo"; auto txModel = dynamic_cast(ui->transactionsTable->model()); QString memo = txModel->getMemo(index.row()); @@ -1294,6 +1298,7 @@ void MainWindow::setupTransactionsTab() { void MainWindow::addNewZaddr() { rpc->newZaddr( [=] (QJsonValue reply) { QString addr = reply.toString(); + qDebug() << __func__ << ": created new zaddr " << addr; // Make sure the RPC class reloads the z-addrs for future use rpc->refreshAddresses(); @@ -1335,6 +1340,7 @@ std::function MainWindow::addZAddrsToComboList(bool sapling) { } void MainWindow::setupReceiveTab() { + qDebug() << __func__; auto addNewTAddr = [=] () { rpc->newTaddr([=] (QJsonValue reply) { qDebug() << "New addr button clicked"; diff --git a/src/rpc.cpp b/src/rpc.cpp index 4ba7af9..b6fca5e 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -11,6 +11,7 @@ RPC::RPC(MainWindow* main) { auto cl = new ConnectionLoader(main, this); + qDebug() << "ConnectionLoader created"; // Execute the load connection async, so we can set up the rest of RPC properly. QTimer::singleShot(1, [=]() { cl->loadConnection(); }); @@ -26,26 +27,30 @@ RPC::RPC(MainWindow* main) { transactionsTableModel = new TxTableModel(ui->transactionsTable); main->ui->transactionsTable->setModel(transactionsTableModel); main->ui->transactionsTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch); + qDebug() << "Created transationsTableModel"; // Set up timer to refresh Price priceTimer = new QTimer(main); QObject::connect(priceTimer, &QTimer::timeout, [=]() { + qDebug() << "Refreshing price at " << QDateTime::currentSecsSinceEpoch(); refreshPrice(); }); - priceTimer->start(Settings::priceRefreshSpeed); // Every hour + qDebug() << "Starting price timer with speed=" << Settings::priceRefreshSpeed; + priceTimer->start(Settings::priceRefreshSpeed); // Set up a timer to refresh the UI every few seconds timer = new QTimer(main); QObject::connect(timer, &QTimer::timeout, [=]() { - qDebug() << "Refreshing main UI"; + qDebug() << "Refreshing main UI with timer at " << QDateTime::currentSecsSinceEpoch(); refresh(); }); + qDebug() << "Starting main UI timer with speed=" << Settings::updateSpeed; timer->start(Settings::updateSpeed); // Set up the timer to watch for tx status txTimer = new QTimer(main); QObject::connect(txTimer, &QTimer::timeout, [=]() { - qDebug() << "Watching tx status"; + qDebug() << "Watching tx status at " << QDateTime::currentSecsSinceEpoch(); watchTxStatus(); }); // Start at normal updateSpeed. When an operation is pending, this will change to quickUpdateSpeed @@ -237,6 +242,7 @@ void RPC::getTransactions(const std::function& cb) { void RPC::sendZTransaction(QJsonValue params, const std::function& cb, const std::function& err) { + qDebug() << __func__ << " at " << QDateTime::currentSecsSinceEpoch(); QJsonObject payload = { {"jsonrpc", "1.0"}, {"id", "someid"}, @@ -343,6 +349,7 @@ void RPC::getAllPrivKeys(const std::function> // Build the RPC JSON Parameters for this tx void RPC::fillTxJsonParams(QJsonArray& params, Tx tx) { + qDebug() << __func__; Q_ASSERT(QJsonValue(params).isArray()); @@ -379,6 +386,7 @@ void RPC::fillTxJsonParams(QJsonArray& params, Tx tx) { void RPC::noConnection() { + qDebug() << "No connection!!!"; QIcon i = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); main->statusIcon->setPixmap(i.pixmap(16, 16)); main->statusIcon->setToolTip(""); @@ -411,24 +419,36 @@ void RPC::noConnection() { ui->inputsCombo->clear(); } -// Refresh received z txs by calling z_listreceivedbyaddress/gettransaction +// Refresh received z txs by calling z_listreceivedbyaddress void RPC::refreshReceivedZTrans(QList zaddrs) { + qDebug() << __func__ << " at " << QDateTime::currentSecsSinceEpoch(); if (conn == nullptr) return noConnection(); // We'll only refresh the received Z txs if settings allows us. if (!Settings::getInstance()->getSaveZtxs()) { + qDebug() << "Not saving sent ztx's as per settings"; QList emptylist; transactionsTableModel->addZRecvData(emptylist); return; } - // This method is complicated because z_listreceivedbyaddress only returns the txid, and - // we have to make a follow up call to gettransaction to get details of that transaction. - // Additionally, it has to be done in batches, because there are multiple z-Addresses, + // It has to be done in batches, because there are multiple z-Addresses, // and each z-Addr can have multiple received txs. // 1. For each z-Addr, get list of received txs + /* + { + "txid": "deadbeef", + "amount": 420.69000000, + "memo": "...", + "memoStr": "", + "outindex": 0, + "rawconfirmations": 27793, + "confirmations": 27793, + "change": false + } +*/ conn->doBatchRPC(zaddrs, [=] (QString zaddr) { QJsonObject payload = { @@ -441,12 +461,15 @@ void RPC::refreshReceivedZTrans(QList zaddrs) { return payload; }, [=] (QMap* zaddrTxids) { + qDebug() << __func__ << ": processing z_listreceivedbyaddress JSON at " << QDateTime::currentSecsSinceEpoch(); // Process all txids, removing duplicates. This can happen if the same address // appears multiple times in a single tx's outputs. QSet txids; QMap memos; for (auto it = zaddrTxids->constBegin(); it != zaddrTxids->constEnd(); it++) { - auto zaddr = it.key(); + auto zaddr = it.key(); + qint64 numTx = 0; + qDebug() << __func__ << ": processing tx's of " << zaddr << " at " << QDateTime::currentSecsSinceEpoch(); for (const auto& i : it.value().toArray()) { // Mark the address as used usedAddresses->insert(zaddr, true); @@ -464,63 +487,48 @@ void RPC::refreshReceivedZTrans(QList zaddrs) { if (!memo.trimmed().isEmpty()) memos[zaddr + txid] = memo; } - } - } - } - - // 2. For all txids, go and get the details of that txid. - conn->doBatchRPC(txids.toList(), - [=] (QString txid) { - QJsonObject payload = { - {"jsonrpc", "1.0"}, - {"id", "gettx"}, - {"method", "gettransaction"}, - {"params", QJsonArray {txid}} - }; - - return payload; - }, - [=] (QMap* txidDetails) { - QList txdata; + // Fill in other data + QList txdata; - // Combine them both together. For every zAddr's txid, get the amount, fee, confirmations and time - for (auto it = zaddrTxids->constBegin(); it != zaddrTxids->constEnd(); it++) { - for (const auto& i : it.value().toArray()) { + for (const auto& j : it.value().toArray()) { + numTx++; // Filter out change txs - if (i.toObject()["change"].toBool()) + if (j.toObject()["change"].toBool()) { + //qDebug() << __func__ << ": filtered change"; continue; - + } auto zaddr = it.key(); - auto txid = i.toObject()["txid"].toString(); - + auto txid = j.toObject()["txid"].toString(); // Lookup txid in the map - auto txidInfo = txidDetails->value(txid); - + auto txidInfo = zaddrTxids->find(txid); qint64 timestamp; - if (!txidInfo.toObject()["time"].isUndefined()) { - timestamp = txidInfo.toObject()["time"].toInt(); + if (!txidInfo->toObject()["time"].isUndefined()) { + timestamp = txidInfo->toObject()["time"].toInt(); } else { - timestamp = txidInfo.toObject()["blocktime"].toInt(); + timestamp = txidInfo->toObject()["blocktime"].toInt(); } - - auto amount = i.toObject()["amount"].toDouble(); - auto confirmations = (unsigned long)txidInfo["confirmations"].toInt(); + auto amount = j.toObject()["amount"].toDouble(); + //auto confirmations = (unsigned long)txidInfo["confirmations"].toInt(); + auto confirmations = (unsigned long)txidInfo->toObject()["confirmations"].toInt(); - TransactionItem tx{ QString("receive"), timestamp, zaddr, txid, amount, - confirmations, "", memos.value(zaddr + txid, "") }; + //qDebug() << __func__ << ": Adding " << txid << " at time=" << timestamp << " with " << confirmations << " confs"; + TransactionItem tx{ QString("receive"), timestamp, zaddr, txid, amount, confirmations, "", memos.value(zaddr + txid, "") }; txdata.push_front(tx); + if(numTx % 1000 == 0) { + qDebug() << "z_listreceivedbyaddress: Processed " << numTx << " transactions for " << zaddr; + } } - } - transactionsTableModel->addZRecvData(txdata); - - // Cleanup both responses; - delete zaddrTxids; - delete txidDetails; - } - ); + qDebug() << __func__ << ": Updating transactionsTableModel with numTx=" << numTx; + transactionsTableModel->addZRecvData(txdata); + } + } + } } ); + delete zaddrTxids; + delete txidDetails; + } /// This will refresh all the balance data from hushd @@ -583,6 +591,7 @@ void RPC::getInfoThenRefresh(bool force) { if ( force || (curBlock != lastBlock) ) { // Something changed, so refresh everything. + qDebug() << "Something changed, time to refresh"; lastBlock = curBlock; refreshBalances(); @@ -731,6 +740,7 @@ void RPC::getInfoThenRefresh(bool force) { } void RPC::refreshAddresses() { + qDebug() << __func__; if (conn == nullptr) return noConnection(); @@ -777,6 +787,7 @@ void RPC::updateUI(bool anyUnconfirmed) { // Function to process reply of the listunspent and z_listunspent API calls, used below. bool RPC::processUnspent(const QJsonValue& reply, QMap* balancesMap, QList* newUtxos) { + qDebug() << __func__; bool anyUnconfirmed = false; for (const auto& it : reply.toArray()) { QString qsAddr = it.toObject()["address"].toString(); @@ -796,6 +807,7 @@ bool RPC::processUnspent(const QJsonValue& reply, QMap* balance }; void RPC::refreshBalances() { + qDebug() << __func__; if (conn == nullptr) return noConnection(); @@ -844,9 +856,11 @@ void RPC::refreshBalances() { main->balancesReady(); }); }); + qDebug() << __func__ << ": finished"; } void RPC::refreshTransactions() { + qDebug() << __func__; if (conn == nullptr) return noConnection(); @@ -876,6 +890,7 @@ void RPC::refreshTransactions() { } // Update model data, which updates the table view + qDebug() << __func__ << ": updating transactionTableModel tdata"; transactionsTableModel->addTData(txdata); }); } @@ -974,7 +989,7 @@ void RPC::watchTxStatus() { // Make an RPC to load pending operation statues conn->doRPCIgnoreError(makePayload("z_getoperationstatus"), [=] (const QJsonValue& reply) { - qDebug() << "Got reply from z_getoperationstatus with " << reply.toArray().size() << " items"; + qDebug() << "Got reply from z_getoperationstatus with " << reply.toArray().size() << " items:" << reply.toString(); // conn->doRPCIgnoreError(payload, [=] (const json& reply) { // There's an array for each item in the status for (const auto& it : reply.toArray()) { @@ -990,10 +1005,12 @@ void RPC::watchTxStatus() { if (status == "success") { auto txid = it.toObject()["result"].toObject()["txid"].toString(); + qDebug() << "Found opid " << id << " with status=success and txid=" << txid; SentTxStore::addToSentTx(watchingOps[id].tx, txid); auto wtx = watchingOps[id]; watchingOps.remove(id); + qDebug() << "Removed opid " << id; wtx.completed(id, txid); qDebug() << "opid "<< id << " for " << txid << " started at "<processId() == 0 || conn == nullptr) { + if (ehushd == nullptr || ehushd->processId() == 0 || conn == nullptr) { // No hushd running internally, just return return; } @@ -1254,8 +1272,8 @@ void RPC::shutdownHushd() { QObject::connect(&waiter, &QTimer::timeout, [&] () { waitCount++; - if ((ezcashd->atEnd() && ezcashd->processId() == 0) || - ezcashd->state() == QProcess::NotRunning || + if ((ehushd->atEnd() && ehushd->processId() == 0) || + ehushd->state() == QProcess::NotRunning || waitCount > 30 || conn->config->zcashDaemon) { // If hushd is daemon, then we don't have to do anything else qDebug() << "Ended"; diff --git a/src/rpc.h b/src/rpc.h index 91b85a3..204e29f 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -38,7 +38,7 @@ public: ~RPC(); void setConnection(Connection* c); - const QProcess* getEZcashD() { return ezcashd.get(); } + const QProcess* getEZcashD() { return ehushd.get(); } void refresh(bool force = false); @@ -79,7 +79,9 @@ public: void shutdownHushd(); void noConnection(); - bool isEmbedded() { return ezcashd != nullptr; } + bool isEmbedded() { return ehushd != nullptr; } + QJsonValue makePayload(QString method, QString params); + QJsonValue makePayload(QString method); QString getDefaultSaplingAddress(); QString getDefaultTAddress(); @@ -102,8 +104,6 @@ private: void getInfoThenRefresh(bool force); void getBalance(const std::function& cb); - QJsonValue makePayload(QString method, QString params); - QJsonValue makePayload(QString method); void getTransparentUnspent (const std::function& cb); void getZUnspent (const std::function& cb); @@ -112,7 +112,7 @@ private: void getTAddresses (const std::function& cb); Connection* conn = nullptr; - std::shared_ptr ezcashd = nullptr; + std::shared_ptr ehushd = nullptr; QList* utxos = nullptr; QMap* allBalances = nullptr;