Add address to listtransactions output
[novacoin.git] / main.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5 class COutPoint;
6 class CInPoint;
7 class CDiskTxPos;
8 class CCoinBase;
9 class CTxIn;
10 class CTxOut;
11 class CTransaction;
12 class CBlock;
13 class CBlockIndex;
14 class CWalletTx;
15 class CKeyItem;
16
17 static const unsigned int MAX_BLOCK_SIZE = 1000000;
18 static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
19 static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
20 static const int64 COIN = 100000000;
21 static const int64 CENT = 1000000;
22 static const int64 MAX_MONEY = 21000000 * COIN;
23 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
24 static const int COINBASE_MATURITY = 100;
25
26
27
28
29
30
31 extern CCriticalSection cs_main;
32 extern map<uint256, CBlockIndex*> mapBlockIndex;
33 extern uint256 hashGenesisBlock;
34 extern CBigNum bnProofOfWorkLimit;
35 extern CBlockIndex* pindexGenesisBlock;
36 extern int nBestHeight;
37 extern CBigNum bnBestChainWork;
38 extern CBigNum bnBestInvalidWork;
39 extern uint256 hashBestChain;
40 extern CBlockIndex* pindexBest;
41 extern unsigned int nTransactionsUpdated;
42 extern map<uint256, int> mapRequestCount;
43 extern CCriticalSection cs_mapRequestCount;
44 extern map<string, string> mapAddressBook;
45 extern CCriticalSection cs_mapAddressBook;
46 extern vector<unsigned char> vchDefaultKey;
47 extern double dHashesPerSec;
48 extern int64 nHPSTimerStart;
49
50 // Settings
51 extern int fGenerateBitcoins;
52 extern int64 nTransactionFee;
53 extern CAddress addrIncoming;
54 extern int fLimitProcessors;
55 extern int nLimitProcessors;
56 extern int fMinimizeToTray;
57 extern int fMinimizeOnClose;
58
59
60
61
62
63
64
65 bool CheckDiskSpace(uint64 nAdditionalBytes=0);
66 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
67 FILE* AppendBlockFile(unsigned int& nFileRet);
68 bool AddKey(const CKey& key);
69 vector<unsigned char> GenerateNewKey();
70 bool AddToWallet(const CWalletTx& wtxIn);
71 void WalletUpdateSpent(const COutPoint& prevout);
72 void ReacceptWalletTransactions();
73 bool LoadBlockIndex(bool fAllowNew=true);
74 void PrintBlockTree();
75 bool ProcessMessages(CNode* pfrom);
76 bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
77 bool SendMessages(CNode* pto, bool fSendTrickle);
78 int64 GetBalance();
79 bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
80 bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
81 bool BroadcastTransaction(CWalletTx& wtxNew);
82 string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
83 string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
84 void GenerateBitcoins(bool fGenerate);
85 void ThreadBitcoinMiner(void* parg);
86 CBlock* CreateNewBlock(CReserveKey& reservekey);
87 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
88 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
89 bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
90 void BitcoinMiner();
91 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
92 bool IsInitialBlockDownload();
93 string GetWarnings(string strFor);
94
95
96
97
98
99
100
101
102
103
104
105
106 class CDiskTxPos
107 {
108 public:
109     unsigned int nFile;
110     unsigned int nBlockPos;
111     unsigned int nTxPos;
112
113     CDiskTxPos()
114     {
115         SetNull();
116     }
117
118     CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
119     {
120         nFile = nFileIn;
121         nBlockPos = nBlockPosIn;
122         nTxPos = nTxPosIn;
123     }
124
125     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
126     void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
127     bool IsNull() const { return (nFile == -1); }
128
129     friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
130     {
131         return (a.nFile     == b.nFile &&
132                 a.nBlockPos == b.nBlockPos &&
133                 a.nTxPos    == b.nTxPos);
134     }
135
136     friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
137     {
138         return !(a == b);
139     }
140
141     string ToString() const
142     {
143         if (IsNull())
144             return strprintf("null");
145         else
146             return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
147     }
148
149     void print() const
150     {
151         printf("%s", ToString().c_str());
152     }
153 };
154
155
156
157
158 class CInPoint
159 {
160 public:
161     CTransaction* ptx;
162     unsigned int n;
163
164     CInPoint() { SetNull(); }
165     CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
166     void SetNull() { ptx = NULL; n = -1; }
167     bool IsNull() const { return (ptx == NULL && n == -1); }
168 };
169
170
171
172
173 class COutPoint
174 {
175 public:
176     uint256 hash;
177     unsigned int n;
178
179     COutPoint() { SetNull(); }
180     COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
181     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
182     void SetNull() { hash = 0; n = -1; }
183     bool IsNull() const { return (hash == 0 && n == -1); }
184
185     friend bool operator<(const COutPoint& a, const COutPoint& b)
186     {
187         return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
188     }
189
190     friend bool operator==(const COutPoint& a, const COutPoint& b)
191     {
192         return (a.hash == b.hash && a.n == b.n);
193     }
194
195     friend bool operator!=(const COutPoint& a, const COutPoint& b)
196     {
197         return !(a == b);
198     }
199
200     string ToString() const
201     {
202         return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
203     }
204
205     void print() const
206     {
207         printf("%s\n", ToString().c_str());
208     }
209 };
210
211
212
213
214 //
215 // An input of a transaction.  It contains the location of the previous
216 // transaction's output that it claims and a signature that matches the
217 // output's public key.
218 //
219 class CTxIn
220 {
221 public:
222     COutPoint prevout;
223     CScript scriptSig;
224     unsigned int nSequence;
225
226     CTxIn()
227     {
228         nSequence = UINT_MAX;
229     }
230
231     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
232     {
233         prevout = prevoutIn;
234         scriptSig = scriptSigIn;
235         nSequence = nSequenceIn;
236     }
237
238     CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
239     {
240         prevout = COutPoint(hashPrevTx, nOut);
241         scriptSig = scriptSigIn;
242         nSequence = nSequenceIn;
243     }
244
245     IMPLEMENT_SERIALIZE
246     (
247         READWRITE(prevout);
248         READWRITE(scriptSig);
249         READWRITE(nSequence);
250     )
251
252     bool IsFinal() const
253     {
254         return (nSequence == UINT_MAX);
255     }
256
257     friend bool operator==(const CTxIn& a, const CTxIn& b)
258     {
259         return (a.prevout   == b.prevout &&
260                 a.scriptSig == b.scriptSig &&
261                 a.nSequence == b.nSequence);
262     }
263
264     friend bool operator!=(const CTxIn& a, const CTxIn& b)
265     {
266         return !(a == b);
267     }
268
269     string ToString() const
270     {
271         string str;
272         str += strprintf("CTxIn(");
273         str += prevout.ToString();
274         if (prevout.IsNull())
275             str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
276         else
277             str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
278         if (nSequence != UINT_MAX)
279             str += strprintf(", nSequence=%u", nSequence);
280         str += ")";
281         return str;
282     }
283
284     void print() const
285     {
286         printf("%s\n", ToString().c_str());
287     }
288
289     bool IsMine() const;
290     int64 GetDebit() const;
291 };
292
293
294
295
296 //
297 // An output of a transaction.  It contains the public key that the next input
298 // must be able to sign with to claim it.
299 //
300 class CTxOut
301 {
302 public:
303     int64 nValue;
304     CScript scriptPubKey;
305
306     CTxOut()
307     {
308         SetNull();
309     }
310
311     CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
312     {
313         nValue = nValueIn;
314         scriptPubKey = scriptPubKeyIn;
315     }
316
317     IMPLEMENT_SERIALIZE
318     (
319         READWRITE(nValue);
320         READWRITE(scriptPubKey);
321     )
322
323     void SetNull()
324     {
325         nValue = -1;
326         scriptPubKey.clear();
327     }
328
329     bool IsNull()
330     {
331         return (nValue == -1);
332     }
333
334     uint256 GetHash() const
335     {
336         return SerializeHash(*this);
337     }
338
339     bool IsMine() const
340     {
341         return ::IsMine(scriptPubKey);
342     }
343
344     int64 GetCredit() const
345     {
346         if (!MoneyRange(nValue))
347             throw runtime_error("CTxOut::GetCredit() : value out of range");
348         return (IsMine() ? nValue : 0);
349     }
350
351     bool IsChange() const
352     {
353         // On a debit transaction, a txout that's mine but isn't in the address book is change
354         vector<unsigned char> vchPubKey;
355         if (ExtractPubKey(scriptPubKey, true, vchPubKey))
356             CRITICAL_BLOCK(cs_mapAddressBook)
357                 if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
358                     return true;
359         return false;
360     }
361
362     int64 GetChange() const
363     {
364         if (!MoneyRange(nValue))
365             throw runtime_error("CTxOut::GetChange() : value out of range");
366         return (IsChange() ? nValue : 0);
367     }
368
369     friend bool operator==(const CTxOut& a, const CTxOut& b)
370     {
371         return (a.nValue       == b.nValue &&
372                 a.scriptPubKey == b.scriptPubKey);
373     }
374
375     friend bool operator!=(const CTxOut& a, const CTxOut& b)
376     {
377         return !(a == b);
378     }
379
380     string ToString() const
381     {
382         if (scriptPubKey.size() < 6)
383             return "CTxOut(error)";
384         return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
385     }
386
387     void print() const
388     {
389         printf("%s\n", ToString().c_str());
390     }
391 };
392
393
394
395
396 //
397 // The basic transaction that is broadcasted on the network and contained in
398 // blocks.  A transaction can contain multiple inputs and outputs.
399 //
400 class CTransaction
401 {
402 public:
403     int nVersion;
404     vector<CTxIn> vin;
405     vector<CTxOut> vout;
406     unsigned int nLockTime;
407
408
409     CTransaction()
410     {
411         SetNull();
412     }
413
414     IMPLEMENT_SERIALIZE
415     (
416         READWRITE(this->nVersion);
417         nVersion = this->nVersion;
418         READWRITE(vin);
419         READWRITE(vout);
420         READWRITE(nLockTime);
421     )
422
423     void SetNull()
424     {
425         nVersion = 1;
426         vin.clear();
427         vout.clear();
428         nLockTime = 0;
429     }
430
431     bool IsNull() const
432     {
433         return (vin.empty() && vout.empty());
434     }
435
436     uint256 GetHash() const
437     {
438         return SerializeHash(*this);
439     }
440
441     bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
442     {
443         // Time based nLockTime implemented in 0.1.6
444         if (nLockTime == 0)
445             return true;
446         if (nBlockHeight == 0)
447             nBlockHeight = nBestHeight;
448         if (nBlockTime == 0)
449             nBlockTime = GetAdjustedTime();
450         if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime))
451             return true;
452         foreach(const CTxIn& txin, vin)
453             if (!txin.IsFinal())
454                 return false;
455         return true;
456     }
457
458     bool IsNewerThan(const CTransaction& old) const
459     {
460         if (vin.size() != old.vin.size())
461             return false;
462         for (int i = 0; i < vin.size(); i++)
463             if (vin[i].prevout != old.vin[i].prevout)
464                 return false;
465
466         bool fNewer = false;
467         unsigned int nLowest = UINT_MAX;
468         for (int i = 0; i < vin.size(); i++)
469         {
470             if (vin[i].nSequence != old.vin[i].nSequence)
471             {
472                 if (vin[i].nSequence <= nLowest)
473                 {
474                     fNewer = false;
475                     nLowest = vin[i].nSequence;
476                 }
477                 if (old.vin[i].nSequence < nLowest)
478                 {
479                     fNewer = true;
480                     nLowest = old.vin[i].nSequence;
481                 }
482             }
483         }
484         return fNewer;
485     }
486
487     bool IsCoinBase() const
488     {
489         return (vin.size() == 1 && vin[0].prevout.IsNull());
490     }
491
492     int GetSigOpCount() const
493     {
494         int n = 0;
495         foreach(const CTxIn& txin, vin)
496             n += txin.scriptSig.GetSigOpCount();
497         foreach(const CTxOut& txout, vout)
498             n += txout.scriptPubKey.GetSigOpCount();
499         return n;
500     }
501
502     bool IsStandard() const
503     {
504         foreach(const CTxIn& txin, vin)
505             if (!txin.scriptSig.IsPushOnly())
506                 return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
507         foreach(const CTxOut& txout, vout)
508             if (!::IsStandard(txout.scriptPubKey))
509                 return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
510         return true;
511     }
512
513     bool IsMine() const
514     {
515         foreach(const CTxOut& txout, vout)
516             if (txout.IsMine())
517                 return true;
518         return false;
519     }
520
521     bool IsFromMe() const
522     {
523         return (GetDebit() > 0);
524     }
525
526     int64 GetDebit() const
527     {
528         int64 nDebit = 0;
529         foreach(const CTxIn& txin, vin)
530         {
531             nDebit += txin.GetDebit();
532             if (!MoneyRange(nDebit))
533                 throw runtime_error("CTransaction::GetDebit() : value out of range");
534         }
535         return nDebit;
536     }
537
538     int64 GetCredit() const
539     {
540         int64 nCredit = 0;
541         foreach(const CTxOut& txout, vout)
542         {
543             nCredit += txout.GetCredit();
544             if (!MoneyRange(nCredit))
545                 throw runtime_error("CTransaction::GetCredit() : value out of range");
546         }
547         return nCredit;
548     }
549
550     int64 GetChange() const
551     {
552         if (IsCoinBase())
553             return 0;
554         int64 nChange = 0;
555         foreach(const CTxOut& txout, vout)
556         {
557             nChange += txout.GetChange();
558             if (!MoneyRange(nChange))
559                 throw runtime_error("CTransaction::GetChange() : value out of range");
560         }
561         return nChange;
562     }
563
564     int64 GetValueOut() const
565     {
566         int64 nValueOut = 0;
567         foreach(const CTxOut& txout, vout)
568         {
569             nValueOut += txout.nValue;
570             if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
571                 throw runtime_error("CTransaction::GetValueOut() : value out of range");
572         }
573         return nValueOut;
574     }
575
576     int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true) const
577     {
578         // Base fee is 1 cent per kilobyte
579         unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
580         unsigned int nNewBlockSize = nBlockSize + nBytes;
581         int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT;
582
583         if (fAllowFree)
584         {
585             if (nBlockSize == 1)
586             {
587                 // Transactions under 10K are free
588                 // (about 4500bc if made of 50bc inputs)
589                 if (nBytes < 10000)
590                     nMinFee = 0;
591             }
592             else
593             {
594                 // Free transaction area
595                 if (nNewBlockSize < 27000)
596                     nMinFee = 0;
597             }
598         }
599
600         // To limit dust spam, require a 0.01 fee if any output is less than 0.01
601         if (nMinFee < CENT)
602             foreach(const CTxOut& txout, vout)
603                 if (txout.nValue < CENT)
604                     nMinFee = CENT;
605
606         // Raise the price as the block approaches full
607         if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
608         {
609             if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
610                 return MAX_MONEY;
611             nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
612         }
613
614         if (!MoneyRange(nMinFee))
615             nMinFee = MAX_MONEY;
616         return nMinFee;
617     }
618
619
620     bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
621     {
622         CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
623         if (!filein)
624             return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
625
626         // Read transaction
627         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
628             return error("CTransaction::ReadFromDisk() : fseek failed");
629         filein >> *this;
630
631         // Return file pointer
632         if (pfileRet)
633         {
634             if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
635                 return error("CTransaction::ReadFromDisk() : second fseek failed");
636             *pfileRet = filein.release();
637         }
638         return true;
639     }
640
641     friend bool operator==(const CTransaction& a, const CTransaction& b)
642     {
643         return (a.nVersion  == b.nVersion &&
644                 a.vin       == b.vin &&
645                 a.vout      == b.vout &&
646                 a.nLockTime == b.nLockTime);
647     }
648
649     friend bool operator!=(const CTransaction& a, const CTransaction& b)
650     {
651         return !(a == b);
652     }
653
654
655     string ToString() const
656     {
657         string str;
658         str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
659             GetHash().ToString().substr(0,10).c_str(),
660             nVersion,
661             vin.size(),
662             vout.size(),
663             nLockTime);
664         for (int i = 0; i < vin.size(); i++)
665             str += "    " + vin[i].ToString() + "\n";
666         for (int i = 0; i < vout.size(); i++)
667             str += "    " + vout[i].ToString() + "\n";
668         return str;
669     }
670
671     void print() const
672     {
673         printf("%s", ToString().c_str());
674     }
675
676
677     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
678     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
679     bool ReadFromDisk(COutPoint prevout);
680     bool DisconnectInputs(CTxDB& txdb);
681     bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
682                        CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
683     bool ClientConnectInputs();
684     bool CheckTransaction() const;
685     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
686     bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
687     {
688         CTxDB txdb("r");
689         return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
690     }
691 protected:
692     bool AddToMemoryPoolUnchecked();
693 public:
694     bool RemoveFromMemoryPool();
695 };
696
697
698
699
700
701 //
702 // A transaction with a merkle branch linking it to the block chain
703 //
704 class CMerkleTx : public CTransaction
705 {
706 public:
707     uint256 hashBlock;
708     vector<uint256> vMerkleBranch;
709     int nIndex;
710
711     // memory only
712     mutable char fMerkleVerified;
713
714
715     CMerkleTx()
716     {
717         Init();
718     }
719
720     CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
721     {
722         Init();
723     }
724
725     void Init()
726     {
727         hashBlock = 0;
728         nIndex = -1;
729         fMerkleVerified = false;
730     }
731
732     IMPLEMENT_SERIALIZE
733     (
734         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
735         nVersion = this->nVersion;
736         READWRITE(hashBlock);
737         READWRITE(vMerkleBranch);
738         READWRITE(nIndex);
739     )
740
741
742     int SetMerkleBranch(const CBlock* pblock=NULL);
743     int GetDepthInMainChain(int& nHeightRet) const;
744     int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
745     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
746     int GetBlocksToMaturity() const;
747     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
748     bool AcceptToMemoryPool() { CTxDB txdb("r"); return AcceptToMemoryPool(txdb); }
749 };
750
751
752
753
754 //
755 // A transaction with a bunch of additional info that only the owner cares
756 // about.  It includes any unrecorded transactions needed to link it back
757 // to the block chain.
758 //
759 class CWalletTx : public CMerkleTx
760 {
761 public:
762     vector<CMerkleTx> vtxPrev;
763     map<string, string> mapValue;
764     vector<pair<string, string> > vOrderForm;
765     unsigned int fTimeReceivedIsTxTime;
766     unsigned int nTimeReceived;  // time received by this node
767     char fFromMe;
768     char fSpent;
769     string strFromAccount;
770
771     // memory only
772     mutable char fDebitCached;
773     mutable char fCreditCached;
774     mutable char fChangeCached;
775     mutable int64 nDebitCached;
776     mutable int64 nCreditCached;
777     mutable int64 nChangeCached;
778
779     // memory only UI hints
780     mutable unsigned int nTimeDisplayed;
781     mutable int nLinesDisplayed;
782     mutable char fConfirmedDisplayed;
783
784
785     CWalletTx()
786     {
787         Init();
788     }
789
790     CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
791     {
792         Init();
793     }
794
795     CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
796     {
797         Init();
798     }
799
800     void Init()
801     {
802         vtxPrev.clear();
803         mapValue.clear();
804         vOrderForm.clear();
805         fTimeReceivedIsTxTime = false;
806         nTimeReceived = 0;
807         fFromMe = false;
808         fSpent = false;
809         strFromAccount.clear();
810         fDebitCached = false;
811         fCreditCached = false;
812         fChangeCached = false;
813         nDebitCached = 0;
814         nCreditCached = 0;
815         nChangeCached = 0;
816         nTimeDisplayed = 0;
817         nLinesDisplayed = 0;
818         fConfirmedDisplayed = false;
819     }
820
821     IMPLEMENT_SERIALIZE
822     (
823         CWalletTx* pthis = const_cast<CWalletTx*>(this);
824         if (fRead)
825             pthis->Init();
826         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
827         READWRITE(vtxPrev);
828
829         pthis->mapValue["fromaccount"] = pthis->strFromAccount;
830         READWRITE(mapValue);
831         pthis->strFromAccount = pthis->mapValue["fromaccount"];
832         pthis->mapValue.erase("fromaccount");
833         pthis->mapValue.erase("version");
834
835         READWRITE(vOrderForm);
836         READWRITE(fTimeReceivedIsTxTime);
837         READWRITE(nTimeReceived);
838         READWRITE(fFromMe);
839         READWRITE(fSpent);
840     )
841
842     int64 GetDebit() const
843     {
844         if (vin.empty())
845             return 0;
846         if (fDebitCached)
847             return nDebitCached;
848         nDebitCached = CTransaction::GetDebit();
849         fDebitCached = true;
850         return nDebitCached;
851     }
852
853     int64 GetCredit(bool fUseCache=true) const
854     {
855         // Must wait until coinbase is safely deep enough in the chain before valuing it
856         if (IsCoinBase() && GetBlocksToMaturity() > 0)
857             return 0;
858
859         // GetBalance can assume transactions in mapWallet won't change
860         if (fUseCache && fCreditCached)
861             return nCreditCached;
862         nCreditCached = CTransaction::GetCredit();
863         fCreditCached = true;
864         return nCreditCached;
865     }
866
867     int64 GetChange() const
868     {
869         if (fChangeCached)
870             return nChangeCached;
871         nChangeCached = CTransaction::GetChange();
872         fChangeCached = true;
873         return nChangeCached;
874     }
875
876     void GetAmounts(int64& nGenerated, list<pair<string /* address */, int64> >& listReceived,
877                     list<pair<string /* address */, int64> >& listSent, int64& nFee, string& strSentAccount) const;
878
879     void GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, 
880                            int64& nSent, int64& nFee) const;
881
882     bool IsFromMe() const
883     {
884         return (GetDebit() > 0);
885     }
886
887     bool IsConfirmed() const
888     {
889         // Quick answer in most cases
890         if (!IsFinal())
891             return false;
892         if (GetDepthInMainChain() >= 1)
893             return true;
894         if (!IsFromMe()) // using wtx's cached debit
895             return false;
896
897         // If no confirmations but it's from us, we can still
898         // consider it confirmed if all dependencies are confirmed
899         map<uint256, const CMerkleTx*> mapPrev;
900         vector<const CMerkleTx*> vWorkQueue;
901         vWorkQueue.reserve(vtxPrev.size()+1);
902         vWorkQueue.push_back(this);
903         for (int i = 0; i < vWorkQueue.size(); i++)
904         {
905             const CMerkleTx* ptx = vWorkQueue[i];
906
907             if (!ptx->IsFinal())
908                 return false;
909             if (ptx->GetDepthInMainChain() >= 1)
910                 return true;
911             if (!ptx->IsFromMe())
912                 return false;
913
914             if (mapPrev.empty())
915                 foreach(const CMerkleTx& tx, vtxPrev)
916                     mapPrev[tx.GetHash()] = &tx;
917
918             foreach(const CTxIn& txin, ptx->vin)
919             {
920                 if (!mapPrev.count(txin.prevout.hash))
921                     return false;
922                 vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
923             }
924         }
925         return true;
926     }
927
928     bool WriteToDisk()
929     {
930         return CWalletDB().WriteTx(GetHash(), *this);
931     }
932
933
934     int64 GetTxTime() const;
935     int GetRequestCount() const;
936
937     void AddSupportingTransactions(CTxDB& txdb);
938
939     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
940     bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
941
942     void RelayWalletTransaction(CTxDB& txdb);
943     void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
944 };
945
946
947
948
949 //
950 // A txdb record that contains the disk location of a transaction and the
951 // locations of transactions that spend its outputs.  vSpent is really only
952 // used as a flag, but having the location is very helpful for debugging.
953 //
954 class CTxIndex
955 {
956 public:
957     CDiskTxPos pos;
958     vector<CDiskTxPos> vSpent;
959
960     CTxIndex()
961     {
962         SetNull();
963     }
964
965     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
966     {
967         pos = posIn;
968         vSpent.resize(nOutputs);
969     }
970
971     IMPLEMENT_SERIALIZE
972     (
973         if (!(nType & SER_GETHASH))
974             READWRITE(nVersion);
975         READWRITE(pos);
976         READWRITE(vSpent);
977     )
978
979     void SetNull()
980     {
981         pos.SetNull();
982         vSpent.clear();
983     }
984
985     bool IsNull()
986     {
987         return pos.IsNull();
988     }
989
990     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
991     {
992         return (a.pos    == b.pos &&
993                 a.vSpent == b.vSpent);
994     }
995
996     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
997     {
998         return !(a == b);
999     }
1000 };
1001
1002
1003
1004
1005
1006 //
1007 // Nodes collect new transactions into a block, hash them into a hash tree,
1008 // and scan through nonce values to make the block's hash satisfy proof-of-work
1009 // requirements.  When they solve the proof-of-work, they broadcast the block
1010 // to everyone and the block is added to the block chain.  The first transaction
1011 // in the block is a special one that creates a new coin owned by the creator
1012 // of the block.
1013 //
1014 // Blocks are appended to blk0001.dat files on disk.  Their location on disk
1015 // is indexed by CBlockIndex objects in memory.
1016 //
1017 class CBlock
1018 {
1019 public:
1020     // header
1021     int nVersion;
1022     uint256 hashPrevBlock;
1023     uint256 hashMerkleRoot;
1024     unsigned int nTime;
1025     unsigned int nBits;
1026     unsigned int nNonce;
1027
1028     // network and disk
1029     vector<CTransaction> vtx;
1030
1031     // memory only
1032     mutable vector<uint256> vMerkleTree;
1033
1034
1035     CBlock()
1036     {
1037         SetNull();
1038     }
1039
1040     IMPLEMENT_SERIALIZE
1041     (
1042         READWRITE(this->nVersion);
1043         nVersion = this->nVersion;
1044         READWRITE(hashPrevBlock);
1045         READWRITE(hashMerkleRoot);
1046         READWRITE(nTime);
1047         READWRITE(nBits);
1048         READWRITE(nNonce);
1049
1050         // ConnectBlock depends on vtx being last so it can calculate offset
1051         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
1052             READWRITE(vtx);
1053         else if (fRead)
1054             const_cast<CBlock*>(this)->vtx.clear();
1055     )
1056
1057     void SetNull()
1058     {
1059         nVersion = 1;
1060         hashPrevBlock = 0;
1061         hashMerkleRoot = 0;
1062         nTime = 0;
1063         nBits = 0;
1064         nNonce = 0;
1065         vtx.clear();
1066         vMerkleTree.clear();
1067     }
1068
1069     bool IsNull() const
1070     {
1071         return (nBits == 0);
1072     }
1073
1074     uint256 GetHash() const
1075     {
1076         return Hash(BEGIN(nVersion), END(nNonce));
1077     }
1078
1079     int64 GetBlockTime() const
1080     {
1081         return (int64)nTime;
1082     }
1083
1084     int GetSigOpCount() const
1085     {
1086         int n = 0;
1087         foreach(const CTransaction& tx, vtx)
1088             n += tx.GetSigOpCount();
1089         return n;
1090     }
1091
1092
1093     uint256 BuildMerkleTree() const
1094     {
1095         vMerkleTree.clear();
1096         foreach(const CTransaction& tx, vtx)
1097             vMerkleTree.push_back(tx.GetHash());
1098         int j = 0;
1099         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1100         {
1101             for (int i = 0; i < nSize; i += 2)
1102             {
1103                 int i2 = min(i+1, nSize-1);
1104                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
1105                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
1106             }
1107             j += nSize;
1108         }
1109         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
1110     }
1111
1112     vector<uint256> GetMerkleBranch(int nIndex) const
1113     {
1114         if (vMerkleTree.empty())
1115             BuildMerkleTree();
1116         vector<uint256> vMerkleBranch;
1117         int j = 0;
1118         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1119         {
1120             int i = min(nIndex^1, nSize-1);
1121             vMerkleBranch.push_back(vMerkleTree[j+i]);
1122             nIndex >>= 1;
1123             j += nSize;
1124         }
1125         return vMerkleBranch;
1126     }
1127
1128     static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)
1129     {
1130         if (nIndex == -1)
1131             return 0;
1132         foreach(const uint256& otherside, vMerkleBranch)
1133         {
1134             if (nIndex & 1)
1135                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
1136             else
1137                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
1138             nIndex >>= 1;
1139         }
1140         return hash;
1141     }
1142
1143
1144     bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
1145     {
1146         // Open history file to append
1147         CAutoFile fileout = AppendBlockFile(nFileRet);
1148         if (!fileout)
1149             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
1150
1151         // Write index header
1152         unsigned int nSize = fileout.GetSerializeSize(*this);
1153         fileout << FLATDATA(pchMessageStart) << nSize;
1154
1155         // Write block
1156         nBlockPosRet = ftell(fileout);
1157         if (nBlockPosRet == -1)
1158             return error("CBlock::WriteToDisk() : ftell failed");
1159         fileout << *this;
1160
1161         // Flush stdio buffers and commit to disk before returning
1162         fflush(fileout);
1163         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
1164         {
1165 #ifdef __WXMSW__
1166             _commit(_fileno(fileout));
1167 #else
1168             fsync(fileno(fileout));
1169 #endif
1170         }
1171
1172         return true;
1173     }
1174
1175     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
1176     {
1177         SetNull();
1178
1179         // Open history file to read
1180         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
1181         if (!filein)
1182             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
1183         if (!fReadTransactions)
1184             filein.nType |= SER_BLOCKHEADERONLY;
1185
1186         // Read block
1187         filein >> *this;
1188
1189         // Check the header
1190         if (!CheckProofOfWork(GetHash(), nBits))
1191             return error("CBlock::ReadFromDisk() : errors in block header");
1192
1193         return true;
1194     }
1195
1196
1197
1198     void print() const
1199     {
1200         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1201             GetHash().ToString().substr(0,20).c_str(),
1202             nVersion,
1203             hashPrevBlock.ToString().substr(0,20).c_str(),
1204             hashMerkleRoot.ToString().substr(0,10).c_str(),
1205             nTime, nBits, nNonce,
1206             vtx.size());
1207         for (int i = 0; i < vtx.size(); i++)
1208         {
1209             printf("  ");
1210             vtx[i].print();
1211         }
1212         printf("  vMerkleTree: ");
1213         for (int i = 0; i < vMerkleTree.size(); i++)
1214             printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
1215         printf("\n");
1216     }
1217
1218
1219     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1220     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1221     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1222     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1223     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1224     bool CheckBlock() const;
1225     bool AcceptBlock();
1226 };
1227
1228
1229
1230
1231
1232
1233 //
1234 // The block chain is a tree shaped structure starting with the
1235 // genesis block at the root, with each block potentially having multiple
1236 // candidates to be the next block.  pprev and pnext link a path through the
1237 // main/longest chain.  A blockindex may have multiple pprev pointing back
1238 // to it, but pnext will only point forward to the longest branch, or will
1239 // be null if the block is not part of the longest chain.
1240 //
1241 class CBlockIndex
1242 {
1243 public:
1244     const uint256* phashBlock;
1245     CBlockIndex* pprev;
1246     CBlockIndex* pnext;
1247     unsigned int nFile;
1248     unsigned int nBlockPos;
1249     int nHeight;
1250     CBigNum bnChainWork;
1251
1252     // block header
1253     int nVersion;
1254     uint256 hashMerkleRoot;
1255     unsigned int nTime;
1256     unsigned int nBits;
1257     unsigned int nNonce;
1258
1259
1260     CBlockIndex()
1261     {
1262         phashBlock = NULL;
1263         pprev = NULL;
1264         pnext = NULL;
1265         nFile = 0;
1266         nBlockPos = 0;
1267         nHeight = 0;
1268         bnChainWork = 0;
1269
1270         nVersion       = 0;
1271         hashMerkleRoot = 0;
1272         nTime          = 0;
1273         nBits          = 0;
1274         nNonce         = 0;
1275     }
1276
1277     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1278     {
1279         phashBlock = NULL;
1280         pprev = NULL;
1281         pnext = NULL;
1282         nFile = nFileIn;
1283         nBlockPos = nBlockPosIn;
1284         nHeight = 0;
1285         bnChainWork = 0;
1286
1287         nVersion       = block.nVersion;
1288         hashMerkleRoot = block.hashMerkleRoot;
1289         nTime          = block.nTime;
1290         nBits          = block.nBits;
1291         nNonce         = block.nNonce;
1292     }
1293
1294     CBlock GetBlockHeader() const
1295     {
1296         CBlock block;
1297         block.nVersion       = nVersion;
1298         if (pprev)
1299             block.hashPrevBlock = pprev->GetBlockHash();
1300         block.hashMerkleRoot = hashMerkleRoot;
1301         block.nTime          = nTime;
1302         block.nBits          = nBits;
1303         block.nNonce         = nNonce;
1304         return block;
1305     }
1306
1307     uint256 GetBlockHash() const
1308     {
1309         return *phashBlock;
1310     }
1311
1312     int64 GetBlockTime() const
1313     {
1314         return (int64)nTime;
1315     }
1316
1317     CBigNum GetBlockWork() const
1318     {
1319         CBigNum bnTarget;
1320         bnTarget.SetCompact(nBits);
1321         if (bnTarget <= 0)
1322             return 0;
1323         return (CBigNum(1)<<256) / (bnTarget+1);
1324     }
1325
1326     bool IsInMainChain() const
1327     {
1328         return (pnext || this == pindexBest);
1329     }
1330
1331     bool CheckIndex() const
1332     {
1333         return CheckProofOfWork(GetBlockHash(), nBits);
1334     }
1335
1336     bool EraseBlockFromDisk()
1337     {
1338         // Open history file
1339         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1340         if (!fileout)
1341             return false;
1342
1343         // Overwrite with empty null block
1344         CBlock block;
1345         block.SetNull();
1346         fileout << block;
1347
1348         return true;
1349     }
1350
1351     enum { nMedianTimeSpan=11 };
1352
1353     int64 GetMedianTimePast() const
1354     {
1355         int64 pmedian[nMedianTimeSpan];
1356         int64* pbegin = &pmedian[nMedianTimeSpan];
1357         int64* pend = &pmedian[nMedianTimeSpan];
1358
1359         const CBlockIndex* pindex = this;
1360         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1361             *(--pbegin) = pindex->GetBlockTime();
1362
1363         sort(pbegin, pend);
1364         return pbegin[(pend - pbegin)/2];
1365     }
1366
1367     int64 GetMedianTime() const
1368     {
1369         const CBlockIndex* pindex = this;
1370         for (int i = 0; i < nMedianTimeSpan/2; i++)
1371         {
1372             if (!pindex->pnext)
1373                 return GetBlockTime();
1374             pindex = pindex->pnext;
1375         }
1376         return pindex->GetMedianTimePast();
1377     }
1378
1379
1380
1381     string ToString() const
1382     {
1383         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1384             pprev, pnext, nFile, nBlockPos, nHeight,
1385             hashMerkleRoot.ToString().substr(0,10).c_str(),
1386             GetBlockHash().ToString().substr(0,20).c_str());
1387     }
1388
1389     void print() const
1390     {
1391         printf("%s\n", ToString().c_str());
1392     }
1393 };
1394
1395
1396
1397 //
1398 // Used to marshal pointers into hashes for db storage.
1399 //
1400 class CDiskBlockIndex : public CBlockIndex
1401 {
1402 public:
1403     uint256 hashPrev;
1404     uint256 hashNext;
1405
1406     CDiskBlockIndex()
1407     {
1408         hashPrev = 0;
1409         hashNext = 0;
1410     }
1411
1412     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1413     {
1414         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1415         hashNext = (pnext ? pnext->GetBlockHash() : 0);
1416     }
1417
1418     IMPLEMENT_SERIALIZE
1419     (
1420         if (!(nType & SER_GETHASH))
1421             READWRITE(nVersion);
1422
1423         READWRITE(hashNext);
1424         READWRITE(nFile);
1425         READWRITE(nBlockPos);
1426         READWRITE(nHeight);
1427
1428         // block header
1429         READWRITE(this->nVersion);
1430         READWRITE(hashPrev);
1431         READWRITE(hashMerkleRoot);
1432         READWRITE(nTime);
1433         READWRITE(nBits);
1434         READWRITE(nNonce);
1435     )
1436
1437     uint256 GetBlockHash() const
1438     {
1439         CBlock block;
1440         block.nVersion        = nVersion;
1441         block.hashPrevBlock   = hashPrev;
1442         block.hashMerkleRoot  = hashMerkleRoot;
1443         block.nTime           = nTime;
1444         block.nBits           = nBits;
1445         block.nNonce          = nNonce;
1446         return block.GetHash();
1447     }
1448
1449
1450     string ToString() const
1451     {
1452         string str = "CDiskBlockIndex(";
1453         str += CBlockIndex::ToString();
1454         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
1455             GetBlockHash().ToString().c_str(),
1456             hashPrev.ToString().substr(0,20).c_str(),
1457             hashNext.ToString().substr(0,20).c_str());
1458         return str;
1459     }
1460
1461     void print() const
1462     {
1463         printf("%s\n", ToString().c_str());
1464     }
1465 };
1466
1467
1468
1469
1470
1471
1472
1473
1474 //
1475 // Describes a place in the block chain to another node such that if the
1476 // other node doesn't have the same branch, it can find a recent common trunk.
1477 // The further back it is, the further before the fork it may be.
1478 //
1479 class CBlockLocator
1480 {
1481 protected:
1482     vector<uint256> vHave;
1483 public:
1484
1485     CBlockLocator()
1486     {
1487     }
1488
1489     explicit CBlockLocator(const CBlockIndex* pindex)
1490     {
1491         Set(pindex);
1492     }
1493
1494     explicit CBlockLocator(uint256 hashBlock)
1495     {
1496         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1497         if (mi != mapBlockIndex.end())
1498             Set((*mi).second);
1499     }
1500
1501     IMPLEMENT_SERIALIZE
1502     (
1503         if (!(nType & SER_GETHASH))
1504             READWRITE(nVersion);
1505         READWRITE(vHave);
1506     )
1507
1508     void SetNull()
1509     {
1510         vHave.clear();
1511     }
1512
1513     bool IsNull()
1514     {
1515         return vHave.empty();
1516     }
1517
1518     void Set(const CBlockIndex* pindex)
1519     {
1520         vHave.clear();
1521         int nStep = 1;
1522         while (pindex)
1523         {
1524             vHave.push_back(pindex->GetBlockHash());
1525
1526             // Exponentially larger steps back
1527             for (int i = 0; pindex && i < nStep; i++)
1528                 pindex = pindex->pprev;
1529             if (vHave.size() > 10)
1530                 nStep *= 2;
1531         }
1532         vHave.push_back(hashGenesisBlock);
1533     }
1534
1535     int GetDistanceBack()
1536     {
1537         // Retrace how far back it was in the sender's branch
1538         int nDistance = 0;
1539         int nStep = 1;
1540         foreach(const uint256& hash, vHave)
1541         {
1542             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1543             if (mi != mapBlockIndex.end())
1544             {
1545                 CBlockIndex* pindex = (*mi).second;
1546                 if (pindex->IsInMainChain())
1547                     return nDistance;
1548             }
1549             nDistance += nStep;
1550             if (nDistance > 10)
1551                 nStep *= 2;
1552         }
1553         return nDistance;
1554     }
1555
1556     CBlockIndex* GetBlockIndex()
1557     {
1558         // Find the first block the caller has in the main chain
1559         foreach(const uint256& hash, vHave)
1560         {
1561             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1562             if (mi != mapBlockIndex.end())
1563             {
1564                 CBlockIndex* pindex = (*mi).second;
1565                 if (pindex->IsInMainChain())
1566                     return pindex;
1567             }
1568         }
1569         return pindexGenesisBlock;
1570     }
1571
1572     uint256 GetBlockHash()
1573     {
1574         // Find the first block the caller has in the main chain
1575         foreach(const uint256& hash, vHave)
1576         {
1577             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1578             if (mi != mapBlockIndex.end())
1579             {
1580                 CBlockIndex* pindex = (*mi).second;
1581                 if (pindex->IsInMainChain())
1582                     return hash;
1583             }
1584         }
1585         return hashGenesisBlock;
1586     }
1587
1588     int GetHeight()
1589     {
1590         CBlockIndex* pindex = GetBlockIndex();
1591         if (!pindex)
1592             return 0;
1593         return pindex->nHeight;
1594     }
1595 };
1596
1597
1598
1599
1600
1601
1602 //
1603 // Private key that includes an expiration date in case it never gets used.
1604 //
1605 class CWalletKey
1606 {
1607 public:
1608     CPrivKey vchPrivKey;
1609     int64 nTimeCreated;
1610     int64 nTimeExpires;
1611     string strComment;
1612     //// todo: add something to note what created it (user, getnewaddress, change)
1613     ////   maybe should have a map<string, string> property map
1614
1615     CWalletKey(int64 nExpires=0)
1616     {
1617         nTimeCreated = (nExpires ? GetTime() : 0);
1618         nTimeExpires = nExpires;
1619     }
1620
1621     IMPLEMENT_SERIALIZE
1622     (
1623         if (!(nType & SER_GETHASH))
1624             READWRITE(nVersion);
1625         READWRITE(vchPrivKey);
1626         READWRITE(nTimeCreated);
1627         READWRITE(nTimeExpires);
1628         READWRITE(strComment);
1629     )
1630 };
1631
1632
1633
1634
1635
1636
1637 //
1638 // Account information.
1639 // Stored in wallet with key "acc"+string account name
1640 //
1641 class CAccount
1642 {
1643 public:
1644     vector<unsigned char> vchPubKey;
1645
1646     CAccount()
1647     {
1648         SetNull();
1649     }
1650
1651     void SetNull()
1652     {
1653         vchPubKey.clear();
1654     }
1655
1656     IMPLEMENT_SERIALIZE
1657     (
1658         if (!(nType & SER_GETHASH))
1659             READWRITE(nVersion);
1660         READWRITE(vchPubKey);
1661     )
1662 };
1663
1664
1665
1666 //
1667 // Internal transfers.
1668 // Database key is acentry<account><counter>
1669 //
1670 class CAccountingEntry
1671 {
1672 public:
1673     string strAccount;
1674     int64 nCreditDebit;
1675     int64 nTime;
1676     string strOtherAccount;
1677     string strComment;
1678
1679     CAccountingEntry()
1680     {
1681         SetNull();
1682     }
1683
1684     void SetNull()
1685     {
1686         nCreditDebit = 0;
1687         nTime = 0;
1688         strAccount.clear();
1689         strOtherAccount.clear();
1690         strComment.clear();
1691     }
1692
1693     IMPLEMENT_SERIALIZE
1694     (
1695         if (!(nType & SER_GETHASH))
1696             READWRITE(nVersion);
1697         // Note: strAccount is serialized as part of the key, not here.
1698         READWRITE(nCreditDebit);
1699         READWRITE(nTime);
1700         READWRITE(strOtherAccount);
1701         READWRITE(strComment);
1702     )
1703 };
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713 //
1714 // Alerts are for notifying old versions if they become too obsolete and
1715 // need to upgrade.  The message is displayed in the status bar.
1716 // Alert messages are broadcast as a vector of signed data.  Unserializing may
1717 // not read the entire buffer if the alert is for a newer version, but older
1718 // versions can still relay the original data.
1719 //
1720 class CUnsignedAlert
1721 {
1722 public:
1723     int nVersion;
1724     int64 nRelayUntil;      // when newer nodes stop relaying to newer nodes
1725     int64 nExpiration;
1726     int nID;
1727     int nCancel;
1728     set<int> setCancel;
1729     int nMinVer;            // lowest version inclusive
1730     int nMaxVer;            // highest version inclusive
1731     set<string> setSubVer;  // empty matches all
1732     int nPriority;
1733
1734     // Actions
1735     string strComment;
1736     string strStatusBar;
1737     string strReserved;
1738
1739     IMPLEMENT_SERIALIZE
1740     (
1741         READWRITE(this->nVersion);
1742         nVersion = this->nVersion;
1743         READWRITE(nRelayUntil);
1744         READWRITE(nExpiration);
1745         READWRITE(nID);
1746         READWRITE(nCancel);
1747         READWRITE(setCancel);
1748         READWRITE(nMinVer);
1749         READWRITE(nMaxVer);
1750         READWRITE(setSubVer);
1751         READWRITE(nPriority);
1752
1753         READWRITE(strComment);
1754         READWRITE(strStatusBar);
1755         READWRITE(strReserved);
1756     )
1757
1758     void SetNull()
1759     {
1760         nVersion = 1;
1761         nRelayUntil = 0;
1762         nExpiration = 0;
1763         nID = 0;
1764         nCancel = 0;
1765         setCancel.clear();
1766         nMinVer = 0;
1767         nMaxVer = 0;
1768         setSubVer.clear();
1769         nPriority = 0;
1770
1771         strComment.clear();
1772         strStatusBar.clear();
1773         strReserved.clear();
1774     }
1775
1776     string ToString() const
1777     {
1778         string strSetCancel;
1779         foreach(int n, setCancel)
1780             strSetCancel += strprintf("%d ", n);
1781         string strSetSubVer;
1782         foreach(string str, setSubVer)
1783             strSetSubVer += "\"" + str + "\" ";
1784         return strprintf(
1785                 "CAlert(\n"
1786                 "    nVersion     = %d\n"
1787                 "    nRelayUntil  = %"PRI64d"\n"
1788                 "    nExpiration  = %"PRI64d"\n"
1789                 "    nID          = %d\n"
1790                 "    nCancel      = %d\n"
1791                 "    setCancel    = %s\n"
1792                 "    nMinVer      = %d\n"
1793                 "    nMaxVer      = %d\n"
1794                 "    setSubVer    = %s\n"
1795                 "    nPriority    = %d\n"
1796                 "    strComment   = \"%s\"\n"
1797                 "    strStatusBar = \"%s\"\n"
1798                 ")\n",
1799             nVersion,
1800             nRelayUntil,
1801             nExpiration,
1802             nID,
1803             nCancel,
1804             strSetCancel.c_str(),
1805             nMinVer,
1806             nMaxVer,
1807             strSetSubVer.c_str(),
1808             nPriority,
1809             strComment.c_str(),
1810             strStatusBar.c_str());
1811     }
1812
1813     void print() const
1814     {
1815         printf("%s", ToString().c_str());
1816     }
1817 };
1818
1819 class CAlert : public CUnsignedAlert
1820 {
1821 public:
1822     vector<unsigned char> vchMsg;
1823     vector<unsigned char> vchSig;
1824
1825     CAlert()
1826     {
1827         SetNull();
1828     }
1829
1830     IMPLEMENT_SERIALIZE
1831     (
1832         READWRITE(vchMsg);
1833         READWRITE(vchSig);
1834     )
1835
1836     void SetNull()
1837     {
1838         CUnsignedAlert::SetNull();
1839         vchMsg.clear();
1840         vchSig.clear();
1841     }
1842
1843     bool IsNull() const
1844     {
1845         return (nExpiration == 0);
1846     }
1847
1848     uint256 GetHash() const
1849     {
1850         return SerializeHash(*this);
1851     }
1852
1853     bool IsInEffect() const
1854     {
1855         return (GetAdjustedTime() < nExpiration);
1856     }
1857
1858     bool Cancels(const CAlert& alert) const
1859     {
1860         if (!IsInEffect())
1861             return false; // this was a no-op before 31403
1862         return (alert.nID <= nCancel || setCancel.count(alert.nID));
1863     }
1864
1865     bool AppliesTo(int nVersion, string strSubVerIn) const
1866     {
1867         return (IsInEffect() &&
1868                 nMinVer <= nVersion && nVersion <= nMaxVer &&
1869                 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
1870     }
1871
1872     bool AppliesToMe() const
1873     {
1874         return AppliesTo(VERSION, ::pszSubVer);
1875     }
1876
1877     bool RelayTo(CNode* pnode) const
1878     {
1879         if (!IsInEffect())
1880             return false;
1881         // returns true if wasn't already contained in the set
1882         if (pnode->setKnown.insert(GetHash()).second)
1883         {
1884             if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
1885                 AppliesToMe() ||
1886                 GetAdjustedTime() < nRelayUntil)
1887             {
1888                 pnode->PushMessage("alert", *this);
1889                 return true;
1890             }
1891         }
1892         return false;
1893     }
1894
1895     bool CheckSignature()
1896     {
1897         CKey key;
1898         if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
1899             return error("CAlert::CheckSignature() : SetPubKey failed");
1900         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
1901             return error("CAlert::CheckSignature() : verify signature failed");
1902
1903         // Now unserialize the data
1904         CDataStream sMsg(vchMsg);
1905         sMsg >> *(CUnsignedAlert*)this;
1906         return true;
1907     }
1908
1909     bool ProcessAlert();
1910 };
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921 extern map<uint256, CTransaction> mapTransactions;
1922 extern map<uint256, CWalletTx> mapWallet;
1923 extern vector<uint256> vWalletUpdated;
1924 extern CCriticalSection cs_mapWallet;
1925 extern map<vector<unsigned char>, CPrivKey> mapKeys;
1926 extern map<uint160, vector<unsigned char> > mapPubKeys;
1927 extern CCriticalSection cs_mapKeys;
1928 extern CKey keyUser;