Update all copyrights to 2012
[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
917
918     uint256 BuildMerkleTree() const
919     {
920         vMerkleTree.clear();
921         BOOST_FOREACH(const CTransaction& tx, vtx)
922             vMerkleTree.push_back(tx.GetHash());
923         int j = 0;
924         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
925         {
926             for (int i = 0; i < nSize; i += 2)
927             {
928                 int i2 = std::min(i+1, nSize-1);
929                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
930                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
931             }
932             j += nSize;
933         }
934         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
935     }
936
937     std::vector<uint256> GetMerkleBranch(int nIndex) const
938     {
939         if (vMerkleTree.empty())
940             BuildMerkleTree();
941         std::vector<uint256> vMerkleBranch;
942         int j = 0;
943         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
944         {
945             int i = std::min(nIndex^1, nSize-1);
946             vMerkleBranch.push_back(vMerkleTree[j+i]);
947             nIndex >>= 1;
948             j += nSize;
949         }
950         return vMerkleBranch;
951     }
952
953     static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
954     {
955         if (nIndex == -1)
956             return 0;
957         BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
958         {
959             if (nIndex & 1)
960                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
961             else
962                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
963             nIndex >>= 1;
964         }
965         return hash;
966     }
967
968
969     bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
970     {
971         // Open history file to append
972         CAutoFile fileout = AppendBlockFile(nFileRet);
973         if (!fileout)
974             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
975
976         // Write index header
977         unsigned int nSize = fileout.GetSerializeSize(*this);
978         fileout << FLATDATA(pchMessageStart) << nSize;
979
980         // Write block
981         nBlockPosRet = ftell(fileout);
982         if (nBlockPosRet == -1)
983             return error("CBlock::WriteToDisk() : ftell failed");
984         fileout << *this;
985
986         // Flush stdio buffers and commit to disk before returning
987         fflush(fileout);
988         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
989         {
990 #ifdef WIN32
991             _commit(_fileno(fileout));
992 #else
993             fsync(fileno(fileout));
994 #endif
995         }
996
997         return true;
998     }
999
1000     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
1001     {
1002         SetNull();
1003
1004         // Open history file to read
1005         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
1006         if (!filein)
1007             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
1008         if (!fReadTransactions)
1009             filein.nType |= SER_BLOCKHEADERONLY;
1010
1011         // Read block
1012         filein >> *this;
1013
1014         // Check the header
1015         if (!CheckProofOfWork(GetHash(), nBits))
1016             return error("CBlock::ReadFromDisk() : errors in block header");
1017
1018         return true;
1019     }
1020
1021
1022
1023     void print() const
1024     {
1025         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1026             GetHash().ToString().substr(0,20).c_str(),
1027             nVersion,
1028             hashPrevBlock.ToString().substr(0,20).c_str(),
1029             hashMerkleRoot.ToString().substr(0,10).c_str(),
1030             nTime, nBits, nNonce,
1031             vtx.size());
1032         for (int i = 0; i < vtx.size(); i++)
1033         {
1034             printf("  ");
1035             vtx[i].print();
1036         }
1037         printf("  vMerkleTree: ");
1038         for (int i = 0; i < vMerkleTree.size(); i++)
1039             printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
1040         printf("\n");
1041     }
1042
1043
1044     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1045     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1046     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1047     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1048     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1049     bool CheckBlock() const;
1050     bool AcceptBlock();
1051 };
1052
1053
1054
1055
1056
1057
1058 //
1059 // The block chain is a tree shaped structure starting with the
1060 // genesis block at the root, with each block potentially having multiple
1061 // candidates to be the next block.  pprev and pnext link a path through the
1062 // main/longest chain.  A blockindex may have multiple pprev pointing back
1063 // to it, but pnext will only point forward to the longest branch, or will
1064 // be null if the block is not part of the longest chain.
1065 //
1066 class CBlockIndex
1067 {
1068 public:
1069     const uint256* phashBlock;
1070     CBlockIndex* pprev;
1071     CBlockIndex* pnext;
1072     unsigned int nFile;
1073     unsigned int nBlockPos;
1074     int nHeight;
1075     CBigNum bnChainWork;
1076
1077     // block header
1078     int nVersion;
1079     uint256 hashMerkleRoot;
1080     unsigned int nTime;
1081     unsigned int nBits;
1082     unsigned int nNonce;
1083
1084
1085     CBlockIndex()
1086     {
1087         phashBlock = NULL;
1088         pprev = NULL;
1089         pnext = NULL;
1090         nFile = 0;
1091         nBlockPos = 0;
1092         nHeight = 0;
1093         bnChainWork = 0;
1094
1095         nVersion       = 0;
1096         hashMerkleRoot = 0;
1097         nTime          = 0;
1098         nBits          = 0;
1099         nNonce         = 0;
1100     }
1101
1102     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1103     {
1104         phashBlock = NULL;
1105         pprev = NULL;
1106         pnext = NULL;
1107         nFile = nFileIn;
1108         nBlockPos = nBlockPosIn;
1109         nHeight = 0;
1110         bnChainWork = 0;
1111
1112         nVersion       = block.nVersion;
1113         hashMerkleRoot = block.hashMerkleRoot;
1114         nTime          = block.nTime;
1115         nBits          = block.nBits;
1116         nNonce         = block.nNonce;
1117     }
1118
1119     CBlock GetBlockHeader() const
1120     {
1121         CBlock block;
1122         block.nVersion       = nVersion;
1123         if (pprev)
1124             block.hashPrevBlock = pprev->GetBlockHash();
1125         block.hashMerkleRoot = hashMerkleRoot;
1126         block.nTime          = nTime;
1127         block.nBits          = nBits;
1128         block.nNonce         = nNonce;
1129         return block;
1130     }
1131
1132     uint256 GetBlockHash() const
1133     {
1134         return *phashBlock;
1135     }
1136
1137     int64 GetBlockTime() const
1138     {
1139         return (int64)nTime;
1140     }
1141
1142     CBigNum GetBlockWork() const
1143     {
1144         CBigNum bnTarget;
1145         bnTarget.SetCompact(nBits);
1146         if (bnTarget <= 0)
1147             return 0;
1148         return (CBigNum(1)<<256) / (bnTarget+1);
1149     }
1150
1151     bool IsInMainChain() const
1152     {
1153         return (pnext || this == pindexBest);
1154     }
1155
1156     bool CheckIndex() const
1157     {
1158         return CheckProofOfWork(GetBlockHash(), nBits);
1159     }
1160
1161     bool EraseBlockFromDisk()
1162     {
1163         // Open history file
1164         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1165         if (!fileout)
1166             return false;
1167
1168         // Overwrite with empty null block
1169         CBlock block;
1170         block.SetNull();
1171         fileout << block;
1172
1173         return true;
1174     }
1175
1176     enum { nMedianTimeSpan=11 };
1177
1178     int64 GetMedianTimePast() const
1179     {
1180         int64 pmedian[nMedianTimeSpan];
1181         int64* pbegin = &pmedian[nMedianTimeSpan];
1182         int64* pend = &pmedian[nMedianTimeSpan];
1183
1184         const CBlockIndex* pindex = this;
1185         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1186             *(--pbegin) = pindex->GetBlockTime();
1187
1188         std::sort(pbegin, pend);
1189         return pbegin[(pend - pbegin)/2];
1190     }
1191
1192     int64 GetMedianTime() const
1193     {
1194         const CBlockIndex* pindex = this;
1195         for (int i = 0; i < nMedianTimeSpan/2; i++)
1196         {
1197             if (!pindex->pnext)
1198                 return GetBlockTime();
1199             pindex = pindex->pnext;
1200         }
1201         return pindex->GetMedianTimePast();
1202     }
1203
1204
1205
1206     std::string ToString() const
1207     {
1208         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1209             pprev, pnext, nFile, nBlockPos, nHeight,
1210             hashMerkleRoot.ToString().substr(0,10).c_str(),
1211             GetBlockHash().ToString().substr(0,20).c_str());
1212     }
1213
1214     void print() const
1215     {
1216         printf("%s\n", ToString().c_str());
1217     }
1218 };
1219
1220
1221
1222 //
1223 // Used to marshal pointers into hashes for db storage.
1224 //
1225 class CDiskBlockIndex : public CBlockIndex
1226 {
1227 public:
1228     uint256 hashPrev;
1229     uint256 hashNext;
1230
1231     CDiskBlockIndex()
1232     {
1233         hashPrev = 0;
1234         hashNext = 0;
1235     }
1236
1237     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1238     {
1239         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1240         hashNext = (pnext ? pnext->GetBlockHash() : 0);
1241     }
1242
1243     IMPLEMENT_SERIALIZE
1244     (
1245         if (!(nType & SER_GETHASH))
1246             READWRITE(nVersion);
1247
1248         READWRITE(hashNext);
1249         READWRITE(nFile);
1250         READWRITE(nBlockPos);
1251         READWRITE(nHeight);
1252
1253         // block header
1254         READWRITE(this->nVersion);
1255         READWRITE(hashPrev);
1256         READWRITE(hashMerkleRoot);
1257         READWRITE(nTime);
1258         READWRITE(nBits);
1259         READWRITE(nNonce);
1260     )
1261
1262     uint256 GetBlockHash() const
1263     {
1264         CBlock block;
1265         block.nVersion        = nVersion;
1266         block.hashPrevBlock   = hashPrev;
1267         block.hashMerkleRoot  = hashMerkleRoot;
1268         block.nTime           = nTime;
1269         block.nBits           = nBits;
1270         block.nNonce          = nNonce;
1271         return block.GetHash();
1272     }
1273
1274
1275     std::string ToString() const
1276     {
1277         std::string str = "CDiskBlockIndex(";
1278         str += CBlockIndex::ToString();
1279         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
1280             GetBlockHash().ToString().c_str(),
1281             hashPrev.ToString().substr(0,20).c_str(),
1282             hashNext.ToString().substr(0,20).c_str());
1283         return str;
1284     }
1285
1286     void print() const
1287     {
1288         printf("%s\n", ToString().c_str());
1289     }
1290 };
1291
1292
1293
1294
1295
1296
1297
1298
1299 //
1300 // Describes a place in the block chain to another node such that if the
1301 // other node doesn't have the same branch, it can find a recent common trunk.
1302 // The further back it is, the further before the fork it may be.
1303 //
1304 class CBlockLocator
1305 {
1306 protected:
1307     std::vector<uint256> vHave;
1308 public:
1309
1310     CBlockLocator()
1311     {
1312     }
1313
1314     explicit CBlockLocator(const CBlockIndex* pindex)
1315     {
1316         Set(pindex);
1317     }
1318
1319     explicit CBlockLocator(uint256 hashBlock)
1320     {
1321         std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1322         if (mi != mapBlockIndex.end())
1323             Set((*mi).second);
1324     }
1325
1326     CBlockLocator(const std::vector<uint256>& vHaveIn)
1327     {
1328         vHave = vHaveIn;
1329     }
1330
1331     IMPLEMENT_SERIALIZE
1332     (
1333         if (!(nType & SER_GETHASH))
1334             READWRITE(nVersion);
1335         READWRITE(vHave);
1336     )
1337
1338     void SetNull()
1339     {
1340         vHave.clear();
1341     }
1342
1343     bool IsNull()
1344     {
1345         return vHave.empty();
1346     }
1347
1348     void Set(const CBlockIndex* pindex)
1349     {
1350         vHave.clear();
1351         int nStep = 1;
1352         while (pindex)
1353         {
1354             vHave.push_back(pindex->GetBlockHash());
1355
1356             // Exponentially larger steps back
1357             for (int i = 0; pindex && i < nStep; i++)
1358                 pindex = pindex->pprev;
1359             if (vHave.size() > 10)
1360                 nStep *= 2;
1361         }
1362         vHave.push_back(hashGenesisBlock);
1363     }
1364
1365     int GetDistanceBack()
1366     {
1367         // Retrace how far back it was in the sender's branch
1368         int nDistance = 0;
1369         int nStep = 1;
1370         BOOST_FOREACH(const uint256& hash, vHave)
1371         {
1372             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1373             if (mi != mapBlockIndex.end())
1374             {
1375                 CBlockIndex* pindex = (*mi).second;
1376                 if (pindex->IsInMainChain())
1377                     return nDistance;
1378             }
1379             nDistance += nStep;
1380             if (nDistance > 10)
1381                 nStep *= 2;
1382         }
1383         return nDistance;
1384     }
1385
1386     CBlockIndex* GetBlockIndex()
1387     {
1388         // Find the first block the caller has in the main chain
1389         BOOST_FOREACH(const uint256& hash, vHave)
1390         {
1391             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1392             if (mi != mapBlockIndex.end())
1393             {
1394                 CBlockIndex* pindex = (*mi).second;
1395                 if (pindex->IsInMainChain())
1396                     return pindex;
1397             }
1398         }
1399         return pindexGenesisBlock;
1400     }
1401
1402     uint256 GetBlockHash()
1403     {
1404         // Find the first block the caller has in the main chain
1405         BOOST_FOREACH(const uint256& hash, vHave)
1406         {
1407             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1408             if (mi != mapBlockIndex.end())
1409             {
1410                 CBlockIndex* pindex = (*mi).second;
1411                 if (pindex->IsInMainChain())
1412                     return hash;
1413             }
1414         }
1415         return hashGenesisBlock;
1416     }
1417
1418     int GetHeight()
1419     {
1420         CBlockIndex* pindex = GetBlockIndex();
1421         if (!pindex)
1422             return 0;
1423         return pindex->nHeight;
1424     }
1425 };
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 //
1436 // Alerts are for notifying old versions if they become too obsolete and
1437 // need to upgrade.  The message is displayed in the status bar.
1438 // Alert messages are broadcast as a vector of signed data.  Unserializing may
1439 // not read the entire buffer if the alert is for a newer version, but older
1440 // versions can still relay the original data.
1441 //
1442 class CUnsignedAlert
1443 {
1444 public:
1445     int nVersion;
1446     int64 nRelayUntil;      // when newer nodes stop relaying to newer nodes
1447     int64 nExpiration;
1448     int nID;
1449     int nCancel;
1450     std::set<int> setCancel;
1451     int nMinVer;            // lowest version inclusive
1452     int nMaxVer;            // highest version inclusive
1453     std::set<std::string> setSubVer;  // empty matches all
1454     int nPriority;
1455
1456     // Actions
1457     std::string strComment;
1458     std::string strStatusBar;
1459     std::string strReserved;
1460
1461     IMPLEMENT_SERIALIZE
1462     (
1463         READWRITE(this->nVersion);
1464         nVersion = this->nVersion;
1465         READWRITE(nRelayUntil);
1466         READWRITE(nExpiration);
1467         READWRITE(nID);
1468         READWRITE(nCancel);
1469         READWRITE(setCancel);
1470         READWRITE(nMinVer);
1471         READWRITE(nMaxVer);
1472         READWRITE(setSubVer);
1473         READWRITE(nPriority);
1474
1475         READWRITE(strComment);
1476         READWRITE(strStatusBar);
1477         READWRITE(strReserved);
1478     )
1479
1480     void SetNull()
1481     {
1482         nVersion = 1;
1483         nRelayUntil = 0;
1484         nExpiration = 0;
1485         nID = 0;
1486         nCancel = 0;
1487         setCancel.clear();
1488         nMinVer = 0;
1489         nMaxVer = 0;
1490         setSubVer.clear();
1491         nPriority = 0;
1492
1493         strComment.clear();
1494         strStatusBar.clear();
1495         strReserved.clear();
1496     }
1497
1498     std::string ToString() const
1499     {
1500         std::string strSetCancel;
1501         BOOST_FOREACH(int n, setCancel)
1502             strSetCancel += strprintf("%d ", n);
1503         std::string strSetSubVer;
1504         BOOST_FOREACH(std::string str, setSubVer)
1505             strSetSubVer += "\"" + str + "\" ";
1506         return strprintf(
1507                 "CAlert(\n"
1508                 "    nVersion     = %d\n"
1509                 "    nRelayUntil  = %"PRI64d"\n"
1510                 "    nExpiration  = %"PRI64d"\n"
1511                 "    nID          = %d\n"
1512                 "    nCancel      = %d\n"
1513                 "    setCancel    = %s\n"
1514                 "    nMinVer      = %d\n"
1515                 "    nMaxVer      = %d\n"
1516                 "    setSubVer    = %s\n"
1517                 "    nPriority    = %d\n"
1518                 "    strComment   = \"%s\"\n"
1519                 "    strStatusBar = \"%s\"\n"
1520                 ")\n",
1521             nVersion,
1522             nRelayUntil,
1523             nExpiration,
1524             nID,
1525             nCancel,
1526             strSetCancel.c_str(),
1527             nMinVer,
1528             nMaxVer,
1529             strSetSubVer.c_str(),
1530             nPriority,
1531             strComment.c_str(),
1532             strStatusBar.c_str());
1533     }
1534
1535     void print() const
1536     {
1537         printf("%s", ToString().c_str());
1538     }
1539 };
1540
1541 class CAlert : public CUnsignedAlert
1542 {
1543 public:
1544     std::vector<unsigned char> vchMsg;
1545     std::vector<unsigned char> vchSig;
1546
1547     CAlert()
1548     {
1549         SetNull();
1550     }
1551
1552     IMPLEMENT_SERIALIZE
1553     (
1554         READWRITE(vchMsg);
1555         READWRITE(vchSig);
1556     )
1557
1558     void SetNull()
1559     {
1560         CUnsignedAlert::SetNull();
1561         vchMsg.clear();
1562         vchSig.clear();
1563     }
1564
1565     bool IsNull() const
1566     {
1567         return (nExpiration == 0);
1568     }
1569
1570     uint256 GetHash() const
1571     {
1572         return SerializeHash(*this);
1573     }
1574
1575     bool IsInEffect() const
1576     {
1577         return (GetAdjustedTime() < nExpiration);
1578     }
1579
1580     bool Cancels(const CAlert& alert) const
1581     {
1582         if (!IsInEffect())
1583             return false; // this was a no-op before 31403
1584         return (alert.nID <= nCancel || setCancel.count(alert.nID));
1585     }
1586
1587     bool AppliesTo(int nVersion, std::string strSubVerIn) const
1588     {
1589         // TODO: rework for client-version-embedded-in-strSubVer ?
1590         return (IsInEffect() &&
1591                 nMinVer <= nVersion && nVersion <= nMaxVer &&
1592                 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
1593     }
1594
1595     bool AppliesToMe() const
1596     {
1597         return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
1598     }
1599
1600     bool RelayTo(CNode* pnode) const
1601     {
1602         if (!IsInEffect())
1603             return false;
1604         // returns true if wasn't already contained in the set
1605         if (pnode->setKnown.insert(GetHash()).second)
1606         {
1607             if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
1608                 AppliesToMe() ||
1609                 GetAdjustedTime() < nRelayUntil)
1610             {
1611                 pnode->PushMessage("alert", *this);
1612                 return true;
1613             }
1614         }
1615         return false;
1616     }
1617
1618     bool CheckSignature()
1619     {
1620         CKey key;
1621         if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
1622             return error("CAlert::CheckSignature() : SetPubKey failed");
1623         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
1624             return error("CAlert::CheckSignature() : verify signature failed");
1625
1626         // Now unserialize the data
1627         CDataStream sMsg(vchMsg);
1628         sMsg >> *(CUnsignedAlert*)this;
1629         return true;
1630     }
1631
1632     bool ProcessAlert();
1633 };
1634
1635 #endif