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