diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index ce8ff71a2..3ec47f89e 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -229,6 +229,7 @@ static const CRPCCommand vRPCCommands[] = { "addnode", &addnode, true, true }, { "getaddednodeinfo", &getaddednodeinfo, true, true }, { "getdifficulty", &getdifficulty, true, false }, + { "getnetworkhashps", &getnetworkhashps, true, false }, { "getgenerate", &getgenerate, true, false }, { "setgenerate", &setgenerate, true, false }, { "gethashespersec", &gethashespersec, true, false }, @@ -1188,6 +1189,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 0) ConvertTo(params[0]); if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); + if (strMethod == "getnetworkhashps" && n > 0) ConvertTo(params[0]); + if (strMethod == "getnetworkhashps" && n > 1) ConvertTo(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index ab0a0bc96..0523a1c42 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -162,6 +162,7 @@ extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fH extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index c7f516caa..2b7a5e38c 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -27,6 +27,59 @@ void ShutdownRPCMining() delete pMiningKey; pMiningKey = NULL; } +// Return average network hashes per second based on the last 'lookup' blocks, +// or from the last difficulty change if 'lookup' is nonpositive. +// If 'height' is nonnegative, compute the estimate at the time when a given block was found. +Value GetNetworkHashPS(int lookup, int height) { + CBlockIndex *pb = pindexBest; + + if (height >= 0 && height < nBestHeight) + pb = FindBlockByHeight(height); + + if (pb == NULL || !pb->nHeight) + return 0; + + // If lookup is -1, then use blocks since last difficulty change. + if (lookup <= 0) + lookup = pb->nHeight % 2016 + 1; + + // If lookup is larger than chain, then set it to chain length. + if (lookup > pb->nHeight) + lookup = pb->nHeight; + + CBlockIndex *pb0 = pb; + int64 minTime = pb0->GetBlockTime(); + int64 maxTime = minTime; + for (int i = 0; i < lookup; i++) { + pb0 = pb0->pprev; + int64 time = pb0->GetBlockTime(); + minTime = std::min(time, minTime); + maxTime = std::max(time, maxTime); + } + + // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception. + if (minTime == maxTime) + return 0; + + uint256 workDiff = pb->nChainWork - pb0->nChainWork; + int64 timeDiff = maxTime - minTime; + + return (boost::int64_t)(workDiff.getdouble() / timeDiff); +} + +Value getnetworkhashps(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "getnetworkhashps [blocks] [height]\n" + "Returns the estimated network hashes per second based on the last 120 blocks.\n" + "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n" + "Pass in [height] to estimate the network speed at the time when a certain block was found."); + + return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); +} + + Value getgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -93,6 +146,7 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("generate", GetBoolArg("-gen", false))); obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); obj.push_back(Pair("hashespersec", gethashespersec(params, false))); + obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("testnet", TestNet())); return obj;