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