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