Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

walletmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2014-2020 The Dash Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <qt/walletmodel.h>
7 
8 #include <qt/addresstablemodel.h>
9 #include <consensus/validation.h>
10 #include <qt/guiconstants.h>
11 #include <qt/guiutil.h>
12 #include <qt/paymentserver.h>
15 
16 #include <base58.h>
17 #include <chain.h>
18 #include <keystore.h>
19 #include <validation.h>
20 #include <net.h> // for g_connman
21 #include <sync.h>
22 #include <txmempool.h>
23 #include <ui_interface.h>
24 #include <util.h> // for GetBoolArg
25 #include <wallet/coincontrol.h>
26 #include <wallet/wallet.h>
27 #include <wallet/walletdb.h> // for BackupWallet
28 
29 #include <spork.h>
32 
33 #include <stdint.h>
34 
35 #include <QDebug>
36 #include <QSet>
37 #include <QTimer>
38 
39 
40 WalletModel::WalletModel(CWallet* _wallet, OptionsModel* _optionsModel, QObject* parent) :
41  QObject(parent), wallet(_wallet), optionsModel(_optionsModel), addressTableModel(0),
42  transactionTableModel(0),
43  recentRequestsTableModel(0),
44  cachedBalance(0),
45  cachedUnconfirmedBalance(0),
46  cachedImmatureBalance(0),
47  cachedAnonymizedBalance(0),
48  cachedWatchOnlyBalance(0),
49  cachedWatchUnconfBalance(0),
50  cachedWatchImmatureBalance(0),
51  cachedEncryptionStatus(Unencrypted),
52  cachedNumBlocks(0),
53  cachedNumISLocks(0),
54  cachedPrivateSendRounds(0)
55 {
58 
62 
63  // This timer will be fired repeatedly to update the balance
64  pollTimer = new QTimer(this);
65  connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollBalanceChanged()));
67 
69 }
70 
72 {
74 }
75 
76 CAmount WalletModel::getBalance(const CCoinControl *coinControl) const
77 {
78  if (coinControl)
79  {
80  return wallet->GetAvailableBalance(coinControl);
81  }
82 
83  return wallet->GetBalance();
84 }
85 
86 
87 CAmount WalletModel::getAnonymizableBalance(bool fSkipDenominated, bool fSkipUnconfirmed) const
88 {
89  return wallet->GetAnonymizableBalance(fSkipDenominated, fSkipUnconfirmed);
90 }
91 
93 {
94  return wallet->GetAnonymizedBalance(coinControl);
95 }
96 
98 {
99  return wallet->GetDenominatedBalance(unconfirmed);
100 }
101 
103 {
105 }
106 
108 {
110 }
111 
113 {
114  return wallet->GetUnconfirmedBalance();
115 }
116 
118 {
119  return wallet->GetImmatureBalance();
120 }
121 
123 {
124  return fHaveWatchOnly;
125 }
126 
128 {
129  return wallet->GetWatchOnlyBalance();
130 }
131 
133 {
135 }
136 
138 {
140 }
141 
143 {
144  EncryptionStatus newEncryptionStatus = getEncryptionStatus();
145 
146  if(cachedEncryptionStatus != newEncryptionStatus)
147  Q_EMIT encryptionStatusChanged(newEncryptionStatus);
148 }
149 
151 {
152  // Get required locks upfront. This avoids the GUI from getting stuck on
153  // periodical polls if the core is holding the locks for a longer time -
154  // for example, during a wallet rescan.
155  TRY_LOCK(cs_main, lockMain);
156  if(!lockMain)
157  return;
158  TRY_LOCK(wallet->cs_wallet, lockWallet);
159  if(!lockWallet)
160  return;
161 
163  {
165 
166  // Balance and number of transactions might have changed
169 
173  }
174 }
175 
177 {
178  CAmount newBalance = getBalance();
179  CAmount newUnconfirmedBalance = getUnconfirmedBalance();
180  CAmount newImmatureBalance = getImmatureBalance();
181  CAmount newAnonymizedBalance = getAnonymizedBalance();
182  CAmount newWatchOnlyBalance = 0;
183  CAmount newWatchUnconfBalance = 0;
184  CAmount newWatchImmatureBalance = 0;
185  if (haveWatchOnly())
186  {
187  newWatchOnlyBalance = getWatchBalance();
188  newWatchUnconfBalance = getWatchUnconfirmedBalance();
189  newWatchImmatureBalance = getWatchImmatureBalance();
190  }
191 
192  if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance ||
193  cachedAnonymizedBalance != newAnonymizedBalance ||
194  cachedWatchOnlyBalance != newWatchOnlyBalance || cachedWatchUnconfBalance != newWatchUnconfBalance || cachedWatchImmatureBalance != newWatchImmatureBalance)
195  {
196  cachedBalance = newBalance;
197  cachedUnconfirmedBalance = newUnconfirmedBalance;
198  cachedImmatureBalance = newImmatureBalance;
199  cachedAnonymizedBalance = newAnonymizedBalance;
200  cachedWatchOnlyBalance = newWatchOnlyBalance;
201  cachedWatchUnconfBalance = newWatchUnconfBalance;
202  cachedWatchImmatureBalance = newWatchImmatureBalance;
203  Q_EMIT balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance, newAnonymizedBalance,
204  newWatchOnlyBalance, newWatchUnconfBalance, newWatchImmatureBalance);
205  }
206 }
207 
209 {
210  // Balance and number of transactions might have changed
212 }
213 
215 {
217 }
218 
219 void WalletModel::updateChainLockHeight(int chainLockHeight)
220 {
223  // Number and status of confirmations might have changed (WalletModel::pollBalanceChanged handles this as well)
225 }
226 
228 {
229  return cachedNumISLocks;
230 }
231 
233 {
234  return wallet->GetRealOutpointPrivateSendRounds(outpoint);
235 }
236 
237 bool WalletModel::isFullyMixed(const COutPoint& outpoint) const
238 {
239  return wallet->IsFullyMixed(outpoint);
240 }
241 
242 void WalletModel::updateAddressBook(const QString &address, const QString &label,
243  bool isMine, const QString &purpose, int status)
244 {
246  addressTableModel->updateEntry(address, label, isMine, purpose, status);
247 }
248 
249 void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly)
250 {
251  fHaveWatchOnly = fHaveWatchonly;
252  Q_EMIT notifyWatchonlyChanged(fHaveWatchonly);
253 }
254 
255 bool WalletModel::validateAddress(const QString &address)
256 {
257  return IsValidDestinationString(address.toStdString());
258 }
259 
261 {
262  CAmount total = 0;
263  bool fSubtractFeeFromAmount = false;
264  QList<SendCoinsRecipient> recipients = transaction.getRecipients();
265  std::vector<CRecipient> vecSend;
266 
267  if(recipients.empty())
268  {
269  return OK;
270  }
271 
272  // This should never really happen, yet another safety check, just in case.
273  if(wallet->IsLocked()) {
275  }
276 
277  QSet<QString> setAddress; // Used to detect duplicates
278  int nAddresses = 0;
279 
280  // Pre-check input data for validity
281  for (const SendCoinsRecipient &rcp : recipients)
282  {
283  if (rcp.fSubtractFeeFromAmount)
284  fSubtractFeeFromAmount = true;
285 
286  if (rcp.paymentRequest.IsInitialized())
287  { // PaymentRequest...
288  CAmount subtotal = 0;
289  const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
290  for (int i = 0; i < details.outputs_size(); i++)
291  {
292  const payments::Output& out = details.outputs(i);
293  if (out.amount() <= 0) continue;
294  subtotal += out.amount();
295  const unsigned char* scriptStr = (const unsigned char*)out.script().data();
296  CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
297  CAmount nAmount = out.amount();
298  CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
299  vecSend.push_back(recipient);
300  }
301  if (subtotal <= 0)
302  {
303  return InvalidAmount;
304  }
305  total += subtotal;
306  }
307  else
308  { // User-entered dash address / amount:
309  if(!validateAddress(rcp.address))
310  {
311  return InvalidAddress;
312  }
313  if(rcp.amount <= 0)
314  {
315  return InvalidAmount;
316  }
317  setAddress.insert(rcp.address);
318  ++nAddresses;
319 
320  CScript scriptPubKey = GetScriptForDestination(DecodeDestination(rcp.address.toStdString()));
321  CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
322  vecSend.push_back(recipient);
323 
324  total += rcp.amount;
325  }
326  }
327  if(setAddress.size() != nAddresses)
328  {
329  return DuplicateAddress;
330  }
331 
332  CAmount nBalance = getBalance(&coinControl);
333 
334  if(total > nBalance)
335  {
336  return AmountExceedsBalance;
337  }
338 
339  CAmount nFeeRequired = 0;
340  CAmount nValueOut = 0;
341  size_t nVinSize = 0;
342  bool fCreated;
343  std::string strFailReason;
344  {
347 
348  transaction.newPossibleKeyChange(wallet);
349 
350  int nChangePosRet = -1;
351 
352  CWalletTx* newTx = transaction.getTransaction();
353  CReserveKey *keyChange = transaction.getPossibleKeyChange();
354 
355  fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
356  transaction.setTransactionFee(nFeeRequired);
357  if (fSubtractFeeFromAmount && fCreated)
358  transaction.reassignAmounts();
359 
360  nValueOut = newTx->tx->GetValueOut();
361  nVinSize = newTx->tx->vin.size();
362  }
363 
364  if(!fCreated)
365  {
366  if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
367  {
369  }
370  Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
373  }
374 
375  // reject absurdly high fee. (This can never happen because the
376  // wallet caps the fee at maxTxFee. This merely serves as a
377  // belt-and-suspenders check)
378  if (nFeeRequired > maxTxFee)
379  return AbsurdFee;
380 
381  return SendCoinsReturn(OK);
382 }
383 
385 {
386  QByteArray transaction_array; /* store serialized transaction */
387 
388  {
391 
392  CWalletTx *newTx = transaction.getTransaction();
393  QList<SendCoinsRecipient> recipients = transaction.getRecipients();
394 
395  for (const SendCoinsRecipient &rcp : recipients)
396  {
397  if (rcp.paymentRequest.IsInitialized())
398  {
399  // Make sure any payment requests involved are still valid.
400  if (PaymentServer::verifyExpired(rcp.paymentRequest.getDetails())) {
401  return PaymentRequestExpired;
402  }
403 
404  // Store PaymentRequests in wtx.vOrderForm in wallet.
405  std::string key("PaymentRequest");
406  std::string value;
407  rcp.paymentRequest.SerializeToString(&value);
408  newTx->vOrderForm.push_back(make_pair(key, value));
409  }
410  else if (!rcp.message.isEmpty()) // Message from normal dash:URI (dash:XyZ...?message=example)
411  {
412  newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
413  }
414  }
415 
416  CReserveKey *keyChange = transaction.getPossibleKeyChange();
417  CValidationState state;
418  if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), state))
419  return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason()));
420 
422  ssTx << *newTx->tx;
423  transaction_array.append(ssTx.data(), ssTx.size());
424  }
425 
426  // Add addresses / update labels that we've sent to the address book,
427  // and emit coinsSent signal for each recipient
428  for (const SendCoinsRecipient &rcp : transaction.getRecipients())
429  {
430  // Don't touch the address book when we have a payment request
431  if (!rcp.paymentRequest.IsInitialized())
432  {
433  std::string strAddress = rcp.address.toStdString();
434  CTxDestination dest = DecodeDestination(strAddress);
435  std::string strLabel = rcp.label.toStdString();
436  {
438 
439  std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);
440 
441  // Check if we have a new address or an updated label
442  if (mi == wallet->mapAddressBook.end())
443  {
444  wallet->SetAddressBook(dest, strLabel, "send");
445  }
446  else if (mi->second.name != strLabel)
447  {
448  wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
449  }
450  }
451  }
452  Q_EMIT coinsSent(wallet, rcp, transaction_array);
453  }
454  checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits
455 
456  return SendCoinsReturn(OK);
457 }
458 
460 {
461  return optionsModel;
462 }
463 
465 {
466  return addressTableModel;
467 }
468 
470 {
471  return transactionTableModel;
472 }
473 
475 {
477 }
478 
480 {
481  if(!wallet->IsCrypted())
482  {
483  return Unencrypted;
484  }
485  else if(wallet->IsLocked(true))
486  {
487  return Locked;
488  }
489  else if (wallet->IsLocked())
490  {
491  return UnlockedForMixingOnly;
492  }
493  else
494  {
495  return Unlocked;
496  }
497 }
498 
499 bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase)
500 {
501  if(encrypted)
502  {
503  // Encrypt
504  return wallet->EncryptWallet(passphrase);
505  }
506  else
507  {
508  // Decrypt -- TODO; not supported yet
509  return false;
510  }
511 }
512 
513 bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase, bool fMixing)
514 {
515  if(locked)
516  {
517  // Lock
518  return wallet->Lock(fMixing);
519  }
520  else
521  {
522  // Unlock
523  return wallet->Unlock(passPhrase, fMixing);
524  }
525 }
526 
527 bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
528 {
529  bool retval;
530  {
532  wallet->Lock(); // Make sure wallet is locked before attempting pass change
533  retval = wallet->ChangeWalletPassphrase(oldPass, newPass);
534  }
535  return retval;
536 }
537 
538 bool WalletModel::backupWallet(const QString &filename)
539 {
540  return wallet->BackupWallet(filename.toLocal8Bit().data());
541 }
542 
543 bool WalletModel::autoBackupWallet(QString& strBackupWarningRet, QString& strBackupErrorRet)
544 {
545  std::string strBackupWarning;
546  std::string strBackupError;
547  bool result = wallet->AutoBackupWallet("", strBackupWarning, strBackupError);
548  strBackupWarningRet = QString::fromStdString(strBackupWarning);
549  strBackupErrorRet = QString::fromStdString(strBackupError);
550  return result;
551 }
552 
554 {
556 }
557 
558 // Handlers for core signals
559 static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet)
560 {
561  qDebug() << "NotifyKeyStoreStatusChanged";
562  QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
563 }
564 
565 static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
566  const CTxDestination &address, const std::string &label, bool isMine,
567  const std::string &purpose, ChangeType status)
568 {
569  QString strAddress = QString::fromStdString(EncodeDestination(address));
570  QString strLabel = QString::fromStdString(label);
571  QString strPurpose = QString::fromStdString(purpose);
572 
573  qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
574  QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
575  Q_ARG(QString, strAddress),
576  Q_ARG(QString, strLabel),
577  Q_ARG(bool, isMine),
578  Q_ARG(QString, strPurpose),
579  Q_ARG(int, status));
580 }
581 
582 static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
583 {
584  Q_UNUSED(wallet);
585  Q_UNUSED(hash);
586  Q_UNUSED(status);
587  QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection);
588 }
589 
590 static void NotifyISLockReceived(WalletModel *walletmodel)
591 {
592  QMetaObject::invokeMethod(walletmodel, "updateNumISLocks", Qt::QueuedConnection);
593 }
594 
595 static void NotifyChainLockReceived(WalletModel *walletmodel, int chainLockHeight)
596 {
597  QMetaObject::invokeMethod(walletmodel, "updateChainLockHeight", Qt::QueuedConnection,
598  Q_ARG(int, chainLockHeight));
599 }
600 
601 static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
602 {
603  // emits signal "showProgress"
604  QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
605  Q_ARG(QString, QString::fromStdString(title)),
606  Q_ARG(int, nProgress));
607 }
608 
609 static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly)
610 {
611  QMetaObject::invokeMethod(walletmodel, "updateWatchOnlyFlag", Qt::QueuedConnection,
612  Q_ARG(bool, fHaveWatchonly));
613 }
614 
616 {
617  // Connect signals to wallet
618  wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
619  wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
620  wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
621  wallet->NotifyISLockReceived.connect(boost::bind(NotifyISLockReceived, this));
622  wallet->NotifyChainLockReceived.connect(boost::bind(NotifyChainLockReceived, this, _1));
623  wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
624  wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1));
625 }
626 
628 {
629  // Disconnect signals from wallet
630  wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
631  wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
632  wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
633  wallet->NotifyISLockReceived.disconnect(boost::bind(NotifyISLockReceived, this));
634  wallet->NotifyChainLockReceived.disconnect(boost::bind(NotifyChainLockReceived, this, _1));
635  wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
636  wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1));
637 }
638 
639 // WalletModel::UnlockContext implementation
641 {
642  EncryptionStatus encStatusOld = getEncryptionStatus();
643 
644  // Wallet was completely locked
645  bool was_locked = (encStatusOld == Locked);
646  // Wallet was unlocked for mixing
647  bool was_mixing = (encStatusOld == UnlockedForMixingOnly);
648  // Wallet was unlocked for mixing and now user requested to fully unlock it
649  bool fMixingToFullRequested = !fForMixingOnly && was_mixing;
650 
651  if(was_locked || fMixingToFullRequested) {
652  // Request UI to unlock wallet
653  Q_EMIT requireUnlock(fForMixingOnly);
654  }
655 
656  EncryptionStatus encStatusNew = getEncryptionStatus();
657 
658  // Wallet was locked, user requested to unlock it for mixing and failed to do so
659  bool fMixingUnlockFailed = fForMixingOnly && !(encStatusNew == UnlockedForMixingOnly);
660  // Wallet was unlocked for mixing, user requested to fully unlock it and failed
661  bool fMixingToFullFailed = fMixingToFullRequested && !(encStatusNew == Unlocked);
662  // If wallet is still locked, unlock failed or was cancelled, mark context as invalid
663  bool fInvalid = (encStatusNew == Locked) || fMixingUnlockFailed || fMixingToFullFailed;
664  // Wallet was not locked in any way or user tried to unlock it for mixing only and succeeded, keep it unlocked
665  bool fKeepUnlocked = !was_locked || (fForMixingOnly && !fMixingUnlockFailed);
666 
667  return UnlockContext(this, !fInvalid, !fKeepUnlocked, was_mixing);
668 }
669 
670 WalletModel::UnlockContext::UnlockContext(WalletModel *_wallet, bool _valid, bool _was_locked, bool _was_mixing):
671  wallet(_wallet),
672  valid(_valid),
673  was_locked(_was_locked),
674  was_mixing(_was_mixing)
675 {
676 }
677 
679 {
680  if(valid && (was_locked || was_mixing))
681  {
682  wallet->setWalletLocked(true, "", was_mixing);
683  }
684 }
685 
687 {
688  // Transfer context; old object no longer relocks wallet
689  *this = rhs;
690  rhs.was_locked = false;
691  rhs.was_mixing = false;
692 }
693 
694 bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
695 {
696  return wallet->GetPubKey(address, vchPubKeyOut);
697 }
698 
700 {
701  return IsMine(*wallet, dest) & ISMINE_SPENDABLE;
702 }
703 
704 bool WalletModel::IsSpendable(const CScript& script) const
705 {
706  return IsMine(*wallet, script) & ISMINE_SPENDABLE;
707 }
708 
709 bool WalletModel::getPrivKey(const CKeyID &address, CKey& vchPrivKeyOut) const
710 {
711  return wallet->GetKey(address, vchPrivKeyOut);
712 }
713 
714 // returns a list of COutputs from COutPoints
715 void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
716 {
718  for (const COutPoint& outpoint : vOutpoints)
719  {
720  auto it = wallet->mapWallet.find(outpoint.hash);
721  if (it == wallet->mapWallet.end()) continue;
722  int nDepth = it->second.GetDepthInMainChain();
723  if (nDepth < 0) continue;
724  COutput out(&it->second, outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */);
725  vOutputs.push_back(out);
726  }
727 }
728 
729 bool WalletModel::isSpent(const COutPoint& outpoint) const
730 {
732  return wallet->IsSpent(outpoint.hash, outpoint.n);
733 }
734 
735 // AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address)
736 void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const
737 {
738  for (auto& group : wallet->ListCoins()) {
739  auto& resultGroup = mapCoins[QString::fromStdString(EncodeDestination(group.first))];
740  for (auto& coin : group.second) {
741  resultGroup.emplace_back(std::move(coin));
742  }
743  }
744 }
745 
746 bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const
747 {
749  return wallet->IsLockedCoin(hash, n);
750 }
751 
753 {
755  wallet->LockCoin(output);
756 }
757 
759 {
761  wallet->UnlockCoin(output);
762 }
763 
764 void WalletModel::listLockedCoins(std::vector<COutPoint>& vOutpts)
765 {
767  wallet->ListLockedCoins(vOutpts);
768 }
769 
770 void WalletModel::listProTxCoins(std::vector<COutPoint>& vOutpts)
771 {
773  wallet->ListProTxCoins(vOutpts);
774 }
775 
776 void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
777 {
778  vReceiveRequests = wallet->GetDestValues("rr"); // receive request
779 }
780 
781 bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
782 {
783  CTxDestination dest = DecodeDestination(sAddress);
784 
785  std::stringstream ss;
786  ss << nId;
787  std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
788 
790  if (sRequest.empty())
791  return wallet->EraseDestData(dest, key);
792  else
793  return wallet->AddDestData(dest, key, sRequest);
794 }
795 
797 {
798  return wallet->TransactionCanBeAbandoned(hash);
799 }
800 
802 {
804  return wallet->AbandonTransaction(hash);
805 }
806 
808 {
809  return !gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
810 }
811 
813 {
814  return wallet->IsHDEnabled();
815 }
816 
818 {
819  return nTxConfirmTarget;
820 }
bool abandonTransaction(uint256 hash) const
void loadReceiveRequests(std::vector< std::string > &vReceiveRequests)
bool isLockedCoin(uint256 hash, unsigned int n) const
void listCoins(std::map< QString, std::vector< COutput > > &mapCoins) const
CTxMemPool mempool
Model for list of recently generated payment requests / dash: URIs.
TransactionTableModel * transactionTableModel
Definition: walletmodel.h:245
void getOutputs(const std::vector< COutPoint > &vOutpoints, std::vector< COutput > &vOutputs)
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:80
bool Lock(bool fForMixing=false)
Definition: crypter.cpp:230
RecentRequestsTableModel * recentRequestsTableModel
Definition: walletmodel.h:246
CAmount GetImmatureBalance() const
Definition: wallet.cpp:2666
void lockCoin(COutPoint &output)
UnlockContext(WalletModel *wallet, bool valid, bool was_locked, bool was_mixing)
CWalletTx * getTransaction() const
#define TRY_LOCK(cs, name)
Definition: sync.h:180
static bool isWalletEnabled()
CAmount GetAvailableBalance(const CCoinControl *coinControl=nullptr) const
Definition: wallet.cpp:2760
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:906
std::vector< std::string > GetDestValues(const std::string &prefix) const
Get all destination values matching a prefix.
Definition: wallet.cpp:5010
CCriticalSection cs_wallet
Definition: wallet.h:836
CAmount maxTxFee
Absolute maximum transaction fee (in duffs) used by wallet and mempool (rejects high fee in sendrawtr...
Definition: validation.cpp:247
void requireUnlock(bool fForMixingOnly=false)
bool IsCrypted() const
Definition: crypter.h:155
void unsubscribeFromCoreSignals()
void updateChainLockHeight(int chainLockHeight)
int Height() const
Return the maximal height in the chain.
Definition: chain.h:484
static const bool DEFAULT_DISABLE_WALLET
Definition: wallet.h:76
CCriticalSection cs_main
Definition: validation.cpp:213
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:336
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
bool backupWallet(const QString &filename)
value_type * data()
Definition: streams.h:203
bool AutoBackupWallet(const fs::path &wallet_path, std::string &strBackupWarningRet, std::string &strBackupErrorRet)
Definition: wallet.cpp:5327
SendCoinsReturn sendCoins(WalletModelTransaction &transaction)
bool transactionCanBeAbandoned(uint256 hash) const
QList< SendCoinsRecipient > getRecipients() const
bool fSubtractFeeFromAmount
Definition: wallet.h:171
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:103
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:824
CAmount GetUnconfirmedWatchOnlyBalance() const
Definition: wallet.cpp:2692
AddressTableModel * getAddressTableModel()
Keystore which keeps the private keys encrypted.
Definition: crypter.h:119
CAmount getDenominatedBalance(bool unconfirmed) const
Definition: walletmodel.cpp:97
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:797
bool IsSpent(const uint256 &hash, unsigned int n) const
Outpoint is spent if any non-conflicted transaction spends it:
Definition: wallet.cpp:755
Coin Control Features.
Definition: coincontrol.h:28
CAmount GetBalance() const
Definition: wallet.cpp:2541
bool haveWatchOnly() const
void updateStatus()
void newPossibleKeyChange(CWallet *wallet)
EncryptionStatus getEncryptionStatus() const
CAmount cachedAnonymizedBalance
Definition: walletmodel.h:252
CAmount getBalance(const CCoinControl *coinControl=nullptr) const
Definition: walletmodel.cpp:76
void setTransactionFee(const CAmount &newFee)
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
boost::signals2::signal< void(CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
Definition: wallet.h:1197
CAmount getImmatureBalance() const
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:4277
WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent=0)
Definition: walletmodel.cpp:40
boost::signals2::signal< void(CCryptoKeyStore *wallet)> NotifyStatusChanged
Wallet status (encrypted, locked) changed.
Definition: crypter.h:172
void checkBalanceChanged()
#define LOCK2(cs1, cs2)
Definition: sync.h:179
bool getPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
void push_back(const T &value)
Definition: prevector.h:455
unsigned int nTxConfirmTarget
Definition: wallet.cpp:96
void updateChainLockHeight(int chainLockHeight)
bool IsValidDestinationString(const std::string &str, const CChainParams &params)
Definition: base58.cpp:341
boost::signals2::signal< void(int height)> NotifyChainLockReceived
ChainLock received.
Definition: wallet.h:1209
CWallet * wallet
Definition: walletmodel.h:236
CAmount GetAnonymizableBalance(bool fSkipDenominated=false, bool fSkipUnconfirmed=true) const
Definition: wallet.cpp:2555
int64_t getKeysLeftSinceAutoBackup() const
bool AbandonTransaction(const uint256 &hashTx)
Definition: wallet.cpp:1283
size_type size() const
Definition: streams.h:194
void UnlockCoin(const COutPoint &output)
Definition: wallet.cpp:4803
void updateTransaction()
CAmount cachedImmatureBalance
Definition: walletmodel.h:251
ChangeType
General change type (added, updated, removed).
Definition: ui_interface.h:20
bool getPrivKey(const CKeyID &address, CKey &vchPrivKeyOut) const
CTransactionRef tx
Definition: wallet.h:210
bool IsHDEnabled() const
HD Wallet Functions.
Definition: wallet.cpp:1847
#define LOCK(cs)
Definition: sync.h:178
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass)
bool GetKey(const CKeyID &address, CKey &keyOut) const override
GetKey implementation that can derive a HD private key on the fly.
Definition: wallet.cpp:300
void listProTxCoins(std::vector< COutPoint > &vOutpts)
void ListProTxCoins(std::vector< COutPoint > &vOutpts)
Definition: wallet.cpp:4838
int getDefaultConfirmTarget() const
int64_t nKeysLeftSinceAutoBackup
Definition: wallet.h:910
CAmount getWatchUnconfirmedBalance() const
An encapsulated public key.
Definition: pubkey.h:30
bool TransactionCanBeAbandoned(const uint256 &hashTx) const
Return whether transaction can be abandoned.
Definition: wallet.cpp:1276
bool IsLockedCoin(uint256 hash, unsigned int n) const
Definition: wallet.cpp:4820
std::string GetRejectReason() const
Definition: validation.h:81
uint32_t n
Definition: transaction.h:30
CAmount GetUnconfirmedBalance() const
Definition: wallet.cpp:2653
SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl &coinControl)
CAmount GetImmatureWatchOnlyBalance() const
Definition: wallet.cpp:2705
static bool verifyExpired(const payments::PaymentDetails &requestDetails)
bool EraseDestData(const CTxDestination &dest, const std::string &key)
Erases a destination data tuple in the store and on disk.
Definition: wallet.cpp:4981
CAmount cachedBalance
Definition: walletmodel.h:249
bool isSpent(const COutPoint &outpoint) const
OptionsModel * optionsModel
Definition: walletmodel.h:242
CAmount cachedWatchOnlyBalance
Definition: walletmodel.h:253
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:256
CAmount getAnonymizedBalance(const CCoinControl *coinControl=nullptr) const
Definition: walletmodel.cpp:92
TransactionTableModel * getTransactionTableModel()
CAmount GetDenominatedBalance(bool unconfirmed=false) const
Definition: wallet.cpp:2638
EncryptionStatus cachedEncryptionStatus
Definition: walletmodel.h:256
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
void CopyFrom(const UnlockContext &rhs)
UI model for the transaction table of a wallet.
void updateNumISLocks()
CAmount GetAnonymizedBalance(const CCoinControl *coinControl=nullptr) const
Definition: wallet.cpp:2577
void LockCoin(const COutPoint &output)
Definition: wallet.cpp:4792
Qt model of the address book in the core.
bool Unlock(const SecureString &strWalletPassphrase, bool fForMixingOnly=false)
Definition: wallet.cpp:524
CCriticalSection cs
Definition: txmempool.h:488
static const int MODEL_UPDATE_DELAY
Definition: guiconstants.h:10
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:280
CAmount GetNormalizedAnonymizedBalance() const
Definition: wallet.cpp:2616
void encryptionStatusChanged(int status)
QTimer * pollTimer
Definition: walletmodel.h:261
CAmount GetWatchOnlyBalance() const
Definition: wallet.cpp:2678
static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)
bool validateAddress(const QString &address)
void updateWatchOnlyFlag(bool fHaveWatchonly)
Capture information about block/transaction validation.
Definition: validation.h:22
256-bit opaque blob.
Definition: uint256.h:123
int cachedNumBlocks
Definition: walletmodel.h:257
CAmount cachedWatchUnconfBalance
Definition: walletmodel.h:254
ArgsManager gArgs
Definition: util.cpp:108
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
bool IsFullyMixed(const COutPoint &outpoint) const
Definition: wallet.cpp:1680
bool fForceCheckBalanceChanged
Definition: walletmodel.h:238
CAmount getAverageAnonymizedRounds() const
CAmount cachedWatchImmatureBalance
Definition: walletmodel.h:255
std::map< CTxDestination, std::vector< COutput > > ListCoins() const
Return list of available coins and locked coins grouped by non-change output address.
Definition: wallet.cpp:2871
std::string EncodeDestination(const CTxDestination &dest)
Definition: base58.cpp:329
RecentRequestsTableModel * getRecentRequestsTableModel()
UnlockContext requestUnlock(bool fForMixingOnly=false)
bool hdEnabled() const
CPrivateSendClientManager privateSendClient
boost::signals2::signal< void(CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)> NotifyAddressBookChanged
Address book entry changed.
Definition: wallet.h:1190
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:567
bool IsLocked(bool fForMixing=false) const
Definition: crypter.cpp:209
bool autoBackupWallet(QString &strBackupWarningRet, QString &strBackupErrorRet)
void listLockedCoins(std::vector< COutPoint > &vOutpts)
A key allocated from the key pool.
Definition: wallet.h:1273
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:25
int cachedPrivateSendRounds
Definition: walletmodel.h:259
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:389
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:100
static void NotifyISLockReceived(WalletModel *walletmodel)
CAmount getWatchBalance() const
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:14
CAmount getNormalizedAnonymizedBalance() const
CAmount getUnconfirmedBalance() const
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase)
int getRealOutpointPrivateSendRounds(const COutPoint &outpoint) const
boost::signals2::signal< void()> NotifyISLockReceived
IS-lock received.
Definition: wallet.h:1206
void unlockCoin(COutPoint &output)
void message(const QString &title, const QString &message, unsigned int style)
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
CAmount cachedUnconfirmedBalance
Definition: walletmodel.h:250
bool CreateTransaction(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, bool sign=true, int nExtraPayloadSize=0)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Definition: wallet.cpp:3658
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:715
void balanceChanged(const CAmount &balance, const CAmount &unconfirmedBalance, const CAmount &immatureBalance, const CAmount &anonymizedBalance, const CAmount &watchOnlyBalance, const CAmount &watchUnconfBalance, const CAmount &watchImmatureBalance)
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:97
void notifyWatchonlyChanged(bool fHaveWatchonly)
Data model for a walletmodel transaction.
void coinsSent(CWallet *wallet, SendCoinsRecipient recipient, QByteArray transaction)
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet)
int GetRealOutpointPrivateSendRounds(const COutPoint &outpoint, int nRounds=0) const
Definition: wallet.cpp:1576
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:896
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
Definition: wallet.h:1200
static void NotifyChainLockReceived(WalletModel *walletmodel, int chainLockHeight)
AddressTableModel * addressTableModel
Definition: walletmodel.h:244
static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly)
CAmount getWatchImmatureBalance() const
An encapsulated private key.
Definition: key.h:27
bool HaveWatchOnly(const CScript &dest) const override
Definition: keystore.cpp:138
bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
Adds a destination data tuple to the store, and saves it to disk.
Definition: wallet.cpp:4972
bool fHaveWatchOnly
Definition: walletmodel.h:237
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const
Definition: wallet.cpp:4828
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
GetPubKey implementation that also checks the mapHdPubKeys.
Definition: wallet.cpp:286
int cachedNumISLocks
Definition: walletmodel.h:258
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:217
static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
bool BackupWallet(const std::string &strDest)
Definition: wallet.cpp:5320
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
Definition: wallet.h:1203
float GetAverageAnonymizedRounds() const
Definition: wallet.cpp:2594
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
CAmount getAnonymizableBalance(bool fSkipDenominated, bool fSkipUnconfirmed) const
Definition: walletmodel.cpp:87
int getNumISLocks() const
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: ismine.cpp:28
void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
bool isFullyMixed(const COutPoint &outpoint) const
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString(), bool fMixing=false)
void pollBalanceChanged()
OptionsModel * getOptionsModel()
void subscribeToCoreSignals()
bool IsSpendable(const CTxDestination &dest) const
std::vector< std::pair< std::string, std::string > > vOrderForm
Definition: wallet.h:312
uint256 hash
Definition: transaction.h:29
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, CValidationState &state)
Call after CreateTransaction unless you want to abort.
Definition: wallet.cpp:4089
Released under the MIT license