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