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