block index checking on load, extra redundant checks, misc refactoring
[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_SIZE = 0x02000000;
18 static const unsigned int MAX_BLOCK_SIZE = 1000000;
19 static const int64 COIN = 100000000;
20 static const int64 CENT = 1000000;
21 static const int64 MAX_MONEY = 21000000 * COIN;
22 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
23 static const int COINBASE_MATURITY = 100;
24 static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
25
26
27
28
29
30
31 extern CCriticalSection cs_main;
32 extern map<uint256, CBlockIndex*> mapBlockIndex;
33 extern const uint256 hashGenesisBlock;
34 extern CBlockIndex* pindexGenesisBlock;
35 extern int nBestHeight;
36 extern CBigNum bnBestChainWork;
37 extern CBigNum bnBestInvalidWork;
38 extern uint256 hashBestChain;
39 extern CBlockIndex* pindexBest;
40 extern unsigned int nTransactionsUpdated;
41 extern map<uint256, int> mapRequestCount;
42 extern CCriticalSection cs_mapRequestCount;
43 extern map<string, string> mapAddressBook;
44 extern CCriticalSection cs_mapAddressBook;
45 extern vector<unsigned char> vchDefaultKey;
46 extern double dHashesPerSec;
47 extern int64 nHPSTimerStart;
48
49 // Settings
50 extern int fGenerateBitcoins;
51 extern int64 nTransactionFee;
52 extern CAddress addrIncoming;
53 extern int fLimitProcessors;
54 extern int nLimitProcessors;
55 extern int fMinimizeToTray;
56 extern int fMinimizeOnClose;
57
58
59
60
61
62
63
64 bool CheckDiskSpace(int64 nAdditionalBytes=0);
65 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
66 FILE* AppendBlockFile(unsigned int& nFileRet);
67 bool AddKey(const CKey& key);
68 vector<unsigned char> GenerateNewKey();
69 bool AddToWallet(const CWalletTx& wtxIn);
70 void WalletUpdateSpent(const COutPoint& prevout);
71 void ReacceptWalletTransactions();
72 bool LoadBlockIndex(bool fAllowNew=true);
73 void PrintBlockTree();
74 bool ProcessMessages(CNode* pfrom);
75 bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
76 bool SendMessages(CNode* pto, bool fSendTrickle);
77 int64 GetBalance();
78 bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet);
79 bool CommitTransaction(CWalletTx& wtxNew, const CKey& key);
80 bool BroadcastTransaction(CWalletTx& wtxNew);
81 string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
82 string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
83 void GenerateBitcoins(bool fGenerate);
84 void ThreadBitcoinMiner(void* parg);
85 void BitcoinMiner();
86 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
87 bool IsInitialBlockDownload();
88 bool IsLockdown();
89
90
91
92
93
94
95
96
97
98
99
100
101 class CDiskTxPos
102 {
103 public:
104     unsigned int nFile;
105     unsigned int nBlockPos;
106     unsigned int nTxPos;
107
108     CDiskTxPos()
109     {
110         SetNull();
111     }
112
113     CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
114     {
115         nFile = nFileIn;
116         nBlockPos = nBlockPosIn;
117         nTxPos = nTxPosIn;
118     }
119
120     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
121     void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
122     bool IsNull() const { return (nFile == -1); }
123
124     friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
125     {
126         return (a.nFile     == b.nFile &&
127                 a.nBlockPos == b.nBlockPos &&
128                 a.nTxPos    == b.nTxPos);
129     }
130
131     friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
132     {
133         return !(a == b);
134     }
135
136     string ToString() const
137     {
138         if (IsNull())
139             return strprintf("null");
140         else
141             return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
142     }
143
144     void print() const
145     {
146         printf("%s", ToString().c_str());
147     }
148 };
149
150
151
152
153 class CInPoint
154 {
155 public:
156     CTransaction* ptx;
157     unsigned int n;
158
159     CInPoint() { SetNull(); }
160     CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
161     void SetNull() { ptx = NULL; n = -1; }
162     bool IsNull() const { return (ptx == NULL && n == -1); }
163 };
164
165
166
167
168 class COutPoint
169 {
170 public:
171     uint256 hash;
172     unsigned int n;
173
174     COutPoint() { SetNull(); }
175     COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
176     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
177     void SetNull() { hash = 0; n = -1; }
178     bool IsNull() const { return (hash == 0 && n == -1); }
179
180     friend bool operator<(const COutPoint& a, const COutPoint& b)
181     {
182         return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
183     }
184
185     friend bool operator==(const COutPoint& a, const COutPoint& b)
186     {
187         return (a.hash == b.hash && a.n == b.n);
188     }
189
190     friend bool operator!=(const COutPoint& a, const COutPoint& b)
191     {
192         return !(a == b);
193     }
194
195     string ToString() const
196     {
197         return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n);
198     }
199
200     void print() const
201     {
202         printf("%s\n", ToString().c_str());
203     }
204 };
205
206
207
208
209 //
210 // An input of a transaction.  It contains the location of the previous
211 // transaction's output that it claims and a signature that matches the
212 // output's public key.
213 //
214 class CTxIn
215 {
216 public:
217     COutPoint prevout;
218     CScript scriptSig;
219     unsigned int nSequence;
220
221     CTxIn()
222     {
223         nSequence = UINT_MAX;
224     }
225
226     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
227     {
228         prevout = prevoutIn;
229         scriptSig = scriptSigIn;
230         nSequence = nSequenceIn;
231     }
232
233     CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
234     {
235         prevout = COutPoint(hashPrevTx, nOut);
236         scriptSig = scriptSigIn;
237         nSequence = nSequenceIn;
238     }
239
240     IMPLEMENT_SERIALIZE
241     (
242         READWRITE(prevout);
243         READWRITE(scriptSig);
244         READWRITE(nSequence);
245     )
246
247     bool IsFinal() const
248     {
249         return (nSequence == UINT_MAX);
250     }
251
252     friend bool operator==(const CTxIn& a, const CTxIn& b)
253     {
254         return (a.prevout   == b.prevout &&
255                 a.scriptSig == b.scriptSig &&
256                 a.nSequence == b.nSequence);
257     }
258
259     friend bool operator!=(const CTxIn& a, const CTxIn& b)
260     {
261         return !(a == b);
262     }
263
264     string ToString() const
265     {
266         string str;
267         str += strprintf("CTxIn(");
268         str += prevout.ToString();
269         if (prevout.IsNull())
270             str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str());
271         else
272             str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
273         if (nSequence != UINT_MAX)
274             str += strprintf(", nSequence=%u", nSequence);
275         str += ")";
276         return str;
277     }
278
279     void print() const
280     {
281         printf("%s\n", ToString().c_str());
282     }
283
284     bool IsMine() const;
285     int64 GetDebit() const;
286 };
287
288
289
290
291 //
292 // An output of a transaction.  It contains the public key that the next input
293 // must be able to sign with to claim it.
294 //
295 class CTxOut
296 {
297 public:
298     int64 nValue;
299     CScript scriptPubKey;
300
301 public:
302     CTxOut()
303     {
304         SetNull();
305     }
306
307     CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
308     {
309         nValue = nValueIn;
310         scriptPubKey = scriptPubKeyIn;
311     }
312
313     IMPLEMENT_SERIALIZE
314     (
315         READWRITE(nValue);
316         READWRITE(scriptPubKey);
317     )
318
319     void SetNull()
320     {
321         nValue = -1;
322         scriptPubKey.clear();
323     }
324
325     bool IsNull()
326     {
327         return (nValue == -1);
328     }
329
330     uint256 GetHash() const
331     {
332         return SerializeHash(*this);
333     }
334
335     bool IsMine() const
336     {
337         return ::IsMine(scriptPubKey);
338     }
339
340     int64 GetCredit() const
341     {
342         if (!MoneyRange(nValue))
343             throw runtime_error("CTxOut::GetCredit() : value out of range");
344         if (IsMine())
345             return nValue;
346         return 0;
347     }
348
349     friend bool operator==(const CTxOut& a, const CTxOut& b)
350     {
351         return (a.nValue       == b.nValue &&
352                 a.scriptPubKey == b.scriptPubKey);
353     }
354
355     friend bool operator!=(const CTxOut& a, const CTxOut& b)
356     {
357         return !(a == b);
358     }
359
360     string ToString() const
361     {
362         if (scriptPubKey.size() < 6)
363             return "CTxOut(error)";
364         return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str());
365     }
366
367     void print() const
368     {
369         printf("%s\n", ToString().c_str());
370     }
371 };
372
373
374
375
376 //
377 // The basic transaction that is broadcasted on the network and contained in
378 // blocks.  A transaction can contain multiple inputs and outputs.
379 //
380 class CTransaction
381 {
382 public:
383     int nVersion;
384     vector<CTxIn> vin;
385     vector<CTxOut> vout;
386     unsigned int nLockTime;
387
388
389     CTransaction()
390     {
391         SetNull();
392     }
393
394     IMPLEMENT_SERIALIZE
395     (
396         READWRITE(this->nVersion);
397         nVersion = this->nVersion;
398         READWRITE(vin);
399         READWRITE(vout);
400         READWRITE(nLockTime);
401     )
402
403     void SetNull()
404     {
405         nVersion = 1;
406         vin.clear();
407         vout.clear();
408         nLockTime = 0;
409     }
410
411     bool IsNull() const
412     {
413         return (vin.empty() && vout.empty());
414     }
415
416     uint256 GetHash() const
417     {
418         return SerializeHash(*this);
419     }
420
421     bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
422     {
423         // Time based nLockTime implemented in 0.1.6
424         if (nLockTime == 0)
425             return true;
426         if (nBlockHeight == 0)
427             nBlockHeight = nBestHeight;
428         if (nBlockTime == 0)
429             nBlockTime = GetAdjustedTime();
430         if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime))
431             return true;
432         foreach(const CTxIn& txin, vin)
433             if (!txin.IsFinal())
434                 return false;
435         return true;
436     }
437
438     bool IsNewerThan(const CTransaction& old) const
439     {
440         if (vin.size() != old.vin.size())
441             return false;
442         for (int i = 0; i < vin.size(); i++)
443             if (vin[i].prevout != old.vin[i].prevout)
444                 return false;
445
446         bool fNewer = false;
447         unsigned int nLowest = UINT_MAX;
448         for (int i = 0; i < vin.size(); i++)
449         {
450             if (vin[i].nSequence != old.vin[i].nSequence)
451             {
452                 if (vin[i].nSequence <= nLowest)
453                 {
454                     fNewer = false;
455                     nLowest = vin[i].nSequence;
456                 }
457                 if (old.vin[i].nSequence < nLowest)
458                 {
459                     fNewer = true;
460                     nLowest = old.vin[i].nSequence;
461                 }
462             }
463         }
464         return fNewer;
465     }
466
467     bool IsCoinBase() const
468     {
469         return (vin.size() == 1 && vin[0].prevout.IsNull());
470     }
471
472     bool CheckTransaction() const
473     {
474         // Basic checks that don't depend on any context
475         if (vin.empty() || vout.empty())
476             return error("CTransaction::CheckTransaction() : vin or vout empty");
477
478         // Check for negative or overflow output values
479         int64 nValueOut = 0;
480         foreach(const CTxOut& txout, vout)
481         {
482             if (txout.nValue < 0)
483                 return error("CTransaction::CheckTransaction() : txout.nValue negative");
484             if (txout.nValue > MAX_MONEY)
485                 return error("CTransaction::CheckTransaction() : txout.nValue too high");
486             nValueOut += txout.nValue;
487             if (!MoneyRange(nValueOut))
488                 return error("CTransaction::CheckTransaction() : txout total out of range");
489         }
490
491         if (IsCoinBase())
492         {
493             if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
494                 return error("CTransaction::CheckTransaction() : coinbase script size");
495         }
496         else
497         {
498             foreach(const CTxIn& txin, vin)
499                 if (txin.prevout.IsNull())
500                     return error("CTransaction::CheckTransaction() : prevout is null");
501         }
502
503         return true;
504     }
505
506     bool IsMine() const
507     {
508         foreach(const CTxOut& txout, vout)
509             if (txout.IsMine())
510                 return true;
511         return false;
512     }
513
514     int64 GetDebit() const
515     {
516         int64 nDebit = 0;
517         foreach(const CTxIn& txin, vin)
518         {
519             nDebit += txin.GetDebit();
520             if (!MoneyRange(nDebit))
521                 throw runtime_error("CTransaction::GetDebit() : value out of range");
522         }
523         return nDebit;
524     }
525
526     int64 GetCredit() const
527     {
528         int64 nCredit = 0;
529         foreach(const CTxOut& txout, vout)
530         {
531             nCredit += txout.GetCredit();
532             if (!MoneyRange(nCredit))
533                 throw runtime_error("CTransaction::GetCredit() : value out of range");
534         }
535         return nCredit;
536     }
537
538     int64 GetValueOut() const
539     {
540         int64 nValueOut = 0;
541         foreach(const CTxOut& txout, vout)
542         {
543             nValueOut += txout.nValue;
544             if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
545                 throw runtime_error("CTransaction::GetValueOut() : value out of range");
546         }
547         return nValueOut;
548     }
549
550     int64 GetMinFee(unsigned int nBlockSize=1) const
551     {
552         // Base fee is 1 cent per kilobyte
553         unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
554         int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT;
555
556         // Transactions under 60K are free as long as block size is under 80K
557         // (about 27,000bc if made of 50bc inputs)
558         if (nBytes < 60000 && nBlockSize < 80000)
559             nMinFee = 0;
560
561         // Transactions under 3K are free as long as block size is under 200K
562         if (nBytes < 3000 && nBlockSize < 200000)
563             nMinFee = 0;
564
565         // To limit dust spam, require a 0.01 fee if any output is less than 0.01
566         if (nMinFee < CENT)
567             foreach(const CTxOut& txout, vout)
568                 if (txout.nValue < CENT)
569                     nMinFee = CENT;
570
571         return nMinFee;
572     }
573
574
575
576     bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
577     {
578         CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
579         if (!filein)
580             return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
581
582         // Read transaction
583         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
584             return error("CTransaction::ReadFromDisk() : fseek failed");
585         filein >> *this;
586
587         // Return file pointer
588         if (pfileRet)
589         {
590             if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
591                 return error("CTransaction::ReadFromDisk() : second fseek failed");
592             *pfileRet = filein.release();
593         }
594         return true;
595     }
596
597
598     friend bool operator==(const CTransaction& a, const CTransaction& b)
599     {
600         return (a.nVersion  == b.nVersion &&
601                 a.vin       == b.vin &&
602                 a.vout      == b.vout &&
603                 a.nLockTime == b.nLockTime);
604     }
605
606     friend bool operator!=(const CTransaction& a, const CTransaction& b)
607     {
608         return !(a == b);
609     }
610
611
612     string ToString() const
613     {
614         string str;
615         str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
616             GetHash().ToString().substr(0,6).c_str(),
617             nVersion,
618             vin.size(),
619             vout.size(),
620             nLockTime);
621         for (int i = 0; i < vin.size(); i++)
622             str += "    " + vin[i].ToString() + "\n";
623         for (int i = 0; i < vout.size(); i++)
624             str += "    " + vout[i].ToString() + "\n";
625         return str;
626     }
627
628     void print() const
629     {
630         printf("%s", ToString().c_str());
631     }
632
633
634
635     bool DisconnectInputs(CTxDB& txdb);
636     bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
637                        CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
638     bool ClientConnectInputs();
639
640     bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
641
642     bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
643     {
644         CTxDB txdb("r");
645         return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs);
646     }
647
648 protected:
649     bool AddToMemoryPool();
650 public:
651     bool RemoveFromMemoryPool();
652 };
653
654
655
656
657
658 //
659 // A transaction with a merkle branch linking it to the block chain
660 //
661 class CMerkleTx : public CTransaction
662 {
663 public:
664     uint256 hashBlock;
665     vector<uint256> vMerkleBranch;
666     int nIndex;
667
668     // memory only
669     mutable bool fMerkleVerified;
670     mutable bool fGetCreditCached;
671     mutable int64 nGetCreditCached;
672
673
674     CMerkleTx()
675     {
676         Init();
677     }
678
679     CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
680     {
681         Init();
682     }
683
684     void Init()
685     {
686         hashBlock = 0;
687         nIndex = -1;
688         fMerkleVerified = false;
689         fGetCreditCached = false;
690         nGetCreditCached = 0;
691     }
692
693     IMPLEMENT_SERIALIZE
694     (
695         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
696         nVersion = this->nVersion;
697         READWRITE(hashBlock);
698         READWRITE(vMerkleBranch);
699         READWRITE(nIndex);
700     )
701
702     int64 GetCredit(bool fUseCache=false) const
703     {
704         // Must wait until coinbase is safely deep enough in the chain before valuing it
705         if (IsCoinBase() && GetBlocksToMaturity() > 0)
706             return 0;
707
708         // GetBalance can assume transactions in mapWallet won't change
709         if (fUseCache && fGetCreditCached)
710             return nGetCreditCached;
711         nGetCreditCached = CTransaction::GetCredit();
712         fGetCreditCached = true;
713         return nGetCreditCached;
714     }
715
716
717     int SetMerkleBranch(const CBlock* pblock=NULL);
718     int GetDepthInMainChain(int& nHeightRet) const;
719     int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
720     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
721     int GetBlocksToMaturity() const;
722     bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true);
723     bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); }
724 };
725
726
727
728
729 //
730 // A transaction with a bunch of additional info that only the owner cares
731 // about.  It includes any unrecorded transactions needed to link it back
732 // to the block chain.
733 //
734 class CWalletTx : public CMerkleTx
735 {
736 public:
737     vector<CMerkleTx> vtxPrev;
738     map<string, string> mapValue;
739     vector<pair<string, string> > vOrderForm;
740     unsigned int fTimeReceivedIsTxTime;
741     unsigned int nTimeReceived;  // time received by this node
742     char fFromMe;
743     char fSpent;
744     //// probably need to sign the order info so know it came from payer
745
746     // memory only UI hints
747     mutable unsigned int nTimeDisplayed;
748     mutable int nLinesDisplayed;
749
750
751     CWalletTx()
752     {
753         Init();
754     }
755
756     CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
757     {
758         Init();
759     }
760
761     CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
762     {
763         Init();
764     }
765
766     void Init()
767     {
768         fTimeReceivedIsTxTime = false;
769         nTimeReceived = 0;
770         fFromMe = false;
771         fSpent = false;
772         nTimeDisplayed = 0;
773         nLinesDisplayed = 0;
774     }
775
776     IMPLEMENT_SERIALIZE
777     (
778         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
779         nVersion = this->nVersion;
780         READWRITE(vtxPrev);
781         READWRITE(mapValue);
782         READWRITE(vOrderForm);
783         READWRITE(fTimeReceivedIsTxTime);
784         READWRITE(nTimeReceived);
785         READWRITE(fFromMe);
786         READWRITE(fSpent);
787     )
788
789     bool WriteToDisk()
790     {
791         return CWalletDB().WriteTx(GetHash(), *this);
792     }
793
794
795     int64 GetTxTime() const;
796     int GetRequestCount() const;
797
798     void AddSupportingTransactions(CTxDB& txdb);
799
800     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
801     bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
802
803     void RelayWalletTransaction(CTxDB& txdb);
804     void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
805 };
806
807
808
809
810 //
811 // A txdb record that contains the disk location of a transaction and the
812 // locations of transactions that spend its outputs.  vSpent is really only
813 // used as a flag, but having the location is very helpful for debugging.
814 //
815 class CTxIndex
816 {
817 public:
818     CDiskTxPos pos;
819     vector<CDiskTxPos> vSpent;
820
821     CTxIndex()
822     {
823         SetNull();
824     }
825
826     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
827     {
828         pos = posIn;
829         vSpent.resize(nOutputs);
830     }
831
832     IMPLEMENT_SERIALIZE
833     (
834         if (!(nType & SER_GETHASH))
835             READWRITE(nVersion);
836         READWRITE(pos);
837         READWRITE(vSpent);
838     )
839
840     void SetNull()
841     {
842         pos.SetNull();
843         vSpent.clear();
844     }
845
846     bool IsNull()
847     {
848         return pos.IsNull();
849     }
850
851     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
852     {
853         if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size())
854             return false;
855         for (int i = 0; i < a.vSpent.size(); i++)
856             if (a.vSpent[i] != b.vSpent[i])
857                 return false;
858         return true;
859     }
860
861     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
862     {
863         return !(a == b);
864     }
865 };
866
867
868
869
870
871 //
872 // Nodes collect new transactions into a block, hash them into a hash tree,
873 // and scan through nonce values to make the block's hash satisfy proof-of-work
874 // requirements.  When they solve the proof-of-work, they broadcast the block
875 // to everyone and the block is added to the block chain.  The first transaction
876 // in the block is a special one that creates a new coin owned by the creator
877 // of the block.
878 //
879 // Blocks are appended to blk0001.dat files on disk.  Their location on disk
880 // is indexed by CBlockIndex objects in memory.
881 //
882 class CBlock
883 {
884 public:
885     // header
886     int nVersion;
887     uint256 hashPrevBlock;
888     uint256 hashMerkleRoot;
889     unsigned int nTime;
890     unsigned int nBits;
891     unsigned int nNonce;
892
893     // network and disk
894     vector<CTransaction> vtx;
895
896     // memory only
897     mutable vector<uint256> vMerkleTree;
898
899
900     CBlock()
901     {
902         SetNull();
903     }
904
905     IMPLEMENT_SERIALIZE
906     (
907         READWRITE(this->nVersion);
908         nVersion = this->nVersion;
909         READWRITE(hashPrevBlock);
910         READWRITE(hashMerkleRoot);
911         READWRITE(nTime);
912         READWRITE(nBits);
913         READWRITE(nNonce);
914
915         // ConnectBlock depends on vtx being last so it can calculate offset
916         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
917             READWRITE(vtx);
918         else if (fRead)
919             const_cast<CBlock*>(this)->vtx.clear();
920     )
921
922     void SetNull()
923     {
924         nVersion = 1;
925         hashPrevBlock = 0;
926         hashMerkleRoot = 0;
927         nTime = 0;
928         nBits = 0;
929         nNonce = 0;
930         vtx.clear();
931         vMerkleTree.clear();
932     }
933
934     bool IsNull() const
935     {
936         return (nBits == 0);
937     }
938
939     uint256 GetHash() const
940     {
941         return Hash(BEGIN(nVersion), END(nNonce));
942     }
943
944     int64 GetBlockTime() const
945     {
946         return (int64)nTime;
947     }
948
949
950     uint256 BuildMerkleTree() const
951     {
952         vMerkleTree.clear();
953         foreach(const CTransaction& tx, vtx)
954             vMerkleTree.push_back(tx.GetHash());
955         int j = 0;
956         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
957         {
958             for (int i = 0; i < nSize; i += 2)
959             {
960                 int i2 = min(i+1, nSize-1);
961                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
962                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
963             }
964             j += nSize;
965         }
966         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
967     }
968
969     vector<uint256> GetMerkleBranch(int nIndex) const
970     {
971         if (vMerkleTree.empty())
972             BuildMerkleTree();
973         vector<uint256> vMerkleBranch;
974         int j = 0;
975         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
976         {
977             int i = min(nIndex^1, nSize-1);
978             vMerkleBranch.push_back(vMerkleTree[j+i]);
979             nIndex >>= 1;
980             j += nSize;
981         }
982         return vMerkleBranch;
983     }
984
985     static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)
986     {
987         if (nIndex == -1)
988             return 0;
989         foreach(const uint256& otherside, vMerkleBranch)
990         {
991             if (nIndex & 1)
992                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
993             else
994                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
995             nIndex >>= 1;
996         }
997         return hash;
998     }
999
1000
1001     bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet)
1002     {
1003         // Open history file to append
1004         CAutoFile fileout = AppendBlockFile(nFileRet);
1005         if (!fileout)
1006             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
1007         if (!fWriteTransactions)
1008             fileout.nType |= SER_BLOCKHEADERONLY;
1009
1010         // Write index header
1011         unsigned int nSize = fileout.GetSerializeSize(*this);
1012         fileout << FLATDATA(pchMessageStart) << nSize;
1013
1014         // Write block
1015         nBlockPosRet = ftell(fileout);
1016         if (nBlockPosRet == -1)
1017             return error("CBlock::WriteToDisk() : ftell failed");
1018         fileout << *this;
1019
1020         // Flush stdio buffers and commit to disk before returning
1021         fflush(fileout);
1022         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
1023         {
1024 #ifdef __WXMSW__
1025             _commit(_fileno(fileout));
1026 #else
1027             fsync(fileno(fileout));
1028 #endif
1029         }
1030
1031         return true;
1032     }
1033
1034     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
1035     {
1036         SetNull();
1037
1038         // Open history file to read
1039         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
1040         if (!filein)
1041             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
1042         if (!fReadTransactions)
1043             filein.nType |= SER_BLOCKHEADERONLY;
1044
1045         // Read block
1046         filein >> *this;
1047
1048         // Check the header
1049         if (!CheckProofOfWork(GetHash(), nBits))
1050             return error("CBlock::ReadFromDisk() : errors in block header");
1051
1052         return true;
1053     }
1054
1055
1056
1057     void print() const
1058     {
1059         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1060             GetHash().ToString().substr(0,20).c_str(),
1061             nVersion,
1062             hashPrevBlock.ToString().substr(0,20).c_str(),
1063             hashMerkleRoot.ToString().substr(0,6).c_str(),
1064             nTime, nBits, nNonce,
1065             vtx.size());
1066         for (int i = 0; i < vtx.size(); i++)
1067         {
1068             printf("  ");
1069             vtx[i].print();
1070         }
1071         printf("  vMerkleTree: ");
1072         for (int i = 0; i < vMerkleTree.size(); i++)
1073             printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str());
1074         printf("\n");
1075     }
1076
1077
1078     int64 GetBlockValue(int nHeight, int64 nFees) const;
1079     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1080     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1081     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1082     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1083     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1084     bool CheckBlock() const;
1085     bool AcceptBlock();
1086 };
1087
1088
1089
1090
1091
1092
1093 //
1094 // The block chain is a tree shaped structure starting with the
1095 // genesis block at the root, with each block potentially having multiple
1096 // candidates to be the next block.  pprev and pnext link a path through the
1097 // main/longest chain.  A blockindex may have multiple pprev pointing back
1098 // to it, but pnext will only point forward to the longest branch, or will
1099 // be null if the block is not part of the longest chain.
1100 //
1101 class CBlockIndex
1102 {
1103 public:
1104     const uint256* phashBlock;
1105     CBlockIndex* pprev;
1106     CBlockIndex* pnext;
1107     unsigned int nFile;
1108     unsigned int nBlockPos;
1109     int nHeight;
1110     CBigNum bnChainWork;
1111
1112     // block header
1113     int nVersion;
1114     uint256 hashMerkleRoot;
1115     unsigned int nTime;
1116     unsigned int nBits;
1117     unsigned int nNonce;
1118
1119
1120     CBlockIndex()
1121     {
1122         phashBlock = NULL;
1123         pprev = NULL;
1124         pnext = NULL;
1125         nFile = 0;
1126         nBlockPos = 0;
1127         nHeight = 0;
1128         bnChainWork = 0;
1129
1130         nVersion       = 0;
1131         hashMerkleRoot = 0;
1132         nTime          = 0;
1133         nBits          = 0;
1134         nNonce         = 0;
1135     }
1136
1137     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1138     {
1139         phashBlock = NULL;
1140         pprev = NULL;
1141         pnext = NULL;
1142         nFile = nFileIn;
1143         nBlockPos = nBlockPosIn;
1144         nHeight = 0;
1145         bnChainWork = 0;
1146
1147         nVersion       = block.nVersion;
1148         hashMerkleRoot = block.hashMerkleRoot;
1149         nTime          = block.nTime;
1150         nBits          = block.nBits;
1151         nNonce         = block.nNonce;
1152     }
1153
1154     uint256 GetBlockHash() const
1155     {
1156         return *phashBlock;
1157     }
1158
1159     int64 GetBlockTime() const
1160     {
1161         return (int64)nTime;
1162     }
1163
1164     CBigNum GetBlockWork() const
1165     {
1166         if (CBigNum().SetCompact(nBits) <= 0)
1167             return 0;
1168         return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1);
1169     }
1170
1171     bool IsInMainChain() const
1172     {
1173         return (pnext || this == pindexBest);
1174     }
1175
1176     bool CheckIndex() const
1177     {
1178         return CheckProofOfWork(GetBlockHash(), nBits);
1179     }
1180
1181     bool EraseBlockFromDisk()
1182     {
1183         // Open history file
1184         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1185         if (!fileout)
1186             return false;
1187
1188         // Overwrite with empty null block
1189         CBlock block;
1190         block.SetNull();
1191         fileout << block;
1192
1193         return true;
1194     }
1195
1196     enum { nMedianTimeSpan=11 };
1197
1198     int64 GetMedianTimePast() const
1199     {
1200         int64 pmedian[nMedianTimeSpan];
1201         int64* pbegin = &pmedian[nMedianTimeSpan];
1202         int64* pend = &pmedian[nMedianTimeSpan];
1203
1204         const CBlockIndex* pindex = this;
1205         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1206             *(--pbegin) = pindex->GetBlockTime();
1207
1208         sort(pbegin, pend);
1209         return pbegin[(pend - pbegin)/2];
1210     }
1211
1212     int64 GetMedianTime() const
1213     {
1214         const CBlockIndex* pindex = this;
1215         for (int i = 0; i < nMedianTimeSpan/2; i++)
1216         {
1217             if (!pindex->pnext)
1218                 return GetBlockTime();
1219             pindex = pindex->pnext;
1220         }
1221         return pindex->GetMedianTimePast();
1222     }
1223
1224
1225
1226     string ToString() const
1227     {
1228         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1229             pprev, pnext, nFile, nBlockPos, nHeight,
1230             hashMerkleRoot.ToString().substr(0,6).c_str(),
1231             GetBlockHash().ToString().substr(0,20).c_str());
1232     }
1233
1234     void print() const
1235     {
1236         printf("%s\n", ToString().c_str());
1237     }
1238 };
1239
1240
1241
1242 //
1243 // Used to marshal pointers into hashes for db storage.
1244 //
1245 class CDiskBlockIndex : public CBlockIndex
1246 {
1247 public:
1248     uint256 hashPrev;
1249     uint256 hashNext;
1250
1251     CDiskBlockIndex()
1252     {
1253         hashPrev = 0;
1254         hashNext = 0;
1255     }
1256
1257     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1258     {
1259         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1260         hashNext = (pnext ? pnext->GetBlockHash() : 0);
1261     }
1262
1263     IMPLEMENT_SERIALIZE
1264     (
1265         if (!(nType & SER_GETHASH))
1266             READWRITE(nVersion);
1267
1268         READWRITE(hashNext);
1269         READWRITE(nFile);
1270         READWRITE(nBlockPos);
1271         READWRITE(nHeight);
1272
1273         // block header
1274         READWRITE(this->nVersion);
1275         READWRITE(hashPrev);
1276         READWRITE(hashMerkleRoot);
1277         READWRITE(nTime);
1278         READWRITE(nBits);
1279         READWRITE(nNonce);
1280     )
1281
1282     uint256 GetBlockHash() const
1283     {
1284         CBlock block;
1285         block.nVersion        = nVersion;
1286         block.hashPrevBlock   = hashPrev;
1287         block.hashMerkleRoot  = hashMerkleRoot;
1288         block.nTime           = nTime;
1289         block.nBits           = nBits;
1290         block.nNonce          = nNonce;
1291         return block.GetHash();
1292     }
1293
1294
1295     string ToString() const
1296     {
1297         string str = "CDiskBlockIndex(";
1298         str += CBlockIndex::ToString();
1299         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
1300             GetBlockHash().ToString().c_str(),
1301             hashPrev.ToString().substr(0,20).c_str(),
1302             hashNext.ToString().substr(0,20).c_str());
1303         return str;
1304     }
1305
1306     void print() const
1307     {
1308         printf("%s\n", ToString().c_str());
1309     }
1310 };
1311
1312
1313
1314
1315
1316
1317
1318
1319 //
1320 // Describes a place in the block chain to another node such that if the
1321 // other node doesn't have the same branch, it can find a recent common trunk.
1322 // The further back it is, the further before the fork it may be.
1323 //
1324 class CBlockLocator
1325 {
1326 protected:
1327     vector<uint256> vHave;
1328 public:
1329
1330     CBlockLocator()
1331     {
1332     }
1333
1334     explicit CBlockLocator(const CBlockIndex* pindex)
1335     {
1336         Set(pindex);
1337     }
1338
1339     explicit CBlockLocator(uint256 hashBlock)
1340     {
1341         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1342         if (mi != mapBlockIndex.end())
1343             Set((*mi).second);
1344     }
1345
1346     IMPLEMENT_SERIALIZE
1347     (
1348         if (!(nType & SER_GETHASH))
1349             READWRITE(nVersion);
1350         READWRITE(vHave);
1351     )
1352
1353     void Set(const CBlockIndex* pindex)
1354     {
1355         vHave.clear();
1356         int nStep = 1;
1357         while (pindex)
1358         {
1359             vHave.push_back(pindex->GetBlockHash());
1360
1361             // Exponentially larger steps back
1362             for (int i = 0; pindex && i < nStep; i++)
1363                 pindex = pindex->pprev;
1364             if (vHave.size() > 10)
1365                 nStep *= 2;
1366         }
1367         vHave.push_back(hashGenesisBlock);
1368     }
1369
1370     int GetDistanceBack()
1371     {
1372         // Retrace how far back it was in the sender's branch
1373         int nDistance = 0;
1374         int nStep = 1;
1375         foreach(const uint256& hash, vHave)
1376         {
1377             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1378             if (mi != mapBlockIndex.end())
1379             {
1380                 CBlockIndex* pindex = (*mi).second;
1381                 if (pindex->IsInMainChain())
1382                     return nDistance;
1383             }
1384             nDistance += nStep;
1385             if (nDistance > 10)
1386                 nStep *= 2;
1387         }
1388         return nDistance;
1389     }
1390
1391     CBlockIndex* GetBlockIndex()
1392     {
1393         // Find the first block the caller has in the main chain
1394         foreach(const uint256& hash, vHave)
1395         {
1396             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1397             if (mi != mapBlockIndex.end())
1398             {
1399                 CBlockIndex* pindex = (*mi).second;
1400                 if (pindex->IsInMainChain())
1401                     return pindex;
1402             }
1403         }
1404         return pindexGenesisBlock;
1405     }
1406
1407     uint256 GetBlockHash()
1408     {
1409         // Find the first block the caller has in the main chain
1410         foreach(const uint256& hash, vHave)
1411         {
1412             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1413             if (mi != mapBlockIndex.end())
1414             {
1415                 CBlockIndex* pindex = (*mi).second;
1416                 if (pindex->IsInMainChain())
1417                     return hash;
1418             }
1419         }
1420         return hashGenesisBlock;
1421     }
1422
1423     int GetHeight()
1424     {
1425         CBlockIndex* pindex = GetBlockIndex();
1426         if (!pindex)
1427             return 0;
1428         return pindex->nHeight;
1429     }
1430 };
1431
1432
1433
1434
1435
1436
1437 //
1438 // Private key that includes an expiration date in case it never gets used.
1439 //
1440 class CWalletKey
1441 {
1442 public:
1443     CPrivKey vchPrivKey;
1444     int64 nTimeCreated;
1445     int64 nTimeExpires;
1446     string strComment;
1447     //// todo: add something to note what created it (user, getnewaddress, change)
1448     ////   maybe should have a map<string, string> property map
1449
1450     CWalletKey(int64 nTimeExpiresIn=0)
1451     {
1452         nTimeCreated = (nTimeExpiresIn ? GetTime() : 0);
1453         nTimeExpires = nTimeExpiresIn;
1454     }
1455
1456     IMPLEMENT_SERIALIZE
1457     (
1458         if (!(nType & SER_GETHASH))
1459             READWRITE(nVersion);
1460         READWRITE(vchPrivKey);
1461         READWRITE(nTimeCreated);
1462         READWRITE(nTimeExpires);
1463         READWRITE(strComment);
1464     )
1465 };
1466
1467
1468
1469
1470
1471
1472 extern map<uint256, CTransaction> mapTransactions;
1473 extern map<uint256, CWalletTx> mapWallet;
1474 extern vector<uint256> vWalletUpdated;
1475 extern CCriticalSection cs_mapWallet;
1476 extern map<vector<unsigned char>, CPrivKey> mapKeys;
1477 extern map<uint160, vector<unsigned char> > mapPubKeys;
1478 extern CCriticalSection cs_mapKeys;
1479 extern CKey keyUser;