From e5d2ae7d9bd753b379ed73db2f5c5a4177a73731 Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Sun, 28 Oct 2018 22:36:49 -0700 Subject: [PATCH] Handle edge cases for sapling activation --- src/mainwindow.cpp | 62 +++++++++++++++++++++++++++----------- src/mainwindow.ui | 4 +-- src/rpc.cpp | 11 +++++-- src/turnstile.cpp | 27 +++++++++-------- src/turnstile.h | 6 ++-- src/turnstileprogress.ui | 7 +++-- src/ui_mainwindow.h | 4 +-- src/ui_turnstileprogress.h | 5 +-- 8 files changed, 83 insertions(+), 43 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9404433..633aa73 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -75,8 +75,6 @@ void MainWindow::turnstileProgress() { QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); progress.msgIcon->setPixmap(icon.pixmap(64, 64)); - progress.buttonBox->button(QDialogButtonBox::Cancel)->setText("Abort"); - auto fnUpdateProgressUI = [=] () { // Get the plan progress if (rpc->getTurnstile()->isMigrationPresent()) { @@ -112,20 +110,31 @@ void MainWindow::turnstileProgress() { progressTimer.start(Utils::updateSpeed); fnUpdateProgressUI(); - auto accpeted = d.exec(); auto curProgress = rpc->getTurnstile()->getPlanProgress(); + + // Abort button + if (curProgress.step != curProgress.totalSteps) + progress.buttonBox->button(QDialogButtonBox::Discard)->setText("Abort"); + else + progress.buttonBox->button(QDialogButtonBox::Discard)->setVisible(false); + QObject::connect(progress.buttonBox->button(QDialogButtonBox::Discard), &QPushButton::clicked, [&] () { + if (curProgress.step != curProgress.totalSteps) { + auto abort = QMessageBox::warning(this, "Are you sure you want to Abort?", + "Are you sure you want to abort the migration?\nAll further transactions will be cancelled.\nAll your funds are still in your wallet.", + QMessageBox::Yes, QMessageBox::No); + if (abort == QMessageBox::Yes) { + rpc->getTurnstile()->removeFile(); + d.close(); + ui->statusBar->showMessage("Automatic Sapling turnstile migration aborted."); + } + } + }); + + auto accpeted = d.exec(); if (accpeted == QDialog::Accepted && curProgress.step == curProgress.totalSteps) { // Finished, so delete the file rpc->getTurnstile()->removeFile(); - } - if (accpeted == QDialog::Rejected && curProgress.step != curProgress.totalSteps) { - auto abort = QMessageBox::warning(this, "Are you sure you want to Abort?", - "Are you sure you want to abort the migration?\nAll further transactions will be cancelled.\nAll your funds are still in your wallet.", - QMessageBox::Yes, QMessageBox::No); - if (abort) { - rpc->getTurnstile()->removeFile(); - } - } + } } void MainWindow::turnstileDoMigration() { @@ -158,7 +167,7 @@ void MainWindow::turnstileDoMigration() { } } - QObject::connect(turnstile.migrateZaddList, &QComboBox::currentTextChanged, [=] (auto addr) { + auto fnUpdateSproutBalance = [=] (QString addr) { double bal = 0; if (addr.startsWith("All")) { bal = fnGetAllSproutBalance(); @@ -166,9 +175,26 @@ void MainWindow::turnstileDoMigration() { bal = rpc->getAllBalances()->value(addr); } - turnstile.fromBalance->setText(Settings::getInstance()->getZECUSDDisplayFormat(bal)); - }); - + auto balTxt = Settings::getInstance()->getZECUSDDisplayFormat(bal); + + if (bal < Turnstile::minMigrationAmount) { + turnstile.fromBalance->setStyleSheet("color: red;"); + turnstile.fromBalance->setText(balTxt % " [You need at least " + % Settings::getInstance()->getZECDisplayFormat(Turnstile::minMigrationAmount) + % " for automatic migration]"); + turnstile.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + } else { + turnstile.fromBalance->setStyleSheet(""); + turnstile.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + turnstile.fromBalance->setText(balTxt); + } + }; + + fnUpdateSproutBalance(turnstile.migrateZaddList->currentText()); + + // Combo box selection event + QObject::connect(turnstile.migrateZaddList, &QComboBox::currentTextChanged, fnUpdateSproutBalance); + // Privacy level combobox // Num tx over num blocks QList> privOptions; @@ -196,12 +222,12 @@ void MainWindow::turnstileDoMigration() { privLevel.first, privLevel.second); QMessageBox::information(this, "Backup your wallet.dat", - "The migration will now start. You can check progress in the File -> Turnstile Migration menu.\n\nYOU MUST BACKUP YOUR wallet.dat NOW!.\n\nNew Addresses have been added to your wallet which will be used for the migration.", + "The migration will now start. You can check progress in the File -> Sapling Turnstile menu.\n\nYOU MUST BACKUP YOUR wallet.dat NOW!\n\nNew Addresses have been added to your wallet which will be used for the migration.", QMessageBox::Ok); } } -void MainWindow::setupTurnstileDialog() { +void MainWindow::setupTurnstileDialog() { // Turnstile migration QObject::connect(ui->actionTurnstile_Migration, &QAction::triggered, [=] () { // If there is current migration that is present, show the progress button diff --git a/src/mainwindow.ui b/src/mainwindow.ui index ed585db..111fe9c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -22,7 +22,7 @@ - 1 + 0 @@ -778,7 +778,7 @@ - Turnstile Migration + Sapling Turnstile diff --git a/src/rpc.cpp b/src/rpc.cpp index c2959e4..8fd9117 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -11,7 +11,7 @@ RPC::RPC(QNetworkAccessManager* client, MainWindow* main) { this->main = main; this->ui = main->ui; - this->turnstile = new Turnstile(this); + this->turnstile = new Turnstile(this, main); // Setup balances table model balancesTableModel = new BalancesTableModel(main->ui->balancesTable); @@ -510,8 +510,13 @@ void RPC::refreshAddresses() { // Function to create the data model and update the views, used below. void RPC::updateUI(bool anyUnconfirmed) { - // See if the turnstile migration has any steps that need to be done. - turnstile->executeMigrationStep(); + if (Settings::getInstance()->isTestnet()) { + // See if the turnstile migration has any steps that need to be done. + turnstile->executeMigrationStep(); + } else { + // Not available on mainnet yet. + main->ui->actionTurnstile_Migration->setVisible(false); + } ui->unconfirmedWarning->setVisible(anyUnconfirmed); diff --git a/src/turnstile.cpp b/src/turnstile.cpp index e9c2706..50df245 100644 --- a/src/turnstile.cpp +++ b/src/turnstile.cpp @@ -9,8 +9,9 @@ using json = nlohmann::json; -Turnstile::Turnstile(RPC* _rpc) { +Turnstile::Turnstile(RPC* _rpc, QWidget* mainwindow) { this->rpc = _rpc; + this->mainwindow = mainwindow; } Turnstile::~Turnstile() { @@ -117,6 +118,13 @@ void Turnstile::planMigration(QString zaddr, QString destAddr, int numsplits, in // The first migration is shifted to the current block, so the user sees something // happening immediately + if (migItems.size() == 0) { + // Show error and abort + QMessageBox::warning(mainwindow, + "Locked funds", "Could not initiate migration.\nYou either have unconfirmed funds or the balance is too low for an automatic migration."); + return; + } + migItems[0].blockNumber = curBlock; std::sort(migItems.begin(), migItems.end(), [&] (auto a, auto b) { @@ -124,7 +132,7 @@ void Turnstile::planMigration(QString zaddr, QString destAddr, int numsplits, in }); writeMigrationPlan(migItems); - auto readPlan = readMigrationPlan(); + rpc->refresh(true); // Force refresh, to start the migration immediately } ); } @@ -141,10 +149,13 @@ QList Turnstile::getBlockNumbers(int start, int end, int count) { return blocks; } + // Need at least 0.0005 ZEC for this +double Turnstile::minMigrationAmount = 0.0005; + QList Turnstile::splitAmount(double amount, int parts) { QList amounts; - // Need at least 0.0004 ZEC for this - if (amount < 0.0004) + + if (amount < minMigrationAmount) return amounts; fillAmounts(amounts, amount, parts); @@ -201,14 +212,6 @@ Turnstile::getNextStep(QList& plan) { item.status == TurnstileMigrationItemStatus::SentToT; }; - // // Fn to find if there are any unconfirmed funds for this address. - // auto fnHasUnconfirmed = [=] (QString addr) { - // auto utxoset = rpc->getUTXOs(); - // return std::find_if(utxoset->begin(), utxoset->end(), [=] (auto utxo) { - // return utxo.address == addr && utxo.confirmations == 0; - // }) != utxoset->end(); - // }; - // Find the next step auto nextStep = std::find_if(plan.begin(), plan.end(), fnIsEligibleItem); return nextStep; diff --git a/src/turnstile.h b/src/turnstile.h index a198aad..b46d877 100644 --- a/src/turnstile.h +++ b/src/turnstile.h @@ -33,7 +33,7 @@ struct ProgressReport { class Turnstile { public: - Turnstile(RPC* _rpc); + Turnstile(RPC* _rpc, QWidget* mainwindow); ~Turnstile(); void planMigration(QString zaddr, QString destAddr, int splits, int numBlocks); @@ -48,6 +48,7 @@ public: ProgressReport getPlanProgress(); bool isMigrationPresent(); + static double minMigrationAmount; private: QList getBlockNumbers(int start, int end, int count); QString writeableFile(); @@ -57,7 +58,8 @@ private: QList::Iterator getNextStep(QList& plan); - RPC* rpc; + RPC* rpc; + QWidget* mainwindow; }; #endif diff --git a/src/turnstileprogress.ui b/src/turnstileprogress.ui index 0f2fb5c..8deebf4 100644 --- a/src/turnstileprogress.ui +++ b/src/turnstileprogress.ui @@ -30,7 +30,7 @@ - Please Ensure you have your wallet.dat backed up! + Please ensure you have your wallet.dat backed up! true @@ -90,7 +90,10 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Close|QDialogButtonBox::Discard|QDialogButtonBox::Ok + + + false diff --git a/src/ui_mainwindow.h b/src/ui_mainwindow.h index 4769dfa..88ffa57 100644 --- a/src/ui_mainwindow.h +++ b/src/ui_mainwindow.h @@ -681,7 +681,7 @@ public: retranslateUi(MainWindow); - tabWidget->setCurrentIndex(1); + tabWidget->setCurrentIndex(0); QMetaObject::connectSlotsByName(MainWindow); @@ -696,7 +696,7 @@ public: actionDonate->setText(QApplication::translate("MainWindow", "Donate", nullptr)); actionImport_Private_Keys->setText(QApplication::translate("MainWindow", "Import Private Keys", nullptr)); actionCheck_for_Updates->setText(QApplication::translate("MainWindow", "Check github.com for Updates", nullptr)); - actionTurnstile_Migration->setText(QApplication::translate("MainWindow", "Turnstile Migration", nullptr)); + actionTurnstile_Migration->setText(QApplication::translate("MainWindow", "Sapling Turnstile", nullptr)); groupBox->setTitle(QApplication::translate("MainWindow", "Summary", nullptr)); label->setText(QApplication::translate("MainWindow", "Shielded", nullptr)); balSheilded->setText(QString()); diff --git a/src/ui_turnstileprogress.h b/src/ui_turnstileprogress.h index fd75220..5c15e70 100644 --- a/src/ui_turnstileprogress.h +++ b/src/ui_turnstileprogress.h @@ -97,7 +97,8 @@ public: buttonBox = new QDialogButtonBox(TurnstileProgress); buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + buttonBox->setStandardButtons(QDialogButtonBox::Close|QDialogButtonBox::Discard|QDialogButtonBox::Ok); + buttonBox->setCenterButtons(false); gridLayout->addWidget(buttonBox, 9, 0, 1, 3); @@ -123,7 +124,7 @@ public: void retranslateUi(QDialog *TurnstileProgress) { TurnstileProgress->setWindowTitle(QApplication::translate("TurnstileProgress", "Turnstile Migration Progress", nullptr)); - label_4->setText(QApplication::translate("TurnstileProgress", "Please Ensure you have your wallet.dat backed up!", nullptr)); + label_4->setText(QApplication::translate("TurnstileProgress", "Please ensure you have your wallet.dat backed up!", nullptr)); nextTx->setText(QApplication::translate("TurnstileProgress", "Next Transaction in 4 hours", nullptr)); progressTxt->setText(QApplication::translate("TurnstileProgress", "4 / 12", nullptr)); label_2->setText(QApplication::translate("TurnstileProgress", "Migration Progress", nullptr));