Bitcoin Core  0.18.99
P2P Digital Currency
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:
57  explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
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);
107  READWRITE(sPaymentRequest);
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
144  PaymentRequestExpired
145  };
146 
148  {
149  Unencrypted, // !wallet->IsCrypted()
150  Locked, // wallet->IsCrypted() && wallet->IsLocked()
151  Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
152  };
153 
154  OptionsModel *getOptionsModel();
155  AddressTableModel *getAddressTableModel();
156  TransactionTableModel *getTransactionTableModel();
157  RecentRequestsTableModel *getRecentRequestsTableModel();
158 
159  EncryptionStatus getEncryptionStatus() const;
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
180  SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
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:
192  UnlockContext(WalletModel *wallet, bool valid, bool relock);
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 
211  UnlockContext requestUnlock();
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 
230  AddressTableModel* getAddressTableModel() const { return addressTableModel; }
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 
243  bool fForceCheckBalanceChanged{false};
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();
261  void unsubscribeFromCoreSignals();
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
269  void encryptionStatusChanged();
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
UnlockContext(UnlockContext &&obj)
Definition: walletmodel.h:200
Model for list of recently generated payment requests / bitcoin: URIs.
TransactionTableModel * transactionTableModel
Definition: walletmodel.h:250
CWallet & m_wallet
Definition: wallet.cpp:58
interfaces::Wallet & wallet() const
Definition: walletmodel.h:223
RecentRequestsTableModel * recentRequestsTableModel
Definition: walletmodel.h:251
std::unique_ptr< interfaces::Handler > m_handler_address_book_changed
Definition: walletmodel.h:235
std::unique_ptr< interfaces::Handler > m_handler_unload
Definition: walletmodel.h:233
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:60
bool SerializeToString(std::string *output) const
std::unique_ptr< interfaces::Handler > m_handler_status_changed
Definition: walletmodel.h:234
SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount &_amount, const QString &_message)
Definition: walletmodel.h:58
OutputType
Definition: outputtype.h:16
Coin Control Features.
Definition: coincontrol.h:16
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
Collection of wallet balances.
Definition: wallet.h:319
An encapsulated public key.
Definition: pubkey.h:30
Interface for accessing a wallet.
Definition: wallet.h:46
std::unique_ptr< interfaces::Wallet > m_wallet
Definition: walletmodel.h:232
SendCoinsReturn(StatusCode _status=OK, QString _reasonCommitFailed="")
Definition: walletmodel.h:167
OptionsModel * optionsModel
Definition: walletmodel.h:247
EncryptionStatus cachedEncryptionStatus
Definition: walletmodel.h:255
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:18
interfaces::Node & node() const
Definition: walletmodel.h:222
void SerializationOp(Stream &s, Operation ser_action)
Definition: walletmodel.h:91
UI model for the transaction table of a wallet.
bool parse(const QByteArray &data)
Qt model of the address book in the core.
std::unique_ptr< interfaces::Handler > m_handler_show_progress
Definition: walletmodel.h:237
QTimer * pollTimer
Definition: walletmodel.h:258
UnlockContext & operator=(UnlockContext &&rhs)
Definition: walletmodel.h:201
256-bit opaque blob.
Definition: uint256.h:121
int cachedNumBlocks
Definition: walletmodel.h:256
std::unique_ptr< interfaces::Handler > m_handler_can_get_addrs_changed
Definition: walletmodel.h:239
AddressTableModel * getAddressTableModel() const
Definition: walletmodel.h:230
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:29
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:125
interfaces::WalletBalances m_cached_balances
Definition: walletmodel.h:254
interfaces::Node & m_node
Definition: walletmodel.h:240
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
Data model for a walletmodel transaction.
AddressTableModel * addressTableModel
Definition: walletmodel.h:249
bool fSubtractFeeFromAmount
Definition: walletmodel.h:83
std::unique_ptr< interfaces::Handler > m_handler_transaction_changed
Definition: walletmodel.h:236
bool fHaveWatchOnly
Definition: walletmodel.h:242
std::string sPaymentRequest
Definition: walletmodel.h:78
#define READWRITE(...)
Definition: serialize.h:184
QString authenticatedMerchant
Definition: walletmodel.h:81
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:36
std::unique_ptr< interfaces::Handler > m_handler_watch_only_changed
Definition: walletmodel.h:238