Allow UPnP mapping when USE_UPNP is defined and miniupnpc is installed at build time...
[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 #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     IMPLEMENT_SERIALIZE
748     (
749         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
750         nVersion = this->nVersion;
751         READWRITE(hashBlock);
752         READWRITE(vMerkleBranch);
753         READWRITE(nIndex);
754     )
755
756
757     int SetMerkleBranch(const CBlock* pblock=NULL);
758     int GetDepthInMainChain(int& nHeightRet) const;
759     int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
760     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
761     int GetBlocksToMaturity() const;
762     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
763     bool AcceptToMemoryPool() { CTxDB txdb("r"); return AcceptToMemoryPool(txdb); }
764 };
765
766
767
768
769 //
770 // A transaction with a bunch of additional info that only the owner cares
771 // about.  It includes any unrecorded transactions needed to link it back
772 // to the block chain.
773 //
774 class CWalletTx : public CMerkleTx
775 {
776 public:
777     vector<CMerkleTx> vtxPrev;
778     map<string, string> mapValue;
779     vector<pair<string, string> > vOrderForm;
780     unsigned int fTimeReceivedIsTxTime;
781     unsigned int nTimeReceived;  // time received by this node
782     char fFromMe;
783     char fSpent;
784     string strFromAccount;
785
786     // memory only
787     mutable char fDebitCached;
788     mutable char fCreditCached;
789     mutable char fChangeCached;
790     mutable int64 nDebitCached;
791     mutable int64 nCreditCached;
792     mutable int64 nChangeCached;
793
794     // memory only UI hints
795     mutable unsigned int nTimeDisplayed;
796     mutable int nLinesDisplayed;
797     mutable char fConfirmedDisplayed;
798
799
800     CWalletTx()
801     {
802         Init();
803     }
804
805     CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
806     {
807         Init();
808     }
809
810     CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
811     {
812         Init();
813     }
814
815     void Init()
816     {
817         vtxPrev.clear();
818         mapValue.clear();
819         vOrderForm.clear();
820         fTimeReceivedIsTxTime = false;
821         nTimeReceived = 0;
822         fFromMe = false;
823         fSpent = false;
824         strFromAccount.clear();
825         fDebitCached = false;
826         fCreditCached = false;
827         fChangeCached = false;
828         nDebitCached = 0;
829         nCreditCached = 0;
830         nChangeCached = 0;
831         nTimeDisplayed = 0;
832         nLinesDisplayed = 0;
833         fConfirmedDisplayed = false;
834     }
835
836     IMPLEMENT_SERIALIZE
837     (
838         CWalletTx* pthis = const_cast<CWalletTx*>(this);
839         if (fRead)
840             pthis->Init();
841         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
842         READWRITE(vtxPrev);
843
844         pthis->mapValue["fromaccount"] = pthis->strFromAccount;
845         READWRITE(mapValue);
846         pthis->strFromAccount = pthis->mapValue["fromaccount"];
847         pthis->mapValue.erase("fromaccount");
848         pthis->mapValue.erase("version");
849
850         READWRITE(vOrderForm);
851         READWRITE(fTimeReceivedIsTxTime);
852         READWRITE(nTimeReceived);
853         READWRITE(fFromMe);
854         READWRITE(fSpent);
855     )
856
857     int64 GetDebit() const
858     {
859         if (vin.empty())
860             return 0;
861         if (fDebitCached)
862             return nDebitCached;
863         nDebitCached = CTransaction::GetDebit();
864         fDebitCached = true;
865         return nDebitCached;
866     }
867
868     int64 GetCredit(bool fUseCache=true) const
869     {
870         // Must wait until coinbase is safely deep enough in the chain before valuing it
871         if (IsCoinBase() && GetBlocksToMaturity() > 0)
872             return 0;
873
874         // GetBalance can assume transactions in mapWallet won't change
875         if (fUseCache && fCreditCached)
876             return nCreditCached;
877         nCreditCached = CTransaction::GetCredit();
878         fCreditCached = true;
879         return nCreditCached;
880     }
881
882     int64 GetChange() const
883     {
884         if (fChangeCached)
885             return nChangeCached;
886         nChangeCached = CTransaction::GetChange();
887         fChangeCached = true;
888         return nChangeCached;
889     }
890
891     void GetAmounts(int64& nGenerated, list<pair<string /* address */, int64> >& listReceived,
892                     list<pair<string /* address */, int64> >& listSent, int64& nFee, string& strSentAccount) const;
893
894     void GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, 
895                            int64& nSent, int64& nFee) const;
896
897     bool IsFromMe() const
898     {
899         return (GetDebit() > 0);
900     }
901
902     bool IsConfirmed() const
903     {
904         // Quick answer in most cases
905         if (!IsFinal())
906             return false;
907         if (GetDepthInMainChain() >= 1)
908             return true;
909         if (!IsFromMe()) // using wtx's cached debit
910             return false;
911
912         // If no confirmations but it's from us, we can still
913         // consider it confirmed if all dependencies are confirmed
914         map<uint256, const CMerkleTx*> mapPrev;
915         vector<const CMerkleTx*> vWorkQueue;
916         vWorkQueue.reserve(vtxPrev.size()+1);
917         vWorkQueue.push_back(this);
918         for (int i = 0; i < vWorkQueue.size(); i++)
919         {
920             const CMerkleTx* ptx = vWorkQueue[i];
921
922             if (!ptx->IsFinal())
923                 return false;
924             if (ptx->GetDepthInMainChain() >= 1)
925                 return true;
926             if (!ptx->IsFromMe())
927                 return false;
928
929             if (mapPrev.empty())
930                 foreach(const CMerkleTx& tx, vtxPrev)
931                     mapPrev[tx.GetHash()] = &tx;
932
933             foreach(const CTxIn& txin, ptx->vin)
934             {
935                 if (!mapPrev.count(txin.prevout.hash))
936                     return false;
937                 vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
938             }
939         }
940         return true;
941     }
942
943     bool WriteToDisk()
944     {
945         return CWalletDB().WriteTx(GetHash(), *this);
946     }
947
948
949     int64 GetTxTime() const;
950     int GetRequestCount() const;
951
952     void AddSupportingTransactions(CTxDB& txdb);
953
954     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
955     bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
956
957     void RelayWalletTransaction(CTxDB& txdb);
958     void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
959 };
960
961
962
963
964 //
965 // A txdb record that contains the disk location of a transaction and the
966 // locations of transactions that spend its outputs.  vSpent is really only
967 // used as a flag, but having the location is very helpful for debugging.
968 //
969 class CTxIndex
970 {
971 public:
972     CDiskTxPos pos;
973     vector<CDiskTxPos> vSpent;
974
975     CTxIndex()
976     {
977         SetNull();
978     }
979
980     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
981     {
982         pos = posIn;
983         vSpent.resize(nOutputs);
984     }
985
986     IMPLEMENT_SERIALIZE
987     (
988         if (!(nType & SER_GETHASH))
989             READWRITE(nVersion);
990         READWRITE(pos);
991         READWRITE(vSpent);
992     )
993
994     void SetNull()
995     {
996         pos.SetNull();
997         vSpent.clear();
998     }
999
1000     bool IsNull()
1001     {
1002         return pos.IsNull();
1003     }
1004
1005     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
1006     {
1007         return (a.pos    == b.pos &&
1008                 a.vSpent == b.vSpent);
1009     }
1010
1011     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
1012     {
1013         return !(a == b);
1014     }
1015     int GetDepthInMainChain() const;
1016 };
1017
1018
1019
1020
1021
1022 //
1023 // Nodes collect new transactions into a block, hash them into a hash tree,
1024 // and scan through nonce values to make the block's hash satisfy proof-of-work
1025 // requirements.  When they solve the proof-of-work, they broadcast the block
1026 // to everyone and the block is added to the block chain.  The first transaction
1027 // in the block is a special one that creates a new coin owned by the creator
1028 // of the block.
1029 //
1030 // Blocks are appended to blk0001.dat files on disk.  Their location on disk
1031 // is indexed by CBlockIndex objects in memory.
1032 //
1033 class CBlock
1034 {
1035 public:
1036     // header
1037     int nVersion;
1038     uint256 hashPrevBlock;
1039     uint256 hashMerkleRoot;
1040     unsigned int nTime;
1041     unsigned int nBits;
1042     unsigned int nNonce;
1043
1044     // network and disk
1045     vector<CTransaction> vtx;
1046
1047     // memory only
1048     mutable vector<uint256> vMerkleTree;
1049
1050
1051     CBlock()
1052     {
1053         SetNull();
1054     }
1055
1056     IMPLEMENT_SERIALIZE
1057     (
1058         READWRITE(this->nVersion);
1059         nVersion = this->nVersion;
1060         READWRITE(hashPrevBlock);
1061         READWRITE(hashMerkleRoot);
1062         READWRITE(nTime);
1063         READWRITE(nBits);
1064         READWRITE(nNonce);
1065
1066         // ConnectBlock depends on vtx being last so it can calculate offset
1067         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
1068             READWRITE(vtx);
1069         else if (fRead)
1070             const_cast<CBlock*>(this)->vtx.clear();
1071     )
1072
1073     void SetNull()
1074     {
1075         nVersion = 1;
1076         hashPrevBlock = 0;
1077         hashMerkleRoot = 0;
1078         nTime = 0;
1079         nBits = 0;
1080         nNonce = 0;
1081         vtx.clear();
1082         vMerkleTree.clear();
1083     }
1084
1085     bool IsNull() const
1086     {
1087         return (nBits == 0);
1088     }
1089
1090     uint256 GetHash() const
1091     {
1092         return Hash(BEGIN(nVersion), END(nNonce));
1093     }
1094
1095     int64 GetBlockTime() const
1096     {
1097         return (int64)nTime;
1098     }
1099
1100     int GetSigOpCount() const
1101     {
1102         int n = 0;
1103         foreach(const CTransaction& tx, vtx)
1104             n += tx.GetSigOpCount();
1105         return n;
1106     }
1107
1108
1109     uint256 BuildMerkleTree() const
1110     {
1111         vMerkleTree.clear();
1112         foreach(const CTransaction& tx, vtx)
1113             vMerkleTree.push_back(tx.GetHash());
1114         int j = 0;
1115         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1116         {
1117             for (int i = 0; i < nSize; i += 2)
1118             {
1119                 int i2 = min(i+1, nSize-1);
1120                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
1121                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
1122             }
1123             j += nSize;
1124         }
1125         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
1126     }
1127
1128     vector<uint256> GetMerkleBranch(int nIndex) const
1129     {
1130         if (vMerkleTree.empty())
1131             BuildMerkleTree();
1132         vector<uint256> vMerkleBranch;
1133         int j = 0;
1134         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1135         {
1136             int i = min(nIndex^1, nSize-1);
1137             vMerkleBranch.push_back(vMerkleTree[j+i]);
1138             nIndex >>= 1;
1139             j += nSize;
1140         }
1141         return vMerkleBranch;
1142     }
1143
1144     static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)
1145     {
1146         if (nIndex == -1)
1147             return 0;
1148         foreach(const uint256& otherside, vMerkleBranch)
1149         {
1150             if (nIndex & 1)
1151                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
1152             else
1153                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
1154             nIndex >>= 1;
1155         }
1156         return hash;
1157     }
1158
1159
1160     bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
1161     {
1162         // Open history file to append
1163         CAutoFile fileout = AppendBlockFile(nFileRet);
1164         if (!fileout)
1165             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
1166
1167         // Write index header
1168         unsigned int nSize = fileout.GetSerializeSize(*this);
1169         fileout << FLATDATA(pchMessageStart) << nSize;
1170
1171         // Write block
1172         nBlockPosRet = ftell(fileout);
1173         if (nBlockPosRet == -1)
1174             return error("CBlock::WriteToDisk() : ftell failed");
1175         fileout << *this;
1176
1177         // Flush stdio buffers and commit to disk before returning
1178         fflush(fileout);
1179         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
1180         {
1181 #ifdef __WXMSW__
1182             _commit(_fileno(fileout));
1183 #else
1184             fsync(fileno(fileout));
1185 #endif
1186         }
1187
1188         return true;
1189     }
1190
1191     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
1192     {
1193         SetNull();
1194
1195         // Open history file to read
1196         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
1197         if (!filein)
1198             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
1199         if (!fReadTransactions)
1200             filein.nType |= SER_BLOCKHEADERONLY;
1201
1202         // Read block
1203         filein >> *this;
1204
1205         // Check the header
1206         if (!CheckProofOfWork(GetHash(), nBits))
1207             return error("CBlock::ReadFromDisk() : errors in block header");
1208
1209         return true;
1210     }
1211
1212
1213
1214     void print() const
1215     {
1216         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
1217             GetHash().ToString().substr(0,20).c_str(),
1218             nVersion,
1219             hashPrevBlock.ToString().substr(0,20).c_str(),
1220             hashMerkleRoot.ToString().substr(0,10).c_str(),
1221             nTime, nBits, nNonce,
1222             vtx.size());
1223         for (int i = 0; i < vtx.size(); i++)
1224         {
1225             printf("  ");
1226             vtx[i].print();
1227         }
1228         printf("  vMerkleTree: ");
1229         for (int i = 0; i < vMerkleTree.size(); i++)
1230             printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
1231         printf("\n");
1232     }
1233
1234
1235     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1236     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
1237     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
1238     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
1239     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
1240     bool CheckBlock() const;
1241     bool AcceptBlock();
1242 };
1243
1244
1245
1246
1247
1248
1249 //
1250 // The block chain is a tree shaped structure starting with the
1251 // genesis block at the root, with each block potentially having multiple
1252 // candidates to be the next block.  pprev and pnext link a path through the
1253 // main/longest chain.  A blockindex may have multiple pprev pointing back
1254 // to it, but pnext will only point forward to the longest branch, or will
1255 // be null if the block is not part of the longest chain.
1256 //
1257 class CBlockIndex
1258 {
1259 public:
1260     const uint256* phashBlock;
1261     CBlockIndex* pprev;
1262     CBlockIndex* pnext;
1263     unsigned int nFile;
1264     unsigned int nBlockPos;
1265     int nHeight;
1266     CBigNum bnChainWork;
1267
1268     // block header
1269     int nVersion;
1270     uint256 hashMerkleRoot;
1271     unsigned int nTime;
1272     unsigned int nBits;
1273     unsigned int nNonce;
1274
1275
1276     CBlockIndex()
1277     {
1278         phashBlock = NULL;
1279         pprev = NULL;
1280         pnext = NULL;
1281         nFile = 0;
1282         nBlockPos = 0;
1283         nHeight = 0;
1284         bnChainWork = 0;
1285
1286         nVersion       = 0;
1287         hashMerkleRoot = 0;
1288         nTime          = 0;
1289         nBits          = 0;
1290         nNonce         = 0;
1291     }
1292
1293     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
1294     {
1295         phashBlock = NULL;
1296         pprev = NULL;
1297         pnext = NULL;
1298         nFile = nFileIn;
1299         nBlockPos = nBlockPosIn;
1300         nHeight = 0;
1301         bnChainWork = 0;
1302
1303         nVersion       = block.nVersion;
1304         hashMerkleRoot = block.hashMerkleRoot;
1305         nTime          = block.nTime;
1306         nBits          = block.nBits;
1307         nNonce         = block.nNonce;
1308     }
1309
1310     CBlock GetBlockHeader() const
1311     {
1312         CBlock block;
1313         block.nVersion       = nVersion;
1314         if (pprev)
1315             block.hashPrevBlock = pprev->GetBlockHash();
1316         block.hashMerkleRoot = hashMerkleRoot;
1317         block.nTime          = nTime;
1318         block.nBits          = nBits;
1319         block.nNonce         = nNonce;
1320         return block;
1321     }
1322
1323     uint256 GetBlockHash() const
1324     {
1325         return *phashBlock;
1326     }
1327
1328     int64 GetBlockTime() const
1329     {
1330         return (int64)nTime;
1331     }
1332
1333     CBigNum GetBlockWork() const
1334     {
1335         CBigNum bnTarget;
1336         bnTarget.SetCompact(nBits);
1337         if (bnTarget <= 0)
1338             return 0;
1339         return (CBigNum(1)<<256) / (bnTarget+1);
1340     }
1341
1342     bool IsInMainChain() const
1343     {
1344         return (pnext || this == pindexBest);
1345     }
1346
1347     bool CheckIndex() const
1348     {
1349         return CheckProofOfWork(GetBlockHash(), nBits);
1350     }
1351
1352     bool EraseBlockFromDisk()
1353     {
1354         // Open history file
1355         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1356         if (!fileout)
1357             return false;
1358
1359         // Overwrite with empty null block
1360         CBlock block;
1361         block.SetNull();
1362         fileout << block;
1363
1364         return true;
1365     }
1366
1367     enum { nMedianTimeSpan=11 };
1368
1369     int64 GetMedianTimePast() const
1370     {
1371         int64 pmedian[nMedianTimeSpan];
1372         int64* pbegin = &pmedian[nMedianTimeSpan];
1373         int64* pend = &pmedian[nMedianTimeSpan];
1374
1375         const CBlockIndex* pindex = this;
1376         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1377             *(--pbegin) = pindex->GetBlockTime();
1378
1379         sort(pbegin, pend);
1380         return pbegin[(pend - pbegin)/2];
1381     }
1382
1383     int64 GetMedianTime() const
1384     {
1385         const CBlockIndex* pindex = this;
1386         for (int i = 0; i < nMedianTimeSpan/2; i++)
1387         {
1388             if (!pindex->pnext)
1389                 return GetBlockTime();
1390             pindex = pindex->pnext;
1391         }
1392         return pindex->GetMedianTimePast();
1393     }
1394
1395
1396
1397     string ToString() const
1398     {
1399         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1400             pprev, pnext, nFile, nBlockPos, nHeight,
1401             hashMerkleRoot.ToString().substr(0,10).c_str(),
1402             GetBlockHash().ToString().substr(0,20).c_str());
1403     }
1404
1405     void print() const
1406     {
1407         printf("%s\n", ToString().c_str());
1408     }
1409 };
1410
1411
1412
1413 //
1414 // Used to marshal pointers into hashes for db storage.
1415 //
1416 class CDiskBlockIndex : public CBlockIndex
1417 {
1418 public:
1419     uint256 hashPrev;
1420     uint256 hashNext;
1421
1422     CDiskBlockIndex()
1423     {
1424         hashPrev = 0;
1425         hashNext = 0;
1426     }
1427
1428     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1429     {
1430         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1431         hashNext = (pnext ? pnext->GetBlockHash() : 0);
1432     }
1433
1434     IMPLEMENT_SERIALIZE
1435     (
1436         if (!(nType & SER_GETHASH))
1437             READWRITE(nVersion);
1438
1439         READWRITE(hashNext);
1440         READWRITE(nFile);
1441         READWRITE(nBlockPos);
1442         READWRITE(nHeight);
1443
1444         // block header
1445         READWRITE(this->nVersion);
1446         READWRITE(hashPrev);
1447         READWRITE(hashMerkleRoot);
1448         READWRITE(nTime);
1449         READWRITE(nBits);
1450         READWRITE(nNonce);
1451     )
1452
1453     uint256 GetBlockHash() const
1454     {
1455         CBlock block;
1456         block.nVersion        = nVersion;
1457         block.hashPrevBlock   = hashPrev;
1458         block.hashMerkleRoot  = hashMerkleRoot;
1459         block.nTime           = nTime;
1460         block.nBits           = nBits;
1461         block.nNonce          = nNonce;
1462         return block.GetHash();
1463     }
1464
1465
1466     string ToString() const
1467     {
1468         string str = "CDiskBlockIndex(";
1469         str += CBlockIndex::ToString();
1470         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
1471             GetBlockHash().ToString().c_str(),
1472             hashPrev.ToString().substr(0,20).c_str(),
1473             hashNext.ToString().substr(0,20).c_str());
1474         return str;
1475     }
1476
1477     void print() const
1478     {
1479         printf("%s\n", ToString().c_str());
1480     }
1481 };
1482
1483
1484
1485
1486
1487
1488
1489
1490 //
1491 // Describes a place in the block chain to another node such that if the
1492 // other node doesn't have the same branch, it can find a recent common trunk.
1493 // The further back it is, the further before the fork it may be.
1494 //
1495 class CBlockLocator
1496 {
1497 protected:
1498     vector<uint256> vHave;
1499 public:
1500
1501     CBlockLocator()
1502     {
1503     }
1504
1505     explicit CBlockLocator(const CBlockIndex* pindex)
1506     {
1507         Set(pindex);
1508     }
1509
1510     explicit CBlockLocator(uint256 hashBlock)
1511     {
1512         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1513         if (mi != mapBlockIndex.end())
1514             Set((*mi).second);
1515     }
1516
1517     IMPLEMENT_SERIALIZE
1518     (
1519         if (!(nType & SER_GETHASH))
1520             READWRITE(nVersion);
1521         READWRITE(vHave);
1522     )
1523
1524     void SetNull()
1525     {
1526         vHave.clear();
1527     }
1528
1529     bool IsNull()
1530     {
1531         return vHave.empty();
1532     }
1533
1534     void Set(const CBlockIndex* pindex)
1535     {
1536         vHave.clear();
1537         int nStep = 1;
1538         while (pindex)
1539         {
1540             vHave.push_back(pindex->GetBlockHash());
1541
1542             // Exponentially larger steps back
1543             for (int i = 0; pindex && i < nStep; i++)
1544                 pindex = pindex->pprev;
1545             if (vHave.size() > 10)
1546                 nStep *= 2;
1547         }
1548         vHave.push_back(hashGenesisBlock);
1549     }
1550
1551     int GetDistanceBack()
1552     {
1553         // Retrace how far back it was in the sender's branch
1554         int nDistance = 0;
1555         int nStep = 1;
1556         foreach(const uint256& hash, vHave)
1557         {
1558             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1559             if (mi != mapBlockIndex.end())
1560             {
1561                 CBlockIndex* pindex = (*mi).second;
1562                 if (pindex->IsInMainChain())
1563                     return nDistance;
1564             }
1565             nDistance += nStep;
1566             if (nDistance > 10)
1567                 nStep *= 2;
1568         }
1569         return nDistance;
1570     }
1571
1572     CBlockIndex* GetBlockIndex()
1573     {
1574         // Find the first block the caller has in the main chain
1575         foreach(const uint256& hash, vHave)
1576         {
1577             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1578             if (mi != mapBlockIndex.end())
1579             {
1580                 CBlockIndex* pindex = (*mi).second;
1581                 if (pindex->IsInMainChain())
1582                     return pindex;
1583             }
1584         }
1585         return pindexGenesisBlock;
1586     }
1587
1588     uint256 GetBlockHash()
1589     {
1590         // Find the first block the caller has in the main chain
1591         foreach(const uint256& hash, vHave)
1592         {
1593             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1594             if (mi != mapBlockIndex.end())
1595             {
1596                 CBlockIndex* pindex = (*mi).second;
1597                 if (pindex->IsInMainChain())
1598                     return hash;
1599             }
1600         }
1601         return hashGenesisBlock;
1602     }
1603
1604     int GetHeight()
1605     {
1606         CBlockIndex* pindex = GetBlockIndex();
1607         if (!pindex)
1608             return 0;
1609         return pindex->nHeight;
1610     }
1611 };
1612
1613
1614
1615
1616
1617
1618 //
1619 // Private key that includes an expiration date in case it never gets used.
1620 //
1621 class CWalletKey
1622 {
1623 public:
1624     CPrivKey vchPrivKey;
1625     int64 nTimeCreated;
1626     int64 nTimeExpires;
1627     string strComment;
1628     //// todo: add something to note what created it (user, getnewaddress, change)
1629     ////   maybe should have a map<string, string> property map
1630
1631     CWalletKey(int64 nExpires=0)
1632     {
1633         nTimeCreated = (nExpires ? GetTime() : 0);
1634         nTimeExpires = nExpires;
1635     }
1636
1637     IMPLEMENT_SERIALIZE
1638     (
1639         if (!(nType & SER_GETHASH))
1640             READWRITE(nVersion);
1641         READWRITE(vchPrivKey);
1642         READWRITE(nTimeCreated);
1643         READWRITE(nTimeExpires);
1644         READWRITE(strComment);
1645     )
1646 };
1647
1648
1649
1650
1651
1652
1653 //
1654 // Account information.
1655 // Stored in wallet with key "acc"+string account name
1656 //
1657 class CAccount
1658 {
1659 public:
1660     vector<unsigned char> vchPubKey;
1661
1662     CAccount()
1663     {
1664         SetNull();
1665     }
1666
1667     void SetNull()
1668     {
1669         vchPubKey.clear();
1670     }
1671
1672     IMPLEMENT_SERIALIZE
1673     (
1674         if (!(nType & SER_GETHASH))
1675             READWRITE(nVersion);
1676         READWRITE(vchPubKey);
1677     )
1678 };
1679
1680
1681
1682 //
1683 // Internal transfers.
1684 // Database key is acentry<account><counter>
1685 //
1686 class CAccountingEntry
1687 {
1688 public:
1689     string strAccount;
1690     int64 nCreditDebit;
1691     int64 nTime;
1692     string strOtherAccount;
1693     string strComment;
1694
1695     CAccountingEntry()
1696     {
1697         SetNull();
1698     }
1699
1700     void SetNull()
1701     {
1702         nCreditDebit = 0;
1703         nTime = 0;
1704         strAccount.clear();
1705         strOtherAccount.clear();
1706         strComment.clear();
1707     }
1708
1709     IMPLEMENT_SERIALIZE
1710     (
1711         if (!(nType & SER_GETHASH))
1712             READWRITE(nVersion);
1713         // Note: strAccount is serialized as part of the key, not here.
1714         READWRITE(nCreditDebit);
1715         READWRITE(nTime);
1716         READWRITE(strOtherAccount);
1717         READWRITE(strComment);
1718     )
1719 };
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729 //
1730 // Alerts are for notifying old versions if they become too obsolete and
1731 // need to upgrade.  The message is displayed in the status bar.
1732 // Alert messages are broadcast as a vector of signed data.  Unserializing may
1733 // not read the entire buffer if the alert is for a newer version, but older
1734 // versions can still relay the original data.
1735 //
1736 class CUnsignedAlert
1737 {
1738 public:
1739     int nVersion;
1740     int64 nRelayUntil;      // when newer nodes stop relaying to newer nodes
1741     int64 nExpiration;
1742     int nID;
1743     int nCancel;
1744     set<int> setCancel;
1745     int nMinVer;            // lowest version inclusive
1746     int nMaxVer;            // highest version inclusive
1747     set<string> setSubVer;  // empty matches all
1748     int nPriority;
1749
1750     // Actions
1751     string strComment;
1752     string strStatusBar;
1753     string strReserved;
1754
1755     IMPLEMENT_SERIALIZE
1756     (
1757         READWRITE(this->nVersion);
1758         nVersion = this->nVersion;
1759         READWRITE(nRelayUntil);
1760         READWRITE(nExpiration);
1761         READWRITE(nID);
1762         READWRITE(nCancel);
1763         READWRITE(setCancel);
1764         READWRITE(nMinVer);
1765         READWRITE(nMaxVer);
1766         READWRITE(setSubVer);
1767         READWRITE(nPriority);
1768
1769         READWRITE(strComment);
1770         READWRITE(strStatusBar);
1771         READWRITE(strReserved);
1772     )
1773
1774     void SetNull()
1775     {
1776         nVersion = 1;
1777         nRelayUntil = 0;
1778         nExpiration = 0;
1779         nID = 0;
1780         nCancel = 0;
1781         setCancel.clear();
1782         nMinVer = 0;
1783         nMaxVer = 0;
1784         setSubVer.clear();
1785         nPriority = 0;
1786
1787         strComment.clear();
1788         strStatusBar.clear();
1789         strReserved.clear();
1790     }
1791
1792     string ToString() const
1793     {
1794         string strSetCancel;
1795         foreach(int n, setCancel)
1796             strSetCancel += strprintf("%d ", n);
1797         string strSetSubVer;
1798         foreach(string str, setSubVer)
1799             strSetSubVer += "\"" + str + "\" ";
1800         return strprintf(
1801                 "CAlert(\n"
1802                 "    nVersion     = %d\n"
1803                 "    nRelayUntil  = %"PRI64d"\n"
1804                 "    nExpiration  = %"PRI64d"\n"
1805                 "    nID          = %d\n"
1806                 "    nCancel      = %d\n"
1807                 "    setCancel    = %s\n"
1808                 "    nMinVer      = %d\n"
1809                 "    nMaxVer      = %d\n"
1810                 "    setSubVer    = %s\n"
1811                 "    nPriority    = %d\n"
1812                 "    strComment   = \"%s\"\n"
1813                 "    strStatusBar = \"%s\"\n"
1814                 ")\n",
1815             nVersion,
1816             nRelayUntil,
1817             nExpiration,
1818             nID,
1819             nCancel,
1820             strSetCancel.c_str(),
1821             nMinVer,
1822             nMaxVer,
1823             strSetSubVer.c_str(),
1824             nPriority,
1825             strComment.c_str(),
1826             strStatusBar.c_str());
1827     }
1828
1829     void print() const
1830     {
1831         printf("%s", ToString().c_str());
1832     }
1833 };
1834
1835 class CAlert : public CUnsignedAlert
1836 {
1837 public:
1838     vector<unsigned char> vchMsg;
1839     vector<unsigned char> vchSig;
1840
1841     CAlert()
1842     {
1843         SetNull();
1844     }
1845
1846     IMPLEMENT_SERIALIZE
1847     (
1848         READWRITE(vchMsg);
1849         READWRITE(vchSig);
1850     )
1851
1852     void SetNull()
1853     {
1854         CUnsignedAlert::SetNull();
1855         vchMsg.clear();
1856         vchSig.clear();
1857     }
1858
1859     bool IsNull() const
1860     {
1861         return (nExpiration == 0);
1862     }
1863
1864     uint256 GetHash() const
1865     {
1866         return SerializeHash(*this);
1867     }
1868
1869     bool IsInEffect() const
1870     {
1871         return (GetAdjustedTime() < nExpiration);
1872     }
1873
1874     bool Cancels(const CAlert& alert) const
1875     {
1876         if (!IsInEffect())
1877             return false; // this was a no-op before 31403
1878         return (alert.nID <= nCancel || setCancel.count(alert.nID));
1879     }
1880
1881     bool AppliesTo(int nVersion, string strSubVerIn) const
1882     {
1883         return (IsInEffect() &&
1884                 nMinVer <= nVersion && nVersion <= nMaxVer &&
1885                 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
1886     }
1887
1888     bool AppliesToMe() const
1889     {
1890         return AppliesTo(VERSION, ::pszSubVer);
1891     }
1892
1893     bool RelayTo(CNode* pnode) const
1894     {
1895         if (!IsInEffect())
1896             return false;
1897         // returns true if wasn't already contained in the set
1898         if (pnode->setKnown.insert(GetHash()).second)
1899         {
1900             if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
1901                 AppliesToMe() ||
1902                 GetAdjustedTime() < nRelayUntil)
1903             {
1904                 pnode->PushMessage("alert", *this);
1905                 return true;
1906             }
1907         }
1908         return false;
1909     }
1910
1911     bool CheckSignature()
1912     {
1913         CKey key;
1914         if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
1915             return error("CAlert::CheckSignature() : SetPubKey failed");
1916         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
1917             return error("CAlert::CheckSignature() : verify signature failed");
1918
1919         // Now unserialize the data
1920         CDataStream sMsg(vchMsg);
1921         sMsg >> *(CUnsignedAlert*)this;
1922         return true;
1923     }
1924
1925     bool ProcessAlert();
1926 };
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937 extern map<uint256, CTransaction> mapTransactions;
1938 extern map<uint256, CWalletTx> mapWallet;
1939 extern vector<uint256> vWalletUpdated;
1940 extern CCriticalSection cs_mapWallet;
1941 extern map<vector<unsigned char>, CPrivKey> mapKeys;
1942 extern map<uint160, vector<unsigned char> > mapPubKeys;
1943 extern CCriticalSection cs_mapKeys;
1944 extern CKey keyUser;