Bitcoin
walletmodel.h
Go to the documentation of this file.
1 // Copyright (c) 2011-2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_QT_WALLETMODEL_H
6 #define BITCOIN_QT_WALLETMODEL_H
7 
8 #include <amount.h>
9 #include <key.h>
10 #include <serialize.h>
11 #include <script/standard.h>
12 
13 #if defined(HAVE_CONFIG_H)
14 #include <config/bitcoin-config.h>
15 #endif
16 
17 #ifdef ENABLE_BIP70
18 #include <qt/paymentrequestplus.h>
19 #endif
21 
22 #include <interfaces/wallet.h>
24 
25 #include <map>
26 #include <vector>
27 
28 #include <QObject>
29 
30 enum class OutputType;
31 
32 class AddressTableModel;
33 class OptionsModel;
34 class PlatformStyle;
38 
39 class CCoinControl;
40 class CKeyID;
41 class COutPoint;
42 class COutput;
43 class CPubKey;
44 class uint256;
45 
46 namespace interfaces {
47 class Node;
48 } // namespace interfaces
49 
50 QT_BEGIN_NAMESPACE
51 class QTimer;
52 QT_END_NAMESPACE
53 
55 {
56 public:
58  explicit SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount& _amount, const QString &_message):
59  address(addr), label(_label), amount(_amount), message(_message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
60 
61  // If from an unauthenticated payment request, this is used for storing
62  // the addresses, e.g. address-A<br />address-B<br />address-C.
63  // Info: As we don't need to process addresses in here when using
64  // payment requests, we can abuse it for displaying an address list.
65  // Todo: This is a hack, should be replaced with a cleaner solution!
66  QString address;
67  QString label;
69  // If from a payment request, this is used for storing the memo
70  QString message;
71 
72 #ifdef ENABLE_BIP70
73  // If from a payment request, paymentRequest.IsInitialized() will be true
74  PaymentRequestPlus paymentRequest;
75 #else
76  // If building with BIP70 is disabled, keep the payment request around as
77  // serialized string to ensure load/store is lossless
78  std::string sPaymentRequest;
79 #endif
80  // Empty if no authentication or invalid signature/cert/etc.
82 
83  bool fSubtractFeeFromAmount; // memory only
84 
85  static const int CURRENT_VERSION = 1;
86  int nVersion;
87 
89 
90  template <typename Stream, typename Operation>
91  inline void SerializationOp(Stream& s, Operation ser_action) {
92  std::string sAddress = address.toStdString();
93  std::string sLabel = label.toStdString();
94  std::string sMessage = message.toStdString();
95 #ifdef ENABLE_BIP70
96  std::string sPaymentRequest;
97  if (!ser_action.ForRead() && paymentRequest.IsInitialized())
98  paymentRequest.SerializeToString(&sPaymentRequest);
99 #endif
100  std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString();
101 
102  READWRITE(this->nVersion);
103  READWRITE(sAddress);
104  READWRITE(sLabel);
105  READWRITE(amount);
106  READWRITE(sMessage);
108  READWRITE(sAuthenticatedMerchant);
109 
110  if (ser_action.ForRead())
111  {
112  address = QString::fromStdString(sAddress);
113  label = QString::fromStdString(sLabel);
114  message = QString::fromStdString(sMessage);
115 #ifdef ENABLE_BIP70
116  if (!sPaymentRequest.empty())
117  paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
118 #endif
119  authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
120  }
121  }
122 };
123 
125 class WalletModel : public QObject
126 {
127  Q_OBJECT
128 
129 public:
130  explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *optionsModel, QObject *parent = nullptr);
131  ~WalletModel();
132 
133  enum StatusCode // Returned by sendCoins
134  {
135  OK,
141  TransactionCreationFailed, // Error returned when wallet is still locked
145  };
146 
148  {
149  Unencrypted, // !wallet->IsCrypted()
150  Locked, // wallet->IsCrypted() && wallet->IsLocked()
151  Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
152  };
153 
158 
160 
161  // Check address for validity
162  bool validateAddress(const QString &address);
163 
164  // Return status record for SendCoins, contains error id + information
166  {
167  SendCoinsReturn(StatusCode _status = OK, QString _reasonCommitFailed = "")
168  : status(_status),
169  reasonCommitFailed(_reasonCommitFailed)
170  {
171  }
174  };
175 
176  // prepare transaction for getting txfee before sending coins
177  SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl& coinControl);
178 
179  // Send coins to a list of recipients
181 
182  // Wallet encryption
183  bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
184  // Passphrase only needed when unlocking
185  bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
186  bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
187 
188  // RAI object for unlocking wallet, returned by requestUnlock()
190  {
191  public:
193  ~UnlockContext();
194 
195  bool isValid() const { return valid; }
196 
197  // Copy constructor is disabled.
198  UnlockContext(const UnlockContext&) = delete;
199  // Move operator and constructor transfer the context
200  UnlockContext(UnlockContext&& obj) { CopyFrom(std::move(obj)); }
201  UnlockContext& operator=(UnlockContext&& rhs) { CopyFrom(std::move(rhs)); return *this; }
202  private:
204  bool valid;
205  mutable bool relock; // mutable, as it can be set to false by copying
206 
207  UnlockContext& operator=(const UnlockContext&) = default;
208  void CopyFrom(UnlockContext&& rhs);
209  };
210 
212 
213  void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
214  bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
215 
216  bool bumpFee(uint256 hash, uint256& new_hash);
217 
218  static bool isWalletEnabled();
219  bool privateKeysDisabled() const;
220  bool canGetAddresses() const;
221 
222  interfaces::Node& node() const { return m_node; }
223  interfaces::Wallet& wallet() const { return *m_wallet; }
224 
225  QString getWalletName() const;
226  QString getDisplayName() const;
227 
228  bool isMultiwallet();
229 
231 private:
232  std::unique_ptr<interfaces::Wallet> m_wallet;
233  std::unique_ptr<interfaces::Handler> m_handler_unload;
234  std::unique_ptr<interfaces::Handler> m_handler_status_changed;
235  std::unique_ptr<interfaces::Handler> m_handler_address_book_changed;
236  std::unique_ptr<interfaces::Handler> m_handler_transaction_changed;
237  std::unique_ptr<interfaces::Handler> m_handler_show_progress;
238  std::unique_ptr<interfaces::Handler> m_handler_watch_only_changed;
239  std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
241 
244 
245  // Wallet has an options model for wallet-specific options
246  // (transaction fee, for example)
248 
252 
253  // Cache some values to be able to detect changes
257 
258  QTimer *pollTimer;
259 
260  void subscribeToCoreSignals();
262  void checkBalanceChanged(const interfaces::WalletBalances& new_balances);
263 
264 Q_SIGNALS:
265  // Signal that balance in wallet changed
266  void balanceChanged(const interfaces::WalletBalances& balances);
267 
268  // Encryption status of wallet changed
270 
271  // Signal emitted when wallet needs to be unlocked
272  // It is valid behaviour for listeners to keep the wallet locked after this signal;
273  // this means that the unlocking failed or was cancelled.
274  void requireUnlock();
275 
276  // Fired when a message should be reported to the user
277  void message(const QString &title, const QString &message, unsigned int style);
278 
279  // Coins sent: from wallet, to recipient, in (serialized) transaction:
280  void coinsSent(WalletModel* wallet, SendCoinsRecipient recipient, QByteArray transaction);
281 
282  // Show progress dialog e.g. for rescan
283  void showProgress(const QString &title, int nProgress);
284 
285  // Watch-only address added
286  void notifyWatchonlyChanged(bool fHaveWatchonly);
287 
288  // Signal that wallet is about to be removed
289  void unload();
290 
291  // Notify that there are now keys in the keypool
292  void canGetAddressesChanged();
293 
294 public Q_SLOTS:
295  /* Wallet status might have changed */
296  void updateStatus();
297  /* New transaction, or transaction changed status */
298  void updateTransaction();
299  /* New, updated or removed address book entry */
300  void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
301  /* Watch-only added */
302  void updateWatchOnlyFlag(bool fHaveWatchonly);
303  /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
304  void pollBalanceChanged();
305 };
306 
307 #endif // BITCOIN_QT_WALLETMODEL_H
std::unique_ptr< interfaces::Handler > m_handler_transaction_changed
Definition: walletmodel.h:236
bool isMultiwallet()
Definition: walletmodel.cpp:605
void updateStatus()
Definition: walletmodel.cpp:60
static const int CURRENT_VERSION
Definition: walletmodel.h:85
Definition: wallet.h:636
Definition: walletmodel.h:125
std::unique_ptr< interfaces::Handler > m_handler_show_progress
Definition: walletmodel.h:237
void unsubscribeFromCoreSignals()
Definition: walletmodel.cpp:451
Definition: optionsmodel.h:29
Definition: walletmodel.h:140
void message(const QString &title, const QString &message, unsigned int style)
Definition: moc_walletmodel.cpp:296
std::unique_ptr< interfaces::Handler > m_handler_address_book_changed
Definition: walletmodel.h:235
void updateTransaction()
Definition: walletmodel.cpp:102
UnlockContext(UnlockContext &&obj)
Definition: walletmodel.h:200
Definition: addresstablemodel.h:23
UnlockContext(WalletModel *wallet, bool valid, bool relock)
Definition: walletmodel.cpp:478
QString label
Definition: walletmodel.h:67
Definition: walletmodel.h:189
EncryptionStatus cachedEncryptionStatus
Definition: walletmodel.h:255
bool parse(const QByteArray &data)
Definition: paymentrequestplus.cpp:28
Definition: paymentrequestplus.h:29
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:60
bool IsInitialized() const
Definition: paymentrequestplus.cpp:55
Collection of wallet balances.
Definition: wallet.h:321
Definition: pubkey.h:20
std::string sPaymentRequest
Definition: walletmodel.h:78
WalletModel(std::unique_ptr< interfaces::Wallet > wallet, interfaces::Node &node, const PlatformStyle *platformStyle, OptionsModel *optionsModel, QObject *parent=nullptr)
Definition: walletmodel.cpp:35
EncryptionStatus getEncryptionStatus() const
Definition: walletmodel.cpp:326
bool canGetAddresses() const
Definition: walletmodel.cpp:589
UnlockContext requestUnlock()
Definition: walletmodel.cpp:464
SendCoinsReturn(StatusCode _status=OK, QString _reasonCommitFailed="")
Definition: walletmodel.h:167
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
Definition: walletmodel.cpp:108
QString address
Definition: walletmodel.h:66
static bool isWalletEnabled()
Definition: walletmodel.cpp:579
Definition: walletmodel.h:149
void unload()
Definition: moc_walletmodel.cpp:324
TransactionTableModel * getTransactionTableModel()
Definition: walletmodel.cpp:316
OutputType
Definition: outputtype.h:16
std::unique_ptr< interfaces::Handler > m_handler_watch_only_changed
Definition: walletmodel.h:238
bool fSubtractFeeFromAmount
Definition: walletmodel.h:83
Definition: coincontrol.h:16
bool bumpFee(uint256 hash, uint256 &new_hash)
Definition: walletmodel.cpp:519
Definition: walletmodel.h:138
Definition: walletmodel.h:144
int64_t CAmount
Definition: amount.h:12
void updateWatchOnlyFlag(bool fHaveWatchonly)
Definition: walletmodel.cpp:115
bool SerializeToString(std::string *output) const
Definition: paymentrequestplus.cpp:50
bool relock
Definition: walletmodel.h:205
RecentRequestsTableModel * recentRequestsTableModel
Definition: walletmodel.h:251
std::unique_ptr< interfaces::Handler > m_handler_status_changed
Definition: walletmodel.h:234
Definition: walletmodel.h:151
RecentRequestsTableModel * getRecentRequestsTableModel()
Definition: walletmodel.cpp:321
QString getDisplayName() const
Definition: walletmodel.cpp:599
void loadReceiveRequests(std::vector< std::string > &vReceiveRequests)
Definition: walletmodel.cpp:500
Definition: walletmodel.h:150
CAmount amount
Definition: walletmodel.h:68
SendCoinsReturn sendCoins(WalletModelTransaction &transaction)
Definition: walletmodel.cpp:235
Definition: dummywallet.cpp:11
void coinsSent(WalletModel *wallet, SendCoinsRecipient recipient, QByteArray transaction)
Definition: moc_walletmodel.cpp:303
void notifyWatchonlyChanged(bool fHaveWatchonly)
Definition: moc_walletmodel.cpp:317
Definition: transaction.h:18
~UnlockContext()
Definition: walletmodel.cpp:485
std::unique_ptr< interfaces::Handler > m_handler_unload
Definition: walletmodel.h:233
bool privateKeysDisabled() const
Definition: walletmodel.cpp:584
std::unique_ptr< interfaces::Handler > m_handler_can_get_addrs_changed
Definition: walletmodel.h:239
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase)
Definition: walletmodel.cpp:342
Definition: walletmodel.h:139
int cachedNumBlocks
Definition: walletmodel.h:256
interfaces::WalletBalances m_cached_balances
Definition: walletmodel.h:254
void balanceChanged(const interfaces::WalletBalances &balances)
Definition: moc_walletmodel.cpp:277
int nVersion
Definition: walletmodel.h:86
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:36
Definition: walletmodeltransaction.h:23
void showProgress(const QString &title, int nProgress)
Definition: moc_walletmodel.cpp:310
UnlockContext & operator=(UnlockContext &&rhs)
Definition: walletmodel.h:201
OptionsModel * getOptionsModel()
Definition: walletmodel.cpp:306
SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount &_amount, const QString &_message)
Definition: walletmodel.h:58
void subscribeToCoreSignals()
Definition: walletmodel.cpp:439
bool validateAddress(const QString &address)
Definition: walletmodel.cpp:121
Definition: walletmodel.h:141
Definition: walletmodel.h:165
TransactionTableModel * transactionTableModel
Definition: walletmodel.h:250
std::unique_ptr< interfaces::Wallet > m_wallet
Definition: walletmodel.h:232
Definition: walletmodel.h:137
bool valid
Definition: walletmodel.h:204
Definition: uint256.h:121
WalletModel * wallet
Definition: walletmodel.h:203
void encryptionStatusChanged()
Definition: moc_walletmodel.cpp:284
AddressTableModel * getAddressTableModel() const
Definition: walletmodel.h:230
void canGetAddressesChanged()
Definition: moc_walletmodel.cpp:330
Definition: walletmodel.h:143
bool fHaveWatchOnly
Definition: walletmodel.h:242
EncryptionStatus
Definition: walletmodel.h:147
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass)
Definition: walletmodel.cpp:370
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
Definition: walletmodel.cpp:505
StatusCode
Definition: walletmodel.h:133
OptionsModel * optionsModel
Definition: walletmodel.h:247
QString reasonCommitFailed
Definition: walletmodel.h:173
void requireUnlock()
Definition: moc_walletmodel.cpp:290
QString authenticatedMerchant
Definition: walletmodel.h:81
AddressTableModel * addressTableModel
Definition: walletmodel.h:249
void checkBalanceChanged(const interfaces::WalletBalances &new_balances)
Definition: walletmodel.cpp:94
interfaces::Node & m_node
Definition: walletmodel.h:240
bool fForceCheckBalanceChanged
Definition: walletmodel.h:243
interfaces::Node & node() const
Definition: walletmodel.h:222
StatusCode status
Definition: walletmodel.h:172
Definition: walletmodel.h:142
Definition: walletmodel.h:136
QString message
Definition: walletmodel.h:70
QTimer * pollTimer
Definition: walletmodel.h:258
signed long long int64_t
Definition: stdint.h:18
Definition: pubkey.h:30
Definition: platformstyle.h:13
void pollBalanceChanged()
Definition: walletmodel.cpp:69
Definition: transactiontablemodel.h:26
QString getWalletName() const
Definition: walletmodel.cpp:594
void SerializationOp(Stream &s, Operation ser_action)
Definition: walletmodel.h:91
void CopyFrom(UnlockContext &&rhs)
Definition: walletmodel.cpp:493
Definition: recentrequeststablemodel.h:56
#define READWRITE(...)
Definition: serialize.h:184
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString())
Definition: walletmodel.cpp:356
~WalletModel()
Definition: walletmodel.cpp:55
interfaces::Wallet & wallet() const
Definition: walletmodel.h:223
Definition: walletmodel.h:135
bool isValid() const
Definition: walletmodel.h:195
AddressTableModel * getAddressTableModel()
Definition: walletmodel.cpp:311
Definition: walletmodel.h:54
SendCoinsRecipient()
Definition: walletmodel.h:57
SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl &coinControl)
Definition: walletmodel.cpp:126
ADD_SERIALIZE_METHODS
Definition: walletmodel.h:88
Interface for accessing a wallet.
Definition: wallet.h:48