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