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