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