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