genesis                 1 
genesis                 2 
genesis                 3 
genesis                 4 
genesis                 5 #ifndef BITCOIN_MAIN_H
genesis                 6 #define BITCOIN_MAIN_H
genesis                 7 
genesis                 8 #include "bignum.h"
genesis                 9 #include "net.h"
genesis                10 #include "key.h"
genesis                11 #include "script.h"
genesis                12 #include "db.h"
genesis                13 
genesis                14 #include <list>
genesis                15 
genesis                16 class CBlock;
genesis                17 class CBlockIndex;
genesis                18 class CWalletTx;
genesis                19 class CWallet;
genesis                20 class CKeyItem;
genesis                21 class CReserveKey;
genesis                22 class CWalletDB;
genesis                23 
genesis                24 class CAddress;
genesis                25 class CInv;
genesis                26 class CRequestTracker;
genesis                27 class CNode;
genesis                28 class CBlockIndex;
genesis                29 
genesis                30 static const unsigned int MAX_BLOCK_SIZE = 1000000;
genesis                31 static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
genesis                32 static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
genesis                33 static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
genesis                34 static const int64 COIN = 100000000;
genesis                35 static const int64 CENT = 1000000;
genesis                36 static const int64 MIN_TX_FEE = 50000;
genesis                37 static const int64 MIN_RELAY_TX_FEE = 10000;
genesis                38 static const int64 MAX_MONEY = 21000000 * COIN;
genesis                39 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
genesis                40 static const int COINBASE_MATURITY = 100;
genesis                41 
genesis                42 static const int LOCKTIME_THRESHOLD = 500000000; 
genesis                43 #ifdef USE_UPNP
genesis                44 static const int fHaveUPnP = true;
genesis                45 #else
genesis                46 static const int fHaveUPnP = false;
genesis                47 #endif
genesis                48 
genesis                49 
genesis                50 
genesis                51 
genesis                52 
genesis                53 
genesis                54 extern CCriticalSection cs_main;
genesis                55 extern std::map<uint256, CBlockIndex*> mapBlockIndex;
genesis                56 extern uint256 hashGenesisBlock;
genesis                57 extern CBlockIndex* pindexGenesisBlock;
genesis                58 extern int nBestHeight;
genesis                59 extern CBigNum bnBestChainWork;
genesis                60 extern CBigNum bnBestInvalidWork;
genesis                61 extern uint256 hashBestChain;
genesis                62 extern CBlockIndex* pindexBest;
genesis                63 extern unsigned int nTransactionsUpdated;
genesis                64 extern double dHashesPerSec;
genesis                65 extern int64 nHPSTimerStart;
genesis                66 extern int64 nTimeBestReceived;
genesis                67 extern CCriticalSection cs_setpwalletRegistered;
genesis                68 extern std::set<CWallet*> setpwalletRegistered;
genesis                69 
genesis                70 
genesis                71 extern int fGenerateBitcoins;
genesis                72 extern int64 nTransactionFee;
genesis                73 extern int fLimitProcessors;
genesis                74 extern int nLimitProcessors;
genesis                75 extern int fMinimizeToTray;
genesis                76 extern int fMinimizeOnClose;
genesis                77 extern int fUseUPnP;
genesis                78 
genesis                79 
genesis                80 
genesis                81 
genesis                82 
genesis                83 class CReserveKey;
genesis                84 class CTxDB;
genesis                85 class CTxIndex;
genesis                86 
genesis                87 void RegisterWallet(CWallet* pwalletIn);
genesis                88 void UnregisterWallet(CWallet* pwalletIn);
genesis                89 bool ProcessBlock(CNode* pfrom, CBlock* pblock);
genesis                90 bool CheckDiskSpace(uint64 nAdditionalBytes=0);
genesis                91 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
genesis                92 FILE* AppendBlockFile(unsigned int& nFileRet);
genesis                93 bool LoadBlockIndex(bool fAllowNew=true);
genesis                94 void PrintBlockTree();
genesis                95 bool ProcessMessages(CNode* pfrom);
genesis                96 bool SendMessages(CNode* pto, bool fSendTrickle);
genesis                97 void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
genesis                98 CBlock* CreateNewBlock(CReserveKey& reservekey);
genesis                99 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
genesis               100 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
genesis               101 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
genesis               102 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
genesis               103 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
genesis               104 int GetNumBlocksOfPeers();
genesis               105 bool IsInitialBlockDownload();
genesis               106 std::string GetWarnings(std::string strFor);
genesis               107 
genesis               108 
genesis               109 
genesis               110 
genesis               111 
genesis               112 
genesis               113 
genesis               114 
genesis               115 
genesis               116 
genesis               117 
genesis               118 
genesis               119 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
genesis               120 
genesis               121 template<typename T>
genesis               122 bool WriteSetting(const std::string& strKey, const T& value)
genesis               123 {
genesis               124     bool fOk = false;
genesis               125     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               126     {
genesis               127         std::string strWalletFile;
genesis               128         if (!GetWalletFile(pwallet, strWalletFile))
genesis               129             continue;
genesis               130         fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
genesis               131     }
genesis               132     return fOk;
genesis               133 }
genesis               134 
genesis               135 
genesis               136 class CDiskTxPos
genesis               137 {
genesis               138 public:
genesis               139     unsigned int nFile;
genesis               140     unsigned int nBlockPos;
genesis               141     unsigned int nTxPos;
genesis               142 
genesis               143     CDiskTxPos()
genesis               144     {
genesis               145         SetNull();
genesis               146     }
genesis               147 
genesis               148     CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
genesis               149     {
genesis               150         nFile = nFileIn;
genesis               151         nBlockPos = nBlockPosIn;
genesis               152         nTxPos = nTxPosIn;
genesis               153     }
genesis               154 
genesis               155     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
genesis               156     void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
genesis               157     bool IsNull() const { return (nFile == -1); }
genesis               158 
genesis               159     friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
genesis               160     {
genesis               161         return (a.nFile     == b.nFile &&
genesis               162                 a.nBlockPos == b.nBlockPos &&
genesis               163                 a.nTxPos    == b.nTxPos);
genesis               164     }
genesis               165 
genesis               166     friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
genesis               167     {
genesis               168         return !(a == b);
genesis               169     }
genesis               170 
genesis               171     std::string ToString() const
genesis               172     {
genesis               173         if (IsNull())
genesis               174             return strprintf("null");
genesis               175         else
genesis               176             return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
genesis               177     }
genesis               178 
genesis               179     void print() const
genesis               180     {
genesis               181         printf("%s", ToString().c_str());
genesis               182     }
genesis               183 };
genesis               184 
genesis               185 
genesis               186 
genesis               187 
genesis               188 class CInPoint
genesis               189 {
genesis               190 public:
genesis               191     CTransaction* ptx;
genesis               192     unsigned int n;
genesis               193 
genesis               194     CInPoint() { SetNull(); }
genesis               195     CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
genesis               196     void SetNull() { ptx = NULL; n = -1; }
genesis               197     bool IsNull() const { return (ptx == NULL && n == -1); }
genesis               198 };
genesis               199 
genesis               200 
genesis               201 
genesis               202 
genesis               203 class COutPoint
genesis               204 {
genesis               205 public:
genesis               206     uint256 hash;
genesis               207     unsigned int n;
genesis               208 
genesis               209     COutPoint() { SetNull(); }
genesis               210     COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
genesis               211     IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
genesis               212     void SetNull() { hash = 0; n = -1; }
genesis               213     bool IsNull() const { return (hash == 0 && n == -1); }
genesis               214 
genesis               215     friend bool operator<(const COutPoint& a, const COutPoint& b)
genesis               216     {
genesis               217         return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
genesis               218     }
genesis               219 
genesis               220     friend bool operator==(const COutPoint& a, const COutPoint& b)
genesis               221     {
genesis               222         return (a.hash == b.hash && a.n == b.n);
genesis               223     }
genesis               224 
genesis               225     friend bool operator!=(const COutPoint& a, const COutPoint& b)
genesis               226     {
genesis               227         return !(a == b);
genesis               228     }
genesis               229 
genesis               230     std::string ToString() const
genesis               231     {
genesis               232         return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
genesis               233     }
genesis               234 
genesis               235     void print() const
genesis               236     {
genesis               237         printf("%s\n", ToString().c_str());
genesis               238     }
genesis               239 };
genesis               240 
genesis               241 
genesis               242 
genesis               243 
genesis               244 
genesis               245 
genesis               246 
genesis               247 
genesis               248 
genesis               249 class CTxIn
genesis               250 {
genesis               251 public:
genesis               252     COutPoint prevout;
genesis               253     CScript scriptSig;
genesis               254     unsigned int nSequence;
genesis               255 
genesis               256     CTxIn()
genesis               257     {
genesis               258         nSequence = UINT_MAX;
genesis               259     }
genesis               260 
genesis               261     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
genesis               262     {
genesis               263         prevout = prevoutIn;
genesis               264         scriptSig = scriptSigIn;
genesis               265         nSequence = nSequenceIn;
genesis               266     }
genesis               267 
genesis               268     CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
genesis               269     {
genesis               270         prevout = COutPoint(hashPrevTx, nOut);
genesis               271         scriptSig = scriptSigIn;
genesis               272         nSequence = nSequenceIn;
genesis               273     }
genesis               274 
genesis               275     IMPLEMENT_SERIALIZE
genesis               276     (
genesis               277         READWRITE(prevout);
genesis               278         READWRITE(scriptSig);
genesis               279         READWRITE(nSequence);
genesis               280     )
genesis               281 
genesis               282     bool IsFinal() const
genesis               283     {
genesis               284         return (nSequence == UINT_MAX);
genesis               285     }
genesis               286 
genesis               287     friend bool operator==(const CTxIn& a, const CTxIn& b)
genesis               288     {
genesis               289         return (a.prevout   == b.prevout &&
genesis               290                 a.scriptSig == b.scriptSig &&
genesis               291                 a.nSequence == b.nSequence);
genesis               292     }
genesis               293 
genesis               294     friend bool operator!=(const CTxIn& a, const CTxIn& b)
genesis               295     {
genesis               296         return !(a == b);
genesis               297     }
genesis               298 
genesis               299     std::string ToString() const
genesis               300     {
genesis               301         std::string str;
genesis               302         str += strprintf("CTxIn(");
genesis               303         str += prevout.ToString();
genesis               304         if (prevout.IsNull())
genesis               305             str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
genesis               306         else
genesis               307             str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
genesis               308         if (nSequence != UINT_MAX)
genesis               309             str += strprintf(", nSequence=%u", nSequence);
genesis               310         str += ")";
genesis               311         return str;
genesis               312     }
genesis               313 
genesis               314     void print() const
genesis               315     {
genesis               316         printf("%s\n", ToString().c_str());
genesis               317     }
genesis               318 };
genesis               319 
genesis               320 
genesis               321 
genesis               322 
genesis               323 
genesis               324 
genesis               325 
genesis               326 
genesis               327 class CTxOut
genesis               328 {
genesis               329 public:
genesis               330     int64 nValue;
genesis               331     CScript scriptPubKey;
genesis               332 
genesis               333     CTxOut()
genesis               334     {
genesis               335         SetNull();
genesis               336     }
genesis               337 
genesis               338     CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
genesis               339     {
genesis               340         nValue = nValueIn;
genesis               341         scriptPubKey = scriptPubKeyIn;
genesis               342     }
genesis               343 
genesis               344     IMPLEMENT_SERIALIZE
genesis               345     (
genesis               346         READWRITE(nValue);
genesis               347         READWRITE(scriptPubKey);
genesis               348     )
genesis               349 
genesis               350     void SetNull()
genesis               351     {
genesis               352         nValue = -1;
genesis               353         scriptPubKey.clear();
genesis               354     }
genesis               355 
genesis               356     bool IsNull()
genesis               357     {
genesis               358         return (nValue == -1);
genesis               359     }
genesis               360 
genesis               361     uint256 GetHash() const
genesis               362     {
genesis               363         return SerializeHash(*this);
genesis               364     }
genesis               365 
genesis               366     friend bool operator==(const CTxOut& a, const CTxOut& b)
genesis               367     {
genesis               368         return (a.nValue       == b.nValue &&
genesis               369                 a.scriptPubKey == b.scriptPubKey);
genesis               370     }
genesis               371 
genesis               372     friend bool operator!=(const CTxOut& a, const CTxOut& b)
genesis               373     {
genesis               374         return !(a == b);
genesis               375     }
genesis               376 
genesis               377     std::string ToString() const
genesis               378     {
genesis               379         if (scriptPubKey.size() < 6)
genesis               380             return "CTxOut(error)";
genesis               381         return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
genesis               382     }
genesis               383 
genesis               384     void print() const
genesis               385     {
genesis               386         printf("%s\n", ToString().c_str());
genesis               387     }
genesis               388 };
genesis               389 
genesis               390 
genesis               391 
genesis               392 
genesis               393 
genesis               394 
genesis               395 
genesis               396 
genesis               397 class CTransaction
genesis               398 {
genesis               399 public:
genesis               400     int nVersion;
genesis               401     std::vector<CTxIn> vin;
genesis               402     std::vector<CTxOut> vout;
genesis               403     unsigned int nLockTime;
genesis               404 
genesis               405     
genesis               406     mutable int nDoS;
genesis               407     bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
genesis               408 
genesis               409     CTransaction()
genesis               410     {
genesis               411         SetNull();
genesis               412     }
genesis               413 
genesis               414     IMPLEMENT_SERIALIZE
genesis               415     (
genesis               416         READWRITE(this->nVersion);
genesis               417         nVersion = this->nVersion;
genesis               418         READWRITE(vin);
genesis               419         READWRITE(vout);
genesis               420         READWRITE(nLockTime);
genesis               421     )
genesis               422 
genesis               423     void SetNull()
genesis               424     {
genesis               425         nVersion = 1;
genesis               426         vin.clear();
genesis               427         vout.clear();
genesis               428         nLockTime = 0;
genesis               429         nDoS = 0;  
genesis               430     }
genesis               431 
genesis               432     bool IsNull() const
genesis               433     {
genesis               434         return (vin.empty() && vout.empty());
genesis               435     }
genesis               436 
genesis               437     uint256 GetHash() const
genesis               438     {
genesis               439         return SerializeHash(*this);
genesis               440     }
genesis               441 
genesis               442     bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
genesis               443     {
genesis               444         
genesis               445         if (nLockTime == 0)
genesis               446             return true;
genesis               447         if (nBlockHeight == 0)
genesis               448             nBlockHeight = nBestHeight;
genesis               449         if (nBlockTime == 0)
genesis               450             nBlockTime = GetAdjustedTime();
genesis               451         if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
genesis               452             return true;
genesis               453         BOOST_FOREACH(const CTxIn& txin, vin)
genesis               454             if (!txin.IsFinal())
genesis               455                 return false;
genesis               456         return true;
genesis               457     }
genesis               458 
genesis               459     bool IsNewerThan(const CTransaction& old) const
genesis               460     {
genesis               461         if (vin.size() != old.vin.size())
genesis               462             return false;
genesis               463         for (int i = 0; i < vin.size(); i++)
genesis               464             if (vin[i].prevout != old.vin[i].prevout)
genesis               465                 return false;
genesis               466 
genesis               467         bool fNewer = false;
genesis               468         unsigned int nLowest = UINT_MAX;
genesis               469         for (int i = 0; i < vin.size(); i++)
genesis               470         {
genesis               471             if (vin[i].nSequence != old.vin[i].nSequence)
genesis               472             {
genesis               473                 if (vin[i].nSequence <= nLowest)
genesis               474                 {
genesis               475                     fNewer = false;
genesis               476                     nLowest = vin[i].nSequence;
genesis               477                 }
genesis               478                 if (old.vin[i].nSequence < nLowest)
genesis               479                 {
genesis               480                     fNewer = true;
genesis               481                     nLowest = old.vin[i].nSequence;
genesis               482                 }
genesis               483             }
genesis               484         }
genesis               485         return fNewer;
genesis               486     }
genesis               487 
genesis               488     bool IsCoinBase() const
genesis               489     {
genesis               490         return (vin.size() == 1 && vin[0].prevout.IsNull());
genesis               491     }
genesis               492 
genesis               493     int GetSigOpCount() const
genesis               494     {
genesis               495         int n = 0;
genesis               496         BOOST_FOREACH(const CTxIn& txin, vin)
genesis               497             n += txin.scriptSig.GetSigOpCount();
genesis               498         BOOST_FOREACH(const CTxOut& txout, vout)
genesis               499             n += txout.scriptPubKey.GetSigOpCount();
genesis               500         return n;
genesis               501     }
genesis               502 
genesis               503     bool IsStandard() const
genesis               504     {
genesis               505         BOOST_FOREACH(const CTxIn& txin, vin)
genesis               506             if (!txin.scriptSig.IsPushOnly())
genesis               507                 return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
genesis               508         BOOST_FOREACH(const CTxOut& txout, vout)
genesis               509             if (!::IsStandard(txout.scriptPubKey))
genesis               510                 return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
genesis               511         return true;
genesis               512     }
genesis               513 
genesis               514     int64 GetValueOut() const
genesis               515     {
genesis               516         int64 nValueOut = 0;
genesis               517         BOOST_FOREACH(const CTxOut& txout, vout)
genesis               518         {
genesis               519             nValueOut += txout.nValue;
genesis               520             if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
genesis               521                 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
genesis               522         }
genesis               523         return nValueOut;
genesis               524     }
genesis               525 
genesis               526     static bool AllowFree(double dPriority)
genesis               527     {
genesis               528         
genesis               529         
genesis               530         return dPriority > COIN * 144 / 250;
genesis               531     }
genesis               532 
genesis               533     int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
genesis               534     {
genesis               535         
genesis               536         int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
genesis               537 
genesis               538         unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
genesis               539         unsigned int nNewBlockSize = nBlockSize + nBytes;
genesis               540         int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
genesis               541 
genesis               542         if (fAllowFree)
genesis               543         {
genesis               544             if (nBlockSize == 1)
genesis               545             {
genesis               546                 
genesis               547                 
genesis               548                 if (nBytes < 10000)
genesis               549                     nMinFee = 0;
genesis               550             }
genesis               551             else
genesis               552             {
genesis               553                 
genesis               554                 if (nNewBlockSize < 27000)
genesis               555                     nMinFee = 0;
genesis               556             }
genesis               557         }
genesis               558 
genesis               559         
genesis               560         if (nMinFee < nBaseFee)
genesis               561             BOOST_FOREACH(const CTxOut& txout, vout)
genesis               562                 if (txout.nValue < CENT)
genesis               563                     nMinFee = nBaseFee;
genesis               564 
genesis               565         
genesis               566         if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
genesis               567         {
genesis               568             if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
genesis               569                 return MAX_MONEY;
genesis               570             nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
genesis               571         }
genesis               572 
genesis               573         if (!MoneyRange(nMinFee))
genesis               574             nMinFee = MAX_MONEY;
genesis               575         return nMinFee;
genesis               576     }
genesis               577 
genesis               578 
genesis               579     bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
genesis               580     {
genesis               581         CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
genesis               582         if (!filein)
genesis               583             return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
genesis               584 
genesis               585         
genesis               586         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
genesis               587             return error("CTransaction::ReadFromDisk() : fseek failed");
genesis               588         filein >> *this;
genesis               589 
genesis               590         
genesis               591         if (pfileRet)
genesis               592         {
genesis               593             if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
genesis               594                 return error("CTransaction::ReadFromDisk() : second fseek failed");
genesis               595             *pfileRet = filein.release();
genesis               596         }
genesis               597         return true;
genesis               598     }
genesis               599 
genesis               600     friend bool operator==(const CTransaction& a, const CTransaction& b)
genesis               601     {
genesis               602         return (a.nVersion  == b.nVersion &&
genesis               603                 a.vin       == b.vin &&
genesis               604                 a.vout      == b.vout &&
genesis               605                 a.nLockTime == b.nLockTime);
genesis               606     }
genesis               607 
genesis               608     friend bool operator!=(const CTransaction& a, const CTransaction& b)
genesis               609     {
genesis               610         return !(a == b);
genesis               611     }
genesis               612 
genesis               613 
genesis               614     std::string ToString() const
genesis               615     {
genesis               616         std::string str;
genesis               617         str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
genesis               618             GetHash().ToString().substr(0,10).c_str(),
genesis               619             nVersion,
genesis               620             vin.size(),
genesis               621             vout.size(),
genesis               622             nLockTime);
genesis               623         for (int i = 0; i < vin.size(); i++)
genesis               624             str += "    " + vin[i].ToString() + "\n";
genesis               625         for (int i = 0; i < vout.size(); i++)
genesis               626             str += "    " + vout[i].ToString() + "\n";
genesis               627         return str;
genesis               628     }
genesis               629 
genesis               630     void print() const
genesis               631     {
genesis               632         printf("%s", ToString().c_str());
genesis               633     }
genesis               634 
genesis               635 
genesis               636     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
genesis               637     bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
genesis               638     bool ReadFromDisk(COutPoint prevout);
genesis               639     bool DisconnectInputs(CTxDB& txdb);
genesis               640     bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
genesis               641                        CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
genesis               642                        bool& fInvalid);
genesis               643     bool ClientConnectInputs();
genesis               644     bool CheckTransaction() const;
genesis               645     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis               646     bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
genesis               647 protected:
genesis               648     bool AddToMemoryPoolUnchecked();
genesis               649 public:
genesis               650     bool RemoveFromMemoryPool();
genesis               651 };
genesis               652 
genesis               653 
genesis               654 
genesis               655 
genesis               656 
genesis               657 
genesis               658 
genesis               659 
genesis               660 class CMerkleTx : public CTransaction
genesis               661 {
genesis               662 public:
genesis               663     uint256 hashBlock;
genesis               664     std::vector<uint256> vMerkleBranch;
genesis               665     int nIndex;
genesis               666 
genesis               667     
genesis               668     mutable char fMerkleVerified;
genesis               669 
genesis               670 
genesis               671     CMerkleTx()
genesis               672     {
genesis               673         Init();
genesis               674     }
genesis               675 
genesis               676     CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
genesis               677     {
genesis               678         Init();
genesis               679     }
genesis               680 
genesis               681     void Init()
genesis               682     {
genesis               683         hashBlock = 0;
genesis               684         nIndex = -1;
genesis               685         fMerkleVerified = false;
genesis               686     }
genesis               687 
genesis               688 
genesis               689     IMPLEMENT_SERIALIZE
genesis               690     (
genesis               691         nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
genesis               692         nVersion = this->nVersion;
genesis               693         READWRITE(hashBlock);
genesis               694         READWRITE(vMerkleBranch);
genesis               695         READWRITE(nIndex);
genesis               696     )
genesis               697 
genesis               698 
genesis               699     int SetMerkleBranch(const CBlock* pblock=NULL);
genesis               700     int GetDepthInMainChain(int& nHeightRet) const;
genesis               701     int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
genesis               702     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
genesis               703     int GetBlocksToMaturity() const;
genesis               704     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
genesis               705     bool AcceptToMemoryPool();
genesis               706 };
genesis               707 
genesis               708 
genesis               709 
genesis               710 
genesis               711 
genesis               712 
genesis               713 
genesis               714 
genesis               715 
genesis               716 class CTxIndex
genesis               717 {
genesis               718 public:
genesis               719     CDiskTxPos pos;
genesis               720     std::vector<CDiskTxPos> vSpent;
genesis               721 
genesis               722     CTxIndex()
genesis               723     {
genesis               724         SetNull();
genesis               725     }
genesis               726 
genesis               727     CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
genesis               728     {
genesis               729         pos = posIn;
genesis               730         vSpent.resize(nOutputs);
genesis               731     }
genesis               732 
genesis               733     IMPLEMENT_SERIALIZE
genesis               734     (
genesis               735         if (!(nType & SER_GETHASH))
genesis               736             READWRITE(nVersion);
genesis               737         READWRITE(pos);
genesis               738         READWRITE(vSpent);
genesis               739     )
genesis               740 
genesis               741     void SetNull()
genesis               742     {
genesis               743         pos.SetNull();
genesis               744         vSpent.clear();
genesis               745     }
genesis               746 
genesis               747     bool IsNull()
genesis               748     {
genesis               749         return pos.IsNull();
genesis               750     }
genesis               751 
genesis               752     friend bool operator==(const CTxIndex& a, const CTxIndex& b)
genesis               753     {
genesis               754         return (a.pos    == b.pos &&
genesis               755                 a.vSpent == b.vSpent);
genesis               756     }
genesis               757 
genesis               758     friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
genesis               759     {
genesis               760         return !(a == b);
genesis               761     }
genesis               762     int GetDepthInMainChain() const;
genesis               763 };
genesis               764 
genesis               765 
genesis               766 
genesis               767 
genesis               768 
genesis               769 
genesis               770 
genesis               771 
genesis               772 
genesis               773 
genesis               774 
genesis               775 
genesis               776 
genesis               777 
genesis               778 
genesis               779 
genesis               780 class CBlock
genesis               781 {
genesis               782 public:
genesis               783     
genesis               784     int nVersion;
genesis               785     uint256 hashPrevBlock;
genesis               786     uint256 hashMerkleRoot;
genesis               787     unsigned int nTime;
genesis               788     unsigned int nBits;
genesis               789     unsigned int nNonce;
genesis               790 
genesis               791     
genesis               792     std::vector<CTransaction> vtx;
genesis               793 
genesis               794     
genesis               795     mutable std::vector<uint256> vMerkleTree;
genesis               796 
genesis               797     
genesis               798     mutable int nDoS;
genesis               799     bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
genesis               800 
genesis               801     CBlock()
genesis               802     {
genesis               803         SetNull();
genesis               804     }
genesis               805 
genesis               806     IMPLEMENT_SERIALIZE
genesis               807     (
genesis               808         READWRITE(this->nVersion);
genesis               809         nVersion = this->nVersion;
genesis               810         READWRITE(hashPrevBlock);
genesis               811         READWRITE(hashMerkleRoot);
genesis               812         READWRITE(nTime);
genesis               813         READWRITE(nBits);
genesis               814         READWRITE(nNonce);
genesis               815 
genesis               816         
genesis               817         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
genesis               818             READWRITE(vtx);
genesis               819         else if (fRead)
genesis               820             const_cast<CBlock*>(this)->vtx.clear();
genesis               821     )
genesis               822 
genesis               823     void SetNull()
genesis               824     {
genesis               825         nVersion = 1;
genesis               826         hashPrevBlock = 0;
genesis               827         hashMerkleRoot = 0;
genesis               828         nTime = 0;
genesis               829         nBits = 0;
genesis               830         nNonce = 0;
genesis               831         vtx.clear();
genesis               832         vMerkleTree.clear();
genesis               833         nDoS = 0;
genesis               834     }
genesis               835 
genesis               836     bool IsNull() const
genesis               837     {
genesis               838         return (nBits == 0);
genesis               839     }
genesis               840 
genesis               841     uint256 GetHash() const
genesis               842     {
genesis               843         return Hash(BEGIN(nVersion), END(nNonce));
genesis               844     }
genesis               845 
genesis               846     int64 GetBlockTime() const
genesis               847     {
genesis               848         return (int64)nTime;
genesis               849     }
genesis               850 
genesis               851     int GetSigOpCount() const
genesis               852     {
genesis               853         int n = 0;
genesis               854         BOOST_FOREACH(const CTransaction& tx, vtx)
genesis               855             n += tx.GetSigOpCount();
genesis               856         return n;
genesis               857     }
genesis               858 
genesis               859 
genesis               860     uint256 BuildMerkleTree() const
genesis               861     {
genesis               862         vMerkleTree.clear();
genesis               863         BOOST_FOREACH(const CTransaction& tx, vtx)
genesis               864             vMerkleTree.push_back(tx.GetHash());
genesis               865         int j = 0;
genesis               866         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis               867         {
genesis               868             for (int i = 0; i < nSize; i += 2)
genesis               869             {
genesis               870                 int i2 = std::min(i+1, nSize-1);
genesis               871                 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
genesis               872                                            BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
genesis               873             }
genesis               874             j += nSize;
genesis               875         }
genesis               876         return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
genesis               877     }
genesis               878 
genesis               879     std::vector<uint256> GetMerkleBranch(int nIndex) const
genesis               880     {
genesis               881         if (vMerkleTree.empty())
genesis               882             BuildMerkleTree();
genesis               883         std::vector<uint256> vMerkleBranch;
genesis               884         int j = 0;
genesis               885         for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
genesis               886         {
genesis               887             int i = std::min(nIndex^1, nSize-1);
genesis               888             vMerkleBranch.push_back(vMerkleTree[j+i]);
genesis               889             nIndex >>= 1;
genesis               890             j += nSize;
genesis               891         }
genesis               892         return vMerkleBranch;
genesis               893     }
genesis               894 
genesis               895     static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
genesis               896     {
genesis               897         if (nIndex == -1)
genesis               898             return 0;
genesis               899         BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
genesis               900         {
genesis               901             if (nIndex & 1)
genesis               902                 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
genesis               903             else
genesis               904                 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
genesis               905             nIndex >>= 1;
genesis               906         }
genesis               907         return hash;
genesis               908     }
genesis               909 
genesis               910 
genesis               911     bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
genesis               912     {
genesis               913         
genesis               914         CAutoFile fileout = AppendBlockFile(nFileRet);
genesis               915         if (!fileout)
genesis               916             return error("CBlock::WriteToDisk() : AppendBlockFile failed");
genesis               917 
genesis               918         
genesis               919         unsigned int nSize = fileout.GetSerializeSize(*this);
genesis               920         fileout << FLATDATA(pchMessageStart) << nSize;
genesis               921 
genesis               922         
genesis               923         nBlockPosRet = ftell(fileout);
genesis               924         if (nBlockPosRet == -1)
genesis               925             return error("CBlock::WriteToDisk() : ftell failed");
genesis               926         fileout << *this;
genesis               927 
genesis               928         
genesis               929         fflush(fileout);
genesis               930         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
genesis               931         {
genesis               932 #ifdef WIN32
genesis               933             _commit(_fileno(fileout));
genesis               934 #else
genesis               935             fsync(fileno(fileout));
genesis               936 #endif
genesis               937         }
genesis               938 
genesis               939         return true;
genesis               940     }
genesis               941 
genesis               942     bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
genesis               943     {
genesis               944         SetNull();
genesis               945 
genesis               946         
genesis               947         CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
genesis               948         if (!filein)
genesis               949             return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
genesis               950         if (!fReadTransactions)
genesis               951             filein.nType |= SER_BLOCKHEADERONLY;
genesis               952 
genesis               953         
genesis               954         filein >> *this;
genesis               955 
genesis               956         
genesis               957         if (!CheckProofOfWork(GetHash(), nBits))
genesis               958             return error("CBlock::ReadFromDisk() : errors in block header");
genesis               959 
genesis               960         return true;
genesis               961     }
genesis               962 
genesis               963 
genesis               964 
genesis               965     void print() const
genesis               966     {
genesis               967         printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
genesis               968             GetHash().ToString().substr(0,20).c_str(),
genesis               969             nVersion,
genesis               970             hashPrevBlock.ToString().substr(0,20).c_str(),
genesis               971             hashMerkleRoot.ToString().substr(0,10).c_str(),
genesis               972             nTime, nBits, nNonce,
genesis               973             vtx.size());
genesis               974         for (int i = 0; i < vtx.size(); i++)
genesis               975         {
genesis               976             printf("  ");
genesis               977             vtx[i].print();
genesis               978         }
genesis               979         printf("  vMerkleTree: ");
genesis               980         for (int i = 0; i < vMerkleTree.size(); i++)
genesis               981             printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
genesis               982         printf("\n");
genesis               983     }
genesis               984 
genesis               985 
genesis               986     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis               987     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
genesis               988     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
genesis               989     bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
genesis               990     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
genesis               991     bool CheckBlock() const;
genesis               992     bool AcceptBlock();
genesis               993 };
genesis               994 
genesis               995 
genesis               996 
genesis               997 
genesis               998 
genesis               999 
genesis              1000 
genesis              1001 
genesis              1002 
genesis              1003 
genesis              1004 
genesis              1005 
genesis              1006 
genesis              1007 
genesis              1008 class CBlockIndex
genesis              1009 {
genesis              1010 public:
genesis              1011     const uint256* phashBlock;
genesis              1012     CBlockIndex* pprev;
genesis              1013     CBlockIndex* pnext;
genesis              1014     unsigned int nFile;
genesis              1015     unsigned int nBlockPos;
genesis              1016     int nHeight;
genesis              1017     CBigNum bnChainWork;
genesis              1018 
genesis              1019     
genesis              1020     int nVersion;
genesis              1021     uint256 hashMerkleRoot;
genesis              1022     unsigned int nTime;
genesis              1023     unsigned int nBits;
genesis              1024     unsigned int nNonce;
genesis              1025 
genesis              1026 
genesis              1027     CBlockIndex()
genesis              1028     {
genesis              1029         phashBlock = NULL;
genesis              1030         pprev = NULL;
genesis              1031         pnext = NULL;
genesis              1032         nFile = 0;
genesis              1033         nBlockPos = 0;
genesis              1034         nHeight = 0;
genesis              1035         bnChainWork = 0;
genesis              1036 
genesis              1037         nVersion       = 0;
genesis              1038         hashMerkleRoot = 0;
genesis              1039         nTime          = 0;
genesis              1040         nBits          = 0;
genesis              1041         nNonce         = 0;
genesis              1042     }
genesis              1043 
genesis              1044     CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
genesis              1045     {
genesis              1046         phashBlock = NULL;
genesis              1047         pprev = NULL;
genesis              1048         pnext = NULL;
genesis              1049         nFile = nFileIn;
genesis              1050         nBlockPos = nBlockPosIn;
genesis              1051         nHeight = 0;
genesis              1052         bnChainWork = 0;
genesis              1053 
genesis              1054         nVersion       = block.nVersion;
genesis              1055         hashMerkleRoot = block.hashMerkleRoot;
genesis              1056         nTime          = block.nTime;
genesis              1057         nBits          = block.nBits;
genesis              1058         nNonce         = block.nNonce;
genesis              1059     }
genesis              1060 
genesis              1061     CBlock GetBlockHeader() const
genesis              1062     {
genesis              1063         CBlock block;
genesis              1064         block.nVersion       = nVersion;
genesis              1065         if (pprev)
genesis              1066             block.hashPrevBlock = pprev->GetBlockHash();
genesis              1067         block.hashMerkleRoot = hashMerkleRoot;
genesis              1068         block.nTime          = nTime;
genesis              1069         block.nBits          = nBits;
genesis              1070         block.nNonce         = nNonce;
genesis              1071         return block;
genesis              1072     }
genesis              1073 
genesis              1074     uint256 GetBlockHash() const
genesis              1075     {
genesis              1076         return *phashBlock;
genesis              1077     }
genesis              1078 
genesis              1079     int64 GetBlockTime() const
genesis              1080     {
genesis              1081         return (int64)nTime;
genesis              1082     }
genesis              1083 
genesis              1084     CBigNum GetBlockWork() const
genesis              1085     {
genesis              1086         CBigNum bnTarget;
genesis              1087         bnTarget.SetCompact(nBits);
genesis              1088         if (bnTarget <= 0)
genesis              1089             return 0;
genesis              1090         return (CBigNum(1)<<256) / (bnTarget+1);
genesis              1091     }
genesis              1092 
genesis              1093     bool IsInMainChain() const
genesis              1094     {
genesis              1095         return (pnext || this == pindexBest);
genesis              1096     }
genesis              1097 
genesis              1098     bool CheckIndex() const
genesis              1099     {
genesis              1100         return CheckProofOfWork(GetBlockHash(), nBits);
genesis              1101     }
genesis              1102 
genesis              1103     bool EraseBlockFromDisk()
genesis              1104     {
genesis              1105         
genesis              1106         CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
genesis              1107         if (!fileout)
genesis              1108             return false;
genesis              1109 
genesis              1110         
genesis              1111         CBlock block;
genesis              1112         block.SetNull();
genesis              1113         fileout << block;
genesis              1114 
genesis              1115         return true;
genesis              1116     }
genesis              1117 
genesis              1118     enum { nMedianTimeSpan=11 };
genesis              1119 
genesis              1120     int64 GetMedianTimePast() const
genesis              1121     {
genesis              1122         int64 pmedian[nMedianTimeSpan];
genesis              1123         int64* pbegin = &pmedian[nMedianTimeSpan];
genesis              1124         int64* pend = &pmedian[nMedianTimeSpan];
genesis              1125 
genesis              1126         const CBlockIndex* pindex = this;
genesis              1127         for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
genesis              1128             *(--pbegin) = pindex->GetBlockTime();
genesis              1129 
genesis              1130         std::sort(pbegin, pend);
genesis              1131         return pbegin[(pend - pbegin)/2];
genesis              1132     }
genesis              1133 
genesis              1134     int64 GetMedianTime() const
genesis              1135     {
genesis              1136         const CBlockIndex* pindex = this;
genesis              1137         for (int i = 0; i < nMedianTimeSpan/2; i++)
genesis              1138         {
genesis              1139             if (!pindex->pnext)
genesis              1140                 return GetBlockTime();
genesis              1141             pindex = pindex->pnext;
genesis              1142         }
genesis              1143         return pindex->GetMedianTimePast();
genesis              1144     }
genesis              1145 
genesis              1146 
genesis              1147 
genesis              1148     std::string ToString() const
genesis              1149     {
genesis              1150         return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
genesis              1151             pprev, pnext, nFile, nBlockPos, nHeight,
genesis              1152             hashMerkleRoot.ToString().substr(0,10).c_str(),
genesis              1153             GetBlockHash().ToString().substr(0,20).c_str());
genesis              1154     }
genesis              1155 
genesis              1156     void print() const
genesis              1157     {
genesis              1158         printf("%s\n", ToString().c_str());
genesis              1159     }
genesis              1160 };
genesis              1161 
genesis              1162 
genesis              1163 
genesis              1164 
genesis              1165 
genesis              1166 
genesis              1167 class CDiskBlockIndex : public CBlockIndex
genesis              1168 {
genesis              1169 public:
genesis              1170     uint256 hashPrev;
genesis              1171     uint256 hashNext;
genesis              1172 
genesis              1173     CDiskBlockIndex()
genesis              1174     {
genesis              1175         hashPrev = 0;
genesis              1176         hashNext = 0;
genesis              1177     }
genesis              1178 
genesis              1179     explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
genesis              1180     {
genesis              1181         hashPrev = (pprev ? pprev->GetBlockHash() : 0);
genesis              1182         hashNext = (pnext ? pnext->GetBlockHash() : 0);
genesis              1183     }
genesis              1184 
genesis              1185     IMPLEMENT_SERIALIZE
genesis              1186     (
genesis              1187         if (!(nType & SER_GETHASH))
genesis              1188             READWRITE(nVersion);
genesis              1189 
genesis              1190         READWRITE(hashNext);
genesis              1191         READWRITE(nFile);
genesis              1192         READWRITE(nBlockPos);
genesis              1193         READWRITE(nHeight);
genesis              1194 
genesis              1195         
genesis              1196         READWRITE(this->nVersion);
genesis              1197         READWRITE(hashPrev);
genesis              1198         READWRITE(hashMerkleRoot);
genesis              1199         READWRITE(nTime);
genesis              1200         READWRITE(nBits);
genesis              1201         READWRITE(nNonce);
genesis              1202     )
genesis              1203 
genesis              1204     uint256 GetBlockHash() const
genesis              1205     {
genesis              1206         CBlock block;
genesis              1207         block.nVersion        = nVersion;
genesis              1208         block.hashPrevBlock   = hashPrev;
genesis              1209         block.hashMerkleRoot  = hashMerkleRoot;
genesis              1210         block.nTime           = nTime;
genesis              1211         block.nBits           = nBits;
genesis              1212         block.nNonce          = nNonce;
genesis              1213         return block.GetHash();
genesis              1214     }
genesis              1215 
genesis              1216 
genesis              1217     std::string ToString() const
genesis              1218     {
genesis              1219         std::string str = "CDiskBlockIndex(";
genesis              1220         str += CBlockIndex::ToString();
genesis              1221         str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
genesis              1222             GetBlockHash().ToString().c_str(),
genesis              1223             hashPrev.ToString().substr(0,20).c_str(),
genesis              1224             hashNext.ToString().substr(0,20).c_str());
genesis              1225         return str;
genesis              1226     }
genesis              1227 
genesis              1228     void print() const
genesis              1229     {
genesis              1230         printf("%s\n", ToString().c_str());
genesis              1231     }
genesis              1232 };
genesis              1233 
genesis              1234 
genesis              1235 
genesis              1236 
genesis              1237 
genesis              1238 
genesis              1239 
genesis              1240 
genesis              1241 
genesis              1242 
genesis              1243 
genesis              1244 
genesis              1245 
genesis              1246 class CBlockLocator
genesis              1247 {
genesis              1248 protected:
genesis              1249     std::vector<uint256> vHave;
genesis              1250 public:
genesis              1251 
genesis              1252     CBlockLocator()
genesis              1253     {
genesis              1254     }
genesis              1255 
genesis              1256     explicit CBlockLocator(const CBlockIndex* pindex)
genesis              1257     {
genesis              1258         Set(pindex);
genesis              1259     }
genesis              1260 
genesis              1261     explicit CBlockLocator(uint256 hashBlock)
genesis              1262     {
genesis              1263         std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis              1264         if (mi != mapBlockIndex.end())
genesis              1265             Set((*mi).second);
genesis              1266     }
genesis              1267 
genesis              1268     IMPLEMENT_SERIALIZE
genesis              1269     (
genesis              1270         if (!(nType & SER_GETHASH))
genesis              1271             READWRITE(nVersion);
genesis              1272         READWRITE(vHave);
genesis              1273     )
genesis              1274 
genesis              1275     void SetNull()
genesis              1276     {
genesis              1277         vHave.clear();
genesis              1278     }
genesis              1279 
genesis              1280     bool IsNull()
genesis              1281     {
genesis              1282         return vHave.empty();
genesis              1283     }
genesis              1284 
genesis              1285     void Set(const CBlockIndex* pindex)
genesis              1286     {
genesis              1287         vHave.clear();
genesis              1288         int nStep = 1;
genesis              1289         while (pindex)
genesis              1290         {
genesis              1291             vHave.push_back(pindex->GetBlockHash());
genesis              1292 
genesis              1293             
genesis              1294             for (int i = 0; pindex && i < nStep; i++)
genesis              1295                 pindex = pindex->pprev;
genesis              1296             if (vHave.size() > 10)
genesis              1297                 nStep *= 2;
genesis              1298         }
genesis              1299         vHave.push_back(hashGenesisBlock);
genesis              1300     }
genesis              1301 
genesis              1302     int GetDistanceBack()
genesis              1303     {
genesis              1304         
genesis              1305         int nDistance = 0;
genesis              1306         int nStep = 1;
genesis              1307         BOOST_FOREACH(const uint256& hash, vHave)
genesis              1308         {
genesis              1309             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis              1310             if (mi != mapBlockIndex.end())
genesis              1311             {
genesis              1312                 CBlockIndex* pindex = (*mi).second;
genesis              1313                 if (pindex->IsInMainChain())
genesis              1314                     return nDistance;
genesis              1315             }
genesis              1316             nDistance += nStep;
genesis              1317             if (nDistance > 10)
genesis              1318                 nStep *= 2;
genesis              1319         }
genesis              1320         return nDistance;
genesis              1321     }
genesis              1322 
genesis              1323     CBlockIndex* GetBlockIndex()
genesis              1324     {
genesis              1325         
genesis              1326         BOOST_FOREACH(const uint256& hash, vHave)
genesis              1327         {
genesis              1328             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis              1329             if (mi != mapBlockIndex.end())
genesis              1330             {
genesis              1331                 CBlockIndex* pindex = (*mi).second;
genesis              1332                 if (pindex->IsInMainChain())
genesis              1333                     return pindex;
genesis              1334             }
genesis              1335         }
genesis              1336         return pindexGenesisBlock;
genesis              1337     }
genesis              1338 
genesis              1339     uint256 GetBlockHash()
genesis              1340     {
genesis              1341         
genesis              1342         BOOST_FOREACH(const uint256& hash, vHave)
genesis              1343         {
genesis              1344             std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
genesis              1345             if (mi != mapBlockIndex.end())
genesis              1346             {
genesis              1347                 CBlockIndex* pindex = (*mi).second;
genesis              1348                 if (pindex->IsInMainChain())
genesis              1349                     return hash;
genesis              1350             }
genesis              1351         }
genesis              1352         return hashGenesisBlock;
genesis              1353     }
genesis              1354 
genesis              1355     int GetHeight()
genesis              1356     {
genesis              1357         CBlockIndex* pindex = GetBlockIndex();
genesis              1358         if (!pindex)
genesis              1359             return 0;
genesis              1360         return pindex->nHeight;
genesis              1361     }
genesis              1362 };
genesis              1363 
genesis              1364 
genesis              1365 
genesis              1366 
genesis              1367 
genesis              1368 
genesis              1369 
genesis              1370 
genesis              1371 
genesis              1372 
genesis              1373 
genesis              1374 
genesis              1375 
genesis              1376 
genesis              1377 
genesis              1378 
genesis              1379 class CUnsignedAlert
genesis              1380 {
genesis              1381 public:
genesis              1382     int nVersion;
genesis              1383     int64 nRelayUntil;      
genesis              1384     int64 nExpiration;
genesis              1385     int nID;
genesis              1386     int nCancel;
genesis              1387     std::set<int> setCancel;
genesis              1388     int nMinVer;            
genesis              1389     int nMaxVer;            
genesis              1390     std::set<std::string> setSubVer;  
genesis              1391     int nPriority;
genesis              1392 
genesis              1393     
genesis              1394     std::string strComment;
genesis              1395     std::string strStatusBar;
genesis              1396     std::string strReserved;
genesis              1397 
genesis              1398     IMPLEMENT_SERIALIZE
genesis              1399     (
genesis              1400         READWRITE(this->nVersion);
genesis              1401         nVersion = this->nVersion;
genesis              1402         READWRITE(nRelayUntil);
genesis              1403         READWRITE(nExpiration);
genesis              1404         READWRITE(nID);
genesis              1405         READWRITE(nCancel);
genesis              1406         READWRITE(setCancel);
genesis              1407         READWRITE(nMinVer);
genesis              1408         READWRITE(nMaxVer);
genesis              1409         READWRITE(setSubVer);
genesis              1410         READWRITE(nPriority);
genesis              1411 
genesis              1412         READWRITE(strComment);
genesis              1413         READWRITE(strStatusBar);
genesis              1414         READWRITE(strReserved);
genesis              1415     )
genesis              1416 
genesis              1417     void SetNull()
genesis              1418     {
genesis              1419         nVersion = 1;
genesis              1420         nRelayUntil = 0;
genesis              1421         nExpiration = 0;
genesis              1422         nID = 0;
genesis              1423         nCancel = 0;
genesis              1424         setCancel.clear();
genesis              1425         nMinVer = 0;
genesis              1426         nMaxVer = 0;
genesis              1427         setSubVer.clear();
genesis              1428         nPriority = 0;
genesis              1429 
genesis              1430         strComment.clear();
genesis              1431         strStatusBar.clear();
genesis              1432         strReserved.clear();
genesis              1433     }
genesis              1434 
genesis              1435     std::string ToString() const
genesis              1436     {
genesis              1437         std::string strSetCancel;
genesis              1438         BOOST_FOREACH(int n, setCancel)
genesis              1439             strSetCancel += strprintf("%d ", n);
genesis              1440         std::string strSetSubVer;
genesis              1441         BOOST_FOREACH(std::string str, setSubVer)
genesis              1442             strSetSubVer += "\"" + str + "\" ";
genesis              1443         return strprintf(
genesis              1444                 "CAlert(\n"
genesis              1445                 "    nVersion     = %d\n"
genesis              1446                 "    nRelayUntil  = %"PRI64d"\n"
genesis              1447                 "    nExpiration  = %"PRI64d"\n"
genesis              1448                 "    nID          = %d\n"
genesis              1449                 "    nCancel      = %d\n"
genesis              1450                 "    setCancel    = %s\n"
genesis              1451                 "    nMinVer      = %d\n"
genesis              1452                 "    nMaxVer      = %d\n"
genesis              1453                 "    setSubVer    = %s\n"
genesis              1454                 "    nPriority    = %d\n"
genesis              1455                 "    strComment   = \"%s\"\n"
genesis              1456                 "    strStatusBar = \"%s\"\n"
genesis              1457                 ")\n",
genesis              1458             nVersion,
genesis              1459             nRelayUntil,
genesis              1460             nExpiration,
genesis              1461             nID,
genesis              1462             nCancel,
genesis              1463             strSetCancel.c_str(),
genesis              1464             nMinVer,
genesis              1465             nMaxVer,
genesis              1466             strSetSubVer.c_str(),
genesis              1467             nPriority,
genesis              1468             strComment.c_str(),
genesis              1469             strStatusBar.c_str());
genesis              1470     }
genesis              1471 
genesis              1472     void print() const
genesis              1473     {
genesis              1474         printf("%s", ToString().c_str());
genesis              1475     }
genesis              1476 };
genesis              1477 
genesis              1478 class CAlert : public CUnsignedAlert
genesis              1479 {
genesis              1480 public:
genesis              1481     std::vector<unsigned char> vchMsg;
genesis              1482     std::vector<unsigned char> vchSig;
genesis              1483 
genesis              1484     CAlert()
genesis              1485     {
genesis              1486         SetNull();
genesis              1487     }
genesis              1488 
genesis              1489     IMPLEMENT_SERIALIZE
genesis              1490     (
genesis              1491         READWRITE(vchMsg);
genesis              1492         READWRITE(vchSig);
genesis              1493     )
genesis              1494 
genesis              1495     void SetNull()
genesis              1496     {
genesis              1497         CUnsignedAlert::SetNull();
genesis              1498         vchMsg.clear();
genesis              1499         vchSig.clear();
genesis              1500     }
genesis              1501 
genesis              1502     bool IsNull() const
genesis              1503     {
genesis              1504         return (nExpiration == 0);
genesis              1505     }
genesis              1506 
genesis              1507     uint256 GetHash() const
genesis              1508     {
genesis              1509         return SerializeHash(*this);
genesis              1510     }
genesis              1511 
genesis              1512     bool IsInEffect() const
genesis              1513     {
genesis              1514         return (GetAdjustedTime() < nExpiration);
genesis              1515     }
genesis              1516 
genesis              1517     bool Cancels(const CAlert& alert) const
genesis              1518     {
genesis              1519         if (!IsInEffect())
genesis              1520             return false; 
genesis              1521         return (alert.nID <= nCancel || setCancel.count(alert.nID));
genesis              1522     }
genesis              1523 
genesis              1524     bool AppliesTo(int nVersion, std::string strSubVerIn) const
genesis              1525     {
genesis              1526         return (IsInEffect() &&
genesis              1527                 nMinVer <= nVersion && nVersion <= nMaxVer &&
genesis              1528                 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
genesis              1529     }
genesis              1530 
genesis              1531     bool AppliesToMe() const
genesis              1532     {
genesis              1533         return AppliesTo(VERSION, ::pszSubVer);
genesis              1534     }
genesis              1535 
genesis              1536     bool RelayTo(CNode* pnode) const
genesis              1537     {
genesis              1538         if (!IsInEffect())
genesis              1539             return false;
genesis              1540         
genesis              1541         if (pnode->setKnown.insert(GetHash()).second)
genesis              1542         {
genesis              1543             if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
genesis              1544                 AppliesToMe() ||
genesis              1545                 GetAdjustedTime() < nRelayUntil)
genesis              1546             {
genesis              1547                 pnode->PushMessage("alert", *this);
genesis              1548                 return true;
genesis              1549             }
genesis              1550         }
genesis              1551         return false;
genesis              1552     }
genesis              1553 
genesis              1554     bool CheckSignature()
genesis              1555     {
genesis              1556         CKey key;
genesis              1557         if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
genesis              1558             return error("CAlert::CheckSignature() : SetPubKey failed");
genesis              1559         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
genesis              1560             return error("CAlert::CheckSignature() : verify signature failed");
genesis              1561 
genesis              1562         
genesis              1563         CDataStream sMsg(vchMsg);
genesis              1564         sMsg >> *(CUnsignedAlert*)this;
genesis              1565         return true;
genesis              1566     }
genesis              1567 
genesis              1568     bool ProcessAlert();
genesis              1569 };
genesis              1570 
genesis              1571 #endif