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