Bitcoin Core  0.19.99
P2P Digital Currency
walletmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <qt/walletmodel.h>
10 
11 #include <qt/addresstablemodel.h>
12 #include <qt/guiconstants.h>
13 #include <qt/guiutil.h>
14 #include <qt/optionsmodel.h>
15 #include <qt/paymentserver.h>
17 #include <qt/sendcoinsdialog.h>
19 
20 #include <interfaces/handler.h>
21 #include <interfaces/node.h>
22 #include <key_io.h>
23 #include <ui_interface.h>
24 #include <util/system.h> // for GetBoolArg
25 #include <wallet/coincontrol.h>
26 #include <wallet/wallet.h>
27 
28 #include <stdint.h>
29 
30 #include <QDebug>
31 #include <QMessageBox>
32 #include <QSet>
33 #include <QTimer>
34 
35 
36 WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *_optionsModel, QObject *parent) :
37  QObject(parent), m_wallet(std::move(wallet)), m_node(node), optionsModel(_optionsModel), addressTableModel(nullptr),
38  transactionTableModel(nullptr),
39  recentRequestsTableModel(nullptr),
40  cachedEncryptionStatus(Unencrypted),
41  cachedNumBlocks(0)
42 {
43  fHaveWatchOnly = m_wallet->haveWatchOnly();
45  transactionTableModel = new TransactionTableModel(platformStyle, this);
47 
49 }
50 
52 {
54 }
55 
57 {
58  // This timer will be fired repeatedly to update the balance
59  QTimer* timer = new QTimer(this);
60  connect(timer, &QTimer::timeout, this, &WalletModel::pollBalanceChanged);
61  timer->start(MODEL_UPDATE_DELAY);
62 }
63 
65 {
66  EncryptionStatus newEncryptionStatus = getEncryptionStatus();
67 
68  if(cachedEncryptionStatus != newEncryptionStatus) {
69  Q_EMIT encryptionStatusChanged();
70  }
71 }
72 
74 {
75  // Try to get balances and return early if locks can't be acquired. This
76  // avoids the GUI from getting stuck on periodical polls if the core is
77  // holding the locks for a longer time - for example, during a wallet
78  // rescan.
79  interfaces::WalletBalances new_balances;
80  int numBlocks = -1;
81  if (!m_wallet->tryGetBalances(new_balances, numBlocks)) {
82  return;
83  }
84 
85  if(fForceCheckBalanceChanged || numBlocks != cachedNumBlocks)
86  {
88 
89  // Balance and number of transactions might have changed
90  cachedNumBlocks = numBlocks;
91 
92  checkBalanceChanged(new_balances);
95  }
96 }
97 
99 {
100  if(new_balances.balanceChanged(m_cached_balances)) {
101  m_cached_balances = new_balances;
102  Q_EMIT balanceChanged(new_balances);
103  }
104 }
105 
107 {
108  // Balance and number of transactions might have changed
110 }
111 
112 void WalletModel::updateAddressBook(const QString &address, const QString &label,
113  bool isMine, const QString &purpose, int status)
114 {
116  addressTableModel->updateEntry(address, label, isMine, purpose, status);
117 }
118 
119 void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly)
120 {
121  fHaveWatchOnly = fHaveWatchonly;
122  Q_EMIT notifyWatchonlyChanged(fHaveWatchonly);
123 }
124 
125 bool WalletModel::validateAddress(const QString &address)
126 {
127  return IsValidDestinationString(address.toStdString());
128 }
129 
131 {
132  CAmount total = 0;
133  bool fSubtractFeeFromAmount = false;
134  QList<SendCoinsRecipient> recipients = transaction.getRecipients();
135  std::vector<CRecipient> vecSend;
136 
137  if(recipients.empty())
138  {
139  return OK;
140  }
141 
142  QSet<QString> setAddress; // Used to detect duplicates
143  int nAddresses = 0;
144 
145  // Pre-check input data for validity
146  for (const SendCoinsRecipient &rcp : recipients)
147  {
148  if (rcp.fSubtractFeeFromAmount)
149  fSubtractFeeFromAmount = true;
150  { // User-entered bitcoin address / amount:
151  if(!validateAddress(rcp.address))
152  {
153  return InvalidAddress;
154  }
155  if(rcp.amount <= 0)
156  {
157  return InvalidAmount;
158  }
159  setAddress.insert(rcp.address);
160  ++nAddresses;
161 
162  CScript scriptPubKey = GetScriptForDestination(DecodeDestination(rcp.address.toStdString()));
163  CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
164  vecSend.push_back(recipient);
165 
166  total += rcp.amount;
167  }
168  }
169  if(setAddress.size() != nAddresses)
170  {
171  return DuplicateAddress;
172  }
173 
174  CAmount nBalance = m_wallet->getAvailableBalance(coinControl);
175 
176  if(total > nBalance)
177  {
178  return AmountExceedsBalance;
179  }
180 
181  {
182  CAmount nFeeRequired = 0;
183  int nChangePosRet = -1;
184  std::string strFailReason;
185 
186  auto& newTx = transaction.getWtx();
187  newTx = m_wallet->createTransaction(vecSend, coinControl, !privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, strFailReason);
188  transaction.setTransactionFee(nFeeRequired);
189  if (fSubtractFeeFromAmount && newTx)
190  transaction.reassignAmounts(nChangePosRet);
191 
192  if(!newTx)
193  {
194  if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
195  {
197  }
198  Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
201  }
202 
203  // Reject absurdly high fee. (This can never happen because the
204  // wallet never creates transactions with fee greater than
205  // m_default_max_tx_fee. This merely a belt-and-suspenders check).
206  if (nFeeRequired > m_wallet->getDefaultMaxTxFee()) {
207  return AbsurdFee;
208  }
209  }
210 
211  return SendCoinsReturn(OK);
212 }
213 
215 {
216  QByteArray transaction_array; /* store serialized transaction */
217 
218  {
219  std::vector<std::pair<std::string, std::string>> vOrderForm;
220  for (const SendCoinsRecipient &rcp : transaction.getRecipients())
221  {
222  if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
223  vOrderForm.emplace_back("Message", rcp.message.toStdString());
224  }
225 
226  auto& newTx = transaction.getWtx();
227  wallet().commitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm));
228 
230  ssTx << *newTx;
231  transaction_array.append(&(ssTx[0]), ssTx.size());
232  }
233 
234  // Add addresses / update labels that we've sent to the address book,
235  // and emit coinsSent signal for each recipient
236  for (const SendCoinsRecipient &rcp : transaction.getRecipients())
237  {
238  {
239  std::string strAddress = rcp.address.toStdString();
240  CTxDestination dest = DecodeDestination(strAddress);
241  std::string strLabel = rcp.label.toStdString();
242  {
243  // Check if we have a new address or an updated label
244  std::string name;
245  if (!m_wallet->getAddress(
246  dest, &name, /* is_mine= */ nullptr, /* purpose= */ nullptr))
247  {
248  m_wallet->setAddressBook(dest, strLabel, "send");
249  }
250  else if (name != strLabel)
251  {
252  m_wallet->setAddressBook(dest, strLabel, ""); // "" means don't change purpose
253  }
254  }
255  }
256  Q_EMIT coinsSent(this, rcp, transaction_array);
257  }
258 
259  checkBalanceChanged(m_wallet->getBalances()); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits
260 
261  return SendCoinsReturn(OK);
262 }
263 
265 {
266  return optionsModel;
267 }
268 
270 {
271  return addressTableModel;
272 }
273 
275 {
276  return transactionTableModel;
277 }
278 
280 {
282 }
283 
285 {
286  if(!m_wallet->isCrypted())
287  {
288  return Unencrypted;
289  }
290  else if(m_wallet->isLocked())
291  {
292  return Locked;
293  }
294  else
295  {
296  return Unlocked;
297  }
298 }
299 
300 bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase)
301 {
302  if(encrypted)
303  {
304  // Encrypt
305  return m_wallet->encryptWallet(passphrase);
306  }
307  else
308  {
309  // Decrypt -- TODO; not supported yet
310  return false;
311  }
312 }
313 
314 bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
315 {
316  if(locked)
317  {
318  // Lock
319  return m_wallet->lock();
320  }
321  else
322  {
323  // Unlock
324  return m_wallet->unlock(passPhrase);
325  }
326 }
327 
328 bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
329 {
330  m_wallet->lock(); // Make sure wallet is locked before attempting pass change
331  return m_wallet->changeWalletPassphrase(oldPass, newPass);
332 }
333 
334 // Handlers for core signals
335 static void NotifyUnload(WalletModel* walletModel)
336 {
337  qDebug() << "NotifyUnload";
338  bool invoked = QMetaObject::invokeMethod(walletModel, "unload");
339  assert(invoked);
340 }
341 
342 static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel)
343 {
344  qDebug() << "NotifyKeyStoreStatusChanged";
345  bool invoked = QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
346  assert(invoked);
347 }
348 
349 static void NotifyAddressBookChanged(WalletModel *walletmodel,
350  const CTxDestination &address, const std::string &label, bool isMine,
351  const std::string &purpose, ChangeType status)
352 {
353  QString strAddress = QString::fromStdString(EncodeDestination(address));
354  QString strLabel = QString::fromStdString(label);
355  QString strPurpose = QString::fromStdString(purpose);
356 
357  qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
358  bool invoked = QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
359  Q_ARG(QString, strAddress),
360  Q_ARG(QString, strLabel),
361  Q_ARG(bool, isMine),
362  Q_ARG(QString, strPurpose),
363  Q_ARG(int, status));
364  assert(invoked);
365 }
366 
367 static void NotifyTransactionChanged(WalletModel *walletmodel, const uint256 &hash, ChangeType status)
368 {
369  Q_UNUSED(hash);
370  Q_UNUSED(status);
371  bool invoked = QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection);
372  assert(invoked);
373 }
374 
375 static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
376 {
377  // emits signal "showProgress"
378  bool invoked = QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
379  Q_ARG(QString, QString::fromStdString(title)),
380  Q_ARG(int, nProgress));
381  assert(invoked);
382 }
383 
384 static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly)
385 {
386  bool invoked = QMetaObject::invokeMethod(walletmodel, "updateWatchOnlyFlag", Qt::QueuedConnection,
387  Q_ARG(bool, fHaveWatchonly));
388  assert(invoked);
389 }
390 
391 static void NotifyCanGetAddressesChanged(WalletModel* walletmodel)
392 {
393  bool invoked = QMetaObject::invokeMethod(walletmodel, "canGetAddressesChanged");
394  assert(invoked);
395 }
396 
398 {
399  // Connect signals to wallet
400  m_handler_unload = m_wallet->handleUnload(std::bind(&NotifyUnload, this));
401  m_handler_status_changed = m_wallet->handleStatusChanged(std::bind(&NotifyKeyStoreStatusChanged, this));
402  m_handler_address_book_changed = m_wallet->handleAddressBookChanged(std::bind(NotifyAddressBookChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
403  m_handler_transaction_changed = m_wallet->handleTransactionChanged(std::bind(NotifyTransactionChanged, this, std::placeholders::_1, std::placeholders::_2));
404  m_handler_show_progress = m_wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
405  m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(std::bind(NotifyWatchonlyChanged, this, std::placeholders::_1));
406  m_handler_can_get_addrs_changed = m_wallet->handleCanGetAddressesChanged(boost::bind(NotifyCanGetAddressesChanged, this));
407 }
408 
410 {
411  // Disconnect signals from wallet
412  m_handler_unload->disconnect();
413  m_handler_status_changed->disconnect();
414  m_handler_address_book_changed->disconnect();
415  m_handler_transaction_changed->disconnect();
416  m_handler_show_progress->disconnect();
417  m_handler_watch_only_changed->disconnect();
418  m_handler_can_get_addrs_changed->disconnect();
419 }
420 
421 // WalletModel::UnlockContext implementation
423 {
424  bool was_locked = getEncryptionStatus() == Locked;
425  if(was_locked)
426  {
427  // Request UI to unlock wallet
428  Q_EMIT requireUnlock();
429  }
430  // If wallet is still locked, unlock was failed or cancelled, mark context as invalid
431  bool valid = getEncryptionStatus() != Locked;
432 
433  return UnlockContext(this, valid, was_locked);
434 }
435 
436 WalletModel::UnlockContext::UnlockContext(WalletModel *_wallet, bool _valid, bool _relock):
437  wallet(_wallet),
438  valid(_valid),
439  relock(_relock)
440 {
441 }
442 
444 {
445  if(valid && relock)
446  {
447  wallet->setWalletLocked(true);
448  }
449 }
450 
452 {
453  // Transfer context; old object no longer relocks wallet
454  *this = rhs;
455  rhs.relock = false;
456 }
457 
458 void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
459 {
460  vReceiveRequests = m_wallet->getDestValues("rr"); // receive request
461 }
462 
463 bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
464 {
465  CTxDestination dest = DecodeDestination(sAddress);
466 
467  std::stringstream ss;
468  ss << nId;
469  std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
470 
471  if (sRequest.empty())
472  return m_wallet->eraseDestData(dest, key);
473  else
474  return m_wallet->addDestData(dest, key, sRequest);
475 }
476 
477 bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
478 {
479  CCoinControl coin_control;
480  coin_control.m_signal_bip125_rbf = true;
481  std::vector<std::string> errors;
482  CAmount old_fee;
483  CAmount new_fee;
485  if (!m_wallet->createBumpTransaction(hash, coin_control, 0 /* totalFee */, errors, old_fee, new_fee, mtx)) {
486  QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Increasing transaction fee failed") + "<br />(" +
487  (errors.size() ? QString::fromStdString(errors[0]) : "") +")");
488  return false;
489  }
490 
491  const bool create_psbt = privateKeysDisabled();
492 
493  // allow a user based fee verification
494  QString questionString = create_psbt ? tr("Do you want to draft a transaction with fee increase?") : tr("Do you want to increase the fee?");
495  questionString.append("<br />");
496  questionString.append("<table style=\"text-align: left;\">");
497  questionString.append("<tr><td>");
498  questionString.append(tr("Current fee:"));
499  questionString.append("</td><td>");
500  questionString.append(BitcoinUnits::formatHtmlWithUnit(getOptionsModel()->getDisplayUnit(), old_fee));
501  questionString.append("</td></tr><tr><td>");
502  questionString.append(tr("Increase:"));
503  questionString.append("</td><td>");
504  questionString.append(BitcoinUnits::formatHtmlWithUnit(getOptionsModel()->getDisplayUnit(), new_fee - old_fee));
505  questionString.append("</td></tr><tr><td>");
506  questionString.append(tr("New fee:"));
507  questionString.append("</td><td>");
508  questionString.append(BitcoinUnits::formatHtmlWithUnit(getOptionsModel()->getDisplayUnit(), new_fee));
509  questionString.append("</td></tr></table>");
510  SendConfirmationDialog confirmationDialog(tr("Confirm fee bump"), questionString);
511  confirmationDialog.exec();
512  QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result());
513 
514  // cancel sign&broadcast if user doesn't want to bump the fee
515  if (retval != QMessageBox::Yes) {
516  return false;
517  }
518 
520  if(!ctx.isValid())
521  {
522  return false;
523  }
524 
525  // Short-circuit if we are returning a bumped transaction PSBT to clipboard
526  if (create_psbt) {
527  PartiallySignedTransaction psbtx(mtx);
528  bool complete = false;
529  const TransactionError err = wallet().fillPSBT(psbtx, complete, SIGHASH_ALL, false /* sign */, true /* bip32derivs */);
530  if (err != TransactionError::OK || complete) {
531  QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't draft transaction."));
532  return false;
533  }
534  // Serialize the PSBT
536  ssTx << psbtx;
537  GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str());
538  Q_EMIT message(tr("PSBT copied"), "Copied to clipboard", CClientUIInterface::MSG_INFORMATION);
539  return true;
540  }
541 
542  // sign bumped transaction
543  if (!m_wallet->signBumpTransaction(mtx)) {
544  QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't sign transaction."));
545  return false;
546  }
547  // commit the bumped transaction
548  if(!m_wallet->commitBumpTransaction(hash, std::move(mtx), errors, new_hash)) {
549  QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Could not commit transaction") + "<br />(" +
550  QString::fromStdString(errors[0])+")");
551  return false;
552  }
553  return true;
554 }
555 
557 {
558  return !gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
559 }
560 
562 {
563  return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
564 }
565 
567 {
568  return m_wallet->canGetAddresses();
569 }
570 
572 {
573  return QString::fromStdString(m_wallet->getWalletName());
574 }
575 
577 {
578  const QString name = getWalletName();
579  return name.isEmpty() ? "["+tr("default wallet")+"]" : name;
580 }
581 
583 {
584  return m_node.getWallets().size() > 1;
585 }
void loadReceiveRequests(std::vector< std::string > &vReceiveRequests)
Model for list of recently generated payment requests / bitcoin: URIs.
TransactionTableModel * transactionTableModel
Definition: walletmodel.h:174
std::shared_ptr< CWallet > m_wallet
Definition: wallet.cpp:512
interfaces::Wallet & wallet() const
Definition: walletmodel.h:147
void coinsSent(WalletModel *wallet, SendCoinsRecipient recipient, QByteArray transaction)
RecentRequestsTableModel * recentRequestsTableModel
Definition: walletmodel.h:175
std::unique_ptr< interfaces::Handler > m_handler_address_book_changed
Definition: walletmodel.h:159
static bool isWalletEnabled()
void startPollBalance()
Definition: walletmodel.cpp:56
bool IsValidDestinationString(const std::string &str, const CChainParams &params)
Definition: key_io.cpp:220
NodeContext & m_node
Definition: chain.cpp:374
UnlockContext requestUnlock()
std::unique_ptr< interfaces::Handler > m_handler_unload
Definition: walletmodel.h:157
void unsubscribeFromCoreSignals()
static QString formatHtmlWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as HTML string (with unit)
std::string str() const
Definition: streams.h:279
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:60
SendCoinsReturn sendCoins(WalletModelTransaction &transaction)
QList< SendCoinsRecipient > getRecipients() const
static const bool DEFAULT_DISABLE_WALLET
Definition: wallet.h:82
std::unique_ptr< interfaces::Handler > m_handler_status_changed
Definition: walletmodel.h:158
A version of CTransaction with the PSBT format.
Definition: psbt.h:388
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:201
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:384
virtual std::vector< std::unique_ptr< Wallet > > getWallets()=0
Return interfaces for accessing wallets (if any).
AddressTableModel * getAddressTableModel()
Coin Control Features.
Definition: coincontrol.h:22
void updateStatus()
Definition: walletmodel.cpp:64
EncryptionStatus getEncryptionStatus() const
void setTransactionFee(const CAmount &newFee)
bool bumpFee(uint256 hash, uint256 &new_hash)
UnlockContext(WalletModel *wallet, bool valid, bool relock)
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
Optional< bool > m_signal_bip125_rbf
Override the wallet&#39;s m_signal_rbf if set.
Definition: coincontrol.h:40
static void NotifyCanGetAddressesChanged(WalletModel *walletmodel)
void push_back(const T &value)
Definition: prevector.h:427
bool canGetAddresses() const
size_type size() const
Definition: streams.h:292
void updateTransaction()
ChangeType
General change type (added, updated, removed).
Definition: ui_interface.h:21
Collection of wallet balances.
Definition: wallet.h:314
void setClipboard(const QString &str)
Definition: guiutil.cpp:704
const char * name
Definition: rest.cpp:40
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass)
static void NotifyAddressBookChanged(WalletModel *walletmodel, const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)
static secp256k1_context * ctx
Definition: tests.c:46
void reassignAmounts(int nChangePosRet)
std::string EncodeBase64(const unsigned char *pch, size_t len)
bool privateKeysDisabled() const
std::unique_ptr< interfaces::Wallet > m_wallet
Definition: walletmodel.h:156
SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl &coinControl)
void encryptionStatusChanged()
OptionsModel * optionsModel
Definition: walletmodel.h:171
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:289
QString getWalletName() const
TransactionTableModel * getTransactionTableModel()
EncryptionStatus cachedEncryptionStatus
Definition: walletmodel.h:179
UI model for the transaction table of a wallet.
Qt model of the address book in the core.
static const int MODEL_UPDATE_DELAY
Definition: guiconstants.h:11
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString())
std::unique_ptr< interfaces::Handler > m_handler_show_progress
Definition: walletmodel.h:161
bool validateAddress(const QString &address)
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel)
void updateWatchOnlyFlag(bool fHaveWatchonly)
static void NotifyUnload(WalletModel *walletModel)
256-bit opaque blob.
Definition: uint256.h:120
int cachedNumBlocks
Definition: walletmodel.h:180
WalletModel(std::unique_ptr< interfaces::Wallet > wallet, interfaces::Node &node, const PlatformStyle *platformStyle, OptionsModel *optionsModel, QObject *parent=nullptr)
Definition: walletmodel.cpp:36
CTxDestination DecodeDestination(const std::string &str)
Definition: key_io.cpp:215
void requireUnlock()
bool fForceCheckBalanceChanged
Definition: walletmodel.h:167
std::unique_ptr< interfaces::Handler > m_handler_can_get_addrs_changed
Definition: walletmodel.h:163
RecentRequestsTableModel * getRecentRequestsTableModel()
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:36
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:390
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:50
interfaces::WalletBalances m_cached_balances
Definition: walletmodel.h:178
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase)
interfaces::Node & m_node
Definition: walletmodel.h:164
static void NotifyTransactionChanged(WalletModel *walletmodel, const uint256 &hash, ChangeType status)
void message(const QString &title, const QString &message, unsigned int style)
ArgsManager gArgs
Definition: system.cpp:76
TransactionError
Definition: error.h:22
void CopyFrom(UnlockContext &&rhs)
void notifyWatchonlyChanged(bool fHaveWatchonly)
Data model for a walletmodel transaction.
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:210
QString getDisplayName() const
A mutable version of CTransaction.
Definition: transaction.h:366
AddressTableModel * addressTableModel
Definition: walletmodel.h:173
static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly)
std::unique_ptr< interfaces::Handler > m_handler_transaction_changed
Definition: walletmodel.h:160
bool isMultiwallet()
bool fHaveWatchOnly
Definition: walletmodel.h:166
virtual void commitTransaction(CTransactionRef tx, WalletValueMap value_map, WalletOrderForm order_form)=0
Commit transaction.
void checkBalanceChanged(const interfaces::WalletBalances &new_balances)
Definition: walletmodel.cpp:98
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:143
static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
bool balanceChanged(const WalletBalances &prev) const
Definition: wallet.h:324
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:39
void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
void balanceChanged(const interfaces::WalletBalances &balances)
std::unique_ptr< interfaces::Handler > m_handler_watch_only_changed
Definition: walletmodel.h:162
void pollBalanceChanged()
Definition: walletmodel.cpp:73
OptionsModel * getOptionsModel()
void subscribeToCoreSignals()
Predefined combinations for certain default usage cases.
Definition: ui_interface.h:74