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