From d64eef48a45d1bbbbab5adf39d6ba1fe4537cea1 Mon Sep 17 00:00:00 2001 From: coblee Date: Fri, 17 May 2013 00:57:05 -1000 Subject: [PATCH] Add getnetworkhashps to get the calculated network hashrate --- src/bitcoinrpc.cpp | 3 +++ src/bitcoinrpc.h | 1 + src/rpcmining.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 7a3e6560..22442b65 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -201,6 +201,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 }, @@ -1158,6 +1159,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 4d5599be..55365828 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -153,6 +153,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 25111d37..ca768ad7 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;