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