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