From b428f40def46b885b553b2d7d3384eeb1f311094 Mon Sep 17 00:00:00 2001 From: adityapk00 Date: Fri, 23 Nov 2018 17:30:21 -0800 Subject: [PATCH] Auto shielding for t Addresses --- src/mainwindow.cpp | 7 +++++ src/mainwindow.h | 1 + src/sendtab.cpp | 35 +++++++++++++++++++++++- src/settings.cpp | 12 +++++++++ src/settings.h | 9 +++++-- src/settings.ui | 66 +++++++++++++++++++++++++++++++--------------- src/turnstile.cpp | 4 +-- 7 files changed, 108 insertions(+), 26 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b623cbb..2594890 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -387,6 +387,9 @@ void MainWindow::setupSettingsModal() { // Custom fees settings.chkCustomFees->setChecked(Settings::getInstance()->getAllowCustomFees()); + // Auto shielding + settings.chkAutoShield->setChecked(Settings::getInstance()->getAutoShield()); + // Connection Settings QIntValidator validator(0, 65535); settings.port->setValidator(&validator); @@ -426,6 +429,9 @@ void MainWindow::setupSettingsModal() { if (!customFees) ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee())); + // Auto shield + Settings::getInstance()->setAutoShield(settings.chkAutoShield->isChecked()); + if (zcashConfLocation.isEmpty()) { // Save settings Settings::getInstance()->saveSettings( @@ -567,6 +573,7 @@ void MainWindow::postToZBoard() { auto toAddr = topics[zb.topicsList->currentText()]; tx.toAddrs.push_back(ToFields{ toAddr, Settings::getZboardAmount(), memo, memo.toUtf8().toHex() }); tx.fee = Settings::getMinerFee(); + tx.sendChangeToSapling = false; json params = json::array(); rpc->fillTxJsonParams(params, tx); diff --git a/src/mainwindow.h b/src/mainwindow.h index 382b86e..529ea6b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -23,6 +23,7 @@ struct Tx { QString fromAddr; QList toAddrs; double fee; + bool sendChangeToSapling; }; namespace Ui { diff --git a/src/sendtab.cpp b/src/sendtab.cpp index da54884..24bc6b0 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -363,17 +363,26 @@ void MainWindow::maxAmountChecked(int checked) { // Create a Tx from the current state of the send page. Tx MainWindow::createTxFromSendPage() { Tx tx; + + bool sendChangeToSapling = Settings::getInstance()->getAutoShield(); + // Gather the from / to addresses tx.fromAddr = ui->inputsCombo->currentText(); + sendChangeToSapling = sendChangeToSapling && Settings::isTAddress(tx.fromAddr); // For each addr/amt in the sendTo tab int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that + double totalAmt = 0; for (int i=0; i < totalItems; i++) { QString addr = ui->sendToWidgets->findChild(QString("Address") % QString::number(i+1))->text().trimmed(); // Remove label if it exists addr = AddressBook::addressFromAddressLabel(addr); + + // If address is sprout, then we can't send change to sapling, because of turnstile. + sendChangeToSapling = sendChangeToSapling && !Settings::getInstance()->isSproutAddress(addr); double amt = ui->sendToWidgets->findChild(QString("Amount") % QString::number(i+1))->text().trimmed().toDouble(); + totalAmt += amt; QString memo = ui->sendToWidgets->findChild(QString("MemoTxt") % QString::number(i+1))->text().trimmed(); tx.toAddrs.push_back( ToFields{addr, amt, memo, memo.toUtf8().toHex()} ); @@ -381,10 +390,34 @@ Tx MainWindow::createTxFromSendPage() { if (Settings::getInstance()->getAllowCustomFees()) { tx.fee = ui->minerFeeAmt->text().toDouble(); - } else { + } + else { tx.fee = Settings::getMinerFee(); } + if (sendChangeToSapling) { + auto saplingAddr = std::find_if(rpc->getAllZAddresses()->begin(), rpc->getAllZAddresses()->end(), [=](auto i) -> bool { + // We're finding a sapling address that is not one of the To addresses, because zcash doesn't allow duplicated addresses + bool isSapling = Settings::getInstance()->isSaplingAddress(i); + if (!isSapling) return false; + + // Also check all the To addresses + for (auto t : tx.toAddrs) { + if (t.addr == i) + return false; + } + + return true; + }); + if (saplingAddr != rpc->getAllZAddresses()->end()) { + tx.sendChangeToSapling = sendChangeToSapling; + double change = rpc->getAllBalances()->value(tx.fromAddr) - totalAmt - tx.fee; + + QString changeMemo = "change from " + tx.fromAddr; + tx.toAddrs.push_back( ToFields{*saplingAddr, change, changeMemo, changeMemo.toUtf8().toHex()} ); + } + } + return tx; } diff --git a/src/settings.cpp b/src/settings.cpp index 86b8f68..371bd5c 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -66,6 +66,10 @@ bool Settings::isZAddress(QString addr) { return addr.startsWith("z"); } +bool Settings::isTAddress(QString addr) { + return addr.startsWith("t"); +} + bool Settings::isSyncing() { return _isSyncing; } @@ -91,6 +95,14 @@ double Settings::getZECPrice() { return zecPrice; } +bool Settings::getAutoShield() { + // Load from Qt settings + return QSettings().value("options/autoshield", false).toBool(); +} + +void Settings::setAutoShield(bool allow) { + QSettings().setValue("options/autoshield", allow); +} bool Settings::getAllowCustomFees() { // Load from the QT Settings. diff --git a/src/settings.h b/src/settings.h index ee5318b..7261b73 100644 --- a/src/settings.h +++ b/src/settings.h @@ -27,7 +27,6 @@ public: bool isSaplingAddress(QString addr); bool isSproutAddress(QString addr); - bool isZAddress(QString addr); bool isSyncing(); void setSyncing(bool syncing); @@ -40,7 +39,10 @@ public: bool getSaveZtxs(); void setSaveZtxs(bool save); - + + bool getAutoShield(); + void setAutoShield(bool allow); + bool getAllowCustomFees(); void setAllowCustomFees(bool allow); @@ -57,6 +59,9 @@ public: static void saveRestore(QDialog* d); + static bool isZAddress(QString addr); + static bool isTAddress(QString addr); + static QString getDecimalString(double amt); static QString getUSDFormat(double bal); static QString getZECDisplayFormat(double bal); diff --git a/src/settings.ui b/src/settings.ui index 17bb025..d5a540b 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -139,19 +139,6 @@ Options - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -169,6 +156,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -176,7 +176,14 @@ - + + + + Qt::Horizontal + + + + Qt::Vertical @@ -189,13 +196,6 @@ - - - - Qt::Horizontal - - - @@ -213,6 +213,30 @@ + + + + Normally, change from t-Addresses goes to another t-Address. Checking this option will send the change to your shielded Sapling address instead. Check this option to increase your privacy. + + + true + + + + + + + Shield change from t-Addresses to your Sapling addresses + + + + + + + + + + diff --git a/src/turnstile.cpp b/src/turnstile.cpp index 13e3d40..d34bbdc 100644 --- a/src/turnstile.cpp +++ b/src/turnstile.cpp @@ -304,7 +304,7 @@ void Turnstile::executeMigrationStep() { } // Create the Tx - auto tx = Tx{ nextStep->fromAddr, { to }, Settings::getMinerFee() }; + auto tx = Tx{ nextStep->fromAddr, { to }, Settings::getMinerFee(), false }; // And send it doSendTx(tx, [=] () { @@ -339,7 +339,7 @@ void Turnstile::executeMigrationStep() { QList to = { ToFields{ nextStep->destAddr, sendAmt, "", "" } }; // Create the Tx - auto tx = Tx{ nextStep->intTAddr, to, Settings::getMinerFee() }; + auto tx = Tx{ nextStep->intTAddr, to, Settings::getMinerFee(), false }; // And send it doSendTx(tx, [=] () {