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