diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/init.cpp | 4 | ||||
-rw-r--r-- | src/main.h | 4 | ||||
-rw-r--r-- | src/miner.cpp | 2 | ||||
-rw-r--r-- | src/primitives/transaction.cpp | 9 | ||||
-rw-r--r-- | src/primitives/transaction.h | 3 | ||||
-rw-r--r-- | src/qt/optionsdialog.cpp | 2 | ||||
-rw-r--r-- | src/rest.cpp | 2 | ||||
-rw-r--r-- | src/rpcblockchain.cpp | 82 | ||||
-rw-r--r-- | src/rpcclient.cpp | 1 | ||||
-rw-r--r-- | src/rpcserver.cpp | 1 | ||||
-rw-r--r-- | src/rpcserver.h | 1 | ||||
-rw-r--r-- | src/txmempool.cpp | 2 | ||||
-rw-r--r-- | src/util.cpp | 10 | ||||
-rw-r--r-- | src/util.h | 7 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 1 |
15 files changed, 123 insertions, 8 deletions
diff --git a/src/init.cpp b/src/init.cpp index b9510bec9d..94bf5eb2f4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -283,7 +283,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), - -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); + -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef WIN32 strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid")); #endif @@ -772,7 +772,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); if (nScriptCheckThreads <= 0) - nScriptCheckThreads += boost::thread::hardware_concurrency(); + nScriptCheckThreads += GetNumCores(); if (nScriptCheckThreads <= 1) nScriptCheckThreads = 0; else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS) diff --git a/src/main.h b/src/main.h index 4e2efaada0..43bc4031f1 100644 --- a/src/main.h +++ b/src/main.h @@ -131,7 +131,7 @@ extern bool fPruneMode; /** Number of MiB of block files that we're trying to stay below. */ extern uint64_t nPruneTarget; /** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */ -static const signed int MIN_BLOCKS_TO_KEEP = 288; +static const unsigned int MIN_BLOCKS_TO_KEEP = 288; // Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat) // At 1MB per block, 288 blocks = 288MB. @@ -141,7 +141,7 @@ static const signed int MIN_BLOCKS_TO_KEEP = 288; // full block file chunks, we need the high water mark which triggers the prune to be // one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB // Setting the target to > than 550MB will make it likely we can respect the target. -static const signed int MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; +static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; /** Register with a network node to receive its signals */ void RegisterNodeSignals(CNodeSignals& nodeSignals); diff --git a/src/miner.cpp b/src/miner.cpp index 2c5cba742c..ca32e9f7b3 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -546,7 +546,7 @@ void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainpar if (Params().DefaultMinerThreads()) nThreads = Params().DefaultMinerThreads(); else - nThreads = boost::thread::hardware_concurrency(); + nThreads = GetNumCores(); } if (minerThreads != NULL) diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 606dbea798..d864a9b6d3 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -87,6 +87,15 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) { return *this; } +bool CTransaction::IsEquivalentTo(const CTransaction& tx) const +{ + CMutableTransaction tx1 = *this; + CMutableTransaction tx2 = tx; + for (unsigned int i = 0; i < tx1.vin.size(); i++) tx1.vin[i].scriptSig = CScript(); + for (unsigned int i = 0; i < tx2.vin.size(); i++) tx2.vin[i].scriptSig = CScript(); + return CTransaction(tx1) == CTransaction(tx2); +} + CAmount CTransaction::GetValueOut() const { CAmount nValueOut = 0; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 6cfd93a9a1..0c9ebb7b88 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -222,6 +222,9 @@ public: return hash; } + // True if only scriptSigs are different + bool IsEquivalentTo(const CTransaction& tx) const; + // Return sum of txouts. CAmount GetValueOut() const; // GetValueIn() is a method on CCoinsViewCache, because diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index efb2bf4158..87c727335e 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -42,7 +42,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : /* Main elements init */ ui->databaseCache->setMinimum(nMinDbCache); ui->databaseCache->setMaximum(nMaxDbCache); - ui->threadsScriptVerif->setMinimum(-(int)boost::thread::hardware_concurrency()); + ui->threadsScriptVerif->setMinimum(-GetNumCores()); ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS); /* Network elements init */ diff --git a/src/rest.cpp b/src/rest.cpp index 1fce7dfc9c..a1bd893bec 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -20,7 +20,7 @@ using namespace std; -static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once +static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once enum RetFormat { RF_UNDEF, diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 0b34225d8f..b7c3eb1724 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -51,6 +51,32 @@ double GetDifficulty(const CBlockIndex* blockindex) return dDiff; } +UniValue blockheaderToJSON(const CBlockIndex* blockindex) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + int confirmations = -1; + // Only report confirmations if the block is on the main chain + if (chainActive.Contains(blockindex)) + confirmations = chainActive.Height() - blockindex->nHeight + 1; + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", blockindex->nVersion)); + result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); + result.push_back(Pair("time", (int64_t)blockindex->nTime)); + result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); + result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { @@ -255,6 +281,62 @@ UniValue getblockhash(const UniValue& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } +UniValue getblockheader(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getblockheader \"hash\" ( verbose )\n" + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" + "If verbose is true, returns an Object with information about blockheader <hash>.\n" + "\nArguments:\n" + "1. \"hash\" (string, required) The block hash\n" + "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" + "\nResult (for verbose = true):\n" + "{\n" + " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" + " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" + " \"height\" : n, (numeric) The block height or index\n" + " \"version\" : n, (numeric) The block version\n" + " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" + " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"nonce\" : n, (numeric) The nonce\n" + " \"bits\" : \"1d00ffff\", (string) The bits\n" + " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" + " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" + "}\n" + "\nResult (for verbose=false):\n" + "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" + "\nExamples:\n" + + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + ); + + LOCK(cs_main); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + + bool fVerbose = true; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (!fVerbose) + { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + ssBlock << pblockindex->GetBlockHeader(); + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); + return strHex; + } + + return blockheaderToJSON(pblockindex); +} + UniValue getblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 4c6b47e4a0..b41e960e8a 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -71,6 +71,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listunspent", 1 }, { "listunspent", 2 }, { "getblock", 1 }, + { "getblockheader", 1 }, { "gettransaction", 1 }, { "getrawtransaction", 1 }, { "createrawtransaction", 0 }, diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index b76575fc4a..287cfb2f13 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -289,6 +289,7 @@ static const CRPCCommand vRPCCommands[] = { "blockchain", "getblockcount", &getblockcount, true }, { "blockchain", "getblock", &getblock, true }, { "blockchain", "getblockhash", &getblockhash, true }, + { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 45af10c2a8..89d3980223 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -234,6 +234,7 @@ extern UniValue settxfee(const UniValue& params, bool fHelp); extern UniValue getmempoolinfo(const UniValue& params, bool fHelp); extern UniValue getrawmempool(const UniValue& params, bool fHelp); extern UniValue getblockhash(const UniValue& params, bool fHelp); +extern UniValue getblockheader(const UniValue& params, bool fHelp); extern UniValue getblock(const UniValue& params, bool fHelp); extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp); extern UniValue gettxout(const UniValue& params, bool fHelp); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 1c16e2092e..2292191be4 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -166,7 +166,7 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in continue; const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); if (fSanityCheck) assert(coins); - if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) { + if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { transactionsToRemove.push_back(tx); break; } diff --git a/src/util.cpp b/src/util.cpp index da5821e530..bb7df23205 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -756,3 +756,13 @@ void SetThreadPriority(int nPriority) #endif // PRIO_THREAD #endif // WIN32 } + +int GetNumCores() +{ +#if BOOST_VERSION >= 105600 + return boost::thread::physical_concurrency(); +#else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores + return boost::thread::hardware_concurrency(); +#endif +} + diff --git a/src/util.h b/src/util.h index 6ec81698ea..6019e25015 100644 --- a/src/util.h +++ b/src/util.h @@ -199,6 +199,13 @@ std::string HelpMessageGroup(const std::string& message); */ std::string HelpMessageOpt(const std::string& option, const std::string& message); +/** + * Return the number of physical cores available on the current system. + * @note This does not count virtual cores, such as those provided by HyperThreading + * when boost is newer than 1.56. + */ +int GetNumCores(); + void SetThreadPriority(int nPriority); void RenameThread(const char* name); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 238f62a575..44e28de0cd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -419,6 +419,7 @@ void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range) const uint256& hash = it->second; CWalletTx* copyTo = &mapWallet[hash]; if (copyFrom == copyTo) continue; + if (!copyFrom->IsEquivalentTo(*copyTo)) continue; copyTo->mapValue = copyFrom->mapValue; copyTo->vOrderForm = copyFrom->vOrderForm; // fTimeReceivedIsTxTime not copied on purpose |