1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2013 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include "bitcoinrpc.h"
7 #include "chainparams.h"
17 #include "json/json_spirit_utils.h"
18 #include "json/json_spirit_value.h"
20 using namespace json_spirit;
23 // Key used by getwork/getblocktemplate miners.
24 // Allocated in InitRPCMining, free'd in ShutdownRPCMining
25 static CReserveKey* pMiningKey = NULL;
32 // getwork/getblocktemplate mining rewards paid here:
33 pMiningKey = new CReserveKey(pwalletMain);
36 void ShutdownRPCMining()
41 delete pMiningKey; pMiningKey = NULL;
44 // Return average network hashes per second based on the last 'lookup' blocks,
45 // or from the last difficulty change if 'lookup' is nonpositive.
46 // If 'height' is nonnegative, compute the estimate at the time when a given block was found.
47 Value GetNetworkHashPS(int lookup, int height) {
48 CBlockIndex *pb = chainActive[height];
50 if (pb == NULL || !pb->nHeight)
53 // If lookup is -1, then use blocks since last difficulty change.
55 lookup = pb->nHeight % 2016 + 1;
57 // If lookup is larger than chain, then set it to chain length.
58 if (lookup > pb->nHeight)
61 CBlockIndex *pb0 = pb;
62 int64_t minTime = pb0->GetBlockTime();
63 int64_t maxTime = minTime;
64 for (int i = 0; i < lookup; i++) {
66 int64_t time = pb0->GetBlockTime();
67 minTime = std::min(time, minTime);
68 maxTime = std::max(time, maxTime);
71 // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
72 if (minTime == maxTime)
75 uint256 workDiff = pb->nChainWork - pb0->nChainWork;
76 int64_t timeDiff = maxTime - minTime;
78 return (boost::int64_t)(workDiff.getdouble() / timeDiff);
81 Value getnetworkhashps(const Array& params, bool fHelp)
83 if (fHelp || params.size() > 2)
85 "getnetworkhashps [blocks] [height]\n"
86 "Returns the estimated network hashes per second based on the last 120 blocks.\n"
87 "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
88 "Pass in [height] to estimate the network speed at the time when a certain block was found.");
90 return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
94 Value getgenerate(const Array& params, bool fHelp)
96 if (fHelp || params.size() != 0)
99 "Returns true or false.");
104 return GetBoolArg("-gen", false);
108 Value setgenerate(const Array& params, bool fHelp)
110 if (fHelp || params.size() < 1 || params.size() > 2)
112 "setgenerate <generate> [genproclimit]\n"
113 "<generate> is true or false to turn generation on or off.\n"
114 "Generation is limited to [genproclimit] processors, -1 is unlimited.");
116 bool fGenerate = true;
117 if (params.size() > 0)
118 fGenerate = params[0].get_bool();
120 if (params.size() > 1)
122 int nGenProcLimit = params[1].get_int();
123 mapArgs["-genproclimit"] = itostr(nGenProcLimit);
124 if (nGenProcLimit == 0)
127 mapArgs["-gen"] = (fGenerate ? "1" : "0");
129 assert(pwalletMain != NULL);
130 GenerateBitcoins(fGenerate, pwalletMain);
135 Value gethashespersec(const Array& params, bool fHelp)
137 if (fHelp || params.size() != 0)
140 "Returns a recent hashes per second performance measurement while generating.");
142 if (GetTimeMillis() - nHPSTimerStart > 8000)
143 return (boost::int64_t)0;
144 return (boost::int64_t)dHashesPerSec;
148 Value getmininginfo(const Array& params, bool fHelp)
150 if (fHelp || params.size() != 0)
153 "Returns an object containing mining-related information.");
156 obj.push_back(Pair("blocks", (int)chainActive.Height()));
157 obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
158 obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
159 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
160 obj.push_back(Pair("errors", GetWarnings("statusbar")));
161 obj.push_back(Pair("generate", getgenerate(params, false)));
162 obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
163 obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
164 obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
165 obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
166 obj.push_back(Pair("testnet", TestNet()));
171 Value getwork(const Array& params, bool fHelp)
173 if (fHelp || params.size() > 1)
176 "If [data] is not specified, returns formatted hash data to work on:\n"
177 " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
178 " \"data\" : block data\n"
179 " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
180 " \"target\" : little endian hash target\n"
181 "If [data] is specified, tries to solve the block and returns true if it was successful.");
184 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
186 if (IsInitialBlockDownload())
187 throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
189 typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
190 static mapNewBlock_t mapNewBlock; // FIXME: thread safety
191 static vector<CBlockTemplate*> vNewBlockTemplate;
193 if (params.size() == 0)
196 static unsigned int nTransactionsUpdatedLast;
197 static CBlockIndex* pindexPrev;
198 static int64_t nStart;
199 static CBlockTemplate* pblocktemplate;
200 if (pindexPrev != chainActive.Tip() ||
201 (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60))
203 if (pindexPrev != chainActive.Tip())
205 // Deallocate old blocks since they're obsolete now
207 BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
208 delete pblocktemplate;
209 vNewBlockTemplate.clear();
212 // Clear pindexPrev so future getworks make a new block, despite any failures from here on
215 // Store the pindexBest used before CreateNewBlock, to avoid races
216 nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
217 CBlockIndex* pindexPrevNew = chainActive.Tip();
221 pblocktemplate = CreateNewBlockWithKey(*pMiningKey);
223 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
224 vNewBlockTemplate.push_back(pblocktemplate);
226 // Need to update only after we know CreateNewBlock succeeded
227 pindexPrev = pindexPrevNew;
229 CBlock* pblock = &pblocktemplate->block; // pointer for convenience
232 UpdateTime(*pblock, pindexPrev);
235 // Update nExtraNonce
236 static unsigned int nExtraNonce = 0;
237 IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
240 mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
242 // Pre-build hash buffers
246 FormatHashBuffers(pblock, pmidstate, pdata, phash1);
248 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
251 result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
252 result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata))));
253 result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated
254 result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget))));
260 vector<unsigned char> vchData = ParseHex(params[0].get_str());
261 if (vchData.size() != 128)
262 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
263 CBlock* pdata = (CBlock*)&vchData[0];
266 for (int i = 0; i < 128/4; i++)
267 ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
270 if (!mapNewBlock.count(pdata->hashMerkleRoot))
272 CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
274 pblock->nTime = pdata->nTime;
275 pblock->nNonce = pdata->nNonce;
276 pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
277 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
279 assert(pwalletMain != NULL);
280 return CheckWork(pblock, *pwalletMain, *pMiningKey);
285 Value getblocktemplate(const Array& params, bool fHelp)
287 if (fHelp || params.size() > 1)
289 "getblocktemplate [params]\n"
290 "Returns data needed to construct a block to work on:\n"
291 " \"version\" : block version\n"
292 " \"previousblockhash\" : hash of current highest block\n"
293 " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
294 " \"coinbaseaux\" : data that should be included in coinbase\n"
295 " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
296 " \"target\" : hash target\n"
297 " \"mintime\" : minimum timestamp appropriate for next block\n"
298 " \"curtime\" : current timestamp\n"
299 " \"mutable\" : list of ways the block template may be changed\n"
300 " \"noncerange\" : range of valid nonces\n"
301 " \"sigoplimit\" : limit of sigops in blocks\n"
302 " \"sizelimit\" : limit of block size\n"
303 " \"bits\" : compressed target of next block\n"
304 " \"height\" : height of the next block\n"
305 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.");
307 std::string strMode = "template";
308 if (params.size() > 0)
310 const Object& oparam = params[0].get_obj();
311 const Value& modeval = find_value(oparam, "mode");
312 if (modeval.type() == str_type)
313 strMode = modeval.get_str();
314 else if (modeval.type() == null_type)
319 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
322 if (strMode != "template")
323 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
326 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
328 if (IsInitialBlockDownload())
329 throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
332 static unsigned int nTransactionsUpdatedLast;
333 static CBlockIndex* pindexPrev;
334 static int64_t nStart;
335 static CBlockTemplate* pblocktemplate;
336 if (pindexPrev != chainActive.Tip() ||
337 (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
339 // Clear pindexPrev so future calls make a new block, despite any failures from here on
342 // Store the pindexBest used before CreateNewBlock, to avoid races
343 nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
344 CBlockIndex* pindexPrevNew = chainActive.Tip();
350 delete pblocktemplate;
351 pblocktemplate = NULL;
353 CScript scriptDummy = CScript() << OP_TRUE;
354 pblocktemplate = CreateNewBlock(scriptDummy);
356 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
358 // Need to update only after we know CreateNewBlock succeeded
359 pindexPrev = pindexPrevNew;
361 CBlock* pblock = &pblocktemplate->block; // pointer for convenience
364 UpdateTime(*pblock, pindexPrev);
368 map<uint256, int64_t> setTxIndex;
370 BOOST_FOREACH (CTransaction& tx, pblock->vtx)
372 uint256 txHash = tx.GetHash();
373 setTxIndex[txHash] = i++;
380 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
382 entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end())));
384 entry.push_back(Pair("hash", txHash.GetHex()));
387 BOOST_FOREACH (const CTxIn &in, tx.vin)
389 if (setTxIndex.count(in.prevout.hash))
390 deps.push_back(setTxIndex[in.prevout.hash]);
392 entry.push_back(Pair("depends", deps));
394 int index_in_template = i - 1;
395 entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
396 entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
398 transactions.push_back(entry);
402 aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
404 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
406 static Array aMutable;
407 if (aMutable.empty())
409 aMutable.push_back("time");
410 aMutable.push_back("transactions");
411 aMutable.push_back("prevblock");
415 result.push_back(Pair("version", pblock->nVersion));
416 result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
417 result.push_back(Pair("transactions", transactions));
418 result.push_back(Pair("coinbaseaux", aux));
419 result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
420 result.push_back(Pair("target", hashTarget.GetHex()));
421 result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
422 result.push_back(Pair("mutable", aMutable));
423 result.push_back(Pair("noncerange", "00000000ffffffff"));
424 result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
425 result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
426 result.push_back(Pair("curtime", (int64_t)pblock->nTime));
427 result.push_back(Pair("bits", HexBits(pblock->nBits)));
428 result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
433 Value submitblock(const Array& params, bool fHelp)
435 if (fHelp || params.size() < 1 || params.size() > 2)
437 "submitblock <hex data> [optional-params-obj]\n"
438 "[optional-params-obj] parameter is currently ignored.\n"
439 "Attempts to submit new block to network.\n"
440 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.");
442 vector<unsigned char> blockData(ParseHex(params[0].get_str()));
443 CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
448 catch (std::exception &e) {
449 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
452 CValidationState state;
453 bool fAccepted = ProcessBlock(state, NULL, &pblock);
455 return "rejected"; // TODO: report validation state