From 663960af2f73aa4a87c8d7e6f40ac7ae19801817 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Wed, 5 May 2021 01:09:19 +0200 Subject: [PATCH] Beta-6 fixes --- CMakeLists.txt | 2 +- Dockerfile | 14 +++--- monero | 2 +- src/api/LocalMoneroApi.cpp | 2 +- src/appcontext.cpp | 15 ++++--- src/appcontext.h | 3 +- src/dialog/UpdateDialog.cpp | 11 +++-- src/dialog/debuginfodialog.ui | 5 ++- src/dialog/splashdialog.cpp | 9 +++- src/dialog/splashdialog.h | 3 ++ src/dialog/torinfodialog.cpp | 21 +++++---- src/libwalletqt/Wallet.cpp | 22 ++++----- src/mainwindow.cpp | 74 ++++++++++++++++++++++--------- src/mainwindow.ui | 8 ++-- src/utils/TorManager.cpp | 6 ++- src/utils/config.cpp | 2 +- src/utils/daemonrpc.cpp | 5 ++- src/utils/nodes.cpp | 9 +++- src/utils/tails.cpp | 9 ++++ src/utils/tails.h | 3 ++ src/utils/utils.cpp | 10 ----- src/widgets/LocalMoneroWidget.cpp | 2 +- src/widgets/LocalMoneroWidget.ui | 2 +- src/wizard/PageHardwareDevice.ui | 5 --- src/wizard/PageNetworkTor.cpp | 19 ++++++-- src/wizard/PageNetworkTor.h | 1 + src/wizard/PageNetworkTor.ui | 26 ++++++++++- src/wizard/PageWalletFile.cpp | 6 ++- 28 files changed, 201 insertions(+), 95 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b58da067..2a77d0d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ if(DEBUG) set(CMAKE_VERBOSE_MAKEFILE ON) endif() -set(MONERO_HEAD "626f1b4ba1c1a490ca97fe265230aea84eac0ed2") +set(MONERO_HEAD "36fb05da3394505f8033ceb8806b28909617696f") set(BUILD_GUI_DEPS ON) set(ARCH "x86-64") set(BUILD_64 ON) diff --git a/Dockerfile b/Dockerfile index 36cc376b..9ad20909 100644 --- a/Dockerfile +++ b/Dockerfile @@ -323,17 +323,17 @@ RUN rm /usr/lib/x86_64-linux-gnu/libX11.a && \ cd ../../../.. && \ rm -rf $(pwd) -RUN git clone -b v1.0.23 --depth 1 https://github.com/libusb/libusb && \ +RUN git clone -b v1.0.24 --depth 1 https://github.com/libusb/libusb && \ cd libusb && \ - git reset --hard e782eeb2514266f6738e242cdcb18e3ae1ed06fa && \ + git reset --hard c6a35c56016ea2ab2f19115d2ea1e85e0edae155 && \ ./autogen.sh --disable-shared --enable-static && \ make -j$THREADS && \ make -j$THREADS install && \ rm -rf $(pwd) -RUN git clone -b hidapi-0.9.0 --depth 1 https://github.com/libusb/hidapi && \ +RUN git clone -b hidapi-0.10.1 --depth 1 https://github.com/libusb/hidapi && \ cd hidapi && \ - git reset --hard 7da5cc91fc0d2dbe4df4f08cd31f6ca1a262418f && \ + git reset --hard f6d0073fcddbdda24549199445e844971d3c9cef && \ ./bootstrap && \ ./configure --disable-shared --enable-static && \ make -j$THREADS && \ @@ -384,9 +384,9 @@ RUN git clone -b v3.18.4 --depth 1 https://github.com/Kitware/CMake && \ make -j$THREADS install && \ rm -rf $(pwd) -RUN git clone -b v4.0.2 --depth 1 https://github.com/fukuchi/libqrencode.git && \ +RUN git clone -b v4.1.1 --depth 1 https://github.com/fukuchi/libqrencode.git && \ cd libqrencode && \ - git reset --hard 59ee597f913fcfda7a010a6e106fbee2595f68e4 && \ + git reset --hard 715e29fd4cd71b6e452ae0f4e36d917b43122ce8 && \ cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=/usr . && \ make -j$THREADS && \ make -j$THREADS install && \ @@ -415,7 +415,7 @@ RUN mkdir linuxdeployqt && \ ./linuxdeployqt-7-x86_64.AppImage --appimage-extract && \ rm linuxdeployqt-7-x86_64.AppImage -RUN git clone https://github.com/nih-at/libzip.git && \ +RUN git clone -b v1.7.3 --depth 1 https://github.com/nih-at/libzip.git && \ cd libzip && \ git reset --hard 66e496489bdae81bfda8b0088172871d8fda0032 && \ cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=/usr . && \ diff --git a/monero b/monero index 626f1b4b..36fb05da 160000 --- a/monero +++ b/monero @@ -1 +1 @@ -Subproject commit 626f1b4ba1c1a490ca97fe265230aea84eac0ed2 +Subproject commit 36fb05da3394505f8033ceb8806b28909617696f diff --git a/src/api/LocalMoneroApi.cpp b/src/api/LocalMoneroApi.cpp index 9e332b78..a047a87f 100644 --- a/src/api/LocalMoneroApi.cpp +++ b/src/api/LocalMoneroApi.cpp @@ -112,7 +112,7 @@ QString LocalMoneroApi::getBuySellUrl(bool buy, const QString ¤cyCode, con url += QString("/%1/%2").arg(countryCode, paymentMethod); QUrlQuery query; - if (!amount.isEmpty()) + if (!amount.isEmpty() && amount != "0") query.addQueryItem("amount", amount); if (page > 0) query.addQueryItem("page", QString::number(page)); diff --git a/src/appcontext.cpp b/src/appcontext.cpp index c0eefdb3..de5c2e16 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -84,6 +84,8 @@ AppContext::AppContext(QCommandLineParser *cmdargs) { // TODO: move me connect(websocketNotifier(), &WebsocketNotifier::NodesReceived, this->nodes, &Nodes::onWSNodesReceived); + + m_rpc = new DaemonRpc{this, getNetworkTor(), ""}; } void AppContext::initTor() { @@ -113,7 +115,7 @@ void AppContext::onCancelTransaction(PendingTransaction *tx, const QVectorcurrentWallet->disposeTransaction(tx); } -void AppContext::onSweepOutput(const QString &keyImage, QString address, bool churn, int outputs) const { +void AppContext::onSweepOutput(const QString &keyImage, QString address, bool churn, int outputs) { if(this->currentWallet == nullptr){ qCritical() << "Cannot create transaction; no wallet loaded"; return; @@ -125,6 +127,8 @@ void AppContext::onSweepOutput(const QString &keyImage, QString address, bool ch qCritical() << "Creating transaction"; this->currentWallet->createTransactionSingleAsync(keyImage, address, outputs, this->tx_priority); + + emit initiateTransaction(); } void AppContext::onCreateTransaction(const QString &address, quint64 amount, const QString &description, bool all) { @@ -266,8 +270,6 @@ void AppContext::commitTransaction(PendingTransaction *tx) { } void AppContext::onMultiBroadcast(PendingTransaction *tx) { - DaemonRpc rpc{this, getNetworkTor(), ""}; - int count = tx->txCount(); for (int i = 0; i < count; i++) { QString txData = tx->signedTxToHex(i); @@ -277,8 +279,8 @@ void AppContext::onMultiBroadcast(PendingTransaction *tx) { QString address = node.toURL(); qDebug() << QString("Relaying %1 to: %2").arg(tx->txid()[i], address); - rpc.setDaemonAddress(address); - rpc.sendRawTransaction(txData); + m_rpc->setDaemonAddress(address); + m_rpc->sendRawTransaction(txData); } } } @@ -362,6 +364,7 @@ void AppContext::onWalletOpened(Wallet *wallet) { connect(this->currentWallet, &Wallet::heightRefreshed, this, &AppContext::onHeightRefreshed); connect(this->currentWallet, &Wallet::transactionCreated, this, &AppContext::onTransactionCreated); connect(this->currentWallet, &Wallet::deviceError, this, &AppContext::onDeviceError); + connect(this->currentWallet, &Wallet::deviceButtonRequest, this, &AppContext::onDeviceButtonRequest); emit walletOpened(); @@ -626,6 +629,8 @@ void AppContext::onHeightRefreshed(quint64 walletHeight, quint64 daemonHeight, q } void AppContext::onTransactionCreated(PendingTransaction *tx, const QVector &address) { + qDebug() << Q_FUNC_INFO; + for (auto &addr : address) { if (addr == globals::donationAddress) { this->donationSending = true; diff --git a/src/appcontext.h b/src/appcontext.h index 53c8b580..35435b7c 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -82,7 +82,7 @@ public slots: void onCreateTransaction(const QString &address, quint64 amount, const QString &description, bool all); void onCreateTransactionMultiDest(const QVector &addresses, const QVector &amounts, const QString &description); void onCancelTransaction(PendingTransaction *tx, const QVector &address); - void onSweepOutput(const QString &keyImage, QString address, bool churn, int outputs) const; + void onSweepOutput(const QString &keyImage, QString address, bool churn, int outputs); void onCreateTransactionError(const QString &msg); void onOpenAliasResolve(const QString &openAlias); void onSetRestoreHeight(quint64 height); @@ -140,6 +140,7 @@ signals: void deviceError(const QString &message); private: + DaemonRpc *m_rpc; QTimer m_storeTimer; bool m_openWalletTriedOnce = false; }; diff --git a/src/dialog/UpdateDialog.cpp b/src/dialog/UpdateDialog.cpp index 99a126e2..f5483704 100644 --- a/src/dialog/UpdateDialog.cpp +++ b/src/dialog/UpdateDialog.cpp @@ -47,6 +47,7 @@ UpdateDialog::UpdateDialog(QWidget *parent, QString version, QString downloadUrl } void UpdateDialog::onDownloadClicked() { + ui->label_body->setText("Downloading update.."); ui->btn_download->hide(); ui->progressBar->show(); @@ -173,7 +174,9 @@ void UpdateDialog::onInstallUpdate() { zip_close(zip_archive); QString applicationPath = qgetenv("APPIMAGE"); - if (applicationPath.isEmpty()) { + if (!applicationPath.isEmpty()) { + applicationPath = QFileInfo(applicationPath).absoluteDir().path(); + } else { applicationPath = QCoreApplication::applicationDirPath(); } @@ -184,7 +187,7 @@ void UpdateDialog::onInstallUpdate() { QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { - this->onInstallError("Error: Could not write to application directory"); + this->onInstallError(QString("Error: Could not write to application path: %1").arg(filePath)); return; } @@ -193,7 +196,9 @@ void UpdateDialog::onInstallUpdate() { return; } - if (!file.setPermissions(QFile::ExeUser | QFile::ExeOwner | QFile::ReadUser | QFile::ReadOwner | QFile::WriteUser | QFile::WriteOwner)) { + if (!file.setPermissions(QFile::ExeUser | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther + | QFile::ReadUser | QFile::ReadOwner + | QFile::WriteUser | QFile::WriteOwner)) { this->onInstallError("Error: Unable to set executable flags"); return; } diff --git a/src/dialog/debuginfodialog.ui b/src/dialog/debuginfodialog.ui index d516f7d2..87c204ef 100644 --- a/src/dialog/debuginfodialog.ui +++ b/src/dialog/debuginfodialog.ui @@ -7,7 +7,7 @@ 0 0 693 - 612 + 613 @@ -270,6 +270,9 @@ TextLabel + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + diff --git a/src/dialog/splashdialog.cpp b/src/dialog/splashdialog.cpp index d594cc4d..ded389f3 100644 --- a/src/dialog/splashdialog.cpp +++ b/src/dialog/splashdialog.cpp @@ -18,7 +18,14 @@ SplashDialog::SplashDialog(QWidget *parent) this->adjustSize(); } +void SplashDialog::setMessage(const QString &message) { + ui->label_message->setText(message); +} + +void SplashDialog::setIcon(const QPixmap &icon) { + ui->icon->setPixmap(icon.scaledToWidth(32, Qt::SmoothTransformation)); +} + SplashDialog::~SplashDialog() { delete ui; } - diff --git a/src/dialog/splashdialog.h b/src/dialog/splashdialog.h index 825a2ad3..c4acf902 100644 --- a/src/dialog/splashdialog.h +++ b/src/dialog/splashdialog.h @@ -18,6 +18,9 @@ public: explicit SplashDialog(QWidget *parent = nullptr); ~SplashDialog() override; + void setMessage(const QString &message); + void setIcon(const QPixmap &icon); + private: Ui::SplashDialog *ui; }; diff --git a/src/dialog/torinfodialog.cpp b/src/dialog/torinfodialog.cpp index 6a0a702c..48528765 100644 --- a/src/dialog/torinfodialog.cpp +++ b/src/dialog/torinfodialog.cpp @@ -120,17 +120,16 @@ void TorInfoDialog::initPrivacyLevel() { if (m_ctx->nodes->connection().isLocal()) { ui->label_notice->setText("You are connected to a local node. Traffic is not routed over Tor."); } - else if (Utils::isTorsocks() || WhonixOS::detect() || TailsOS::detect()) { - ui->radio_allTorExceptNode->setEnabled(false); - ui->radio_allTorExceptInitSync->setEnabled(false); - - if (Utils::isTorsocks()) - ui->label_notice->setText("Feather was started with torsocks, all traffic is routed over Tor"); - else if (WhonixOS::detect()) - ui->label_notice->setText("Feather is running on Whonix, all traffic is routed over Tor"); - else if (TailsOS::detect()) - ui->label_notice->setText("Feather is running on Tails, all traffic is routed over Tor"); - } else { + else if (Utils::isTorsocks()) { + ui->label_notice->setText("Feather was started with torsocks, all traffic is routed over Tor"); + } + else if (WhonixOS::detect()) { + ui->label_notice->setText("Feather is running on Whonix, all traffic is routed over Tor"); + } + else if (TailsOS::detect()) { + ui->label_notice->setText("Feather is running on Tails, all traffic is routed over Tor"); + } + else { ui->frame_notice->hide(); } diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index f0d6c490..2079519e 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -605,15 +605,15 @@ PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QSt quint64 amount, quint32 mixin_count, PendingTransaction::Priority priority) { - pauseRefresh(); +// pauseRefresh(); std::set subaddr_indices; Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction( dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count, static_cast(priority), currentSubaddressAccount(), subaddr_indices); - PendingTransaction * result = new PendingTransaction(ptImpl,0); + PendingTransaction * result = new PendingTransaction(ptImpl, nullptr); - startRefresh(); +// startRefresh(); return result; } @@ -631,7 +631,7 @@ void Wallet::createTransactionAsync(const QString &dst_addr, const QString &paym PendingTransaction* Wallet::createTransactionMultiDest(const QVector &dst_addr, const QVector &amount, PendingTransaction::Priority priority) { - pauseRefresh(); +// pauseRefresh(); std::vector dests; for (auto &addr : dst_addr) { @@ -647,7 +647,7 @@ PendingTransaction* Wallet::createTransactionMultiDest(const QVector &d Monero::PendingTransaction * ptImpl = m_walletImpl->createTransactionMultDest(dests, "", amounts, 11, static_cast(priority)); PendingTransaction * result = new PendingTransaction(ptImpl); - startRefresh(); +// startRefresh(); return result; } @@ -667,7 +667,7 @@ void Wallet::createTransactionMultiDestAsync(const QVector &dst_addr, c PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id, quint32 mixin_count, PendingTransaction::Priority priority) { - pauseRefresh(); +// pauseRefresh(); std::set subaddr_indices; Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction( @@ -675,7 +675,7 @@ PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const static_cast(priority), currentSubaddressAccount(), subaddr_indices); PendingTransaction * result = new PendingTransaction(ptImpl, this); - startRefresh(); +// startRefresh(); return result; } @@ -693,13 +693,13 @@ void Wallet::createTransactionAllAsync(const QString &dst_addr, const QString &p PendingTransaction *Wallet::createTransactionSingle(const QString &key_image, const QString &dst_addr, const size_t outputs, PendingTransaction::Priority priority) { - pauseRefresh(); +// pauseRefresh(); Monero::PendingTransaction * ptImpl = m_walletImpl->createTransactionSingle(key_image.toStdString(), dst_addr.toStdString(), outputs, static_cast(priority)); PendingTransaction * result = new PendingTransaction(ptImpl, this); - startRefresh(); +// startRefresh(); return result; } @@ -715,12 +715,12 @@ void Wallet::createTransactionSingleAsync(const QString &key_image, const QStrin PendingTransaction *Wallet::createSweepUnmixableTransaction() { - pauseRefresh(); +// pauseRefresh(); Monero::PendingTransaction * ptImpl = m_walletImpl->createSweepUnmixableTransaction(); PendingTransaction * result = new PendingTransaction(ptImpl, this); - startRefresh(); +// startRefresh(); return result; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c6fbef6e..228c4bcd 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -86,7 +86,7 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) connect(m_ctx, &AppContext::walletRefreshed, ui->historyWidget, &HistoryWidget::onWalletRefreshed); connect(m_ctx, &AppContext::walletOpened, ui->historyWidget, &HistoryWidget::onWalletOpened); - if (!config()->get(Config::firstRun).toBool()) { + if (!config()->get(Config::firstRun).toBool() || TailsOS::detect() || WhonixOS::detect()) { this->onInitialNetworkConfigured(); } @@ -418,8 +418,9 @@ void MainWindow::initWalletContext() { } void MainWindow::initWizard() { + this->setEnabled(false); auto startPage = WalletWizard::Page_Menu; - if (config()->get(Config::firstRun).toBool()) { + if (config()->get(Config::firstRun).toBool() && !(TailsOS::detect() || WhonixOS::detect())) { startPage = WalletWizard::Page_Network; } @@ -544,6 +545,8 @@ void MainWindow::onDeviceButtonRequest(quint64 code) { m_wizard->hide(); } + m_splashDialog->setMessage("Action required on device: Export the view key to open the wallet."); + m_splashDialog->setIcon(QPixmap(":/assets/images/key.png")); m_splashDialog->show(); m_splashDialog->setEnabled(true); } @@ -571,7 +574,10 @@ void MainWindow::displayWalletErrorMsg(const QString &err) { errMsg += "\n\nIncompatible version: you may need to upgrade the Monero app on the Ledger device to the latest version."; } else if (errMsg.contains("Wrong Device Status")) { - errMsg += "\n\nThe device may need to be unlocked"; + errMsg += "\n\nThe device may need to be unlocked."; + } + else if (errMsg.contains("Wrong Channel")) { + errMsg += "\n\nRestart the hardware device and try again."; } QMessageBox::warning(this, "Wallet error", errMsg); @@ -630,9 +636,18 @@ void MainWindow::onBalanceUpdated(quint64 balance, quint64 spendable) { qDebug() << Q_FUNC_INFO; bool hide = config()->get(Config::hideBalance).toBool(); - QString label_str = QString("Balance: %1 XMR").arg(Utils::balanceFormat(spendable)); - if (balance > spendable) + int amountPrecision = config()->get(Config::amountPrecision).toInt(); + + QString balance_str = WalletManager::displayAmount(spendable); + balance_str.remove(QRegExp("0+$")); + + QString label_str = QString("Balance: %1 XMR").arg(balance_str); + if (balance > spendable) { + QString unconfirmed_str = WalletManager::displayAmount(spendable); + unconfirmed_str.remove(QRegExp("0+$")); label_str += QString(" (+%1 XMR unconfirmed)").arg(Utils::balanceFormat(balance - spendable)); + } + if (hide) label_str = "Balance: HIDDEN"; @@ -725,12 +740,12 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVecto err = QString("%1 %2").arg(err).arg(tx_err); qDebug() << Q_FUNC_INFO << err; - QMessageBox::warning(this, "Transactions error", err); + this->displayWalletErrorMsg(err); m_ctx->currentWallet->disposeTransaction(tx); } else if (tx->txCount() == 0) { err = QString("%1 %2").arg(err).arg("No unmixable outputs to sweep."); qDebug() << Q_FUNC_INFO << err; - QMessageBox::warning(this, "Transaction error", err); + this->displayWalletErrorMsg(err); m_ctx->currentWallet->disposeTransaction(tx); } else { const auto &description = m_ctx->tmpTxDescription; @@ -797,7 +812,7 @@ void MainWindow::showWalletInfoDialog() { void MainWindow::showSeedDialog() { if (m_ctx->currentWallet->isHwBacked()) { - QMessageBox::information(this, "Information", "Wallet keys are stored on hardware device."); + QMessageBox::information(this, "Information", "Seed unavailable: Wallet keys are stored on hardware device."); return; } @@ -1232,15 +1247,21 @@ void MainWindow::createUnsignedTxDialog(UnsignedTransaction *tx) { void MainWindow::importTransaction() { - auto result = QMessageBox::warning(this, "Warning", "Using this feature may allow a remote node to associate the transaction with your IP address.\n" - "\n" - "Connect to a trusted node or run Feather over Tor if network level metadata leakage is included in your threat model.", - QMessageBox::Ok | QMessageBox::Cancel); - if (result == QMessageBox::Ok) { - auto *dialog = new TxImportDialog(this, m_ctx); - dialog->exec(); - dialog->deleteLater(); + if (config()->get(Config::torPrivacyLevel).toInt() == Config::allTorExceptNode) { + // TODO: don't show if connected to local node + + auto result = QMessageBox::warning(this, "Warning", "Using this feature may allow a remote node to associate the transaction with your IP address.\n" + "\n" + "Connect to a trusted node or run Feather over Tor if network level metadata leakage is included in your threat model.", + QMessageBox::Ok | QMessageBox::Cancel); + if (result != QMessageBox::Ok) { + return; + } } + + auto *dialog = new TxImportDialog(this, m_ctx); + dialog->exec(); + dialog->deleteLater(); } void MainWindow::onDeviceError(const QString &error) { @@ -1332,9 +1353,10 @@ void MainWindow::onCheckUpdatesComplete(const QString &version, const QString &b versionDisplay.replace("beta", "Beta"); QString updateText = QString("Update to Feather %1 is available").arg(versionDisplay); m_statusUpdateAvailable->setText(updateText); + m_statusUpdateAvailable->setToolTip("Click to Download update."); m_statusUpdateAvailable->show(); - disconnect(m_statusUpdateAvailable); + m_statusUpdateAvailable->disconnect(); connect(m_statusUpdateAvailable, &StatusBarButton::clicked, [this, version, binaryFilename, hash, signer] { this->onShowUpdateCheck(version, binaryFilename, hash, signer); }); @@ -1367,9 +1389,9 @@ void MainWindow::onUpdatesAvailable(const QJsonObject &updates) { } QString newVersion = platformData["version"].toString(); -// if (SemanticVersion::fromString(newVersion) <= featherVersion) { -// return; -// } + if (SemanticVersion::fromString(newVersion) <= featherVersion) { + return; + } // Hooray! New update available @@ -1423,6 +1445,14 @@ void MainWindow::onInitiateTransaction() { m_statusDots = 0; m_constructingTransaction = true; m_txTimer.start(1000); + + if (m_ctx->currentWallet->isHwBacked()) { + QString message = "Constructing transaction: action may be required on device."; + m_splashDialog->setMessage(message); + m_splashDialog->setIcon(QPixmap(":/assets/images/unconfirmed.png")); + m_splashDialog->show(); + m_splashDialog->setEnabled(true); + } } void MainWindow::onEndTransaction() { @@ -1430,6 +1460,10 @@ void MainWindow::onEndTransaction() { m_constructingTransaction = false; m_txTimer.stop(); this->setStatusText(m_statusText); + + if (m_ctx->currentWallet->isHwBacked()) { + m_splashDialog->hide(); + } } void MainWindow::onCustomRestoreHeightSet(int height) { diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 2c6e526c..be1b3814 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 1156 - 496 + 977 + 499 @@ -352,8 +352,8 @@ 0 0 - 1156 - 27 + 977 + 28 diff --git a/src/utils/TorManager.cpp b/src/utils/TorManager.cpp index 5c284a56..252417b0 100644 --- a/src/utils/TorManager.cpp +++ b/src/utils/TorManager.cpp @@ -44,9 +44,10 @@ void TorManager::stop() { } void TorManager::start() { + m_checkConnectionTimer->start(5000); + if (m_localTor) { this->checkConnection(); - m_checkConnectionTimer->start(5000); return; } @@ -256,6 +257,9 @@ bool TorManager::shouldStartTorDaemon() { // Tor daemon (or other service) is already running on our port (19450) if (Utils::portOpen(featherTorHost, featherTorPort)) { + // TODO: this is a hack, fix it later + config()->set(Config::socks5Host, featherTorHost); + config()->set(Config::socks5Port, featherTorPort); return false; } diff --git a/src/utils/config.cpp b/src/utils/config.cpp index 728b612a..883a871d 100644 --- a/src/utils/config.cpp +++ b/src/utils/config.cpp @@ -38,7 +38,7 @@ static const QHash configStrings = { {Config::useOnionNodes,{QS("useOnionNodes"), false}}, {Config::showTabHome,{QS("showTabHome"), true}}, {Config::showTabCoins,{QS("showTabCoins"), false}}, - {Config::showTabExchange, {QS("showTabExchange"), true}}, + {Config::showTabExchange, {QS("showTabExchange"), false}}, {Config::showTabXMRig,{QS("showTabXMRig"), false}}, {Config::showTabCalc,{QS("showTabCalc"), true}}, {Config::geometry, {QS("geometry"), {}}}, diff --git a/src/utils/daemonrpc.cpp b/src/utils/daemonrpc.cpp index 6e40657b..58c57d9f 100644 --- a/src/utils/daemonrpc.cpp +++ b/src/utils/daemonrpc.cpp @@ -37,6 +37,7 @@ void DaemonRpc::onResponse(QNetworkReply *reply, Endpoint endpoint) { const auto err = reply->errorString(); QByteArray data = reply->readAll(); + reply->deleteLater(); QJsonObject obj; if (!data.isEmpty() && Utils::validateJSON(data)) { auto doc = QJsonDocument::fromJson(data); @@ -65,8 +66,8 @@ void DaemonRpc::onResponse(QNetworkReply *reply, Endpoint endpoint) { return; } - reply->deleteLater(); - emit ApiResponse(DaemonResponse(true, endpoint, "", obj)); + DaemonResponse resp{true, endpoint, "", obj}; + emit ApiResponse(resp); } QString DaemonRpc::onSendRawTransactionFailed(const QJsonObject &obj) { diff --git a/src/utils/nodes.cpp b/src/utils/nodes.cpp index c44159bf..2d7b08c4 100644 --- a/src/utils/nodes.cpp +++ b/src/utils/nodes.cpp @@ -318,12 +318,19 @@ void Nodes::setCustomNodes(const QList &nodes) { } void Nodes::onWalletRefreshed() { - if (config()->get(Config::torPrivacyLevel).toInt() == Config::allTorExceptInitSync && !m_connection.isLocal()) { + if (config()->get(Config::torPrivacyLevel).toInt() == Config::allTorExceptInitSync) { + if (m_connection.isLocal()) + return; + if (TailsOS::detect() || WhonixOS::detect()) + return; this->autoConnect(true); } } bool Nodes::useOnionNodes() { + if (TailsOS::detect() || WhonixOS::detect()) { + return true; + } auto privacyLevel = config()->get(Config::torPrivacyLevel).toInt(); if (privacyLevel == Config::allTor || (privacyLevel == Config::allTorExceptInitSync && m_ctx->refreshed)) { return true; diff --git a/src/utils/tails.cpp b/src/utils/tails.cpp index 4f8849b8..80c5b378 100644 --- a/src/utils/tails.cpp +++ b/src/utils/tails.cpp @@ -7,10 +7,16 @@ #include "tails.h" #include "utils.h" +bool TailsOS::detected = false; +bool TailsOS::isTails = false; const QString TailsOS::tailsPathData = QString("/live/persistence/TailsData_unlocked/"); bool TailsOS::detect() { + if (detected) { + return TailsOS::isTails; + } + if (!Utils::fileExists("/etc/os-release")) return false; @@ -22,6 +28,9 @@ bool TailsOS::detect() if (matched) qDebug() << "Tails OS detected"; + TailsOS::detected = true; + TailsOS::isTails = matched; + return matched; } diff --git a/src/utils/tails.h b/src/utils/tails.h index 701d6606..eaa932f6 100644 --- a/src/utils/tails.h +++ b/src/utils/tails.h @@ -21,6 +21,9 @@ public: static bool usePersistence; static bool rememberChoice; static const QString tailsPathData; + + static bool isTails; + static bool detected; }; #endif // TAILSOS_H diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index ffdb3f6f..97e38c9e 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -17,10 +17,6 @@ #include "utils/ColorScheme.h" #include "globals.h" -// Application log for current session -QVector applicationLog = QVector(); // todo: replace with ring buffer -QMutex logMutex; - QByteArray Utils::fileGetContents(const QString &path) { QFile file(path); @@ -128,12 +124,6 @@ void Utils::applicationLogHandler(QtMsgType type, const QMessageLogContext &cont auto message = logMessage(type, line, fn); - { - QMutexLocker locker(&logMutex); - applicationLog.append(message); - } - - //emit applicationLogUpdated(message); } diff --git a/src/widgets/LocalMoneroWidget.cpp b/src/widgets/LocalMoneroWidget.cpp index 1b2b3555..e8565c07 100644 --- a/src/widgets/LocalMoneroWidget.cpp +++ b/src/widgets/LocalMoneroWidget.cpp @@ -194,7 +194,7 @@ void LocalMoneroWidget::updatePaymentMethods() { QString currency = ui->combo_currency->currentText().toUpper(); ui->combo_paymentMethod->clear(); - ui->combo_paymentMethod->addItem("All online offers"); + ui->combo_paymentMethod->addItem("Any payment method"); for (const auto &payment_method : m_paymentMethods.keys()) { auto pm = m_paymentMethods[payment_method].toObject(); diff --git a/src/widgets/LocalMoneroWidget.ui b/src/widgets/LocalMoneroWidget.ui index 4c9e37b9..25a8cc7a 100644 --- a/src/widgets/LocalMoneroWidget.ui +++ b/src/widgets/LocalMoneroWidget.ui @@ -112,7 +112,7 @@ - All online offers + Any payment method diff --git a/src/wizard/PageHardwareDevice.ui b/src/wizard/PageHardwareDevice.ui index b9c0c480..736edea4 100644 --- a/src/wizard/PageHardwareDevice.ui +++ b/src/wizard/PageHardwareDevice.ui @@ -28,11 +28,6 @@ Ledger Nano S/X - - - Trezor Model T - - diff --git a/src/wizard/PageNetworkTor.cpp b/src/wizard/PageNetworkTor.cpp index 550f0c12..cade2ee7 100644 --- a/src/wizard/PageNetworkTor.cpp +++ b/src/wizard/PageNetworkTor.cpp @@ -12,16 +12,20 @@ PageNetworkTor::PageNetworkTor(AppContext *ctx, QWidget *parent) { ui->setupUi(this); - QPixmap iconAllTorExceptNode(":/assets/images/securityLevelStandardWhite.png"); - QPixmap iconAllTorExceptInitSync(":/assets/images/securityLevelSaferWhite.png"); - QPixmap iconAllTor(":/assets/images/securityLevelSafestWhite.png"); + this->setCommitPage(true); + this->setButtonText(QWizard::CommitButton, "Next"); + + QPixmap iconAllTorExceptNode(":/assets/images/securityLevelStandard.png"); + QPixmap iconAllTorExceptInitSync(":/assets/images/securityLevelSafer.png"); + QPixmap iconAllTor(":/assets/images/securityLevelSafest.png"); ui->icon_allTorExceptNode->setPixmap(iconAllTorExceptNode.scaledToHeight(16, Qt::SmoothTransformation)); ui->icon_allTorExceptInitSync->setPixmap(iconAllTorExceptInitSync.scaledToHeight(16, Qt::SmoothTransformation)); ui->icon_allTor->setPixmap(iconAllTor.scaledToHeight(16, Qt::SmoothTransformation)); - ui->frame_privacyLevel->setVisible(false); connect(ui->radio_configureManually, &QRadioButton::toggled, [this](bool checked){ ui->frame_privacyLevel->setVisible(checked); + this->adjustSize(); + this->updateGeometry(); }); ui->btnGroup_privacyLevel->setId(ui->radio_allTorExceptNode, Config::allTorExceptNode); @@ -35,6 +39,13 @@ PageNetworkTor::PageNetworkTor(AppContext *ctx, QWidget *parent) } } +void PageNetworkTor::initializePage() { + // Fuck you Qt. No squish. + QTimer::singleShot(1, [this]{ + ui->frame_privacyLevel->setVisible(false); + }); +} + int PageNetworkTor::nextId() const { return WalletWizard::Page_Menu; } diff --git a/src/wizard/PageNetworkTor.h b/src/wizard/PageNetworkTor.h index 93639b3c..9863b58b 100644 --- a/src/wizard/PageNetworkTor.h +++ b/src/wizard/PageNetworkTor.h @@ -18,6 +18,7 @@ Q_OBJECT public: explicit PageNetworkTor(AppContext *ctx, QWidget *parent = nullptr); + void initializePage() override; bool validatePage() override; int nextId() const override; diff --git a/src/wizard/PageNetworkTor.ui b/src/wizard/PageNetworkTor.ui index f7959012..8cabfc8e 100644 --- a/src/wizard/PageNetworkTor.ui +++ b/src/wizard/PageNetworkTor.ui @@ -83,6 +83,12 @@ + + + 0 + 0 + + QFrame::StyledPanel @@ -107,6 +113,12 @@ + + + 0 + 0 + + Route all traffic over Tor, except traffic to node @@ -134,8 +146,14 @@ + + + 0 + 0 + + - Route all traffic over Tor, except initial wallet synchronization + Route all traffic over Tor, except initial wallet sync btnGroup_privacyLevel @@ -161,6 +179,12 @@ + + + 0 + 0 + + Route all traffic over Tor diff --git a/src/wizard/PageWalletFile.cpp b/src/wizard/PageWalletFile.cpp index 0e3bb8ea..cfde928b 100644 --- a/src/wizard/PageWalletFile.cpp +++ b/src/wizard/PageWalletFile.cpp @@ -97,7 +97,11 @@ QString PageWalletFile::defaultWalletName() { int count = 1; QString walletName; do { - walletName = QString("wallet_%1").arg(count); + QString walletStr = QString("wallet_%1"); + if (m_fields->mode == WizardMode::CreateWalletFromDevice) { + walletStr = QString("ledger_%1"); + } + walletName = walletStr.arg(count); count++; } while (this->walletPathExists(walletName));