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