aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-05-15 07:54:29 -0400
committerMarcoFalke <falke.marco@gmail.com>2020-05-15 07:54:36 -0400
commit17bdf2afaee048da05b5e876bfbf64b6e834b962 (patch)
tree091e01639ac8e8c3c870e848539ede3f0f4a3aef /src/qt
parentaa7c6858e6e480eb841195bdaf2ee0185f17f9a7 (diff)
parent245c862cfd4883ea91b53d766abb00a9c3c1ea5c (diff)
downloadbitcoin-17bdf2afaee048da05b5e876bfbf64b6e834b962.tar.xz
Merge #18973: [0.20] Final backports for rc2
245c862cfd4883ea91b53d766abb00a9c3c1ea5c test: disable script fuzz tests (fanquake) 9a8fb4cf4ba472a5c3e1b9b71d31673f881a4896 fuzz: Remove enumeration of expected deserialization exceptions in ProcessMessage(...) fuzzer (practicalswift) 6161c94a6108ebddafe4e95c14bde4cdc3f8c01c [net processing] Only send a getheaders for one block in an INV (John Newbery) cf2a6e2a390ad18a616d7f2718688375f2576577 test: Remove const to work around compiler error on xenial (Wladimir J. van der Laan) cc7d34465bbb0195d8bcd9143097840a2e9765f2 miner: Avoid stack-use-after-return in validationinterface (MarcoFalke) 37a620748bd3578eda1c74daad8df8451d13b989 test: Add unregister_validation_interface_race test (MarcoFalke) ff4dc2075031e9a49220cc27a270aeabe8954989 gui: Fix manual coin control with multiple wallets loaded (João Barbosa) ed0afe8c1ff37926cc5bdcb0e8e4983e194e6d61 test: Add test for conflicted wallet tx notifications (Russell Yanofsky) 251e321ad7d9ddb938e8a07ddfbe90739f0bafdd rpc: Relock wallet only if most recent callback (João Barbosa) ca4dac48c5675af3fc53db6740a0b70fef622b0a rpc: Add mutex to guard deadlineTimers (João Barbosa) a3fe458a1e477cacd19e7e0edb8e7bb965067115 [docs] Improve commenting in ProcessGetData() (John Newbery) 011532e380bb1a42eac9e79a17b35531f768becf [test] test that an invalid GETDATA doesn't prevent processing of future messages (Amiti Uttarwar) 1e73d7248a10863dc99a93f1db36d035c17f29d7 [net processing] ignore unknown INV types in GETDATA messages (Amiti Uttarwar) fb821731eb12906996bffdf4b3633d7fe47c85a7 [net processing] ignore tx GETDATA from blocks-only peers (Amiti Uttarwar) 315ae14f3f5c98ae4c4476e4bb260b9086c773a4 gui: Fix itemWalletAddress leak when not tree mode (João Barbosa) Pull request description: Backports the following PRs to the 0.20 branch: * https://github.com/bitcoin/bitcoin/pull/18578: gui: Fix leak in CoinControlDialog::updateView * https://github.com/bitcoin/bitcoin/pull/18808: [net processing] Drop unknown types in getdata * https://github.com/bitcoin/bitcoin/pull/18814: rpc: Relock wallet only if most recent callback * https://github.com/bitcoin/bitcoin/pull/18878: test: Add test for conflicted wallet tx notifications * https://github.com/bitcoin/bitcoin/pull/18894: gui: Fix manual coin control with multiple wallets loaded * https://github.com/bitcoin/bitcoin/pull/18742: miner: Avoid stack-use-after-return in validationinterface * https://github.com/bitcoin/bitcoin/pull/18962: net processing: Only send a getheaders for one block in an INV * https://github.com/bitcoin/bitcoin/pull/18975: test: Remove const to work around compiler error on xenial ACKs for top commit: promag: Tested ACK 245c862cfd4883ea91b53d766abb00a9c3c1ea5c coin control with multiple wallets. laanwj: ACK 245c862cfd4883ea91b53d766abb00a9c3c1ea5c MarcoFalke: ACK 245c862cfd solved the conflicts myself as a sanity check. Did not re-review 🍷 Tree-SHA512: 285e5a5fad5bbeba6032742c65dc68836e8eccfcceda9e69fec4ddd162a3f61679a96f9bbe3d434267835af67c21ac4c05accf6f63e827c2eb47203c6daafe31
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/coincontroldialog.cpp57
-rw-r--r--src/qt/coincontroldialog.h9
-rw-r--r--src/qt/sendcoinsdialog.cpp50
-rw-r--r--src/qt/sendcoinsdialog.h2
4 files changed, 47 insertions, 71 deletions
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 9495ba389a..88e7304383 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -41,10 +41,11 @@ bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const {
return QTreeWidgetItem::operator<(other);
}
-CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
+CoinControlDialog::CoinControlDialog(CCoinControl& coin_control, WalletModel* _model, const PlatformStyle *_platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::CoinControlDialog),
- model(nullptr),
+ m_coin_control(coin_control),
+ model(_model),
platformStyle(_platformStyle)
{
ui->setupUi(this);
@@ -134,6 +135,13 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidge
ui->radioTreeMode->click();
if (settings.contains("nCoinControlSortColumn") && settings.contains("nCoinControlSortOrder"))
sortView(settings.value("nCoinControlSortColumn").toInt(), (static_cast<Qt::SortOrder>(settings.value("nCoinControlSortOrder").toInt())));
+
+ if(_model->getOptionsModel() && _model->getAddressTableModel())
+ {
+ updateView();
+ updateLabelLocked();
+ CoinControlDialog::updateLabels(m_coin_control, _model, this);
+ }
}
CoinControlDialog::~CoinControlDialog()
@@ -146,18 +154,6 @@ CoinControlDialog::~CoinControlDialog()
delete ui;
}
-void CoinControlDialog::setModel(WalletModel *_model)
-{
- this->model = _model;
-
- if(_model && _model->getOptionsModel() && _model->getAddressTableModel())
- {
- updateView();
- updateLabelLocked();
- CoinControlDialog::updateLabels(_model, this);
- }
-}
-
// ok button
void CoinControlDialog::buttonBoxClicked(QAbstractButton* button)
{
@@ -183,8 +179,8 @@ void CoinControlDialog::buttonSelectAllClicked()
ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX, state);
ui->treeWidget->setEnabled(true);
if (state == Qt::Unchecked)
- coinControl()->UnSelectAll(); // just to be sure
- CoinControlDialog::updateLabels(model, this);
+ m_coin_control.UnSelectAll(); // just to be sure
+ CoinControlDialog::updateLabels(m_coin_control, model, this);
}
// context menu
@@ -369,15 +365,15 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
COutPoint outpt(uint256S(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), item->data(COLUMN_ADDRESS, VOutRole).toUInt());
if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked)
- coinControl()->UnSelect(outpt);
+ m_coin_control.UnSelect(outpt);
else if (item->isDisabled()) // locked (this happens if "check all" through parent node)
item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
else
- coinControl()->Select(outpt);
+ m_coin_control.Select(outpt);
// selection changed -> update labels
if (ui->treeWidget->isEnabled()) // do not update on every click for (un)select all
- CoinControlDialog::updateLabels(model, this);
+ CoinControlDialog::updateLabels(m_coin_control, model, this);
}
// TODO: Remove this temporary qt5 fix after Qt5.3 and Qt5.4 are no longer used.
@@ -402,7 +398,7 @@ void CoinControlDialog::updateLabelLocked()
else ui->labelLocked->setVisible(false);
}
-void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
+void CoinControlDialog::updateLabels(CCoinControl& m_coin_control, WalletModel *model, QDialog* dialog)
{
if (!model)
return;
@@ -434,7 +430,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
bool fWitness = false;
std::vector<COutPoint> vCoinControl;
- coinControl()->ListSelected(vCoinControl);
+ m_coin_control.ListSelected(vCoinControl);
size_t i = 0;
for (const auto& out : model->wallet().getCoins(vCoinControl)) {
@@ -445,7 +441,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
const COutPoint& outpt = vCoinControl[i++];
if (out.is_spent)
{
- coinControl()->UnSelect(outpt);
+ m_coin_control.UnSelect(outpt);
continue;
}
@@ -498,7 +494,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
nBytes -= 34;
// Fee
- nPayFee = model->wallet().getMinimumFee(nBytes, *coinControl(), nullptr /* returned_target */, nullptr /* reason */);
+ nPayFee = model->wallet().getMinimumFee(nBytes, m_coin_control, nullptr /* returned_target */, nullptr /* reason */);
if (nPayAmount > 0)
{
@@ -590,12 +586,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
label->setVisible(nChange < 0);
}
-CCoinControl* CoinControlDialog::coinControl()
-{
- static CCoinControl coin_control;
- return &coin_control;
-}
-
void CoinControlDialog::updateView()
{
if (!model || !model->getOptionsModel() || !model->getAddressTableModel())
@@ -612,8 +602,7 @@ void CoinControlDialog::updateView()
int nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
for (const auto& coins : model->wallet().listCoins()) {
- CCoinControlWidgetItem *itemWalletAddress = new CCoinControlWidgetItem();
- itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
+ CCoinControlWidgetItem* itemWalletAddress{nullptr};
QString sWalletAddress = QString::fromStdString(EncodeDestination(coins.first));
QString sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress);
if (sWalletLabel.isEmpty())
@@ -622,7 +611,7 @@ void CoinControlDialog::updateView()
if (treeMode)
{
// wallet address
- ui->treeWidget->addTopLevelItem(itemWalletAddress);
+ itemWalletAddress = new CCoinControlWidgetItem(ui->treeWidget);
itemWalletAddress->setFlags(flgTristate);
itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
@@ -696,13 +685,13 @@ void CoinControlDialog::updateView()
// disable locked coins
if (model->wallet().isLockedCoin(output))
{
- coinControl()->UnSelect(output); // just to be sure
+ m_coin_control.UnSelect(output); // just to be sure
itemOutput->setDisabled(true);
itemOutput->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
}
// set checkbox
- if (coinControl()->IsSelected(output))
+ if (m_coin_control.IsSelected(output))
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
}
diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h
index efc06a7656..c8a91e5f58 100644
--- a/src/qt/coincontroldialog.h
+++ b/src/qt/coincontroldialog.h
@@ -31,7 +31,6 @@ class CCoinControlWidgetItem : public QTreeWidgetItem
{
public:
explicit CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {}
- explicit CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {}
explicit CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {}
bool operator<(const QTreeWidgetItem &other) const;
@@ -43,20 +42,18 @@ class CoinControlDialog : public QDialog
Q_OBJECT
public:
- explicit CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent = nullptr);
+ explicit CoinControlDialog(CCoinControl& coin_control, WalletModel* model, const PlatformStyle *platformStyle, QWidget *parent = nullptr);
~CoinControlDialog();
- void setModel(WalletModel *model);
-
// static because also called from sendcoinsdialog
- static void updateLabels(WalletModel*, QDialog*);
+ static void updateLabels(CCoinControl& m_coin_control, WalletModel*, QDialog*);
static QList<CAmount> payAmounts;
- static CCoinControl *coinControl();
static bool fSubtractFeeFromAmount;
private:
Ui::CoinControlDialog *ui;
+ CCoinControl& m_coin_control;
WalletModel *model;
int sortColumn;
Qt::SortOrder sortOrder;
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index a8c82aaf6c..2a6ef41221 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -57,6 +57,7 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p
ui(new Ui::SendCoinsDialog),
clientModel(nullptr),
model(nullptr),
+ m_coin_control(new CCoinControl),
fNewRecipientAllowed(true),
fFeeMinimized(true),
platformStyle(_platformStyle)
@@ -262,14 +263,9 @@ void SendCoinsDialog::on_sendButton_clicked()
WalletModelTransaction currentTransaction(recipients);
WalletModel::SendCoinsReturn prepareStatus;
- // Always use a CCoinControl instance, use the CoinControlDialog instance if CoinControl has been enabled
- CCoinControl ctrl;
- if (model->getOptionsModel()->getCoinControlFeatures())
- ctrl = *CoinControlDialog::coinControl();
+ updateCoinControlState(*m_coin_control);
- updateCoinControlState(ctrl);
-
- prepareStatus = model->prepareTransaction(currentTransaction, ctrl);
+ prepareStatus = model->prepareTransaction(currentTransaction, *m_coin_control);
// process prepareStatus and on error generate message shown to user
processSendCoinsReturn(prepareStatus,
@@ -413,7 +409,7 @@ void SendCoinsDialog::on_sendButton_clicked()
}
if (!send_failure) {
accept();
- CoinControlDialog::coinControl()->UnSelectAll();
+ m_coin_control->UnSelectAll();
coinControlUpdateLabels();
}
fNewRecipientAllowed = true;
@@ -422,7 +418,7 @@ void SendCoinsDialog::on_sendButton_clicked()
void SendCoinsDialog::clear()
{
// Clear coin control settings
- CoinControlDialog::coinControl()->UnSelectAll();
+ m_coin_control->UnSelectAll();
ui->checkBoxCoinControlChange->setChecked(false);
ui->lineEditCoinControlChange->clear();
coinControlUpdateLabels();
@@ -645,17 +641,11 @@ void SendCoinsDialog::on_buttonMinimizeFee_clicked()
void SendCoinsDialog::useAvailableBalance(SendCoinsEntry* entry)
{
- // Get CCoinControl instance if CoinControl is enabled or create a new one.
- CCoinControl coin_control;
- if (model->getOptionsModel()->getCoinControlFeatures()) {
- coin_control = *CoinControlDialog::coinControl();
- }
-
// Include watch-only for wallets without private key
- coin_control.fAllowWatchOnly = model->wallet().privateKeysDisabled();
+ m_coin_control->fAllowWatchOnly = model->wallet().privateKeysDisabled();
// Calculate available amount to send.
- CAmount amount = model->wallet().getAvailableBalance(coin_control);
+ CAmount amount = model->wallet().getAvailableBalance(*m_coin_control);
for (int i = 0; i < ui->entries->count(); ++i) {
SendCoinsEntry* e = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
if (e && !e->isHidden() && e != entry) {
@@ -714,12 +704,11 @@ void SendCoinsDialog::updateSmartFeeLabel()
{
if(!model || !model->getOptionsModel())
return;
- CCoinControl coin_control;
- updateCoinControlState(coin_control);
- coin_control.m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels
+ updateCoinControlState(*m_coin_control);
+ m_coin_control->m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels
int returned_target;
FeeReason reason;
- CFeeRate feeRate = CFeeRate(model->wallet().getMinimumFee(1000, coin_control, &returned_target, &reason));
+ CFeeRate feeRate = CFeeRate(model->wallet().getMinimumFee(1000, *m_coin_control, &returned_target, &reason));
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
@@ -790,7 +779,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
ui->frameCoinControl->setVisible(checked);
if (!checked && model) // coin control features disabled
- CoinControlDialog::coinControl()->SetNull();
+ m_coin_control->SetNull();
coinControlUpdateLabels();
}
@@ -798,8 +787,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
// Coin Control: button inputs -> show actual coin control dialog
void SendCoinsDialog::coinControlButtonClicked()
{
- CoinControlDialog dlg(platformStyle);
- dlg.setModel(model);
+ CoinControlDialog dlg(*m_coin_control, model, platformStyle);
dlg.exec();
coinControlUpdateLabels();
}
@@ -809,7 +797,7 @@ void SendCoinsDialog::coinControlChangeChecked(int state)
{
if (state == Qt::Unchecked)
{
- CoinControlDialog::coinControl()->destChange = CNoDestination();
+ m_coin_control->destChange = CNoDestination();
ui->labelCoinControlChangeLabel->clear();
}
else
@@ -825,7 +813,7 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
if (model && model->getAddressTableModel())
{
// Default to no change address until verified
- CoinControlDialog::coinControl()->destChange = CNoDestination();
+ m_coin_control->destChange = CNoDestination();
ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}");
const CTxDestination dest = DecodeDestination(text.toStdString());
@@ -848,7 +836,7 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
if(btnRetVal == QMessageBox::Yes)
- CoinControlDialog::coinControl()->destChange = dest;
+ m_coin_control->destChange = dest;
else
{
ui->lineEditCoinControlChange->setText("");
@@ -867,7 +855,7 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
else
ui->labelCoinControlChangeLabel->setText(tr("(no label)"));
- CoinControlDialog::coinControl()->destChange = dest;
+ m_coin_control->destChange = dest;
}
}
}
@@ -879,7 +867,7 @@ void SendCoinsDialog::coinControlUpdateLabels()
if (!model || !model->getOptionsModel())
return;
- updateCoinControlState(*CoinControlDialog::coinControl());
+ updateCoinControlState(*m_coin_control);
// set pay amounts
CoinControlDialog::payAmounts.clear();
@@ -897,10 +885,10 @@ void SendCoinsDialog::coinControlUpdateLabels()
}
}
- if (CoinControlDialog::coinControl()->HasSelected())
+ if (m_coin_control->HasSelected())
{
// actual coin control calculation
- CoinControlDialog::updateLabels(model, this);
+ CoinControlDialog::updateLabels(*m_coin_control, model, this);
// show coin control stats
ui->labelCoinControlAutomaticallySelected->hide();
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index 86422c4030..8eadc5a225 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -12,6 +12,7 @@
#include <QString>
#include <QTimer>
+class CCoinControl;
class ClientModel;
class PlatformStyle;
class SendCoinsEntry;
@@ -60,6 +61,7 @@ private:
Ui::SendCoinsDialog *ui;
ClientModel *clientModel;
WalletModel *model;
+ std::unique_ptr<CCoinControl> m_coin_control;
bool fNewRecipientAllowed;
bool fFeeMinimized;
const PlatformStyle *platformStyle;