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