Raven Core  3.0.0
P2P Digital Currency
walletmodel.h
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 #ifndef RAVEN_QT_WALLETMODEL_H
7 #define RAVEN_QT_WALLETMODEL_H
8 
9 #include "paymentrequestplus.h"
10 #include "walletmodeltransaction.h"
11 
13 
14 #include <map>
15 #include <vector>
16 
17 #include <QObject>
18 
19 class AddressTableModel;
20 class OptionsModel;
21 class PlatformStyle;
24 class AssetTableModel;
26 
27 class CCoinControl;
28 class CKeyID;
29 class COutPoint;
30 class COutput;
31 class CPubKey;
32 class CWallet;
33 class CWalletTx;
34 class CReserveKey;
35 class uint256;
36 
37 QT_BEGIN_NAMESPACE
38 class QTimer;
39 QT_END_NAMESPACE
40 
42 {
43 public:
45  explicit SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount& _amount, const QString &_message):
46  address(addr), label(_label), amount(_amount), message(_message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
47 
48  // If from an unauthenticated payment request, this is used for storing
49  // the addresses, e.g. address-A<br />address-B<br />address-C.
50  // Info: As we don't need to process addresses in here when using
51  // payment requests, we can abuse it for displaying an address list.
52  // Todo: This is a hack, should be replaced with a cleaner solution!
53  QString address;
54  QString label;
56  // If from a payment request, this is used for storing the memo
57  QString message;
58 
59  // If from a payment request, paymentRequest.IsInitialized() will be true
61  // Empty if no authentication or invalid signature/cert/etc.
63 
64  bool fSubtractFeeFromAmount; // memory only
65 
66  static const int CURRENT_VERSION = 1;
67  int nVersion;
68 
70 
71  template <typename Stream, typename Operation>
72  inline void SerializationOp(Stream& s, Operation ser_action) {
73  std::string sAddress = address.toStdString();
74  std::string sLabel = label.toStdString();
75  std::string sMessage = message.toStdString();
76  std::string sPaymentRequest;
77  if (!ser_action.ForRead() && paymentRequest.IsInitialized())
78  paymentRequest.SerializeToString(&sPaymentRequest);
79  std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString();
80 
81  READWRITE(this->nVersion);
82  READWRITE(sAddress);
83  READWRITE(sLabel);
84  READWRITE(amount);
85  READWRITE(sMessage);
86  READWRITE(sPaymentRequest);
87  READWRITE(sAuthenticatedMerchant);
88 
89  if (ser_action.ForRead())
90  {
91  address = QString::fromStdString(sAddress);
92  label = QString::fromStdString(sLabel);
93  message = QString::fromStdString(sMessage);
94  if (!sPaymentRequest.empty())
95  paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
96  authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
97  }
98  }
99 };
100 
102 {
103 public:
105  explicit SendAssetsRecipient(const QString& assetName, const QString &addr, const QString &_label, const CAmount& _amount, const QString &_message):
106  assetName(assetName), address(addr), label(_label), amount(_amount), message(_message), nVersion(SendAssetsRecipient::CURRENT_VERSION) {}
107 
108  // If from an unauthenticated payment request, this is used for storing
109  // the addresses, e.g. address-A<br />address-B<br />address-C.
110  // Info: As we don't need to process addresses in here when using
111  // payment requests, we can abuse it for displaying an address list.
112  // Todo: This is a hack, should be replaced with a cleaner solution!
113 
114  QString assetName;
115  QString address;
116  QString label;
118  // If from a payment request, this is used for storing the memo
119  QString message;
120 
121  // If from a payment request, paymentRequest.IsInitialized() will be true
123  // Empty if no authentication or invalid signature/cert/etc.
125 
126  static const int CURRENT_VERSION = 1;
127  int nVersion;
128 
130 
131  template <typename Stream, typename Operation>
132  inline void SerializationOp(Stream& s, Operation ser_action) {
133  std::string sAddress = address.toStdString();
134  std::string sLabel = label.toStdString();
135  std::string sMessage = message.toStdString();
136  std::string sPaymentRequest;
137  std::string sAssetName = assetName.toStdString();
138  if (!ser_action.ForRead() && paymentRequest.IsInitialized())
139  paymentRequest.SerializeToString(&sPaymentRequest);
140  std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString();
141 
142  READWRITE(this->nVersion);
143  READWRITE(sAssetName);
144  READWRITE(sAddress);
145  READWRITE(sLabel);
146  READWRITE(amount);
147  READWRITE(sMessage);
148  READWRITE(sPaymentRequest);
149  READWRITE(sAuthenticatedMerchant);
150 
151  if (ser_action.ForRead())
152  {
153  assetName = QString::fromStdString(sAssetName);
154  address = QString::fromStdString(sAddress);
155  label = QString::fromStdString(sLabel);
156  message = QString::fromStdString(sMessage);
157  if (!sPaymentRequest.empty())
158  paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
159  authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
160  }
161  }
162 };
163 
165 class WalletModel : public QObject
166 {
167  Q_OBJECT
168 
169 public:
170  explicit WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
171  ~WalletModel();
172 
173  enum StatusCode // Returned by sendCoins
174  {
175  OK,
181  TransactionCreationFailed, // Error returned when wallet is still locked
184  PaymentRequestExpired
185  };
186 
188  {
189  Unencrypted, // !wallet->IsCrypted()
190  Locked, // wallet->IsCrypted() && wallet->IsLocked()
191  Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
192  };
193 
194  OptionsModel *getOptionsModel();
195  AddressTableModel *getAddressTableModel();
196  TransactionTableModel *getTransactionTableModel();
197  AssetTableModel *getAssetTableModel();
198  RecentRequestsTableModel *getRecentRequestsTableModel();
199 
200  CAmount getBalance(const CCoinControl *coinControl = nullptr) const;
201  CAmount getUnconfirmedBalance() const;
202  CAmount getImmatureBalance() const;
203  bool haveWatchOnly() const;
204  CAmount getWatchBalance() const;
205  CAmount getWatchUnconfirmedBalance() const;
206  CAmount getWatchImmatureBalance() const;
207  EncryptionStatus getEncryptionStatus() const;
208 
209  // Check address for validity
210  bool validateAddress(const QString &address);
211 
212  // Return status record for SendCoins, contains error id + information
214  {
215  SendCoinsReturn(StatusCode _status = OK, QString _reasonCommitFailed = "")
216  : status(_status),
217  reasonCommitFailed(_reasonCommitFailed)
218  {
219  }
222  };
223 
224  // prepare transaction for getting txfee before sending coins
225  SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl& coinControl);
226 
227  // Send coins to a list of recipients
228  SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
229 
230  SendCoinsReturn sendAssets(CWalletTx& tx, QList<SendAssetsRecipient>& recipients, CReserveKey& reservekey);
231 
232  // Wallet encryption
233  bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
234  // Passphrase only needed when unlocking
235  bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
236  bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
237  // Wallet backup
238  bool backupWallet(const QString &filename);
239 
240  // RAI object for unlocking wallet, returned by requestUnlock()
242  {
243  public:
244  UnlockContext(WalletModel *wallet, bool valid, bool relock);
245  ~UnlockContext();
246 
247  bool isValid() const { return valid; }
248 
249  // Copy operator and constructor transfer the context
250  UnlockContext(const UnlockContext& obj) { CopyFrom(obj); }
251  UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; }
252  private:
254  bool valid;
255  mutable bool relock; // mutable, as it can be set to false by copying
256 
257  void CopyFrom(const UnlockContext& rhs);
258  };
259 
260  UnlockContext requestUnlock();
261 
262  bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
263  bool IsSpendable(const CTxDestination& dest) const;
264  bool getPrivKey(const CKeyID &address, CKey& vchPrivKeyOut) const;
265  void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
266  bool isSpent(const COutPoint& outpoint) const;
267  void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
269  // Map of asset name to map of address to CTxOut
270  void listAssets(std::map<QString, std::map<QString, std::vector<COutput> > >& mapCoins) const;
272  bool isLockedCoin(uint256 hash, unsigned int n) const;
273  void lockCoin(COutPoint& output);
274  void unlockCoin(COutPoint& output);
275  void listLockedCoins(std::vector<COutPoint>& vOutpts);
276 
277  void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
278  bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
279 
280  bool transactionCanBeAbandoned(uint256 hash) const;
281  bool abandonTransaction(uint256 hash) const;
282 
283  bool transactionCanBeBumped(uint256 hash) const;
284  bool bumpFee(uint256 hash);
285 
286  static bool isWalletEnabled();
287 
288  bool hdEnabled() const;
289 
290  int getDefaultConfirmTarget() const;
291 
292  bool getDefaultWalletRbf() const;
293 
294  CWallet* getWallet() const;
295 
296 private:
300 
301  // Wallet has an options model for wallet-specific options
302  // (transaction fee, for example)
304 
309 
310  // Cache some values to be able to detect changes
319 
320  QTimer *pollTimer;
321 
322  void subscribeToCoreSignals();
323  void unsubscribeFromCoreSignals();
324  void checkBalanceChanged();
325 
326 Q_SIGNALS:
327  // Signal that balance in wallet changed
328  void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
329  const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
330 
331  // Encryption status of wallet changed
332  void encryptionStatusChanged(int status);
333 
334  // Signal emitted when wallet needs to be unlocked
335  // It is valid behaviour for listeners to keep the wallet locked after this signal;
336  // this means that the unlocking failed or was cancelled.
337  void requireUnlock();
338 
339  // Fired when a message should be reported to the user
340  void message(const QString &title, const QString &message, unsigned int style);
341 
342  // Coins sent: from wallet, to recipient, in (serialized) transaction:
343  void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
344 
345  // Asset sent: from wallet, to recipient, in (serialized) transaction:
346  void assetsSent(CWallet* wallet, SendAssetsRecipient recipient, QByteArray transaction);
347 
348  // Show progress dialog e.g. for rescan
349  void showProgress(const QString &title, int nProgress);
350 
351  // Watch-only address added
352  void notifyWatchonlyChanged(bool fHaveWatchonly);
353 
354 public Q_SLOTS:
355  /* Wallet status might have changed */
356  void updateStatus();
357  /* New transaction, or transaction changed status */
358  void updateTransaction();
359  /* New, updated or removed address book entry */
360  void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
361  /* Watch-only added */
362  void updateWatchOnlyFlag(bool fHaveWatchonly);
363  /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
364  void pollBalanceChanged();
365 };
366 
367 #endif // RAVEN_QT_WALLETMODEL_H
Model for list of recently generated payment requests / raven: URIs.
TransactionTableModel * transactionTableModel
Definition: walletmodel.h:306
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:89
RecentRequestsTableModel * recentRequestsTableModel
Definition: walletmodel.h:308
PaymentRequestPlus paymentRequest
Definition: walletmodel.h:60
UnlockContext & operator=(const UnlockContext &rhs)
Definition: walletmodel.h:251
#define READWRITE(obj)
Definition: serialize.h:163
SendAssetsRecipient(const QString &assetName, const QString &addr, const QString &_label, const CAmount &_amount, const QString &_message)
Definition: walletmodel.h:105
static const int CURRENT_VERSION
Definition: walletmodel.h:66
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
bool SerializeToString(std::string *output) const
SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount &_amount, const QString &_message)
Definition: walletmodel.h:45
PaymentRequestPlus paymentRequest
Definition: walletmodel.h:122
AssetTableModel * assetTableModel
Definition: walletmodel.h:307
Coin Control Features.
Definition: coincontrol.h:17
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
void SerializationOp(Stream &s, Operation ser_action)
Definition: walletmodel.h:132
CWallet * wallet
Definition: walletmodel.h:297
Models assets portion of wallet as table of owned assets.
CAmount cachedImmatureBalance
Definition: walletmodel.h:313
An encapsulated public key.
Definition: pubkey.h:40
SendCoinsReturn(StatusCode _status=OK, QString _reasonCommitFailed="")
Definition: walletmodel.h:215
CAmount cachedBalance
Definition: walletmodel.h:311
OptionsModel * optionsModel
Definition: walletmodel.h:303
CAmount cachedWatchOnlyBalance
Definition: walletmodel.h:314
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 SerializationOp(Stream &s, Operation ser_action)
Definition: walletmodel.h:72
UI model for the transaction table of a wallet.
bool parse(const QByteArray &data)
Qt model of the address book in the core.
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:285
UnlockContext(const UnlockContext &obj)
Definition: walletmodel.h:250
QTimer * pollTimer
Definition: walletmodel.h:320
256-bit opaque blob.
Definition: uint256.h:123
int cachedNumBlocks
Definition: walletmodel.h:318
CAmount cachedWatchUnconfBalance
Definition: walletmodel.h:315
bool fForceCheckBalanceChanged
Definition: walletmodel.h:299
CAmount cachedWatchImmatureBalance
Definition: walletmodel.h:316
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
Interface to Raven wallet from Qt view code.
Definition: walletmodel.h:165
QString authenticatedMerchant
Definition: walletmodel.h:124
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
Data model for a walletmodel transaction.
AddressTableModel * addressTableModel
Definition: walletmodel.h:305
bool fSubtractFeeFromAmount
Definition: walletmodel.h:64
An encapsulated private key.
Definition: key.h:36
bool fHaveWatchOnly
Definition: walletmodel.h:298
QString authenticatedMerchant
Definition: walletmodel.h:62