Update License in File Headers
[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 COPYING 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 (unsigned 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 (unsigned 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         {
576             BOOST_FOREACH(const CTxOut& txout, vout)
577                 if (txout.nValue < CENT)
578                     nMinFee = nBaseFee;
579         }
580
581         // Raise the price as the block approaches full
582         if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
583         {
584             if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
585                 return MAX_MONEY;
586             nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
587         }
588
589         if (!MoneyRange(nMinFee))
590             nMinFee = MAX_MONEY;
591         return nMinFee;
592     }
593
594
595     bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
596     {
597         CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
598         if (!filein)
599             return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
600
601         // Read transaction
602         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
603             return error("CTransaction::ReadFromDisk() : fseek failed");
604         filein >> *this;
605
606         // Return file pointer
607         if (pfileRet)
608         {
609             if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
610                 return error("CTransaction::ReadFromDisk() : second fseek failed");
611             *pfileRet = filein.release();
612         }
613         return true;
614     }
615
616     friend bool operator==(const CTransaction& a, const CTransaction& b)
617     {
618         return (a.nVersion  == b.nVersion &&
619                 a.vin       == b.vin &&
620                 a.vout      == b.vout &&
621                 a.nLockTime == b.nLockTime);
622     }
623
624     friend bool operator!=(const CTransaction& a, const CTransaction& b)
625     {
626         return !(a == b);
627     }
628
629
630     std::string ToString() const
631     {
632         std::string str;
633         str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
634             GetHash().ToString().substr(0,10).c_str(),
635             nVersion,
636             vin.size(),
637             vout.size(),
638             nLockTime);
639         for (unsigned int i = 0; i < vin.size(); i++)
640             str += "    " + vin[i].ToString() + "\n";
641         for (unsigned int i = 0; i < vout.size(); i++)
642             str += "    " + vout[i].ToString() + "\n";
643         return str;
644     }
645
646     void print() const
647     {
648         printf("%s", ToString().c_str());
649     }
650
651
652     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
653     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
654     bool ReadFromDisk(COutPoint prevout);
655     bool DisconnectInputs(CTxDB& txdb);
656
657     /** Fetch from memory and/or disk. inputsRet keys are transaction hashes.
658
659      @param[in] txdb    Transaction database
660      @param[in] mapTestPool     List of pending changes to the transaction index database
661      @param[in] fBlock  True if being called to add a new best-block to the chain
662      @param[in] fMiner  True if being called by CreateNewBlock
663      @param[out] inputsRet      Pointers to this transaction's inputs
664      @param[out] fInvalid       returns true if transaction is invalid
665      @return    Returns true if all inputs are in txdb or mapTestPool
666      */
667     bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
668                      bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid);
669
670     /** Sanity check previous transactions, then, if all checks succeed,
671         mark them as spent by this transaction.
672
673         @param[in] inputsPrevious transactions (from FetchInputs)
674         @param[out] mapTestPoolKeeps track of inputs that need to be updated on disk
675         @param[in] posThisTxPosition of this transaction on disk
676         @param[in] pindexBlock
677         @param[in] fBlock  true if called from ConnectBlock
678         @param[in] fMiner  true if called from CreateNewBlock
679         @param[in] fStrictPayToScriptHash  true if fully validating p2sh transactions
680         @return Returns true if all checks succeed
681     */
682     bool ConnectInputs(MapPrevTx inputs,
683                        std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
684                        const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true);
685     bool ClientConnectInputs();
686     bool CheckTransaction() const;
687     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
688     bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
689 protected:
690     const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
691     bool AddToMemoryPoolUnchecked();
692 public:
693     bool RemoveFromMemoryPool();
694 };
695
696
697
698
699
700 //
701 // A transaction with a merkle branch linking it to the block chain
702 //
703 class CMerkleTx : public CTransaction
704 {
705 public:
706     uint256 hashBlock;
707     std::vector<uint256> vMerkleBranch;
708     int nIndex;
709
710     // memory only
711     mutable char fMerkleVerified;
712
713
714     CMerkleTx()
715     {
716         Init();
717     }
718
719     CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
720     {
721         Init();
722     }
723
724     void Init()
725     {
726         hashBlock = 0;
727         nIndex = -1;
728         fMerkleVerified = false;
729     }
730
731
732     IMPLEMENT_SERIALIZE
733     (
734         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
735         nVersion = this->nVersion;
736         READWRITE(hashBlock);
737         READWRITE(vMerkleBranch);
738         READWRITE(nIndex);
739     )
740
741
742     int SetMerkleBranch(const CBlock* pblock=NULL);
743     int GetDepthInMainChain(int& nHeightRet) const;
744     int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
745     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
746     int GetBlocksToMaturity() const;
747     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
748     bool AcceptToMemoryPool();
749 };
750
751
752
753
754 //
755 // A txdb record that contains the disk location of a transaction and the
756 // locations of transactions that spend its outputs.  vSpent is really only
757 // used as a flag, but having the location is very helpful for debugging.
758 //
759 class CTxIndex
760 {
761 public:
762     CDiskTxPos pos;
763     std::vector<CDiskTxPos> vSpent;
764
765     CTxIndex()
766     {
767         SetNull();
768     }
769
770     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
771     {
772         pos = posIn;
773         vSpent.resize(nOutputs);
774     }
775
776     IMPLEMENT_SERIALIZE
777     (
778         if (!(nType & SER_GETHASH))
779             READWRITE(nVersion);
780         READWRITE(pos);
781         READWRITE(vSpent);
782     )
783
784     void SetNull()
785     {
786         pos.SetNull();
787         vSpent.clear();
788     }
789
790     bool IsNull()
791     {
792         return pos.IsNull();
793     }
794
795     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
796     {
797         return (a.pos    == b.pos &&
798                 a.vSpent == b.vSpent);
799     }
800
801     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
802     {
803         return !(a == b);
804     }
805     int GetDepthInMainChain() const;
806 };
807
808
809
810
811
812 //
813 // Nodes collect new transactions into a block, hash them into a hash tree,
814 // and scan through nonce values to make the block's hash satisfy proof-of-work
815 // requirements.  When they solve the proof-of-work, they broadcast the block
816 // to everyone and the block is added to the block chain.  The first transaction
817 // in the block is a special one that creates a new coin owned by the creator
818 // of the block.
819 //
820 // Blocks are appended to blk0001.dat files on disk.  Their location on disk
821 // is indexed by CBlockIndex objects in memory.
822 //
823 class CBlock
824 {
825 public:
826     // header
827     int nVersion;
828     uint256 hashPrevBlock;
829     uint256 hashMerkleRoot;
830     unsigned int nTime;
831     unsigned int nBits;
832     unsigned int nNonce;
833
834     // network and disk
835     std::vector<CTransaction> vtx;
836
837     // memory only
838     mutable std::vector<uint256> vMerkleTree;
839
840
841     CBlock()
842     {
843         SetNull();
844     }
845
846     IMPLEMENT_SERIALIZE
847     (
848         READWRITE(this->nVersion);
849         nVersion = this->nVersion;
850         READWRITE(hashPrevBlock);
851         READWRITE(hashMerkleRoot);
852         READWRITE(nTime);
853         READWRITE(nBits);
854         READWRITE(nNonce);
855
856         // ConnectBlock depends on vtx being last so it can calculate offset
857         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
858             READWRITE(vtx);
859         else if (fRead)
860             const_cast<CBlock*>(this)->vtx.clear();
861     )
862
863     void SetNull()
864     {
865         nVersion = 1;
866         hashPrevBlock = 0;
867         hashMerkleRoot = 0;
868         nTime = 0;
869         nBits = 0;
870         nNonce = 0;
871         vtx.clear();
872         vMerkleTree.clear();
873     }
874
875     bool IsNull() const
876     {
877         return (nBits == 0);
878     }
879
880     uint256 GetHash() const
881     {
882         return Hash(BEGIN(nVersion), END(nNonce));
883     }
884
885     int64 GetBlockTime() const
886     {
887         return (int64)nTime;
888     }
889
890     int GetSigOpCount() const
891     {
892         int n = 0;
893         BOOST_FOREACH(const CTransaction& tx, vtx)
894             n += tx.GetSigOpCount();
895         return n;
896     }
897
898     void UpdateTime(const CBlockIndex* pindexPrev);
899
900
901     uint256 BuildMerkleTree() const
902     {
903         vMerkleTree.clear();
904         BOOST_FOREACH(const CTransaction& tx, vtx)
905             vMerkleTree.push_back(tx.GetHash());
906         int j = 0;
907         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
908         {
909             for (int i = 0; i < nSize; i += 2)
910             {
911                 int i2 = std::min(i+1, nSize-1);
912                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
913                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
914             }
915             j += nSize;
916         }
917         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
918     }
919
920     std::vector<uint256> GetMerkleBranch(int nIndex) const
921     {
922         if (vMerkleTree.empty())
923             BuildMerkleTree();
924         std::vector<uint256> vMerkleBranch;
925         int j = 0;
926         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
927         {
928             int i = std::min(nIndex^1, nSize-1);
929             vMerkleBranch.push_back(vMerkleTree[j+i]);
930             nIndex >>= 1;
931             j += nSize;
932         }
933         return vMerkleBranch;
934     }
935
936     static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
937     {
938         if (nIndex == -1)
939             return 0;
940         BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
941         {
942             if (nIndex & 1)
943                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
944             else
945                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
946             nIndex >>= 1;
947         }
948         return hash;
949     }
950
951
952     bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
953     {
954         // Open history file to append
955         CAutoFile fileout = AppendBlockFile(nFileRet);
956         if (!fileout)
957             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
958
959         // Write index header
960         unsigned int nSize = fileout.GetSerializeSize(*this);
961         fileout << FLATDATA(pchMessageStart) << nSize;
962
963         // Write block
964         long fileOutPos = ftell(fileout);
965         if (fileOutPos < 0)
966             return error("CBlock::WriteToDisk() : ftell failed");
967         nBlockPosRet = fileOutPos;
968         fileout << *this;
969
970         // Flush stdio buffers and commit to disk before returning
971         fflush(fileout);
972         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
973         {
974 #ifdef __WXMSW__
975             _commit(_fileno(fileout));
976 #else
977             fsync(fileno(fileout));
978 #endif
979         }
980
981         return true;
982     }
983
984     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
985     {
986         SetNull();
987
988         // Open history file to read
989         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
990         if (!filein)
991             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
992         if (!fReadTransactions)
993             filein.nType |= SER_BLOCKHEADERONLY;
994
995         // Read block
996         filein >> *this;
997
998         // Check the header
999         if (!CheckProofOfWork(GetHash(), nBits))
1000             return error("CBlock::ReadFromDisk() : errors in block header");
1001
1002         return true;
1003     }
1004
1005
1006
1007     void print() const
1008     {
1009         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1010             GetHash().ToString().substr(0,20).c_str(),
1011             nVersion,
1012             hashPrevBlock.ToString().substr(0,20).c_str(),
1013             hashMerkleRoot.ToString().substr(0,10).c_str(),
1014             nTime, nBits, nNonce,
1015             vtx.size());
1016         for (unsigned int i = 0; i < vtx.size(); i++)
1017         {
1018             printf("  ");
1019             vtx[i].print();
1020         }
1021         printf("  vMerkleTree: ");
1022         for (unsigned int i = 0; i < vMerkleTree.size(); i++)
1023             printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
1024         printf("\n");
1025     }
1026
1027
1028     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1029     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1030     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1031     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1032     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1033     bool CheckBlock() const;
1034     bool AcceptBlock();
1035 };
1036
1037
1038
1039
1040
1041
1042 //
1043 // The block chain is a tree shaped structure starting with the
1044 // genesis block at the root, with each block potentially having multiple
1045 // candidates to be the next block.  pprev and pnext link a path through the
1046 // main/longest chain.  A blockindex may have multiple pprev pointing back
1047 // to it, but pnext will only point forward to the longest branch, or will
1048 // be null if the block is not part of the longest chain.
1049 //
1050 class CBlockIndex
1051 {
1052 public:
1053     const uint256* phashBlock;
1054     CBlockIndex* pprev;
1055     CBlockIndex* pnext;
1056     unsigned int nFile;
1057     unsigned int nBlockPos;
1058     int nHeight;
1059     CBigNum bnChainWork;
1060
1061     // block header
1062     int nVersion;
1063     uint256 hashMerkleRoot;
1064     unsigned int nTime;
1065     unsigned int nBits;
1066     unsigned int nNonce;
1067
1068
1069     CBlockIndex()
1070     {
1071         phashBlock = NULL;
1072         pprev = NULL;
1073         pnext = NULL;
1074         nFile = 0;
1075         nBlockPos = 0;
1076         nHeight = 0;
1077         bnChainWork = 0;
1078
1079         nVersion       = 0;
1080         hashMerkleRoot = 0;
1081         nTime          = 0;
1082         nBits          = 0;
1083         nNonce         = 0;
1084     }
1085
1086     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1087     {
1088         phashBlock = NULL;
1089         pprev = NULL;
1090         pnext = NULL;
1091         nFile = nFileIn;
1092         nBlockPos = nBlockPosIn;
1093         nHeight = 0;
1094         bnChainWork = 0;
1095
1096         nVersion       = block.nVersion;
1097         hashMerkleRoot = block.hashMerkleRoot;
1098         nTime          = block.nTime;
1099         nBits          = block.nBits;
1100         nNonce         = block.nNonce;
1101     }
1102
1103     CBlock GetBlockHeader() const
1104     {
1105         CBlock block;
1106         block.nVersion       = nVersion;
1107         if (pprev)
1108             block.hashPrevBlock = pprev->GetBlockHash();
1109         block.hashMerkleRoot = hashMerkleRoot;
1110         block.nTime          = nTime;
1111         block.nBits          = nBits;
1112         block.nNonce         = nNonce;
1113         return block;
1114     }
1115
1116     uint256 GetBlockHash() const
1117     {
1118         return *phashBlock;
1119     }
1120
1121     int64 GetBlockTime() const
1122     {
1123         return (int64)nTime;
1124     }
1125
1126     CBigNum GetBlockWork() const
1127     {
1128         CBigNum bnTarget;
1129         bnTarget.SetCompact(nBits);
1130         if (bnTarget <= 0)
1131             return 0;
1132         return (CBigNum(1)<<256) / (bnTarget+1);
1133     }
1134
1135     bool IsInMainChain() const
1136     {
1137         return (pnext || this == pindexBest);
1138     }
1139
1140     bool CheckIndex() const
1141     {
1142         return CheckProofOfWork(GetBlockHash(), nBits);
1143     }
1144
1145     bool EraseBlockFromDisk()
1146     {
1147         // Open history file
1148         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1149         if (!fileout)
1150             return false;
1151
1152         // Overwrite with empty null block
1153         CBlock block;
1154         block.SetNull();
1155         fileout << block;
1156
1157         return true;
1158     }
1159
1160     enum { nMedianTimeSpan=11 };
1161
1162     int64 GetMedianTimePast() const
1163     {
1164         int64 pmedian[nMedianTimeSpan];
1165         int64* pbegin = &pmedian[nMedianTimeSpan];
1166         int64* pend = &pmedian[nMedianTimeSpan];
1167
1168         const CBlockIndex* pindex = this;
1169         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1170             *(--pbegin) = pindex->GetBlockTime();
1171
1172         std::sort(pbegin, pend);
1173         return pbegin[(pend - pbegin)/2];
1174     }
1175
1176     int64 GetMedianTime() const
1177     {
1178         const CBlockIndex* pindex = this;
1179         for (int i = 0; i < nMedianTimeSpan/2; i++)
1180         {
1181             if (!pindex->pnext)
1182                 return GetBlockTime();
1183             pindex = pindex->pnext;
1184         }
1185         return pindex->GetMedianTimePast();
1186     }
1187
1188
1189
1190     std::string ToString() const
1191     {
1192         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1193             pprev, pnext, nFile, nBlockPos, nHeight,
1194             hashMerkleRoot.ToString().substr(0,10).c_str(),
1195             GetBlockHash().ToString().substr(0,20).c_str());
1196     }
1197
1198     void print() const
1199     {
1200         printf("%s\n", ToString().c_str());
1201     }
1202 };
1203
1204
1205
1206 //
1207 // Used to marshal pointers into hashes for db storage.
1208 //
1209 class CDiskBlockIndex : public CBlockIndex
1210 {
1211 public:
1212     uint256 hashPrev;
1213     uint256 hashNext;
1214
1215     CDiskBlockIndex()
1216     {
1217         hashPrev = 0;
1218         hashNext = 0;
1219     }
1220
1221     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1222     {
1223         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1224         hashNext = (pnext ? pnext->GetBlockHash() : 0);
1225     }
1226
1227     IMPLEMENT_SERIALIZE
1228     (
1229         if (!(nType & SER_GETHASH))
1230             READWRITE(nVersion);
1231
1232         READWRITE(hashNext);
1233         READWRITE(nFile);
1234         READWRITE(nBlockPos);
1235         READWRITE(nHeight);
1236
1237         // block header
1238         READWRITE(this->nVersion);
1239         READWRITE(hashPrev);
1240         READWRITE(hashMerkleRoot);
1241         READWRITE(nTime);
1242         READWRITE(nBits);
1243         READWRITE(nNonce);
1244     )
1245
1246     uint256 GetBlockHash() const
1247     {
1248         CBlock block;
1249         block.nVersion        = nVersion;
1250         block.hashPrevBlock   = hashPrev;
1251         block.hashMerkleRoot  = hashMerkleRoot;
1252         block.nTime           = nTime;
1253         block.nBits           = nBits;
1254         block.nNonce          = nNonce;
1255         return block.GetHash();
1256     }
1257
1258
1259     std::string ToString() const
1260     {
1261         std::string str = "CDiskBlockIndex(";
1262         str += CBlockIndex::ToString();
1263         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
1264             GetBlockHash().ToString().c_str(),
1265             hashPrev.ToString().substr(0,20).c_str(),
1266             hashNext.ToString().substr(0,20).c_str());
1267         return str;
1268     }
1269
1270     void print() const
1271     {
1272         printf("%s\n", ToString().c_str());
1273     }
1274 };
1275
1276
1277
1278
1279
1280
1281
1282
1283 //
1284 // Describes a place in the block chain to another node such that if the
1285 // other node doesn't have the same branch, it can find a recent common trunk.
1286 // The further back it is, the further before the fork it may be.
1287 //
1288 class CBlockLocator
1289 {
1290 protected:
1291     std::vector<uint256> vHave;
1292 public:
1293
1294     CBlockLocator()
1295     {
1296     }
1297
1298     explicit CBlockLocator(const CBlockIndex* pindex)
1299     {
1300         Set(pindex);
1301     }
1302
1303     explicit CBlockLocator(uint256 hashBlock)
1304     {
1305         std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1306         if (mi != mapBlockIndex.end())
1307             Set((*mi).second);
1308     }
1309
1310     IMPLEMENT_SERIALIZE
1311     (
1312         if (!(nType & SER_GETHASH))
1313             READWRITE(nVersion);
1314         READWRITE(vHave);
1315     )
1316
1317     void SetNull()
1318     {
1319         vHave.clear();
1320     }
1321
1322     bool IsNull()
1323     {
1324         return vHave.empty();
1325     }
1326
1327     void Set(const CBlockIndex* pindex)
1328     {
1329         vHave.clear();
1330         int nStep = 1;
1331         while (pindex)
1332         {
1333             vHave.push_back(pindex->GetBlockHash());
1334
1335             // Exponentially larger steps back
1336             for (int i = 0; pindex && i < nStep; i++)
1337                 pindex = pindex->pprev;
1338             if (vHave.size() > 10)
1339                 nStep *= 2;
1340         }
1341         vHave.push_back(hashGenesisBlock);
1342     }
1343
1344     int GetDistanceBack()
1345     {
1346         // Retrace how far back it was in the sender's branch
1347         int nDistance = 0;
1348         int nStep = 1;
1349         BOOST_FOREACH(const uint256& hash, vHave)
1350         {
1351             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1352             if (mi != mapBlockIndex.end())
1353             {
1354                 CBlockIndex* pindex = (*mi).second;
1355                 if (pindex->IsInMainChain())
1356                     return nDistance;
1357             }
1358             nDistance += nStep;
1359             if (nDistance > 10)
1360                 nStep *= 2;
1361         }
1362         return nDistance;
1363     }
1364
1365     CBlockIndex* GetBlockIndex()
1366     {
1367         // Find the first block the caller has in the main chain
1368         BOOST_FOREACH(const uint256& hash, vHave)
1369         {
1370             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1371             if (mi != mapBlockIndex.end())
1372             {
1373                 CBlockIndex* pindex = (*mi).second;
1374                 if (pindex->IsInMainChain())
1375                     return pindex;
1376             }
1377         }
1378         return pindexGenesisBlock;
1379     }
1380
1381     uint256 GetBlockHash()
1382     {
1383         // Find the first block the caller has in the main chain
1384         BOOST_FOREACH(const uint256& hash, vHave)
1385         {
1386             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1387             if (mi != mapBlockIndex.end())
1388             {
1389                 CBlockIndex* pindex = (*mi).second;
1390                 if (pindex->IsInMainChain())
1391                     return hash;
1392             }
1393         }
1394         return hashGenesisBlock;
1395     }
1396
1397     int GetHeight()
1398     {
1399         CBlockIndex* pindex = GetBlockIndex();
1400         if (!pindex)
1401             return 0;
1402         return pindex->nHeight;
1403     }
1404 };
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 //
1415 // Alerts are for notifying old versions if they become too obsolete and
1416 // need to upgrade.  The message is displayed in the status bar.
1417 // Alert messages are broadcast as a vector of signed data.  Unserializing may
1418 // not read the entire buffer if the alert is for a newer version, but older
1419 // versions can still relay the original data.
1420 //
1421 class CUnsignedAlert
1422 {
1423 public:
1424     int nVersion;
1425     int64 nRelayUntil;      // when newer nodes stop relaying to newer nodes
1426     int64 nExpiration;
1427     int nID;
1428     int nCancel;
1429     std::set<int> setCancel;
1430     int nMinVer;            // lowest version inclusive
1431     int nMaxVer;            // highest version inclusive
1432     std::set<std::string> setSubVer;  // empty matches all
1433     int nPriority;
1434
1435     // Actions
1436     std::string strComment;
1437     std::string strStatusBar;
1438     std::string strReserved;
1439
1440     IMPLEMENT_SERIALIZE
1441     (
1442         READWRITE(this->nVersion);
1443         nVersion = this->nVersion;
1444         READWRITE(nRelayUntil);
1445         READWRITE(nExpiration);
1446         READWRITE(nID);
1447         READWRITE(nCancel);
1448         READWRITE(setCancel);
1449         READWRITE(nMinVer);
1450         READWRITE(nMaxVer);
1451         READWRITE(setSubVer);
1452         READWRITE(nPriority);
1453
1454         READWRITE(strComment);
1455         READWRITE(strStatusBar);
1456         READWRITE(strReserved);
1457     )
1458
1459     void SetNull()
1460     {
1461         nVersion = 1;
1462         nRelayUntil = 0;
1463         nExpiration = 0;
1464         nID = 0;
1465         nCancel = 0;
1466         setCancel.clear();
1467         nMinVer = 0;
1468         nMaxVer = 0;
1469         setSubVer.clear();
1470         nPriority = 0;
1471
1472         strComment.clear();
1473         strStatusBar.clear();
1474         strReserved.clear();
1475     }
1476
1477     std::string ToString() const
1478     {
1479         std::string strSetCancel;
1480         BOOST_FOREACH(int n, setCancel)
1481             strSetCancel += strprintf("%d ", n);
1482         std::string strSetSubVer;
1483         BOOST_FOREACH(std::string str, setSubVer)
1484             strSetSubVer += "\"" + str + "\" ";
1485         return strprintf(
1486                 "CAlert(\n"
1487                 "    nVersion     = %d\n"
1488                 "    nRelayUntil  = %"PRI64d"\n"
1489                 "    nExpiration  = %"PRI64d"\n"
1490                 "    nID          = %d\n"
1491                 "    nCancel      = %d\n"
1492                 "    setCancel    = %s\n"
1493                 "    nMinVer      = %d\n"
1494                 "    nMaxVer      = %d\n"
1495                 "    setSubVer    = %s\n"
1496                 "    nPriority    = %d\n"
1497                 "    strComment   = \"%s\"\n"
1498                 "    strStatusBar = \"%s\"\n"
1499                 ")\n",
1500             nVersion,
1501             nRelayUntil,
1502             nExpiration,
1503             nID,
1504             nCancel,
1505             strSetCancel.c_str(),
1506             nMinVer,
1507             nMaxVer,
1508             strSetSubVer.c_str(),
1509             nPriority,
1510             strComment.c_str(),
1511             strStatusBar.c_str());
1512     }
1513
1514     void print() const
1515     {
1516         printf("%s", ToString().c_str());
1517     }
1518 };
1519
1520 class CAlert : public CUnsignedAlert
1521 {
1522 public:
1523     std::vector<unsigned char> vchMsg;
1524     std::vector<unsigned char> vchSig;
1525
1526     CAlert()
1527     {
1528         SetNull();
1529     }
1530
1531     IMPLEMENT_SERIALIZE
1532     (
1533         READWRITE(vchMsg);
1534         READWRITE(vchSig);
1535     )
1536
1537     void SetNull()
1538     {
1539         CUnsignedAlert::SetNull();
1540         vchMsg.clear();
1541         vchSig.clear();
1542     }
1543
1544     bool IsNull() const
1545     {
1546         return (nExpiration == 0);
1547     }
1548
1549     uint256 GetHash() const
1550     {
1551         return SerializeHash(*this);
1552     }
1553
1554     bool IsInEffect() const
1555     {
1556         return (GetAdjustedTime() < nExpiration);
1557     }
1558
1559     bool Cancels(const CAlert& alert) const
1560     {
1561         if (!IsInEffect())
1562             return false; // this was a no-op before 31403
1563         return (alert.nID <= nCancel || setCancel.count(alert.nID));
1564     }
1565
1566     bool AppliesTo(int nVersion, std::string strSubVerIn) const
1567     {
1568         return (IsInEffect() &&
1569                 nMinVer <= nVersion && nVersion <= nMaxVer &&
1570                 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
1571     }
1572
1573     bool AppliesToMe() const
1574     {
1575         return AppliesTo(VERSION, ::pszSubVer);
1576     }
1577
1578     bool RelayTo(CNode* pnode) const
1579     {
1580         if (!IsInEffect())
1581             return false;
1582         // returns true if wasn't already contained in the set
1583         if (pnode->setKnown.insert(GetHash()).second)
1584         {
1585             if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
1586                 AppliesToMe() ||
1587                 GetAdjustedTime() < nRelayUntil)
1588             {
1589                 pnode->PushMessage("alert", *this);
1590                 return true;
1591             }
1592         }
1593         return false;
1594     }
1595
1596     bool CheckSignature()
1597     {
1598         CKey key;
1599         if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
1600             return error("CAlert::CheckSignature() : SetPubKey failed");
1601         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
1602             return error("CAlert::CheckSignature() : verify signature failed");
1603
1604         // Now unserialize the data
1605         CDataStream sMsg(vchMsg);
1606         sMsg >> *(CUnsignedAlert*)this;
1607         return true;
1608     }
1609
1610     bool ProcessAlert();
1611 };
1612
1613 #endif