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