Remove headers.h
[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 license.txt or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_WALLET_H
6 #define BITCOIN_WALLET_H
7
8 #include "main.h"
9 #include "bignum.h"
10 #include "key.h"
11 #include "keystore.h"
12 #include "script.h"
13
14 class CWalletTx;
15 class CReserveKey;
16 class CWalletDB;
17
18 /** (client) version numbers for particular wallet features */
19 enum WalletFeature
20 {
21     FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output)
22
23     FEATURE_WALLETCRYPT = 40000, // wallet encryption
24     FEATURE_COMPRPUBKEY = 60000, // compressed public keys
25
26     FEATURE_LATEST = 60000
27 };
28
29
30 /** A key pool entry */
31 class CKeyPool
32 {
33 public:
34     int64 nTime;
35     std::vector<unsigned char> vchPubKey;
36
37     CKeyPool()
38     {
39         nTime = GetTime();
40     }
41
42     CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
43     {
44         nTime = GetTime();
45         vchPubKey = vchPubKeyIn;
46     }
47
48     IMPLEMENT_SERIALIZE
49     (
50         if (!(nType & SER_GETHASH))
51             READWRITE(nVersion);
52         READWRITE(nTime);
53         READWRITE(vchPubKey);
54     )
55 };
56
57 /** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
58  * and provides the ability to create new transactions.
59  */
60 class CWallet : public CCryptoKeyStore
61 {
62 private:
63     bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
64     bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
65
66     CWalletDB *pwalletdbEncryption;
67
68     // the current wallet version: clients below this version are not able to load the wallet
69     int nWalletVersion;
70
71     // the maxmimum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
72     int nWalletMaxVersion;
73
74 public:
75     mutable CCriticalSection cs_wallet;
76
77     bool fFileBacked;
78     std::string strWalletFile;
79
80     std::set<int64> setKeyPool;
81
82
83     typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
84     MasterKeyMap mapMasterKeys;
85     unsigned int nMasterKeyMaxID;
86
87     CWallet()
88     {
89         nWalletVersion = FEATURE_BASE;
90         nWalletMaxVersion = FEATURE_BASE;
91         fFileBacked = false;
92         nMasterKeyMaxID = 0;
93         pwalletdbEncryption = NULL;
94     }
95     CWallet(std::string strWalletFileIn)
96     {
97         nWalletVersion = FEATURE_BASE;
98         nWalletMaxVersion = FEATURE_BASE;
99         strWalletFile = strWalletFileIn;
100         fFileBacked = true;
101         nMasterKeyMaxID = 0;
102         pwalletdbEncryption = NULL;
103     }
104
105     std::map<uint256, CWalletTx> mapWallet;
106     std::vector<uint256> vWalletUpdated;
107
108     std::map<uint256, int> mapRequestCount;
109
110     std::map<CBitcoinAddress, std::string> mapAddressBook;
111
112     std::vector<unsigned char> vchDefaultKey;
113
114     // check whether we are allowed to upgrade (or already support) to the named feature
115     bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
116
117     // keystore implementation
118     // Generate a new key
119     std::vector<unsigned char> GenerateNewKey();
120     // Adds a key to the store, and saves it to disk.
121     bool AddKey(const CKey& key);
122     // Adds a key to the store, without saving it to disk (used by LoadWallet)
123     bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); }
124
125     bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
126
127     // Adds an encrypted key to the store, and saves it to disk.
128     bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
129     // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
130     bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
131     bool AddCScript(const CScript& redeemScript);
132     bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
133
134     bool Unlock(const SecureString& strWalletPassphrase);
135     bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
136     bool EncryptWallet(const SecureString& strWalletPassphrase);
137
138     void MarkDirty();
139     bool AddToWallet(const CWalletTx& wtxIn);
140     bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false);
141     bool EraseFromWallet(uint256 hash);
142     void WalletUpdateSpent(const CTransaction& prevout);
143     int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
144     int ScanForWalletTransaction(const uint256& hashTx);
145     void ReacceptWalletTransactions();
146     void ResendWalletTransactions();
147     int64 GetBalance() const;
148     int64 GetUnconfirmedBalance() const;
149     bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
150     bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
151     bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
152     std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
153     std::string SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
154
155     bool NewKeyPool();
156     bool TopUpKeyPool();
157     int64 AddReserveKey(const CKeyPool& keypool);
158     void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
159     void KeepKey(int64 nIndex);
160     void ReturnKey(int64 nIndex);
161     bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
162     int64 GetOldestKeyPoolTime();
163     void GetAllReserveAddresses(std::set<CBitcoinAddress>& setAddress);
164
165     bool IsMine(const CTxIn& txin) const;
166     int64 GetDebit(const CTxIn& txin) const;
167     bool IsMine(const CTxOut& txout) const
168     {
169         return ::IsMine(*this, txout.scriptPubKey);
170     }
171     int64 GetCredit(const CTxOut& txout) const
172     {
173         if (!MoneyRange(txout.nValue))
174             throw std::runtime_error("CWallet::GetCredit() : value out of range");
175         return (IsMine(txout) ? txout.nValue : 0);
176     }
177     bool IsChange(const CTxOut& txout) const;
178     int64 GetChange(const CTxOut& txout) const
179     {
180         if (!MoneyRange(txout.nValue))
181             throw std::runtime_error("CWallet::GetChange() : value out of range");
182         return (IsChange(txout) ? txout.nValue : 0);
183     }
184     bool IsMine(const CTransaction& tx) const
185     {
186         BOOST_FOREACH(const CTxOut& txout, tx.vout)
187             if (IsMine(txout))
188                 return true;
189         return false;
190     }
191     bool IsFromMe(const CTransaction& tx) const
192     {
193         return (GetDebit(tx) > 0);
194     }
195     int64 GetDebit(const CTransaction& tx) const
196     {
197         int64 nDebit = 0;
198         BOOST_FOREACH(const CTxIn& txin, tx.vin)
199         {
200             nDebit += GetDebit(txin);
201             if (!MoneyRange(nDebit))
202                 throw std::runtime_error("CWallet::GetDebit() : value out of range");
203         }
204         return nDebit;
205     }
206     int64 GetCredit(const CTransaction& tx) const
207     {
208         int64 nCredit = 0;
209         BOOST_FOREACH(const CTxOut& txout, tx.vout)
210         {
211             nCredit += GetCredit(txout);
212             if (!MoneyRange(nCredit))
213                 throw std::runtime_error("CWallet::GetCredit() : value out of range");
214         }
215         return nCredit;
216     }
217     int64 GetChange(const CTransaction& tx) const
218     {
219         int64 nChange = 0;
220         BOOST_FOREACH(const CTxOut& txout, tx.vout)
221         {
222             nChange += GetChange(txout);
223             if (!MoneyRange(nChange))
224                 throw std::runtime_error("CWallet::GetChange() : value out of range");
225         }
226         return nChange;
227     }
228     void SetBestChain(const CBlockLocator& loc);
229
230     int LoadWallet(bool& fFirstRunRet);
231 //    bool BackupWallet(const std::string& strDest);
232
233     bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName);
234
235     bool DelAddressBookName(const CBitcoinAddress& address);
236
237     void UpdatedTransaction(const uint256 &hashTx)
238     {
239         {
240             LOCK(cs_wallet);
241             vWalletUpdated.push_back(hashTx);
242         }
243     }
244
245     void PrintWallet(const CBlock& block);
246
247     void Inventory(const uint256 &hash)
248     {
249         {
250             LOCK(cs_wallet);
251             std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
252             if (mi != mapRequestCount.end())
253                 (*mi).second++;
254         }
255     }
256
257     int GetKeyPoolSize()
258     {
259         return setKeyPool.size();
260     }
261
262     bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
263
264     bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey);
265
266     // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
267     bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
268
269     // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
270     bool SetMaxVersion(int nVersion);
271
272     // get the current wallet format (the oldest client version guaranteed to understand this wallet)
273     int GetVersion() { return nWalletVersion; }
274 };
275
276 /** A key allocated from the key pool. */
277 class CReserveKey
278 {
279 protected:
280     CWallet* pwallet;
281     int64 nIndex;
282     std::vector<unsigned char> vchPubKey;
283 public:
284     CReserveKey(CWallet* pwalletIn)
285     {
286         nIndex = -1;
287         pwallet = pwalletIn;
288     }
289
290     ~CReserveKey()
291     {
292         if (!fShutdown)
293             ReturnKey();
294     }
295
296     void ReturnKey();
297     std::vector<unsigned char> GetReservedKey();
298     void KeepKey();
299 };
300
301
302 /** A transaction with a bunch of additional info that only the owner cares about. 
303  * It includes any unrecorded transactions needed to link it back to the block chain.
304  */
305 class CWalletTx : public CMerkleTx
306 {
307 private:
308     const CWallet* pwallet;
309
310 public:
311     std::vector<CMerkleTx> vtxPrev;
312     std::map<std::string, std::string> mapValue;
313     std::vector<std::pair<std::string, std::string> > vOrderForm;
314     unsigned int fTimeReceivedIsTxTime;
315     unsigned int nTimeReceived;  // time received by this node
316     char fFromMe;
317     std::string strFromAccount;
318     std::vector<char> vfSpent; // which outputs are already spent
319
320     // memory only
321     mutable char fDebitCached;
322     mutable char fCreditCached;
323     mutable char fAvailableCreditCached;
324     mutable char fChangeCached;
325     mutable int64 nDebitCached;
326     mutable int64 nCreditCached;
327     mutable int64 nAvailableCreditCached;
328     mutable int64 nChangeCached;
329
330     // memory only UI hints
331     mutable unsigned int nTimeDisplayed;
332     mutable int nLinesDisplayed;
333     mutable char fConfirmedDisplayed;
334
335     CWalletTx()
336     {
337         Init(NULL);
338     }
339
340     CWalletTx(const CWallet* pwalletIn)
341     {
342         Init(pwalletIn);
343     }
344
345     CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
346     {
347         Init(pwalletIn);
348     }
349
350     CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
351     {
352         Init(pwalletIn);
353     }
354
355     void Init(const CWallet* pwalletIn)
356     {
357         pwallet = pwalletIn;
358         vtxPrev.clear();
359         mapValue.clear();
360         vOrderForm.clear();
361         fTimeReceivedIsTxTime = false;
362         nTimeReceived = 0;
363         fFromMe = false;
364         strFromAccount.clear();
365         vfSpent.clear();
366         fDebitCached = false;
367         fCreditCached = false;
368         fAvailableCreditCached = false;
369         fChangeCached = false;
370         nDebitCached = 0;
371         nCreditCached = 0;
372         nAvailableCreditCached = 0;
373         nChangeCached = 0;
374         nTimeDisplayed = 0;
375         nLinesDisplayed = 0;
376         fConfirmedDisplayed = false;
377     }
378
379     IMPLEMENT_SERIALIZE
380     (
381         CWalletTx* pthis = const_cast<CWalletTx*>(this);
382         if (fRead)
383             pthis->Init(NULL);
384         char fSpent = false;
385
386         if (!fRead)
387         {
388             pthis->mapValue["fromaccount"] = pthis->strFromAccount;
389
390             std::string str;
391             BOOST_FOREACH(char f, vfSpent)
392             {
393                 str += (f ? '1' : '0');
394                 if (f)
395                     fSpent = true;
396             }
397             pthis->mapValue["spent"] = str;
398         }
399
400         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
401         READWRITE(vtxPrev);
402         READWRITE(mapValue);
403         READWRITE(vOrderForm);
404         READWRITE(fTimeReceivedIsTxTime);
405         READWRITE(nTimeReceived);
406         READWRITE(fFromMe);
407         READWRITE(fSpent);
408
409         if (fRead)
410         {
411             pthis->strFromAccount = pthis->mapValue["fromaccount"];
412
413             if (mapValue.count("spent"))
414                 BOOST_FOREACH(char c, pthis->mapValue["spent"])
415                     pthis->vfSpent.push_back(c != '0');
416             else
417                 pthis->vfSpent.assign(vout.size(), fSpent);
418         }
419
420         pthis->mapValue.erase("fromaccount");
421         pthis->mapValue.erase("version");
422         pthis->mapValue.erase("spent");
423     )
424
425     // marks certain txout's as spent
426     // returns true if any update took place
427     bool UpdateSpent(const std::vector<char>& vfNewSpent)
428     {
429         bool fReturn = false;
430         for (unsigned int i = 0; i < vfNewSpent.size(); i++)
431         {
432             if (i == vfSpent.size())
433                 break;
434
435             if (vfNewSpent[i] && !vfSpent[i])
436             {
437                 vfSpent[i] = true;
438                 fReturn = true;
439                 fAvailableCreditCached = false;
440             }
441         }
442         return fReturn;
443     }
444
445     // make sure balances are recalculated
446     void MarkDirty()
447     {
448         fCreditCached = false;
449         fAvailableCreditCached = false;
450         fDebitCached = false;
451         fChangeCached = false;
452     }
453
454     void BindWallet(CWallet *pwalletIn)
455     {
456         pwallet = pwalletIn;
457         MarkDirty();
458     }
459
460     void MarkSpent(unsigned int nOut)
461     {
462         if (nOut >= vout.size())
463             throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
464         vfSpent.resize(vout.size());
465         if (!vfSpent[nOut])
466         {
467             vfSpent[nOut] = true;
468             fAvailableCreditCached = false;
469         }
470     }
471
472     bool IsSpent(unsigned int nOut) const
473     {
474         if (nOut >= vout.size())
475             throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
476         if (nOut >= vfSpent.size())
477             return false;
478         return (!!vfSpent[nOut]);
479     }
480
481     int64 GetDebit() const
482     {
483         if (vin.empty())
484             return 0;
485         if (fDebitCached)
486             return nDebitCached;
487         nDebitCached = pwallet->GetDebit(*this);
488         fDebitCached = true;
489         return nDebitCached;
490     }
491
492     int64 GetCredit(bool fUseCache=true) const
493     {
494         // Must wait until coinbase is safely deep enough in the chain before valuing it
495         if (IsCoinBase() && GetBlocksToMaturity() > 0)
496             return 0;
497
498         // GetBalance can assume transactions in mapWallet won't change
499         if (fUseCache && fCreditCached)
500             return nCreditCached;
501         nCreditCached = pwallet->GetCredit(*this);
502         fCreditCached = true;
503         return nCreditCached;
504     }
505
506     int64 GetAvailableCredit(bool fUseCache=true) const
507     {
508         // Must wait until coinbase is safely deep enough in the chain before valuing it
509         if (IsCoinBase() && GetBlocksToMaturity() > 0)
510             return 0;
511
512         if (fUseCache && fAvailableCreditCached)
513             return nAvailableCreditCached;
514
515         int64 nCredit = 0;
516         for (unsigned int i = 0; i < vout.size(); i++)
517         {
518             if (!IsSpent(i))
519             {
520                 const CTxOut &txout = vout[i];
521                 nCredit += pwallet->GetCredit(txout);
522                 if (!MoneyRange(nCredit))
523                     throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
524             }
525         }
526
527         nAvailableCreditCached = nCredit;
528         fAvailableCreditCached = true;
529         return nCredit;
530     }
531
532
533     int64 GetChange() const
534     {
535         if (fChangeCached)
536             return nChangeCached;
537         nChangeCached = pwallet->GetChange(*this);
538         fChangeCached = true;
539         return nChangeCached;
540     }
541
542     void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CBitcoinAddress, int64> >& listReceived,
543                     std::list<std::pair<CBitcoinAddress, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
544
545     void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, 
546                            int64& nSent, int64& nFee) const;
547
548     bool IsFromMe() const
549     {
550         return (GetDebit() > 0);
551     }
552
553     bool IsConfirmed() const
554     {
555         // Quick answer in most cases
556         if (!IsFinal())
557             return false;
558         if (GetDepthInMainChain() >= 1)
559             return true;
560         if (!IsFromMe()) // using wtx's cached debit
561             return false;
562
563         // If no confirmations but it's from us, we can still
564         // consider it confirmed if all dependencies are confirmed
565         std::map<uint256, const CMerkleTx*> mapPrev;
566         std::vector<const CMerkleTx*> vWorkQueue;
567         vWorkQueue.reserve(vtxPrev.size()+1);
568         vWorkQueue.push_back(this);
569         for (unsigned int i = 0; i < vWorkQueue.size(); i++)
570         {
571             const CMerkleTx* ptx = vWorkQueue[i];
572
573             if (!ptx->IsFinal())
574                 return false;
575             if (ptx->GetDepthInMainChain() >= 1)
576                 continue;
577             if (!pwallet->IsFromMe(*ptx))
578                 return false;
579
580             if (mapPrev.empty())
581             {
582                 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
583                     mapPrev[tx.GetHash()] = &tx;
584             }
585
586             BOOST_FOREACH(const CTxIn& txin, ptx->vin)
587             {
588                 if (!mapPrev.count(txin.prevout.hash))
589                     return false;
590                 vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
591             }
592         }
593         return true;
594     }
595
596     bool WriteToDisk();
597
598     int64 GetTxTime() const;
599     int GetRequestCount() const;
600
601     void AddSupportingTransactions(CTxDB& txdb);
602
603     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
604     bool AcceptWalletTransaction();
605
606     void RelayWalletTransaction(CTxDB& txdb);
607     void RelayWalletTransaction();
608 };
609
610
611 /** Private key that includes an expiration date in case it never gets used. */
612 class CWalletKey
613 {
614 public:
615     CPrivKey vchPrivKey;
616     int64 nTimeCreated;
617     int64 nTimeExpires;
618     std::string strComment;
619     //// todo: add something to note what created it (user, getnewaddress, change)
620     ////   maybe should have a map<string, string> property map
621
622     CWalletKey(int64 nExpires=0)
623     {
624         nTimeCreated = (nExpires ? GetTime() : 0);
625         nTimeExpires = nExpires;
626     }
627
628     IMPLEMENT_SERIALIZE
629     (
630         if (!(nType & SER_GETHASH))
631             READWRITE(nVersion);
632         READWRITE(vchPrivKey);
633         READWRITE(nTimeCreated);
634         READWRITE(nTimeExpires);
635         READWRITE(strComment);
636     )
637 };
638
639
640
641
642
643
644 /** Account information.
645  * Stored in wallet with key "acc"+string account name.
646  */
647 class CAccount
648 {
649 public:
650     std::vector<unsigned char> vchPubKey;
651
652     CAccount()
653     {
654         SetNull();
655     }
656
657     void SetNull()
658     {
659         vchPubKey.clear();
660     }
661
662     IMPLEMENT_SERIALIZE
663     (
664         if (!(nType & SER_GETHASH))
665             READWRITE(nVersion);
666         READWRITE(vchPubKey);
667     )
668 };
669
670
671
672 /** Internal transfers.
673  * Database key is acentry<account><counter>.
674  */
675 class CAccountingEntry
676 {
677 public:
678     std::string strAccount;
679     int64 nCreditDebit;
680     int64 nTime;
681     std::string strOtherAccount;
682     std::string strComment;
683
684     CAccountingEntry()
685     {
686         SetNull();
687     }
688
689     void SetNull()
690     {
691         nCreditDebit = 0;
692         nTime = 0;
693         strAccount.clear();
694         strOtherAccount.clear();
695         strComment.clear();
696     }
697
698     IMPLEMENT_SERIALIZE
699     (
700         if (!(nType & SER_GETHASH))
701             READWRITE(nVersion);
702         // Note: strAccount is serialized as part of the key, not here.
703         READWRITE(nCreditDebit);
704         READWRITE(nTime);
705         READWRITE(strOtherAccount);
706         READWRITE(strComment);
707     )
708 };
709
710 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
711
712 #endif