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