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