Fix issue #848 : broken mining on testnet
[novacoin.git] / src / main.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_MAIN_H
6 #define BITCOIN_MAIN_H
7
8 #include "bignum.h"
9 #include "net.h"
10 #include "key.h"
11 #include "script.h"
12 #include "db.h"
13
14 #include <list>
15
16 class CBlock;
17 class CBlockIndex;
18 class CWalletTx;
19 class CWallet;
20 class CKeyItem;
21 class CReserveKey;
22 class CWalletDB;
23
24 class CAddress;
25 class CInv;
26 class CRequestTracker;
27 class CNode;
28
29 static const int CLIENT_VERSION = 60000;
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 extern CScript COINBASE_FLAGS;
53
54
55
56
57
58
59 extern CCriticalSection cs_main;
60 extern std::map<uint256, CBlockIndex*> mapBlockIndex;
61 extern uint256 hashGenesisBlock;
62 extern CBlockIndex* pindexGenesisBlock;
63 extern int nBestHeight;
64 extern CBigNum bnBestChainWork;
65 extern CBigNum bnBestInvalidWork;
66 extern uint256 hashBestChain;
67 extern CBlockIndex* pindexBest;
68 extern uint64 nPooledTx;
69 extern unsigned int nTransactionsUpdated;
70 extern uint64 nLastBlockTx;
71 extern uint64 nLastBlockSize;
72 extern const std::string strMessageMagic;
73 extern double dHashesPerSec;
74 extern int64 nHPSTimerStart;
75 extern int64 nTimeBestReceived;
76 extern CCriticalSection cs_setpwalletRegistered;
77 extern std::set<CWallet*> setpwalletRegistered;
78
79 // Settings
80 extern int fGenerateBitcoins;
81 extern int64 nTransactionFee;
82 extern int fLimitProcessors;
83 extern int nLimitProcessors;
84 extern int fMinimizeToTray;
85 extern int fMinimizeOnClose;
86 extern int fUseUPnP;
87
88
89
90
91
92 class CReserveKey;
93 class CTxDB;
94 class CTxIndex;
95
96 void RegisterWallet(CWallet* pwalletIn);
97 void UnregisterWallet(CWallet* pwalletIn);
98 bool ProcessBlock(CNode* pfrom, CBlock* pblock);
99 bool CheckDiskSpace(uint64 nAdditionalBytes=0);
100 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
101 FILE* AppendBlockFile(unsigned int& nFileRet);
102 bool LoadBlockIndex(bool fAllowNew=true);
103 void PrintBlockTree();
104 bool ProcessMessages(CNode* pfrom);
105 bool SendMessages(CNode* pto, bool fSendTrickle);
106 void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
107 CBlock* CreateNewBlock(CReserveKey& reservekey);
108 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
109 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
110 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
111 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
112 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
113 int GetNumBlocksOfPeers();
114 bool IsInitialBlockDownload();
115 std::string GetWarnings(std::string strFor);
116
117
118
119
120
121
122
123
124
125
126
127
128 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
129
130 template<typename T>
131 bool WriteSetting(const std::string& strKey, const T& value)
132 {
133     bool fOk = false;
134     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
135     {
136         std::string strWalletFile;
137         if (!GetWalletFile(pwallet, strWalletFile))
138             continue;
139         fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
140     }
141     return fOk;
142 }
143
144
145 class CDiskTxPos
146 {
147 public:
148     unsigned int nFile;
149     unsigned int nBlockPos;
150     unsigned int nTxPos;
151
152     CDiskTxPos()
153     {
154         SetNull();
155     }
156
157     CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
158     {
159         nFile = nFileIn;
160         nBlockPos = nBlockPosIn;
161         nTxPos = nTxPosIn;
162     }
163
164     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
165     void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
166     bool IsNull() const { return (nFile == -1); }
167
168     friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
169     {
170         return (a.nFile     == b.nFile &&
171                 a.nBlockPos == b.nBlockPos &&
172                 a.nTxPos    == b.nTxPos);
173     }
174
175     friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
176     {
177         return !(a == b);
178     }
179
180     std::string ToString() const
181     {
182         if (IsNull())
183             return strprintf("null");
184         else
185             return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
186     }
187
188     void print() const
189     {
190         printf("%s", ToString().c_str());
191     }
192 };
193
194
195
196
197 class CInPoint
198 {
199 public:
200     CTransaction* ptx;
201     unsigned int n;
202
203     CInPoint() { SetNull(); }
204     CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
205     void SetNull() { ptx = NULL; n = -1; }
206     bool IsNull() const { return (ptx == NULL && n == -1); }
207 };
208
209
210
211
212 class COutPoint
213 {
214 public:
215     uint256 hash;
216     unsigned int n;
217
218     COutPoint() { SetNull(); }
219     COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
220     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
221     void SetNull() { hash = 0; n = -1; }
222     bool IsNull() const { return (hash == 0 && n == -1); }
223
224     friend bool operator<(const COutPoint& a, const COutPoint& b)
225     {
226         return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
227     }
228
229     friend bool operator==(const COutPoint& a, const COutPoint& b)
230     {
231         return (a.hash == b.hash && a.n == b.n);
232     }
233
234     friend bool operator!=(const COutPoint& a, const COutPoint& b)
235     {
236         return !(a == b);
237     }
238
239     std::string ToString() const
240     {
241         return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
242     }
243
244     void print() const
245     {
246         printf("%s\n", ToString().c_str());
247     }
248 };
249
250
251
252
253 //
254 // An input of a transaction.  It contains the location of the previous
255 // transaction's output that it claims and a signature that matches the
256 // output's public key.
257 //
258 class CTxIn
259 {
260 public:
261     COutPoint prevout;
262     CScript scriptSig;
263     unsigned int nSequence;
264
265     CTxIn()
266     {
267         nSequence = std::numeric_limits<unsigned int>::max();
268     }
269
270     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
271     {
272         prevout = prevoutIn;
273         scriptSig = scriptSigIn;
274         nSequence = nSequenceIn;
275     }
276
277     CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
278     {
279         prevout = COutPoint(hashPrevTx, nOut);
280         scriptSig = scriptSigIn;
281         nSequence = nSequenceIn;
282     }
283
284     IMPLEMENT_SERIALIZE
285     (
286         READWRITE(prevout);
287         READWRITE(scriptSig);
288         READWRITE(nSequence);
289     )
290
291     bool IsFinal() const
292     {
293         return (nSequence == std::numeric_limits<unsigned int>::max());
294     }
295
296     friend bool operator==(const CTxIn& a, const CTxIn& b)
297     {
298         return (a.prevout   == b.prevout &&
299                 a.scriptSig == b.scriptSig &&
300                 a.nSequence == b.nSequence);
301     }
302
303     friend bool operator!=(const CTxIn& a, const CTxIn& b)
304     {
305         return !(a == b);
306     }
307
308     std::string ToString() const
309     {
310         std::string str;
311         str += strprintf("CTxIn(");
312         str += prevout.ToString();
313         if (prevout.IsNull())
314             str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
315         else
316             str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
317         if (nSequence != std::numeric_limits<unsigned int>::max())
318             str += strprintf(", nSequence=%u", nSequence);
319         str += ")";
320         return str;
321     }
322
323     void print() const
324     {
325         printf("%s\n", ToString().c_str());
326     }
327 };
328
329
330
331
332 //
333 // An output of a transaction.  It contains the public key that the next input
334 // must be able to sign with to claim it.
335 //
336 class CTxOut
337 {
338 public:
339     int64 nValue;
340     CScript scriptPubKey;
341
342     CTxOut()
343     {
344         SetNull();
345     }
346
347     CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
348     {
349         nValue = nValueIn;
350         scriptPubKey = scriptPubKeyIn;
351     }
352
353     IMPLEMENT_SERIALIZE
354     (
355         READWRITE(nValue);
356         READWRITE(scriptPubKey);
357     )
358
359     void SetNull()
360     {
361         nValue = -1;
362         scriptPubKey.clear();
363     }
364
365     bool IsNull()
366     {
367         return (nValue == -1);
368     }
369
370     uint256 GetHash() const
371     {
372         return SerializeHash(*this);
373     }
374
375     friend bool operator==(const CTxOut& a, const CTxOut& b)
376     {
377         return (a.nValue       == b.nValue &&
378                 a.scriptPubKey == b.scriptPubKey);
379     }
380
381     friend bool operator!=(const CTxOut& a, const CTxOut& b)
382     {
383         return !(a == b);
384     }
385
386     std::string ToString() const
387     {
388         if (scriptPubKey.size() < 6)
389             return "CTxOut(error)";
390         return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
391     }
392
393     void print() const
394     {
395         printf("%s\n", ToString().c_str());
396     }
397 };
398
399
400
401
402 enum GetMinFee_mode
403 {
404     GMF_BLOCK,
405     GMF_RELAY,
406     GMF_SEND,
407 };
408
409 typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
410
411 //
412 // The basic transaction that is broadcasted on the network and contained in
413 // blocks.  A transaction can contain multiple inputs and outputs.
414 //
415 class CTransaction
416 {
417 public:
418     int nVersion;
419     std::vector<CTxIn> vin;
420     std::vector<CTxOut> vout;
421     unsigned int nLockTime;
422
423     // Denial-of-service detection:
424     mutable int nDoS;
425     bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
426
427     CTransaction()
428     {
429         SetNull();
430     }
431
432     IMPLEMENT_SERIALIZE
433     (
434         READWRITE(this->nVersion);
435         nVersion = this->nVersion;
436         READWRITE(vin);
437         READWRITE(vout);
438         READWRITE(nLockTime);
439     )
440
441     void SetNull()
442     {
443         nVersion = 1;
444         vin.clear();
445         vout.clear();
446         nLockTime = 0;
447         nDoS = 0;  // Denial-of-service prevention
448     }
449
450     bool IsNull() const
451     {
452         return (vin.empty() && vout.empty());
453     }
454
455     uint256 GetHash() const
456     {
457         return SerializeHash(*this);
458     }
459
460     bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
461     {
462         // Time based nLockTime implemented in 0.1.6
463         if (nLockTime == 0)
464             return true;
465         if (nBlockHeight == 0)
466             nBlockHeight = nBestHeight;
467         if (nBlockTime == 0)
468             nBlockTime = GetAdjustedTime();
469         if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
470             return true;
471         BOOST_FOREACH(const CTxIn& txin, vin)
472             if (!txin.IsFinal())
473                 return false;
474         return true;
475     }
476
477     bool IsNewerThan(const CTransaction& old) const
478     {
479         if (vin.size() != old.vin.size())
480             return false;
481         for (int i = 0; i < vin.size(); i++)
482             if (vin[i].prevout != old.vin[i].prevout)
483                 return false;
484
485         bool fNewer = false;
486         unsigned int nLowest = std::numeric_limits<unsigned int>::max();
487         for (int i = 0; i < vin.size(); i++)
488         {
489             if (vin[i].nSequence != old.vin[i].nSequence)
490             {
491                 if (vin[i].nSequence <= nLowest)
492                 {
493                     fNewer = false;
494                     nLowest = vin[i].nSequence;
495                 }
496                 if (old.vin[i].nSequence < nLowest)
497                 {
498                     fNewer = true;
499                     nLowest = old.vin[i].nSequence;
500                 }
501             }
502         }
503         return fNewer;
504     }
505
506     bool IsCoinBase() const
507     {
508         return (vin.size() == 1 && vin[0].prevout.IsNull());
509     }
510
511     /** Check for standard transaction types
512         @return True if all outputs (scriptPubKeys) use only standard transaction forms
513     */
514     bool IsStandard() const;
515
516     /** Check for standard transaction types
517         @param[in] mapInputs    Map of previous transactions that have outputs we're spending
518         @return True if all inputs (scriptSigs) use only standard transaction forms
519         @see CTransaction::FetchInputs
520     */
521     bool AreInputsStandard(const MapPrevTx& mapInputs) const;
522
523     /** Count ECDSA signature operations the old-fashioned (pre-0.6) way
524         @return number of sigops this transaction's outputs will produce when spent
525         @see CTransaction::FetchInputs
526     */
527     int GetLegacySigOpCount() const;
528
529     /** Count ECDSA signature operations in pay-to-script-hash inputs.
530
531         @param[in] mapInputs    Map of previous transactions that have outputs we're spending
532         @return maximum number of sigops required to validate this transaction's inputs
533         @see CTransaction::FetchInputs
534      */
535     int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const;
536
537     /** Amount of bitcoins spent by this transaction.
538         @return sum of all outputs (note: does not include fees)
539      */
540     int64 GetValueOut() const
541     {
542         int64 nValueOut = 0;
543         BOOST_FOREACH(const CTxOut& txout, vout)
544         {
545             nValueOut += txout.nValue;
546             if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
547                 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
548         }
549         return nValueOut;
550     }
551
552     /** Amount of bitcoins coming in to this transaction
553         Note that lightweight clients may not know anything besides the hash of previous transactions,
554         so may not be able to calculate this.
555
556         @param[in] mapInputs    Map of previous transactions that have outputs we're spending
557         @return Sum of value of all inputs (scriptSigs)
558         @see CTransaction::FetchInputs
559      */
560     int64 GetValueIn(const MapPrevTx& mapInputs) const;
561
562     static bool AllowFree(double dPriority)
563     {
564         // Large (in bytes) low-priority (new, small-coin) transactions
565         // need a fee.
566         return dPriority > COIN * 144 / 250;
567     }
568
569     int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const
570     {
571         // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
572         int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
573
574         unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
575         unsigned int nNewBlockSize = nBlockSize + nBytes;
576         int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
577
578         if (fAllowFree)
579         {
580             if (nBlockSize == 1)
581             {
582                 // Transactions under 10K are free
583                 // (about 4500bc if made of 50bc inputs)
584                 if (nBytes < 10000)
585                     nMinFee = 0;
586             }
587             else
588             {
589                 // Free transaction area
590                 if (nNewBlockSize < 27000)
591                     nMinFee = 0;
592             }
593         }
594
595         // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
596         if (nMinFee < nBaseFee)
597             BOOST_FOREACH(const CTxOut& txout, vout)
598                 if (txout.nValue < CENT)
599                     nMinFee = nBaseFee;
600
601         // Raise the price as the block approaches full
602         if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
603         {
604             if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
605                 return MAX_MONEY;
606             nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
607         }
608
609         if (!MoneyRange(nMinFee))
610             nMinFee = MAX_MONEY;
611         return nMinFee;
612     }
613
614
615     bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
616     {
617         CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
618         if (!filein)
619             return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
620
621         // Read transaction
622         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
623             return error("CTransaction::ReadFromDisk() : fseek failed");
624         filein >> *this;
625
626         // Return file pointer
627         if (pfileRet)
628         {
629             if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
630                 return error("CTransaction::ReadFromDisk() : second fseek failed");
631             *pfileRet = filein.release();
632         }
633         return true;
634     }
635
636     friend bool operator==(const CTransaction& a, const CTransaction& b)
637     {
638         return (a.nVersion  == b.nVersion &&
639                 a.vin       == b.vin &&
640                 a.vout      == b.vout &&
641                 a.nLockTime == b.nLockTime);
642     }
643
644     friend bool operator!=(const CTransaction& a, const CTransaction& b)
645     {
646         return !(a == b);
647     }
648
649
650     std::string ToString() const
651     {
652         std::string str;
653         str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
654             GetHash().ToString().substr(0,10).c_str(),
655             nVersion,
656             vin.size(),
657             vout.size(),
658             nLockTime);
659         for (int i = 0; i < vin.size(); i++)
660             str += "    " + vin[i].ToString() + "\n";
661         for (int i = 0; i < vout.size(); i++)
662             str += "    " + vout[i].ToString() + "\n";
663         return str;
664     }
665
666     void print() const
667     {
668         printf("%s", ToString().c_str());
669     }
670
671
672     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
673     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
674     bool ReadFromDisk(COutPoint prevout);
675     bool DisconnectInputs(CTxDB& txdb);
676
677     /** Fetch from memory and/or disk. inputsRet keys are transaction hashes.
678
679      @param[in] txdb    Transaction database
680      @param[in] mapTestPool     List of pending changes to the transaction index database
681      @param[in] fBlock  True if being called to add a new best-block to the chain
682      @param[in] fMiner  True if being called by CreateNewBlock
683      @param[out] inputsRet      Pointers to this transaction's inputs
684      @param[out] fInvalid       returns true if transaction is invalid
685      @return    Returns true if all inputs are in txdb or mapTestPool
686      */
687     bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
688                      bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid);
689
690     /** Sanity check previous transactions, then, if all checks succeed,
691         mark them as spent by this transaction.
692
693         @param[in] inputs       Previous transactions (from FetchInputs)
694         @param[out] mapTestPool Keeps track of inputs that need to be updated on disk
695         @param[in] posThisTx    Position of this transaction on disk
696         @param[in] pindexBlock
697         @param[in] fBlock       true if called from ConnectBlock
698         @param[in] fMiner       true if called from CreateNewBlock
699         @param[in] fStrictPayToScriptHash       true if fully validating p2sh transactions
700         @return Returns true if all checks succeed
701      */
702     bool ConnectInputs(MapPrevTx inputs,
703                        std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
704                        const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true);
705     bool ClientConnectInputs();
706     bool CheckTransaction() const;
707     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
708     bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
709
710 protected:
711     const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
712     bool AddToMemoryPoolUnchecked();
713 public:
714     bool RemoveFromMemoryPool();
715 };
716
717
718
719
720
721 //
722 // A transaction with a merkle branch linking it to the block chain
723 //
724 class CMerkleTx : public CTransaction
725 {
726 public:
727     uint256 hashBlock;
728     std::vector<uint256> vMerkleBranch;
729     int nIndex;
730
731     // memory only
732     mutable char fMerkleVerified;
733
734
735     CMerkleTx()
736     {
737         Init();
738     }
739
740     CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
741     {
742         Init();
743     }
744
745     void Init()
746     {
747         hashBlock = 0;
748         nIndex = -1;
749         fMerkleVerified = false;
750     }
751
752
753     IMPLEMENT_SERIALIZE
754     (
755         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
756         nVersion = this->nVersion;
757         READWRITE(hashBlock);
758         READWRITE(vMerkleBranch);
759         READWRITE(nIndex);
760     )
761
762
763     int SetMerkleBranch(const CBlock* pblock=NULL);
764     int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
765     int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
766     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
767     int GetBlocksToMaturity() const;
768     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
769     bool AcceptToMemoryPool();
770 };
771
772
773
774
775 //
776 // A txdb record that contains the disk location of a transaction and the
777 // locations of transactions that spend its outputs.  vSpent is really only
778 // used as a flag, but having the location is very helpful for debugging.
779 //
780 class CTxIndex
781 {
782 public:
783     CDiskTxPos pos;
784     std::vector<CDiskTxPos> vSpent;
785
786     CTxIndex()
787     {
788         SetNull();
789     }
790
791     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
792     {
793         pos = posIn;
794         vSpent.resize(nOutputs);
795     }
796
797     IMPLEMENT_SERIALIZE
798     (
799         if (!(nType & SER_GETHASH))
800             READWRITE(nVersion);
801         READWRITE(pos);
802         READWRITE(vSpent);
803     )
804
805     void SetNull()
806     {
807         pos.SetNull();
808         vSpent.clear();
809     }
810
811     bool IsNull()
812     {
813         return pos.IsNull();
814     }
815
816     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
817     {
818         return (a.pos    == b.pos &&
819                 a.vSpent == b.vSpent);
820     }
821
822     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
823     {
824         return !(a == b);
825     }
826     int GetDepthInMainChain() const;
827  
828 };
829
830
831
832
833
834 //
835 // Nodes collect new transactions into a block, hash them into a hash tree,
836 // and scan through nonce values to make the block's hash satisfy proof-of-work
837 // requirements.  When they solve the proof-of-work, they broadcast the block
838 // to everyone and the block is added to the block chain.  The first transaction
839 // in the block is a special one that creates a new coin owned by the creator
840 // of the block.
841 //
842 // Blocks are appended to blk0001.dat files on disk.  Their location on disk
843 // is indexed by CBlockIndex objects in memory.
844 //
845 class CBlock
846 {
847 public:
848     // header
849     int nVersion;
850     uint256 hashPrevBlock;
851     uint256 hashMerkleRoot;
852     unsigned int nTime;
853     unsigned int nBits;
854     unsigned int nNonce;
855
856     // network and disk
857     std::vector<CTransaction> vtx;
858
859     // memory only
860     mutable std::vector<uint256> vMerkleTree;
861
862     // Denial-of-service detection:
863     mutable int nDoS;
864     bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
865
866     CBlock()
867     {
868         SetNull();
869     }
870
871     IMPLEMENT_SERIALIZE
872     (
873         READWRITE(this->nVersion);
874         nVersion = this->nVersion;
875         READWRITE(hashPrevBlock);
876         READWRITE(hashMerkleRoot);
877         READWRITE(nTime);
878         READWRITE(nBits);
879         READWRITE(nNonce);
880
881         // ConnectBlock depends on vtx being last so it can calculate offset
882         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
883             READWRITE(vtx);
884         else if (fRead)
885             const_cast<CBlock*>(this)->vtx.clear();
886     )
887
888     void SetNull()
889     {
890         nVersion = 1;
891         hashPrevBlock = 0;
892         hashMerkleRoot = 0;
893         nTime = 0;
894         nBits = 0;
895         nNonce = 0;
896         vtx.clear();
897         vMerkleTree.clear();
898         nDoS = 0;
899     }
900
901     bool IsNull() const
902     {
903         return (nBits == 0);
904     }
905
906     uint256 GetHash() const
907     {
908         return Hash(BEGIN(nVersion), END(nNonce));
909     }
910
911     int64 GetBlockTime() const
912     {
913         return (int64)nTime;
914     }
915
916     void UpdateTime(const CBlockIndex* pindexPrev);
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