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