You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

walletmodel.h 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // Copyright (c) 2011-2014 The Bitcoin developers
  2. // Distributed under the MIT/X11 software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #ifndef WALLETMODEL_H
  5. #define WALLETMODEL_H
  6. #include "paymentrequestplus.h"
  7. #include "walletmodeltransaction.h"
  8. #include "allocators.h" /* for SecureString */
  9. #include <map>
  10. #include <vector>
  11. #include <QObject>
  12. class AddressTableModel;
  13. class OptionsModel;
  14. class RecentRequestsTableModel;
  15. class TransactionTableModel;
  16. class WalletModelTransaction;
  17. class CCoinControl;
  18. class CKeyID;
  19. class COutPoint;
  20. class COutput;
  21. class CPubKey;
  22. class CWallet;
  23. class uint256;
  24. QT_BEGIN_NAMESPACE
  25. class QTimer;
  26. QT_END_NAMESPACE
  27. class SendCoinsRecipient
  28. {
  29. public:
  30. explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
  31. explicit SendCoinsRecipient(const QString &addr, const QString &label, quint64 amount, const QString &message):
  32. address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
  33. // If from an insecure payment request, this is used for storing
  34. // the addresses, e.g. address-A<br />address-B<br />address-C.
  35. // Info: As we don't need to process addresses in here when using
  36. // payment requests, we can abuse it for displaying an address list.
  37. // Todo: This is a hack, should be replaced with a cleaner solution!
  38. QString address;
  39. QString label;
  40. qint64 amount;
  41. // If from a payment request, this is used for storing the memo
  42. QString message;
  43. // If from a payment request, paymentRequest.IsInitialized() will be true
  44. PaymentRequestPlus paymentRequest;
  45. // Empty if no authentication or invalid signature/cert/etc.
  46. QString authenticatedMerchant;
  47. static const int CURRENT_VERSION = 1;
  48. int nVersion;
  49. ADD_SERIALIZE_METHODS;
  50. template <typename Stream, typename Operation>
  51. inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
  52. std::string sAddress = address.toStdString();
  53. std::string sLabel = label.toStdString();
  54. std::string sMessage = message.toStdString();
  55. std::string sPaymentRequest;
  56. if (!ser_action.ForRead() && paymentRequest.IsInitialized())
  57. paymentRequest.SerializeToString(&sPaymentRequest);
  58. std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString();
  59. READWRITE(this->nVersion);
  60. nVersion = this->nVersion;
  61. READWRITE(sAddress);
  62. READWRITE(sLabel);
  63. READWRITE(amount);
  64. READWRITE(sMessage);
  65. READWRITE(sPaymentRequest);
  66. READWRITE(sAuthenticatedMerchant);
  67. if (ser_action.ForRead())
  68. {
  69. address = QString::fromStdString(sAddress);
  70. label = QString::fromStdString(sLabel);
  71. message = QString::fromStdString(sMessage);
  72. if (!sPaymentRequest.empty())
  73. paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
  74. authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
  75. }
  76. }
  77. };
  78. /** Interface to Bitcoin wallet from Qt view code. */
  79. class WalletModel : public QObject
  80. {
  81. Q_OBJECT
  82. public:
  83. explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
  84. ~WalletModel();
  85. enum StatusCode // Returned by sendCoins
  86. {
  87. OK,
  88. InvalidAmount,
  89. InvalidAddress,
  90. AmountExceedsBalance,
  91. AmountWithFeeExceedsBalance,
  92. DuplicateAddress,
  93. TransactionCreationFailed, // Error returned when wallet is still locked
  94. TransactionCommitFailed
  95. };
  96. enum EncryptionStatus
  97. {
  98. Unencrypted, // !wallet->IsCrypted()
  99. Locked, // wallet->IsCrypted() && wallet->IsLocked()
  100. Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
  101. };
  102. OptionsModel *getOptionsModel();
  103. AddressTableModel *getAddressTableModel();
  104. TransactionTableModel *getTransactionTableModel();
  105. RecentRequestsTableModel *getRecentRequestsTableModel();
  106. qint64 getBalance(const CCoinControl *coinControl = NULL) const;
  107. qint64 getUnconfirmedBalance() const;
  108. qint64 getImmatureBalance() const;
  109. bool haveWatchOnly() const;
  110. qint64 getWatchBalance() const;
  111. qint64 getWatchUnconfirmedBalance() const;
  112. qint64 getWatchImmatureBalance() const;
  113. EncryptionStatus getEncryptionStatus() const;
  114. bool processingQueuedTransactions() { return fProcessingQueuedTransactions; }
  115. // Check address for validity
  116. bool validateAddress(const QString &address);
  117. // Return status record for SendCoins, contains error id + information
  118. struct SendCoinsReturn
  119. {
  120. SendCoinsReturn(StatusCode status = OK):
  121. status(status) {}
  122. StatusCode status;
  123. };
  124. // prepare transaction for getting txfee before sending coins
  125. SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL);
  126. // Send coins to a list of recipients
  127. SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
  128. // Wallet encryption
  129. bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
  130. // Passphrase only needed when unlocking
  131. bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
  132. bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
  133. // Wallet backup
  134. bool backupWallet(const QString &filename);
  135. // RAI object for unlocking wallet, returned by requestUnlock()
  136. class UnlockContext
  137. {
  138. public:
  139. UnlockContext(WalletModel *wallet, bool valid, bool relock);
  140. ~UnlockContext();
  141. bool isValid() const { return valid; }
  142. // Copy operator and constructor transfer the context
  143. UnlockContext(const UnlockContext& obj) { CopyFrom(obj); }
  144. UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; }
  145. private:
  146. WalletModel *wallet;
  147. bool valid;
  148. mutable bool relock; // mutable, as it can be set to false by copying
  149. void CopyFrom(const UnlockContext& rhs);
  150. };
  151. UnlockContext requestUnlock();
  152. bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
  153. void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
  154. bool isSpent(const COutPoint& outpoint) const;
  155. void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
  156. bool isLockedCoin(uint256 hash, unsigned int n) const;
  157. void lockCoin(COutPoint& output);
  158. void unlockCoin(COutPoint& output);
  159. void listLockedCoins(std::vector<COutPoint>& vOutpts);
  160. void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
  161. bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
  162. private:
  163. CWallet *wallet;
  164. bool fProcessingQueuedTransactions;
  165. bool fHaveWatchOnly;
  166. // Wallet has an options model for wallet-specific options
  167. // (transaction fee, for example)
  168. OptionsModel *optionsModel;
  169. AddressTableModel *addressTableModel;
  170. TransactionTableModel *transactionTableModel;
  171. RecentRequestsTableModel *recentRequestsTableModel;
  172. // Cache some values to be able to detect changes
  173. qint64 cachedBalance;
  174. qint64 cachedUnconfirmedBalance;
  175. qint64 cachedImmatureBalance;
  176. qint64 cachedWatchOnlyBalance;
  177. qint64 cachedWatchUnconfBalance;
  178. qint64 cachedWatchImmatureBalance;
  179. EncryptionStatus cachedEncryptionStatus;
  180. int cachedNumBlocks;
  181. QTimer *pollTimer;
  182. void subscribeToCoreSignals();
  183. void unsubscribeFromCoreSignals();
  184. void checkBalanceChanged();
  185. signals:
  186. // Signal that balance in wallet changed
  187. void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
  188. qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance);
  189. // Encryption status of wallet changed
  190. void encryptionStatusChanged(int status);
  191. // Signal emitted when wallet needs to be unlocked
  192. // It is valid behaviour for listeners to keep the wallet locked after this signal;
  193. // this means that the unlocking failed or was cancelled.
  194. void requireUnlock();
  195. // Fired when a message should be reported to the user
  196. void message(const QString &title, const QString &message, unsigned int style);
  197. // Coins sent: from wallet, to recipient, in (serialized) transaction:
  198. void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
  199. // Show progress dialog e.g. for rescan
  200. void showProgress(const QString &title, int nProgress);
  201. // Watch-only address added
  202. void notifyWatchonlyChanged(bool fHaveWatchonly);
  203. public slots:
  204. /* Wallet status might have changed */
  205. void updateStatus();
  206. /* New transaction, or transaction changed status */
  207. void updateTransaction(const QString &hash, int status);
  208. /* New, updated or removed address book entry */
  209. void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
  210. /* Watchonly added */
  211. void updateWatchOnlyFlag(bool fHaveWatchonly);
  212. /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
  213. void pollBalanceChanged();
  214. /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */
  215. void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; }
  216. };
  217. #endif // WALLETMODEL_H