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