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