]>
Commit | Line | Data |
---|---|---|
b2120e22 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
5b40d886 | 3 | // Distributed under the MIT software license, see the accompanying |
3a25a2b9 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
093303a8 | 5 | |
e8ef3da7 WL |
6 | #ifndef BITCOIN_WALLET_H |
7 | #define BITCOIN_WALLET_H | |
8 | ||
eda37330 | 9 | #include "amount.h" |
d2270111 LD |
10 | #include "primitives/block.h" |
11 | #include "primitives/transaction.h" | |
51ed9ec9 | 12 | #include "crypter.h" |
e8ef3da7 | 13 | #include "key.h" |
2a45a494 | 14 | #include "keystore.h" |
51ed9ec9 | 15 | #include "main.h" |
ab1b288f | 16 | #include "ui_interface.h" |
611116d4 | 17 | #include "wallet_ismine.h" |
51ed9ec9 BD |
18 | #include "walletdb.h" |
19 | ||
20 | #include <algorithm> | |
21 | #include <map> | |
22 | #include <set> | |
23 | #include <stdexcept> | |
24 | #include <stdint.h> | |
25 | #include <string> | |
26 | #include <utility> | |
27 | #include <vector> | |
e8ef3da7 | 28 | |
5b40d886 MF |
29 | /** |
30 | * Settings | |
31 | */ | |
c6cb21d1 | 32 | extern CFeeRate payTxFee; |
aa279d61 | 33 | extern CAmount maxTxFee; |
b33d1f5e | 34 | extern unsigned int nTxConfirmTarget; |
1bbca249 | 35 | extern bool bSpendZeroConfChange; |
0ed9675b | 36 | extern bool fSendFreeTransactions; |
ed3e5e46 | 37 | extern bool fPayAtLeastCustomFee; |
cd7fa8bb | 38 | |
5b40d886 | 39 | //! -paytxfee default |
a372168e | 40 | static const CAmount DEFAULT_TRANSACTION_FEE = 0; |
5b40d886 | 41 | //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB |
a372168e | 42 | static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; |
aa279d61 GM |
43 | //! -maxtxfee default |
44 | static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; | |
45 | //! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) | |
46 | static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; | |
5b40d886 | 47 | //! Largest (in bytes) free transaction we're willing to create |
b33d1f5e | 48 | static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; |
ffeb4736 | 49 | |
c3f95ef1 | 50 | class CAccountingEntry; |
0689f46c | 51 | class CCoinControl; |
9b0369c7 | 52 | class COutput; |
51ed9ec9 BD |
53 | class CReserveKey; |
54 | class CScript; | |
55 | class CWalletTx; | |
e8ef3da7 | 56 | |
6b8de05d | 57 | /** (client) version numbers for particular wallet features */ |
439e1497 PW |
58 | enum WalletFeature |
59 | { | |
60 | FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output) | |
61 | ||
62 | FEATURE_WALLETCRYPT = 40000, // wallet encryption | |
63 | FEATURE_COMPRPUBKEY = 60000, // compressed public keys | |
64 | ||
65 | FEATURE_LATEST = 60000 | |
66 | }; | |
67 | ||
ed6d0b5f PW |
68 | |
69 | /** A key pool entry */ | |
70 | class CKeyPool | |
71 | { | |
72 | public: | |
51ed9ec9 | 73 | int64_t nTime; |
fd61d6f5 | 74 | CPubKey vchPubKey; |
ed6d0b5f | 75 | |
af8297c0 WL |
76 | CKeyPool(); |
77 | CKeyPool(const CPubKey& vchPubKeyIn); | |
ed6d0b5f | 78 | |
3f6540ad | 79 | ADD_SERIALIZE_METHODS; |
3d796f89 | 80 | |
84881f8c | 81 | template <typename Stream, typename Operation> |
31e9a838 | 82 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
ed6d0b5f PW |
83 | if (!(nType & SER_GETHASH)) |
84 | READWRITE(nVersion); | |
85 | READWRITE(nTime); | |
86 | READWRITE(vchPubKey); | |
3d796f89 | 87 | } |
ed6d0b5f PW |
88 | }; |
89 | ||
61885513 GA |
90 | /** Address book data */ |
91 | class CAddressBookData | |
92 | { | |
93 | public: | |
94 | std::string name; | |
a41d5fe0 | 95 | std::string purpose; |
61885513 GA |
96 | |
97 | CAddressBookData() | |
98 | { | |
a41d5fe0 | 99 | purpose = "unknown"; |
61885513 | 100 | } |
b10e1470 WL |
101 | |
102 | typedef std::map<std::string, std::string> StringMap; | |
103 | StringMap destdata; | |
61885513 GA |
104 | }; |
105 | ||
292623ad CL |
106 | struct CRecipient |
107 | { | |
108 | CScript scriptPubKey; | |
109 | CAmount nAmount; | |
110 | bool fSubtractFeeFromAmount; | |
111 | }; | |
3447cf87 CF |
112 | |
113 | typedef std::map<std::string, std::string> mapValue_t; | |
114 | ||
115 | ||
116 | static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue) | |
117 | { | |
118 | if (!mapValue.count("n")) | |
119 | { | |
120 | nOrderPos = -1; // TODO: calculate elsewhere | |
121 | return; | |
122 | } | |
123 | nOrderPos = atoi64(mapValue["n"].c_str()); | |
124 | } | |
125 | ||
126 | ||
127 | static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue) | |
128 | { | |
129 | if (nOrderPos == -1) | |
130 | return; | |
131 | mapValue["n"] = i64tostr(nOrderPos); | |
132 | } | |
133 | ||
134 | struct COutputEntry | |
135 | { | |
136 | CTxDestination destination; | |
137 | CAmount amount; | |
138 | int vout; | |
139 | }; | |
140 | ||
141 | /** A transaction with a merkle branch linking it to the block chain. */ | |
142 | class CMerkleTx : public CTransaction | |
e8ef3da7 WL |
143 | { |
144 | private: | |
3447cf87 | 145 | int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const; |
e8ef3da7 | 146 | |
3447cf87 CF |
147 | public: |
148 | uint256 hashBlock; | |
149 | std::vector<uint256> vMerkleBranch; | |
150 | int nIndex; | |
e8ef3da7 | 151 | |
3447cf87 CF |
152 | // memory only |
153 | mutable bool fMerkleVerified; | |
0b807a41 | 154 | |
439e1497 | 155 | |
3447cf87 CF |
156 | CMerkleTx() |
157 | { | |
158 | Init(); | |
159 | } | |
203d1ae6 | 160 | |
3447cf87 CF |
161 | CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) |
162 | { | |
163 | Init(); | |
164 | } | |
93a18a36 | 165 | |
3447cf87 CF |
166 | void Init() |
167 | { | |
168 | hashBlock = uint256(); | |
169 | nIndex = -1; | |
170 | fMerkleVerified = false; | |
171 | } | |
731b89b8 | 172 | |
3447cf87 CF |
173 | ADD_SERIALIZE_METHODS; |
174 | ||
175 | template <typename Stream, typename Operation> | |
176 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
177 | READWRITE(*(CTransaction*)this); | |
178 | nVersion = this->nVersion; | |
179 | READWRITE(hashBlock); | |
180 | READWRITE(vMerkleBranch); | |
181 | READWRITE(nIndex); | |
182 | } | |
183 | ||
184 | int SetMerkleBranch(const CBlock& block); | |
185 | ||
186 | ||
187 | /** | |
188 | * Return depth of transaction in blockchain: | |
189 | * -1 : not in blockchain, and not in memory pool (conflicted transaction) | |
190 | * 0 : in memory pool, waiting to be included in a block | |
191 | * >=1 : this many blocks deep in the main chain | |
5b40d886 | 192 | */ |
3447cf87 CF |
193 | int GetDepthInMainChain(const CBlockIndex* &pindexRet) const; |
194 | int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } | |
195 | bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } | |
196 | int GetBlocksToMaturity() const; | |
197 | bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); | |
198 | }; | |
6cc4a62c | 199 | |
3447cf87 CF |
200 | /** |
201 | * A transaction with a bunch of additional info that only the owner cares about. | |
202 | * It includes any unrecorded transactions needed to link it back to the block chain. | |
203 | */ | |
204 | class CWalletTx : public CMerkleTx | |
205 | { | |
206 | private: | |
207 | const CWallet* pwallet; | |
e8ef3da7 | 208 | |
3447cf87 CF |
209 | public: |
210 | mapValue_t mapValue; | |
211 | std::vector<std::pair<std::string, std::string> > vOrderForm; | |
212 | unsigned int fTimeReceivedIsTxTime; | |
213 | unsigned int nTimeReceived; //! time received by this node | |
214 | unsigned int nTimeSmart; | |
215 | char fFromMe; | |
216 | std::string strFromAccount; | |
217 | int64_t nOrderPos; //! position in ordered transaction list | |
0b807a41 | 218 | |
3447cf87 CF |
219 | // memory only |
220 | mutable bool fDebitCached; | |
221 | mutable bool fCreditCached; | |
222 | mutable bool fImmatureCreditCached; | |
223 | mutable bool fAvailableCreditCached; | |
224 | mutable bool fWatchDebitCached; | |
225 | mutable bool fWatchCreditCached; | |
226 | mutable bool fImmatureWatchCreditCached; | |
227 | mutable bool fAvailableWatchCreditCached; | |
228 | mutable bool fChangeCached; | |
229 | mutable CAmount nDebitCached; | |
230 | mutable CAmount nCreditCached; | |
231 | mutable CAmount nImmatureCreditCached; | |
232 | mutable CAmount nAvailableCreditCached; | |
233 | mutable CAmount nWatchDebitCached; | |
234 | mutable CAmount nWatchCreditCached; | |
235 | mutable CAmount nImmatureWatchCreditCached; | |
236 | mutable CAmount nAvailableWatchCreditCached; | |
237 | mutable CAmount nChangeCached; | |
4e87d341 | 238 | |
3447cf87 | 239 | CWalletTx() |
e8ef3da7 | 240 | { |
3447cf87 | 241 | Init(NULL); |
e8ef3da7 | 242 | } |
870da77d | 243 | |
3447cf87 | 244 | CWalletTx(const CWallet* pwalletIn) |
e8ef3da7 | 245 | { |
3447cf87 CF |
246 | Init(pwalletIn); |
247 | } | |
d04fd3e2 | 248 | |
3447cf87 CF |
249 | CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) |
250 | { | |
251 | Init(pwalletIn); | |
d04fd3e2 | 252 | } |
870da77d | 253 | |
3447cf87 | 254 | CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) |
870da77d | 255 | { |
3447cf87 | 256 | Init(pwalletIn); |
870da77d PK |
257 | } |
258 | ||
3447cf87 | 259 | void Init(const CWallet* pwalletIn) |
d04fd3e2 | 260 | { |
3447cf87 CF |
261 | pwallet = pwalletIn; |
262 | mapValue.clear(); | |
263 | vOrderForm.clear(); | |
264 | fTimeReceivedIsTxTime = false; | |
265 | nTimeReceived = 0; | |
266 | nTimeSmart = 0; | |
267 | fFromMe = false; | |
268 | strFromAccount.clear(); | |
269 | fDebitCached = false; | |
270 | fCreditCached = false; | |
271 | fImmatureCreditCached = false; | |
272 | fAvailableCreditCached = false; | |
273 | fWatchDebitCached = false; | |
274 | fWatchCreditCached = false; | |
275 | fImmatureWatchCreditCached = false; | |
276 | fAvailableWatchCreditCached = false; | |
277 | fChangeCached = false; | |
278 | nDebitCached = 0; | |
279 | nCreditCached = 0; | |
280 | nImmatureCreditCached = 0; | |
281 | nAvailableCreditCached = 0; | |
282 | nWatchDebitCached = 0; | |
283 | nWatchCreditCached = 0; | |
284 | nAvailableWatchCreditCached = 0; | |
285 | nImmatureWatchCreditCached = 0; | |
286 | nChangeCached = 0; | |
287 | nOrderPos = -1; | |
e8ef3da7 WL |
288 | } |
289 | ||
3447cf87 | 290 | ADD_SERIALIZE_METHODS; |
731b89b8 | 291 | |
3447cf87 CF |
292 | template <typename Stream, typename Operation> |
293 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
294 | if (ser_action.ForRead()) | |
295 | Init(NULL); | |
296 | char fSpent = false; | |
e8ef3da7 | 297 | |
3447cf87 CF |
298 | if (!ser_action.ForRead()) |
299 | { | |
300 | mapValue["fromaccount"] = strFromAccount; | |
e8ef3da7 | 301 | |
3447cf87 | 302 | WriteOrderPos(nOrderPos, mapValue); |
e8ef3da7 | 303 | |
3447cf87 CF |
304 | if (nTimeSmart) |
305 | mapValue["timesmart"] = strprintf("%u", nTimeSmart); | |
306 | } | |
fdbb537d | 307 | |
3447cf87 CF |
308 | READWRITE(*(CMerkleTx*)this); |
309 | std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev | |
310 | READWRITE(vUnused); | |
311 | READWRITE(mapValue); | |
312 | READWRITE(vOrderForm); | |
313 | READWRITE(fTimeReceivedIsTxTime); | |
314 | READWRITE(nTimeReceived); | |
315 | READWRITE(fFromMe); | |
316 | READWRITE(fSpent); | |
3869fb89 | 317 | |
3447cf87 CF |
318 | if (ser_action.ForRead()) |
319 | { | |
320 | strFromAccount = mapValue["fromaccount"]; | |
93a18a36 | 321 | |
3447cf87 | 322 | ReadOrderPos(nOrderPos, mapValue); |
439e1497 | 323 | |
3447cf87 CF |
324 | nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0; |
325 | } | |
95691680 | 326 | |
3447cf87 CF |
327 | mapValue.erase("fromaccount"); |
328 | mapValue.erase("version"); | |
329 | mapValue.erase("spent"); | |
330 | mapValue.erase("n"); | |
331 | mapValue.erase("timesmart"); | |
332 | } | |
93a18a36 | 333 | |
3447cf87 CF |
334 | //! make sure balances are recalculated |
335 | void MarkDirty() | |
336 | { | |
337 | fCreditCached = false; | |
338 | fAvailableCreditCached = false; | |
339 | fWatchDebitCached = false; | |
340 | fWatchCreditCached = false; | |
341 | fAvailableWatchCreditCached = false; | |
342 | fImmatureWatchCreditCached = false; | |
343 | fDebitCached = false; | |
344 | fChangeCached = false; | |
345 | } | |
346 | ||
347 | void BindWallet(CWallet *pwalletIn) | |
348 | { | |
349 | pwallet = pwalletIn; | |
350 | MarkDirty(); | |
351 | } | |
352 | ||
353 | //! filter decides which addresses will count towards the debit | |
354 | CAmount GetDebit(const isminefilter& filter) const; | |
355 | CAmount GetCredit(const isminefilter& filter) const; | |
356 | CAmount GetImmatureCredit(bool fUseCache=true) const; | |
357 | CAmount GetAvailableCredit(bool fUseCache=true) const; | |
358 | CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const; | |
359 | CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const; | |
360 | CAmount GetChange() const; | |
361 | ||
362 | void GetAmounts(std::list<COutputEntry>& listReceived, | |
363 | std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const; | |
364 | ||
365 | void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived, | |
366 | CAmount& nSent, CAmount& nFee, const isminefilter& filter) const; | |
367 | ||
368 | bool IsFromMe(const isminefilter& filter) const | |
369 | { | |
370 | return (GetDebit(filter) > 0); | |
371 | } | |
372 | ||
373 | bool IsTrusted() const; | |
374 | ||
375 | bool WriteToDisk(CWalletDB *pwalletdb); | |
376 | ||
377 | int64_t GetTxTime() const; | |
378 | int GetRequestCount() const; | |
379 | ||
380 | void RelayWalletTransaction(); | |
381 | ||
382 | std::set<uint256> GetConflicts() const; | |
383 | }; | |
384 | ||
385 | ||
386 | ||
387 | ||
388 | class COutput | |
389 | { | |
390 | public: | |
391 | const CWalletTx *tx; | |
392 | int i; | |
393 | int nDepth; | |
394 | bool fSpendable; | |
395 | ||
396 | COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) | |
397 | { | |
398 | tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; | |
399 | } | |
400 | ||
401 | std::string ToString() const; | |
402 | }; | |
403 | ||
404 | ||
405 | ||
406 | ||
407 | /** Private key that includes an expiration date in case it never gets used. */ | |
408 | class CWalletKey | |
409 | { | |
410 | public: | |
411 | CPrivKey vchPrivKey; | |
412 | int64_t nTimeCreated; | |
413 | int64_t nTimeExpires; | |
414 | std::string strComment; | |
415 | //! todo: add something to note what created it (user, getnewaddress, change) | |
416 | //! maybe should have a map<string, string> property map | |
417 | ||
418 | CWalletKey(int64_t nExpires=0); | |
419 | ||
420 | ADD_SERIALIZE_METHODS; | |
421 | ||
422 | template <typename Stream, typename Operation> | |
423 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
424 | if (!(nType & SER_GETHASH)) | |
425 | READWRITE(nVersion); | |
426 | READWRITE(vchPrivKey); | |
427 | READWRITE(nTimeCreated); | |
428 | READWRITE(nTimeExpires); | |
429 | READWRITE(LIMITED_STRING(strComment, 65536)); | |
430 | } | |
431 | }; | |
432 | ||
433 | ||
434 | ||
435 | /** | |
436 | * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, | |
437 | * and provides the ability to create new transactions. | |
438 | */ | |
439 | class CWallet : public CCryptoKeyStore, public CValidationInterface | |
440 | { | |
441 | private: | |
442 | bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; | |
443 | ||
444 | CWalletDB *pwalletdbEncryption; | |
445 | ||
446 | //! the current wallet version: clients below this version are not able to load the wallet | |
447 | int nWalletVersion; | |
448 | ||
449 | //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded | |
450 | int nWalletMaxVersion; | |
451 | ||
452 | int64_t nNextResend; | |
453 | int64_t nLastResend; | |
454 | ||
455 | /** | |
456 | * Used to keep track of spent outpoints, and | |
457 | * detect and report conflicts (double-spends or | |
458 | * mutated transactions where the mutant gets mined). | |
459 | */ | |
460 | typedef std::multimap<COutPoint, uint256> TxSpends; | |
461 | TxSpends mapTxSpends; | |
462 | void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); | |
463 | void AddToSpends(const uint256& wtxid); | |
464 | ||
465 | void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>); | |
466 | ||
467 | public: | |
468 | /* | |
469 | * Main wallet lock. | |
470 | * This lock protects all the fields added by CWallet | |
471 | * except for: | |
472 | * fFileBacked (immutable after instantiation) | |
473 | * strWalletFile (immutable after instantiation) | |
474 | */ | |
475 | mutable CCriticalSection cs_wallet; | |
476 | ||
477 | bool fFileBacked; | |
478 | std::string strWalletFile; | |
479 | ||
480 | std::set<int64_t> setKeyPool; | |
481 | std::map<CKeyID, CKeyMetadata> mapKeyMetadata; | |
482 | ||
483 | typedef std::map<unsigned int, CMasterKey> MasterKeyMap; | |
484 | MasterKeyMap mapMasterKeys; | |
485 | unsigned int nMasterKeyMaxID; | |
486 | ||
487 | CWallet() | |
488 | { | |
489 | SetNull(); | |
490 | } | |
491 | ||
492 | CWallet(std::string strWalletFileIn) | |
493 | { | |
494 | SetNull(); | |
495 | ||
496 | strWalletFile = strWalletFileIn; | |
497 | fFileBacked = true; | |
498 | } | |
499 | ||
500 | ~CWallet() | |
501 | { | |
502 | delete pwalletdbEncryption; | |
503 | pwalletdbEncryption = NULL; | |
504 | } | |
505 | ||
506 | void SetNull() | |
507 | { | |
508 | nWalletVersion = FEATURE_BASE; | |
509 | nWalletMaxVersion = FEATURE_BASE; | |
510 | fFileBacked = false; | |
511 | nMasterKeyMaxID = 0; | |
512 | pwalletdbEncryption = NULL; | |
513 | nOrderPosNext = 0; | |
514 | nNextResend = 0; | |
515 | nLastResend = 0; | |
516 | nTimeFirstKey = 0; | |
517 | } | |
518 | ||
519 | std::map<uint256, CWalletTx> mapWallet; | |
520 | ||
521 | int64_t nOrderPosNext; | |
522 | std::map<uint256, int> mapRequestCount; | |
523 | ||
524 | std::map<CTxDestination, CAddressBookData> mapAddressBook; | |
525 | ||
526 | CPubKey vchDefaultKey; | |
527 | ||
528 | std::set<COutPoint> setLockedCoins; | |
529 | ||
530 | int64_t nTimeFirstKey; | |
531 | ||
532 | const CWalletTx* GetWalletTx(const uint256& hash) const; | |
533 | ||
534 | //! check whether we are allowed to upgrade (or already support) to the named feature | |
535 | bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } | |
536 | ||
537 | void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const; | |
538 | bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const; | |
539 | ||
540 | bool IsSpent(const uint256& hash, unsigned int n) const; | |
541 | ||
542 | bool IsLockedCoin(uint256 hash, unsigned int n) const; | |
fdbb537d JG |
543 | void LockCoin(COutPoint& output); |
544 | void UnlockCoin(COutPoint& output); | |
545 | void UnlockAllCoins(); | |
546 | void ListLockedCoins(std::vector<COutPoint>& vOutpts); | |
9b0369c7 | 547 | |
5b40d886 MF |
548 | /** |
549 | * keystore implementation | |
550 | * Generate a new key | |
551 | */ | |
fd61d6f5 | 552 | CPubKey GenerateNewKey(); |
5b40d886 | 553 | //! Adds a key to the store, and saves it to disk. |
4addb2c0 | 554 | bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); |
5b40d886 | 555 | //! Adds a key to the store, without saving it to disk (used by LoadWallet) |
dfa23b94 | 556 | bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } |
5b40d886 | 557 | //! Load metadata (used by LoadWallet) |
4addb2c0 | 558 | bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata); |
d825e6a3 | 559 | |
95691680 | 560 | bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } |
0b807a41 | 561 | |
5b40d886 | 562 | //! Adds an encrypted key to the store, and saves it to disk. |
4addb2c0 | 563 | bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); |
5b40d886 | 564 | //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) |
2f15e86a | 565 | bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); |
922e8e29 | 566 | bool AddCScript(const CScript& redeemScript); |
18116b06 | 567 | bool LoadCScript(const CScript& redeemScript); |
4e87d341 | 568 | |
5b40d886 | 569 | //! Adds a destination data tuple to the store, and saves it to disk |
b10e1470 | 570 | bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value); |
5b40d886 | 571 | //! Erases a destination data tuple in the store and on disk |
b10e1470 | 572 | bool EraseDestData(const CTxDestination &dest, const std::string &key); |
5b40d886 | 573 | //! Adds a destination data tuple to the store, without saving it to disk |
b10e1470 | 574 | bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value); |
5b40d886 | 575 | //! Look up a destination data tuple in the store, return true if found false otherwise |
b10e1470 WL |
576 | bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const; |
577 | ||
5b40d886 | 578 | //! Adds a watch-only address to the store, and saves it to disk. |
d5087d1b | 579 | bool AddWatchOnly(const CScript &dest); |
ccca27a7 | 580 | bool RemoveWatchOnly(const CScript &dest); |
5b40d886 | 581 | //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) |
d5087d1b | 582 | bool LoadWatchOnly(const CScript &dest); |
c8988460 | 583 | |
94f778bd DN |
584 | bool Unlock(const SecureString& strWalletPassphrase); |
585 | bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); | |
586 | bool EncryptWallet(const SecureString& strWalletPassphrase); | |
acd65016 | 587 | |
51ed9ec9 | 588 | void GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const; |
434e4273 | 589 | |
5b40d886 MF |
590 | /** |
591 | * Increment the next transaction order id | |
592 | * @return next transaction order id | |
da7b8c12 | 593 | */ |
51ed9ec9 | 594 | int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL); |
da7b8c12 | 595 | |
c3f95ef1 | 596 | typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; |
51ed9ec9 | 597 | typedef std::multimap<int64_t, TxPair > TxItems; |
ddb709e9 | 598 | |
5b40d886 MF |
599 | /** |
600 | * Get the wallet's activity log | |
601 | * @return multimap of ordered transactions and accounting entries | |
602 | * @warning Returned pointers are *only* valid within the scope of passed acentries | |
ddb709e9 LD |
603 | */ |
604 | TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = ""); | |
c3f95ef1 | 605 | |
95d888a6 | 606 | void MarkDirty(); |
44bc988e | 607 | bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); |
d38da59b PW |
608 | void SyncTransaction(const CTransaction& tx, const CBlock* pblock); |
609 | bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); | |
00588c3f | 610 | void EraseFromWallet(const uint256 &hash); |
e8ef3da7 WL |
611 | int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); |
612 | void ReacceptWalletTransactions(); | |
613 | void ResendWalletTransactions(); | |
a372168e MF |
614 | CAmount GetBalance() const; |
615 | CAmount GetUnconfirmedBalance() const; | |
616 | CAmount GetImmatureBalance() const; | |
617 | CAmount GetWatchOnlyBalance() const; | |
618 | CAmount GetUnconfirmedWatchOnlyBalance() const; | |
619 | CAmount GetImmatureWatchOnlyBalance() const; | |
292623ad CL |
620 | bool CreateTransaction(const std::vector<CRecipient>& vecSend, |
621 | CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); | |
e8ef3da7 | 622 | bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); |
e8ef3da7 | 623 | |
13fc83c7 | 624 | static CFeeRate minTxFee; |
a372168e | 625 | static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); |
b33d1f5e | 626 | |
37971fcc | 627 | bool NewKeyPool(); |
13dd2d09 | 628 | bool TopUpKeyPool(unsigned int kpSize = 0); |
51ed9ec9 BD |
629 | void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool); |
630 | void KeepKey(int64_t nIndex); | |
631 | void ReturnKey(int64_t nIndex); | |
71ac5052 | 632 | bool GetKeyFromPool(CPubKey &key); |
51ed9ec9 | 633 | int64_t GetOldestKeyPoolTime(); |
434e4273 | 634 | void GetAllReserveKeys(std::set<CKeyID>& setAddress) const; |
e8ef3da7 | 635 | |
b1093efa | 636 | std::set< std::set<CTxDestination> > GetAddressGroupings(); |
a372168e | 637 | std::map<CTxDestination, CAmount> GetAddressBalances(); |
22dfd735 | 638 | |
3624356e GA |
639 | std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const; |
640 | ||
c8988460 | 641 | isminetype IsMine(const CTxIn& txin) const; |
a372168e | 642 | CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; |
c8988460 | 643 | isminetype IsMine(const CTxOut& txout) const |
e8ef3da7 WL |
644 | { |
645 | return ::IsMine(*this, txout.scriptPubKey); | |
646 | } | |
a372168e | 647 | CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const |
e8ef3da7 WL |
648 | { |
649 | if (!MoneyRange(txout.nValue)) | |
5262fde0 | 650 | throw std::runtime_error("CWallet::GetCredit(): value out of range"); |
ffd40da3 | 651 | return ((IsMine(txout) & filter) ? txout.nValue : 0); |
3447cf87 CF |
652 | } |
653 | bool IsChange(const CTxOut& txout) const; | |
654 | CAmount GetChange(const CTxOut& txout) const | |
e8ef3da7 | 655 | { |
3447cf87 CF |
656 | if (!MoneyRange(txout.nValue)) |
657 | throw std::runtime_error("CWallet::GetChange(): value out of range"); | |
658 | return (IsChange(txout) ? txout.nValue : 0); | |
e8ef3da7 | 659 | } |
3447cf87 | 660 | bool IsMine(const CTransaction& tx) const |
e8ef3da7 | 661 | { |
3447cf87 CF |
662 | BOOST_FOREACH(const CTxOut& txout, tx.vout) |
663 | if (IsMine(txout)) | |
664 | return true; | |
665 | return false; | |
e8ef3da7 | 666 | } |
3447cf87 CF |
667 | /** should probably be renamed to IsRelevantToMe */ |
668 | bool IsFromMe(const CTransaction& tx) const | |
e8ef3da7 | 669 | { |
3447cf87 | 670 | return (GetDebit(tx, ISMINE_ALL) > 0); |
e8ef3da7 | 671 | } |
3447cf87 | 672 | CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const |
e8ef3da7 | 673 | { |
3447cf87 CF |
674 | CAmount nDebit = 0; |
675 | BOOST_FOREACH(const CTxIn& txin, tx.vin) | |
676 | { | |
677 | nDebit += GetDebit(txin, filter); | |
678 | if (!MoneyRange(nDebit)) | |
679 | throw std::runtime_error("CWallet::GetDebit(): value out of range"); | |
680 | } | |
681 | return nDebit; | |
e8ef3da7 | 682 | } |
3447cf87 | 683 | CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const |
e8ef3da7 | 684 | { |
3447cf87 CF |
685 | CAmount nCredit = 0; |
686 | BOOST_FOREACH(const CTxOut& txout, tx.vout) | |
687 | { | |
688 | nCredit += GetCredit(txout, filter); | |
689 | if (!MoneyRange(nCredit)) | |
690 | throw std::runtime_error("CWallet::GetCredit(): value out of range"); | |
691 | } | |
692 | return nCredit; | |
e8ef3da7 | 693 | } |
3447cf87 CF |
694 | CAmount GetChange(const CTransaction& tx) const |
695 | { | |
696 | CAmount nChange = 0; | |
697 | BOOST_FOREACH(const CTxOut& txout, tx.vout) | |
e8ef3da7 | 698 | { |
3447cf87 CF |
699 | nChange += GetChange(txout); |
700 | if (!MoneyRange(nChange)) | |
701 | throw std::runtime_error("CWallet::GetChange(): value out of range"); | |
e8ef3da7 | 702 | } |
3447cf87 CF |
703 | return nChange; |
704 | } | |
705 | void SetBestChain(const CBlockLocator& loc); | |
e8ef3da7 | 706 | |
3447cf87 CF |
707 | DBErrors LoadWallet(bool& fFirstRunRet); |
708 | DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx); | |
e8ef3da7 | 709 | |
3447cf87 | 710 | bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose); |
9c7722b7 | 711 | |
3447cf87 | 712 | bool DelAddressBook(const CTxDestination& address); |
c3f95ef1 | 713 | |
3447cf87 | 714 | void UpdatedTransaction(const uint256 &hashTx); |
e8ef3da7 | 715 | |
3447cf87 | 716 | void Inventory(const uint256 &hash) |
e8ef3da7 | 717 | { |
3447cf87 CF |
718 | { |
719 | LOCK(cs_wallet); | |
720 | std::map<uint256, int>::iterator mi = mapRequestCount.find(hash); | |
721 | if (mi != mapRequestCount.end()) | |
722 | (*mi).second++; | |
723 | } | |
e8ef3da7 WL |
724 | } |
725 | ||
3447cf87 | 726 | unsigned int GetKeyPoolSize() |
4c6e2295 | 727 | { |
3447cf87 CF |
728 | AssertLockHeld(cs_wallet); // setKeyPool |
729 | return setKeyPool.size(); | |
4c6e2295 PW |
730 | } |
731 | ||
3447cf87 | 732 | bool SetDefaultKey(const CPubKey &vchPubKey); |
e8ef3da7 | 733 | |
3447cf87 CF |
734 | //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower |
735 | bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false); | |
e8ef3da7 | 736 | |
3447cf87 CF |
737 | //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) |
738 | bool SetMaxVersion(int nVersion); | |
e8ef3da7 | 739 | |
3447cf87 CF |
740 | //! get the current wallet format (the oldest client version guaranteed to understand this wallet) |
741 | int GetVersion() { LOCK(cs_wallet); return nWalletVersion; } | |
e8ef3da7 | 742 | |
3447cf87 CF |
743 | //! Get wallet transactions that conflict with given transaction (spend same outputs) |
744 | std::set<uint256> GetConflicts(const uint256& txid) const; | |
e8ef3da7 | 745 | |
3447cf87 CF |
746 | /** |
747 | * Address book entry changed. | |
748 | * @note called with lock cs_wallet held. | |
749 | */ | |
750 | boost::signals2::signal<void (CWallet *wallet, const CTxDestination | |
751 | &address, const std::string &label, bool isMine, | |
752 | const std::string &purpose, | |
753 | ChangeType status)> NotifyAddressBookChanged; | |
e8ef3da7 | 754 | |
3447cf87 CF |
755 | /** |
756 | * Wallet transaction added, removed or updated. | |
757 | * @note called with lock cs_wallet held. | |
758 | */ | |
759 | boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, | |
760 | ChangeType status)> NotifyTransactionChanged; | |
e8ef3da7 | 761 | |
3447cf87 CF |
762 | /** Show progress e.g. for rescan */ |
763 | boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress; | |
731b89b8 | 764 | |
3447cf87 CF |
765 | /** Watch-only address added */ |
766 | boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged; | |
e8ef3da7 WL |
767 | }; |
768 | ||
3447cf87 CF |
769 | /** A key allocated from the key pool. */ |
770 | class CReserveKey | |
9b0369c7 | 771 | { |
3447cf87 CF |
772 | protected: |
773 | CWallet* pwallet; | |
774 | int64_t nIndex; | |
775 | CPubKey vchPubKey; | |
9b0369c7 | 776 | public: |
3447cf87 | 777 | CReserveKey(CWallet* pwalletIn) |
9b0369c7 | 778 | { |
3447cf87 CF |
779 | nIndex = -1; |
780 | pwallet = pwalletIn; | |
9b0369c7 CM |
781 | } |
782 | ||
3447cf87 CF |
783 | ~CReserveKey() |
784 | { | |
785 | ReturnKey(); | |
3d796f89 | 786 | } |
e8ef3da7 | 787 | |
3447cf87 CF |
788 | void ReturnKey(); |
789 | bool GetReservedKey(CPubKey &pubkey); | |
790 | void KeepKey(); | |
791 | }; | |
e8ef3da7 WL |
792 | |
793 | ||
5b40d886 MF |
794 | /** |
795 | * Account information. | |
6b8de05d PW |
796 | * Stored in wallet with key "acc"+string account name. |
797 | */ | |
e8ef3da7 WL |
798 | class CAccount |
799 | { | |
800 | public: | |
fd61d6f5 | 801 | CPubKey vchPubKey; |
e8ef3da7 WL |
802 | |
803 | CAccount() | |
804 | { | |
805 | SetNull(); | |
806 | } | |
807 | ||
808 | void SetNull() | |
809 | { | |
fd61d6f5 | 810 | vchPubKey = CPubKey(); |
e8ef3da7 WL |
811 | } |
812 | ||
3f6540ad | 813 | ADD_SERIALIZE_METHODS; |
3d796f89 | 814 | |
84881f8c | 815 | template <typename Stream, typename Operation> |
31e9a838 | 816 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
e8ef3da7 WL |
817 | if (!(nType & SER_GETHASH)) |
818 | READWRITE(nVersion); | |
819 | READWRITE(vchPubKey); | |
3d796f89 | 820 | } |
e8ef3da7 WL |
821 | }; |
822 | ||
823 | ||
824 | ||
5b40d886 MF |
825 | /** |
826 | * Internal transfers. | |
6b8de05d PW |
827 | * Database key is acentry<account><counter>. |
828 | */ | |
e8ef3da7 WL |
829 | class CAccountingEntry |
830 | { | |
831 | public: | |
832 | std::string strAccount; | |
a372168e | 833 | CAmount nCreditDebit; |
51ed9ec9 | 834 | int64_t nTime; |
e8ef3da7 WL |
835 | std::string strOtherAccount; |
836 | std::string strComment; | |
9c7722b7 | 837 | mapValue_t mapValue; |
5b40d886 | 838 | int64_t nOrderPos; //! position in ordered transaction list |
51ed9ec9 | 839 | uint64_t nEntryNo; |
e8ef3da7 WL |
840 | |
841 | CAccountingEntry() | |
842 | { | |
843 | SetNull(); | |
844 | } | |
845 | ||
846 | void SetNull() | |
847 | { | |
848 | nCreditDebit = 0; | |
849 | nTime = 0; | |
850 | strAccount.clear(); | |
851 | strOtherAccount.clear(); | |
852 | strComment.clear(); | |
9c7722b7 | 853 | nOrderPos = -1; |
8bdd2877 | 854 | nEntryNo = 0; |
e8ef3da7 WL |
855 | } |
856 | ||
3f6540ad | 857 | ADD_SERIALIZE_METHODS; |
3d796f89 | 858 | |
84881f8c | 859 | template <typename Stream, typename Operation> |
31e9a838 | 860 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
e8ef3da7 WL |
861 | if (!(nType & SER_GETHASH)) |
862 | READWRITE(nVersion); | |
5b40d886 | 863 | //! Note: strAccount is serialized as part of the key, not here. |
e8ef3da7 WL |
864 | READWRITE(nCreditDebit); |
865 | READWRITE(nTime); | |
216e9a44 | 866 | READWRITE(LIMITED_STRING(strOtherAccount, 65536)); |
9c7722b7 | 867 | |
47eb7659 | 868 | if (!ser_action.ForRead()) |
9c7722b7 | 869 | { |
47eb7659 | 870 | WriteOrderPos(nOrderPos, mapValue); |
9c7722b7 LD |
871 | |
872 | if (!(mapValue.empty() && _ssExtra.empty())) | |
873 | { | |
874 | CDataStream ss(nType, nVersion); | |
875 | ss.insert(ss.begin(), '\0'); | |
876 | ss << mapValue; | |
877 | ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); | |
47eb7659 | 878 | strComment.append(ss.str()); |
9c7722b7 LD |
879 | } |
880 | } | |
881 | ||
216e9a44 | 882 | READWRITE(LIMITED_STRING(strComment, 65536)); |
9c7722b7 LD |
883 | |
884 | size_t nSepPos = strComment.find("\0", 0, 1); | |
47eb7659 | 885 | if (ser_action.ForRead()) |
9c7722b7 | 886 | { |
47eb7659 | 887 | mapValue.clear(); |
9c7722b7 LD |
888 | if (std::string::npos != nSepPos) |
889 | { | |
890 | CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); | |
47eb7659 PW |
891 | ss >> mapValue; |
892 | _ssExtra = std::vector<char>(ss.begin(), ss.end()); | |
9c7722b7 | 893 | } |
47eb7659 | 894 | ReadOrderPos(nOrderPos, mapValue); |
9c7722b7 LD |
895 | } |
896 | if (std::string::npos != nSepPos) | |
47eb7659 | 897 | strComment.erase(nSepPos); |
9c7722b7 | 898 | |
31e9a838 | 899 | mapValue.erase("n"); |
3d796f89 | 900 | } |
9c7722b7 LD |
901 | |
902 | private: | |
903 | std::vector<char> _ssExtra; | |
e8ef3da7 WL |
904 | }; |
905 | ||
093303a8 | 906 | #endif // BITCOIN_WALLET_H |