4b7e1948fcaf00bb4d24f83f316fd51ad6ae3bc5
[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         long fileOutPos = ftell(fileout);
975         if (fileOutPos < 0)
976             return error("CBlock::WriteToDisk() : ftell failed");
977         nBlockPosRet = fileOutPos;
978         fileout << *this;
979
980         // Flush stdio buffers and commit to disk before returning
981         fflush(fileout);
982         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
983         {
984 #ifdef WIN32
985             _commit(_fileno(fileout));
986 #else
987             fsync(fileno(fileout));
988 #endif
989         }
990
991         return true;
992     }
993
994     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
995     {
996         SetNull();
997
998         // Open history file to read
999         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
1000         if (!filein)
1001             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
1002         if (!fReadTransactions)
1003             filein.nType |= SER_BLOCKHEADERONLY;
1004
1005         // Read block
1006         filein >> *this;
1007
1008         // Check the header
1009         if (!CheckProofOfWork(GetHash(), nBits))
1010             return error("CBlock::ReadFromDisk() : errors in block header");
1011
1012         return true;
1013     }
1014
1015
1016
1017     void print() const
1018     {
1019         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1020             GetHash().ToString().substr(0,20).c_str(),
1021             nVersion,
1022             hashPrevBlock.ToString().substr(0,20).c_str(),
1023             hashMerkleRoot.ToString().substr(0,10).c_str(),
1024             nTime, nBits, nNonce,
1025             vtx.size());
1026         for (unsigned int i = 0; i < vtx.size(); i++)
1027         {
1028             printf("  ");
1029             vtx[i].print();
1030         }
1031         printf("  vMerkleTree: ");
1032         for (unsigned int i = 0; i < vMerkleTree.size(); i++)
1033             printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
1034         printf("\n");
1035     }
1036
1037
1038     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1039     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1040     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1041     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1042     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1043     bool CheckBlock() const;
1044     bool AcceptBlock();
1045 };
1046
1047
1048
1049
1050
1051
1052 //
1053 // The block chain is a tree shaped structure starting with the
1054 // genesis block at the root, with each block potentially having multiple
1055 // candidates to be the next block.  pprev and pnext link a path through the
1056 // main/longest chain.  A blockindex may have multiple pprev pointing back
1057 // to it, but pnext will only point forward to the longest branch, or will
1058 // be null if the block is not part of the longest chain.
1059 //
1060 class CBlockIndex
1061 {
1062 public:
1063     const uint256* phashBlock;
1064     CBlockIndex* pprev;
1065     CBlockIndex* pnext;
1066     unsigned int nFile;
1067     unsigned int nBlockPos;
1068     int nHeight;
1069     CBigNum bnChainWork;
1070
1071     // block header
1072     int nVersion;
1073     uint256 hashMerkleRoot;
1074     unsigned int nTime;
1075     unsigned int nBits;
1076     unsigned int nNonce;
1077
1078
1079     CBlockIndex()
1080     {
1081         phashBlock = NULL;
1082         pprev = NULL;
1083         pnext = NULL;
1084         nFile = 0;
1085         nBlockPos = 0;
1086         nHeight = 0;
1087         bnChainWork = 0;
1088
1089         nVersion       = 0;
1090         hashMerkleRoot = 0;
1091         nTime          = 0;
1092         nBits          = 0;
1093         nNonce         = 0;
1094     }
1095
1096     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1097     {
1098         phashBlock = NULL;
1099         pprev = NULL;
1100         pnext = NULL;
1101         nFile = nFileIn;
1102         nBlockPos = nBlockPosIn;
1103         nHeight = 0;
1104         bnChainWork = 0;
1105
1106         nVersion       = block.nVersion;
1107         hashMerkleRoot = block.hashMerkleRoot;
1108         nTime          = block.nTime;
1109         nBits          = block.nBits;
1110         nNonce         = block.nNonce;
1111     }
1112
1113     CBlock GetBlockHeader() const
1114     {
1115         CBlock block;
1116         block.nVersion       = nVersion;
1117         if (pprev)
1118             block.hashPrevBlock = pprev->GetBlockHash();
1119         block.hashMerkleRoot = hashMerkleRoot;
1120         block.nTime          = nTime;
1121         block.nBits          = nBits;
1122         block.nNonce         = nNonce;
1123         return block;
1124     }
1125
1126     uint256 GetBlockHash() const
1127     {
1128         return *phashBlock;
1129     }
1130
1131     int64 GetBlockTime() const
1132     {
1133         return (int64)nTime;
1134     }
1135
1136     CBigNum GetBlockWork() const
1137     {
1138         CBigNum bnTarget;
1139         bnTarget.SetCompact(nBits);
1140         if (bnTarget <= 0)
1141             return 0;
1142         return (CBigNum(1)<<256) / (bnTarget+1);
1143     }
1144
1145     bool IsInMainChain() const
1146     {
1147         return (pnext || this == pindexBest);
1148     }
1149
1150     bool CheckIndex() const
1151     {
1152         return CheckProofOfWork(GetBlockHash(), nBits);
1153     }
1154
1155     bool EraseBlockFromDisk()
1156     {
1157         // Open history file
1158         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1159         if (!fileout)
1160             return false;
1161
1162         // Overwrite with empty null block
1163         CBlock block;
1164         block.SetNull();
1165         fileout << block;
1166
1167         return true;
1168     }
1169
1170     enum { nMedianTimeSpan=11 };
1171
1172     int64 GetMedianTimePast() const
1173     {
1174         int64 pmedian[nMedianTimeSpan];
1175         int64* pbegin = &pmedian[nMedianTimeSpan];
1176         int64* pend = &pmedian[nMedianTimeSpan];
1177
1178         const CBlockIndex* pindex = this;
1179         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1180             *(--pbegin) = pindex->GetBlockTime();
1181
1182         std::sort(pbegin, pend);
1183         return pbegin[(pend - pbegin)/2];
1184     }
1185
1186     int64 GetMedianTime() const
1187     {
1188         const CBlockIndex* pindex = this;
1189         for (int i = 0; i < nMedianTimeSpan/2; i++)
1190         {
1191             if (!pindex->pnext)
1192                 return GetBlockTime();
1193             pindex = pindex->pnext;
1194         }
1195         return pindex->GetMedianTimePast();
1196     }
1197
1198
1199
1200     std::string ToString() const
1201     {
1202         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1203             pprev, pnext, nFile, nBlockPos, nHeight,
1204             hashMerkleRoot.ToString().substr(0,10).c_str(),
1205             GetBlockHash().ToString().substr(0,20).c_str());
1206     }
1207
1208     void print() const
1209     {
1210         printf("%s\n", ToString().c_str());
1211     }
1212 };
1213
1214
1215
1216 //
1217 // Used to marshal pointers into hashes for db storage.
1218 //
1219 class CDiskBlockIndex : public CBlockIndex
1220 {
1221 public:
1222     uint256 hashPrev;
1223     uint256 hashNext;
1224
1225     CDiskBlockIndex()
1226     {
1227         hashPrev = 0;
1228         hashNext = 0;
1229     }
1230
1231     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1232     {
1233         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1234         hashNext = (pnext ? pnext->GetBlockHash() : 0);
1235     }
1236
1237     IMPLEMENT_SERIALIZE
1238     (
1239         if (!(nType & SER_GETHASH))
1240             READWRITE(nVersion);
1241
1242         READWRITE(hashNext);
1243         READWRITE(nFile);
1244         READWRITE(nBlockPos);
1245         READWRITE(nHeight);
1246
1247         // block header
1248         READWRITE(this->nVersion);
1249         READWRITE(hashPrev);
1250         READWRITE(hashMerkleRoot);
1251         READWRITE(nTime);
1252         READWRITE(nBits);
1253         READWRITE(nNonce);
1254     )
1255
1256     uint256 GetBlockHash() const
1257     {
1258         CBlock block;
1259         block.nVersion        = nVersion;
1260         block.hashPrevBlock   = hashPrev;
1261         block.hashMerkleRoot  = hashMerkleRoot;
1262         block.nTime           = nTime;
1263         block.nBits           = nBits;
1264         block.nNonce          = nNonce;
1265         return block.GetHash();
1266     }
1267
1268
1269     std::string ToString() const
1270     {
1271         std::string str = "CDiskBlockIndex(";
1272         str += CBlockIndex::ToString();
1273         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
1274             GetBlockHash().ToString().c_str(),
1275             hashPrev.ToString().substr(0,20).c_str(),
1276             hashNext.ToString().substr(0,20).c_str());
1277         return str;
1278     }
1279
1280     void print() const
1281     {
1282         printf("%s\n", ToString().c_str());
1283     }
1284 };
1285
1286
1287
1288
1289
1290
1291
1292
1293 //
1294 // Describes a place in the block chain to another node such that if the
1295 // other node doesn't have the same branch, it can find a recent common trunk.
1296 // The further back it is, the further before the fork it may be.
1297 //
1298 class CBlockLocator
1299 {
1300 protected:
1301     std::vector<uint256> vHave;
1302 public:
1303
1304     CBlockLocator()
1305     {
1306     }
1307
1308     explicit CBlockLocator(const CBlockIndex* pindex)
1309     {
1310         Set(pindex);
1311     }
1312
1313     explicit CBlockLocator(uint256 hashBlock)
1314     {
1315         std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1316         if (mi != mapBlockIndex.end())
1317             Set((*mi).second);
1318     }
1319
1320     IMPLEMENT_SERIALIZE
1321     (
1322         if (!(nType & SER_GETHASH))
1323             READWRITE(nVersion);
1324         READWRITE(vHave);
1325     )
1326
1327     void SetNull()
1328     {
1329         vHave.clear();
1330     }
1331
1332     bool IsNull()
1333     {
1334         return vHave.empty();
1335     }
1336
1337     void Set(const CBlockIndex* pindex)
1338     {
1339         vHave.clear();
1340         int nStep = 1;
1341         while (pindex)
1342         {
1343             vHave.push_back(pindex->GetBlockHash());
1344
1345             // Exponentially larger steps back
1346             for (int i = 0; pindex && i < nStep; i++)
1347                 pindex = pindex->pprev;
1348             if (vHave.size() > 10)
1349                 nStep *= 2;
1350         }
1351         vHave.push_back(hashGenesisBlock);
1352     }
1353
1354     int GetDistanceBack()
1355     {
1356         // Retrace how far back it was in the sender's branch
1357         int nDistance = 0;
1358         int nStep = 1;
1359         BOOST_FOREACH(const uint256& hash, vHave)
1360         {
1361             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1362             if (mi != mapBlockIndex.end())
1363             {
1364                 CBlockIndex* pindex = (*mi).second;
1365                 if (pindex->IsInMainChain())
1366                     return nDistance;
1367             }
1368             nDistance += nStep;
1369             if (nDistance > 10)
1370                 nStep *= 2;
1371         }
1372         return nDistance;
1373     }
1374
1375     CBlockIndex* GetBlockIndex()
1376     {
1377         // Find the first block the caller has in the main chain
1378         BOOST_FOREACH(const uint256& hash, vHave)
1379         {
1380             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1381             if (mi != mapBlockIndex.end())
1382             {
1383                 CBlockIndex* pindex = (*mi).second;
1384                 if (pindex->IsInMainChain())
1385                     return pindex;
1386             }
1387         }
1388         return pindexGenesisBlock;
1389     }
1390
1391     uint256 GetBlockHash()
1392     {
1393         // Find the first block the caller has in the main chain
1394         BOOST_FOREACH(const uint256& hash, vHave)
1395         {
1396             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1397             if (mi != mapBlockIndex.end())
1398             {
1399                 CBlockIndex* pindex = (*mi).second;
1400                 if (pindex->IsInMainChain())
1401                     return hash;
1402             }
1403         }
1404         return hashGenesisBlock;
1405     }
1406
1407     int GetHeight()
1408     {
1409         CBlockIndex* pindex = GetBlockIndex();
1410         if (!pindex)
1411             return 0;
1412         return pindex->nHeight;
1413     }
1414 };
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424 //
1425 // Alerts are for notifying old versions if they become too obsolete and
1426 // need to upgrade.  The message is displayed in the status bar.
1427 // Alert messages are broadcast as a vector of signed data.  Unserializing may
1428 // not read the entire buffer if the alert is for a newer version, but older
1429 // versions can still relay the original data.
1430 //
1431 class CUnsignedAlert
1432 {
1433 public:
1434     int nVersion;
1435     int64 nRelayUntil;      // when newer nodes stop relaying to newer nodes
1436     int64 nExpiration;
1437     int nID;
1438     int nCancel;
1439     std::set<int> setCancel;
1440     int nMinVer;            // lowest version inclusive
1441     int nMaxVer;            // highest version inclusive
1442     std::set<std::string> setSubVer;  // empty matches all
1443     int nPriority;
1444
1445     // Actions
1446     std::string strComment;
1447     std::string strStatusBar;
1448     std::string strReserved;
1449
1450     IMPLEMENT_SERIALIZE
1451     (
1452         READWRITE(this->nVersion);
1453         nVersion = this->nVersion;
1454         READWRITE(nRelayUntil);
1455         READWRITE(nExpiration);
1456         READWRITE(nID);
1457         READWRITE(nCancel);
1458         READWRITE(setCancel);
1459         READWRITE(nMinVer);
1460         READWRITE(nMaxVer);
1461         READWRITE(setSubVer);
1462         READWRITE(nPriority);
1463
1464         READWRITE(strComment);
1465         READWRITE(strStatusBar);
1466         READWRITE(strReserved);
1467     )
1468
1469     void SetNull()
1470     {
1471         nVersion = 1;
1472         nRelayUntil = 0;
1473         nExpiration = 0;
1474         nID = 0;
1475         nCancel = 0;
1476         setCancel.clear();
1477         nMinVer = 0;
1478         nMaxVer = 0;
1479         setSubVer.clear();
1480         nPriority = 0;
1481
1482         strComment.clear();
1483         strStatusBar.clear();
1484         strReserved.clear();
1485     }
1486
1487     std::string ToString() const
1488     {
1489         std::string strSetCancel;
1490         BOOST_FOREACH(int n, setCancel)
1491             strSetCancel += strprintf("%d ", n);
1492         std::string strSetSubVer;
1493         BOOST_FOREACH(std::string str, setSubVer)
1494             strSetSubVer += "\"" + str + "\" ";
1495         return strprintf(
1496                 "CAlert(\n"
1497                 "    nVersion     = %d\n"
1498                 "    nRelayUntil  = %"PRI64d"\n"
1499                 "    nExpiration  = %"PRI64d"\n"
1500                 "    nID          = %d\n"
1501                 "    nCancel      = %d\n"
1502                 "    setCancel    = %s\n"
1503                 "    nMinVer      = %d\n"
1504                 "    nMaxVer      = %d\n"
1505                 "    setSubVer    = %s\n"
1506                 "    nPriority    = %d\n"
1507                 "    strComment   = \"%s\"\n"
1508                 "    strStatusBar = \"%s\"\n"
1509                 ")\n",
1510             nVersion,
1511             nRelayUntil,
1512             nExpiration,
1513             nID,
1514             nCancel,
1515             strSetCancel.c_str(),
1516             nMinVer,
1517             nMaxVer,
1518             strSetSubVer.c_str(),
1519             nPriority,
1520             strComment.c_str(),
1521             strStatusBar.c_str());
1522     }
1523
1524     void print() const
1525     {
1526         printf("%s", ToString().c_str());
1527     }
1528 };
1529
1530 class CAlert : public CUnsignedAlert
1531 {
1532 public:
1533     std::vector<unsigned char> vchMsg;
1534     std::vector<unsigned char> vchSig;
1535
1536     CAlert()
1537     {
1538         SetNull();
1539     }
1540
1541     IMPLEMENT_SERIALIZE
1542     (
1543         READWRITE(vchMsg);
1544         READWRITE(vchSig);
1545     )
1546
1547     void SetNull()
1548     {
1549         CUnsignedAlert::SetNull();
1550         vchMsg.clear();
1551         vchSig.clear();
1552     }
1553
1554     bool IsNull() const
1555     {
1556         return (nExpiration == 0);
1557     }
1558
1559     uint256 GetHash() const
1560     {
1561         return SerializeHash(*this);
1562     }
1563
1564     bool IsInEffect() const
1565     {
1566         return (GetAdjustedTime() < nExpiration);
1567     }
1568
1569     bool Cancels(const CAlert& alert) const
1570     {
1571         if (!IsInEffect())
1572             return false; // this was a no-op before 31403
1573         return (alert.nID <= nCancel || setCancel.count(alert.nID));
1574     }
1575
1576     bool AppliesTo(int nVersion, std::string strSubVerIn) const
1577     {
1578         return (IsInEffect() &&
1579                 nMinVer <= nVersion && nVersion <= nMaxVer &&
1580                 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
1581     }
1582
1583     bool AppliesToMe() const
1584     {
1585         return AppliesTo(VERSION, ::pszSubVer);
1586     }
1587
1588     bool RelayTo(CNode* pnode) const
1589     {
1590         if (!IsInEffect())
1591             return false;
1592         // returns true if wasn't already contained in the set
1593         if (pnode->setKnown.insert(GetHash()).second)
1594         {
1595             if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
1596                 AppliesToMe() ||
1597                 GetAdjustedTime() < nRelayUntil)
1598             {
1599                 pnode->PushMessage("alert", *this);
1600                 return true;
1601             }
1602         }
1603         return false;
1604     }
1605
1606     bool CheckSignature()
1607     {
1608         CKey key;
1609         if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
1610             return error("CAlert::CheckSignature() : SetPubKey failed");
1611         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
1612             return error("CAlert::CheckSignature() : verify signature failed");
1613
1614         // Now unserialize the data
1615         CDataStream sMsg(vchMsg);
1616         sMsg >> *(CUnsignedAlert*)this;
1617         return true;
1618     }
1619
1620     bool ProcessAlert();
1621 };
1622
1623 #endif