From ca76dd08686dc9f1496384aecb688d5b2ac35a2b Mon Sep 17 00:00:00 2001 From: dustinface <35775977+xdustinface@users.noreply.github.com> Date: Tue, 4 Aug 2020 13:34:51 +0200 Subject: [PATCH 01/12] qt: Give PrivateSend separate instances of SendCoinsDialog + CCoinControl (#3625) Prior to this commit there are (imo) flaws in the behaviour of the PrivateSend tab. - If you enter an address, label, add a recipient, do whatever in the normal Send tab its also reflected in the PrivateSend tab - If you select fully mixed coins in the Send tab's CoinControl they are also selected in the PrivateSend tab if you switch over. - If you select non-fully mixed coins in the Send tab's CoinControl you get a warning when switching over to PrivateSend tab due to non-fully mixed coins selected in CoinControl. With giving the private send tab separate instances of `SendCoinsDialog` and `CCoinControl` they are independent from each other which just makes more sense imo and by doing this the points above are solved. I would say this just better reflects the actual behaviour of a tab. --- src/qt/coincontroldialog.cpp | 27 +++++++++++++++------------ src/qt/coincontroldialog.h | 8 ++++++++ src/qt/sendcoinsdialog.cpp | 29 ++++++++++++++--------------- src/qt/sendcoinsdialog.h | 6 ++++-- src/qt/walletview.cpp | 13 ++++++++----- src/qt/walletview.h | 1 + 6 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 9c545e1caf94..b240002510fa 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -34,6 +34,7 @@ QList CoinControlDialog::payAmounts; bool CoinControlDialog::fSubtractFeeFromAmount = false; +CoinControlDialog::Mode CoinControlDialog::mode{CoinControlDialog::Mode::NORMAL}; bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const { int column = treeWidget()->sortColumn(); @@ -514,16 +515,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) continue; } - // unselect non-fully-mixed, this can happen when users switch from Send to PrivateSend - if (coinControl()->IsUsingPrivateSend()) { - int nRounds = model->getRealOutpointPrivateSendRounds(outpt); - if (nRounds < privateSendClient.nPrivateSendRounds) { - coinControl()->UnSelect(outpt); - fUnselectedNonMixed = true; - continue; - } - } - // Quantity nQuantity++; @@ -669,10 +660,22 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) } } +void CoinControlDialog::usePrivateSend(bool fUsePrivateSend) +{ + CoinControlDialog::mode = fUsePrivateSend ? CoinControlDialog::Mode::PRIVATESEND : CoinControlDialog::Mode::NORMAL; +} + CCoinControl* CoinControlDialog::coinControl() { - static CCoinControl coin_control; - return &coin_control; + if (CoinControlDialog::mode == CoinControlDialog::Mode::NORMAL) { + static CCoinControl coinControlNormal; + coinControlNormal.UsePrivateSend(false); + return &coinControlNormal; + } else { + static CCoinControl coinControlPrivateSend; + coinControlPrivateSend.UsePrivateSend(true); + return &coinControlPrivateSend; + } } void CoinControlDialog::updateView() diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 30c3b5bcfbd2..6e679127f85a 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -53,6 +53,7 @@ class CoinControlDialog : public QDialog static QList payAmounts; static CCoinControl *coinControl(); static bool fSubtractFeeFromAmount; + static void usePrivateSend(bool fUsePrivateSend); private: Ui::CoinControlDialog *ui; @@ -83,6 +84,13 @@ class CoinControlDialog : public QDialog }; friend class CCoinControlWidgetItem; + enum class Mode { + NORMAL, + PRIVATESEND, + }; + + static CoinControlDialog::Mode mode; + private Q_SLOTS: void showMenu(const QPoint &); void copyAmount(); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 670c3f3efc5b..18e4e58d1e07 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -51,14 +51,14 @@ int getIndexForConfTarget(int target) { return confTargets.size() - 1; } -SendCoinsDialog::SendCoinsDialog(QWidget* parent) : +SendCoinsDialog::SendCoinsDialog(bool _fPrivateSend, QWidget* parent) : QDialog(parent), ui(new Ui::SendCoinsDialog), clientModel(0), model(0), fNewRecipientAllowed(true), fFeeMinimized(true), - fPrivateSend(false) + fPrivateSend(_fPrivateSend) { ui->setupUi(this); @@ -155,6 +155,14 @@ SendCoinsDialog::SendCoinsDialog(QWidget* parent) : ui->customFee->setValue(settings.value("nTransactionFee").toLongLong()); ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool()); minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool()); + + if (fPrivateSend) { + ui->sendButton->setText("PrivateS&end"); + ui->sendButton->setToolTip("Confirm the PrivateSend action"); + } else { + ui->sendButton->setText("S&end"); + ui->sendButton->setToolTip("Confirm the send action"); + } } void SendCoinsDialog::setClientModel(ClientModel *_clientModel) @@ -629,7 +637,6 @@ void SendCoinsDialog::updateDisplayUnit() { setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance(), model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); - CoinControlDialog::coinControl()->UsePrivateSend(fPrivateSend); coinControlUpdateLabels(); ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit()); updateMinFeeLabel(); @@ -788,19 +795,11 @@ void SendCoinsDialog::updateCoinControlState(CCoinControl& ctrl) ctrl.m_confirm_target = getConfTargetForIndex(ui->confTargetSelector->currentIndex()); } -void SendCoinsDialog::setPrivateSend(bool privateSend) +void SendCoinsDialog::showEvent(QShowEvent* event) { - if (fPrivateSend != privateSend) { - fPrivateSend = privateSend; - coinControlUpdateLabels(); - updateDisplayUnit(); - if (privateSend) { - ui->sendButton->setText("PrivateS&end"); - ui->sendButton->setToolTip("Confirm the PrivateSend action"); - } else { - ui->sendButton->setText("S&end"); - ui->sendButton->setToolTip("Confirm the send action"); - } + QWidget::showEvent(event); + if (!event->spontaneous()) { + CoinControlDialog::usePrivateSend(fPrivateSend); } } diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 514057afa87f..58c4c620c032 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -32,7 +33,7 @@ class SendCoinsDialog : public QDialog Q_OBJECT public: - explicit SendCoinsDialog(QWidget* parent = 0); + explicit SendCoinsDialog(bool fPrivateSend = false, QWidget* parent = 0); ~SendCoinsDialog(); void setClientModel(ClientModel *clientModel); @@ -45,7 +46,6 @@ class SendCoinsDialog : public QDialog void setAddress(const QString &address); void pasteEntry(const SendCoinsRecipient &rv); bool handlePaymentRequest(const SendCoinsRecipient &recipient); - void setPrivateSend(bool privateSend); public Q_SLOTS: void clear(); @@ -74,6 +74,8 @@ public Q_SLOTS: // Update the passed in CCoinControl with state from the GUI void updateCoinControlState(CCoinControl& ctrl); + void showEvent(QShowEvent* event); + private Q_SLOTS: void on_sendButton_clicked(); void on_buttonChooseFee_clicked(); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 40585b7ae761..c0ad8e424a55 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -71,6 +71,7 @@ WalletView::WalletView(QWidget* parent) : receiveCoinsPage = new ReceiveCoinsDialog(); sendCoinsPage = new SendCoinsDialog(); + privateSendCoinsPage = new SendCoinsDialog(true); usedSendingAddressesPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); usedReceivingAddressesPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); @@ -79,6 +80,7 @@ WalletView::WalletView(QWidget* parent) : addWidget(transactionsPage); addWidget(receiveCoinsPage); addWidget(sendCoinsPage); + addWidget(privateSendCoinsPage); QSettings settings; if (settings.value("fShowMasternodesTab").toBool()) { @@ -99,8 +101,9 @@ WalletView::WalletView(QWidget* parent) : // Clicking on "Export" allows to export the transaction list connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked())); - // Pass through messages from sendCoinsPage + // Pass through messages from SendCoinsDialog connect(sendCoinsPage, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); + connect(privateSendCoinsPage, SIGNAL(message(QString, QString, unsigned int)), this, SIGNAL(message(QString, QString, unsigned int))); // Pass through messages from transactionView connect(transactionView, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); @@ -139,6 +142,7 @@ void WalletView::setClientModel(ClientModel *_clientModel) overviewPage->setClientModel(_clientModel); sendCoinsPage->setClientModel(_clientModel); + privateSendCoinsPage->setClientModel(_clientModel); QSettings settings; if (settings.value("fShowMasternodesTab").toBool()) { masternodeListPage->setClientModel(_clientModel); @@ -158,6 +162,7 @@ void WalletView::setWalletModel(WalletModel *_walletModel) } receiveCoinsPage->setModel(_walletModel); sendCoinsPage->setModel(_walletModel); + privateSendCoinsPage->setModel(_walletModel); usedReceivingAddressesPage->setModel(_walletModel ? _walletModel->getAddressTableModel() : nullptr); usedSendingAddressesPage->setModel(_walletModel ? _walletModel->getAddressTableModel() : nullptr); @@ -239,7 +244,6 @@ void WalletView::gotoReceiveCoinsPage() void WalletView::gotoSendCoinsPage(QString addr) { - sendCoinsPage->setPrivateSend(false); setCurrentWidget(sendCoinsPage); if (!addr.isEmpty()) { @@ -249,11 +253,10 @@ void WalletView::gotoSendCoinsPage(QString addr) void WalletView::gotoPrivateSendCoinsPage(QString addr) { - sendCoinsPage->setPrivateSend(true); - setCurrentWidget(sendCoinsPage); + setCurrentWidget(privateSendCoinsPage); if (!addr.isEmpty()) - sendCoinsPage->setAddress(addr); + privateSendCoinsPage->setAddress(addr); } void WalletView::gotoSignMessageTab(QString addr) diff --git a/src/qt/walletview.h b/src/qt/walletview.h index da077a1e966e..38f4d224dea6 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -63,6 +63,7 @@ class WalletView : public QStackedWidget QWidget *transactionsPage; ReceiveCoinsDialog *receiveCoinsPage; SendCoinsDialog *sendCoinsPage; + SendCoinsDialog* privateSendCoinsPage; AddressBookPage *usedSendingAddressesPage; AddressBookPage *usedReceivingAddressesPage; MasternodeList *masternodeListPage; From 60d298376b41965e51dfdfc035eb61920e746c92 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 28 Jul 2020 23:50:23 +0300 Subject: [PATCH 02/12] Fix crash on splash screen when wallet fails to load (#3629) --- src/wallet/wallet.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1cebe35ffbf1..4c6623ec25e0 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4176,8 +4176,6 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet) if (nLoadWalletRet != DB_LOAD_OK) return nLoadWalletRet; - uiInterface.LoadWallet(this); - return DB_LOAD_OK; } @@ -5232,6 +5230,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& InitError(_("Failed to rescan the wallet during initialization")); return nullptr; } + uiInterface.LoadWallet(walletInstance); // TODO: move it up when backporting 13063 walletInstance->ScanForWalletTransactions(pindexRescan, nullptr, reserver, true); } LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart); From 604d6a422564586191501b6937303ae2f2d5f3d7 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 10 Aug 2020 00:37:08 +0300 Subject: [PATCH 03/12] Fix some translation issues (#3656) * Avoid translating "PrivateSend" * Make some strings translatable --- src/qt/bitcoingui.cpp | 2 +- src/qt/masternodelist.cpp | 6 +++--- src/qt/overviewpage.cpp | 12 ++++++------ src/qt/sendcoinsdialog.cpp | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/transactionview.cpp | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 4327e9aac253..bf484e10942f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -326,7 +326,7 @@ void BitcoinGUI::createActions() sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip()); privateSendCoinsAction = new QToolButton(this); - privateSendCoinsAction->setText(tr("&PrivateSend")); + privateSendCoinsAction->setText("&PrivateSend"); privateSendCoinsAction->setStatusTip(tr("PrivateSend coins to a Dash address")); privateSendCoinsAction->setToolTip(privateSendCoinsAction->statusTip()); privateSendCoinsAction->setCheckable(true); diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index 4b33289da20e..b32ec17a9ba9 100644 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -142,7 +142,7 @@ void MasternodeList::updateDIP3ListScheduled() // after filter was last changed unless we want to force the update. if (fFilterUpdatedDIP3) { int64_t nSecondsToWait = nTimeFilterUpdatedDIP3 - GetTime() + MASTERNODELIST_FILTER_COOLDOWN_SECONDS; - ui->countLabelDIP3->setText(QString::fromStdString(strprintf("Please wait... %d", nSecondsToWait))); + ui->countLabelDIP3->setText(tr("Please wait... %1").arg(nSecondsToWait)); if (nSecondsToWait <= 0) { updateDIP3List(); @@ -184,7 +184,7 @@ void MasternodeList::updateDIP3List() LOCK(cs_dip3list); QString strToFilter; - ui->countLabelDIP3->setText("Updating..."); + ui->countLabelDIP3->setText(tr("Updating...")); ui->tableWidgetMasternodesDIP3->setSortingEnabled(false); ui->tableWidgetMasternodesDIP3->clearContents(); ui->tableWidgetMasternodesDIP3->setRowCount(0); @@ -304,7 +304,7 @@ void MasternodeList::on_filterLineEditDIP3_textChanged(const QString& strFilterI strCurrentFilterDIP3 = strFilterIn; nTimeFilterUpdatedDIP3 = GetTime(); fFilterUpdatedDIP3 = true; - ui->countLabelDIP3->setText(QString::fromStdString(strprintf("Please wait... %d", MASTERNODELIST_FILTER_COOLDOWN_SECONDS))); + ui->countLabelDIP3->setText(tr("Please wait... %1").arg(MASTERNODELIST_FILTER_COOLDOWN_SECONDS)); } void MasternodeList::on_checkBoxMyMasternodesOnly_stateChanged(int state) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index dd4d5010d2ac..794302048dc5 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -526,7 +526,7 @@ void OverviewPage::privateSendStatus(bool fForce) tr("Note: You can turn this message off in options."); ui->labelPrivateSendEnabled->setToolTip(strWarn); LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- Very low number of keys left since last automatic backup, warning user and trying to create new backup...\n"); - QMessageBox::warning(this, tr("PrivateSend"), strWarn, QMessageBox::Ok, QMessageBox::Ok); + QMessageBox::warning(this, "PrivateSend", strWarn, QMessageBox::Ok, QMessageBox::Ok); } else { LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- Very low number of keys left since last automatic backup, skipping warning and trying to create new backup...\n"); } @@ -538,7 +538,7 @@ void OverviewPage::privateSendStatus(bool fForce) // It's still more or less safe to continue but warn user anyway LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- WARNING! Something went wrong on automatic backup: %s\n", strBackupWarning.toStdString()); - QMessageBox::warning(this, tr("PrivateSend"), + QMessageBox::warning(this, "PrivateSend", tr("WARNING! Something went wrong on automatic backup") + ":

" + strBackupWarning, QMessageBox::Ok, QMessageBox::Ok); } @@ -546,7 +546,7 @@ void OverviewPage::privateSendStatus(bool fForce) // Things are really broken, warn user and stop mixing immediately LogPrint(BCLog::PRIVATESEND, "OverviewPage::privateSendStatus -- ERROR! Failed to create automatic backup: %s\n", strBackupError.toStdString()); - QMessageBox::warning(this, tr("PrivateSend"), + QMessageBox::warning(this, "PrivateSend", tr("ERROR! Failed to create automatic backup") + ":

" + strBackupError + "
" + tr("Mixing is disabled, please close your wallet and fix the issue!"), QMessageBox::Ok, QMessageBox::Ok); @@ -592,7 +592,7 @@ void OverviewPage::togglePrivateSend(){ // Popup some information on first mixing QString hasMixed = settings.value("hasMixed").toString(); if(hasMixed.isEmpty()){ - QMessageBox::information(this, tr("PrivateSend"), + QMessageBox::information(this, "PrivateSend", tr("If you don't want to see internal PrivateSend fees/transactions select \"Most Common\" as Type on the \"Transactions\" tab."), QMessageBox::Ok, QMessageBox::Ok); settings.setValue("hasMixed", "hasMixed"); @@ -601,7 +601,7 @@ void OverviewPage::togglePrivateSend(){ const CAmount nMinAmount = CPrivateSend::GetSmallestDenomination() + CPrivateSend::GetMaxCollateralAmount(); if(currentBalance < nMinAmount){ QString strMinAmount(BitcoinUnits::formatWithUnit(nDisplayUnit, nMinAmount)); - QMessageBox::warning(this, tr("PrivateSend"), + QMessageBox::warning(this, "PrivateSend", tr("PrivateSend requires at least %1 to use.").arg(strMinAmount), QMessageBox::Ok, QMessageBox::Ok); return; @@ -615,7 +615,7 @@ void OverviewPage::togglePrivateSend(){ { //unlock was cancelled privateSendClient.nCachedNumBlocks = std::numeric_limits::max(); - QMessageBox::warning(this, tr("PrivateSend"), + QMessageBox::warning(this, "PrivateSend", tr("Wallet is locked and user declined to unlock. Disabling PrivateSend."), QMessageBox::Ok, QMessageBox::Ok); LogPrint(BCLog::PRIVATESEND, "OverviewPage::togglePrivateSend -- Wallet is locked and user declined to unlock. Disabling PrivateSend.\n"); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 18e4e58d1e07..3e8cd461d5a3 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -160,7 +160,7 @@ SendCoinsDialog::SendCoinsDialog(bool _fPrivateSend, QWidget* parent) : ui->sendButton->setText("PrivateS&end"); ui->sendButton->setToolTip("Confirm the PrivateSend action"); } else { - ui->sendButton->setText("S&end"); + ui->sendButton->setText(tr("S&end")); ui->sendButton->setToolTip("Confirm the send action"); } } diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 6d8a7243d486..9990da5f9118 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -421,7 +421,7 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const case TransactionRecord::PrivateSendCreateDenominations: return tr("PrivateSend Create Denominations"); case TransactionRecord::PrivateSend: - return tr("PrivateSend"); + return "PrivateSend"; default: return QString(); diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 831d02e46bbc..090ceb00ab73 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -89,7 +89,7 @@ TransactionView::TransactionView(QWidget* parent) : TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther)); typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) | TransactionFilterProxy::TYPE(TransactionRecord::SendToOther)); - typeWidget->addItem(tr("PrivateSend"), TransactionFilterProxy::TYPE(TransactionRecord::PrivateSend)); + typeWidget->addItem("PrivateSend", TransactionFilterProxy::TYPE(TransactionRecord::PrivateSend)); typeWidget->addItem(tr("PrivateSend Make Collateral Inputs"), TransactionFilterProxy::TYPE(TransactionRecord::PrivateSendMakeCollaterals)); typeWidget->addItem(tr("PrivateSend Create Denominations"), TransactionFilterProxy::TYPE(TransactionRecord::PrivateSendCreateDenominations)); typeWidget->addItem(tr("PrivateSend Denominate"), TransactionFilterProxy::TYPE(TransactionRecord::PrivateSendDenominate)); From f9bf42cb90a9ae92b3e54cd3522b2c49640380a1 Mon Sep 17 00:00:00 2001 From: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com> Date: Sun, 30 Aug 2020 14:22:21 +0000 Subject: [PATCH 04/12] Harden spork6 logic then remove spork6 (#3662) * Harden Spork6 Spork6 was previously activated on testnet, but we then developed an alternative fix for the issue and never activated spork6 on mainnet. At this point, Spork6 will not be activated on mainnet. As such, it makes sense to harden Spork6 and ensure that spork6 will never be activated on mainnet. So, we just change from checking Spork6 to checking if we are on testnet. If we are on testnet, use spork6 logic, else don't. Signed-off-by: pasta * remove now unused SPORK_6_NEW_SIGS Signed-off-by: pasta * force fSporkSixActive to be correct, otherwise return Signed-off-by: pasta * Harden spork6 even more * Add TODO in chainparams as a reminder to drop all spork6 related code on next testnet reset Co-authored-by: UdjinM6 --- src/chainparams.cpp | 2 +- src/governance/governance-vote.cpp | 19 +++------ src/spork.cpp | 65 ++++++++++++------------------ src/spork.h | 7 ++-- 4 files changed, 35 insertions(+), 58 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index e0b375df129c..d80a6ec8c4c9 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -490,7 +490,7 @@ class CTestNetParams : public CChainParams { consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowNoRetargeting = false; consensus.nPowKGWHeight = 4002; // nPowKGWHeight >= nPowDGWHeight means "no KGW" - consensus.nPowDGWHeight = 4002; + consensus.nPowDGWHeight = 4002; // TODO: make sure to drop all spork6 related code on next testnet reset consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; diff --git a/src/governance/governance-vote.cpp b/src/governance/governance-vote.cpp index f07037d70218..ea17200539b0 100644 --- a/src/governance/governance-vote.cpp +++ b/src/governance/governance-vote.cpp @@ -164,7 +164,8 @@ bool CGovernanceVote::Sign(const CKey& key, const CKeyID& keyID) { std::string strError; - if (sporkManager.IsSporkActive(SPORK_6_NEW_SIGS)) { + // Harden Spork6 so that it is active on testnet and no other networks + if (Params().NetworkIDString() == CBaseChainParams::TESTNET) { uint256 hash = GetSignatureHash(); if (!CHashSigner::SignHash(hash, key, vchSig)) { @@ -198,21 +199,13 @@ bool CGovernanceVote::CheckSignature(const CKeyID& keyID) const { std::string strError; - if (sporkManager.IsSporkActive(SPORK_6_NEW_SIGS)) { + // Harden Spork6 so that it is active on testnet and no other networks + if (Params().NetworkIDString() == CBaseChainParams::TESTNET) { uint256 hash = GetSignatureHash(); if (!CHashSigner::VerifyHash(hash, keyID, vchSig, strError)) { - // could be a signature in old format - std::string strMessage = masternodeOutpoint.ToStringShort() + "|" + nParentHash.ToString() + "|" + - std::to_string(nVoteSignal) + "|" + - std::to_string(nVoteOutcome) + "|" + - std::to_string(nTime); - - if (!CMessageSigner::VerifyMessage(keyID, vchSig, strMessage, strError)) { - // nope, not in old format either - LogPrint(BCLog::GOBJECT, "CGovernanceVote::IsValid -- VerifyMessage() failed, error: %s\n", strError); - return false; - } + LogPrint(BCLog::GOBJECT, "CGovernanceVote::IsValid -- VerifyHash() failed, error: %s\n", strError); + return false; } } else { std::string strMessage = masternodeOutpoint.ToStringShort() + "|" + nParentHash.ToString() + "|" + diff --git a/src/spork.cpp b/src/spork.cpp index 16c41d6d0429..0cd515ebba2a 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -19,7 +19,6 @@ const std::string CSporkManager::SERIALIZATION_VERSION_STRING = "CSporkManager-V std::vector sporkDefs = { MAKE_SPORK_DEF(SPORK_2_INSTANTSEND_ENABLED, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_3_INSTANTSEND_BLOCK_FILTERING, 4070908800ULL), // OFF - MAKE_SPORK_DEF(SPORK_6_NEW_SIGS, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_9_SUPERBLOCKS_ENABLED, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_17_QUORUM_DKG_ENABLED, 4070908800ULL), // OFF MAKE_SPORK_DEF(SPORK_19_CHAINLOCKS_ENABLED, 4070908800ULL), // OFF @@ -81,12 +80,10 @@ void CSporkManager::CheckAndRemove() mapSporksByHash.erase(itSignerPair->second.GetHash()); continue; } - if (!itSignerPair->second.CheckSignature(itSignerPair->first, false)) { - if (!itSignerPair->second.CheckSignature(itSignerPair->first, true)) { - mapSporksByHash.erase(itSignerPair->second.GetHash()); - itActive->second.erase(itSignerPair++); - continue; - } + if (!itSignerPair->second.CheckSignature(itSignerPair->first)) { + mapSporksByHash.erase(itSignerPair->second.GetHash()); + itActive->second.erase(itSignerPair++); + continue; } ++itSignerPair; } @@ -101,8 +98,7 @@ void CSporkManager::CheckAndRemove() while (itByHash != mapSporksByHash.end()) { bool found = false; for (const auto& signer: setSporkPubKeyIDs) { - if (itByHash->second.CheckSignature(signer, false) || - itByHash->second.CheckSignature(signer, true)) { + if (itByHash->second.CheckSignature(signer)) { found = true; break; } @@ -141,17 +137,12 @@ void CSporkManager::ProcessSpork(CNode* pfrom, const std::string& strCommand, CD } CKeyID keyIDSigner; - bool fSpork6IsActive = IsSporkActive(SPORK_6_NEW_SIGS); - if (!spork.GetSignerKeyID(keyIDSigner, fSpork6IsActive) || !setSporkPubKeyIDs.count(keyIDSigner)) { - // Note: unlike for other messages we have to check for new format even with SPORK_6_NEW_SIGS - // inactive because SPORK_6_NEW_SIGS default is OFF and it is not the first spork to sync - // (and even if it would, spork order can't be guaranteed anyway). - if (!spork.GetSignerKeyID(keyIDSigner, !fSpork6IsActive) || !setSporkPubKeyIDs.count(keyIDSigner)) { - LOCK(cs_main); - LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: invalid signature\n"); - Misbehaving(pfrom->GetId(), 100); - return; - } + + if (!spork.GetSignerKeyID(keyIDSigner) || !setSporkPubKeyIDs.count(keyIDSigner)) { + LOCK(cs_main); + LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: invalid signature\n"); + Misbehaving(pfrom->GetId(), 100); + return; } { @@ -197,14 +188,13 @@ bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& conn LOCK(cs); - bool fSpork6IsActive = IsSporkActive(SPORK_6_NEW_SIGS); - if (!spork.Sign(sporkPrivKey, fSpork6IsActive)) { + if (!spork.Sign(sporkPrivKey)) { LogPrintf("CSporkManager::%s -- ERROR: signing failed for spork %d\n", __func__, nSporkID); return false; } CKeyID keyIDSigner; - if (!spork.GetSignerKeyID(keyIDSigner, fSpork6IsActive) || !setSporkPubKeyIDs.count(keyIDSigner)) { + if (!spork.GetSignerKeyID(keyIDSigner) || !setSporkPubKeyIDs.count(keyIDSigner)) { LogPrintf("CSporkManager::UpdateSpork: failed to find keyid for private key\n"); return false; } @@ -314,7 +304,7 @@ bool CSporkManager::SetPrivKey(const std::string& strPrivKey) } CSporkMessage spork; - if (!spork.Sign(key, IsSporkActive(SPORK_6_NEW_SIGS))) { + if (!spork.Sign(key)) { LogPrintf("CSporkManager::SetPrivKey -- Test signing failed\n"); return false; } @@ -346,7 +336,7 @@ uint256 CSporkMessage::GetSignatureHash() const return s.GetHash(); } -bool CSporkMessage::Sign(const CKey& key, bool fSporkSixActive) +bool CSporkMessage::Sign(const CKey& key) { if (!key.IsValid()) { LogPrintf("CSporkMessage::Sign -- signing key is not valid\n"); @@ -356,7 +346,8 @@ bool CSporkMessage::Sign(const CKey& key, bool fSporkSixActive) CKeyID pubKeyId = key.GetPubKey().GetID(); std::string strError = ""; - if (fSporkSixActive) { + // Harden Spork6 so that it is active on testnet and no other networks + if (Params().NetworkIDString() == CBaseChainParams::TESTNET) { uint256 hash = GetSignatureHash(); if(!CHashSigner::SignHash(hash, key, vchSig)) { @@ -385,16 +376,15 @@ bool CSporkMessage::Sign(const CKey& key, bool fSporkSixActive) return true; } -bool CSporkMessage::CheckSignature(const CKeyID& pubKeyId, bool fSporkSixActive) const +bool CSporkMessage::CheckSignature(const CKeyID& pubKeyId) const { std::string strError = ""; - if (fSporkSixActive) { + // Harden Spork6 so that it is active on testnet and no other networks + if (Params().NetworkIDString() == CBaseChainParams::TESTNET) { uint256 hash = GetSignatureHash(); if (!CHashSigner::VerifyHash(hash, pubKeyId, vchSig, strError)) { - // Note: unlike for many other messages when SPORK_6_NEW_SIGS is ON sporks with sigs in old format - // and newer timestamps should not be accepted, so if we failed here - that's it LogPrint(BCLog::SPORK, "CSporkMessage::CheckSignature -- VerifyHash() failed, error: %s\n", strError); return false; } @@ -402,24 +392,19 @@ bool CSporkMessage::CheckSignature(const CKeyID& pubKeyId, bool fSporkSixActive) std::string strMessage = std::to_string(nSporkID) + std::to_string(nValue) + std::to_string(nTimeSigned); if (!CMessageSigner::VerifyMessage(pubKeyId, vchSig, strMessage, strError)){ - // Note: unlike for other messages we have to check for new format even with SPORK_6_NEW_SIGS - // inactive because SPORK_6_NEW_SIGS default is OFF and it is not the first spork to sync - // (and even if it would, spork order can't be guaranteed anyway). - uint256 hash = GetSignatureHash(); - if (!CHashSigner::VerifyHash(hash, pubKeyId, vchSig, strError)) { - LogPrint(BCLog::SPORK, "CSporkMessage::CheckSignature -- VerifyHash() failed, error: %s\n", strError); - return false; - } + LogPrint(BCLog::SPORK, "CSporkMessage::CheckSignature -- VerifyMessage() failed, error: %s\n", strError); + return false; } } return true; } -bool CSporkMessage::GetSignerKeyID(CKeyID &retKeyidSporkSigner, bool fSporkSixActive) +bool CSporkMessage::GetSignerKeyID(CKeyID &retKeyidSporkSigner) { CPubKey pubkeyFromSig; - if (fSporkSixActive) { + // Harden Spork6 so that it is active on testnet and no other networks + if (Params().NetworkIDString() == CBaseChainParams::TESTNET) { if (!pubkeyFromSig.RecoverCompact(GetSignatureHash(), vchSig)) { return false; } diff --git a/src/spork.h b/src/spork.h index e5142f3b6ad0..feae107b56c5 100644 --- a/src/spork.h +++ b/src/spork.h @@ -23,7 +23,6 @@ class CSporkManager; enum SporkId : int32_t { SPORK_2_INSTANTSEND_ENABLED = 10001, SPORK_3_INSTANTSEND_BLOCK_FILTERING = 10002, - SPORK_6_NEW_SIGS = 10005, SPORK_9_SUPERBLOCKS_ENABLED = 10008, SPORK_17_QUORUM_DKG_ENABLED = 10016, SPORK_19_CHAINLOCKS_ENABLED = 10018, @@ -121,13 +120,13 @@ class CSporkMessage /** * Sign will sign the spork message with the given key. */ - bool Sign(const CKey& key, bool fSporkSixActive); + bool Sign(const CKey& key); /** * CheckSignature will ensure the spork signature matches the provided public * key hash. */ - bool CheckSignature(const CKeyID& pubKeyId, bool fSporkSixActive) const; + bool CheckSignature(const CKeyID& pubKeyId) const; /** * GetSignerKeyID is used to recover the spork address of the key used to @@ -136,7 +135,7 @@ class CSporkMessage * This method was introduced along with the multi-signer sporks feature, * in order to identify which spork key signed this message. */ - bool GetSignerKeyID(CKeyID& retKeyidSporkSigner, bool fSporkSixActive); + bool GetSignerKeyID(CKeyID& retKeyidSporkSigner); /** * Relay is used to send this spork message to other peers. From b1a35b2d32ec20ce57a688f3b75fa3b53f3dbad6 Mon Sep 17 00:00:00 2001 From: dustinface <35775977+xdustinface@users.noreply.github.com> Date: Mon, 24 Aug 2020 17:16:42 +0200 Subject: [PATCH 05/12] Merge #13007: test: Fix dangling wallet pointer in vpwallets (#3666) * test: Fix importwallet_rescan test The wallet should be removed after the dumpwallet() call otherwise it may lead to unepexted behaviour in other wallet tests since the wallet stays in vpwallets then. * tests: Change where RemoveWallet call is to be more in line with upstream Signed-off-by: pasta Co-authored-by: pasta --- src/wallet/test/wallet_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 6892132ba8dd..efe7db34eb60 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -479,6 +479,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) request.params.push_back((pathTemp / "wallet.backup").string()); AddWallet(&wallet); ::dumpwallet(request); + RemoveWallet(&wallet); } // Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME @@ -491,6 +492,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) request.params.push_back((pathTemp / "wallet.backup").string()); AddWallet(&wallet); ::importwallet(request); + RemoveWallet(&wallet); LOCK(wallet.cs_wallet); BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3); @@ -500,7 +502,6 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) bool expected = i >= 100; BOOST_CHECK_EQUAL(found, expected); } - RemoveWallet(&wallet); } SetMockTime(0); From 195dcad1ee91aad6c513722dfd46f80dd110f386 Mon Sep 17 00:00:00 2001 From: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com> Date: Mon, 24 Aug 2020 11:17:13 -0400 Subject: [PATCH 06/12] trivial/docs: minor adjustments to PrivateSend help text (#3669) Signed-off-by: pasta --- src/qt/utilitydialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 22664ee59369..61014cc31837 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -148,7 +148,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, HelpMode helpMode) :

PrivateSend Basics

\ PrivateSend gives you true financial privacy by obscuring the origins of your funds. \ All the Dash in your wallet is comprised of different \"inputs\" which you can think of as separate, discrete coins.
\ -PrivateSend uses an innovative process to mix your inputs with the inputs of two other people, without having your coins ever leave your wallet. \ +PrivateSend uses an innovative process to mix your inputs with the inputs of two or more other people, without having your coins ever leave your wallet. \ You retain control of your money at all times.
\ The PrivateSend process works like this:\
    \ @@ -157,7 +157,7 @@ These denominations are 0.001 DASH, 0.01 DASH, 0.1 DASH, 1 DASH and 10 DASH -- s
  1. Your wallet then sends requests to specially configured software nodes on the network, called \"masternodes.\" \ These masternodes are informed then that you are interested in mixing a certain denomination. \ No identifiable information is sent to the masternodes, so they never know \"who\" you are.
  2. \ -
  3. When two other people send similar messages, indicating that they wish to mix the same denomination, a mixing session begins. \ +
  4. When two or more other people send similar messages, indicating that they wish to mix the same denomination, a mixing session begins. \ The masternode mixes up the inputs and instructs all three users' wallets to pay the now-transformed input back to themselves. \ Your wallet pays that denomination directly to itself, but in a different address (called a change address).
  5. \
  6. In order to fully obscure your funds, your wallet must repeat this process a number of times with each denomination. \ From 25e4fed75bbccd6f1627a933bd2d1cbe26aeaf69 Mon Sep 17 00:00:00 2001 From: sc-9310 <60552402+sc-9310@users.noreply.github.com> Date: Sun, 30 Aug 2020 16:24:05 +0200 Subject: [PATCH 07/12] QT: add last block hash to debug ui (#3672) * [QT] Add last block hash to debug ui Trivial addition to display last block hash next to last block time * [QT] Make last block hash selectable ... and linter happy Switch QMetaObject to get last hash from pIndex instead of clientmodel * [Trivial] Fix trailing whitespaces --- src/qt/clientmodel.cpp | 11 +++++++++++ src/qt/clientmodel.h | 3 ++- src/qt/forms/debugwindow.ui | 37 ++++++++++++++++++++++++++++++------- src/qt/rpcconsole.cpp | 7 ++++--- src/qt/rpcconsole.h | 4 ++-- 5 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 8063a6d6a269..71c9cff08aed 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -153,6 +153,16 @@ QDateTime ClientModel::getLastBlockDate() const return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network } +QString ClientModel::getLastBlockHash() const +{ + LOCK(cs_main); + + if (chainActive.Tip()) + return QString::fromStdString(chainActive.Tip()->GetBlockHash().ToString()); + + return QString::fromStdString(Params().GenesisBlock().GetHash().ToString()); // Genesis block's hash of current network +} + long ClientModel::getMempoolSize() const { return mempool.size(); @@ -344,6 +354,7 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight), Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())), + Q_ARG(QString, QString::fromStdString(pIndex->GetBlockHash().ToString())), Q_ARG(double, clientmodel->getVerificationProgress(pIndex)), Q_ARG(bool, fHeader)); nLastUpdateNotification = now; diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 129343e6d97b..222a4df7e055 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -72,6 +72,7 @@ class ClientModel : public QObject double getVerificationProgress(const CBlockIndex *tip) const; QDateTime getLastBlockDate() const; + QString getLastBlockHash() const; //! Return true if core is doing initial block download bool inInitialBlockDownload() const; @@ -113,7 +114,7 @@ class ClientModel : public QObject Q_SIGNALS: void numConnectionsChanged(int count); void masternodeListChanged() const; - void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress, bool header); + void numBlocksChanged(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header); void additionalDataSyncProgressChanged(double nSyncProgress); void mempoolSizeChanged(long count, size_t mempoolSizeInBytes); void islockCountChanged(size_t count); diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 9df65c113916..b0f65665f3aa 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -351,20 +351,43 @@ + + + Last block hash + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + Memory Pool - + Current number of transactions - + IBeamCursor @@ -380,14 +403,14 @@ - + Memory usage - + IBeamCursor @@ -443,7 +466,7 @@ - + Qt::Vertical @@ -456,14 +479,14 @@ - + InstantSend locks - + IBeamCursor diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 07ccc17fccc4..c74849d68df6 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -602,8 +602,8 @@ void RPCConsole::setClientModel(ClientModel *model) setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(nullptr), false); - connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); + setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getLastBlockHash(), model->getVerificationProgress(nullptr), false); + connect(model, SIGNAL(numBlocksChanged(int,QDateTime,QString,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,QString,double,bool))); updateNetworkState(); connect(model, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool))); @@ -941,11 +941,12 @@ void RPCConsole::setNetworkActive(bool networkActive) updateNetworkState(); } -void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers) +void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool headers) { if (!headers) { ui->numberOfBlocks->setText(QString::number(count)); ui->lastBlockTime->setText(blockDate.toString()); + ui->lastBlockHash->setText(blockHash); } } diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 92158efc0c6b..581433c5e098 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -110,8 +110,8 @@ public Q_SLOTS: void setNetworkActive(bool networkActive); /** Update number of masternodes shown in the UI */ void updateMasternodeCount(); - /** Set number of blocks and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers); + /** Set number of blocks, last block date and last block hash shown in the UI */ + void setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool headers); /** Set size (number of transactions and memory usage) of the mempool in the UI */ void setMempoolSize(long numberOfTxs, size_t dynUsage); /** Set number of InstantSend locks */ From 608f481a9c693824f943e4e2384459afa59a2fe4 Mon Sep 17 00:00:00 2001 From: dustinface <35775977+xdustinface@users.noreply.github.com> Date: Tue, 8 Sep 2020 11:54:49 +0200 Subject: [PATCH 08/12] qt: Fix block update signals/slots in BitcoinGUI and SendCoinsDialog (#3685) --- src/qt/bitcoingui.cpp | 6 +++--- src/qt/bitcoingui.h | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index bf484e10942f..b601c9909da2 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -681,8 +681,8 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) connect(_clientModel, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool))); modalOverlay->setKnownBestHeight(_clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(_clientModel->getHeaderTipTime())); - setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(nullptr), false); - connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); + setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getLastBlockHash(), _clientModel->getVerificationProgress(nullptr), false); + connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,QString,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,QString,double,bool))); connect(_clientModel, SIGNAL(additionalDataSyncProgressChanged(double)), this, SLOT(setAdditionalDataSyncProgress(double))); @@ -1031,7 +1031,7 @@ void BitcoinGUI::updateHeadersSyncProgressLabel() progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1))); } -void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header) +void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header) { #ifdef Q_OS_MAC // Disabling macOS App Nap on initial sync, disk, reindex operations and mixing. diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 4c0e3e6f0f6e..4b07392a9869 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -195,7 +195,7 @@ public Q_SLOTS: /** Get restart command-line parameters and request restart */ void handleRestart(QStringList args); /** Set number of blocks and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers); + void setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool headers); /** Set additional data sync status shown in the UI */ void setAdditionalDataSyncProgress(double nSyncProgress); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 3e8cd461d5a3..007ff9f5c8a8 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -170,7 +170,7 @@ void SendCoinsDialog::setClientModel(ClientModel *_clientModel) this->clientModel = _clientModel; if (_clientModel) { - connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel())); + connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,QString,double,bool)), this, SLOT(updateSmartFeeLabel())); } } From 50d7a2fecfcca751e498fc85626c006a82a53cc6 Mon Sep 17 00:00:00 2001 From: dustinface <35775977+xdustinface@users.noreply.github.com> Date: Tue, 8 Sep 2020 11:55:38 +0200 Subject: [PATCH 09/12] qt: Ignore GUIUtil::updateFont calls until GUIUtil::loadFonts was called (#3687) --- src/qt/guiutil.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 9432057d6508..bbd6af975fc5 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1555,6 +1555,11 @@ void setFixedPitchFont(const std::vector& vecWidgets) void updateFonts() { + // Fonts need to be loaded by GUIIUtil::loadFonts(), if not just return. + if (!osDefaultFont) { + return; + } + setApplicationFont(); auto getKey = [](QWidget* w) -> QString { From e8d5c8e19d811589d7392330bcc2a8bc12cdda59 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 29 Jul 2020 16:27:45 +0300 Subject: [PATCH 10/12] More of 13153 (fix LogPrintf-s) -- TODO: backport to 0.16 --- src/evo/specialtx.cpp | 2 +- src/init.cpp | 7 ++++--- src/llmq/quorums.cpp | 2 +- src/llmq/quorums_signing_shares.cpp | 2 +- src/net_processing.cpp | 2 +- src/privatesend/privatesend-client.cpp | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/evo/specialtx.cpp b/src/evo/specialtx.cpp index e6d8eade36a2..d75bb5d83692 100644 --- a/src/evo/specialtx.cpp +++ b/src/evo/specialtx.cpp @@ -140,7 +140,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV int64_t nTime5 = GetTimeMicros(); nTimeMerkle += nTime5 - nTime4; LogPrint(BCLog::BENCHMARK, " - CheckCbTxMerkleRoots: %.2fms [%.2fs]\n", 0.001 * (nTime5 - nTime4), nTimeMerkle * 0.000001); } catch (const std::exception& e) { - LogPrintf(strprintf("%s -- failed: %s\n", __func__, e.what()).c_str()); + LogPrintf("%s -- failed: %s\n", __func__, e.what()); return state.DoS(100, false, REJECT_INVALID, "failed-procspectxsinblock"); } diff --git a/src/init.cpp b/src/init.cpp index 20c9f2546e14..b10c08b6f8af 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -988,12 +988,13 @@ void InitParameterInteraction() } } - if (gArgs.GetArg("-prune", 0) > 0) { + int64_t nPruneArg = gArgs.GetArg("-prune", 0); + if (nPruneArg > 0) { if (gArgs.SoftSetBoolArg("-disablegovernance", true)) { - LogPrintf("%s: parameter interaction: -prune=%d -> setting -disablegovernance=true\n", __func__); + LogPrintf("%s: parameter interaction: -prune=%d -> setting -disablegovernance=true\n", __func__, nPruneArg); } if (gArgs.SoftSetBoolArg("-txindex", false)) { - LogPrintf("%s: parameter interaction: -prune=%d -> setting -txindex=false\n", __func__); + LogPrintf("%s: parameter interaction: -prune=%d -> setting -txindex=false\n", __func__, nPruneArg); } } diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index cdc744f98c3f..82c85a5e10d4 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -342,7 +342,7 @@ CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, const uint25 auto quorumIt = mapBlockIndex.find(quorumHash); if (quorumIt == mapBlockIndex.end()) { - LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- block %s not found", __func__, quorumHash.ToString()); + LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- block %s not found\n", __func__, quorumHash.ToString()); return nullptr; } pindexQuorum = quorumIt->second; diff --git a/src/llmq/quorums_signing_shares.cpp b/src/llmq/quorums_signing_shares.cpp index 1b7c6b116aef..10a986bb97e7 100644 --- a/src/llmq/quorums_signing_shares.cpp +++ b/src/llmq/quorums_signing_shares.cpp @@ -677,7 +677,7 @@ bool CSigSharesManager::ProcessPendingSigShares(CConnman& connman) if (!pubKeyShare.IsValid()) { // this should really not happen (we already ensured we have the quorum vvec, // so we should also be able to create all pubkey shares) - LogPrintf("CSigSharesManager::%s -- pubKeyShare is invalid, which should not be possible here"); + LogPrintf("CSigSharesManager::%s -- pubKeyShare is invalid, which should not be possible here", __func__); assert(false); } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 0cc112ee3553..ea5012c76ad1 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2341,7 +2341,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // Note: do not break the flow here if (pfrom->fMasternodeProbe && !pfrom->fFirstMessageIsMNAUTH) { - LogPrint(BCLog::NET, "connection is a masternode probe but first received message is not MNAUTH, peer=%d", pfrom->GetId()); + LogPrint(BCLog::NET, "connection is a masternode probe but first received message is not MNAUTH, peer=%d\n", pfrom->GetId()); pfrom->fDisconnect = true; return false; } diff --git a/src/privatesend/privatesend-client.cpp b/src/privatesend/privatesend-client.cpp index 214b426471ad..b9108445a3fb 100644 --- a/src/privatesend/privatesend-client.cpp +++ b/src/privatesend/privatesend-client.cpp @@ -573,7 +573,7 @@ bool CPrivateSendClientSession::SignFinalTransaction(const CTransaction& finalTr if (!fFound) { // Something went wrong and we'll refuse to sign. It's possible we'll be charged collateral. But that's // better than signing if the transaction doesn't look like what we wanted. - LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::%s -- an output is missing, refusing to sign! txout=%s\n", txout.ToString()); + LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::%s -- an output is missing, refusing to sign! txout=%s\n", __func__, txout.ToString()); UnlockCoins(); keyHolderStorage.ReturnAll(); SetNull(); From 14fd2214afcdc3a0b38fca31c54e6c3414a19c26 Mon Sep 17 00:00:00 2001 From: Pasta Date: Fri, 12 Jun 2020 00:01:11 -0500 Subject: [PATCH 11/12] fix lint failure Signed-off-by: Pasta --- src/bloom.cpp | 2 +- src/governance/governance-object.cpp | 2 +- src/init.cpp | 2 +- src/llmq/quorums_instantsend.cpp | 2 +- src/llmq/quorums_signing_shares.cpp | 2 +- src/masternode/masternode-payments.cpp | 6 +++--- src/stacktraces.cpp | 2 +- src/wallet/init.cpp | 2 +- src/wallet/wallet.cpp | 4 ++-- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index bbc19ded98eb..545c75cb938e 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -226,7 +226,7 @@ bool CBloomFilter::CheckSpecialTransactionMatchesAndUpdate(const CTransaction &t return false; } - LogPrintf("Unknown special transaction type in Bloom filter check."); + LogPrintf("Unknown special transaction type in Bloom filter check.\n"); return false; } diff --git a/src/governance/governance-object.cpp b/src/governance/governance-object.cpp index e0614e0b03b7..6ba16f2a5568 100644 --- a/src/governance/governance-object.cpp +++ b/src/governance/governance-object.cpp @@ -268,7 +268,7 @@ std::set CGovernanceObject::RemoveInvalidVotes(const COutPoint& mnOutpo for (auto& h : removedVotes) { removedStr += strprintf(" %s\n", h.ToString()); } - LogPrintf("CGovernanceObject::%s -- Removed %d invalid votes for %s from MN %s:\n%s", __func__, removedVotes.size(), nParentHash.ToString(), mnOutpoint.ToString(), removedStr); + LogPrintf("CGovernanceObject::%s -- Removed %d invalid votes for %s from MN %s:\n%s\n", __func__, removedVotes.size(), nParentHash.ToString(), mnOutpoint.ToString(), removedStr); fDirtyCache = true; } diff --git a/src/init.cpp b/src/init.cpp index b10c08b6f8af..d3772e7c28a0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1975,7 +1975,7 @@ bool AppInitMain() if (!is_coinsview_empty) { uiInterface.InitMessage(_("Verifying blocks...")); if (fHavePruned && gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { - LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks", + LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks\n", MIN_BLOCKS_TO_KEEP); } diff --git a/src/llmq/quorums_instantsend.cpp b/src/llmq/quorums_instantsend.cpp index f245874f1091..e644cec27b6a 100644 --- a/src/llmq/quorums_instantsend.cpp +++ b/src/llmq/quorums_instantsend.cpp @@ -656,7 +656,7 @@ void CInstantSendManager::HandleNewInstantSendLockRecoveredSig(const llmq::CReco } if (islock.txid != recoveredSig.msgHash) { - LogPrintf("CInstantSendManager::%s -- txid=%s: islock conflicts with %s, dropping own version", __func__, + LogPrintf("CInstantSendManager::%s -- txid=%s: islock conflicts with %s, dropping own version\n", __func__, islock.txid.ToString(), recoveredSig.msgHash.ToString()); return; } diff --git a/src/llmq/quorums_signing_shares.cpp b/src/llmq/quorums_signing_shares.cpp index 10a986bb97e7..92cfae4a2531 100644 --- a/src/llmq/quorums_signing_shares.cpp +++ b/src/llmq/quorums_signing_shares.cpp @@ -677,7 +677,7 @@ bool CSigSharesManager::ProcessPendingSigShares(CConnman& connman) if (!pubKeyShare.IsValid()) { // this should really not happen (we already ensured we have the quorum vvec, // so we should also be able to create all pubkey shares) - LogPrintf("CSigSharesManager::%s -- pubKeyShare is invalid, which should not be possible here", __func__); + LogPrintf("CSigSharesManager::%s -- pubKeyShare is invalid, which should not be possible here\n", __func__); assert(false); } diff --git a/src/masternode/masternode-payments.cpp b/src/masternode/masternode-payments.cpp index 9bca61120362..c955bdff7b52 100644 --- a/src/masternode/masternode-payments.cpp +++ b/src/masternode/masternode-payments.cpp @@ -149,7 +149,7 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar // this actually also checks for correct payees and not only amount if (!CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) { // triggered but invalid? that's weird - LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, block.vtx[0]->ToString()); + LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s\n", __func__, nBlockHeight, block.vtx[0]->ToString()); // should NOT allow invalid superblocks, when superblocks are enabled strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight); return false; @@ -189,7 +189,7 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc LogPrint(BCLog::GOBJECT, "%s -- Valid superblock at height %d: %s", __func__, nBlockHeight, txNew.ToString()); // continue validation, should also pay MN } else { - LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, txNew.ToString()); + LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s\n", __func__, nBlockHeight, txNew.ToString()); // should NOT allow such superblocks, when superblocks are enabled return false; } @@ -207,7 +207,7 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc return true; } - LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s", __func__, nBlockHeight, txNew.ToString()); + LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s\n", __func__, nBlockHeight, txNew.ToString()); return false; } diff --git a/src/stacktraces.cpp b/src/stacktraces.cpp index 020b7fee2be9..0de4efeb2262 100644 --- a/src/stacktraces.cpp +++ b/src/stacktraces.cpp @@ -524,7 +524,7 @@ static std::string GetCrashInfoStr(const crash_info& ci, size_t spaces) static void PrintCrashInfo(const crash_info& ci) { auto str = GetCrashInfoStr(ci); - LogPrintf("%s", str); + LogPrintf("%s", str); /* Continued */ fprintf(stderr, "%s", str.c_str()); fflush(stderr); } diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 0d764ed2db8f..5be1b67969d3 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -421,7 +421,7 @@ void WalletInit::InitPrivateSendSettings() privateSendClient.nPrivateSendDenomsHardCap = std::min(std::max((int)gArgs.GetArg("-privatesenddenomshardcap", DEFAULT_PRIVATESEND_DENOMS_HARDCAP), MIN_PRIVATESEND_DENOMS_HARDCAP), MAX_PRIVATESEND_DENOMS_HARDCAP); if (privateSendClient.fEnablePrivateSend) { - LogPrintf("PrivateSend: autostart=%d, multisession=%d, " + LogPrintf("PrivateSend: autostart=%d, multisession=%d," /* Continued */ "sessions=%d, rounds=%d, amount=%d, denoms_goal=%d, denoms_hardcap=%d\n", privateSendClient.fPrivateSendRunning, privateSendClient.fPrivateSendMultiSession, privateSendClient.nPrivateSendSessions, privateSendClient.nPrivateSendRounds, diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4c6623ec25e0..9a7ce0b29938 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -621,7 +621,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, // Update KeePass if necessary if(bUseKeePass) { - LogPrintf("CWallet::ChangeWalletPassphrase -- Updating KeePass with new passphrase"); + LogPrintf("CWallet::ChangeWalletPassphrase -- Updating KeePass with new passphrase\n"); try { keePassInt.updatePassphrase(strNewWalletPassphrase); } catch (std::exception& e) { @@ -903,7 +903,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) // Update KeePass if necessary if(gArgs.GetBoolArg("-keepass", false)) { - LogPrintf("CWallet::EncryptWallet -- Updating KeePass with new passphrase"); + LogPrintf("CWallet::EncryptWallet -- Updating KeePass with new passphrase\n"); try { keePassInt.updatePassphrase(strWalletPassphrase); } catch (std::exception& e) { From c2f56e08a876314e367efbdc9d8fbdef85282852 Mon Sep 17 00:00:00 2001 From: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com> Date: Fri, 12 Jun 2020 15:45:05 +0000 Subject: [PATCH 12/12] remove /* continued */ where is is not needed Co-authored-by: UdjinM6 --- src/governance/governance-object.cpp | 2 +- src/masternode/masternode-payments.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/governance/governance-object.cpp b/src/governance/governance-object.cpp index 6ba16f2a5568..f0d8d5a10566 100644 --- a/src/governance/governance-object.cpp +++ b/src/governance/governance-object.cpp @@ -268,7 +268,7 @@ std::set CGovernanceObject::RemoveInvalidVotes(const COutPoint& mnOutpo for (auto& h : removedVotes) { removedStr += strprintf(" %s\n", h.ToString()); } - LogPrintf("CGovernanceObject::%s -- Removed %d invalid votes for %s from MN %s:\n%s\n", __func__, removedVotes.size(), nParentHash.ToString(), mnOutpoint.ToString(), removedStr); + LogPrintf("CGovernanceObject::%s -- Removed %d invalid votes for %s from MN %s:\n%s", __func__, removedVotes.size(), nParentHash.ToString(), mnOutpoint.ToString(), removedStr); /* Continued */ fDirtyCache = true; } diff --git a/src/masternode/masternode-payments.cpp b/src/masternode/masternode-payments.cpp index c955bdff7b52..06debb172425 100644 --- a/src/masternode/masternode-payments.cpp +++ b/src/masternode/masternode-payments.cpp @@ -149,7 +149,7 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar // this actually also checks for correct payees and not only amount if (!CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) { // triggered but invalid? that's weird - LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s\n", __func__, nBlockHeight, block.vtx[0]->ToString()); + LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, block.vtx[0]->ToString()); /* Continued */ // should NOT allow invalid superblocks, when superblocks are enabled strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight); return false; @@ -189,7 +189,7 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc LogPrint(BCLog::GOBJECT, "%s -- Valid superblock at height %d: %s", __func__, nBlockHeight, txNew.ToString()); // continue validation, should also pay MN } else { - LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s\n", __func__, nBlockHeight, txNew.ToString()); + LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, txNew.ToString()); /* Continued */ // should NOT allow such superblocks, when superblocks are enabled return false; } @@ -207,7 +207,7 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc return true; } - LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s\n", __func__, nBlockHeight, txNew.ToString()); + LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s", __func__, nBlockHeight, txNew.ToString()); /* Continued */ return false; }