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