aboutsummaryrefslogtreecommitdiff
path: root/src/qt/walletmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt/walletmodel.cpp')
-rw-r--r--src/qt/walletmodel.cpp96
1 files changed, 59 insertions, 37 deletions
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 9909810e06..f63ffd9018 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2019 The Bitcoin Core developers
+// Copyright (c) 2011-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,7 +9,9 @@
#include <qt/walletmodel.h>
#include <qt/addresstablemodel.h>
+#include <qt/clientmodel.h>
#include <qt/guiconstants.h>
+#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <qt/paymentserver.h>
#include <qt/recentrequeststablemodel.h>
@@ -19,10 +21,12 @@
#include <interfaces/handler.h>
#include <interfaces/node.h>
#include <key_io.h>
+#include <psbt.h>
#include <ui_interface.h>
#include <util/system.h> // for GetBoolArg
+#include <util/translation.h>
#include <wallet/coincontrol.h>
-#include <wallet/wallet.h>
+#include <wallet/wallet.h> // for CRecipient
#include <stdint.h>
@@ -32,12 +36,18 @@
#include <QTimer>
-WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *_optionsModel, QObject *parent) :
- QObject(parent), m_wallet(std::move(wallet)), m_node(node), optionsModel(_optionsModel), addressTableModel(nullptr),
+WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent) :
+ QObject(parent),
+ m_wallet(std::move(wallet)),
+ m_client_model(&client_model),
+ m_node(client_model.node()),
+ optionsModel(client_model.getOptionsModel()),
+ addressTableModel(nullptr),
transactionTableModel(nullptr),
recentRequestsTableModel(nullptr),
cachedEncryptionStatus(Unencrypted),
- cachedNumBlocks(0)
+ cachedNumBlocks(0),
+ timer(new QTimer(this))
{
fHaveWatchOnly = m_wallet->haveWatchOnly();
addressTableModel = new AddressTableModel(this);
@@ -55,11 +65,16 @@ WalletModel::~WalletModel()
void WalletModel::startPollBalance()
{
// This timer will be fired repeatedly to update the balance
- QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &WalletModel::pollBalanceChanged);
timer->start(MODEL_UPDATE_DELAY);
}
+void WalletModel::setClientModel(ClientModel* client_model)
+{
+ m_client_model = client_model;
+ if (!m_client_model) timer->stop();
+}
+
void WalletModel::updateStatus()
{
EncryptionStatus newEncryptionStatus = getEncryptionStatus();
@@ -71,6 +86,10 @@ void WalletModel::updateStatus()
void WalletModel::pollBalanceChanged()
{
+ // Avoid recomputing wallet balances unless a TransactionChanged or
+ // BlockTip notification was received.
+ if (!fForceCheckBalanceChanged && cachedNumBlocks == m_client_model->getNumBlocks()) return;
+
// Try to get balances and return early if locks can't be acquired. This
// avoids the GUI from getting stuck on periodical polls if the core is
// holding the locks for a longer time - for example, during a wallet
@@ -81,12 +100,12 @@ void WalletModel::pollBalanceChanged()
return;
}
- if(fForceCheckBalanceChanged || m_node.getNumBlocks() != cachedNumBlocks)
+ if(fForceCheckBalanceChanged || numBlocks != cachedNumBlocks)
{
fForceCheckBalanceChanged = false;
// Balance and number of transactions might have changed
- cachedNumBlocks = m_node.getNumBlocks();
+ cachedNumBlocks = numBlocks;
checkBalanceChanged(new_balances);
if(transactionTableModel)
@@ -180,10 +199,10 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
{
CAmount nFeeRequired = 0;
int nChangePosRet = -1;
- std::string strFailReason;
+ bilingual_str error;
auto& newTx = transaction.getWtx();
- newTx = m_wallet->createTransaction(vecSend, coinControl, !privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, strFailReason);
+ newTx = m_wallet->createTransaction(vecSend, coinControl, !wallet().privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, error);
transaction.setTransactionFee(nFeeRequired);
if (fSubtractFeeFromAmount && newTx)
transaction.reassignAmounts(nChangePosRet);
@@ -194,8 +213,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
{
return SendCoinsReturn(AmountWithFeeExceedsBalance);
}
- Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
- CClientUIInterface::MSG_ERROR);
+ Q_EMIT message(tr("Send Coins"), QString::fromStdString(error.translated),
+ CClientUIInterface::MSG_ERROR);
return TransactionCreationFailed;
}
@@ -298,16 +317,10 @@ WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const
bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase)
{
- if(encrypted)
- {
- // Encrypt
+ if (encrypted) {
return m_wallet->encryptWallet(passphrase);
}
- else
- {
- // Decrypt -- TODO; not supported yet
- return false;
- }
+ return false;
}
bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
@@ -477,18 +490,20 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
{
CCoinControl coin_control;
coin_control.m_signal_bip125_rbf = true;
- std::vector<std::string> errors;
+ std::vector<bilingual_str> errors;
CAmount old_fee;
CAmount new_fee;
CMutableTransaction mtx;
- if (!m_wallet->createBumpTransaction(hash, coin_control, 0 /* totalFee */, errors, old_fee, new_fee, mtx)) {
+ if (!m_wallet->createBumpTransaction(hash, coin_control, errors, old_fee, new_fee, mtx)) {
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Increasing transaction fee failed") + "<br />(" +
- (errors.size() ? QString::fromStdString(errors[0]) : "") +")");
- return false;
+ (errors.size() ? QString::fromStdString(errors[0].translated) : "") +")");
+ return false;
}
+ const bool create_psbt = m_wallet->privateKeysDisabled();
+
// allow a user based fee verification
- QString questionString = tr("Do you want to increase the fee?");
+ QString questionString = create_psbt ? tr("Do you want to draft a transaction with fee increase?") : tr("Do you want to increase the fee?");
questionString.append("<br />");
questionString.append("<table style=\"text-align: left;\">");
questionString.append("<tr><td>");
@@ -519,6 +534,23 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
return false;
}
+ // Short-circuit if we are returning a bumped transaction PSBT to clipboard
+ if (create_psbt) {
+ PartiallySignedTransaction psbtx(mtx);
+ bool complete = false;
+ const TransactionError err = wallet().fillPSBT(SIGHASH_ALL, false /* sign */, true /* bip32derivs */, psbtx, complete);
+ if (err != TransactionError::OK || complete) {
+ QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't draft transaction."));
+ return false;
+ }
+ // Serialize the PSBT
+ CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
+ ssTx << psbtx;
+ GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str());
+ Q_EMIT message(tr("PSBT copied"), "Copied to clipboard", CClientUIInterface::MSG_INFORMATION);
+ return true;
+ }
+
// sign bumped transaction
if (!m_wallet->signBumpTransaction(mtx)) {
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't sign transaction."));
@@ -527,8 +559,8 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
// commit the bumped transaction
if(!m_wallet->commitBumpTransaction(hash, std::move(mtx), errors, new_hash)) {
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Could not commit transaction") + "<br />(" +
- QString::fromStdString(errors[0])+")");
- return false;
+ QString::fromStdString(errors[0].translated)+")");
+ return false;
}
return true;
}
@@ -538,16 +570,6 @@ bool WalletModel::isWalletEnabled()
return !gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
}
-bool WalletModel::privateKeysDisabled() const
-{
- return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
-}
-
-bool WalletModel::canGetAddresses() const
-{
- return m_wallet->canGetAddresses();
-}
-
QString WalletModel::getWalletName() const
{
return QString::fromStdString(m_wallet->getWalletName());