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