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