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