Files
agrarian/src/qt/privacydialog.cpp
T
2026-04-28 16:50:31 +00:00

825 lines
33 KiB
C++

// Copyright (c) 2017-2019 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "privacydialog.h"
#include "ui_privacydialog.h"
#include "addressbookpage.h"
#include "addresstablemodel.h"
#include "bitcoinunits.h"
#include "coincontroldialog.h"
#include "libzerocoin/Denominations.h"
#include "optionsmodel.h"
#include "sendcoinsentry.h"
#include "walletmodel.h"
#include "coincontrol.h"
#include "zagrcontroldialog.h"
#include "spork.h"
#include "askpassphrasedialog.h"
#include <QClipboard>
#include <QSettings>
#include <utilmoneystr.h>
#include <QtWidgets>
#include <zagr/deterministicmint.h>
#include <zagr/accumulators.h>
PrivacyDialog::PrivacyDialog(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowCloseButtonHint),
ui(new Ui::PrivacyDialog),
walletModel(0),
currentBalance(-1),
fDenomsMinimized(true)
{
nDisplayUnit = 0; // just make sure it's not unitialized
ui->setupUi(this);
// "Spending 999999 zAGR ought to be enough for anybody." - Bill Gates, 2017
ui->zAGRpayAmount->setValidator( new QDoubleValidator(0.0, 21000000.0, 20, this) );
//ui->labelMintAmountValue->setValidator( new QIntValidator(0, 999999, this) ); // disable MINT
// Default texts for (mini-) coincontrol
//ui->labelCoinControlQuantity->setText (tr("Coins automatically selected")); // disable MINT
//ui->labelCoinControlAmount->setText (tr("Coins automatically selected")); // disable MINT
ui->labelzAGRSyncStatus->setText("(" + tr("out of sync") + ")");
// Sunken frame for minting messages
ui->TEMintStatus->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
ui->TEMintStatus->setLineWidth (2);
ui->TEMintStatus->setMidLineWidth (2);
ui->TEMintStatus->setPlainText(tr("Mint Status: Okay"));
// Coin Control signals
/* [disable MINT and coinControl]
connect(ui->pushButtonCoinControl, SIGNAL(clicked()), this, SLOT(coinControlButtonClicked()));
// Coin Control: clipboard actions
QAction* clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
QAction* clipboardAmountAction = new QAction(tr("Copy amount"), this);
connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity()));
connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAmount()));
ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
ui->labelCoinControlAmount->addAction(clipboardAmountAction);
*/
// Denomination labels
ui->labelzDenom1Text->setText(tr("Denom. with value <b>1</b>:"));
ui->labelzDenom2Text->setText(tr("Denom. with value <b>5</b>:"));
ui->labelzDenom3Text->setText(tr("Denom. with value <b>10</b>:"));
ui->labelzDenom4Text->setText(tr("Denom. with value <b>50</b>:"));
ui->labelzDenom5Text->setText(tr("Denom. with value <b>100</b>:"));
ui->labelzDenom6Text->setText(tr("Denom. with value <b>500</b>:"));
ui->labelzDenom7Text->setText(tr("Denom. with value <b>1000</b>:"));
ui->labelzDenom8Text->setText(tr("Denom. with value <b>5000</b>:"));
// AutoMint status
ui->label_AutoMintStatus->setText(tr("AutoMint Status:"));
// Global Supply labels
ui->labelZsupplyText1->setText(tr("Denom. <b>1</b>:"));
ui->labelZsupplyText5->setText(tr("Denom. <b>5</b>:"));
ui->labelZsupplyText10->setText(tr("Denom. <b>10</b>:"));
ui->labelZsupplyText50->setText(tr("Denom. <b>50</b>:"));
ui->labelZsupplyText100->setText(tr("Denom. <b>100</b>:"));
ui->labelZsupplyText500->setText(tr("Denom. <b>500</b>:"));
ui->labelZsupplyText1000->setText(tr("Denom. <b>1000</b>:"));
ui->labelZsupplyText5000->setText(tr("Denom. <b>5000</b>:"));
// Agrarian settings
QSettings settings;
if (!settings.contains("fMinimizeChange")){
fMinimizeChange = false;
settings.setValue("fMinimizeChange", fMinimizeChange);
}
else{
fMinimizeChange = settings.value("fMinimizeChange").toBool();
}
ui->checkBoxMinimizeChange->setChecked(fMinimizeChange);
// Start with displaying the "out of sync" warnings
showOutOfSyncWarning(true);
// Hide those placeholder elements needed for CoinControl interaction
ui->WarningLabel->hide(); // Explanatory text visible in QT-Creator
ui->dummyHideWidget->hide(); // Dummy widget with elements to hide
// Set labels/buttons depending on SPORK_16 status
updateSPORK16Status();
// init Denoms section
if(!settings.contains("fDenomsSectionMinimized"))
settings.setValue("fDenomsSectionMinimized", true);
minimizeDenomsSection(settings.value("fDenomsSectionMinimized").toBool());
ui->checkBoxMintChange->setVisible(false);
}
PrivacyDialog::~PrivacyDialog()
{
QSettings settings;
settings.setValue("fDenomsSectionMinimized", fDenomsMinimized);
delete ui;
}
void PrivacyDialog::setModel(WalletModel* walletModel)
{
this->walletModel = walletModel;
if (walletModel && walletModel->getOptionsModel()) {
// Keep up to date with wallet
setBalance(walletModel->getBalance(), walletModel->getUnconfirmedBalance(), walletModel->getImmatureBalance(),
walletModel->getZerocoinBalance(), walletModel->getUnconfirmedZerocoinBalance(), walletModel->getImmatureZerocoinBalance(),
walletModel->getWatchBalance(), walletModel->getWatchUnconfirmedBalance(), walletModel->getWatchImmatureBalance());
connect(walletModel, SIGNAL(balanceChanged(CAmount, CAmount, CAmount, CAmount, CAmount, CAmount, CAmount, CAmount, CAmount)), this,
SLOT(setBalance(CAmount, CAmount, CAmount, CAmount, CAmount, CAmount, CAmount, CAmount, CAmount)));
connect(walletModel->getOptionsModel(), SIGNAL(zeromintEnableChanged(bool)), this, SLOT(updateAutomintStatus()));
connect(walletModel->getOptionsModel(), SIGNAL(zeromintPercentageChanged(int)), this, SLOT(updateAutomintStatus()));
}
}
void PrivacyDialog::on_pasteButton_clicked()
{
// Paste text from clipboard into recipient field
ui->payTo->setText(QApplication::clipboard()->text());
}
void PrivacyDialog::on_addressBookButton_clicked()
{
if (!walletModel || !walletModel->getOptionsModel())
return;
AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
dlg.setModel(walletModel->getAddressTableModel());
if (dlg.exec()) {
ui->payTo->setText(dlg.getReturnValue());
ui->zAGRpayAmount->setFocus();
}
}
/* disable MINT
*
void PrivacyDialog::on_pushButtonMintzAGR_clicked()
{
if (!walletModel || !walletModel->getOptionsModel())
return;
if(GetAdjustedTime() > GetSporkValue(SPORK_16_ZEROCOIN_MAINTENANCE_MODE)) {
QMessageBox::information(this, tr("Mint Zerocoin"),
tr("zAGR is currently undergoing maintenance."), QMessageBox::Ok,
QMessageBox::Ok);
return;
}
// Reset message text
ui->TEMintStatus->setPlainText(tr("Mint Status: Okay"));
// Request unlock if wallet was locked or unlocked for mixing:
WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus();
if (encStatus == walletModel->Locked) {
WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Mint_zAGR, true));
if (!ctx.isValid()) {
// Unlock wallet was cancelled
ui->TEMintStatus->setPlainText(tr("Error: Your wallet is locked. Please enter the wallet passphrase first."));
return;
}
}
QString sAmount = ui->labelMintAmountValue->text();
CAmount nAmount = sAmount.toInt() * COIN;
// Minting amount must be > 0
if(nAmount <= 0){
ui->TEMintStatus->setPlainText(tr("Message: Enter an amount > 0."));
return;
}
ui->TEMintStatus->setPlainText(tr("Minting ") + ui->labelMintAmountValue->text() + " zAGR...");
ui->TEMintStatus->repaint ();
int64_t nTime = GetTimeMillis();
CWalletTx wtx;
vector<CDeterministicMint> vMints;
string strError = pwalletMain->MintZerocoin(nAmount, wtx, vMints, CoinControlDialog::coinControl);
// Return if something went wrong during minting
if (strError != ""){
ui->TEMintStatus->setPlainText(QString::fromStdString(strError));
return;
}
double fDuration = (double)(GetTimeMillis() - nTime)/1000.0;
// Minting successfully finished. Show some stats for entertainment.
QString strStatsHeader = tr("Successfully minted ") + ui->labelMintAmountValue->text() + tr(" zAGR in ") +
QString::number(fDuration) + tr(" sec. Used denominations:\n");
// Clear amount to avoid double spending when accidentally clicking twice
ui->labelMintAmountValue->setText ("0");
QString strStats = "";
ui->TEMintStatus->setPlainText(strStatsHeader);
for (CDeterministicMint dMint : vMints) {
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
strStats = strStats + QString::number(dMint.GetDenomination()) + " ";
ui->TEMintStatus->setPlainText(strStatsHeader + strStats);
ui->TEMintStatus->repaint ();
}
ui->TEMintStatus->verticalScrollBar()->setValue(ui->TEMintStatus->verticalScrollBar()->maximum()); // Automatically scroll to end of text
// Available balance isn't always updated, so force it.
setBalance(walletModel->getBalance(), walletModel->getUnconfirmedBalance(), walletModel->getImmatureBalance(),
walletModel->getZerocoinBalance(), walletModel->getUnconfirmedZerocoinBalance(), walletModel->getImmatureZerocoinBalance(),
walletModel->getWatchBalance(), walletModel->getWatchUnconfirmedBalance(), walletModel->getWatchImmatureBalance());
coinControlUpdateLabels();
return;
}
*/
void PrivacyDialog::on_pushButtonMintReset_clicked()
{
ui->TEMintStatus->setPlainText(tr("Starting ResetMintZerocoin: rescanning complete blockchain, this will need up to 30 minutes depending on your hardware.\nPlease be patient..."));
ui->TEMintStatus->repaint ();
int64_t nTime = GetTimeMillis();
string strResetMintResult = pwalletMain->ResetMintZerocoin();
double fDuration = (double)(GetTimeMillis() - nTime)/1000.0;
ui->TEMintStatus->setPlainText(QString::fromStdString(strResetMintResult) + tr("Duration: ") + QString::number(fDuration) + tr(" sec.\n"));
ui->TEMintStatus->repaint ();
ui->TEMintStatus->verticalScrollBar()->setValue(ui->TEMintStatus->verticalScrollBar()->maximum()); // Automatically scroll to end of text
return;
}
void PrivacyDialog::on_pushButtonSpentReset_clicked()
{
ui->TEMintStatus->setPlainText(tr("Starting ResetSpentZerocoin: "));
ui->TEMintStatus->repaint ();
int64_t nTime = GetTimeMillis();
string strResetSpentResult = pwalletMain->ResetSpentZerocoin();
double fDuration = (double)(GetTimeMillis() - nTime)/1000.0;
ui->TEMintStatus->setPlainText(QString::fromStdString(strResetSpentResult) + tr("Duration: ") + QString::number(fDuration) + tr(" sec.\n"));
ui->TEMintStatus->repaint ();
ui->TEMintStatus->verticalScrollBar()->setValue(ui->TEMintStatus->verticalScrollBar()->maximum()); // Automatically scroll to end of text
return;
}
void PrivacyDialog::on_pushButtonSpendzAGR_clicked()
{
if (!walletModel || !walletModel->getOptionsModel() || !pwalletMain)
return;
if(GetAdjustedTime() > GetSporkValue(SPORK_16_ZEROCOIN_MAINTENANCE_MODE)) {
QMessageBox::information(this, tr("Mint Zerocoin"),
tr("zAGR is currently undergoing maintenance."), QMessageBox::Ok, QMessageBox::Ok);
return;
}
// Request unlock if wallet was locked or unlocked for mixing:
WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus();
if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) {
WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Send_zAGR, true));
if (!ctx.isValid()) {
// Unlock wallet was cancelled
return;
}
// Wallet is unlocked now, sedn zAGR
sendzAGR();
return;
}
// Wallet already unlocked or not encrypted at all, send zAGR
sendzAGR();
}
void PrivacyDialog::on_pushButtonZPivControl_clicked()
{
if (!walletModel || !walletModel->getOptionsModel())
return;
ZPivControlDialog* zPivControl = new ZPivControlDialog(this);
zPivControl->setModel(walletModel);
zPivControl->exec();
}
void PrivacyDialog::setZPivControlLabels(int64_t nAmount, int nQuantity)
{
ui->labelzPivSelected_int->setText(QString::number(nAmount));
ui->labelQuantitySelected_int->setText(QString::number(nQuantity));
}
static inline int64_t roundint64(double d)
{
return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
}
void PrivacyDialog::sendzAGR()
{
QSettings settings;
// Handle 'Pay To' address options
CBitcoinAddress address(ui->payTo->text().toStdString());
if(ui->payTo->text().isEmpty()){
QMessageBox::information(this, tr("Spend Zerocoin"), tr("No 'Pay To' address provided, creating local payment"), QMessageBox::Ok, QMessageBox::Ok);
}
else{
if (!address.IsValid()) {
QMessageBox::warning(this, tr("Spend Zerocoin"), tr("Invalid Agrarian Address"), QMessageBox::Ok, QMessageBox::Ok);
ui->payTo->setFocus();
return;
}
}
// Double is allowed now
double dAmount = ui->zAGRpayAmount->text().toDouble();
CAmount nAmount = roundint64(dAmount* COIN);
// Check amount validity
if (!MoneyRange(nAmount) || nAmount <= 0.0) {
QMessageBox::warning(this, tr("Spend Zerocoin"), tr("Invalid Send Amount"), QMessageBox::Ok, QMessageBox::Ok);
ui->zAGRpayAmount->setFocus();
return;
}
// Convert change to zAGR
bool fMintChange = false;// ui->checkBoxMintChange->isChecked();
// Persist minimize change setting
fMinimizeChange = ui->checkBoxMinimizeChange->isChecked();
settings.setValue("fMinimizeChange", fMinimizeChange);
// Warn for additional fees if amount is not an integer and change as zAGR is requested
bool fWholeNumber = floor(dAmount) == dAmount;
double dzFee = 0.0;
if(!fWholeNumber)
dzFee = 1.0 - (dAmount - floor(dAmount));
if(!fWholeNumber && fMintChange){
QString strFeeWarning = "You've entered an amount with fractional digits and want the change to be converted to Zerocoin.<br /><br /><b>";
strFeeWarning += QString::number(dzFee, 'f', 8) + " AGR </b>will be added to the standard transaction fees!<br />";
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm additional Fees"),
strFeeWarning,
QMessageBox::Yes | QMessageBox::Cancel,
QMessageBox::Cancel);
if (retval != QMessageBox::Yes) {
// Sending canceled
ui->zAGRpayAmount->setFocus();
return;
}
}
// Spend confirmation message box
// Add address info if available
QString strAddressLabel = "";
if(!ui->payTo->text().isEmpty() && !ui->addAsLabel->text().isEmpty()){
strAddressLabel = "<br />(" + ui->addAsLabel->text() + ") ";
}
// General info
QString strQuestionString = tr("Are you sure you want to send?<br /><br />");
QString strAmount = "<b>" + QString::number(dAmount, 'f', 8) + " zAGR</b>";
QString strAddress = tr(" to address ") + QString::fromStdString(address.ToString()) + strAddressLabel + " <br />";
if(ui->payTo->text().isEmpty()){
// No address provided => send to local address
strAddress = tr(" to a newly generated (unused and therefore anonymous) local address <br />");
}
strQuestionString += strAmount + strAddress;
// Display message box
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
strQuestionString,
QMessageBox::Yes | QMessageBox::Cancel,
QMessageBox::Cancel);
if (retval != QMessageBox::Yes) {
// Sending canceled
return;
}
int64_t nTime = GetTimeMillis();
ui->TEMintStatus->setPlainText(tr("Spending Zerocoin.\nComputationally expensive, might need several minutes depending on your hardware.\nPlease be patient..."));
ui->TEMintStatus->repaint();
// use mints from zAGR selector if applicable
vector<CMintMeta> vMintsToFetch;
vector<CZerocoinMint> vMintsSelected;
if (!ZPivControlDialog::setSelectedMints.empty()) {
vMintsToFetch = ZPivControlDialog::GetSelectedMints();
for (auto& meta : vMintsToFetch) {
CZerocoinMint mint;
if (!pwalletMain->GetMint(meta.hashSerial, mint)) {
ui->TEMintStatus->setPlainText(tr("Failed to fetch mint associated with serial hash"));
ui->TEMintStatus->repaint();
return;
}
vMintsSelected.emplace_back(mint);
}
}
// Spend zAGR
CWalletTx wtxNew;
CZerocoinSpendReceipt receipt;
bool fSuccess = false;
if(ui->payTo->text().isEmpty()){
// Spend to newly generated local address
fSuccess = pwalletMain->SpendZerocoin(nAmount, wtxNew, receipt, vMintsSelected, fMintChange, fMinimizeChange);
}
else {
// Spend to supplied destination address
fSuccess = pwalletMain->SpendZerocoin(nAmount, wtxNew, receipt, vMintsSelected, fMintChange, fMinimizeChange, &address);
}
// Display errors during spend
if (!fSuccess) {
/*
int nNeededSpends = receipt.GetNeededSpends(); // Number of spends we would need for this transaction
const int nMaxSpends = Params().Zerocoin_MaxSpendsPerTransaction(); // Maximum possible spends for one zAGR transaction
if (nNeededSpends > nMaxSpends) {
QString strStatusMessage = tr("Too much inputs (") + QString::number(nNeededSpends, 10) + tr(") needed.\nMaximum allowed: ") + QString::number(nMaxSpends, 10);
strStatusMessage += tr("\nEither mint higher denominations (so fewer inputs are needed) or reduce the amount to spend.");
QMessageBox::warning(this, tr("Spend Zerocoin"), strStatusMessage.toStdString().c_str(), QMessageBox::Ok, QMessageBox::Ok);
ui->TEMintStatus->setPlainText(tr("Spend Zerocoin failed with status = ") +QString::number(receipt.GetStatus(), 10) + "\n" + "Message: " + QString::fromStdString(strStatusMessage.toStdString()));
}
else {
*/
QMessageBox::warning(this, tr("Spend Zerocoin"), receipt.GetStatusMessage().c_str(), QMessageBox::Ok, QMessageBox::Ok);
ui->TEMintStatus->setPlainText(tr("Spend Zerocoin failed with status = ") +QString::number(receipt.GetStatus(), 10) + "\n" + "Message: " + QString::fromStdString(receipt.GetStatusMessage()));
//}
ui->zAGRpayAmount->setFocus();
ui->TEMintStatus->repaint();
ui->TEMintStatus->verticalScrollBar()->setValue(ui->TEMintStatus->verticalScrollBar()->maximum()); // Automatically scroll to end of text
return;
}
if (walletModel && walletModel->getAddressTableModel()) {
// If zAGR was spent successfully update the addressbook with the label
std::string labelText = ui->addAsLabel->text().toStdString();
if (!labelText.empty())
walletModel->updateAddressBookLabels(address.Get(), labelText, "send");
else
walletModel->updateAddressBookLabels(address.Get(), "(no label)", "send");
}
// Clear zagr selector in case it was used
ZPivControlDialog::setSelectedMints.clear();
ui->labelzPivSelected_int->setText(QString("0"));
ui->labelQuantitySelected_int->setText(QString("0"));
// Some statistics for entertainment
QString strStats = "";
CAmount nValueIn = 0;
int nCount = 0;
for (CZerocoinSpend spend : receipt.GetSpends()) {
strStats += tr("zAGR Spend #: ") + QString::number(nCount) + ", ";
strStats += tr("denomination: ") + QString::number(spend.GetDenomination()) + ", ";
strStats += tr("serial: ") + spend.GetSerial().ToString().c_str() + "\n";
strStats += tr("Spend is 1 of : ") + QString::number(spend.GetMintCount()) + " mints in the accumulator\n";
nValueIn += libzerocoin::ZerocoinDenominationToAmount(spend.GetDenomination());
++nCount;
}
CAmount nValueOut = 0;
for (const CTxOut& txout: wtxNew.vout) {
strStats += tr("value out: ") + FormatMoney(txout.nValue).c_str() + " Piv, ";
nValueOut += txout.nValue;
strStats += tr("address: ");
CTxDestination dest;
if(txout.IsZerocoinMint())
strStats += tr("zAGR Mint");
else if(ExtractDestination(txout.scriptPubKey, dest))
strStats += tr(CBitcoinAddress(dest).ToString().c_str());
strStats += "\n";
}
double fDuration = (double)(GetTimeMillis() - nTime)/1000.0;
strStats += tr("Duration: ") + QString::number(fDuration) + tr(" sec.\n");
strStats += tr("Sending successful, return code: ") + QString::number(receipt.GetStatus()) + "\n";
QString strReturn;
strReturn += tr("txid: ") + wtxNew.GetHash().ToString().c_str() + "\n";
strReturn += tr("fee: ") + QString::fromStdString(FormatMoney(nValueIn-nValueOut)) + "\n";
strReturn += strStats;
// Clear amount to avoid double spending when accidentally clicking twice
ui->zAGRpayAmount->setText ("0");
ui->TEMintStatus->setPlainText(strReturn);
ui->TEMintStatus->repaint();
ui->TEMintStatus->verticalScrollBar()->setValue(ui->TEMintStatus->verticalScrollBar()->maximum()); // Automatically scroll to end of text
}
void PrivacyDialog::on_payTo_textChanged(const QString& address)
{
updateLabel(address);
}
/* DISABLE MINTs: no need for coinCointrol
// Coin Control: copy label "Quantity" to clipboard
void PrivacyDialog::coinControlClipboardQuantity()
{
GUIUtil::setClipboard(ui->labelCoinControlQuantity->text());
}
// Coin Control: copy label "Amount" to clipboard
void PrivacyDialog::coinControlClipboardAmount()
{
GUIUtil::setClipboard(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" ")));
}
// Coin Control: button inputs -> show actual coin control dialog
void PrivacyDialog::coinControlButtonClicked()
{
if (!walletModel || !walletModel->getOptionsModel())
return;
CoinControlDialog dlg;
dlg.setModel(walletModel);
dlg.exec();
coinControlUpdateLabels();
}
// Coin Control: update labels
void PrivacyDialog::coinControlUpdateLabels()
{
if (!walletModel || !walletModel->getOptionsModel() || !walletModel->getOptionsModel()->getCoinControlFeatures())
return;
// set pay amounts
CoinControlDialog::payAmounts.clear();
if (CoinControlDialog::coinControl->HasSelected()) {
// Actual coin control calculation
CoinControlDialog::updateLabels(walletModel, this);
} else {
ui->labelCoinControlQuantity->setText (tr("Coins automatically selected"));
ui->labelCoinControlAmount->setText (tr("Coins automatically selected"));
}
}
*/
void PrivacyDialog::on_pushButtonShowDenoms_clicked()
{
minimizeDenomsSection(false);
}
void PrivacyDialog::on_pushButtonHideDenoms_clicked()
{
minimizeDenomsSection(true);
}
void PrivacyDialog::minimizeDenomsSection(bool fMinimize)
{
if (fMinimize) {
ui->balanceSupplyFrame->show();
ui->verticalFrameRight->hide();
} else {
ui->balanceSupplyFrame->hide();
ui->verticalFrameRight->show();
}
fDenomsMinimized = fMinimize;
}
bool PrivacyDialog::updateLabel(const QString& address)
{
if (!walletModel)
return false;
// Fill in label from address book, if address has an associated label
QString associatedLabel = walletModel->getAddressTableModel()->labelForAddress(address);
if (!associatedLabel.isEmpty()) {
ui->addAsLabel->setText(associatedLabel);
return true;
}
return false;
}
void PrivacyDialog::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
const CAmount& zerocoinBalance, const CAmount& unconfirmedZerocoinBalance, const CAmount& immatureZerocoinBalance,
const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance)
{
currentBalance = balance;
currentUnconfirmedBalance = unconfirmedBalance;
currentImmatureBalance = immatureBalance;
currentZerocoinBalance = zerocoinBalance;
currentUnconfirmedZerocoinBalance = unconfirmedZerocoinBalance;
currentImmatureZerocoinBalance = immatureZerocoinBalance;
currentWatchOnlyBalance = watchOnlyBalance;
currentWatchUnconfBalance = watchUnconfBalance;
currentWatchImmatureBalance = watchImmatureBalance;
std::map<libzerocoin::CoinDenomination, CAmount> mapDenomBalances;
std::map<libzerocoin::CoinDenomination, int> mapUnconfirmed;
std::map<libzerocoin::CoinDenomination, int> mapImmature;
for (const auto& denom : libzerocoin::zerocoinDenomList){
mapDenomBalances.insert(make_pair(denom, 0));
mapUnconfirmed.insert(make_pair(denom, 0));
mapImmature.insert(make_pair(denom, 0));
}
std::vector<CMintMeta> vMints = pwalletMain->zagrTracker->GetMints(false);
map<libzerocoin::CoinDenomination, int> mapMaturityHeights = GetMintMaturityHeight();
for (auto& meta : vMints){
// All denominations
mapDenomBalances.at(meta.denom)++;
if (!meta.nHeight || chainActive.Height() - meta.nHeight <= Params().Zerocoin_MintRequiredConfirmations()) {
// All unconfirmed denominations
mapUnconfirmed.at(meta.denom)++;
} else {
if (meta.denom == libzerocoin::CoinDenomination::ZQ_ERROR) {
mapImmature.at(meta.denom)++;
} else if (meta.nHeight >= mapMaturityHeights.at(meta.denom)) {
mapImmature.at(meta.denom)++;
}
}
}
int64_t nCoins = 0;
int64_t nSumPerCoin = 0;
int64_t nUnconfirmed = 0;
int64_t nImmature = 0;
QString strDenomStats, strUnconfirmed = "";
for (const auto& denom : libzerocoin::zerocoinDenomList) {
nCoins = libzerocoin::ZerocoinDenominationToInt(denom);
nSumPerCoin = nCoins * mapDenomBalances.at(denom);
nUnconfirmed = mapUnconfirmed.at(denom);
nImmature = mapImmature.at(denom);
strUnconfirmed = "";
if (nUnconfirmed) {
strUnconfirmed += QString::number(nUnconfirmed) + QString(" unconf. ");
}
if(nImmature) {
strUnconfirmed += QString::number(nImmature) + QString(" immature ");
}
if(nImmature || nUnconfirmed) {
strUnconfirmed = QString("( ") + strUnconfirmed + QString(") ");
}
strDenomStats = strUnconfirmed + QString::number(mapDenomBalances.at(denom)) + " x " +
QString::number(nCoins) + " = <b>" +
QString::number(nSumPerCoin) + " zAGR </b>";
switch (nCoins) {
case libzerocoin::CoinDenomination::ZQ_ONE:
ui->labelzDenom1Amount->setText(strDenomStats);
break;
case libzerocoin::CoinDenomination::ZQ_FIVE:
ui->labelzDenom2Amount->setText(strDenomStats);
break;
case libzerocoin::CoinDenomination::ZQ_TEN:
ui->labelzDenom3Amount->setText(strDenomStats);
break;
case libzerocoin::CoinDenomination::ZQ_FIFTY:
ui->labelzDenom4Amount->setText(strDenomStats);
break;
case libzerocoin::CoinDenomination::ZQ_ONE_HUNDRED:
ui->labelzDenom5Amount->setText(strDenomStats);
break;
case libzerocoin::CoinDenomination::ZQ_FIVE_HUNDRED:
ui->labelzDenom6Amount->setText(strDenomStats);
break;
case libzerocoin::CoinDenomination::ZQ_ONE_THOUSAND:
ui->labelzDenom7Amount->setText(strDenomStats);
break;
case libzerocoin::CoinDenomination::ZQ_FIVE_THOUSAND:
ui->labelzDenom8Amount->setText(strDenomStats);
break;
default:
// Error Case: don't update display
break;
}
}
CAmount matureZerocoinBalance = zerocoinBalance - unconfirmedZerocoinBalance - immatureZerocoinBalance;
ui->labelzAvailableAmount->setText(QString::number(zerocoinBalance/COIN) + QString(" zAGR "));
ui->labelzAvailableAmount_2->setText(QString::number(matureZerocoinBalance/COIN) + QString(" zAGR "));
ui->labelzAvailableAmount_4->setText(QString::number(zerocoinBalance/COIN) + QString(" zAGR "));
// Display AutoMint status
updateAutomintStatus();
// Update/enable labels and buttons depending on the current SPORK_16 status
updateSPORK16Status();
// Display global supply
ui->labelZsupplyAmount->setText(QString::number(chainActive.Tip()->GetZerocoinSupply()/COIN) + QString(" <b>zAGR </b> "));
ui->labelZsupplyAmount_2->setText(QString::number(chainActive.Tip()->GetZerocoinSupply()/COIN) + QString(" <b>zAGR </b> "));
for (auto denom : libzerocoin::zerocoinDenomList) {
int64_t nSupply = chainActive.Tip()->mapZerocoinSupply.at(denom);
QString strSupply = QString::number(nSupply) + " x " + QString::number(denom) + " = <b>" +
QString::number(nSupply*denom) + " zAGR </b> ";
switch (denom) {
case libzerocoin::CoinDenomination::ZQ_ONE:
ui->labelZsupplyAmount1->setText(strSupply);
break;
case libzerocoin::CoinDenomination::ZQ_FIVE:
ui->labelZsupplyAmount5->setText(strSupply);
break;
case libzerocoin::CoinDenomination::ZQ_TEN:
ui->labelZsupplyAmount10->setText(strSupply);
break;
case libzerocoin::CoinDenomination::ZQ_FIFTY:
ui->labelZsupplyAmount50->setText(strSupply);
break;
case libzerocoin::CoinDenomination::ZQ_ONE_HUNDRED:
ui->labelZsupplyAmount100->setText(strSupply);
break;
case libzerocoin::CoinDenomination::ZQ_FIVE_HUNDRED:
ui->labelZsupplyAmount500->setText(strSupply);
break;
case libzerocoin::CoinDenomination::ZQ_ONE_THOUSAND:
ui->labelZsupplyAmount1000->setText(strSupply);
break;
case libzerocoin::CoinDenomination::ZQ_FIVE_THOUSAND:
ui->labelZsupplyAmount5000->setText(strSupply);
break;
default:
// Error Case: don't update display
break;
}
}
}
void PrivacyDialog::updateDisplayUnit()
{
if (walletModel && walletModel->getOptionsModel()) {
nDisplayUnit = walletModel->getOptionsModel()->getDisplayUnit();
if (currentBalance != -1)
setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance,
currentZerocoinBalance, currentUnconfirmedZerocoinBalance, currentImmatureZerocoinBalance,
currentWatchOnlyBalance, currentWatchUnconfBalance, currentWatchImmatureBalance);
}
}
void PrivacyDialog::showOutOfSyncWarning(bool fShow)
{
ui->labelzAGRSyncStatus->setVisible(fShow);
}
void PrivacyDialog::keyPressEvent(QKeyEvent* event)
{
if (event->key() != Qt::Key_Escape) // press esc -> ignore
{
this->QDialog::keyPressEvent(event);
} else {
event->ignore();
}
}
void PrivacyDialog::updateAutomintStatus()
{
QString strAutomintStatus = tr("AutoMint Status:");
if (pwalletMain->isZeromintEnabled ()) {
strAutomintStatus += tr(" <b>enabled</b>.");
}
else {
strAutomintStatus += tr(" <b>disabled</b>.");
}
strAutomintStatus += tr(" Configured target percentage: <b>") + QString::number(pwalletMain->getZeromintPercentage()) + "%</b>";
ui->label_AutoMintStatus->setText(strAutomintStatus);
}
void PrivacyDialog::updateSPORK16Status()
{
// Update/enable labels, buttons and tooltips depending on the current SPORK_16 status
//bool fButtonsEnabled = ui->pushButtonMintzAGR->isEnabled();
bool fButtonsEnabled = false;
bool fMaintenanceMode = GetAdjustedTime() > GetSporkValue(SPORK_16_ZEROCOIN_MAINTENANCE_MODE);
if (fMaintenanceMode && fButtonsEnabled) {
// Mint zAGR
//ui->pushButtonMintzAGR->setEnabled(false);
//ui->pushButtonMintzAGR->setToolTip(tr("zAGR is currently disabled due to maintenance."));
// Spend zAGR
ui->pushButtonSpendzAGR->setEnabled(false);
ui->pushButtonSpendzAGR->setToolTip(tr("zAGR is currently disabled due to maintenance."));
} else if (!fMaintenanceMode && !fButtonsEnabled) {
// Mint zAGR
//ui->pushButtonMintzAGR->setEnabled(true);
//ui->pushButtonMintzAGR->setToolTip(tr("PrivacyDialog", "Enter an amount of AGR to convert to zAGR", 0));
// Spend zAGR
ui->pushButtonSpendzAGR->setEnabled(true);
ui->pushButtonSpendzAGR->setToolTip(tr("Spend Zerocoin. Without 'Pay To:' address creates payments to yourself."));
}
}