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