Raven Core  3.0.0
P2P Digital Currency
walletmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven 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 "walletmodel.h"
7 
8 #include "addresstablemodel.h"
9 #include "consensus/validation.h"
10 #include "guiconstants.h"
11 #include "guiutil.h"
12 #include "optionsmodel.h"
13 #include "paymentserver.h"
15 #include "sendcoinsdialog.h"
16 #include "transactiontablemodel.h"
17 #include "assettablemodel.h"
18 
19 #include "base58.h"
20 #include "chain.h"
21 #include "keystore.h"
22 #include "validation.h"
23 #include "net.h" // for g_connman
24 #include "policy/fees.h"
25 #include "policy/rbf.h"
26 #include "sync.h"
27 #include "ui_interface.h"
28 #include "util.h" // for GetBoolArg
29 #include "wallet/coincontrol.h"
30 #include "wallet/feebumper.h"
31 #include "wallet/wallet.h"
32 #include "wallet/walletdb.h" // for BackupWallet
33 
34 #include <stdint.h>
35 
36 #include <QDebug>
37 #include <QMessageBox>
38 #include <QSet>
39 #include <QTimer>
40 
41 
42 WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, OptionsModel *_optionsModel, QObject *parent) :
43  QObject(parent), wallet(_wallet), optionsModel(_optionsModel), addressTableModel(0),
44  transactionTableModel(0),
45  assetTableModel(0),
46  recentRequestsTableModel(0),
47  cachedBalance(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0),
48  cachedEncryptionStatus(Unencrypted),
49  cachedNumBlocks(0)
50 {
53 
55  transactionTableModel = new TransactionTableModel(platformStyle, wallet, this);
56  assetTableModel = new AssetTableModel(this);
58 
59  // This timer will be fired repeatedly to update the balance
60  pollTimer = new QTimer(this);
61  connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollBalanceChanged()));
62  pollTimer->start(MODEL_UPDATE_DELAY);
63 
65 }
66 
68 {
70 }
71 
72 CAmount WalletModel::getBalance(const CCoinControl *coinControl) const
73 {
74  if (coinControl)
75  {
76  return wallet->GetAvailableBalance(coinControl);
77  }
78 
79  return wallet->GetBalance();
80 }
81 
83 {
84  return wallet->GetUnconfirmedBalance();
85 }
86 
88 {
89  return wallet->GetImmatureBalance();
90 }
91 
93 {
94  return fHaveWatchOnly;
95 }
96 
98 {
99  return wallet->GetWatchOnlyBalance();
100 }
101 
103 {
105 }
106 
108 {
110 }
111 
113 {
114  EncryptionStatus newEncryptionStatus = getEncryptionStatus();
115 
116  if(cachedEncryptionStatus != newEncryptionStatus)
117  Q_EMIT encryptionStatusChanged(newEncryptionStatus);
118 }
119 
121 {
122  // Get required locks upfront. This avoids the GUI from getting stuck on
123  // periodical polls if the core is holding the locks for a longer time -
124  // for example, during a wallet rescan.
125  TRY_LOCK(cs_main, lockMain);
126  if(!lockMain)
127  return;
128  TRY_LOCK(wallet->cs_wallet, lockWallet);
129  if(!lockWallet)
130  return;
131 
133  {
135 
136  // Balance and number of transactions might have changed
138 
142  if(assetTableModel)
144  }
145 }
146 
148 {
149  CAmount newBalance = getBalance();
150  CAmount newUnconfirmedBalance = getUnconfirmedBalance();
151  CAmount newImmatureBalance = getImmatureBalance();
152  CAmount newWatchOnlyBalance = 0;
153  CAmount newWatchUnconfBalance = 0;
154  CAmount newWatchImmatureBalance = 0;
155  if (haveWatchOnly())
156  {
157  newWatchOnlyBalance = getWatchBalance();
158  newWatchUnconfBalance = getWatchUnconfirmedBalance();
159  newWatchImmatureBalance = getWatchImmatureBalance();
160  }
161 
162  if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance ||
163  cachedWatchOnlyBalance != newWatchOnlyBalance || cachedWatchUnconfBalance != newWatchUnconfBalance || cachedWatchImmatureBalance != newWatchImmatureBalance)
164  {
165  cachedBalance = newBalance;
166  cachedUnconfirmedBalance = newUnconfirmedBalance;
167  cachedImmatureBalance = newImmatureBalance;
168  cachedWatchOnlyBalance = newWatchOnlyBalance;
169  cachedWatchUnconfBalance = newWatchUnconfBalance;
170  cachedWatchImmatureBalance = newWatchImmatureBalance;
171  Q_EMIT balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance,
172  newWatchOnlyBalance, newWatchUnconfBalance, newWatchImmatureBalance);
173  }
174 }
175 
177 {
178  // Balance and number of transactions might have changed
180 }
181 
182 void WalletModel::updateAddressBook(const QString &address, const QString &label,
183  bool isMine, const QString &purpose, int status)
184 {
186  addressTableModel->updateEntry(address, label, isMine, purpose, status);
187 }
188 
189 void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly)
190 {
191  fHaveWatchOnly = fHaveWatchonly;
192  Q_EMIT notifyWatchonlyChanged(fHaveWatchonly);
193 }
194 
195 bool WalletModel::validateAddress(const QString &address)
196 {
197  return IsValidDestinationString(address.toStdString());
198 }
199 
201 {
202  CAmount total = 0;
203  bool fSubtractFeeFromAmount = false;
204  QList<SendCoinsRecipient> recipients = transaction.getRecipients();
205  std::vector<CRecipient> vecSend;
206 
207  if(recipients.empty())
208  {
209  return OK;
210  }
211 
212  QSet<QString> setAddress; // Used to detect duplicates
213  int nAddresses = 0;
214 
215  // Pre-check input data for validity
216  for (const SendCoinsRecipient &rcp : recipients)
217  {
218  if (rcp.fSubtractFeeFromAmount)
219  fSubtractFeeFromAmount = true;
220 
221  if (rcp.paymentRequest.IsInitialized())
222  { // PaymentRequest...
223  CAmount subtotal = 0;
224  const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
225  for (int i = 0; i < details.outputs_size(); i++)
226  {
227  const payments::Output& out = details.outputs(i);
228  if (out.amount() <= 0) continue;
229  subtotal += out.amount();
230  const unsigned char* scriptStr = (const unsigned char*)out.script().data();
231  CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
232  CAmount nAmount = out.amount();
233  CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
234  vecSend.push_back(recipient);
235  }
236  if (subtotal <= 0)
237  {
238  return InvalidAmount;
239  }
240  total += subtotal;
241  }
242  else
243  { // User-entered raven address / amount:
244  if(!validateAddress(rcp.address))
245  {
246  return InvalidAddress;
247  }
248  if(rcp.amount <= 0)
249  {
250  return InvalidAmount;
251  }
252  setAddress.insert(rcp.address);
253  ++nAddresses;
254 
255  CScript scriptPubKey = GetScriptForDestination(DecodeDestination(rcp.address.toStdString()));
256  CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
257  vecSend.push_back(recipient);
258 
259  total += rcp.amount;
260  }
261  }
262  if(setAddress.size() != nAddresses)
263  {
264  return DuplicateAddress;
265  }
266 
267  CAmount nBalance = getBalance(&coinControl);
268 
269  if(total > nBalance)
270  {
271  return AmountExceedsBalance;
272  }
273 
274  {
276 
277  transaction.newPossibleKeyChange(wallet);
278 
279  CAmount nFeeRequired = 0;
280  int nChangePosRet = -1;
281  std::string strFailReason;
282 
283  CWalletTx *newTx = transaction.getTransaction();
284  CReserveKey *keyChange = transaction.getPossibleKeyChange();
285  bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
286  transaction.setTransactionFee(nFeeRequired);
287  if (fSubtractFeeFromAmount && fCreated)
288  transaction.reassignAmounts(nChangePosRet);
289 
290  if(!fCreated)
291  {
292  if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
293  {
295  }
296  Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
299  }
300 
301  // reject absurdly high fee. (This can never happen because the
302  // wallet caps the fee at maxTxFee. This merely serves as a
303  // belt-and-suspenders check)
304  if (nFeeRequired > maxTxFee)
305  return AbsurdFee;
306  }
307 
308  return SendCoinsReturn(OK);
309 }
310 
312 {
313  QByteArray transaction_array; /* store serialized transaction */
314 
315  {
317  CWalletTx *newTx = transaction.getTransaction();
318 
319  for (const SendCoinsRecipient &rcp : transaction.getRecipients())
320  {
321  if (rcp.paymentRequest.IsInitialized())
322  {
323  // Make sure any payment requests involved are still valid.
324  if (PaymentServer::verifyExpired(rcp.paymentRequest.getDetails())) {
325  return PaymentRequestExpired;
326  }
327 
328  // Store PaymentRequests in wtx.vOrderForm in wallet.
329  std::string key("PaymentRequest");
330  std::string value;
331  rcp.paymentRequest.SerializeToString(&value);
332  newTx->vOrderForm.push_back(make_pair(key, value));
333  }
334  else if (!rcp.message.isEmpty()) // Message from normal raven:URI (raven:123...?message=example)
335  newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
336  }
337 
338  CReserveKey *keyChange = transaction.getPossibleKeyChange();
339  CValidationState state;
340  if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), state))
341  return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason()));
342 
343  CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
344  ssTx << *newTx->tx;
345  transaction_array.append(&(ssTx[0]), ssTx.size());
346  }
347 
348  // Add addresses / update labels that we've sent to the address book,
349  // and emit coinsSent signal for each recipient
350  for (const SendCoinsRecipient &rcp : transaction.getRecipients())
351  {
352  // Don't touch the address book when we have a payment request
353  if (!rcp.paymentRequest.IsInitialized())
354  {
355  std::string strAddress = rcp.address.toStdString();
356  CTxDestination dest = DecodeDestination(strAddress);
357  std::string strLabel = rcp.label.toStdString();
358  {
360 
361  std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);
362 
363  // Check if we have a new address or an updated label
364  if (mi == wallet->mapAddressBook.end())
365  {
366  wallet->SetAddressBook(dest, strLabel, "send");
367  }
368  else if (mi->second.name != strLabel)
369  {
370  wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
371  }
372  }
373  }
374  Q_EMIT coinsSent(wallet, rcp, transaction_array);
375  }
376  checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits
377 
378  return SendCoinsReturn(OK);
379 }
380 
381 WalletModel::SendCoinsReturn WalletModel::sendAssets(CWalletTx& tx, QList<SendAssetsRecipient>& recipients, CReserveKey& reservekey)
382 {
383  QByteArray transaction_array; /* store serialized transaction */
384 
385  {
387 
388  std::pair<int, std::string> error;
389  std::string txid;
390  if (!SendAssetTransaction(this->wallet, tx, reservekey, error, txid))
391  return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(error.second));
392 
393  CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
394  ssTx << tx.tx;
395  transaction_array.append(&(ssTx[0]), ssTx.size());
396  }
397 
398  // Add addresses / update labels that we've sent to the address book,
399  // and emit coinsSent signal for each recipient
400  for (const SendAssetsRecipient &rcp : recipients)
401  {
402  // Don't touch the address book when we have a payment request
403  if (!rcp.paymentRequest.IsInitialized())
404  {
405  std::string strAddress = rcp.address.toStdString();
406  CTxDestination dest = DecodeDestination(strAddress);
407  std::string strLabel = rcp.label.toStdString();
408  {
410 
411  std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);
412 
413  // Check if we have a new address or an updated label
414  if (mi == wallet->mapAddressBook.end())
415  {
416  wallet->SetAddressBook(dest, strLabel, "send");
417  }
418  else if (mi->second.name != strLabel)
419  {
420  wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
421  }
422  }
423  }
424  Q_EMIT assetsSent(wallet, rcp, transaction_array);
425  }
426  checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits
427 
428  return SendCoinsReturn(OK);
429 }
430 
432 {
433  return optionsModel;
434 }
435 
437 {
438  return addressTableModel;
439 }
440 
442 {
443  return transactionTableModel;
444 }
445 
447 {
448  return assetTableModel;
449 }
450 
452 {
454 }
455 
457 {
458  if(!wallet->IsCrypted())
459  {
460  return Unencrypted;
461  }
462  else if(wallet->IsLocked())
463  {
464  return Locked;
465  }
466  else
467  {
468  return Unlocked;
469  }
470 }
471 
472 bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase)
473 {
474  if(encrypted)
475  {
476  // Encrypt
477  return wallet->EncryptWallet(passphrase);
478  }
479  else
480  {
481  // Decrypt -- TODO; not supported yet
482  return false;
483  }
484 }
485 
486 bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
487 {
488  if(locked)
489  {
490  // Lock
491  return wallet->Lock();
492  }
493  else
494  {
495  // Unlock
496  return wallet->Unlock(passPhrase);
497  }
498 }
499 
500 bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
501 {
502  bool retval;
503  {
505  wallet->Lock(); // Make sure wallet is locked before attempting pass change
506  retval = wallet->ChangeWalletPassphrase(oldPass, newPass);
507  }
508  return retval;
509 }
510 
511 bool WalletModel::backupWallet(const QString &filename)
512 {
513  return wallet->BackupWallet(filename.toLocal8Bit().data());
514 }
515 
516 // Handlers for core signals
517 static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet)
518 {
519  qDebug() << "NotifyKeyStoreStatusChanged";
520  QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
521 }
522 
523 static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
524  const CTxDestination &address, const std::string &label, bool isMine,
525  const std::string &purpose, ChangeType status)
526 {
527  QString strAddress = QString::fromStdString(EncodeDestination(address));
528  QString strLabel = QString::fromStdString(label);
529  QString strPurpose = QString::fromStdString(purpose);
530 
531  qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
532  QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
533  Q_ARG(QString, strAddress),
534  Q_ARG(QString, strLabel),
535  Q_ARG(bool, isMine),
536  Q_ARG(QString, strPurpose),
537  Q_ARG(int, status));
538 }
539 
540 static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
541 {
542  Q_UNUSED(wallet);
543  Q_UNUSED(hash);
544  Q_UNUSED(status);
545  QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection);
546 }
547 
548 static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
549 {
550  // emits signal "showProgress"
551  QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
552  Q_ARG(QString, QString::fromStdString(title)),
553  Q_ARG(int, nProgress));
554 }
555 
556 static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly)
557 {
558  QMetaObject::invokeMethod(walletmodel, "updateWatchOnlyFlag", Qt::QueuedConnection,
559  Q_ARG(bool, fHaveWatchonly));
560 }
561 
563 {
564  // Connect signals to wallet
565  wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
566  wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
567  wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
568  wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
569  wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1));
570 }
571 
573 {
574  // Disconnect signals from wallet
575  wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
576  wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
577  wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
578  wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
579  wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1));
580 }
581 
582 // WalletModel::UnlockContext implementation
584 {
585  bool was_locked = getEncryptionStatus() == Locked;
586  if(was_locked)
587  {
588  // Request UI to unlock wallet
589  Q_EMIT requireUnlock();
590  }
591  // If wallet is still locked, unlock was failed or cancelled, mark context as invalid
592  bool valid = getEncryptionStatus() != Locked;
593 
594  return UnlockContext(this, valid, was_locked);
595 }
596 
597 WalletModel::UnlockContext::UnlockContext(WalletModel *_wallet, bool _valid, bool _relock):
598  wallet(_wallet),
599  valid(_valid),
600  relock(_relock)
601 {
602 }
603 
605 {
606  if(valid && relock)
607  {
608  wallet->setWalletLocked(true);
609  }
610 }
611 
613 {
614  // Transfer context; old object no longer relocks wallet
615  *this = rhs;
616  rhs.relock = false;
617 }
618 
619 bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
620 {
621  return wallet->GetPubKey(address, vchPubKeyOut);
622 }
623 
625 {
626  return IsMine(*wallet, dest) & ISMINE_SPENDABLE;
627 }
628 
629 bool WalletModel::getPrivKey(const CKeyID &address, CKey& vchPrivKeyOut) const
630 {
631  return wallet->GetKey(address, vchPrivKeyOut);
632 }
633 
634 // returns a list of COutputs from COutPoints
635 void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
636 {
637  LOCK2(cs_main, wallet->cs_wallet);
638  for (const COutPoint& outpoint : vOutpoints)
639  {
640  auto it = wallet->mapWallet.find(outpoint.hash);
641  if (it == wallet->mapWallet.end()) continue;
642  int nDepth = it->second.GetDepthInMainChain();
643  if (nDepth < 0) continue;
644  COutput out(&it->second, outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */);
645  vOutputs.push_back(out);
646  }
647 }
648 
649 bool WalletModel::isSpent(const COutPoint& outpoint) const
650 {
651  LOCK2(cs_main, wallet->cs_wallet);
652  return wallet->IsSpent(outpoint.hash, outpoint.n);
653 }
654 
655 // AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address)
656 void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const
657 {
658  for (auto& group : wallet->ListCoins()) {
659  auto& resultGroup = mapCoins[QString::fromStdString(EncodeDestination(group.first))];
660  for (auto& coin : group.second) {
661  resultGroup.emplace_back(std::move(coin));
662  }
663  }
664 }
665 
667 // AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address)
668 void WalletModel::listAssets(std::map<QString, std::map<QString, std::vector<COutput> > >& mapCoins) const
669 {
670  std::map<QString, std::map<QString, std::vector<COutput> > > mapSortedByAssetName;
671  auto list = wallet->ListAssets();
672 
673  for (auto& group : list) {
674  auto address = QString::fromStdString(EncodeDestination(group.first));
675 
676  for (auto& coin : group.second) {
677  auto out = coin.tx->tx->vout[coin.i];
678  std::string strAssetName;
679  CAmount nAmount;
680  if (!GetAssetInfoFromScript(out.scriptPubKey, strAssetName, nAmount))
681  continue;
682 
683  if (nAmount == 0)
684  continue;
685 
686  QString assetName = QString::fromStdString(strAssetName);
687  auto& assetMap = mapCoins[assetName];
688  assetMap[address].emplace_back(coin);
689  }
690  }
691 }
694 bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const
695 {
696  LOCK2(cs_main, wallet->cs_wallet);
697  return wallet->IsLockedCoin(hash, n);
698 }
699 
701 {
702  LOCK2(cs_main, wallet->cs_wallet);
703  wallet->LockCoin(output);
704 }
705 
707 {
708  LOCK2(cs_main, wallet->cs_wallet);
709  wallet->UnlockCoin(output);
710 }
711 
712 void WalletModel::listLockedCoins(std::vector<COutPoint>& vOutpts)
713 {
714  LOCK2(cs_main, wallet->cs_wallet);
715  wallet->ListLockedCoins(vOutpts);
716 }
717 
718 void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
719 {
720  vReceiveRequests = wallet->GetDestValues("rr"); // receive request
721 }
722 
723 bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
724 {
725  CTxDestination dest = DecodeDestination(sAddress);
726 
727  std::stringstream ss;
728  ss << nId;
729  std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
730 
731  LOCK(wallet->cs_wallet);
732  if (sRequest.empty())
733  return wallet->EraseDestData(dest, key);
734  else
735  return wallet->AddDestData(dest, key, sRequest);
736 }
737 
739 {
740  return wallet->TransactionCanBeAbandoned(hash);
741 }
742 
744 {
745  LOCK2(cs_main, wallet->cs_wallet);
746  return wallet->AbandonTransaction(hash);
747 }
748 
750 {
751  return false;
752  // For now, remove the ability to bump a transaction. Always return false.
753 // LOCK2(cs_main, wallet->cs_wallet);
754 // const CWalletTx *wtx = wallet->GetWalletTx(hash);
755 // return wtx && SignalsOptInRBF(*wtx) && !wtx->mapValue.count("replaced_by_txid");
756 }
757 
759 {
760  return false;
761 // std::unique_ptr<CFeeBumper> feeBump;
762 // {
763 // CCoinControl coin_control;
764 // coin_control.signalRbf = true;
765 // LOCK2(cs_main, wallet->cs_wallet);
766 // feeBump.reset(new CFeeBumper(wallet, hash, coin_control, 0));
767 // }
768 // if (feeBump->getResult() != BumpFeeResult::OK)
769 // {
770 // QMessageBox::critical(0, tr("Fee bump error"), tr("Increasing transaction fee failed") + "<br />(" +
771 // (feeBump->getErrors().size() ? QString::fromStdString(feeBump->getErrors()[0]) : "") +")");
772 // return false;
773 // }
774 //
775 // // allow a user based fee verification
776 // QString questionString = tr("Do you want to increase the fee?");
777 // questionString.append("<br />");
778 // CAmount oldFee = feeBump->getOldFee();
779 // CAmount newFee = feeBump->getNewFee();
780 // questionString.append("<table style=\"text-align: left;\">");
781 // questionString.append("<tr><td>");
782 // questionString.append(tr("Current fee:"));
783 // questionString.append("</td><td>");
784 // questionString.append(RavenUnits::formatHtmlWithUnit(getOptionsModel()->getDisplayUnit(), oldFee));
785 // questionString.append("</td></tr><tr><td>");
786 // questionString.append(tr("Increase:"));
787 // questionString.append("</td><td>");
788 // questionString.append(RavenUnits::formatHtmlWithUnit(getOptionsModel()->getDisplayUnit(), newFee - oldFee));
789 // questionString.append("</td></tr><tr><td>");
790 // questionString.append(tr("New fee:"));
791 // questionString.append("</td><td>");
792 // questionString.append(RavenUnits::formatHtmlWithUnit(getOptionsModel()->getDisplayUnit(), newFee));
793 // questionString.append("</td></tr></table>");
794 // SendConfirmationDialog confirmationDialog(tr("Confirm fee bump"), questionString);
795 // confirmationDialog.exec();
796 // QMessageBox::StandardButton retval = (QMessageBox::StandardButton)confirmationDialog.result();
797 //
798 // // cancel sign&broadcast if users doesn't want to bump the fee
799 // if (retval != QMessageBox::Yes) {
800 // return false;
801 // }
802 //
803 // WalletModel::UnlockContext ctx(requestUnlock());
804 // if(!ctx.isValid())
805 // {
806 // return false;
807 // }
808 //
809 // // sign bumped transaction
810 // bool res = false;
811 // {
812 // LOCK2(cs_main, wallet->cs_wallet);
813 // res = feeBump->signTransaction(wallet);
814 // }
815 // if (!res) {
816 // QMessageBox::critical(0, tr("Fee bump error"), tr("Can't sign transaction."));
817 // return false;
818 // }
819 // // commit the bumped transaction
820 // {
821 // LOCK2(cs_main, wallet->cs_wallet);
822 // res = feeBump->commit(wallet);
823 // }
824 // if(!res) {
825 // QMessageBox::critical(0, tr("Fee bump error"), tr("Could not commit transaction") + "<br />(" +
826 // QString::fromStdString(feeBump->getErrors()[0])+")");
827 // return false;
828 // }
829 // return true;
830 }
831 
833 {
834  return !gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
835 }
836 
838 {
839  return wallet->IsHDEnabled();
840 }
841 
843 {
844  return nTxConfirmTarget;
845 }
846 
848 {
849  return fWalletRbf;
850 }
851 
853 {
854  return wallet;
855 }
bool abandonTransaction(uint256 hash) const
void loadReceiveRequests(std::vector< std::string > &vReceiveRequests)
bool isLockedCoin(uint256 hash, unsigned int n) const
RVN END.
void listCoins(std::map< QString, std::vector< COutput > > &mapCoins) const
Model for list of recently generated payment requests / raven: URIs.
TransactionTableModel * transactionTableModel
Definition: walletmodel.h:306
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:89
RecentRequestsTableModel * recentRequestsTableModel
Definition: walletmodel.h:308
CAmount GetImmatureBalance() const
Definition: wallet.cpp:2041
void lockCoin(COutPoint &output)
CWalletTx * getTransaction() const
#define TRY_LOCK(cs, name)
Definition: sync.h:178
static bool isWalletEnabled()
CAmount GetAvailableBalance(const CCoinControl *coinControl=nullptr) const
Definition: wallet.cpp:2143
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:829
std::vector< std::string > GetDestValues(const std::string &prefix) const
Get all destination values matching a prefix.
Definition: wallet.cpp:4515
CCriticalSection cs_wallet
Definition: wallet.h:751
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
Definition: validation.cpp:105
bool IsCrypted() const
Definition: crypter.h:143
UnlockContext requestUnlock()
void unsubscribeFromCoreSignals()
bool bumpFee(uint256 hash)
int Height() const
Return the maximal height in the chain.
Definition: chain.h:479
CCriticalSection cs_main
Global state.
Definition: validation.cpp:72
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:333
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
bool backupWallet(const QString &filename)
SendCoinsReturn sendCoins(WalletModelTransaction &transaction)
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey, SigVersion sigversion)
Definition: ismine.cpp:32
bool transactionCanBeAbandoned(uint256 hash) const
QList< SendCoinsRecipient > getRecipients() const
void assetsSent(CWallet *wallet, SendAssetsRecipient recipient, QByteArray transaction)
std::map< CTxDestination, std::vector< COutput > > ListAssets() const
Return list of available assets and locked assets grouped by non-change output address.
Definition: wallet.cpp:2373
bool fSubtractFeeFromAmount
Definition: wallet.h:159
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:470
CAmount GetUnconfirmedWatchOnlyBalance() const
Definition: wallet.cpp:2071
AddressTableModel * getAddressTableModel()
Keystore which keeps the private keys encrypted.
Definition: crypter.h:116
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:594
AssetTableModel * assetTableModel
Definition: walletmodel.h:307
bool IsSpent(const uint256 &hash, unsigned int n) const
Outpoint is spent if any non-conflicted transaction spends it:
Definition: wallet.cpp:553
Coin Control Features.
Definition: coincontrol.h:17
CAmount GetBalance() const
Definition: wallet.cpp:2010
bool haveWatchOnly() const
Definition: walletmodel.cpp:92
void updateStatus()
void newPossibleKeyChange(CWallet *wallet)
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
Definition: crypter.cpp:260
EncryptionStatus getEncryptionStatus() const
CAmount getBalance(const CCoinControl *coinControl=nullptr) const
Definition: walletmodel.cpp:72
void setTransactionFee(const CAmount &newFee)
UnlockContext(WalletModel *wallet, bool valid, bool relock)
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
boost::signals2::signal< void(CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
Definition: wallet.h:1139
CAmount getImmatureBalance() const
Definition: walletmodel.cpp:87
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)
Definition: wallet.cpp:3089
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:3832
boost::signals2::signal< void(CCryptoKeyStore *wallet)> NotifyStatusChanged
Wallet status (encrypted, locked) changed.
Definition: crypter.h:194
void checkBalanceChanged()
#define LOCK2(cs1, cs2)
Definition: sync.h:177
bool getPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
void push_back(const T &value)
Definition: prevector.h:412
unsigned int nTxConfirmTarget
Definition: wallet.cpp:47
bool transactionCanBeBumped(uint256 hash) const
bool IsValidDestinationString(const std::string &str, const CChainParams &params)
Definition: base58.cpp:338
CWallet * wallet
Definition: walletmodel.h:297
Models assets portion of wallet as table of owned assets.
bool AbandonTransaction(const uint256 &hashTx)
Definition: wallet.cpp:1069
size_type size() const
Definition: streams.h:238
void UnlockCoin(const COutPoint &output)
Definition: wallet.cpp:4329
void updateTransaction()
CAmount cachedImmatureBalance
Definition: walletmodel.h:313
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:211
bool fWalletRbf
Definition: wallet.cpp:49
bool IsHDEnabled() const
Definition: wallet.cpp:1453
#define LOCK(cs)
Definition: sync.h:176
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass)
bool IsLocked() const
Definition: crypter.h:148
void reassignAmounts(int nChangePosRet)
int getDefaultConfirmTarget() const
CAmount getWatchUnconfirmedBalance() const
An encapsulated public key.
Definition: pubkey.h:40
bool TransactionCanBeAbandoned(const uint256 &hashTx) const
Return whether transaction can be abandoned.
Definition: wallet.cpp:1062
bool IsLockedCoin(uint256 hash, unsigned int n) const
Definition: wallet.cpp:4341
std::string GetRejectReason() const
Definition: validation.h:92
uint32_t n
Definition: transaction.h:26
CAmount GetUnconfirmedBalance() const
Definition: wallet.cpp:2026
SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl &coinControl)
CAmount GetImmatureWatchOnlyBalance() const
Definition: wallet.cpp:2086
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:4486
CAmount cachedBalance
Definition: walletmodel.h:311
bool GetAssetInfoFromScript(const CScript &scriptPubKey, std::string &strName, CAmount &nAmount)
Definition: assets.cpp:3423
bool isSpent(const COutPoint &outpoint) const
bool GetKey(const CKeyID &address, CKey &keyOut) const override
Definition: crypter.cpp:242
OptionsModel * optionsModel
Definition: walletmodel.h:303
CAmount cachedWatchOnlyBalance
Definition: walletmodel.h:314
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:75
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Raven scriptPubKey for the given CTxDestination.
Definition: standard.cpp:347
TransactionTableModel * getTransactionTableModel()
EncryptionStatus cachedEncryptionStatus
Definition: walletmodel.h:317
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
void CopyFrom(const UnlockContext &rhs)
UI model for the transaction table of a wallet.
bool SendAssetTransaction(CWallet *pwallet, CWalletTx &transaction, CReserveKey &reserveKey, std::pair< int, std::string > &error, std::string &txid)
Send any type of asset transaction to the network.
Definition: assets.cpp:4243
void LockCoin(const COutPoint &output)
Definition: wallet.cpp:4323
Qt model of the address book in the core.
AssetTableModel * getAssetTableModel()
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString())
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:285
void encryptionStatusChanged(int status)
QTimer * pollTimer
Definition: walletmodel.h:320
CAmount GetWatchOnlyBalance() const
Definition: wallet.cpp:2055
bool validateAddress(const QString &address)
WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent=0)
Definition: walletmodel.cpp:42
void updateWatchOnlyFlag(bool fHaveWatchonly)
RVN END.
Definition: validation.h:30
256-bit opaque blob.
Definition: uint256.h:123
int cachedNumBlocks
Definition: walletmodel.h:318
CAmount cachedWatchUnconfBalance
Definition: walletmodel.h:315
ArgsManager gArgs
Definition: util.cpp:94
void requireUnlock()
bool fForceCheckBalanceChanged
Definition: walletmodel.h:299
CAmount cachedWatchImmatureBalance
Definition: walletmodel.h:316
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:2425
std::string EncodeDestination(const CTxDestination &dest)
Definition: base58.cpp:326
RecentRequestsTableModel * getRecentRequestsTableModel()
bool hdEnabled() const
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:1132
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:386
void listLockedCoins(std::vector< COutPoint > &vOutpts)
A key allocated from the key pool.
Definition: wallet.h:1193
Interface from Qt to configuration data structure for Raven client.
Definition: optionsmodel.h:23
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:396
Interface to Raven wallet from Qt view code.
Definition: walletmodel.h:165
CAmount getWatchBalance() const
Definition: walletmodel.cpp:97
CAmount getUnconfirmedBalance() const
Definition: walletmodel.cpp:82
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase)
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:30
CAmount cachedUnconfirmedBalance
Definition: walletmodel.h:312
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:673
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:81
void notifyWatchonlyChanged(bool fHaveWatchonly)
Data model for a walletmodel transaction.
void coinsSent(CWallet *wallet, SendCoinsRecipient recipient, QByteArray transaction)
bool error(const char *fmt, const Args &... args)
Definition: util.h:168
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:818
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
Definition: wallet.h:1142
bool getDefaultWalletRbf() const
AddressTableModel * addressTableModel
Definition: walletmodel.h:305
CAmount getWatchImmatureBalance() const
void listAssets(std::map< QString, std::map< QString, std::vector< COutput > > > &mapCoins) const
RVN START.
SendCoinsReturn sendAssets(CWalletTx &tx, QList< SendAssetsRecipient > &recipients, CReserveKey &reservekey)
An encapsulated private key.
Definition: key.h:36
bool HaveWatchOnly(const CScript &dest) const override
Definition: keystore.cpp:104
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:4477
bool fHaveWatchOnly
Definition: walletmodel.h:298
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const
Definition: wallet.cpp:4349
CWallet * getWallet() const
bool BackupWallet(const std::string &strDest)
Definition: wallet.cpp:4731
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:1145
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
void balanceChanged(const CAmount &balance, const CAmount &unconfirmedBalance, const CAmount &immatureBalance, const CAmount &watchOnlyBalance, const CAmount &watchUnconfBalance, const CAmount &watchImmatureBalance)
void pollBalanceChanged()
OptionsModel * getOptionsModel()
bool Unlock(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:366
void subscribeToCoreSignals()
bool IsSpendable(const CTxDestination &dest) const
std::vector< std::pair< std::string, std::string > > vOrderForm
Definition: wallet.h:317
uint256 hash
Definition: transaction.h:25
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, CValidationState &state)
RVN END.
Definition: wallet.cpp:3683