IsStandard() check for CScripts: only relay/include in blocks CScripts we can understand.
[novacoin.git] / main.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5 class COutPoint;
6 class CInPoint;
7 class CDiskTxPos;
8 class CCoinBase;
9 class CTxIn;
10 class CTxOut;
11 class CTransaction;
12 class CBlock;
13 class CBlockIndex;
14 class CWalletTx;
15 class CKeyItem;
16
17 static const unsigned int MAX_BLOCK_SIZE = 1000000;
18 static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
19 static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
20 static const int64 COIN = 100000000;
21 static const int64 CENT = 1000000;
22 static const int64 MAX_MONEY = 21000000 * COIN;
23 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
24 static const int COINBASE_MATURITY = 100;
25
26
27
28
29
30
31 extern CCriticalSection cs_main;
32 extern map<uint256, CBlockIndex*> mapBlockIndex;
33 extern uint256 hashGenesisBlock;
34 extern CBigNum bnProofOfWorkLimit;
35 extern CBlockIndex* pindexGenesisBlock;
36 extern int nBestHeight;
37 extern CBigNum bnBestChainWork;
38 extern CBigNum bnBestInvalidWork;
39 extern uint256 hashBestChain;
40 extern CBlockIndex* pindexBest;
41 extern unsigned int nTransactionsUpdated;
42 extern map<uint256, int> mapRequestCount;
43 extern CCriticalSection cs_mapRequestCount;
44 extern map<string, string> mapAddressBook;
45 extern CCriticalSection cs_mapAddressBook;
46 extern vector<unsigned char> vchDefaultKey;
47 extern double dHashesPerSec;
48 extern int64 nHPSTimerStart;
49
50 // Settings
51 extern int fGenerateBitcoins;
52 extern int64 nTransactionFee;
53 extern CAddress addrIncoming;
54 extern int fLimitProcessors;
55 extern int nLimitProcessors;
56 extern int fMinimizeToTray;
57 extern int fMinimizeOnClose;
58
59
60
61
62
63
64
65 bool CheckDiskSpace(uint64 nAdditionalBytes=0);
66 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
67 FILE* AppendBlockFile(unsigned int& nFileRet);
68 bool AddKey(const CKey& key);
69 vector<unsigned char> GenerateNewKey();
70 bool AddToWallet(const CWalletTx& wtxIn);
71 void WalletUpdateSpent(const COutPoint& prevout);
72 void ReacceptWalletTransactions();
73 bool LoadBlockIndex(bool fAllowNew=true);
74 void PrintBlockTree();
75 bool ProcessMessages(CNode* pfrom);
76 bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
77 bool SendMessages(CNode* pto, bool fSendTrickle);
78 int64 GetBalance();
79 bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
80 bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
81 bool BroadcastTransaction(CWalletTx& wtxNew);
82 string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
83 string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
84 void GenerateBitcoins(bool fGenerate);
85 void ThreadBitcoinMiner(void* parg);
86 CBlock* CreateNewBlock(CReserveKey& reservekey);
87 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
88 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
89 bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
90 void BitcoinMiner();
91 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
92 bool IsInitialBlockDownload();
93 string GetWarnings(string strFor);
94
95
96
97
98
99
100
101
102
103
104
105
106 class CDiskTxPos
107 {
108 public:
109     unsigned int nFile;
110     unsigned int nBlockPos;
111     unsigned int nTxPos;
112
113     CDiskTxPos()
114     {
115         SetNull();
116     }
117
118     CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
119     {
120         nFile = nFileIn;
121         nBlockPos = nBlockPosIn;
122         nTxPos = nTxPosIn;
123     }
124
125     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
126     void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
127     bool IsNull() const { return (nFile == -1); }
128
129     friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
130     {
131         return (a.nFile     == b.nFile &&
132                 a.nBlockPos == b.nBlockPos &&
133                 a.nTxPos    == b.nTxPos);
134     }
135
136     friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
137     {
138         return !(a == b);
139     }
140
141     string ToString() const
142     {
143         if (IsNull())
144             return strprintf("null");
145         else
146             return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
147     }
148
149     void print() const
150     {
151         printf("%s", ToString().c_str());
152     }
153 };
154
155
156
157
158 class CInPoint
159 {
160 public:
161     CTransaction* ptx;
162     unsigned int n;
163
164     CInPoint() { SetNull(); }
165     CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
166     void SetNull() { ptx = NULL; n = -1; }
167     bool IsNull() const { return (ptx == NULL && n == -1); }
168 };
169
170
171
172
173 class COutPoint
174 {
175 public:
176     uint256 hash;
177     unsigned int n;
178
179     COutPoint() { SetNull(); }
180     COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
181     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
182     void SetNull() { hash = 0; n = -1; }
183     bool IsNull() const { return (hash == 0 && n == -1); }
184
185     friend bool operator<(const COutPoint& a, const COutPoint& b)
186     {
187         return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
188     }
189
190     friend bool operator==(const COutPoint& a, const COutPoint& b)
191     {
192         return (a.hash == b.hash && a.n == b.n);
193     }
194
195     friend bool operator!=(const COutPoint& a, const COutPoint& b)
196     {
197         return !(a == b);
198     }
199
200     string ToString() const
201     {
202         return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
203     }
204
205     void print() const
206     {
207         printf("%s\n", ToString().c_str());
208     }
209 };
210
211
212
213
214 //
215 // An input of a transaction.  It contains the location of the previous
216 // transaction's output that it claims and a signature that matches the
217 // output's public key.
218 //
219 class CTxIn
220 {
221 public:
222     COutPoint prevout;
223     CScript scriptSig;
224     unsigned int nSequence;
225
226     CTxIn()
227     {
228         nSequence = UINT_MAX;
229     }
230
231     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
232     {
233         prevout = prevoutIn;
234         scriptSig = scriptSigIn;
235         nSequence = nSequenceIn;
236     }
237
238     CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
239     {
240         prevout = COutPoint(hashPrevTx, nOut);
241         scriptSig = scriptSigIn;
242         nSequence = nSequenceIn;
243     }
244
245     IMPLEMENT_SERIALIZE
246     (
247         READWRITE(prevout);
248         READWRITE(scriptSig);
249         READWRITE(nSequence);
250     )
251
252     bool IsFinal() const
253     {
254         return (nSequence == UINT_MAX);
255     }
256
257     friend bool operator==(const CTxIn& a, const CTxIn& b)
258     {
259         return (a.prevout   == b.prevout &&
260                 a.scriptSig == b.scriptSig &&
261                 a.nSequence == b.nSequence);
262     }
263
264     friend bool operator!=(const CTxIn& a, const CTxIn& b)
265     {
266         return !(a == b);
267     }
268
269     string ToString() const
270     {
271         string str;
272         str += strprintf("CTxIn(");
273         str += prevout.ToString();
274         if (prevout.IsNull())
275             str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
276         else
277             str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
278         if (nSequence != UINT_MAX)
279             str += strprintf(", nSequence=%u", nSequence);
280         str += ")";
281         return str;
282     }
283
284     void print() const
285     {
286         printf("%s\n", ToString().c_str());
287     }
288
289     bool IsMine() const;
290     int64 GetDebit() const;
291 };
292
293
294
295
296 //
297 // An output of a transaction.  It contains the public key that the next input
298 // must be able to sign with to claim it.
299 //
300 class CTxOut
301 {
302 public:
303     int64 nValue;
304     CScript scriptPubKey;
305
306     CTxOut()
307     {
308         SetNull();
309     }
310
311     CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
312     {
313         nValue = nValueIn;
314         scriptPubKey = scriptPubKeyIn;
315     }
316
317     IMPLEMENT_SERIALIZE
318     (
319         READWRITE(nValue);
320         READWRITE(scriptPubKey);
321     )
322
323     void SetNull()
324     {
325         nValue = -1;
326         scriptPubKey.clear();
327     }
328
329     bool IsNull()
330     {
331         return (nValue == -1);
332     }
333
334     uint256 GetHash() const
335     {
336         return SerializeHash(*this);
337     }
338
339     bool IsMine() const
340     {
341         return ::IsMine(scriptPubKey);
342     }
343
344     int64 GetCredit() const
345     {
346         if (!MoneyRange(nValue))
347             throw runtime_error("CTxOut::GetCredit() : value out of range");
348         return (IsMine() ? nValue : 0);
349     }
350
351     bool IsChange() const
352     {
353         // On a debit transaction, a txout that's mine but isn't in the address book is change
354         vector<unsigned char> vchPubKey;
355         if (ExtractPubKey(scriptPubKey, true, vchPubKey))
356             CRITICAL_BLOCK(cs_mapAddressBook)
357                 if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
358                     return true;
359         return false;
360     }
361
362     int64 GetChange() const
363     {
364         if (!MoneyRange(nValue))
365             throw runtime_error("CTxOut::GetChange() : value out of range");
366         return (IsChange() ? nValue : 0);
367     }
368
369     friend bool operator==(const CTxOut& a, const CTxOut& b)
370     {
371         return (a.nValue       == b.nValue &&
372                 a.scriptPubKey == b.scriptPubKey);
373     }
374
375     friend bool operator!=(const CTxOut& a, const CTxOut& b)
376     {
377         return !(a == b);
378     }
379
380     string ToString() const
381     {
382         if (scriptPubKey.size() < 6)
383             return "CTxOut(error)";
384         return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
385     }
386
387     void print() const
388     {
389         printf("%s\n", ToString().c_str());
390     }
391 };
392
393
394
395
396 //
397 // The basic transaction that is broadcasted on the network and contained in
398 // blocks.  A transaction can contain multiple inputs and outputs.
399 //
400 class CTransaction
401 {
402 public:
403     int nVersion;
404     vector<CTxIn> vin;
405     vector<CTxOut> vout;
406     unsigned int nLockTime;
407
408
409     CTransaction()
410     {
411         SetNull();
412     }
413
414     IMPLEMENT_SERIALIZE
415     (
416         READWRITE(this->nVersion);
417         nVersion = this->nVersion;
418         READWRITE(vin);
419         READWRITE(vout);
420         READWRITE(nLockTime);
421     )
422
423     void SetNull()
424     {
425         nVersion = 1;
426         vin.clear();
427         vout.clear();
428         nLockTime = 0;
429     }
430
431     bool IsNull() const
432     {
433         return (vin.empty() && vout.empty());
434     }
435
436     uint256 GetHash() const
437     {
438         return SerializeHash(*this);
439     }
440
441     bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
442     {
443         // Time based nLockTime implemented in 0.1.6
444         if (nLockTime == 0)
445             return true;
446         if (nBlockHeight == 0)
447             nBlockHeight = nBestHeight;
448         if (nBlockTime == 0)
449             nBlockTime = GetAdjustedTime();
450         if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime))
451             return true;
452         foreach(const CTxIn& txin, vin)
453             if (!txin.IsFinal())
454                 return false;
455         return true;
456     }
457
458     bool IsNewerThan(const CTransaction& old) const
459     {
460         if (vin.size() != old.vin.size())
461             return false;
462         for (int i = 0; i < vin.size(); i++)
463             if (vin[i].prevout != old.vin[i].prevout)
464                 return false;
465
466         bool fNewer = false;
467         unsigned int nLowest = UINT_MAX;
468         for (int i = 0; i < vin.size(); i++)
469         {
470             if (vin[i].nSequence != old.vin[i].nSequence)
471             {
472                 if (vin[i].nSequence <= nLowest)
473                 {
474                     fNewer = false;
475                     nLowest = vin[i].nSequence;
476                 }
477                 if (old.vin[i].nSequence < nLowest)
478                 {
479                     fNewer = true;
480                     nLowest = old.vin[i].nSequence;
481                 }
482             }
483         }
484         return fNewer;
485     }
486
487     bool IsCoinBase() const
488     {
489         return (vin.size() == 1 && vin[0].prevout.IsNull());
490     }
491
492     int GetSigOpCount() const
493     {
494         int n = 0;
495         foreach(const CTxIn& txin, vin)
496             n += txin.scriptSig.GetSigOpCount();
497         foreach(const CTxOut& txout, vout)
498             n += txout.scriptPubKey.GetSigOpCount();
499         return n;
500     }
501
502     bool IsStandard() const
503     {
504         foreach(const CTxIn& txin, vin)
505             if (!txin.scriptSig.IsPushOnly())
506                 return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
507         foreach(const CTxOut& txout, vout)
508             if (!::IsStandard(txout.scriptPubKey))
509                 return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
510         return true;
511     }
512
513     bool IsMine() const
514     {
515         foreach(const CTxOut& txout, vout)
516             if (txout.IsMine())
517                 return true;
518         return false;
519     }
520
521     bool IsFromMe() const
522     {
523         return (GetDebit() > 0);
524     }
525
526     int64 GetDebit() const
527     {
528         int64 nDebit = 0;
529         foreach(const CTxIn& txin, vin)
530         {
531             nDebit += txin.GetDebit();
532             if (!MoneyRange(nDebit))
533                 throw runtime_error("CTransaction::GetDebit() : value out of range");
534         }
535         return nDebit;
536     }
537
538     int64 GetCredit() const
539     {
540         int64 nCredit = 0;
541         foreach(const CTxOut& txout, vout)
542         {
543             nCredit += txout.GetCredit();
544             if (!MoneyRange(nCredit))
545                 throw runtime_error("CTransaction::GetCredit() : value out of range");
546         }
547         return nCredit;
548     }
549
550     int64 GetChange() const
551     {
552         if (IsCoinBase())
553             return 0;
554         int64 nChange = 0;
555         foreach(const CTxOut& txout, vout)
556         {
557             nChange += txout.GetChange();
558             if (!MoneyRange(nChange))
559                 throw runtime_error("CTransaction::GetChange() : value out of range");
560         }
561         return nChange;
562     }
563
564     int64 GetValueOut() const
565     {
566         int64 nValueOut = 0;
567         foreach(const CTxOut& txout, vout)
568         {
569             nValueOut += txout.nValue;
570             if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
571                 throw runtime_error("CTransaction::GetValueOut() : value out of range");
572         }
573         return nValueOut;
574     }
575
576     int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true) const
577     {
578         // Base fee is 1 cent per kilobyte
579         unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
580         unsigned int nNewBlockSize = nBlockSize + nBytes;
581         int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT;
582
583         if (fAllowFree)
584         {
585             if (nBlockSize == 1)
586             {
587                 // Transactions under 10K are free
588                 // (about 4500bc if made of 50bc inputs)
589                 if (nBytes < 10000)
590                     nMinFee = 0;
591             }
592             else
593             {
594                 // Free transaction area
595                 if (nNewBlockSize < 27000)
596                     nMinFee = 0;
597             }
598         }
599
600         // To limit dust spam, require a 0.01 fee if any output is less than 0.01
601         if (nMinFee < CENT)
602             foreach(const CTxOut& txout, vout)
603                 if (txout.nValue < CENT)
604                     nMinFee = CENT;
605
606         // Raise the price as the block approaches full
607         if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
608         {
609             if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
610                 return MAX_MONEY;
611             nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
612         }
613
614         if (!MoneyRange(nMinFee))
615             nMinFee = MAX_MONEY;
616         return nMinFee;
617     }
618
619
620     bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
621     {
622         CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
623         if (!filein)
624             return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
625
626         // Read transaction
627         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
628             return error("CTransaction::ReadFromDisk() : fseek failed");
629         filein >> *this;
630
631         // Return file pointer
632         if (pfileRet)
633         {
634             if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
635                 return error("CTransaction::ReadFromDisk() : second fseek failed");
636             *pfileRet = filein.release();
637         }
638         return true;
639     }
640
641     friend bool operator==(const CTransaction& a, const CTransaction& b)
642     {
643         return (a.nVersion  == b.nVersion &&
644                 a.vin       == b.vin &&
645                 a.vout      == b.vout &&
646                 a.nLockTime == b.nLockTime);
647     }
648
649     friend bool operator!=(const CTransaction& a, const CTransaction& b)
650     {
651         return !(a == b);
652     }
653
654
655     string ToString() const
656     {
657         string str;
658         str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
659             GetHash().ToString().substr(0,10).c_str(),
660             nVersion,
661             vin.size(),
662             vout.size(),
663             nLockTime);
664         for (int i = 0; i < vin.size(); i++)
665             str += "    " + vin[i].ToString() + "\n";
666         for (int i = 0; i < vout.size(); i++)
667             str += "    " + vout[i].ToString() + "\n";
668         return str;
669     }
670
671     void print() const
672     {
673         printf("%s", ToString().c_str());
674     }
675
676
677     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
678     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
679     bool ReadFromDisk(COutPoint prevout);
680     bool DisconnectInputs(CTxDB& txdb);
681     bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
682                        CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
683     bool ClientConnectInputs();
684     bool CheckTransaction() const;
685     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
686     bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
687     {
688         CTxDB txdb("r");
689         return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
690     }
691 protected:
692     bool AddToMemoryPoolUnchecked();
693 public:
694     bool RemoveFromMemoryPool();
695 };
696
697
698
699
700
701 //
702 // A transaction with a merkle branch linking it to the block chain
703 //
704 class CMerkleTx : public CTransaction
705 {
706 public:
707     uint256 hashBlock;
708     vector<uint256> vMerkleBranch;
709     int nIndex;
710
711     // memory only
712     mutable char fMerkleVerified;
713
714
715     CMerkleTx()
716     {
717         Init();
718     }
719
720     CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
721     {
722         Init();
723     }
724
725     void Init()
726     {
727         hashBlock = 0;
728         nIndex = -1;
729         fMerkleVerified = false;
730     }
731
732     IMPLEMENT_SERIALIZE
733     (
734         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
735         nVersion = this->nVersion;
736         READWRITE(hashBlock);
737         READWRITE(vMerkleBranch);
738         READWRITE(nIndex);
739     )
740
741
742     int SetMerkleBranch(const CBlock* pblock=NULL);
743     int GetDepthInMainChain(int& nHeightRet) const;
744     int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
745     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
746     int GetBlocksToMaturity() const;
747     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
748     bool AcceptToMemoryPool() { CTxDB txdb("r"); return AcceptToMemoryPool(txdb); }
749 };
750
751
752
753
754 //
755 // A transaction with a bunch of additional info that only the owner cares
756 // about.  It includes any unrecorded transactions needed to link it back
757 // to the block chain.
758 //
759 class CWalletTx : public CMerkleTx
760 {
761 public:
762     vector<CMerkleTx> vtxPrev;
763     map<string, string> mapValue;
764     vector<pair<string, string> > vOrderForm;
765     unsigned int fTimeReceivedIsTxTime;
766     unsigned int nTimeReceived;  // time received by this node
767     char fFromMe;
768     char fSpent;
769     string strFromAccount;
770
771     // memory only
772     mutable char fDebitCached;
773     mutable char fCreditCached;
774     mutable char fChangeCached;
775     mutable int64 nDebitCached;
776     mutable int64 nCreditCached;
777     mutable int64 nChangeCached;
778
779     // memory only UI hints
780     mutable unsigned int nTimeDisplayed;
781     mutable int nLinesDisplayed;
782     mutable char fConfirmedDisplayed;
783
784
785     CWalletTx()
786     {
787         Init();
788     }
789
790     CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
791     {
792         Init();
793     }
794
795     CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
796     {
797         Init();
798     }
799
800     void Init()
801     {
802         vtxPrev.clear();
803         mapValue.clear();
804         vOrderForm.clear();
805         fTimeReceivedIsTxTime = false;
806         nTimeReceived = 0;
807         fFromMe = false;
808         fSpent = false;
809         strFromAccount.clear();
810         fDebitCached = false;
811         fCreditCached = false;
812         fChangeCached = false;
813         nDebitCached = 0;
814         nCreditCached = 0;
815         nChangeCached = 0;
816         nTimeDisplayed = 0;
817         nLinesDisplayed = 0;
818         fConfirmedDisplayed = false;
819     }
820
821     IMPLEMENT_SERIALIZE
822     (
823         CWalletTx* pthis = const_cast<CWalletTx*>(this);
824         if (fRead)
825             pthis->Init();
826         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
827         READWRITE(vtxPrev);
828
829         pthis->mapValue["fromaccount"] = pthis->strFromAccount;
830         READWRITE(mapValue);
831         pthis->strFromAccount = pthis->mapValue["fromaccount"];
832         pthis->mapValue.erase("fromaccount");
833         pthis->mapValue.erase("version");
834
835         READWRITE(vOrderForm);
836         READWRITE(fTimeReceivedIsTxTime);
837         READWRITE(nTimeReceived);
838         READWRITE(fFromMe);
839         READWRITE(fSpent);
840     )
841
842     int64 GetDebit() const
843     {
844         if (vin.empty())
845             return 0;
846         if (fDebitCached)
847             return nDebitCached;
848         nDebitCached = CTransaction::GetDebit();
849         fDebitCached = true;
850         return nDebitCached;
851     }
852
853     int64 GetCredit(bool fUseCache=true) const
854     {
855         // Must wait until coinbase is safely deep enough in the chain before valuing it
856         if (IsCoinBase() && GetBlocksToMaturity() > 0)
857             return 0;
858
859         // GetBalance can assume transactions in mapWallet won't change
860         if (fUseCache && fCreditCached)
861             return nCreditCached;
862         nCreditCached = CTransaction::GetCredit();
863         fCreditCached = true;
864         return nCreditCached;
865     }
866
867     int64 GetChange() const
868     {
869         if (fChangeCached)
870             return nChangeCached;
871         nChangeCached = CTransaction::GetChange();
872         fChangeCached = true;
873         return nChangeCached;
874     }
875
876     void GetAccountAmounts(string strAccount, const set<CScript>& setPubKey,
877                            int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const
878     {
879         nGenerated = nReceived = nSent = nFee = 0;
880
881         // Generated blocks count to account ""
882         if (IsCoinBase())
883         {
884             if (strAccount == "" && GetBlocksToMaturity() == 0)
885                 nGenerated = GetCredit();
886             return;
887         }
888
889         // Received
890         foreach(const CTxOut& txout, vout)
891             if (setPubKey.count(txout.scriptPubKey))
892                 nReceived += txout.nValue;
893
894         // Sent
895         if (strFromAccount == strAccount)
896         {
897             int64 nDebit = GetDebit();
898             if (nDebit > 0)
899             {
900                 int64 nValueOut = GetValueOut();
901                 nFee = nDebit - nValueOut;
902                 nSent = nValueOut - GetChange();
903             }
904         }
905     }
906
907     bool IsFromMe() const
908     {
909         return (GetDebit() > 0);
910     }
911
912     bool IsConfirmed() const
913     {
914         // Quick answer in most cases
915         if (!IsFinal())
916             return false;
917         if (GetDepthInMainChain() >= 1)
918             return true;
919         if (!IsFromMe()) // using wtx's cached debit
920             return false;
921
922         // If no confirmations but it's from us, we can still
923         // consider it confirmed if all dependencies are confirmed
924         map<uint256, const CMerkleTx*> mapPrev;
925         vector<const CMerkleTx*> vWorkQueue;
926         vWorkQueue.reserve(vtxPrev.size()+1);
927         vWorkQueue.push_back(this);
928         for (int i = 0; i < vWorkQueue.size(); i++)
929         {
930             const CMerkleTx* ptx = vWorkQueue[i];
931
932             if (!ptx->IsFinal())
933                 return false;
934             if (ptx->GetDepthInMainChain() >= 1)
935                 return true;
936             if (!ptx->IsFromMe())
937                 return false;
938
939             if (mapPrev.empty())
940                 foreach(const CMerkleTx& tx, vtxPrev)
941                     mapPrev[tx.GetHash()] = &tx;
942
943             foreach(const CTxIn& txin, ptx->vin)
944             {
945                 if (!mapPrev.count(txin.prevout.hash))
946                     return false;
947                 vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
948             }
949         }
950         return true;
951     }
952
953     bool WriteToDisk()
954     {
955         return CWalletDB().WriteTx(GetHash(), *this);
956     }
957
958
959     int64 GetTxTime() const;
960     int GetRequestCount() const;
961
962     void AddSupportingTransactions(CTxDB& txdb);
963
964     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
965     bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
966
967     void RelayWalletTransaction(CTxDB& txdb);
968     void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
969 };
970
971
972
973
974 //
975 // A txdb record that contains the disk location of a transaction and the
976 // locations of transactions that spend its outputs.  vSpent is really only
977 // used as a flag, but having the location is very helpful for debugging.
978 //
979 class CTxIndex
980 {
981 public:
982     CDiskTxPos pos;
983     vector<CDiskTxPos> vSpent;
984
985     CTxIndex()
986     {
987         SetNull();
988     }
989
990     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
991     {
992         pos = posIn;
993         vSpent.resize(nOutputs);
994     }
995
996     IMPLEMENT_SERIALIZE
997     (
998         if (!(nType & SER_GETHASH))
999             READWRITE(nVersion);
1000         READWRITE(pos);
1001         READWRITE(vSpent);
1002     )
1003
1004     void SetNull()
1005     {
1006         pos.SetNull();
1007         vSpent.clear();
1008     }
1009
1010     bool IsNull()
1011     {
1012         return pos.IsNull();
1013     }
1014
1015     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
1016     {
1017         return (a.pos    == b.pos &&
1018                 a.vSpent == b.vSpent);
1019     }
1020
1021     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
1022     {
1023         return !(a == b);
1024     }
1025 };
1026
1027
1028
1029
1030
1031 //
1032 // Nodes collect new transactions into a block, hash them into a hash tree,
1033 // and scan through nonce values to make the block's hash satisfy proof-of-work
1034 // requirements.  When they solve the proof-of-work, they broadcast the block
1035 // to everyone and the block is added to the block chain.  The first transaction
1036 // in the block is a special one that creates a new coin owned by the creator
1037 // of the block.
1038 //
1039 // Blocks are appended to blk0001.dat files on disk.  Their location on disk
1040 // is indexed by CBlockIndex objects in memory.
1041 //
1042 class CBlock
1043 {
1044 public:
1045     // header
1046     int nVersion;
1047     uint256 hashPrevBlock;
1048     uint256 hashMerkleRoot;
1049     unsigned int nTime;
1050     unsigned int nBits;
1051     unsigned int nNonce;
1052
1053     // network and disk
1054     vector<CTransaction> vtx;
1055
1056     // memory only
1057     mutable vector<uint256> vMerkleTree;
1058
1059
1060     CBlock()
1061     {
1062         SetNull();
1063     }
1064
1065     IMPLEMENT_SERIALIZE
1066     (
1067         READWRITE(this->nVersion);
1068         nVersion = this->nVersion;
1069         READWRITE(hashPrevBlock);
1070         READWRITE(hashMerkleRoot);
1071         READWRITE(nTime);
1072         READWRITE(nBits);
1073         READWRITE(nNonce);
1074
1075         // ConnectBlock depends on vtx being last so it can calculate offset
1076         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
1077             READWRITE(vtx);
1078         else if (fRead)
1079             const_cast<CBlock*>(this)->vtx.clear();
1080     )
1081
1082     void SetNull()
1083     {
1084         nVersion = 1;
1085         hashPrevBlock = 0;
1086         hashMerkleRoot = 0;
1087         nTime = 0;
1088         nBits = 0;
1089         nNonce = 0;
1090         vtx.clear();
1091         vMerkleTree.clear();
1092     }
1093
1094     bool IsNull() const
1095     {
1096         return (nBits == 0);
1097     }
1098
1099     uint256 GetHash() const
1100     {
1101         return Hash(BEGIN(nVersion), END(nNonce));
1102     }
1103
1104     int64 GetBlockTime() const
1105     {
1106         return (int64)nTime;
1107     }
1108
1109     int GetSigOpCount() const
1110     {
1111         int n = 0;
1112         foreach(const CTransaction& tx, vtx)
1113             n += tx.GetSigOpCount();
1114         return n;
1115     }
1116
1117
1118     uint256 BuildMerkleTree() const
1119     {
1120         vMerkleTree.clear();
1121         foreach(const CTransaction& tx, vtx)
1122             vMerkleTree.push_back(tx.GetHash());
1123         int j = 0;
1124         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1125         {
1126             for (int i = 0; i < nSize; i += 2)
1127             {
1128                 int i2 = min(i+1, nSize-1);
1129                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
1130                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
1131             }
1132             j += nSize;
1133         }
1134         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
1135     }
1136
1137     vector<uint256> GetMerkleBranch(int nIndex) const
1138     {
1139         if (vMerkleTree.empty())
1140             BuildMerkleTree();
1141         vector<uint256> vMerkleBranch;
1142         int j = 0;
1143         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1144         {
1145             int i = min(nIndex^1, nSize-1);
1146             vMerkleBranch.push_back(vMerkleTree[j+i]);
1147             nIndex >>= 1;
1148             j += nSize;
1149         }
1150         return vMerkleBranch;
1151     }
1152
1153     static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)
1154     {
1155         if (nIndex == -1)
1156             return 0;
1157         foreach(const uint256& otherside, vMerkleBranch)
1158         {
1159             if (nIndex & 1)
1160                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
1161             else
1162                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
1163             nIndex >>= 1;
1164         }
1165         return hash;
1166     }
1167
1168
1169     bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
1170     {
1171         // Open history file to append
1172         CAutoFile fileout = AppendBlockFile(nFileRet);
1173         if (!fileout)
1174             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
1175
1176         // Write index header
1177         unsigned int nSize = fileout.GetSerializeSize(*this);
1178         fileout << FLATDATA(pchMessageStart) << nSize;
1179
1180         // Write block
1181         nBlockPosRet = ftell(fileout);
1182         if (nBlockPosRet == -1)
1183             return error("CBlock::WriteToDisk() : ftell failed");
1184         fileout << *this;
1185
1186         // Flush stdio buffers and commit to disk before returning
1187         fflush(fileout);
1188         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
1189         {
1190 #ifdef __WXMSW__
1191             _commit(_fileno(fileout));
1192 #else
1193             fsync(fileno(fileout));
1194 #endif
1195         }
1196
1197         return true;
1198     }
1199
1200     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
1201     {
1202         SetNull();
1203
1204         // Open history file to read
1205         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
1206         if (!filein)
1207             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
1208         if (!fReadTransactions)
1209             filein.nType |= SER_BLOCKHEADERONLY;
1210
1211         // Read block
1212         filein >> *this;
1213
1214         // Check the header
1215         if (!CheckProofOfWork(GetHash(), nBits))
1216             return error("CBlock::ReadFromDisk() : errors in block header");
1217
1218         return true;
1219     }
1220
1221
1222
1223     void print() const
1224     {
1225         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1226             GetHash().ToString().substr(0,20).c_str(),
1227             nVersion,
1228             hashPrevBlock.ToString().substr(0,20).c_str(),
1229             hashMerkleRoot.ToString().substr(0,10).c_str(),
1230             nTime, nBits, nNonce,
1231             vtx.size());
1232         for (int i = 0; i < vtx.size(); i++)
1233         {
1234             printf("  ");
1235             vtx[i].print();
1236         }
1237         printf("  vMerkleTree: ");
1238         for (int i = 0; i < vMerkleTree.size(); i++)
1239             printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
1240         printf("\n");
1241     }
1242
1243
1244     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1245     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1246     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1247     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1248     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1249     bool CheckBlock() const;
1250     bool AcceptBlock();
1251 };
1252
1253
1254
1255
1256
1257
1258 //
1259 // The block chain is a tree shaped structure starting with the
1260 // genesis block at the root, with each block potentially having multiple
1261 // candidates to be the next block.  pprev and pnext link a path through the
1262 // main/longest chain.  A blockindex may have multiple pprev pointing back
1263 // to it, but pnext will only point forward to the longest branch, or will
1264 // be null if the block is not part of the longest chain.
1265 //
1266 class CBlockIndex
1267 {
1268 public:
1269     const uint256* phashBlock;
1270     CBlockIndex* pprev;
1271     CBlockIndex* pnext;
1272     unsigned int nFile;
1273     unsigned int nBlockPos;
1274     int nHeight;
1275     CBigNum bnChainWork;
1276
1277     // block header
1278     int nVersion;
1279     uint256 hashMerkleRoot;
1280     unsigned int nTime;
1281     unsigned int nBits;
1282     unsigned int nNonce;
1283
1284
1285     CBlockIndex()
1286     {
1287         phashBlock = NULL;
1288         pprev = NULL;
1289         pnext = NULL;
1290         nFile = 0;
1291         nBlockPos = 0;
1292         nHeight = 0;
1293         bnChainWork = 0;
1294
1295         nVersion       = 0;
1296         hashMerkleRoot = 0;
1297         nTime          = 0;
1298         nBits          = 0;
1299         nNonce         = 0;
1300     }
1301
1302     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1303     {
1304         phashBlock = NULL;
1305         pprev = NULL;
1306         pnext = NULL;
1307         nFile = nFileIn;
1308         nBlockPos = nBlockPosIn;
1309         nHeight = 0;
1310         bnChainWork = 0;
1311
1312         nVersion       = block.nVersion;
1313         hashMerkleRoot = block.hashMerkleRoot;
1314         nTime          = block.nTime;
1315         nBits          = block.nBits;
1316         nNonce         = block.nNonce;
1317     }
1318
1319     CBlock GetBlockHeader() const
1320     {
1321         CBlock block;
1322         block.nVersion       = nVersion;
1323         if (pprev)
1324             block.hashPrevBlock = pprev->GetBlockHash();
1325         block.hashMerkleRoot = hashMerkleRoot;
1326         block.nTime          = nTime;
1327         block.nBits          = nBits;
1328         block.nNonce         = nNonce;
1329         return block;
1330     }
1331
1332     uint256 GetBlockHash() const
1333     {
1334         return *phashBlock;
1335     }
1336
1337     int64 GetBlockTime() const
1338     {
1339         return (int64)nTime;
1340     }
1341
1342     CBigNum GetBlockWork() const
1343     {
1344         CBigNum bnTarget;
1345         bnTarget.SetCompact(nBits);
1346         if (bnTarget <= 0)
1347             return 0;
1348         return (CBigNum(1)<<256) / (bnTarget+1);
1349     }
1350
1351     bool IsInMainChain() const
1352     {
1353         return (pnext || this == pindexBest);
1354     }
1355
1356     bool CheckIndex() const
1357     {
1358         return CheckProofOfWork(GetBlockHash(), nBits);
1359     }
1360
1361     bool EraseBlockFromDisk()
1362     {
1363         // Open history file
1364         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1365         if (!fileout)
1366             return false;
1367
1368         // Overwrite with empty null block
1369         CBlock block;
1370         block.SetNull();
1371         fileout << block;
1372
1373         return true;
1374     }
1375
1376     enum { nMedianTimeSpan=11 };
1377
1378     int64 GetMedianTimePast() const
1379     {
1380         int64 pmedian[nMedianTimeSpan];
1381         int64* pbegin = &pmedian[nMedianTimeSpan];
1382         int64* pend = &pmedian[nMedianTimeSpan];
1383
1384         const CBlockIndex* pindex = this;
1385         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1386             *(--pbegin) = pindex->GetBlockTime();
1387
1388         sort(pbegin, pend);
1389         return pbegin[(pend - pbegin)/2];
1390     }
1391
1392     int64 GetMedianTime() const
1393     {
1394         const CBlockIndex* pindex = this;
1395         for (int i = 0; i < nMedianTimeSpan/2; i++)
1396         {
1397             if (!pindex->pnext)
1398                 return GetBlockTime();
1399             pindex = pindex->pnext;
1400         }
1401         return pindex->GetMedianTimePast();
1402     }
1403
1404
1405
1406     string ToString() const
1407     {
1408         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1409             pprev, pnext, nFile, nBlockPos, nHeight,
1410             hashMerkleRoot.ToString().substr(0,10).c_str(),
1411             GetBlockHash().ToString().substr(0,20).c_str());
1412     }
1413
1414     void print() const
1415     {
1416         printf("%s\n", ToString().c_str());
1417     }
1418 };
1419
1420
1421
1422 //
1423 // Used to marshal pointers into hashes for db storage.
1424 //
1425 class CDiskBlockIndex : public CBlockIndex
1426 {
1427 public:
1428     uint256 hashPrev;
1429     uint256 hashNext;
1430
1431     CDiskBlockIndex()
1432     {
1433         hashPrev = 0;
1434         hashNext = 0;
1435     }
1436
1437     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1438     {
1439         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1440         hashNext = (pnext ? pnext->GetBlockHash() : 0);
1441     }
1442
1443     IMPLEMENT_SERIALIZE
1444     (
1445         if (!(nType & SER_GETHASH))
1446             READWRITE(nVersion);
1447
1448         READWRITE(hashNext);
1449         READWRITE(nFile);
1450         READWRITE(nBlockPos);
1451         READWRITE(nHeight);
1452
1453         // block header
1454         READWRITE(this->nVersion);
1455         READWRITE(hashPrev);
1456         READWRITE(hashMerkleRoot);
1457         READWRITE(nTime);
1458         READWRITE(nBits);
1459         READWRITE(nNonce);
1460     )
1461
1462     uint256 GetBlockHash() const
1463     {
1464         CBlock block;
1465         block.nVersion        = nVersion;
1466         block.hashPrevBlock   = hashPrev;
1467         block.hashMerkleRoot  = hashMerkleRoot;
1468         block.nTime           = nTime;
1469         block.nBits           = nBits;
1470         block.nNonce          = nNonce;
1471         return block.GetHash();
1472     }
1473
1474
1475     string ToString() const
1476     {
1477         string str = "CDiskBlockIndex(";
1478         str += CBlockIndex::ToString();
1479         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
1480             GetBlockHash().ToString().c_str(),
1481             hashPrev.ToString().substr(0,20).c_str(),
1482             hashNext.ToString().substr(0,20).c_str());
1483         return str;
1484     }
1485
1486     void print() const
1487     {
1488         printf("%s\n", ToString().c_str());
1489     }
1490 };
1491
1492
1493
1494
1495
1496
1497
1498
1499 //
1500 // Describes a place in the block chain to another node such that if the
1501 // other node doesn't have the same branch, it can find a recent common trunk.
1502 // The further back it is, the further before the fork it may be.
1503 //
1504 class CBlockLocator
1505 {
1506 protected:
1507     vector<uint256> vHave;
1508 public:
1509
1510     CBlockLocator()
1511     {
1512     }
1513
1514     explicit CBlockLocator(const CBlockIndex* pindex)
1515     {
1516         Set(pindex);
1517     }
1518
1519     explicit CBlockLocator(uint256 hashBlock)
1520     {
1521         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1522         if (mi != mapBlockIndex.end())
1523             Set((*mi).second);
1524     }
1525
1526     IMPLEMENT_SERIALIZE
1527     (
1528         if (!(nType & SER_GETHASH))
1529             READWRITE(nVersion);
1530         READWRITE(vHave);
1531     )
1532
1533     void SetNull()
1534     {
1535         vHave.clear();
1536     }
1537
1538     bool IsNull()
1539     {
1540         return vHave.empty();
1541     }
1542
1543     void Set(const CBlockIndex* pindex)
1544     {
1545         vHave.clear();
1546         int nStep = 1;
1547         while (pindex)
1548         {
1549             vHave.push_back(pindex->GetBlockHash());
1550
1551             // Exponentially larger steps back
1552             for (int i = 0; pindex && i < nStep; i++)
1553                 pindex = pindex->pprev;
1554             if (vHave.size() > 10)
1555                 nStep *= 2;
1556         }
1557         vHave.push_back(hashGenesisBlock);
1558     }
1559
1560     int GetDistanceBack()
1561     {
1562         // Retrace how far back it was in the sender's branch
1563         int nDistance = 0;
1564         int nStep = 1;
1565         foreach(const uint256& hash, vHave)
1566         {
1567             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1568             if (mi != mapBlockIndex.end())
1569             {
1570                 CBlockIndex* pindex = (*mi).second;
1571                 if (pindex->IsInMainChain())
1572                     return nDistance;
1573             }
1574             nDistance += nStep;
1575             if (nDistance > 10)
1576                 nStep *= 2;
1577         }
1578         return nDistance;
1579     }
1580
1581     CBlockIndex* GetBlockIndex()
1582     {
1583         // Find the first block the caller has in the main chain
1584         foreach(const uint256& hash, vHave)
1585         {
1586             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1587             if (mi != mapBlockIndex.end())
1588             {
1589                 CBlockIndex* pindex = (*mi).second;
1590                 if (pindex->IsInMainChain())
1591                     return pindex;
1592             }
1593         }
1594         return pindexGenesisBlock;
1595     }
1596
1597     uint256 GetBlockHash()
1598     {
1599         // Find the first block the caller has in the main chain
1600         foreach(const uint256& hash, vHave)
1601         {
1602             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1603             if (mi != mapBlockIndex.end())
1604             {
1605                 CBlockIndex* pindex = (*mi).second;
1606                 if (pindex->IsInMainChain())
1607                     return hash;
1608             }
1609         }
1610         return hashGenesisBlock;
1611     }
1612
1613     int GetHeight()
1614     {
1615         CBlockIndex* pindex = GetBlockIndex();
1616         if (!pindex)
1617             return 0;
1618         return pindex->nHeight;
1619     }
1620 };
1621
1622
1623
1624
1625
1626
1627 //
1628 // Private key that includes an expiration date in case it never gets used.
1629 //
1630 class CWalletKey
1631 {
1632 public:
1633     CPrivKey vchPrivKey;
1634     int64 nTimeCreated;
1635     int64 nTimeExpires;
1636     string strComment;
1637     //// todo: add something to note what created it (user, getnewaddress, change)
1638     ////   maybe should have a map<string, string> property map
1639
1640     CWalletKey(int64 nExpires=0)
1641     {
1642         nTimeCreated = (nExpires ? GetTime() : 0);
1643         nTimeExpires = nExpires;
1644     }
1645
1646     IMPLEMENT_SERIALIZE
1647     (
1648         if (!(nType & SER_GETHASH))
1649             READWRITE(nVersion);
1650         READWRITE(vchPrivKey);
1651         READWRITE(nTimeCreated);
1652         READWRITE(nTimeExpires);
1653         READWRITE(strComment);
1654     )
1655 };
1656
1657
1658
1659
1660
1661
1662 //
1663 // Account information.
1664 // Stored in wallet with key "acc"+string account name
1665 //
1666 class CAccount
1667 {
1668 public:
1669     vector<unsigned char> vchPubKey;
1670
1671     CAccount()
1672     {
1673         SetNull();
1674     }
1675
1676     void SetNull()
1677     {
1678         vchPubKey.clear();
1679     }
1680
1681     IMPLEMENT_SERIALIZE
1682     (
1683         if (!(nType & SER_GETHASH))
1684             READWRITE(nVersion);
1685         READWRITE(vchPubKey);
1686     )
1687 };
1688
1689
1690
1691 //
1692 // Internal transfers.
1693 // Database key is acentry<account><counter>
1694 //
1695 class CAccountingEntry
1696 {
1697 public:
1698     int64 nCreditDebit;
1699     int64 nTime;
1700     string strOtherAccount;
1701     string strComment;
1702
1703     CAccountingEntry()
1704     {
1705         SetNull();
1706     }
1707
1708     void SetNull()
1709     {
1710         nCreditDebit = 0;
1711         nTime = 0;
1712         strOtherAccount.clear();
1713         strComment.clear();
1714     }
1715
1716     IMPLEMENT_SERIALIZE
1717     (
1718         if (!(nType & SER_GETHASH))
1719             READWRITE(nVersion);
1720         READWRITE(nCreditDebit);
1721         READWRITE(nTime);
1722         READWRITE(strOtherAccount);
1723         READWRITE(strComment);
1724     )
1725 };
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735 //
1736 // Alert messages are broadcast as a vector of signed data.  Unserializing may
1737 // not read the entire buffer if the alert is for a newer version, but older
1738 // versions can still relay the original data.
1739 //
1740 class CUnsignedAlert
1741 {
1742 public:
1743     int nVersion;
1744     int64 nRelayUntil;      // when newer nodes stop relaying to newer nodes
1745     int64 nExpiration;
1746     int nID;
1747     int nCancel;
1748     set<int> setCancel;
1749     int nMinVer;            // lowest version inclusive
1750     int nMaxVer;            // highest version inclusive
1751     set<string> setSubVer;  // empty matches all
1752     int nPriority;
1753
1754     // Actions
1755     string strComment;
1756     string strStatusBar;
1757     string strRPCError;
1758
1759     IMPLEMENT_SERIALIZE
1760     (
1761         READWRITE(this->nVersion);
1762         nVersion = this->nVersion;
1763         READWRITE(nRelayUntil);
1764         READWRITE(nExpiration);
1765         READWRITE(nID);
1766         READWRITE(nCancel);
1767         READWRITE(setCancel);
1768         READWRITE(nMinVer);
1769         READWRITE(nMaxVer);
1770         READWRITE(setSubVer);
1771         READWRITE(nPriority);
1772
1773         READWRITE(strComment);
1774         READWRITE(strStatusBar);
1775         READWRITE(strRPCError);
1776     )
1777
1778     void SetNull()
1779     {
1780         nVersion = 1;
1781         nRelayUntil = 0;
1782         nExpiration = 0;
1783         nID = 0;
1784         nCancel = 0;
1785         setCancel.clear();
1786         nMinVer = 0;
1787         nMaxVer = 0;
1788         setSubVer.clear();
1789         nPriority = 0;
1790
1791         strComment.clear();
1792         strStatusBar.clear();
1793         strRPCError.clear();
1794     }
1795
1796     string ToString() const
1797     {
1798         string strSetCancel;
1799         foreach(int n, setCancel)
1800             strSetCancel += strprintf("%d ", n);
1801         string strSetSubVer;
1802         foreach(string str, setSubVer)
1803             strSetSubVer += "\"" + str + "\" ";
1804         return strprintf(
1805                 "CAlert(\n"
1806                 "    nVersion     = %d\n"
1807                 "    nRelayUntil  = %"PRI64d"\n"
1808                 "    nExpiration  = %"PRI64d"\n"
1809                 "    nID          = %d\n"
1810                 "    nCancel      = %d\n"
1811                 "    setCancel    = %s\n"
1812                 "    nMinVer      = %d\n"
1813                 "    nMaxVer      = %d\n"
1814                 "    setSubVer    = %s\n"
1815                 "    nPriority    = %d\n"
1816                 "    strComment   = \"%s\"\n"
1817                 "    strStatusBar = \"%s\"\n"
1818                 "    strRPCError  = \"%s\"\n"
1819                 ")\n",
1820             nVersion,
1821             nRelayUntil,
1822             nExpiration,
1823             nID,
1824             nCancel,
1825             strSetCancel.c_str(),
1826             nMinVer,
1827             nMaxVer,
1828             strSetSubVer.c_str(),
1829             nPriority,
1830             strComment.c_str(),
1831             strStatusBar.c_str(),
1832             strRPCError.c_str());
1833     }
1834
1835     void print() const
1836     {
1837         printf("%s", ToString().c_str());
1838     }
1839 };
1840
1841 class CAlert : public CUnsignedAlert
1842 {
1843 public:
1844     vector<unsigned char> vchMsg;
1845     vector<unsigned char> vchSig;
1846
1847     CAlert()
1848     {
1849         SetNull();
1850     }
1851
1852     IMPLEMENT_SERIALIZE
1853     (
1854         READWRITE(vchMsg);
1855         READWRITE(vchSig);
1856     )
1857
1858     void SetNull()
1859     {
1860         CUnsignedAlert::SetNull();
1861         vchMsg.clear();
1862         vchSig.clear();
1863     }
1864
1865     bool IsNull() const
1866     {
1867         return (nExpiration == 0);
1868     }
1869
1870     uint256 GetHash() const
1871     {
1872         return SerializeHash(*this);
1873     }
1874
1875     bool IsInEffect() const
1876     {
1877         return (GetAdjustedTime() < nExpiration);
1878     }
1879
1880     bool Cancels(const CAlert& alert) const
1881     {
1882         if (!IsInEffect())
1883             return false; // this was a no-op before 31403
1884         return (alert.nID <= nCancel || setCancel.count(alert.nID));
1885     }
1886
1887     bool AppliesTo(int nVersion, string strSubVerIn) const
1888     {
1889         return (IsInEffect() &&
1890                 nMinVer <= nVersion && nVersion <= nMaxVer &&
1891                 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
1892     }
1893
1894     bool AppliesToMe() const
1895     {
1896         return AppliesTo(VERSION, ::pszSubVer);
1897     }
1898
1899     bool RelayTo(CNode* pnode) const
1900     {
1901         if (!IsInEffect())
1902             return false;
1903         // returns true if wasn't already contained in the set
1904         if (pnode->setKnown.insert(GetHash()).second)
1905         {
1906             if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
1907                 AppliesToMe() ||
1908                 GetAdjustedTime() < nRelayUntil)
1909             {
1910                 pnode->PushMessage("alert", *this);
1911                 return true;
1912             }
1913         }
1914         return false;
1915     }
1916
1917     bool CheckSignature()
1918     {
1919         CKey key;
1920         if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
1921             return error("CAlert::CheckSignature() : SetPubKey failed");
1922         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
1923             return error("CAlert::CheckSignature() : verify signature failed");
1924
1925         // Now unserialize the data
1926         CDataStream sMsg(vchMsg);
1927         sMsg >> *(CUnsignedAlert*)this;
1928         return true;
1929     }
1930
1931     bool ProcessAlert();
1932 };
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943 extern map<uint256, CTransaction> mapTransactions;
1944 extern map<uint256, CWalletTx> mapWallet;
1945 extern vector<uint256> vWalletUpdated;
1946 extern CCriticalSection cs_mapWallet;
1947 extern map<vector<unsigned char>, CPrivKey> mapKeys;
1948 extern map<uint160, vector<unsigned char> > mapPubKeys;
1949 extern CCriticalSection cs_mapKeys;
1950 extern CKey keyUser;