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