diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 264 |
1 files changed, 194 insertions, 70 deletions
diff --git a/src/main.cpp b/src/main.cpp index e56a163199..23c6d988aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -564,7 +564,7 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, // Continuously rate-limit free transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to - // be annoying or make other's transactions take longer to confirm. + // be annoying or make others' transactions take longer to confirm. if (nFees < MIN_RELAY_TX_FEE) { static CCriticalSection cs; @@ -653,6 +653,15 @@ bool CTxMemPool::remove(CTransaction &tx) return true; } +void +CTxMemPool::clear() +{ + LOCK(cs); + mapTx.clear(); + mapNextTx.clear(); + ++nTransactionsUpdated; +} + void CTxMemPool::queryHashes(std::vector<uint256>& vtxid) { vtxid.clear(); @@ -846,7 +855,7 @@ int64 static GetBlockValue(int nHeight, int64 nFees) { int64 nSubsidy = 50 * COIN; - // Subsidy is cut in half every 4 years + // Subsidy is cut in half every 210000 blocks, which will occur approximately every 4 years nSubsidy >>= (nHeight / 210000); return nSubsidy + nFees; @@ -997,7 +1006,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew) hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) - printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n"); + printf("InvalidChainFound: Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n"); } void CBlock::UpdateTime(const CBlockIndex* pindexPrev) @@ -1048,7 +1057,7 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb) // Remove transaction from index // This can fail if a duplicate of this transaction was in a chain that got // reorganized away. This is only possible if this transaction was completely - // spent, so erasing it would be a no-op anway. + // spent, so erasing it would be a no-op anyway. txdb.EraseTxIndex(*this); return true; @@ -1111,7 +1120,7 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes } } - // Make sure all prevout.n's are valid: + // Make sure all prevout.n indexes are valid: for (unsigned int i = 0; i < vin.size(); i++) { const COutPoint prevout = vin[i].prevout; @@ -1334,10 +1343,10 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) return true; } -bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) +bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) { // Check it again in case a previous version let a bad block in - if (!CheckBlock()) + if (!CheckBlock(!fJustCheck, !fJustCheck)) return false; // Do not allow blocks that contain transactions which 'overwrite' older transactions, @@ -1347,7 +1356,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) // being sent to another address. // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool - // already refuses previously-known transaction id's entirely. + // already refuses previously-known transaction ids entirely. // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC. int64 nBIP30SwitchTime = 1331769600; bool fEnforceBIP30 = (pindex->nTime > nBIP30SwitchTime); @@ -1357,7 +1366,13 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime); //// issue here: it doesn't know the version - unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size()); + unsigned int nTxPos; + if (fJustCheck) + // FetchInputs treats CDiskTxPos(1,1,1) as a special "refer to memorypool" indicator + // Since we're just checking the block and not actually connecting it, it might not (and probably shouldn't) be on the disk to get the transaction from + nTxPos = 1; + else + nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size()); map<uint256, CTxIndex> mapQueuedChanges; int64 nFees = 0; @@ -1380,7 +1395,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) return DoS(100, error("ConnectBlock() : too many sigops")); CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); - nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); + if (!fJustCheck) + nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); MapPrevTx mapInputs; if (!tx.IsCoinBase()) @@ -1408,6 +1424,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); } + if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) + return false; + + if (fJustCheck) + return true; + // Write queued txindex changes for (map<uint256, CTxIndex>::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi) { @@ -1415,9 +1437,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) return error("ConnectBlock() : UpdateTxIndex failed"); } - if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) - return false; - // Update block index on disk without changing it in memory. // The memory index structure will be changed after the db commits. if (pindex->pprev) @@ -1603,7 +1622,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) return error("SetBestChain() : Reorganize failed"); } - // Connect futher blocks + // Connect further blocks BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vpindexSecondary) { CBlock block; @@ -1657,7 +1676,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) printf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION); if (nUpgraded > 100/2) // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: - strMiscWarning = _("Warning: this version is obsolete, upgrade required"); + strMiscWarning = _("Warning: This version is obsolete, upgrade required!"); } std::string strCmd = GetArg("-blocknotify", ""); @@ -1722,7 +1741,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) -bool CBlock::CheckBlock() const +bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const { // These are checks that are independent of context // that can be verified before saving an orphan block. @@ -1732,7 +1751,7 @@ bool CBlock::CheckBlock() const return DoS(100, error("CheckBlock() : size limits failed")); // Check proof of work matches claimed amount - if (!CheckProofOfWork(GetHash(), nBits)) + if (fCheckPOW && !CheckProofOfWork(GetHash(), nBits)) return DoS(50, error("CheckBlock() : proof of work failed")); // Check timestamp @@ -1769,8 +1788,8 @@ bool CBlock::CheckBlock() const if (nSigOps > MAX_BLOCK_SIGOPS) return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount")); - // Check merkleroot - if (hashMerkleRoot != BuildMerkleTree()) + // Check merkle root + if (fCheckMerkleRoot && hashMerkleRoot != BuildMerkleTree()) return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); return true; @@ -1805,7 +1824,7 @@ bool CBlock::AcceptBlock() // Check that the block chain matches the known block chain up to a checkpoint if (!Checkpoints::CheckBlock(nHeight, hash)) - return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight)); + return DoS(100, error("AcceptBlock() : rejected by checkpoint lock-in at %d", nHeight)); // Write block to history file if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION))) @@ -1923,7 +1942,7 @@ bool CheckDiskSpace(uint64 nAdditionalBytes) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) { fShutdown = true; - string strMessage = _("Warning: Disk space is low"); + string strMessage = _("Warning: Disk space is low!"); strMiscWarning = strMessage; printf("*** %s\n", strMessage.c_str()); uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); @@ -1963,7 +1982,7 @@ FILE* AppendBlockFile(unsigned int& nFileRet) return NULL; if (fseek(file, 0, SEEK_END) != 0) return NULL; - // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB + // FAT32 file size max 4GB, fseek and ftell max 2GB, so we must stay under 2GB if (ftell(file) < 0x7F000000 - MAX_SIZE) { nFileRet = nCurrentBlockFile; @@ -1978,10 +1997,10 @@ bool LoadBlockIndex(bool fAllowNew) { if (fTestNet) { - pchMessageStart[0] = 0xfa; - pchMessageStart[1] = 0xbf; - pchMessageStart[2] = 0xb5; - pchMessageStart[3] = 0xda; + pchMessageStart[0] = 0x0b; + pchMessageStart[1] = 0x11; + pchMessageStart[2] = 0x09; + pchMessageStart[3] = 0x07; hashGenesisBlock = uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); } @@ -2055,7 +2074,7 @@ bool LoadBlockIndex(bool fAllowNew) void PrintBlockTree() { - // precompute tree structure + // pre-compute tree structure map<CBlockIndex*, vector<CBlockIndex*> > mapNext; for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) { @@ -2108,7 +2127,7 @@ void PrintBlockTree() PrintWallets(block); - // put the main timechain first + // put the main time-chain first vector<CBlockIndex*>& vNext = mapNext[pindex]; for (unsigned int i = 0; i < vNext.size(); i++) { @@ -2218,7 +2237,7 @@ string GetWarnings(string strFor) if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) { nPriority = 2000; - strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade."; + strStatusBar = strRPC = _("Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade."); } // Alerts @@ -2347,7 +2366,7 @@ bool static AlreadyHave(CTxDB& txdb, const CInv& inv) // The message start string is designed to be unlikely to occur in normal data. -// The characters are rarely used upper ascii, not valid as UTF-8, and produce +// The characters are rarely used upper ASCII, not valid as UTF-8, and produce // a large 4-byte int at any alignment. unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; @@ -3030,12 +3049,12 @@ bool ProcessMessages(CNode* pfrom) { if (strstr(e.what(), "end of data")) { - // Allow exceptions from underlength message on vRecv + // Allow exceptions from under-length message on vRecv printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } else if (strstr(e.what(), "size too large")) { - // Allow exceptions from overlong size + // Allow exceptions from over-long size printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what()); } else @@ -3284,9 +3303,9 @@ unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1 unsigned int& nNonce = *(unsigned int*)(pdata + 12); for (;;) { - // Crypto++ SHA-256 + // Crypto++ SHA256 // Hash pdata using pmidstate as the starting state into - // preformatted buffer phash1, then hash phash1 into phash + // pre-formatted buffer phash1, then hash phash1 into phash nNonce++; SHA256Transform(phash1, pdata, pmidstate); SHA256Transform(phash, phash1, pSHA256InitState); @@ -3312,16 +3331,18 @@ public: CTransaction* ptx; set<uint256> setDependsOn; double dPriority; + double dFeePerKb; COrphan(CTransaction* ptxIn) { ptx = ptxIn; - dPriority = 0; + dPriority = dFeePerKb = 0; } void print() const { - printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().substr(0,10).c_str(), dPriority); + printf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n", + ptx->GetHash().ToString().substr(0,10).c_str(), dPriority, dFeePerKb); BOOST_FOREACH(uint256 hash, setDependsOn) printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str()); } @@ -3331,6 +3352,33 @@ public: uint64 nLastBlockTx = 0; uint64 nLastBlockSize = 0; +// We want to sort transactions by priority and fee, so: +typedef boost::tuple<double, double, CTransaction*> TxPriority; +class TxPriorityCompare +{ + bool byFee; +public: + TxPriorityCompare(bool _byFee) : byFee(_byFee) { } + bool operator()(const TxPriority& a, const TxPriority& b) + { + if (byFee) + { + if (a.get<1>() == b.get<1>()) + return a.get<0>() < b.get<0>(); + return a.get<1>() < b.get<1>(); + } + else + { + if (a.get<0>() == b.get<0>()) + return a.get<1>() < b.get<1>(); + return a.get<0>() < b.get<0>(); + } + } +}; + +const char* pszDummy = "\0\0"; +CScript scriptDummy(std::vector<unsigned char>(pszDummy, pszDummy + sizeof(pszDummy))); + CBlock* CreateNewBlock(CReserveKey& reservekey) { CBlockIndex* pindexPrev = pindexBest; @@ -3350,6 +3398,30 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) // Add our coinbase tx as first transaction pblock->vtx.push_back(txNew); + // Largest block you're willing to create: + unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/2); + // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + + // How much of the block should be dedicated to high-priority transactions, + // included regardless of the fees they pay + unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", 27000); + nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); + + // Minimum block size you want to create; block will be filled with free transactions + // until there are no more or the block reaches this size: + unsigned int nBlockMinSize = GetArg("-blockminsize", 0); + nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); + + // Fee-per-kilobyte amount considered the same as "free" + // Be careful setting this: if you set it to zero then + // a transaction spammer can cheaply fill blocks using + // 1-satoshi-fee transactions. It should be set above the real + // cost to you of processing a transaction. + int64 nMinTxFee = MIN_TX_FEE; + if (mapArgs.count("-mintxfee")) + ParseMoney(mapArgs["-mintxfee"], nMinTxFee); + // Collect memory pool transactions into the block int64 nFees = 0; { @@ -3359,7 +3431,10 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) // Priority order to process transactions list<COrphan> vOrphan; // list memory doesn't move map<uint256, vector<COrphan*> > mapDependers; - multimap<double, CTransaction*> mapPriority; + + // This vector will be sorted into a priority queue: + vector<TxPriority> vecPriority; + vecPriority.reserve(mempool.mapTx.size()); for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { CTransaction& tx = (*mi).second; @@ -3368,6 +3443,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) COrphan* porphan = NULL; double dPriority = 0; + int64 nTotalIn = 0; + bool fMissingInputs = false; BOOST_FOREACH(const CTxIn& txin, tx.vin) { // Read prev transaction @@ -3375,6 +3452,19 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) CTxIndex txindex; if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) { + // This should never happen; all transactions in the memory + // pool should connect to either transactions in the chain + // or other transactions in the memory pool. + if (!mempool.mapTx.count(txin.prevout.hash)) + { + printf("ERROR: mempool transaction missing input\n"); + if (fDebug) assert("mempool transaction missing input" == 0); + fMissingInputs = true; + if (porphan) + vOrphan.pop_back(); + break; + } + // Has to wait for dependencies if (!porphan) { @@ -3384,34 +3474,33 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) } mapDependers[txin.prevout.hash].push_back(porphan); porphan->setDependsOn.insert(txin.prevout.hash); + nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; continue; } int64 nValueIn = txPrev.vout[txin.prevout.n].nValue; + nTotalIn += nValueIn; - // Read block header int nConf = txindex.GetDepthInMainChain(); - dPriority += (double)nValueIn * nConf; - - if (fDebug && GetBoolArg("-printpriority")) - printf("priority nValueIn=%-12"PRI64d" nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority); } + if (fMissingInputs) continue; // Priority is sum(valuein * age) / txsize - dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + dPriority /= nTxSize; - if (porphan) - porphan->dPriority = dPriority; - else - mapPriority.insert(make_pair(-dPriority, &(*mi).second)); + // This is a more accurate fee-per-kilobyte than is used by the client code, because the + // client code rounds up the size to the nearest 1K. That's good, because it gives an + // incentive to create smaller transactions. + double dFeePerKb = double(nTotalIn-tx.GetValueOut()) / (double(nTxSize)/1000.0); - if (fDebug && GetBoolArg("-printpriority")) + if (porphan) { - printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str()); - if (porphan) - porphan->print(); - printf("\n"); + porphan->dPriority = dPriority; + porphan->dFeePerKb = dFeePerKb; } + else + vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &(*mi).second)); } // Collect transactions into block @@ -3419,16 +3508,24 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) uint64 nBlockSize = 1000; uint64 nBlockTx = 0; int nBlockSigOps = 100; - while (!mapPriority.empty()) + bool fSortedByFee = (nBlockPrioritySize <= 0); + + TxPriorityCompare comparer(fSortedByFee); + std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + + while (!vecPriority.empty()) { - // Take highest priority transaction off priority queue - double dPriority = -(*mapPriority.begin()).first; - CTransaction& tx = *(*mapPriority.begin()).second; - mapPriority.erase(mapPriority.begin()); + // Take highest priority transaction off the priority queue: + double dPriority = vecPriority.front().get<0>(); + double dFeePerKb = vecPriority.front().get<1>(); + CTransaction& tx = *(vecPriority.front().get<2>()); + + std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); + vecPriority.pop_back(); // Size limits unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN) + if (nBlockSize + nTxSize >= nBlockMaxSize) continue; // Legacy limits on sigOps: @@ -3436,9 +3533,19 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) continue; - // Transaction fee required depends on block size - bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority)); - int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree, GMF_BLOCK); + // Skip free transactions if we're past the minimum block size: + if (fSortedByFee && (dFeePerKb < nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) + continue; + + // Prioritize by fee once past the priority size or we run out of high-priority + // transactions: + if (!fSortedByFee && + ((nBlockSize + nTxSize >= nBlockPrioritySize) || (dPriority < COIN * 144 / 250))) + { + fSortedByFee = true; + comparer = TxPriorityCompare(fSortedByFee); + std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + } // Connecting shouldn't fail due to dependency on other memory pool transactions // because we're already processing them in order of dependency @@ -3449,8 +3556,6 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) continue; int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut(); - if (nTxFees < nMinFee) - continue; nTxSigOps += tx.GetP2SHSigOpCount(mapInputs); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) @@ -3468,6 +3573,12 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) nBlockSigOps += nTxSigOps; nFees += nTxFees; + if (fDebug && GetBoolArg("-printpriority")) + { + printf("priority %.1f feeperkb %.1f txid %s\n", + dPriority, dFeePerKb, tx.GetHash().ToString().c_str()); + } + // Add transactions that depend on this one to the priority queue uint256 hash = tx.GetHash(); if (mapDependers.count(hash)) @@ -3478,7 +3589,10 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) { porphan->setDependsOn.erase(hash); if (porphan->setDependsOn.empty()) - mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx)); + { + vecPriority.push_back(TxPriority(porphan->dPriority, porphan->dFeePerKb, porphan->ptx)); + std::push_heap(vecPriority.begin(), vecPriority.end(), comparer); + } } } } @@ -3488,16 +3602,22 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) nLastBlockSize = nBlockSize; printf("CreateNewBlock(): total size %lu\n", nBlockSize); - } pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); pblock->UpdateTime(pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get()); pblock->nNonce = 0; + pblock->vtx[0].vin[0].scriptSig = scriptDummy; + CBlockIndex indexDummy(1, 1, *pblock); + indexDummy.pprev = pindexPrev; + indexDummy.nHeight = pindexPrev->nHeight + 1; + if (!pblock->ConnectBlock(txdb, &indexDummy, true)) + throw std::runtime_error("CreateNewBlock() : ConnectBlock failed"); + } + return pblock.release(); } @@ -3522,7 +3642,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) { // - // Prebuild hash buffers + // Pre-build hash buffers // struct { @@ -3613,6 +3733,9 @@ void static BitcoinMiner(CWallet *pwallet) printf("BitcoinMiner started\n"); SetThreadPriority(THREAD_PRIORITY_LOWEST); + // Make this thread recognisable as the mining thread + RenameThread("bitcoin-miner"); + // Each thread has its own key and counter CReserveKey reservekey(pwallet); unsigned int nExtraNonce = 0; @@ -3642,11 +3765,12 @@ void static BitcoinMiner(CWallet *pwallet) return; IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce); - printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); + printf("Running BitcoinMiner with %d transactions in block (%u bytes)\n", pblock->vtx.size(), + ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); // - // Prebuild hash buffers + // Pre-build hash buffers // char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); @@ -3671,7 +3795,7 @@ void static BitcoinMiner(CWallet *pwallet) unsigned int nHashesDone = 0; unsigned int nNonceFound; - // Crypto++ SHA-256 + // Crypto++ SHA256 nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1, (char*)&hash, nHashesDone); |