genesis                 1 
genesis                 2 
genesis                 3 
genesis                 4 
genesis                 5 #include "headers.h"
genesis                 6 #include "checkpoints.h"
genesis                 7 #include "db.h"
genesis                 8 #include "net.h"
genesis                 9 #include "init.h"
genesis                10 #include <boost/filesystem.hpp>
genesis                11 #include <boost/filesystem/fstream.hpp>
genesis                12 
genesis                13 using namespace std;
genesis                14 using namespace boost;
genesis                15 
genesis                16 
genesis                17 
genesis                18 
genesis                19 
genesis                20 CCriticalSection cs_setpwalletRegistered;
genesis                21 set<CWallet*> setpwalletRegistered;
genesis                22 
genesis                23 CCriticalSection cs_main;
genesis                24 
genesis                25 static map<uint256, CTransaction> mapTransactions;
genesis                26 CCriticalSection cs_mapTransactions;
genesis                27 unsigned int nTransactionsUpdated = 0;
genesis                28 map<COutPoint, CInPoint> mapNextTx;
genesis                29 
genesis                30 map<uint256, CBlockIndex*> mapBlockIndex;
genesis                31 uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
genesis                32 static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
genesis                33 CBlockIndex* pindexGenesisBlock = NULL;
genesis                34 int nBestHeight = -1;
genesis                35 CBigNum bnBestChainWork = 0;
genesis                36 CBigNum bnBestInvalidWork = 0;
genesis                37 uint256 hashBestChain = 0;
genesis                38 CBlockIndex* pindexBest = NULL;
genesis                39 int64 nTimeBestReceived = 0;
genesis                40 
genesis                41 CMedianFilter<int> cPeerBlockCounts(5, 0); 
genesis                42 
genesis                43 map<uint256, CBlock*> mapOrphanBlocks;
genesis                44 multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
genesis                45 
genesis                46 map<uint256, CDataStream*> mapOrphanTransactions;
genesis                47 multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
genesis                48 
genesis                49 
genesis                50 double dHashesPerSec;
genesis                51 int64 nHPSTimerStart;
genesis                52 
genesis                53 
genesis                54 int fGenerateBitcoins = false;
genesis                55 int64 nTransactionFee = 0;
genesis                56 int fLimitProcessors = false;
genesis                57 int nLimitProcessors = 1;
genesis                58 int fMinimizeToTray = true;
genesis                59 int fMinimizeOnClose = true;
genesis                60 #if USE_UPNP
genesis                61 int fUseUPnP = true;
genesis                62 #else
genesis                63 int fUseUPnP = false;
genesis                64 #endif
genesis                65 
genesis                66 
genesis                67 
genesis                68 
genesis                69 
genesis                70 
genesis                71 
genesis                72 
genesis                73 
genesis                74 
genesis                75 void RegisterWallet(CWallet* pwalletIn)
genesis                76 {
genesis                77     CRITICAL_BLOCK(cs_setpwalletRegistered)
genesis                78     {
genesis                79         setpwalletRegistered.insert(pwalletIn);
genesis                80     }
genesis                81 }
genesis                82 
genesis                83 void UnregisterWallet(CWallet* pwalletIn)
genesis                84 {
genesis                85     CRITICAL_BLOCK(cs_setpwalletRegistered)
genesis                86     {
genesis                87         setpwalletRegistered.erase(pwalletIn);
genesis                88     }
genesis                89 }
genesis                90 
genesis                91 
genesis                92 bool static IsFromMe(CTransaction& tx)
genesis                93 {
genesis                94     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis                95         if (pwallet->IsFromMe(tx))
genesis                96             return true;
genesis                97     return false;
genesis                98 }
genesis                99 
genesis               100 
genesis               101 bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
genesis               102 {
genesis               103     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               104         if (pwallet->GetTransaction(hashTx,wtx))
genesis               105             return true;
genesis               106     return false;
genesis               107 }
genesis               108 
genesis               109 
genesis               110 void static EraseFromWallets(uint256 hash)
genesis               111 {
genesis               112     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               113         pwallet->EraseFromWallet(hash);
genesis               114 }
genesis               115 
genesis               116 
genesis               117 void static SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false)
genesis               118 {
genesis               119     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               120         pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate);
genesis               121 }
genesis               122 
genesis               123 
genesis               124 void static SetBestChain(const CBlockLocator& loc)
genesis               125 {
genesis               126     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               127         pwallet->SetBestChain(loc);
genesis               128 }
genesis               129 
genesis               130 
genesis               131 void static UpdatedTransaction(const uint256& hashTx)
genesis               132 {
genesis               133     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               134         pwallet->UpdatedTransaction(hashTx);
genesis               135 }
genesis               136 
genesis               137 
genesis               138 void static PrintWallets(const CBlock& block)
genesis               139 {
genesis               140     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               141         pwallet->PrintWallet(block);
genesis               142 }
genesis               143 
genesis               144 
genesis               145 void static Inventory(const uint256& hash)
genesis               146 {
genesis               147     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               148         pwallet->Inventory(hash);
genesis               149 }
genesis               150 
genesis               151 
genesis               152 void static ResendWalletTransactions()
genesis               153 {
genesis               154     BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis               155         pwallet->ResendWalletTransactions();
genesis               156 }
genesis               157 
genesis               158 
genesis               159 
genesis               160 
genesis               161 
genesis               162 
genesis               163 
genesis               164 
genesis               165 
genesis               166 
genesis               167 
genesis               168 
genesis               169 void AddOrphanTx(const CDataStream& vMsg)
genesis               170 {
genesis               171     CTransaction tx;
genesis               172     CDataStream(vMsg) >> tx;
genesis               173     uint256 hash = tx.GetHash();
genesis               174     if (mapOrphanTransactions.count(hash))
genesis               175         return;
genesis               176 
genesis               177     CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
genesis               178     BOOST_FOREACH(const CTxIn& txin, tx.vin)
genesis               179         mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
genesis               180 }
genesis               181 
genesis               182 void static EraseOrphanTx(uint256 hash)
genesis               183 {
genesis               184     if (!mapOrphanTransactions.count(hash))
genesis               185         return;
genesis               186     const CDataStream* pvMsg = mapOrphanTransactions[hash];
genesis               187     CTransaction tx;
genesis               188     CDataStream(*pvMsg) >> tx;
genesis               189     BOOST_FOREACH(const CTxIn& txin, tx.vin)
genesis               190     {
genesis               191         for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
genesis               192              mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
genesis               193         {
genesis               194             if ((*mi).second == pvMsg)
genesis               195                 mapOrphanTransactionsByPrev.erase(mi++);
genesis               196             else
genesis               197                 mi++;
genesis               198         }
genesis               199     }
genesis               200     delete pvMsg;
genesis               201     mapOrphanTransactions.erase(hash);
genesis               202 }
genesis               203 
genesis               204 int LimitOrphanTxSize(int nMaxOrphans)
genesis               205 {
genesis               206     int nEvicted = 0;
genesis               207     while (mapOrphanTransactions.size() > nMaxOrphans)
genesis               208     {
genesis               209         
genesis               210         std::vector<unsigned char> randbytes(32);
genesis               211         RAND_bytes(&randbytes[0], 32);
genesis               212         uint256 randomhash(randbytes);
genesis               213         map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
genesis               214         if (it == mapOrphanTransactions.end())
genesis               215             it = mapOrphanTransactions.begin();
genesis               216         EraseOrphanTx(it->first);
genesis               217         ++nEvicted;
genesis               218     }
genesis               219     return nEvicted;
genesis               220 }
genesis               221 
genesis               222 
genesis               223 
genesis               224 
genesis               225 
genesis               226 
genesis               227 
genesis               228 
genesis               229 
genesis               230 
genesis               231 
genesis               232 
genesis               233 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet)
genesis               234 {
genesis               235     SetNull();
genesis               236     if (!txdb.ReadTxIndex(prevout.hash, txindexRet))
genesis               237         return false;
genesis               238     if (!ReadFromDisk(txindexRet.pos))
genesis               239         return false;
genesis               240     if (prevout.n >= vout.size())
genesis               241     {
genesis               242         SetNull();
genesis               243         return false;
genesis               244     }
genesis               245     return true;
genesis               246 }
genesis               247 
genesis               248 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout)
genesis               249 {
genesis               250     CTxIndex txindex;
genesis               251     return ReadFromDisk(txdb, prevout, txindex);
genesis               252 }
genesis               253 
genesis               254 bool CTransaction::ReadFromDisk(COutPoint prevout)
genesis               255 {
genesis               256     CTxDB txdb("r");
genesis               257     CTxIndex txindex;
genesis               258     return ReadFromDisk(txdb, prevout, txindex);
genesis               259 }
genesis               260 
genesis               261 
genesis               262 
genesis               263 int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
genesis               264 {
genesis               265     if (fClient)
genesis               266     {
genesis               267         if (hashBlock == 0)
genesis               268             return 0;
genesis               269     }
genesis               270     else
genesis               271     {
genesis               272         CBlock blockTmp;
genesis               273         if (pblock == NULL)
genesis               274         {
genesis               275             
genesis               276             CTxIndex txindex;
genesis               277             if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
genesis               278                 return 0;
genesis               279             if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos))
genesis               280                 return 0;
genesis               281             pblock = &blockTmp;
genesis               282         }
genesis               283 
genesis               284         
genesis               285         hashBlock = pblock->GetHash();
genesis               286 
genesis               287         
genesis               288         for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++)
genesis               289             if (pblock->vtx[nIndex] == *(CTransaction*)this)
genesis               290                 break;
genesis               291         if (nIndex == pblock->vtx.size())
genesis               292         {
genesis               293             vMerkleBranch.clear();
genesis               294             nIndex = -1;
genesis               295             printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
genesis               296             return 0;
genesis               297         }
genesis               298 
genesis               299         
genesis               300         vMerkleBranch = pblock->GetMerkleBranch(nIndex);
genesis               301     }
genesis               302 
genesis               303     
genesis               304     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis               305     if (mi == mapBlockIndex.end())
genesis               306         return 0;
genesis               307     CBlockIndex* pindex = (*mi).second;
genesis               308     if (!pindex || !pindex->IsInMainChain())
genesis               309         return 0;
genesis               310 
genesis               311     return pindexBest->nHeight - pindex->nHeight + 1;
genesis               312 }
genesis               313 
genesis               314 
genesis               315 
genesis               316 
genesis               317 
genesis               318 
genesis               319 
genesis               320 bool CTransaction::CheckTransaction() const
genesis               321 {
genesis               322     
genesis               323     if (vin.empty())
genesis               324         return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
genesis               325     if (vout.empty())
genesis               326         return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
genesis               327     
genesis               328     if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
genesis               329         return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
genesis               330 
genesis               331     
genesis               332     int64 nValueOut = 0;
genesis               333     BOOST_FOREACH(const CTxOut& txout, vout)
genesis               334     {
genesis               335         if (txout.nValue < 0)
genesis               336             return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative"));
genesis               337         if (txout.nValue > MAX_MONEY)
genesis               338             return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high"));
genesis               339         nValueOut += txout.nValue;
genesis               340         if (!MoneyRange(nValueOut))
genesis               341             return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range"));
genesis               342     }
genesis               343 
genesis               344     
genesis               345     set<COutPoint> vInOutPoints;
genesis               346     BOOST_FOREACH(const CTxIn& txin, vin)
genesis               347     {
genesis               348         if (vInOutPoints.count(txin.prevout))
genesis               349             return false;
genesis               350         vInOutPoints.insert(txin.prevout);
genesis               351     }
genesis               352 
genesis               353     if (IsCoinBase())
genesis               354     {
genesis               355         if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
genesis               356             return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size"));
genesis               357     }
genesis               358     else
genesis               359     {
genesis               360         BOOST_FOREACH(const CTxIn& txin, vin)
genesis               361             if (txin.prevout.IsNull())
genesis               362                 return DoS(10, error("CTransaction::CheckTransaction() : prevout is null"));
genesis               363     }
genesis               364 
genesis               365     return true;
genesis               366 }
genesis               367 
genesis               368 bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
genesis               369 {
genesis               370     if (pfMissingInputs)
genesis               371         *pfMissingInputs = false;
genesis               372 
genesis               373     if (!CheckTransaction())
genesis               374         return error("AcceptToMemoryPool() : CheckTransaction failed");
genesis               375 
genesis               376     
genesis               377     if (IsCoinBase())
genesis               378         return DoS(100, error("AcceptToMemoryPool() : coinbase as individual tx"));
genesis               379 
genesis               380     
genesis               381     if ((int64)nLockTime > INT_MAX)
genesis               382         return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
genesis               383 
genesis               384     
genesis               385     unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
genesis               386     
genesis               387     
genesis               388     
genesis               389     
genesis               390     if (GetSigOpCount() > nSize / 34 || nSize < 100)
genesis               391         return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount");
genesis               392 
genesis               393     
genesis               394     if (!fTestNet && !IsStandard())
genesis               395         return error("AcceptToMemoryPool() : nonstandard transaction type");
genesis               396 
genesis               397     
genesis               398     uint256 hash = GetHash();
genesis               399     CRITICAL_BLOCK(cs_mapTransactions)
genesis               400         if (mapTransactions.count(hash))
genesis               401             return false;
genesis               402     if (fCheckInputs)
genesis               403         if (txdb.ContainsTx(hash))
genesis               404             return false;
genesis               405 
genesis               406     
genesis               407     CTransaction* ptxOld = NULL;
genesis               408     for (int i = 0; i < vin.size(); i++)
genesis               409     {
genesis               410         COutPoint outpoint = vin[i].prevout;
genesis               411         if (mapNextTx.count(outpoint))
genesis               412         {
genesis               413             
genesis               414             return false;
genesis               415 
genesis               416             
genesis               417             if (i != 0)
genesis               418                 return false;
genesis               419             ptxOld = mapNextTx[outpoint].ptx;
genesis               420             if (ptxOld->IsFinal())
genesis               421                 return false;
genesis               422             if (!IsNewerThan(*ptxOld))
genesis               423                 return false;
genesis               424             for (int i = 0; i < vin.size(); i++)
genesis               425             {
genesis               426                 COutPoint outpoint = vin[i].prevout;
genesis               427                 if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
genesis               428                     return false;
genesis               429             }
genesis               430             break;
genesis               431         }
genesis               432     }
genesis               433 
genesis               434     if (fCheckInputs)
genesis               435     {
genesis               436         
genesis               437         map<uint256, CTxIndex> mapUnused;
genesis               438         int64 nFees = 0;
genesis               439         bool fInvalid = false;
genesis               440         if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid))
genesis               441         {
genesis               442             if (fInvalid)
genesis               443                 return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
genesis               444             return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
genesis               445         }
genesis               446 
genesis               447         
genesis               448         if (nFees < GetMinFee(1000, true, true))
genesis               449             return error("AcceptToMemoryPool() : not enough fees");
genesis               450 
genesis               451         
genesis               452         
genesis               453         
genesis               454         if (nFees < MIN_RELAY_TX_FEE)
genesis               455         {
genesis               456             static CCriticalSection cs;
genesis               457             static double dFreeCount;
genesis               458             static int64 nLastTime;
genesis               459             int64 nNow = GetTime();
genesis               460 
genesis               461             CRITICAL_BLOCK(cs)
genesis               462             {
genesis               463                 
genesis               464                 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
genesis               465                 nLastTime = nNow;
genesis               466                 
genesis               467                 
genesis               468                 if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(*this))
genesis               469                     return error("AcceptToMemoryPool() : free transaction rejected by rate limiter");
genesis               470                 if (fDebug)
genesis               471                     printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
genesis               472                 dFreeCount += nSize;
genesis               473             }
genesis               474         }
genesis               475     }
genesis               476 
genesis               477     
genesis               478     CRITICAL_BLOCK(cs_mapTransactions)
genesis               479     {
genesis               480         if (ptxOld)
genesis               481         {
genesis               482             printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
genesis               483             ptxOld->RemoveFromMemoryPool();
genesis               484         }
genesis               485         AddToMemoryPoolUnchecked();
genesis               486     }
genesis               487 
genesis               488     
genesis               489     
genesis               490     if (ptxOld)
genesis               491         EraseFromWallets(ptxOld->GetHash());
genesis               492 
genesis               493     printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
genesis               494     return true;
genesis               495 }
genesis               496 
genesis               497 bool CTransaction::AcceptToMemoryPool(bool fCheckInputs, bool* pfMissingInputs)
genesis               498 {
genesis               499     CTxDB txdb("r");
genesis               500     return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
genesis               501 }
genesis               502 
genesis               503 bool CTransaction::AddToMemoryPoolUnchecked()
genesis               504 {
genesis               505     
genesis               506     
genesis               507     CRITICAL_BLOCK(cs_mapTransactions)
genesis               508     {
genesis               509         uint256 hash = GetHash();
genesis               510         mapTransactions[hash] = *this;
genesis               511         for (int i = 0; i < vin.size(); i++)
genesis               512             mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
genesis               513         nTransactionsUpdated++;
genesis               514     }
genesis               515     return true;
genesis               516 }
genesis               517 
genesis               518 
genesis               519 bool CTransaction::RemoveFromMemoryPool()
genesis               520 {
genesis               521     
genesis               522     CRITICAL_BLOCK(cs_mapTransactions)
genesis               523     {
genesis               524         BOOST_FOREACH(const CTxIn& txin, vin)
genesis               525             mapNextTx.erase(txin.prevout);
genesis               526         mapTransactions.erase(GetHash());
genesis               527         nTransactionsUpdated++;
genesis               528     }
genesis               529     return true;
genesis               530 }
genesis               531 
genesis               532 
genesis               533 
genesis               534 
genesis               535 
genesis               536 
genesis               537 int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
genesis               538 {
genesis               539     if (hashBlock == 0 || nIndex == -1)
genesis               540         return 0;
genesis               541 
genesis               542     
genesis               543     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis               544     if (mi == mapBlockIndex.end())
genesis               545         return 0;
genesis               546     CBlockIndex* pindex = (*mi).second;
genesis               547     if (!pindex || !pindex->IsInMainChain())
genesis               548         return 0;
genesis               549 
genesis               550     
genesis               551     if (!fMerkleVerified)
genesis               552     {
genesis               553         if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
genesis               554             return 0;
genesis               555         fMerkleVerified = true;
genesis               556     }
genesis               557 
genesis               558     nHeightRet = pindex->nHeight;
genesis               559     return pindexBest->nHeight - pindex->nHeight + 1;
genesis               560 }
genesis               561 
genesis               562 
genesis               563 int CMerkleTx::GetBlocksToMaturity() const
genesis               564 {
genesis               565     if (!IsCoinBase())
genesis               566         return 0;
genesis               567     return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain());
genesis               568 }
genesis               569 
genesis               570 
genesis               571 bool CMerkleTx::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs)
genesis               572 {
genesis               573     if (fClient)
genesis               574     {
genesis               575         if (!IsInMainChain() && !ClientConnectInputs())
genesis               576             return false;
genesis               577         return CTransaction::AcceptToMemoryPool(txdb, false);
genesis               578     }
genesis               579     else
genesis               580     {
genesis               581         return CTransaction::AcceptToMemoryPool(txdb, fCheckInputs);
genesis               582     }
genesis               583 }
genesis               584 
genesis               585 bool CMerkleTx::AcceptToMemoryPool()
genesis               586 {
genesis               587     CTxDB txdb("r");
genesis               588     return AcceptToMemoryPool(txdb);
genesis               589 }
genesis               590 
genesis               591 
genesis               592 
genesis               593 bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
genesis               594 {
genesis               595     CRITICAL_BLOCK(cs_mapTransactions)
genesis               596     {
genesis               597         
genesis               598         BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
genesis               599         {
genesis               600             if (!tx.IsCoinBase())
genesis               601             {
genesis               602                 uint256 hash = tx.GetHash();
genesis               603                 if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
genesis               604                     tx.AcceptToMemoryPool(txdb, fCheckInputs);
genesis               605             }
genesis               606         }
genesis               607         return AcceptToMemoryPool(txdb, fCheckInputs);
genesis               608     }
genesis               609     return false;
genesis               610 }
genesis               611 
genesis               612 bool CWalletTx::AcceptWalletTransaction() 
genesis               613 {
genesis               614     CTxDB txdb("r");
genesis               615     return AcceptWalletTransaction(txdb);
genesis               616 }
genesis               617 
genesis               618 int CTxIndex::GetDepthInMainChain() const
genesis               619 {
genesis               620     
genesis               621     CBlock block;
genesis               622     if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false))
genesis               623         return 0;
genesis               624     
genesis               625     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.GetHash());
genesis               626     if (mi == mapBlockIndex.end())
genesis               627         return 0;
genesis               628     CBlockIndex* pindex = (*mi).second;
genesis               629     if (!pindex || !pindex->IsInMainChain())
genesis               630         return 0;
genesis               631     return 1 + nBestHeight - pindex->nHeight;
genesis               632 }
genesis               633 
genesis               634 
genesis               635 
genesis               636 
genesis               637 
genesis               638 
genesis               639 
genesis               640 
genesis               641 
genesis               642 
genesis               643 
genesis               644 
genesis               645 
genesis               646 
genesis               647 
genesis               648 bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
genesis               649 {
genesis               650     if (!fReadTransactions)
genesis               651     {
genesis               652         *this = pindex->GetBlockHeader();
genesis               653         return true;
genesis               654     }
genesis               655     if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
genesis               656         return false;
genesis               657     if (GetHash() != pindex->GetBlockHash())
genesis               658         return error("CBlock::ReadFromDisk() : GetHash() doesn't match index");
genesis               659     return true;
genesis               660 }
genesis               661 
genesis               662 uint256 static GetOrphanRoot(const CBlock* pblock)
genesis               663 {
genesis               664     
genesis               665     while (mapOrphanBlocks.count(pblock->hashPrevBlock))
genesis               666         pblock = mapOrphanBlocks[pblock->hashPrevBlock];
genesis               667     return pblock->GetHash();
genesis               668 }
genesis               669 
genesis               670 int64 static GetBlockValue(int nHeight, int64 nFees)
genesis               671 {
genesis               672     int64 nSubsidy = 50 * COIN;
genesis               673 
genesis               674     
genesis               675     nSubsidy >>= (nHeight / 210000);
genesis               676 
genesis               677     return nSubsidy + nFees;
genesis               678 }
genesis               679 
genesis               680 static const int64 nTargetTimespan = 14 * 24 * 60 * 60; 
genesis               681 static const int64 nTargetSpacing = 10 * 60;
genesis               682 static const int64 nInterval = nTargetTimespan / nTargetSpacing;
genesis               683 
genesis               684 
genesis               685 
genesis               686 
genesis               687 
genesis               688 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
genesis               689 {
genesis               690     
genesis               691     
genesis               692     if (fTestNet && nTime > nTargetSpacing*2)
genesis               693         return bnProofOfWorkLimit.GetCompact();
genesis               694 
genesis               695     CBigNum bnResult;
genesis               696     bnResult.SetCompact(nBase);
genesis               697     while (nTime > 0 && bnResult < bnProofOfWorkLimit)
genesis               698     {
genesis               699         
genesis               700         bnResult *= 4;
genesis               701         
genesis               702         nTime -= nTargetTimespan*4;
genesis               703     }
genesis               704     if (bnResult > bnProofOfWorkLimit)
genesis               705         bnResult = bnProofOfWorkLimit;
genesis               706     return bnResult.GetCompact();
genesis               707 }
genesis               708 
genesis               709 unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock)
genesis               710 {
genesis               711     unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact();
genesis               712 
genesis               713     
genesis               714     if (pindexLast == NULL)
genesis               715         return nProofOfWorkLimit;
genesis               716 
genesis               717     
genesis               718     if ((pindexLast->nHeight+1) % nInterval != 0)
genesis               719     {
genesis               720         
genesis               721         if (fTestNet && pblock->nTime > 1329264000)
genesis               722         {
genesis               723             
genesis               724             
genesis               725             if (pblock->nTime - pindexLast->nTime > nTargetSpacing*2)
genesis               726                 return nProofOfWorkLimit;
genesis               727             else
genesis               728             {
genesis               729                 
genesis               730                 const CBlockIndex* pindex = pindexLast;
genesis               731                 while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
genesis               732                     pindex = pindex->pprev;
genesis               733                 return pindex->nBits;
genesis               734             }
genesis               735         }
genesis               736 
genesis               737         return pindexLast->nBits;
genesis               738     }
genesis               739 
genesis               740     
genesis               741     const CBlockIndex* pindexFirst = pindexLast;
genesis               742     for (int i = 0; pindexFirst && i < nInterval-1; i++)
genesis               743         pindexFirst = pindexFirst->pprev;
genesis               744     assert(pindexFirst);
genesis               745 
genesis               746     
genesis               747     int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
genesis               748     printf("  nActualTimespan = %"PRI64d"  before bounds\n", nActualTimespan);
genesis               749     if (nActualTimespan < nTargetTimespan/4)
genesis               750         nActualTimespan = nTargetTimespan/4;
genesis               751     if (nActualTimespan > nTargetTimespan*4)
genesis               752         nActualTimespan = nTargetTimespan*4;
genesis               753 
genesis               754     
genesis               755     CBigNum bnNew;
genesis               756     bnNew.SetCompact(pindexLast->nBits);
genesis               757     bnNew *= nActualTimespan;
genesis               758     bnNew /= nTargetTimespan;
genesis               759 
genesis               760     if (bnNew > bnProofOfWorkLimit)
genesis               761         bnNew = bnProofOfWorkLimit;
genesis               762 
genesis               763     
genesis               764     printf("GetNextWorkRequired RETARGET\n");
genesis               765     printf("nTargetTimespan = %"PRI64d"    nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
genesis               766     printf("Before: %08x  %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
genesis               767     printf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
genesis               768 
genesis               769     return bnNew.GetCompact();
genesis               770 }
genesis               771 
genesis               772 bool CheckProofOfWork(uint256 hash, unsigned int nBits)
genesis               773 {
genesis               774     CBigNum bnTarget;
genesis               775     bnTarget.SetCompact(nBits);
genesis               776 
genesis               777     
genesis               778     if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit)
genesis               779         return error("CheckProofOfWork() : nBits below minimum work");
genesis               780 
genesis               781     
genesis               782     if (hash > bnTarget.getuint256())
genesis               783         return error("CheckProofOfWork() : hash doesn't match nBits");
genesis               784 
genesis               785     return true;
genesis               786 }
genesis               787 
genesis               788 
genesis               789 int GetNumBlocksOfPeers()
genesis               790 {
genesis               791     return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate());
genesis               792 }
genesis               793 
genesis               794 bool IsInitialBlockDownload()
genesis               795 {
genesis               796     if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate())
genesis               797         return true;
genesis               798     static int64 nLastUpdate;
genesis               799     static CBlockIndex* pindexLastBest;
genesis               800     if (pindexBest != pindexLastBest)
genesis               801     {
genesis               802         pindexLastBest = pindexBest;
genesis               803         nLastUpdate = GetTime();
genesis               804     }
genesis               805     return (GetTime() - nLastUpdate < 10 &&
genesis               806             pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60);
genesis               807 }
genesis               808 
genesis               809 void static InvalidChainFound(CBlockIndex* pindexNew)
genesis               810 {
genesis               811     if (pindexNew->bnChainWork > bnBestInvalidWork)
genesis               812     {
genesis               813         bnBestInvalidWork = pindexNew->bnChainWork;
genesis               814         CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
genesis               815         MainFrameRepaint();
genesis               816     }
genesis               817     printf("InvalidChainFound: invalid block=%s  height=%d  work=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
genesis               818     printf("InvalidChainFound:  current best=%s  height=%d  work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
genesis               819     if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
genesis               820         printf("InvalidChainFound: WARNING: Displayed transactions may not be correct!  You may need to upgrade, or other nodes may need to upgrade.\n");
genesis               821 }
genesis               822 
genesis               823 
genesis               824 
genesis               825 
genesis               826 
genesis               827 
genesis               828 
genesis               829 
genesis               830 
genesis               831 
genesis               832 
genesis               833 bool CTransaction::DisconnectInputs(CTxDB& txdb)
genesis               834 {
genesis               835     
genesis               836     if (!IsCoinBase())
genesis               837     {
genesis               838         BOOST_FOREACH(const CTxIn& txin, vin)
genesis               839         {
genesis               840             COutPoint prevout = txin.prevout;
genesis               841 
genesis               842             
genesis               843             CTxIndex txindex;
genesis               844             if (!txdb.ReadTxIndex(prevout.hash, txindex))
genesis               845                 return error("DisconnectInputs() : ReadTxIndex failed");
genesis               846 
genesis               847             if (prevout.n >= txindex.vSpent.size())
genesis               848                 return error("DisconnectInputs() : prevout.n out of range");
genesis               849 
genesis               850             
genesis               851             txindex.vSpent[prevout.n].SetNull();
genesis               852 
genesis               853             
genesis               854             if (!txdb.UpdateTxIndex(prevout.hash, txindex))
genesis               855                 return error("DisconnectInputs() : UpdateTxIndex failed");
genesis               856         }
genesis               857     }
genesis               858 
genesis               859     
genesis               860     
genesis               861     
genesis               862     
genesis               863     txdb.EraseTxIndex(*this);
genesis               864 
genesis               865     return true;
genesis               866 }
genesis               867 
genesis               868 
genesis               869 bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
genesis               870                                  CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
genesis               871                                  bool& fInvalid)
genesis               872 {
genesis               873     
genesis               874     
genesis               875     
genesis               876     
genesis               877     fInvalid = false;
genesis               878 
genesis               879     
genesis               880     
genesis               881     
genesis               882     
genesis               883     if (!IsCoinBase())
genesis               884     {
genesis               885         int64 nValueIn = 0;
genesis               886         for (int i = 0; i < vin.size(); i++)
genesis               887         {
genesis               888             COutPoint prevout = vin[i].prevout;
genesis               889 
genesis               890             
genesis               891             CTxIndex txindex;
genesis               892             bool fFound = true;
genesis               893             if ((fBlock || fMiner) && mapTestPool.count(prevout.hash))
genesis               894             {
genesis               895                 
genesis               896                 txindex = mapTestPool[prevout.hash];
genesis               897             }
genesis               898             else
genesis               899             {
genesis               900                 
genesis               901                 fFound = txdb.ReadTxIndex(prevout.hash, txindex);
genesis               902             }
genesis               903             if (!fFound && (fBlock || fMiner))
genesis               904                 return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(),  prevout.hash.ToString().substr(0,10).c_str());
genesis               905 
genesis               906             
genesis               907             CTransaction txPrev;
genesis               908             if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
genesis               909             {
genesis               910                 
genesis               911                 CRITICAL_BLOCK(cs_mapTransactions)
genesis               912                 {
genesis               913                     if (!mapTransactions.count(prevout.hash))
genesis               914                         return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(),  prevout.hash.ToString().substr(0,10).c_str());
genesis               915                     txPrev = mapTransactions[prevout.hash];
genesis               916                 }
genesis               917                 if (!fFound)
genesis               918                     txindex.vSpent.resize(txPrev.vout.size());
genesis               919             }
genesis               920             else
genesis               921             {
genesis               922                 
genesis               923                 if (!txPrev.ReadFromDisk(txindex.pos))
genesis               924                     return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(),  prevout.hash.ToString().substr(0,10).c_str());
genesis               925             }
genesis               926 
genesis               927             if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
genesis               928             {
genesis               929                 
genesis               930                 
genesis               931                 fInvalid = true;
genesis               932                 return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
genesis               933             }
genesis               934 
genesis               935             
genesis               936             if (txPrev.IsCoinBase())
genesis               937                 for (CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
genesis               938                     if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
genesis               939                         return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
genesis               940 
genesis               941             
genesis               942             
genesis               943             
genesis               944             if (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate())))
genesis               945                 
genesis               946                 if (!VerifySignature(txPrev, *this, i))
genesis               947                     return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
genesis               948 
genesis               949             
genesis               950             
genesis               951             
genesis               952             if (!txindex.vSpent[prevout.n].IsNull())
genesis               953                 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
genesis               954 
genesis               955             
genesis               956             nValueIn += txPrev.vout[prevout.n].nValue;
genesis               957             if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
genesis               958                 return DoS(100, error("ConnectInputs() : txin values out of range"));
genesis               959 
genesis               960             
genesis               961             txindex.vSpent[prevout.n] = posThisTx;
genesis               962 
genesis               963             
genesis               964             if (fBlock || fMiner)
genesis               965             {
genesis               966                 mapTestPool[prevout.hash] = txindex;
genesis               967             }
genesis               968         }
genesis               969 
genesis               970         if (nValueIn < GetValueOut())
genesis               971             return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()));
genesis               972 
genesis               973         
genesis               974         int64 nTxFee = nValueIn - GetValueOut();
genesis               975         if (nTxFee < 0)
genesis               976             return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()));
genesis               977         if (nTxFee < nMinFee)
genesis               978             return false;
genesis               979         nFees += nTxFee;
genesis               980         if (!MoneyRange(nFees))
genesis               981             return DoS(100, error("ConnectInputs() : nFees out of range"));
genesis               982     }
genesis               983 
genesis               984     if (fBlock)
genesis               985     {
genesis               986         
genesis               987         mapTestPool[GetHash()] = CTxIndex(posThisTx, vout.size());
genesis               988     }
genesis               989     else if (fMiner)
genesis               990     {
genesis               991         
genesis               992         mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());
genesis               993     }
genesis               994 
genesis               995     return true;
genesis               996 }
genesis               997 
genesis               998 
genesis               999 bool CTransaction::ClientConnectInputs()
genesis              1000 {
genesis              1001     if (IsCoinBase())
genesis              1002         return false;
genesis              1003 
genesis              1004     
genesis              1005     CRITICAL_BLOCK(cs_mapTransactions)
genesis              1006     {
genesis              1007         int64 nValueIn = 0;
genesis              1008         for (int i = 0; i < vin.size(); i++)
genesis              1009         {
genesis              1010             
genesis              1011             COutPoint prevout = vin[i].prevout;
genesis              1012             if (!mapTransactions.count(prevout.hash))
genesis              1013                 return false;
genesis              1014             CTransaction& txPrev = mapTransactions[prevout.hash];
genesis              1015 
genesis              1016             if (prevout.n >= txPrev.vout.size())
genesis              1017                 return false;
genesis              1018 
genesis              1019             
genesis              1020             if (!VerifySignature(txPrev, *this, i))
genesis              1021                 return error("ConnectInputs() : VerifySignature failed");
genesis              1022 
genesis              1023             
genesis              1024             
genesis              1025             
genesis              1026             
genesis              1027             
genesis              1028             
genesis              1029             
genesis              1030             
genesis              1031 
genesis              1032             nValueIn += txPrev.vout[prevout.n].nValue;
genesis              1033 
genesis              1034             if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
genesis              1035                 return error("ClientConnectInputs() : txin values out of range");
genesis              1036         }
genesis              1037         if (GetValueOut() > nValueIn)
genesis              1038             return false;
genesis              1039     }
genesis              1040 
genesis              1041     return true;
genesis              1042 }
genesis              1043 
genesis              1044 
genesis              1045 
genesis              1046 
genesis              1047 bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
genesis              1048 {
genesis              1049     
genesis              1050     for (int i = vtx.size()-1; i >= 0; i--)
genesis              1051         if (!vtx[i].DisconnectInputs(txdb))
genesis              1052             return false;
genesis              1053 
genesis              1054     
genesis              1055     
genesis              1056     if (pindex->pprev)
genesis              1057     {
genesis              1058         CDiskBlockIndex blockindexPrev(pindex->pprev);
genesis              1059         blockindexPrev.hashNext = 0;
genesis              1060         if (!txdb.WriteBlockIndex(blockindexPrev))
genesis              1061             return error("DisconnectBlock() : WriteBlockIndex failed");
genesis              1062     }
genesis              1063 
genesis              1064     return true;
genesis              1065 }
genesis              1066 
genesis              1067 bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
genesis              1068 {
genesis              1069     
genesis              1070     if (!CheckBlock())
genesis              1071         return false;
genesis              1072 
genesis              1073     
genesis              1074     
genesis              1075     
genesis              1076     
genesis              1077     
genesis              1078     
genesis              1079     
genesis              1080     
genesis              1081     
genesis              1082     
genesis              1083     if (pindex->nTime > 1331769600 || (fTestNet && pindex->nTime > 1329696000))
genesis              1084         BOOST_FOREACH(CTransaction& tx, vtx)
genesis              1085         {
genesis              1086             CTxIndex txindexOld;
genesis              1087             if (txdb.ReadTxIndex(tx.GetHash(), txindexOld))
genesis              1088                 BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent)
genesis              1089                     if (pos.IsNull())
genesis              1090                         return false;
genesis              1091         }
genesis              1092 
genesis              1093     
genesis              1094     unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());
genesis              1095 
genesis              1096     map<uint256, CTxIndex> mapQueuedChanges;
genesis              1097     int64 nFees = 0;
genesis              1098     BOOST_FOREACH(CTransaction& tx, vtx)
genesis              1099     {
genesis              1100         CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
genesis              1101         nTxPos += ::GetSerializeSize(tx, SER_DISK);
genesis              1102 
genesis              1103         bool fInvalid;
genesis              1104         if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false, 0, fInvalid))
genesis              1105             return false;
genesis              1106     }
genesis              1107     
genesis              1108     for (map<uint256, CTxIndex>::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi)
genesis              1109     {
genesis              1110         if (!txdb.UpdateTxIndex((*mi).first, (*mi).second))
genesis              1111             return error("ConnectBlock() : UpdateTxIndex failed");
genesis              1112     }
genesis              1113 
genesis              1114     if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
genesis              1115         return false;
genesis              1116 
genesis              1117     
genesis              1118     
genesis              1119     if (pindex->pprev)
genesis              1120     {
genesis              1121         CDiskBlockIndex blockindexPrev(pindex->pprev);
genesis              1122         blockindexPrev.hashNext = pindex->GetBlockHash();
genesis              1123         if (!txdb.WriteBlockIndex(blockindexPrev))
genesis              1124             return error("ConnectBlock() : WriteBlockIndex failed");
genesis              1125     }
genesis              1126 
genesis              1127     
genesis              1128     BOOST_FOREACH(CTransaction& tx, vtx)
genesis              1129         SyncWithWallets(tx, this, true);
genesis              1130 
genesis              1131     return true;
genesis              1132 }
genesis              1133 
genesis              1134 bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
genesis              1135 {
genesis              1136     printf("REORGANIZE\n");
genesis              1137 
genesis              1138     
genesis              1139     CBlockIndex* pfork = pindexBest;
genesis              1140     CBlockIndex* plonger = pindexNew;
genesis              1141     while (pfork != plonger)
genesis              1142     {
genesis              1143         while (plonger->nHeight > pfork->nHeight)
genesis              1144             if (!(plonger = plonger->pprev))
genesis              1145                 return error("Reorganize() : plonger->pprev is null");
genesis              1146         if (pfork == plonger)
genesis              1147             break;
genesis              1148         if (!(pfork = pfork->pprev))
genesis              1149             return error("Reorganize() : pfork->pprev is null");
genesis              1150     }
genesis              1151 
genesis              1152     
genesis              1153     vector<CBlockIndex*> vDisconnect;
genesis              1154     for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)
genesis              1155         vDisconnect.push_back(pindex);
genesis              1156 
genesis              1157     
genesis              1158     vector<CBlockIndex*> vConnect;
genesis              1159     for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)
genesis              1160         vConnect.push_back(pindex);
genesis              1161     reverse(vConnect.begin(), vConnect.end());
genesis              1162 
genesis              1163     
genesis              1164     vector<CTransaction> vResurrect;
genesis              1165     BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
genesis              1166     {
genesis              1167         CBlock block;
genesis              1168         if (!block.ReadFromDisk(pindex))
genesis              1169             return error("Reorganize() : ReadFromDisk for disconnect failed");
genesis              1170         if (!block.DisconnectBlock(txdb, pindex))
genesis              1171             return error("Reorganize() : DisconnectBlock failed");
genesis              1172 
genesis              1173         
genesis              1174         BOOST_FOREACH(const CTransaction& tx, block.vtx)
genesis              1175             if (!tx.IsCoinBase())
genesis              1176                 vResurrect.push_back(tx);
genesis              1177     }
genesis              1178 
genesis              1179     
genesis              1180     vector<CTransaction> vDelete;
genesis              1181     for (int i = 0; i < vConnect.size(); i++)
genesis              1182     {
genesis              1183         CBlockIndex* pindex = vConnect[i];
genesis              1184         CBlock block;
genesis              1185         if (!block.ReadFromDisk(pindex))
genesis              1186             return error("Reorganize() : ReadFromDisk for connect failed");
genesis              1187         if (!block.ConnectBlock(txdb, pindex))
genesis              1188         {
genesis              1189             
genesis              1190             txdb.TxnAbort();
genesis              1191             return error("Reorganize() : ConnectBlock failed");
genesis              1192         }
genesis              1193 
genesis              1194         
genesis              1195         BOOST_FOREACH(const CTransaction& tx, block.vtx)
genesis              1196             vDelete.push_back(tx);
genesis              1197     }
genesis              1198     if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
genesis              1199         return error("Reorganize() : WriteHashBestChain failed");
genesis              1200 
genesis              1201     
genesis              1202     if (!txdb.TxnCommit())
genesis              1203         return error("Reorganize() : TxnCommit failed");
genesis              1204 
genesis              1205     
genesis              1206     BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
genesis              1207         if (pindex->pprev)
genesis              1208             pindex->pprev->pnext = NULL;
genesis              1209 
genesis              1210     
genesis              1211     BOOST_FOREACH(CBlockIndex* pindex, vConnect)
genesis              1212         if (pindex->pprev)
genesis              1213             pindex->pprev->pnext = pindex;
genesis              1214 
genesis              1215     
genesis              1216     BOOST_FOREACH(CTransaction& tx, vResurrect)
genesis              1217         tx.AcceptToMemoryPool(txdb, false);
genesis              1218 
genesis              1219     
genesis              1220     BOOST_FOREACH(CTransaction& tx, vDelete)
genesis              1221         tx.RemoveFromMemoryPool();
genesis              1222 
genesis              1223     return true;
genesis              1224 }
genesis              1225 
genesis              1226 
genesis              1227 bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
genesis              1228 {
genesis              1229     uint256 hash = GetHash();
genesis              1230 
genesis              1231     txdb.TxnBegin();
genesis              1232     if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
genesis              1233     {
genesis              1234         txdb.WriteHashBestChain(hash);
genesis              1235         if (!txdb.TxnCommit())
genesis              1236             return error("SetBestChain() : TxnCommit failed");
genesis              1237         pindexGenesisBlock = pindexNew;
genesis              1238     }
genesis              1239     else if (hashPrevBlock == hashBestChain)
genesis              1240     {
genesis              1241         
genesis              1242         if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
genesis              1243         {
genesis              1244             txdb.TxnAbort();
genesis              1245             InvalidChainFound(pindexNew);
genesis              1246             return error("SetBestChain() : ConnectBlock failed");
genesis              1247         }
genesis              1248         if (!txdb.TxnCommit())
genesis              1249             return error("SetBestChain() : TxnCommit failed");
genesis              1250 
genesis              1251         
genesis              1252         pindexNew->pprev->pnext = pindexNew;
genesis              1253 
genesis              1254         
genesis              1255         BOOST_FOREACH(CTransaction& tx, vtx)
genesis              1256             tx.RemoveFromMemoryPool();
genesis              1257     }
genesis              1258     else
genesis              1259     {
genesis              1260         
genesis              1261         if (!Reorganize(txdb, pindexNew))
genesis              1262         {
genesis              1263             txdb.TxnAbort();
genesis              1264             InvalidChainFound(pindexNew);
genesis              1265             return error("SetBestChain() : Reorganize failed");
genesis              1266         }
genesis              1267     }
genesis              1268 
genesis              1269     
genesis              1270     if (!IsInitialBlockDownload())
genesis              1271     {
genesis              1272         const CBlockLocator locator(pindexNew);
genesis              1273         ::SetBestChain(locator);
genesis              1274     }
genesis              1275 
genesis              1276     
genesis              1277     hashBestChain = hash;
genesis              1278     pindexBest = pindexNew;
genesis              1279     nBestHeight = pindexBest->nHeight;
genesis              1280     bnBestChainWork = pindexNew->bnChainWork;
genesis              1281     nTimeBestReceived = GetTime();
genesis              1282     nTransactionsUpdated++;
genesis              1283     printf("SetBestChain: new best=%s  height=%d  work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
genesis              1284 
genesis              1285     return true;
genesis              1286 }
genesis              1287 
genesis              1288 
genesis              1289 bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
genesis              1290 {
genesis              1291     
genesis              1292     uint256 hash = GetHash();
genesis              1293     if (mapBlockIndex.count(hash))
genesis              1294         return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
genesis              1295 
genesis              1296     
genesis              1297     CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
genesis              1298     if (!pindexNew)
genesis              1299         return error("AddToBlockIndex() : new CBlockIndex failed");
genesis              1300     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
genesis              1301     pindexNew->phashBlock = &((*mi).first);
genesis              1302     map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
genesis              1303     if (miPrev != mapBlockIndex.end())
genesis              1304     {
genesis              1305         pindexNew->pprev = (*miPrev).second;
genesis              1306         pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
genesis              1307     }
genesis              1308     pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
genesis              1309 
genesis              1310     CTxDB txdb;
genesis              1311     txdb.TxnBegin();
genesis              1312     txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
genesis              1313     if (!txdb.TxnCommit())
genesis              1314         return false;
genesis              1315 
genesis              1316     
genesis              1317     if (pindexNew->bnChainWork > bnBestChainWork)
genesis              1318         if (!SetBestChain(txdb, pindexNew))
genesis              1319             return false;
genesis              1320 
genesis              1321     txdb.Close();
genesis              1322 
genesis              1323     if (pindexNew == pindexBest)
genesis              1324     {
genesis              1325         
genesis              1326         static uint256 hashPrevBestCoinBase;
genesis              1327         UpdatedTransaction(hashPrevBestCoinBase);
genesis              1328         hashPrevBestCoinBase = vtx[0].GetHash();
genesis              1329     }
genesis              1330 
genesis              1331     MainFrameRepaint();
genesis              1332     return true;
genesis              1333 }
genesis              1334 
genesis              1335 
genesis              1336 
genesis              1337 
genesis              1338 bool CBlock::CheckBlock() const
genesis              1339 {
genesis              1340     
genesis              1341     
genesis              1342 
genesis              1343     
genesis              1344     if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
genesis              1345         return DoS(100, error("CheckBlock() : size limits failed"));
genesis              1346 
genesis              1347     
genesis              1348     if (!CheckProofOfWork(GetHash(), nBits))
genesis              1349         return DoS(50, error("CheckBlock() : proof of work failed"));
genesis              1350 
genesis              1351     
genesis              1352     if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
genesis              1353         return error("CheckBlock() : block timestamp too far in the future");
genesis              1354 
genesis              1355     
genesis              1356     if (vtx.empty() || !vtx[0].IsCoinBase())
genesis              1357         return DoS(100, error("CheckBlock() : first tx is not coinbase"));
genesis              1358     for (int i = 1; i < vtx.size(); i++)
genesis              1359         if (vtx[i].IsCoinBase())
genesis              1360             return DoS(100, error("CheckBlock() : more than one coinbase"));
genesis              1361 
genesis              1362     
genesis              1363     BOOST_FOREACH(const CTransaction& tx, vtx)
genesis              1364         if (!tx.CheckTransaction())
genesis              1365             return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
genesis              1366 
genesis              1367     
genesis              1368     if (GetSigOpCount() > MAX_BLOCK_SIGOPS)
genesis              1369         return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));
genesis              1370 
genesis              1371     
genesis              1372     if (hashMerkleRoot != BuildMerkleTree())
genesis              1373         return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
genesis              1374 
genesis              1375     return true;
genesis              1376 }
genesis              1377 
genesis              1378 bool CBlock::AcceptBlock()
genesis              1379 {
genesis              1380     
genesis              1381     uint256 hash = GetHash();
genesis              1382     if (mapBlockIndex.count(hash))
genesis              1383         return error("AcceptBlock() : block already in mapBlockIndex");
genesis              1384 
genesis              1385     
genesis              1386     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
genesis              1387     if (mi == mapBlockIndex.end())
genesis              1388         return DoS(10, error("AcceptBlock() : prev block not found"));
genesis              1389     CBlockIndex* pindexPrev = (*mi).second;
genesis              1390     int nHeight = pindexPrev->nHeight+1;
genesis              1391 
genesis              1392     
genesis              1393     if (nBits != GetNextWorkRequired(pindexPrev, this))
genesis              1394         return DoS(100, error("AcceptBlock() : incorrect proof of work"));
genesis              1395 
genesis              1396     
genesis              1397     if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
genesis              1398         return error("AcceptBlock() : block's timestamp is too early");
genesis              1399 
genesis              1400     
genesis              1401     BOOST_FOREACH(const CTransaction& tx, vtx)
genesis              1402         if (!tx.IsFinal(nHeight, GetBlockTime()))
genesis              1403             return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
genesis              1404 
genesis              1405     
genesis              1406     if (!Checkpoints::CheckBlock(nHeight, hash))
genesis              1407         return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
genesis              1408 
genesis              1409     
genesis              1410     if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
genesis              1411         return error("AcceptBlock() : out of disk space");
genesis              1412     unsigned int nFile = -1;
genesis              1413     unsigned int nBlockPos = 0;
genesis              1414     if (!WriteToDisk(nFile, nBlockPos))
genesis              1415         return error("AcceptBlock() : WriteToDisk failed");
genesis              1416     if (!AddToBlockIndex(nFile, nBlockPos))
genesis              1417         return error("AcceptBlock() : AddToBlockIndex failed");
genesis              1418 
genesis              1419     
genesis              1420     if (hashBestChain == hash)
genesis              1421         CRITICAL_BLOCK(cs_vNodes)
genesis              1422             BOOST_FOREACH(CNode* pnode, vNodes)
genesis              1423                 if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700))
genesis              1424                     pnode->PushInventory(CInv(MSG_BLOCK, hash));
genesis              1425 
genesis              1426     return true;
genesis              1427 }
genesis              1428 
genesis              1429 bool ProcessBlock(CNode* pfrom, CBlock* pblock)
genesis              1430 {
genesis              1431     
genesis              1432     uint256 hash = pblock->GetHash();
genesis              1433     if (mapBlockIndex.count(hash))
genesis              1434         return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
genesis              1435     if (mapOrphanBlocks.count(hash))
genesis              1436         return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str());
genesis              1437 
genesis              1438     
genesis              1439     if (!pblock->CheckBlock())
genesis              1440         return error("ProcessBlock() : CheckBlock FAILED");
genesis              1441 
genesis              1442     CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
genesis              1443     if (pcheckpoint && pblock->hashPrevBlock != hashBestChain)
genesis              1444     {
genesis              1445         
genesis              1446         int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
genesis              1447         if (deltaTime < 0)
genesis              1448         {
genesis              1449             if (pfrom)
genesis              1450                 pfrom->Misbehaving(100);
genesis              1451             return error("ProcessBlock() : block with timestamp before last checkpoint");
genesis              1452         }
genesis              1453         CBigNum bnNewBlock;
genesis              1454         bnNewBlock.SetCompact(pblock->nBits);
genesis              1455         CBigNum bnRequired;
genesis              1456         bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
genesis              1457         if (bnNewBlock > bnRequired)
genesis              1458         {
genesis              1459             if (pfrom)
genesis              1460                 pfrom->Misbehaving(100);
genesis              1461             return error("ProcessBlock() : block with too little proof-of-work");
genesis              1462         }
genesis              1463     }
genesis              1464 
genesis              1465 
genesis              1466     
genesis              1467     if (!mapBlockIndex.count(pblock->hashPrevBlock))
genesis              1468     {
genesis              1469         printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
genesis              1470         CBlock* pblock2 = new CBlock(*pblock);
genesis              1471         mapOrphanBlocks.insert(make_pair(hash, pblock2));
genesis              1472         mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));
genesis              1473 
genesis              1474         
genesis              1475         if (pfrom)
genesis              1476             pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2));
genesis              1477         return true;
genesis              1478     }
genesis              1479 
genesis              1480     
genesis              1481     if (!pblock->AcceptBlock())
genesis              1482         return error("ProcessBlock() : AcceptBlock FAILED");
genesis              1483 
genesis              1484     
genesis              1485     vector<uint256> vWorkQueue;
genesis              1486     vWorkQueue.push_back(hash);
genesis              1487     for (int i = 0; i < vWorkQueue.size(); i++)
genesis              1488     {
genesis              1489         uint256 hashPrev = vWorkQueue[i];
genesis              1490         for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
genesis              1491              mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
genesis              1492              ++mi)
genesis              1493         {
genesis              1494             CBlock* pblockOrphan = (*mi).second;
genesis              1495             if (pblockOrphan->AcceptBlock())
genesis              1496                 vWorkQueue.push_back(pblockOrphan->GetHash());
genesis              1497             mapOrphanBlocks.erase(pblockOrphan->GetHash());
genesis              1498             delete pblockOrphan;
genesis              1499         }
genesis              1500         mapOrphanBlocksByPrev.erase(hashPrev);
genesis              1501     }
genesis              1502 
genesis              1503     printf("ProcessBlock: ACCEPTED\n");
genesis              1504     return true;
genesis              1505 }
genesis              1506 
genesis              1507 
genesis              1508 
genesis              1509 
genesis              1510 
genesis              1511 
genesis              1512 
genesis              1513 
genesis              1514 bool CheckDiskSpace(uint64 nAdditionalBytes)
genesis              1515 {
genesis              1516     uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
genesis              1517 
genesis              1518     
genesis              1519     if (nFreeBytesAvailable < (uint64)15000000 + nAdditionalBytes)
genesis              1520     {
genesis              1521         fShutdown = true;
genesis              1522         string strMessage = _("Warning: Disk space is low  ");
genesis              1523         strMiscWarning = strMessage;
genesis              1524         printf("*** %s\n", strMessage.c_str());
genesis              1525         ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
genesis              1526         CreateThread(Shutdown, NULL);
genesis              1527         return false;
genesis              1528     }
genesis              1529     return true;
genesis              1530 }
genesis              1531 
genesis              1532 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
genesis              1533 {
genesis              1534     if (nFile == -1)
genesis              1535         return NULL;
genesis              1536     FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
genesis              1537     if (!file)
genesis              1538         return NULL;
genesis              1539     if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
genesis              1540     {
genesis              1541         if (fseek(file, nBlockPos, SEEK_SET) != 0)
genesis              1542         {
genesis              1543             fclose(file);
genesis              1544             return NULL;
genesis              1545         }
genesis              1546     }
genesis              1547     return file;
genesis              1548 }
genesis              1549 
genesis              1550 static unsigned int nCurrentBlockFile = 1;
genesis              1551 
genesis              1552 FILE* AppendBlockFile(unsigned int& nFileRet)
genesis              1553 {
genesis              1554     nFileRet = 0;
genesis              1555     loop
genesis              1556     {
genesis              1557         FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
genesis              1558         if (!file)
genesis              1559             return NULL;
genesis              1560         if (fseek(file, 0, SEEK_END) != 0)
genesis              1561             return NULL;
genesis              1562         
genesis              1563         if (ftell(file) < 0x7F000000 - MAX_SIZE)
genesis              1564         {
genesis              1565             nFileRet = nCurrentBlockFile;
genesis              1566             return file;
genesis              1567         }
genesis              1568         fclose(file);
genesis              1569         nCurrentBlockFile++;
genesis              1570     }
genesis              1571 }
genesis              1572 
genesis              1573 bool LoadBlockIndex(bool fAllowNew)
genesis              1574 {
genesis              1575     if (fTestNet)
genesis              1576     {
genesis              1577         hashGenesisBlock = uint256("0x00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008");
genesis              1578         bnProofOfWorkLimit = CBigNum(~uint256(0) >> 28);
genesis              1579         pchMessageStart[0] = 0xfa;
genesis              1580         pchMessageStart[1] = 0xbf;
genesis              1581         pchMessageStart[2] = 0xb5;
genesis              1582         pchMessageStart[3] = 0xda;
genesis              1583     }
genesis              1584 
genesis              1585     
genesis              1586     
genesis              1587     
genesis              1588     CTxDB txdb("cr");
genesis              1589     if (!txdb.LoadBlockIndex())
genesis              1590         return false;
genesis              1591     txdb.Close();
genesis              1592 
genesis              1593     
genesis              1594     
genesis              1595     
genesis              1596     if (mapBlockIndex.empty())
genesis              1597     {
genesis              1598         if (!fAllowNew)
genesis              1599             return false;
genesis              1600 
genesis              1601         
genesis              1602         
genesis              1603         
genesis              1604         
genesis              1605         
genesis              1606         
genesis              1607 
genesis              1608         
genesis              1609         const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
genesis              1610         CTransaction txNew;
genesis              1611         txNew.vin.resize(1);
genesis              1612         txNew.vout.resize(1);
genesis              1613         txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
genesis              1614         txNew.vout[0].nValue = 50 * COIN;
genesis              1615         txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
genesis              1616         CBlock block;
genesis              1617         block.vtx.push_back(txNew);
genesis              1618         block.hashPrevBlock = 0;
genesis              1619         block.hashMerkleRoot = block.BuildMerkleTree();
genesis              1620         block.nVersion = 1;
genesis              1621         block.nTime    = 1231006505;
genesis              1622         block.nBits    = 0x1d00ffff;
genesis              1623         block.nNonce   = 2083236893;
genesis              1624 
genesis              1625         if (fTestNet)
genesis              1626         {
genesis              1627             block.nTime    = 1296688602;
genesis              1628             block.nBits    = 0x1d07fff8;
genesis              1629             block.nNonce   = 384568319;
genesis              1630         }
genesis              1631 
genesis              1632         
genesis              1633         printf("%s\n", block.GetHash().ToString().c_str());
genesis              1634         printf("%s\n", hashGenesisBlock.ToString().c_str());
genesis              1635         printf("%s\n", block.hashMerkleRoot.ToString().c_str());
genesis              1636         assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
genesis              1637         block.print();
genesis              1638         assert(block.GetHash() == hashGenesisBlock);
genesis              1639 
genesis              1640         
genesis              1641         unsigned int nFile;
genesis              1642         unsigned int nBlockPos;
genesis              1643         if (!block.WriteToDisk(nFile, nBlockPos))
genesis              1644             return error("LoadBlockIndex() : writing genesis block to disk failed");
genesis              1645         if (!block.AddToBlockIndex(nFile, nBlockPos))
genesis              1646             return error("LoadBlockIndex() : genesis block not accepted");
genesis              1647     }
genesis              1648 
genesis              1649     return true;
genesis              1650 }
genesis              1651 
genesis              1652 
genesis              1653 
genesis              1654 void PrintBlockTree()
genesis              1655 {
genesis              1656     
genesis              1657     map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
genesis              1658     for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
genesis              1659     {
genesis              1660         CBlockIndex* pindex = (*mi).second;
genesis              1661         mapNext[pindex->pprev].push_back(pindex);
genesis              1662         
genesis              1663         
genesis              1664         
genesis              1665     }
genesis              1666 
genesis              1667     vector<pair<int, CBlockIndex*> > vStack;
genesis              1668     vStack.push_back(make_pair(0, pindexGenesisBlock));
genesis              1669 
genesis              1670     int nPrevCol = 0;
genesis              1671     while (!vStack.empty())
genesis              1672     {
genesis              1673         int nCol = vStack.back().first;
genesis              1674         CBlockIndex* pindex = vStack.back().second;
genesis              1675         vStack.pop_back();
genesis              1676 
genesis              1677         
genesis              1678         if (nCol > nPrevCol)
genesis              1679         {
genesis              1680             for (int i = 0; i < nCol-1; i++)
genesis              1681                 printf("| ");
genesis              1682             printf("|\\\n");
genesis              1683         }
genesis              1684         else if (nCol < nPrevCol)
genesis              1685         {
genesis              1686             for (int i = 0; i < nCol; i++)
genesis              1687                 printf("| ");
genesis              1688             printf("|\n");
genesis              1689        }
genesis              1690         nPrevCol = nCol;
genesis              1691 
genesis              1692         
genesis              1693         for (int i = 0; i < nCol; i++)
genesis              1694             printf("| ");
genesis              1695 
genesis              1696         
genesis              1697         CBlock block;
genesis              1698         block.ReadFromDisk(pindex);
genesis              1699         printf("%d (%u,%u) %s  %s  tx %d",
genesis              1700             pindex->nHeight,
genesis              1701             pindex->nFile,
genesis              1702             pindex->nBlockPos,
genesis              1703             block.GetHash().ToString().substr(0,20).c_str(),
genesis              1704             DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
genesis              1705             block.vtx.size());
genesis              1706 
genesis              1707         PrintWallets(block);
genesis              1708 
genesis              1709         
genesis              1710         vector<CBlockIndex*>& vNext = mapNext[pindex];
genesis              1711         for (int i = 0; i < vNext.size(); i++)
genesis              1712         {
genesis              1713             if (vNext[i]->pnext)
genesis              1714             {
genesis              1715                 swap(vNext[0], vNext[i]);
genesis              1716                 break;
genesis              1717             }
genesis              1718         }
genesis              1719 
genesis              1720         
genesis              1721         for (int i = 0; i < vNext.size(); i++)
genesis              1722             vStack.push_back(make_pair(nCol+i, vNext[i]));
genesis              1723     }
genesis              1724 }
genesis              1725 
genesis              1726 
genesis              1727 
genesis              1728 
genesis              1729 
genesis              1730 
genesis              1731 
genesis              1732 
genesis              1733 
genesis              1734 
genesis              1735 
genesis              1736 
genesis              1737 
genesis              1738 
genesis              1739 
genesis              1740 map<uint256, CAlert> mapAlerts;
genesis              1741 CCriticalSection cs_mapAlerts;
genesis              1742 
genesis              1743 string GetWarnings(string strFor)
genesis              1744 {
genesis              1745     int nPriority = 0;
genesis              1746     string strStatusBar;
genesis              1747     string strRPC;
genesis              1748     if (GetBoolArg("-testsafemode"))
genesis              1749         strRPC = "test";
genesis              1750 
genesis              1751     
genesis              1752     if (strMiscWarning != "")
genesis              1753     {
genesis              1754         nPriority = 1000;
genesis              1755         strStatusBar = strMiscWarning;
genesis              1756     }
genesis              1757 
genesis              1758     
genesis              1759     if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
genesis              1760     {
genesis              1761         nPriority = 2000;
genesis              1762         strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct!  You may need to upgrade, or other nodes may need to upgrade.";
genesis              1763     }
genesis              1764 
genesis              1765     
genesis              1766     CRITICAL_BLOCK(cs_mapAlerts)
genesis              1767     {
genesis              1768         BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
genesis              1769         {
genesis              1770             const CAlert& alert = item.second;
genesis              1771             if (alert.AppliesToMe() && alert.nPriority > nPriority)
genesis              1772             {
genesis              1773                 nPriority = alert.nPriority;
genesis              1774                 strStatusBar = alert.strStatusBar;
genesis              1775             }
genesis              1776         }
genesis              1777     }
genesis              1778 
genesis              1779     if (strFor == "statusbar")
genesis              1780         return strStatusBar;
genesis              1781     else if (strFor == "rpc")
genesis              1782         return strRPC;
genesis              1783     assert(!"GetWarnings() : invalid parameter");
genesis              1784     return "error";
genesis              1785 }
genesis              1786 
genesis              1787 bool CAlert::ProcessAlert()
genesis              1788 {
genesis              1789     if (!CheckSignature())
genesis              1790         return false;
genesis              1791     if (!IsInEffect())
genesis              1792         return false;
genesis              1793 
genesis              1794     CRITICAL_BLOCK(cs_mapAlerts)
genesis              1795     {
genesis              1796         
genesis              1797         for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
genesis              1798         {
genesis              1799             const CAlert& alert = (*mi).second;
genesis              1800             if (Cancels(alert))
genesis              1801             {
genesis              1802                 printf("cancelling alert %d\n", alert.nID);
genesis              1803                 mapAlerts.erase(mi++);
genesis              1804             }
genesis              1805             else if (!alert.IsInEffect())
genesis              1806             {
genesis              1807                 printf("expiring alert %d\n", alert.nID);
genesis              1808                 mapAlerts.erase(mi++);
genesis              1809             }
genesis              1810             else
genesis              1811                 mi++;
genesis              1812         }
genesis              1813 
genesis              1814         
genesis              1815         BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
genesis              1816         {
genesis              1817             const CAlert& alert = item.second;
genesis              1818             if (alert.Cancels(*this))
genesis              1819             {
genesis              1820                 printf("alert already cancelled by %d\n", alert.nID);
genesis              1821                 return false;
genesis              1822             }
genesis              1823         }
genesis              1824 
genesis              1825         
genesis              1826         mapAlerts.insert(make_pair(GetHash(), *this));
genesis              1827     }
genesis              1828 
genesis              1829     printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
genesis              1830     MainFrameRepaint();
genesis              1831     return true;
genesis              1832 }
genesis              1833 
genesis              1834 
genesis              1835 
genesis              1836 
genesis              1837 
genesis              1838 
genesis              1839 
genesis              1840 
genesis              1841 
genesis              1842 
genesis              1843 
genesis              1844 
genesis              1845 
genesis              1846 
genesis              1847 bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
genesis              1848 {
genesis              1849     switch (inv.type)
genesis              1850     {
genesis              1851     case MSG_TX:    return mapTransactions.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
genesis              1852     case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
genesis              1853     }
genesis              1854     
genesis              1855     return true;
genesis              1856 }
genesis              1857 
genesis              1858 
genesis              1859 
genesis              1860 
genesis              1861 
genesis              1862 
genesis              1863 
genesis              1864 unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
genesis              1865 
genesis              1866 
genesis              1867 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
genesis              1868 {
genesis              1869     static map<unsigned int, vector<unsigned char> > mapReuseKey;
genesis              1870     RandAddSeedPerfmon();
genesis              1871     if (fDebug) {
genesis              1872         printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
genesis              1873         printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
genesis              1874     }
genesis              1875     if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
genesis              1876     {
genesis              1877         printf("dropmessagestest DROPPING RECV MESSAGE\n");
genesis              1878         return true;
genesis              1879     }
genesis              1880 
genesis              1881 
genesis              1882 
genesis              1883 
genesis              1884 
genesis              1885     if (strCommand == "version")
genesis              1886     {
genesis              1887         
genesis              1888         if (pfrom->nVersion != 0)
genesis              1889         {
genesis              1890             pfrom->Misbehaving(1);
genesis              1891             return false;
genesis              1892         }
genesis              1893 
genesis              1894         int64 nTime;
genesis              1895         CAddress addrMe;
genesis              1896         CAddress addrFrom;
genesis              1897         uint64 nNonce = 1;
genesis              1898         vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
genesis              1899         if (pfrom->nVersion == 10300)
genesis              1900             pfrom->nVersion = 300;
genesis              1901         if (pfrom->nVersion >= 106 && !vRecv.empty())
genesis              1902             vRecv >> addrFrom >> nNonce;
genesis              1903         if (pfrom->nVersion >= 106 && !vRecv.empty())
genesis              1904             vRecv >> pfrom->strSubVer;
genesis              1905         if (pfrom->nVersion >= 209 && !vRecv.empty())
genesis              1906             vRecv >> pfrom->nStartingHeight;
genesis              1907 
genesis              1908         if (pfrom->nVersion == 0)
genesis              1909             return false;
genesis              1910 
genesis              1911         
genesis              1912         if (nNonce == nLocalHostNonce && nNonce > 1)
genesis              1913         {
genesis              1914             printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
genesis              1915             pfrom->fDisconnect = true;
genesis              1916             return true;
genesis              1917         }
genesis              1918 
genesis              1919         
genesis              1920         if (pfrom->fInbound)
genesis              1921             pfrom->PushVersion();
genesis              1922 
genesis              1923         pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
genesis              1924 
genesis              1925         AddTimeData(pfrom->addr.ip, nTime);
genesis              1926 
genesis              1927         
genesis              1928         if (pfrom->nVersion >= 209)
genesis              1929             pfrom->PushMessage("verack");
genesis              1930         pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
genesis              1931         if (pfrom->nVersion < 209)
genesis              1932             pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
genesis              1933 
genesis              1934         if (!pfrom->fInbound)
genesis              1935         {
genesis              1936             
genesis              1937             if (addrLocalHost.IsRoutable() && !fUseProxy)
genesis              1938             {
genesis              1939                 CAddress addr(addrLocalHost);
genesis              1940                 addr.nTime = GetAdjustedTime();
genesis              1941                 pfrom->PushAddress(addr);
genesis              1942             }
genesis              1943 
genesis              1944             
genesis              1945             if (pfrom->nVersion >= 31402 || mapAddresses.size() < 1000)
genesis              1946             {
genesis              1947                 pfrom->PushMessage("getaddr");
genesis              1948                 pfrom->fGetAddr = true;
genesis              1949             }
genesis              1950         }
genesis              1951 
genesis              1952         
genesis              1953         static int nAskedForBlocks;
genesis              1954         if (!pfrom->fClient &&
genesis              1955             (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
genesis              1956              (nAskedForBlocks < 1 || vNodes.size() <= 1))
genesis              1957         {
genesis              1958             nAskedForBlocks++;
genesis              1959             pfrom->PushGetBlocks(pindexBest, uint256(0));
genesis              1960         }
genesis              1961 
genesis              1962         
genesis              1963         CRITICAL_BLOCK(cs_mapAlerts)
genesis              1964             BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
genesis              1965                 item.second.RelayTo(pfrom);
genesis              1966 
genesis              1967         pfrom->fSuccessfullyConnected = true;
genesis              1968 
genesis              1969         printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
genesis              1970 
genesis              1971         cPeerBlockCounts.input(pfrom->nStartingHeight);
genesis              1972     }
genesis              1973 
genesis              1974 
genesis              1975     else if (pfrom->nVersion == 0)
genesis              1976     {
genesis              1977         
genesis              1978         pfrom->Misbehaving(1);
genesis              1979         return false;
genesis              1980     }
genesis              1981 
genesis              1982 
genesis              1983     else if (strCommand == "verack")
genesis              1984     {
genesis              1985         pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
genesis              1986     }
genesis              1987 
genesis              1988 
genesis              1989     else if (strCommand == "addr")
genesis              1990     {
genesis              1991         vector<CAddress> vAddr;
genesis              1992         vRecv >> vAddr;
genesis              1993 
genesis              1994         
genesis              1995         if (pfrom->nVersion < 209)
genesis              1996             return true;
genesis              1997         if (pfrom->nVersion < 31402 && mapAddresses.size() > 1000)
genesis              1998             return true;
genesis              1999         if (vAddr.size() > 1000)
genesis              2000         {
genesis              2001             pfrom->Misbehaving(20);
genesis              2002             return error("message addr size() = %d", vAddr.size());
genesis              2003         }
genesis              2004 
genesis              2005         
genesis              2006         CAddrDB addrDB;
genesis              2007         addrDB.TxnBegin();
genesis              2008         int64 nNow = GetAdjustedTime();
genesis              2009         int64 nSince = nNow - 10 * 60;
genesis              2010         BOOST_FOREACH(CAddress& addr, vAddr)
genesis              2011         {
genesis              2012             if (fShutdown)
genesis              2013                 return true;
genesis              2014             
genesis              2015             if (!addr.IsIPv4())
genesis              2016                 continue;
genesis              2017             if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
genesis              2018                 addr.nTime = nNow - 5 * 24 * 60 * 60;
genesis              2019             AddAddress(addr, 2 * 60 * 60, &addrDB);
genesis              2020             pfrom->AddAddressKnown(addr);
genesis              2021             if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
genesis              2022             {
genesis              2023                 
genesis              2024                 CRITICAL_BLOCK(cs_vNodes)
genesis              2025                 {
genesis              2026                     
genesis              2027                     
genesis              2028                     static uint256 hashSalt;
genesis              2029                     if (hashSalt == 0)
genesis              2030                         RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
genesis              2031                     uint256 hashRand = hashSalt ^ (((int64)addr.ip)<<32) ^ ((GetTime()+addr.ip)/(24*60*60));
genesis              2032                     hashRand = Hash(BEGIN(hashRand), END(hashRand));
genesis              2033                     multimap<uint256, CNode*> mapMix;
genesis              2034                     BOOST_FOREACH(CNode* pnode, vNodes)
genesis              2035                     {
genesis              2036                         if (pnode->nVersion < 31402)
genesis              2037                             continue;
genesis              2038                         unsigned int nPointer;
genesis              2039                         memcpy(&nPointer, &pnode, sizeof(nPointer));
genesis              2040                         uint256 hashKey = hashRand ^ nPointer;
genesis              2041                         hashKey = Hash(BEGIN(hashKey), END(hashKey));
genesis              2042                         mapMix.insert(make_pair(hashKey, pnode));
genesis              2043                     }
genesis              2044                     int nRelayNodes = 2;
genesis              2045                     for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
genesis              2046                         ((*mi).second)->PushAddress(addr);
genesis              2047                 }
genesis              2048             }
genesis              2049         }
genesis              2050         addrDB.TxnCommit();  
genesis              2051         if (vAddr.size() < 1000)
genesis              2052             pfrom->fGetAddr = false;
genesis              2053     }
genesis              2054 
genesis              2055 
genesis              2056     else if (strCommand == "inv")
genesis              2057     {
genesis              2058         vector<CInv> vInv;
genesis              2059         vRecv >> vInv;
genesis              2060         if (vInv.size() > 50000)
genesis              2061         {
genesis              2062             pfrom->Misbehaving(20);
genesis              2063             return error("message inv size() = %d", vInv.size());
genesis              2064         }
genesis              2065 
genesis              2066         CTxDB txdb("r");
genesis              2067         BOOST_FOREACH(const CInv& inv, vInv)
genesis              2068         {
genesis              2069             if (fShutdown)
genesis              2070                 return true;
genesis              2071             pfrom->AddInventoryKnown(inv);
genesis              2072 
genesis              2073             bool fAlreadyHave = AlreadyHave(txdb, inv);
genesis              2074             if (fDebug)
genesis              2075                 printf("  got inventory: %s  %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
genesis              2076 
genesis              2077             if (!fAlreadyHave)
genesis              2078                 pfrom->AskFor(inv);
genesis              2079             else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
genesis              2080                 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
genesis              2081 
genesis              2082             
genesis              2083             Inventory(inv.hash);
genesis              2084         }
genesis              2085     }
genesis              2086 
genesis              2087 
genesis              2088     else if (strCommand == "getdata")
genesis              2089     {
genesis              2090         vector<CInv> vInv;
genesis              2091         vRecv >> vInv;
genesis              2092         if (vInv.size() > 50000)
genesis              2093         {
genesis              2094             pfrom->Misbehaving(20);
genesis              2095             return error("message getdata size() = %d", vInv.size());
genesis              2096         }
genesis              2097 
genesis              2098         BOOST_FOREACH(const CInv& inv, vInv)
genesis              2099         {
genesis              2100             if (fShutdown)
genesis              2101                 return true;
genesis              2102             printf("received getdata for: %s\n", inv.ToString().c_str());
genesis              2103 
genesis              2104             if (inv.type == MSG_BLOCK)
genesis              2105             {
genesis              2106                 
genesis              2107                 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
genesis              2108                 if (mi != mapBlockIndex.end())
genesis              2109                 {
genesis              2110                     CBlock block;
genesis              2111                     block.ReadFromDisk((*mi).second);
genesis              2112                     pfrom->PushMessage("block", block);
genesis              2113 
genesis              2114                     
genesis              2115                     if (inv.hash == pfrom->hashContinue)
genesis              2116                     {
genesis              2117                         
genesis              2118                         
genesis              2119                         
genesis              2120                         vector<CInv> vInv;
genesis              2121                         vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
genesis              2122                         pfrom->PushMessage("inv", vInv);
genesis              2123                         pfrom->hashContinue = 0;
genesis              2124                     }
genesis              2125                 }
genesis              2126             }
genesis              2127             else if (inv.IsKnownType())
genesis              2128             {
genesis              2129                 
genesis              2130                 CRITICAL_BLOCK(cs_mapRelay)
genesis              2131                 {
genesis              2132                     map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
genesis              2133                     if (mi != mapRelay.end())
genesis              2134                         pfrom->PushMessage(inv.GetCommand(), (*mi).second);
genesis              2135                 }
genesis              2136             }
genesis              2137 
genesis              2138             
genesis              2139             Inventory(inv.hash);
genesis              2140         }
genesis              2141     }
genesis              2142 
genesis              2143 
genesis              2144     else if (strCommand == "getblocks")
genesis              2145     {
genesis              2146         CBlockLocator locator;
genesis              2147         uint256 hashStop;
genesis              2148         vRecv >> locator >> hashStop;
genesis              2149 
genesis              2150         
genesis              2151         CBlockIndex* pindex = locator.GetBlockIndex();
genesis              2152 
genesis              2153         
genesis              2154         if (pindex)
genesis              2155             pindex = pindex->pnext;
genesis              2156         int nLimit = 500 + locator.GetDistanceBack();
genesis              2157         unsigned int nBytes = 0;
genesis              2158         printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
genesis              2159         for (; pindex; pindex = pindex->pnext)
genesis              2160         {
genesis              2161             if (pindex->GetBlockHash() == hashStop)
genesis              2162             {
genesis              2163                 printf("  getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
genesis              2164                 break;
genesis              2165             }
genesis              2166             pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
genesis              2167             CBlock block;
genesis              2168             block.ReadFromDisk(pindex, true);
genesis              2169             nBytes += block.GetSerializeSize(SER_NETWORK);
genesis              2170             if (--nLimit <= 0 || nBytes >= SendBufferSize()/2)
genesis              2171             {
genesis              2172                 
genesis              2173                 
genesis              2174                 printf("  getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
genesis              2175                 pfrom->hashContinue = pindex->GetBlockHash();
genesis              2176                 break;
genesis              2177             }
genesis              2178         }
genesis              2179     }
genesis              2180 
genesis              2181 
genesis              2182     else if (strCommand == "getheaders")
genesis              2183     {
genesis              2184         CBlockLocator locator;
genesis              2185         uint256 hashStop;
genesis              2186         vRecv >> locator >> hashStop;
genesis              2187 
genesis              2188         CBlockIndex* pindex = NULL;
genesis              2189         if (locator.IsNull())
genesis              2190         {
genesis              2191             
genesis              2192             map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop);
genesis              2193             if (mi == mapBlockIndex.end())
genesis              2194                 return true;
genesis              2195             pindex = (*mi).second;
genesis              2196         }
genesis              2197         else
genesis              2198         {
genesis              2199             
genesis              2200             pindex = locator.GetBlockIndex();
genesis              2201             if (pindex)
genesis              2202                 pindex = pindex->pnext;
genesis              2203         }
genesis              2204 
genesis              2205         vector<CBlock> vHeaders;
genesis              2206         int nLimit = 2000 + locator.GetDistanceBack();
genesis              2207         printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
genesis              2208         for (; pindex; pindex = pindex->pnext)
genesis              2209         {
genesis              2210             vHeaders.push_back(pindex->GetBlockHeader());
genesis              2211             if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
genesis              2212                 break;
genesis              2213         }
genesis              2214         pfrom->PushMessage("headers", vHeaders);
genesis              2215     }
genesis              2216 
genesis              2217 
genesis              2218     else if (strCommand == "tx")
genesis              2219     {
genesis              2220         vector<uint256> vWorkQueue;
genesis              2221         CDataStream vMsg(vRecv);
genesis              2222         CTransaction tx;
genesis              2223         vRecv >> tx;
genesis              2224 
genesis              2225         CInv inv(MSG_TX, tx.GetHash());
genesis              2226         pfrom->AddInventoryKnown(inv);
genesis              2227 
genesis              2228         bool fMissingInputs = false;
genesis              2229         if (tx.AcceptToMemoryPool(true, &fMissingInputs))
genesis              2230         {
genesis              2231             SyncWithWallets(tx, NULL, true);
genesis              2232             RelayMessage(inv, vMsg);
genesis              2233             mapAlreadyAskedFor.erase(inv);
genesis              2234             vWorkQueue.push_back(inv.hash);
genesis              2235 
genesis              2236             
genesis              2237             for (int i = 0; i < vWorkQueue.size(); i++)
genesis              2238             {
genesis              2239                 uint256 hashPrev = vWorkQueue[i];
genesis              2240                 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
genesis              2241                      mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
genesis              2242                      ++mi)
genesis              2243                 {
genesis              2244                     const CDataStream& vMsg = *((*mi).second);
genesis              2245                     CTransaction tx;
genesis              2246                     CDataStream(vMsg) >> tx;
genesis              2247                     CInv inv(MSG_TX, tx.GetHash());
genesis              2248 
genesis              2249                     if (tx.AcceptToMemoryPool(true))
genesis              2250                     {
genesis              2251                         printf("   accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
genesis              2252                         SyncWithWallets(tx, NULL, true);
genesis              2253                         RelayMessage(inv, vMsg);
genesis              2254                         mapAlreadyAskedFor.erase(inv);
genesis              2255                         vWorkQueue.push_back(inv.hash);
genesis              2256                     }
genesis              2257                 }
genesis              2258             }
genesis              2259 
genesis              2260             BOOST_FOREACH(uint256 hash, vWorkQueue)
genesis              2261                 EraseOrphanTx(hash);
genesis              2262         }
genesis              2263         else if (fMissingInputs)
genesis              2264         {
genesis              2265             printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
genesis              2266             AddOrphanTx(vMsg);
genesis              2267 
genesis              2268             
genesis              2269             int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
genesis              2270             if (nEvicted > 0)
genesis              2271                 printf("mapOrphan overflow, removed %d tx\n", nEvicted);
genesis              2272         }
genesis              2273         if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
genesis              2274     }
genesis              2275 
genesis              2276 
genesis              2277     else if (strCommand == "block")
genesis              2278     {
genesis              2279         CBlock block;
genesis              2280         vRecv >> block;
genesis              2281 
genesis              2282         printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str());
genesis              2283         
genesis              2284 
genesis              2285         CInv inv(MSG_BLOCK, block.GetHash());
genesis              2286         pfrom->AddInventoryKnown(inv);
genesis              2287 
genesis              2288         if (ProcessBlock(pfrom, &block))
genesis              2289             mapAlreadyAskedFor.erase(inv);
genesis              2290         if (block.nDoS) pfrom->Misbehaving(block.nDoS);
genesis              2291     }
genesis              2292 
genesis              2293 
genesis              2294     else if (strCommand == "getaddr")
genesis              2295     {
genesis              2296         
genesis              2297         pfrom->vAddrToSend.clear();
genesis              2298         int64 nSince = GetAdjustedTime() - 3 * 60 * 60; 
genesis              2299         CRITICAL_BLOCK(cs_mapAddresses)
genesis              2300         {
genesis              2301             unsigned int nCount = 0;
genesis              2302             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
genesis              2303             {
genesis              2304                 const CAddress& addr = item.second;
genesis              2305                 if (addr.nTime > nSince)
genesis              2306                     nCount++;
genesis              2307             }
genesis              2308             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
genesis              2309             {
genesis              2310                 const CAddress& addr = item.second;
genesis              2311                 if (addr.nTime > nSince && GetRand(nCount) < 2500)
genesis              2312                     pfrom->PushAddress(addr);
genesis              2313             }
genesis              2314         }
genesis              2315     }
genesis              2316 
genesis              2317 
genesis              2318     else if (strCommand == "checkorder")
genesis              2319     {
genesis              2320         uint256 hashReply;
genesis              2321         vRecv >> hashReply;
genesis              2322 
genesis              2323         if (!GetBoolArg("-allowreceivebyip"))
genesis              2324         {
genesis              2325             pfrom->PushMessage("reply", hashReply, (int)2, string(""));
genesis              2326             return true;
genesis              2327         }
genesis              2328 
genesis              2329         CWalletTx order;
genesis              2330         vRecv >> order;
genesis              2331 
genesis              2332         
genesis              2333 
genesis              2334         
genesis              2335         if (!mapReuseKey.count(pfrom->addr.ip))
genesis              2336             pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true);
genesis              2337 
genesis              2338         
genesis              2339         CScript scriptPubKey;
genesis              2340         scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;
genesis              2341         pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
genesis              2342     }
genesis              2343 
genesis              2344 
genesis              2345     else if (strCommand == "reply")
genesis              2346     {
genesis              2347         uint256 hashReply;
genesis              2348         vRecv >> hashReply;
genesis              2349 
genesis              2350         CRequestTracker tracker;
genesis              2351         CRITICAL_BLOCK(pfrom->cs_mapRequests)
genesis              2352         {
genesis              2353             map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
genesis              2354             if (mi != pfrom->mapRequests.end())
genesis              2355             {
genesis              2356                 tracker = (*mi).second;
genesis              2357                 pfrom->mapRequests.erase(mi);
genesis              2358             }
genesis              2359         }
genesis              2360         if (!tracker.IsNull())
genesis              2361             tracker.fn(tracker.param1, vRecv);
genesis              2362     }
genesis              2363 
genesis              2364 
genesis              2365     else if (strCommand == "ping")
genesis              2366     {
genesis              2367     }
genesis              2368 
genesis              2369 
genesis              2370     else if (strCommand == "alert")
genesis              2371     {
genesis              2372         CAlert alert;
genesis              2373         vRecv >> alert;
genesis              2374 
genesis              2375         if (alert.ProcessAlert())
genesis              2376         {
genesis              2377             
genesis              2378             pfrom->setKnown.insert(alert.GetHash());
genesis              2379             CRITICAL_BLOCK(cs_vNodes)
genesis              2380                 BOOST_FOREACH(CNode* pnode, vNodes)
genesis              2381                     alert.RelayTo(pnode);
genesis              2382         }
genesis              2383     }
genesis              2384 
genesis              2385 
genesis              2386     else
genesis              2387     {
genesis              2388         
genesis              2389     }
genesis              2390 
genesis              2391 
genesis              2392     
genesis              2393     if (pfrom->fNetworkNode)
genesis              2394         if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
genesis              2395             AddressCurrentlyConnected(pfrom->addr);
genesis              2396 
genesis              2397 
genesis              2398     return true;
genesis              2399 }
genesis              2400 
genesis              2401 bool ProcessMessages(CNode* pfrom)
genesis              2402 {
genesis              2403     CDataStream& vRecv = pfrom->vRecv;
genesis              2404     if (vRecv.empty())
genesis              2405         return true;
genesis              2406     
genesis              2407     
genesis              2408 
genesis              2409     
genesis              2410     
genesis              2411     
genesis              2412     
genesis              2413     
genesis              2414     
genesis              2415     
genesis              2416     
genesis              2417 
genesis              2418     loop
genesis              2419     {
genesis              2420         
genesis              2421         CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
genesis              2422         int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
genesis              2423         if (vRecv.end() - pstart < nHeaderSize)
genesis              2424         {
genesis              2425             if (vRecv.size() > nHeaderSize)
genesis              2426             {
genesis              2427                 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
genesis              2428                 vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
genesis              2429             }
genesis              2430             break;
genesis              2431         }
genesis              2432         if (pstart - vRecv.begin() > 0)
genesis              2433             printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
genesis              2434         vRecv.erase(vRecv.begin(), pstart);
genesis              2435 
genesis              2436         
genesis              2437         vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
genesis              2438         CMessageHeader hdr;
genesis              2439         vRecv >> hdr;
genesis              2440         if (!hdr.IsValid())
genesis              2441         {
genesis              2442             printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
genesis              2443             continue;
genesis              2444         }
genesis              2445         string strCommand = hdr.GetCommand();
genesis              2446 
genesis              2447         
genesis              2448         unsigned int nMessageSize = hdr.nMessageSize;
genesis              2449         if (nMessageSize > MAX_SIZE)
genesis              2450         {
genesis              2451             printf("ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
genesis              2452             continue;
genesis              2453         }
genesis              2454         if (nMessageSize > vRecv.size())
genesis              2455         {
genesis              2456             
genesis              2457             vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
genesis              2458             break;
genesis              2459         }
genesis              2460 
genesis              2461         
genesis              2462         if (vRecv.GetVersion() >= 209)
genesis              2463         {
genesis              2464             uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
genesis              2465             unsigned int nChecksum = 0;
genesis              2466             memcpy(&nChecksum, &hash, sizeof(nChecksum));
genesis              2467             if (nChecksum != hdr.nChecksum)
genesis              2468             {
genesis              2469                 printf("ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
genesis              2470                        strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
genesis              2471                 continue;
genesis              2472             }
genesis              2473         }
genesis              2474 
genesis              2475         
genesis              2476         CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
genesis              2477         vRecv.ignore(nMessageSize);
genesis              2478 
genesis              2479         
genesis              2480         bool fRet = false;
genesis              2481         try
genesis              2482         {
genesis              2483             CRITICAL_BLOCK(cs_main)
genesis              2484                 fRet = ProcessMessage(pfrom, strCommand, vMsg);
genesis              2485             if (fShutdown)
genesis              2486                 return true;
genesis              2487         }
genesis              2488         catch (std::ios_base::failure& e)
genesis              2489         {
genesis              2490             if (strstr(e.what(), "end of data"))
genesis              2491             {
genesis              2492                 
genesis              2493                 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
genesis              2494             }
genesis              2495             else if (strstr(e.what(), "size too large"))
genesis              2496             {
genesis              2497                 
genesis              2498                 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
genesis              2499             }
genesis              2500             else
genesis              2501             {
genesis              2502                 PrintExceptionContinue(&e, "ProcessMessage()");
genesis              2503             }
genesis              2504         }
genesis              2505         catch (std::exception& e) {
genesis              2506             PrintExceptionContinue(&e, "ProcessMessage()");
genesis              2507         } catch (...) {
genesis              2508             PrintExceptionContinue(NULL, "ProcessMessage()");
genesis              2509         }
genesis              2510 
genesis              2511         if (!fRet)
genesis              2512             printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
genesis              2513     }
genesis              2514 
genesis              2515     vRecv.Compact();
genesis              2516     return true;
genesis              2517 }
genesis              2518 
genesis              2519 
genesis              2520 bool SendMessages(CNode* pto, bool fSendTrickle)
genesis              2521 {
genesis              2522     CRITICAL_BLOCK(cs_main)
genesis              2523     {
genesis              2524         
genesis              2525         if (pto->nVersion == 0)
genesis              2526             return true;
genesis              2527 
genesis              2528         
genesis              2529         if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
genesis              2530             pto->PushMessage("ping");
genesis              2531 
genesis              2532         
genesis              2533         ResendWalletTransactions();
genesis              2534 
genesis              2535         
genesis              2536         static int64 nLastRebroadcast;
genesis              2537         if (GetTime() - nLastRebroadcast > 24 * 60 * 60)
genesis              2538         {
genesis              2539             nLastRebroadcast = GetTime();
genesis              2540             CRITICAL_BLOCK(cs_vNodes)
genesis              2541             {
genesis              2542                 BOOST_FOREACH(CNode* pnode, vNodes)
genesis              2543                 {
genesis              2544                     
genesis              2545                     pnode->setAddrKnown.clear();
genesis              2546 
genesis              2547                     
genesis              2548                     if (addrLocalHost.IsRoutable() && !fUseProxy)
genesis              2549                     {
genesis              2550                         CAddress addr(addrLocalHost);
genesis              2551                         addr.nTime = GetAdjustedTime();
genesis              2552                         pnode->PushAddress(addr);
genesis              2553                     }
genesis              2554                 }
genesis              2555             }
genesis              2556         }
genesis              2557 
genesis              2558         
genesis              2559         static int64 nLastClear;
genesis              2560         if (nLastClear == 0)
genesis              2561             nLastClear = GetTime();
genesis              2562         if (GetTime() - nLastClear > 10 * 60 && vNodes.size() >= 3)
genesis              2563         {
genesis              2564             nLastClear = GetTime();
genesis              2565             CRITICAL_BLOCK(cs_mapAddresses)
genesis              2566             {
genesis              2567                 CAddrDB addrdb;
genesis              2568                 int64 nSince = GetAdjustedTime() - 14 * 24 * 60 * 60;
genesis              2569                 for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.begin();
genesis              2570                      mi != mapAddresses.end();)
genesis              2571                 {
genesis              2572                     const CAddress& addr = (*mi).second;
genesis              2573                     if (addr.nTime < nSince)
genesis              2574                     {
genesis              2575                         if (mapAddresses.size() < 1000 || GetTime() > nLastClear + 20)
genesis              2576                             break;
genesis              2577                         addrdb.EraseAddress(addr);
genesis              2578                         mapAddresses.erase(mi++);
genesis              2579                     }
genesis              2580                     else
genesis              2581                         mi++;
genesis              2582                 }
genesis              2583             }
genesis              2584         }
genesis              2585 
genesis              2586 
genesis              2587         
genesis              2588         
genesis              2589         
genesis              2590         if (fSendTrickle)
genesis              2591         {
genesis              2592             vector<CAddress> vAddr;
genesis              2593             vAddr.reserve(pto->vAddrToSend.size());
genesis              2594             BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
genesis              2595             {
genesis              2596                 
genesis              2597                 if (pto->setAddrKnown.insert(addr).second)
genesis              2598                 {
genesis              2599                     vAddr.push_back(addr);
genesis              2600                     
genesis              2601                     if (vAddr.size() >= 1000)
genesis              2602                     {
genesis              2603                         pto->PushMessage("addr", vAddr);
genesis              2604                         vAddr.clear();
genesis              2605                     }
genesis              2606                 }
genesis              2607             }
genesis              2608             pto->vAddrToSend.clear();
genesis              2609             if (!vAddr.empty())
genesis              2610                 pto->PushMessage("addr", vAddr);
genesis              2611         }
genesis              2612 
genesis              2613 
genesis              2614         
genesis              2615         
genesis              2616         
genesis              2617         vector<CInv> vInv;
genesis              2618         vector<CInv> vInvWait;
genesis              2619         CRITICAL_BLOCK(pto->cs_inventory)
genesis              2620         {
genesis              2621             vInv.reserve(pto->vInventoryToSend.size());
genesis              2622             vInvWait.reserve(pto->vInventoryToSend.size());
genesis              2623             BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
genesis              2624             {
genesis              2625                 if (pto->setInventoryKnown.count(inv))
genesis              2626                     continue;
genesis              2627 
genesis              2628                 
genesis              2629                 if (inv.type == MSG_TX && !fSendTrickle)
genesis              2630                 {
genesis              2631                     
genesis              2632                     static uint256 hashSalt;
genesis              2633                     if (hashSalt == 0)
genesis              2634                         RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
genesis              2635                     uint256 hashRand = inv.hash ^ hashSalt;
genesis              2636                     hashRand = Hash(BEGIN(hashRand), END(hashRand));
genesis              2637                     bool fTrickleWait = ((hashRand & 3) != 0);
genesis              2638 
genesis              2639                     
genesis              2640                     if (!fTrickleWait)
genesis              2641                     {
genesis              2642                         CWalletTx wtx;
genesis              2643                         if (GetTransaction(inv.hash, wtx))
genesis              2644                             if (wtx.fFromMe)
genesis              2645                                 fTrickleWait = true;
genesis              2646                     }
genesis              2647 
genesis              2648                     if (fTrickleWait)
genesis              2649                     {
genesis              2650                         vInvWait.push_back(inv);
genesis              2651                         continue;
genesis              2652                     }
genesis              2653                 }
genesis              2654 
genesis              2655                 
genesis              2656                 if (pto->setInventoryKnown.insert(inv).second)
genesis              2657                 {
genesis              2658                     vInv.push_back(inv);
genesis              2659                     if (vInv.size() >= 1000)
genesis              2660                     {
genesis              2661                         pto->PushMessage("inv", vInv);
genesis              2662                         vInv.clear();
genesis              2663                     }
genesis              2664                 }
genesis              2665             }
genesis              2666             pto->vInventoryToSend = vInvWait;
genesis              2667         }
genesis              2668         if (!vInv.empty())
genesis              2669             pto->PushMessage("inv", vInv);
genesis              2670 
genesis              2671 
genesis              2672         
genesis              2673         
genesis              2674         
genesis              2675         vector<CInv> vGetData;
genesis              2676         int64 nNow = GetTime() * 1000000;
genesis              2677         CTxDB txdb("r");
genesis              2678         while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
genesis              2679         {
genesis              2680             const CInv& inv = (*pto->mapAskFor.begin()).second;
genesis              2681             if (!AlreadyHave(txdb, inv))
genesis              2682             {
genesis              2683                 printf("sending getdata: %s\n", inv.ToString().c_str());
genesis              2684                 vGetData.push_back(inv);
genesis              2685                 if (vGetData.size() >= 1000)
genesis              2686                 {
genesis              2687                     pto->PushMessage("getdata", vGetData);
genesis              2688                     vGetData.clear();
genesis              2689                 }
genesis              2690             }
genesis              2691             mapAlreadyAskedFor[inv] = nNow;
genesis              2692             pto->mapAskFor.erase(pto->mapAskFor.begin());
genesis              2693         }
genesis              2694         if (!vGetData.empty())
genesis              2695             pto->PushMessage("getdata", vGetData);
genesis              2696 
genesis              2697     }
genesis              2698     return true;
genesis              2699 }
genesis              2700 
genesis              2701 
genesis              2702 
genesis              2703 
genesis              2704 
genesis              2705 
genesis              2706 
genesis              2707 
genesis              2708 
genesis              2709 
genesis              2710 
genesis              2711 
genesis              2712 
genesis              2713 
genesis              2714 
genesis              2715 
genesis              2716 
genesis              2717 
genesis              2718 
genesis              2719 int static FormatHashBlocks(void* pbuffer, unsigned int len)
genesis              2720 {
genesis              2721     unsigned char* pdata = (unsigned char*)pbuffer;
genesis              2722     unsigned int blocks = 1 + ((len + 8) / 64);
genesis              2723     unsigned char* pend = pdata + 64 * blocks;
genesis              2724     memset(pdata + len, 0, 64 * blocks - len);
genesis              2725     pdata[len] = 0x80;
genesis              2726     unsigned int bits = len * 8;
genesis              2727     pend[-1] = (bits >> 0) & 0xff;
genesis              2728     pend[-2] = (bits >> 8) & 0xff;
genesis              2729     pend[-3] = (bits >> 16) & 0xff;
genesis              2730     pend[-4] = (bits >> 24) & 0xff;
genesis              2731     return blocks;
genesis              2732 }
genesis              2733 
genesis              2734 static const unsigned int pSHA256InitState[8] =
genesis              2735 {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
genesis              2736 
genesis              2737 void SHA256Transform(void* pstate, void* pinput, const void* pinit)
genesis              2738 {
genesis              2739     SHA256_CTX ctx;
genesis              2740     unsigned char data[64];
genesis              2741 
genesis              2742     SHA256_Init(&ctx);
genesis              2743 
genesis              2744     for (int i = 0; i < 16; i++)
genesis              2745         ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]);
genesis              2746 
genesis              2747     for (int i = 0; i < 8; i++)
genesis              2748         ctx.h[i] = ((uint32_t*)pinit)[i];
genesis              2749 
genesis              2750     SHA256_Update(&ctx, data, sizeof(data));
genesis              2751     for (int i = 0; i < 8; i++) 
genesis              2752         ((uint32_t*)pstate)[i] = ctx.h[i];
genesis              2753 }
genesis              2754 
genesis              2755 
genesis              2756 
genesis              2757 
genesis              2758 
genesis              2759 
genesis              2760 
genesis              2761 
genesis              2762 unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
genesis              2763 {
genesis              2764     unsigned int& nNonce = *(unsigned int*)(pdata + 12);
genesis              2765     for (;;)
genesis              2766     {
genesis              2767         
genesis              2768         
genesis              2769         
genesis              2770         nNonce++;
genesis              2771         SHA256Transform(phash1, pdata, pmidstate);
genesis              2772         SHA256Transform(phash, phash1, pSHA256InitState);
genesis              2773 
genesis              2774         
genesis              2775         
genesis              2776         if (((unsigned short*)phash)[14] == 0)
genesis              2777             return nNonce;
genesis              2778 
genesis              2779         
genesis              2780         if ((nNonce & 0xffff) == 0)
genesis              2781         {
genesis              2782             nHashesDone = 0xffff+1;
genesis              2783             return -1;
genesis              2784         }
genesis              2785     }
genesis              2786 }
genesis              2787 
genesis              2788 
genesis              2789 class COrphan
genesis              2790 {
genesis              2791 public:
genesis              2792     CTransaction* ptx;
genesis              2793     set<uint256> setDependsOn;
genesis              2794     double dPriority;
genesis              2795 
genesis              2796     COrphan(CTransaction* ptxIn)
genesis              2797     {
genesis              2798         ptx = ptxIn;
genesis              2799         dPriority = 0;
genesis              2800     }
genesis              2801 
genesis              2802     void print() const
genesis              2803     {
genesis              2804         printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().substr(0,10).c_str(), dPriority);
genesis              2805         BOOST_FOREACH(uint256 hash, setDependsOn)
genesis              2806             printf("   setDependsOn %s\n", hash.ToString().substr(0,10).c_str());
genesis              2807     }
genesis              2808 };
genesis              2809 
genesis              2810 
genesis              2811 CBlock* CreateNewBlock(CReserveKey& reservekey)
genesis              2812 {
genesis              2813     CBlockIndex* pindexPrev = pindexBest;
genesis              2814 
genesis              2815     
genesis              2816     auto_ptr<CBlock> pblock(new CBlock());
genesis              2817     if (!pblock.get())
genesis              2818         return NULL;
genesis              2819 
genesis              2820     
genesis              2821     CTransaction txNew;
genesis              2822     txNew.vin.resize(1);
genesis              2823     txNew.vin[0].prevout.SetNull();
genesis              2824     txNew.vout.resize(1);
genesis              2825     txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
genesis              2826 
genesis              2827     
genesis              2828     pblock->vtx.push_back(txNew);
genesis              2829 
genesis              2830     
genesis              2831     int64 nFees = 0;
genesis              2832     CRITICAL_BLOCK(cs_main)
genesis              2833     CRITICAL_BLOCK(cs_mapTransactions)
genesis              2834     {
genesis              2835         CTxDB txdb("r");
genesis              2836 
genesis              2837         
genesis              2838         list<COrphan> vOrphan; 
genesis              2839         map<uint256, vector<COrphan*> > mapDependers;
genesis              2840         multimap<double, CTransaction*> mapPriority;
genesis              2841         for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi)
genesis              2842         {
genesis              2843             CTransaction& tx = (*mi).second;
genesis              2844             if (tx.IsCoinBase() || !tx.IsFinal())
genesis              2845                 continue;
genesis              2846 
genesis              2847             COrphan* porphan = NULL;
genesis              2848             double dPriority = 0;
genesis              2849             BOOST_FOREACH(const CTxIn& txin, tx.vin)
genesis              2850             {
genesis              2851                 
genesis              2852                 CTransaction txPrev;
genesis              2853                 CTxIndex txindex;
genesis              2854                 if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
genesis              2855                 {
genesis              2856                     
genesis              2857                     if (!porphan)
genesis              2858                     {
genesis              2859                         
genesis              2860                         vOrphan.push_back(COrphan(&tx));
genesis              2861                         porphan = &vOrphan.back();
genesis              2862                     }
genesis              2863                     mapDependers[txin.prevout.hash].push_back(porphan);
genesis              2864                     porphan->setDependsOn.insert(txin.prevout.hash);
genesis              2865                     continue;
genesis              2866                 }
genesis              2867                 int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
genesis              2868 
genesis              2869                 
genesis              2870                 int nConf = txindex.GetDepthInMainChain();
genesis              2871 
genesis              2872                 dPriority += (double)nValueIn * nConf;
genesis              2873 
genesis              2874                 if (fDebug && GetBoolArg("-printpriority"))
genesis              2875                     printf("priority     nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
genesis              2876             }
genesis              2877 
genesis              2878             
genesis              2879             dPriority /= ::GetSerializeSize(tx, SER_NETWORK);
genesis              2880 
genesis              2881             if (porphan)
genesis              2882                 porphan->dPriority = dPriority;
genesis              2883             else
genesis              2884                 mapPriority.insert(make_pair(-dPriority, &(*mi).second));
genesis              2885 
genesis              2886             if (fDebug && GetBoolArg("-printpriority"))
genesis              2887             {
genesis              2888                 printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
genesis              2889                 if (porphan)
genesis              2890                     porphan->print();
genesis              2891                 printf("\n");
genesis              2892             }
genesis              2893         }
genesis              2894 
genesis              2895         
genesis              2896         map<uint256, CTxIndex> mapTestPool;
genesis              2897         uint64 nBlockSize = 1000;
genesis              2898         int nBlockSigOps = 100;
genesis              2899         while (!mapPriority.empty())
genesis              2900         {
genesis              2901             
genesis              2902             double dPriority = -(*mapPriority.begin()).first;
genesis              2903             CTransaction& tx = *(*mapPriority.begin()).second;
genesis              2904             mapPriority.erase(mapPriority.begin());
genesis              2905 
genesis              2906             
genesis              2907             unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
genesis              2908             if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
genesis              2909                 continue;
genesis              2910             int nTxSigOps = tx.GetSigOpCount();
genesis              2911             if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
genesis              2912                 continue;
genesis              2913 
genesis              2914             
genesis              2915             bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
genesis              2916             int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
genesis              2917 
genesis              2918             
genesis              2919             
genesis              2920             map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
genesis              2921             bool fInvalid;
genesis              2922             if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee, fInvalid))
genesis              2923                 continue;
genesis              2924             swap(mapTestPool, mapTestPoolTmp);
genesis              2925 
genesis              2926             
genesis              2927             pblock->vtx.push_back(tx);
genesis              2928             nBlockSize += nTxSize;
genesis              2929             nBlockSigOps += nTxSigOps;
genesis              2930 
genesis              2931             
genesis              2932             uint256 hash = tx.GetHash();
genesis              2933             if (mapDependers.count(hash))
genesis              2934             {
genesis              2935                 BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
genesis              2936                 {
genesis              2937                     if (!porphan->setDependsOn.empty())
genesis              2938                     {
genesis              2939                         porphan->setDependsOn.erase(hash);
genesis              2940                         if (porphan->setDependsOn.empty())
genesis              2941                             mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
genesis              2942                     }
genesis              2943                 }
genesis              2944             }
genesis              2945         }
genesis              2946     }
genesis              2947     pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
genesis              2948 
genesis              2949     
genesis              2950     pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
genesis              2951     pblock->hashMerkleRoot = pblock->BuildMerkleTree();
genesis              2952     pblock->nTime          = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
genesis              2953     pblock->nBits          = GetNextWorkRequired(pindexPrev, pblock.get());
genesis              2954     pblock->nNonce         = 0;
genesis              2955 
genesis              2956     return pblock.release();
genesis              2957 }
genesis              2958 
genesis              2959 
genesis              2960 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
genesis              2961 {
genesis              2962     
genesis              2963     static uint256 hashPrevBlock;
genesis              2964     if (hashPrevBlock != pblock->hashPrevBlock)
genesis              2965     {
genesis              2966         nExtraNonce = 0;
genesis              2967         hashPrevBlock = pblock->hashPrevBlock;
genesis              2968     }
genesis              2969     ++nExtraNonce;
genesis              2970     pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce);
genesis              2971     pblock->hashMerkleRoot = pblock->BuildMerkleTree();
genesis              2972 }
genesis              2973 
genesis              2974 
genesis              2975 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1)
genesis              2976 {
genesis              2977     
genesis              2978     
genesis              2979     
genesis              2980     struct
genesis              2981     {
genesis              2982         struct unnamed2
genesis              2983         {
genesis              2984             int nVersion;
genesis              2985             uint256 hashPrevBlock;
genesis              2986             uint256 hashMerkleRoot;
genesis              2987             unsigned int nTime;
genesis              2988             unsigned int nBits;
genesis              2989             unsigned int nNonce;
genesis              2990         }
genesis              2991         block;
genesis              2992         unsigned char pchPadding0[64];
genesis              2993         uint256 hash1;
genesis              2994         unsigned char pchPadding1[64];
genesis              2995     }
genesis              2996     tmp;
genesis              2997     memset(&tmp, 0, sizeof(tmp));
genesis              2998 
genesis              2999     tmp.block.nVersion       = pblock->nVersion;
genesis              3000     tmp.block.hashPrevBlock  = pblock->hashPrevBlock;
genesis              3001     tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
genesis              3002     tmp.block.nTime          = pblock->nTime;
genesis              3003     tmp.block.nBits          = pblock->nBits;
genesis              3004     tmp.block.nNonce         = pblock->nNonce;
genesis              3005 
genesis              3006     FormatHashBlocks(&tmp.block, sizeof(tmp.block));
genesis              3007     FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
genesis              3008 
genesis              3009     
genesis              3010     for (int i = 0; i < sizeof(tmp)/4; i++)
genesis              3011         ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
genesis              3012 
genesis              3013     
genesis              3014     SHA256Transform(pmidstate, &tmp.block, pSHA256InitState);
genesis              3015 
genesis              3016     memcpy(pdata, &tmp.block, 128);
genesis              3017     memcpy(phash1, &tmp.hash1, 64);
genesis              3018 }
genesis              3019 
genesis              3020 
genesis              3021 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
genesis              3022 {
genesis              3023     uint256 hash = pblock->GetHash();
genesis              3024     uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
genesis              3025 
genesis              3026     if (hash > hashTarget)
genesis              3027         return false;
genesis              3028 
genesis              3029     
genesis              3030     printf("BitcoinMiner:\n");
genesis              3031     printf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
genesis              3032     pblock->print();
genesis              3033     printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
genesis              3034     printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
genesis              3035 
genesis              3036     
genesis              3037     CRITICAL_BLOCK(cs_main)
genesis              3038     {
genesis              3039         if (pblock->hashPrevBlock != hashBestChain)
genesis              3040             return error("BitcoinMiner : generated block is stale");
genesis              3041 
genesis              3042         
genesis              3043         reservekey.KeepKey();
genesis              3044 
genesis              3045         
genesis              3046         CRITICAL_BLOCK(wallet.cs_wallet)
genesis              3047             wallet.mapRequestCount[pblock->GetHash()] = 0;
genesis              3048 
genesis              3049         
genesis              3050         if (!ProcessBlock(NULL, pblock))
genesis              3051             return error("BitcoinMiner : ProcessBlock, block not accepted");
genesis              3052     }
genesis              3053 
genesis              3054     return true;
genesis              3055 }
genesis              3056 
genesis              3057 void static ThreadBitcoinMiner(void* parg);
genesis              3058 
genesis              3059 void static BitcoinMiner(CWallet *pwallet)
genesis              3060 {
genesis              3061     printf("BitcoinMiner started\n");
genesis              3062     SetThreadPriority(THREAD_PRIORITY_LOWEST);
genesis              3063 
genesis              3064     
genesis              3065     CReserveKey reservekey(pwallet);
genesis              3066     unsigned int nExtraNonce = 0;
genesis              3067 
genesis              3068     while (fGenerateBitcoins)
genesis              3069     {
genesis              3070         if (AffinityBugWorkaround(ThreadBitcoinMiner))
genesis              3071             return;
genesis              3072         if (fShutdown)
genesis              3073             return;
genesis              3074         while (vNodes.empty() || IsInitialBlockDownload())
genesis              3075         {
genesis              3076             Sleep(1000);
genesis              3077             if (fShutdown)
genesis              3078                 return;
genesis              3079             if (!fGenerateBitcoins)
genesis              3080                 return;
genesis              3081         }
genesis              3082 
genesis              3083 
genesis              3084         
genesis              3085         
genesis              3086         
genesis              3087         unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
genesis              3088         CBlockIndex* pindexPrev = pindexBest;
genesis              3089 
genesis              3090         auto_ptr<CBlock> pblock(CreateNewBlock(reservekey));
genesis              3091         if (!pblock.get())
genesis              3092             return;
genesis              3093         IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
genesis              3094 
genesis              3095         printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
genesis              3096 
genesis              3097 
genesis              3098         
genesis              3099         
genesis              3100         
genesis              3101         char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
genesis              3102         char pdatabuf[128+16];    char* pdata     = alignup<16>(pdatabuf);
genesis              3103         char phash1buf[64+16];    char* phash1    = alignup<16>(phash1buf);
genesis              3104 
genesis              3105         FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
genesis              3106 
genesis              3107         unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
genesis              3108         unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
genesis              3109 
genesis              3110 
genesis              3111         
genesis              3112         
genesis              3113         
genesis              3114         int64 nStart = GetTime();
genesis              3115         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
genesis              3116         uint256 hashbuf[2];
genesis              3117         uint256& hash = *alignup<16>(hashbuf);
genesis              3118         loop
genesis              3119         {
genesis              3120             unsigned int nHashesDone = 0;
genesis              3121             unsigned int nNonceFound;
genesis              3122 
genesis              3123             
genesis              3124             nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1,
genesis              3125                                             (char*)&hash, nHashesDone);
genesis              3126 
genesis              3127             
genesis              3128             if (nNonceFound != -1)
genesis              3129             {
genesis              3130                 for (int i = 0; i < sizeof(hash)/4; i++)
genesis              3131                     ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
genesis              3132 
genesis              3133                 if (hash <= hashTarget)
genesis              3134                 {
genesis              3135                     
genesis              3136                     pblock->nNonce = ByteReverse(nNonceFound);
genesis              3137                     assert(hash == pblock->GetHash());
genesis              3138 
genesis              3139                     SetThreadPriority(THREAD_PRIORITY_NORMAL);
genesis              3140                     CheckWork(pblock.get(), *pwalletMain, reservekey);
genesis              3141                     SetThreadPriority(THREAD_PRIORITY_LOWEST);
genesis              3142                     break;
genesis              3143                 }
genesis              3144             }
genesis              3145 
genesis              3146             
genesis              3147             static int64 nHashCounter;
genesis              3148             if (nHPSTimerStart == 0)
genesis              3149             {
genesis              3150                 nHPSTimerStart = GetTimeMillis();
genesis              3151                 nHashCounter = 0;
genesis              3152             }
genesis              3153             else
genesis              3154                 nHashCounter += nHashesDone;
genesis              3155             if (GetTimeMillis() - nHPSTimerStart > 4000)
genesis              3156             {
genesis              3157                 static CCriticalSection cs;
genesis              3158                 CRITICAL_BLOCK(cs)
genesis              3159                 {
genesis              3160                     if (GetTimeMillis() - nHPSTimerStart > 4000)
genesis              3161                     {
genesis              3162                         dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
genesis              3163                         nHPSTimerStart = GetTimeMillis();
genesis              3164                         nHashCounter = 0;
genesis              3165                         string strStatus = strprintf("    %.0f khash/s", dHashesPerSec/1000.0);
genesis              3166                         UIThreadCall(boost::bind(CalledSetStatusBar, strStatus, 0));
genesis              3167                         static int64 nLogTime;
genesis              3168                         if (GetTime() - nLogTime > 30 * 60)
genesis              3169                         {
genesis              3170                             nLogTime = GetTime();
genesis              3171                             printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
genesis              3172                             printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
genesis              3173                         }
genesis              3174                     }
genesis              3175                 }
genesis              3176             }
genesis              3177 
genesis              3178             
genesis              3179             if (fShutdown)
genesis              3180                 return;
genesis              3181             if (!fGenerateBitcoins)
genesis              3182                 return;
genesis              3183             if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
genesis              3184                 return;
genesis              3185             if (vNodes.empty())
genesis              3186                 break;
genesis              3187             if (nBlockNonce >= 0xffff0000)
genesis              3188                 break;
genesis              3189             if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
genesis              3190                 break;
genesis              3191             if (pindexPrev != pindexBest)
genesis              3192                 break;
genesis              3193 
genesis              3194             
genesis              3195             pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
genesis              3196             nBlockTime = ByteReverse(pblock->nTime);
genesis              3197         }
genesis              3198     }
genesis              3199 }
genesis              3200 
genesis              3201 void static ThreadBitcoinMiner(void* parg)
genesis              3202 {
genesis              3203     CWallet* pwallet = (CWallet*)parg;
genesis              3204     try
genesis              3205     {
genesis              3206         vnThreadsRunning[3]++;
genesis              3207         BitcoinMiner(pwallet);
genesis              3208         vnThreadsRunning[3]--;
genesis              3209     }
genesis              3210     catch (std::exception& e) {
genesis              3211         vnThreadsRunning[3]--;
genesis              3212         PrintException(&e, "ThreadBitcoinMiner()");
genesis              3213     } catch (...) {
genesis              3214         vnThreadsRunning[3]--;
genesis              3215         PrintException(NULL, "ThreadBitcoinMiner()");
genesis              3216     }
genesis              3217     UIThreadCall(boost::bind(CalledSetStatusBar, "", 0));
genesis              3218     nHPSTimerStart = 0;
genesis              3219     if (vnThreadsRunning[3] == 0)
genesis              3220         dHashesPerSec = 0;
genesis              3221     printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
genesis              3222 }
genesis              3223 
genesis              3224 
genesis              3225 void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
genesis              3226 {
genesis              3227     if (fGenerateBitcoins != fGenerate)
genesis              3228     {
genesis              3229         fGenerateBitcoins = fGenerate;
genesis              3230         WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
genesis              3231         MainFrameRepaint();
genesis              3232     }
genesis              3233     if (fGenerateBitcoins)
genesis              3234     {
genesis              3235         int nProcessors = boost::thread::hardware_concurrency();
genesis              3236         printf("%d processors\n", nProcessors);
genesis              3237         if (nProcessors < 1)
genesis              3238             nProcessors = 1;
genesis              3239         if (fLimitProcessors && nProcessors > nLimitProcessors)
genesis              3240             nProcessors = nLimitProcessors;
genesis              3241         int nAddThreads = nProcessors - vnThreadsRunning[3];
genesis              3242         printf("Starting %d BitcoinMiner threads\n", nAddThreads);
genesis              3243         for (int i = 0; i < nAddThreads; i++)
genesis              3244         {
genesis              3245             if (!CreateThread(ThreadBitcoinMiner, pwallet))
genesis              3246                 printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
genesis              3247             Sleep(10);
genesis              3248         }
genesis              3249     }
genesis              3250 }