Handle edge cases for sapling activation
This commit is contained in:
@@ -75,8 +75,6 @@ void MainWindow::turnstileProgress() {
|
|||||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||||
progress.msgIcon->setPixmap(icon.pixmap(64, 64));
|
progress.msgIcon->setPixmap(icon.pixmap(64, 64));
|
||||||
|
|
||||||
progress.buttonBox->button(QDialogButtonBox::Cancel)->setText("Abort");
|
|
||||||
|
|
||||||
auto fnUpdateProgressUI = [=] () {
|
auto fnUpdateProgressUI = [=] () {
|
||||||
// Get the plan progress
|
// Get the plan progress
|
||||||
if (rpc->getTurnstile()->isMigrationPresent()) {
|
if (rpc->getTurnstile()->isMigrationPresent()) {
|
||||||
@@ -112,20 +110,31 @@ void MainWindow::turnstileProgress() {
|
|||||||
progressTimer.start(Utils::updateSpeed);
|
progressTimer.start(Utils::updateSpeed);
|
||||||
fnUpdateProgressUI();
|
fnUpdateProgressUI();
|
||||||
|
|
||||||
auto accpeted = d.exec();
|
|
||||||
auto curProgress = rpc->getTurnstile()->getPlanProgress();
|
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) {
|
if (accpeted == QDialog::Accepted && curProgress.step == curProgress.totalSteps) {
|
||||||
// Finished, so delete the file
|
// Finished, so delete the file
|
||||||
rpc->getTurnstile()->removeFile();
|
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() {
|
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;
|
double bal = 0;
|
||||||
if (addr.startsWith("All")) {
|
if (addr.startsWith("All")) {
|
||||||
bal = fnGetAllSproutBalance();
|
bal = fnGetAllSproutBalance();
|
||||||
@@ -166,9 +175,26 @@ void MainWindow::turnstileDoMigration() {
|
|||||||
bal = rpc->getAllBalances()->value(addr);
|
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
|
// Privacy level combobox
|
||||||
// Num tx over num blocks
|
// Num tx over num blocks
|
||||||
QList<QPair<int, int>> privOptions;
|
QList<QPair<int, int>> privOptions;
|
||||||
@@ -196,12 +222,12 @@ void MainWindow::turnstileDoMigration() {
|
|||||||
privLevel.first, privLevel.second);
|
privLevel.first, privLevel.second);
|
||||||
|
|
||||||
QMessageBox::information(this, "Backup your wallet.dat",
|
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);
|
QMessageBox::Ok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupTurnstileDialog() {
|
void MainWindow::setupTurnstileDialog() {
|
||||||
// Turnstile migration
|
// Turnstile migration
|
||||||
QObject::connect(ui->actionTurnstile_Migration, &QAction::triggered, [=] () {
|
QObject::connect(ui->actionTurnstile_Migration, &QAction::triggered, [=] () {
|
||||||
// If there is current migration that is present, show the progress button
|
// If there is current migration that is present, show the progress button
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@@ -778,7 +778,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="actionTurnstile_Migration">
|
<action name="actionTurnstile_Migration">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Turnstile Migration</string>
|
<string>Sapling Turnstile</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
11
src/rpc.cpp
11
src/rpc.cpp
@@ -11,7 +11,7 @@ RPC::RPC(QNetworkAccessManager* client, MainWindow* main) {
|
|||||||
this->main = main;
|
this->main = main;
|
||||||
this->ui = main->ui;
|
this->ui = main->ui;
|
||||||
|
|
||||||
this->turnstile = new Turnstile(this);
|
this->turnstile = new Turnstile(this, main);
|
||||||
|
|
||||||
// Setup balances table model
|
// Setup balances table model
|
||||||
balancesTableModel = new BalancesTableModel(main->ui->balancesTable);
|
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.
|
// Function to create the data model and update the views, used below.
|
||||||
void RPC::updateUI(bool anyUnconfirmed) {
|
void RPC::updateUI(bool anyUnconfirmed) {
|
||||||
// See if the turnstile migration has any steps that need to be done.
|
if (Settings::getInstance()->isTestnet()) {
|
||||||
turnstile->executeMigrationStep();
|
// 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);
|
ui->unconfirmedWarning->setVisible(anyUnconfirmed);
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
Turnstile::Turnstile(RPC* _rpc) {
|
Turnstile::Turnstile(RPC* _rpc, QWidget* mainwindow) {
|
||||||
this->rpc = _rpc;
|
this->rpc = _rpc;
|
||||||
|
this->mainwindow = mainwindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
Turnstile::~Turnstile() {
|
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
|
// The first migration is shifted to the current block, so the user sees something
|
||||||
// happening immediately
|
// 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;
|
migItems[0].blockNumber = curBlock;
|
||||||
|
|
||||||
std::sort(migItems.begin(), migItems.end(), [&] (auto a, auto b) {
|
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);
|
writeMigrationPlan(migItems);
|
||||||
auto readPlan = readMigrationPlan();
|
rpc->refresh(true); // Force refresh, to start the migration immediately
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -141,10 +149,13 @@ QList<int> Turnstile::getBlockNumbers(int start, int end, int count) {
|
|||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Need at least 0.0005 ZEC for this
|
||||||
|
double Turnstile::minMigrationAmount = 0.0005;
|
||||||
|
|
||||||
QList<double> Turnstile::splitAmount(double amount, int parts) {
|
QList<double> Turnstile::splitAmount(double amount, int parts) {
|
||||||
QList<double> amounts;
|
QList<double> amounts;
|
||||||
// Need at least 0.0004 ZEC for this
|
|
||||||
if (amount < 0.0004)
|
if (amount < minMigrationAmount)
|
||||||
return amounts;
|
return amounts;
|
||||||
|
|
||||||
fillAmounts(amounts, amount, parts);
|
fillAmounts(amounts, amount, parts);
|
||||||
@@ -201,14 +212,6 @@ Turnstile::getNextStep(QList<TurnstileMigrationItem>& plan) {
|
|||||||
item.status == TurnstileMigrationItemStatus::SentToT;
|
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
|
// Find the next step
|
||||||
auto nextStep = std::find_if(plan.begin(), plan.end(), fnIsEligibleItem);
|
auto nextStep = std::find_if(plan.begin(), plan.end(), fnIsEligibleItem);
|
||||||
return nextStep;
|
return nextStep;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ struct ProgressReport {
|
|||||||
class Turnstile
|
class Turnstile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Turnstile(RPC* _rpc);
|
Turnstile(RPC* _rpc, QWidget* mainwindow);
|
||||||
~Turnstile();
|
~Turnstile();
|
||||||
|
|
||||||
void planMigration(QString zaddr, QString destAddr, int splits, int numBlocks);
|
void planMigration(QString zaddr, QString destAddr, int splits, int numBlocks);
|
||||||
@@ -48,6 +48,7 @@ public:
|
|||||||
ProgressReport getPlanProgress();
|
ProgressReport getPlanProgress();
|
||||||
bool isMigrationPresent();
|
bool isMigrationPresent();
|
||||||
|
|
||||||
|
static double minMigrationAmount;
|
||||||
private:
|
private:
|
||||||
QList<int> getBlockNumbers(int start, int end, int count);
|
QList<int> getBlockNumbers(int start, int end, int count);
|
||||||
QString writeableFile();
|
QString writeableFile();
|
||||||
@@ -57,7 +58,8 @@ private:
|
|||||||
|
|
||||||
QList<TurnstileMigrationItem>::Iterator getNextStep(QList<TurnstileMigrationItem>& plan);
|
QList<TurnstileMigrationItem>::Iterator getNextStep(QList<TurnstileMigrationItem>& plan);
|
||||||
|
|
||||||
RPC* rpc;
|
RPC* rpc;
|
||||||
|
QWidget* mainwindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Please Ensure you have your wallet.dat backed up!</string>
|
<string>Please ensure you have your wallet.dat backed up!</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -90,7 +90,10 @@
|
|||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Close|QDialogButtonBox::Discard|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -681,7 +681,7 @@ public:
|
|||||||
|
|
||||||
retranslateUi(MainWindow);
|
retranslateUi(MainWindow);
|
||||||
|
|
||||||
tabWidget->setCurrentIndex(1);
|
tabWidget->setCurrentIndex(0);
|
||||||
|
|
||||||
|
|
||||||
QMetaObject::connectSlotsByName(MainWindow);
|
QMetaObject::connectSlotsByName(MainWindow);
|
||||||
@@ -696,7 +696,7 @@ public:
|
|||||||
actionDonate->setText(QApplication::translate("MainWindow", "Donate", nullptr));
|
actionDonate->setText(QApplication::translate("MainWindow", "Donate", nullptr));
|
||||||
actionImport_Private_Keys->setText(QApplication::translate("MainWindow", "Import Private Keys", 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));
|
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));
|
groupBox->setTitle(QApplication::translate("MainWindow", "Summary", nullptr));
|
||||||
label->setText(QApplication::translate("MainWindow", "Shielded", nullptr));
|
label->setText(QApplication::translate("MainWindow", "Shielded", nullptr));
|
||||||
balSheilded->setText(QString());
|
balSheilded->setText(QString());
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ public:
|
|||||||
buttonBox = new QDialogButtonBox(TurnstileProgress);
|
buttonBox = new QDialogButtonBox(TurnstileProgress);
|
||||||
buttonBox->setObjectName(QStringLiteral("buttonBox"));
|
buttonBox->setObjectName(QStringLiteral("buttonBox"));
|
||||||
buttonBox->setOrientation(Qt::Horizontal);
|
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);
|
gridLayout->addWidget(buttonBox, 9, 0, 1, 3);
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ public:
|
|||||||
void retranslateUi(QDialog *TurnstileProgress)
|
void retranslateUi(QDialog *TurnstileProgress)
|
||||||
{
|
{
|
||||||
TurnstileProgress->setWindowTitle(QApplication::translate("TurnstileProgress", "Turnstile Migration Progress", nullptr));
|
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));
|
nextTx->setText(QApplication::translate("TurnstileProgress", "Next Transaction in 4 hours", nullptr));
|
||||||
progressTxt->setText(QApplication::translate("TurnstileProgress", "4 / 12", nullptr));
|
progressTxt->setText(QApplication::translate("TurnstileProgress", "4 / 12", nullptr));
|
||||||
label_2->setText(QApplication::translate("TurnstileProgress", "Migration Progress", nullptr));
|
label_2->setText(QApplication::translate("TurnstileProgress", "Migration Progress", nullptr));
|
||||||
|
|||||||
Reference in New Issue
Block a user