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