aboutsummaryrefslogtreecommitdiff
path: root/src/rpcmining.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpcmining.cpp')
-rw-r--r--src/rpcmining.cpp92
1 files changed, 78 insertions, 14 deletions
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index d2cac68706..77dc13815d 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -1,11 +1,12 @@
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2012 The Bitcoin developers
+// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "main.h"
+#include "chainparams.h"
#include "db.h"
#include "init.h"
+#include "miner.h"
#include "bitcoinrpc.h"
using namespace json_spirit;
@@ -17,15 +18,71 @@ static CReserveKey* pMiningKey = NULL;
void InitRPCMining()
{
+ if (!pwalletMain)
+ return;
+
// getwork/getblocktemplate mining rewards paid here:
pMiningKey = new CReserveKey(pwalletMain);
}
void ShutdownRPCMining()
{
+ if (!pMiningKey)
+ return;
+
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 = chainActive[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)
@@ -33,6 +90,9 @@ Value getgenerate(const Array& params, bool fHelp)
"getgenerate\n"
"Returns true or false.");
+ if (!pMiningKey)
+ return false;
+
return GetBoolArg("-gen", false);
}
@@ -58,6 +118,7 @@ Value setgenerate(const Array& params, bool fHelp)
}
mapArgs["-gen"] = (fGenerate ? "1" : "0");
+ assert(pwalletMain != NULL);
GenerateBitcoins(fGenerate, pwalletMain);
return Value::null;
}
@@ -84,16 +145,17 @@ Value getmininginfo(const Array& params, bool fHelp)
"Returns an object containing mining-related information.");
Object obj;
- obj.push_back(Pair("blocks", (int)nBestHeight));
+ obj.push_back(Pair("blocks", (int)chainActive.Height()));
obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
- obj.push_back(Pair("generate", GetBoolArg("-gen", false)));
+ obj.push_back(Pair("generate", getgenerate(params, 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", fTestNet));
+ obj.push_back(Pair("testnet", TestNet()));
return obj;
}
@@ -127,10 +189,10 @@ Value getwork(const Array& params, bool fHelp)
static CBlockIndex* pindexPrev;
static int64 nStart;
static CBlockTemplate* pblocktemplate;
- if (pindexPrev != pindexBest ||
+ if (pindexPrev != chainActive.Tip() ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
{
- if (pindexPrev != pindexBest)
+ if (pindexPrev != chainActive.Tip())
{
// Deallocate old blocks since they're obsolete now
mapNewBlock.clear();
@@ -144,11 +206,11 @@ Value getwork(const Array& params, bool fHelp)
// Store the pindexBest used before CreateNewBlock, to avoid races
nTransactionsUpdatedLast = nTransactionsUpdated;
- CBlockIndex* pindexPrevNew = pindexBest;
+ CBlockIndex* pindexPrevNew = chainActive.Tip();
nStart = GetTime();
// Create new block
- pblocktemplate = CreateNewBlock(*pMiningKey);
+ pblocktemplate = CreateNewBlockWithKey(*pMiningKey);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
vNewBlockTemplate.push_back(pblocktemplate);
@@ -159,7 +221,7 @@ Value getwork(const Array& params, bool fHelp)
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
// Update nTime
- pblock->UpdateTime(pindexPrev);
+ UpdateTime(*pblock, pindexPrev);
pblock->nNonce = 0;
// Update nExtraNonce
@@ -206,6 +268,7 @@ Value getwork(const Array& params, bool fHelp)
pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+ assert(pwalletMain != NULL);
return CheckWork(pblock, *pwalletMain, *pMiningKey);
}
}
@@ -262,7 +325,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
static CBlockIndex* pindexPrev;
static int64 nStart;
static CBlockTemplate* pblocktemplate;
- if (pindexPrev != pindexBest ||
+ if (pindexPrev != chainActive.Tip() ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
{
// Clear pindexPrev so future calls make a new block, despite any failures from here on
@@ -270,7 +333,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
// Store the pindexBest used before CreateNewBlock, to avoid races
nTransactionsUpdatedLast = nTransactionsUpdated;
- CBlockIndex* pindexPrevNew = pindexBest;
+ CBlockIndex* pindexPrevNew = chainActive.Tip();
nStart = GetTime();
// Create new block
@@ -279,7 +342,8 @@ Value getblocktemplate(const Array& params, bool fHelp)
delete pblocktemplate;
pblocktemplate = NULL;
}
- pblocktemplate = CreateNewBlock(*pMiningKey);
+ CScript scriptDummy = CScript() << OP_TRUE;
+ pblocktemplate = CreateNewBlock(scriptDummy);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
@@ -289,7 +353,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
// Update nTime
- pblock->UpdateTime(pindexPrev);
+ UpdateTime(*pblock, pindexPrev);
pblock->nNonce = 0;
Array transactions;