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