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