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