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 "\nReturns the estimated network hashes per second based on the last n 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.\n"
90 "1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n"
91 "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
93 "x (numeric) Hashes per second estimated\n"
95 + HelpExampleCli("getnetworkhashps", "")
96 + HelpExampleRpc("getnetworkhashps", "")
99 return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
103 Value getgenerate(const Array& params, bool fHelp)
105 if (fHelp || params.size() != 0)
108 "\nReturn if the server is set to generate coins or not. The default is false.\n"
109 "It is set with the command line argument -gen (or bitcoin.conf setting gen)\n"
110 "It can also be set with the setgenerate call.\n"
112 "true|false (boolean) If the server is set to generate coins or not\n"
114 + HelpExampleCli("getgenerate", "")
115 + HelpExampleRpc("getgenerate", "")
121 return GetBoolArg("-gen", false);
125 Value setgenerate(const Array& params, bool fHelp)
127 if (fHelp || params.size() < 1 || params.size() > 2)
129 "setgenerate generate ( genproclimit )\n"
130 "\nSet 'generate' true or false to turn generation on or off.\n"
131 "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n"
132 "See the getgenerate call for the current setting.\n"
134 "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n"
135 "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
137 "\nSet the generation on with a limit of one processor\n"
138 + HelpExampleCli("setgenerate", "true 1") +
139 "\nCheck the setting\n"
140 + HelpExampleCli("getgenerate", "") +
141 "\nTurn off generation\n"
142 + HelpExampleCli("setgenerate", "false") +
144 + HelpExampleRpc("setgenerate", "true, 1")
147 bool fGenerate = true;
148 if (params.size() > 0)
149 fGenerate = params[0].get_bool();
151 if (params.size() > 1)
153 int nGenProcLimit = params[1].get_int();
154 mapArgs["-genproclimit"] = itostr(nGenProcLimit);
155 if (nGenProcLimit == 0)
158 mapArgs["-gen"] = (fGenerate ? "1" : "0");
160 assert(pwalletMain != NULL);
161 GenerateBitcoins(fGenerate, pwalletMain);
166 Value gethashespersec(const Array& params, bool fHelp)
168 if (fHelp || params.size() != 0)
171 "\nReturns a recent hashes per second performance measurement while generating.\n"
172 "See the getgenerate and setgenerate calls to turn generation on and off.\n"
174 "n (numeric) The recent hashes per second when generation is on (will return 0 if generation is off)\n"
176 + HelpExampleCli("gethashespersec", "")
177 + HelpExampleRpc("gethashespersec", "")
180 if (GetTimeMillis() - nHPSTimerStart > 8000)
181 return (boost::int64_t)0;
182 return (boost::int64_t)dHashesPerSec;
186 Value getmininginfo(const Array& params, bool fHelp)
188 if (fHelp || params.size() != 0)
191 "\nReturns a json object containing mining-related information."
194 " \"blocks\": nnn, (numeric) The current block\n"
195 " \"currentblocksize\": nnn, (numeric) The last block size\n"
196 " \"currentblocktx\": nnn, (numeric) The last block transaction\n"
197 " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
198 " \"errors\": \"...\" (string) Current errors\n"
199 " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
200 " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
201 " \"hashespersec\": n (numeric) The hashes per second of the generation, or 0 if no generation.\n"
202 " \"pooledtx\": n (numeric) The size of the mem pool\n"
203 " \"testnet\": true|false (boolean) If using testnet or not\n"
206 + HelpExampleCli("getmininginfo", "")
207 + HelpExampleRpc("getmininginfo", "")
211 obj.push_back(Pair("blocks", (int)chainActive.Height()));
212 obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
213 obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
214 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
215 obj.push_back(Pair("errors", GetWarnings("statusbar")));
216 obj.push_back(Pair("generate", getgenerate(params, false)));
217 obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
218 obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
219 obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
220 obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
221 obj.push_back(Pair("testnet", TestNet()));
226 Value getwork(const Array& params, bool fHelp)
228 if (fHelp || params.size() > 1)
230 "getwork ( \"data\" )\n"
231 "\nIf 'data' is not specified, it returns the formatted hash data to work on.\n"
232 "If 'data' is specified, tries to solve the block and returns true if it was successful.\n"
234 "1. \"data\" (string, optional) The hex encoded data to solve\n"
235 "\nResult (when 'data' is not specified):\n"
237 " \"midstate\" : \"xxxx\", (string) The precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
238 " \"data\" : \"xxxxx\", (string) The block data\n"
239 " \"hash1\" : \"xxxxx\", (string) The formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
240 " \"target\" : \"xxxx\" (string) The little endian hash target\n"
242 "\nResult (when 'data' is specified):\n"
243 "true|false (boolean) If solving the block specified in the 'data' was successfull\n"
245 + HelpExampleCli("getwork", "")
246 + HelpExampleRpc("getwork", "")
250 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
252 if (IsInitialBlockDownload())
253 throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
255 typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
256 static mapNewBlock_t mapNewBlock; // FIXME: thread safety
257 static vector<CBlockTemplate*> vNewBlockTemplate;
259 if (params.size() == 0)
262 static unsigned int nTransactionsUpdatedLast;
263 static CBlockIndex* pindexPrev;
264 static int64_t nStart;
265 static CBlockTemplate* pblocktemplate;
266 if (pindexPrev != chainActive.Tip() ||
267 (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60))
269 if (pindexPrev != chainActive.Tip())
271 // Deallocate old blocks since they're obsolete now
273 BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
274 delete pblocktemplate;
275 vNewBlockTemplate.clear();
278 // Clear pindexPrev so future getworks make a new block, despite any failures from here on
281 // Store the pindexBest used before CreateNewBlock, to avoid races
282 nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
283 CBlockIndex* pindexPrevNew = chainActive.Tip();
287 pblocktemplate = CreateNewBlockWithKey(*pMiningKey);
289 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
290 vNewBlockTemplate.push_back(pblocktemplate);
292 // Need to update only after we know CreateNewBlock succeeded
293 pindexPrev = pindexPrevNew;
295 CBlock* pblock = &pblocktemplate->block; // pointer for convenience
298 UpdateTime(*pblock, pindexPrev);
301 // Update nExtraNonce
302 static unsigned int nExtraNonce = 0;
303 IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
306 mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
308 // Pre-build hash buffers
312 FormatHashBuffers(pblock, pmidstate, pdata, phash1);
314 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
317 result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
318 result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata))));
319 result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated
320 result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget))));
326 vector<unsigned char> vchData = ParseHex(params[0].get_str());
327 if (vchData.size() != 128)
328 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
329 CBlock* pdata = (CBlock*)&vchData[0];
332 for (int i = 0; i < 128/4; i++)
333 ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
336 if (!mapNewBlock.count(pdata->hashMerkleRoot))
338 CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
340 pblock->nTime = pdata->nTime;
341 pblock->nNonce = pdata->nNonce;
342 pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
343 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
345 assert(pwalletMain != NULL);
346 return CheckWork(pblock, *pwalletMain, *pMiningKey);
351 Value getblocktemplate(const Array& params, bool fHelp)
353 if (fHelp || params.size() > 1)
355 "getblocktemplate ( \"jsonrequestobject\" )\n"
356 "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
357 "It returns data needed to construct a block to work on.\n"
358 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
361 "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n"
363 " \"mode\":\"template\" (string, optional) This must be set to \"template\" or omitted\n"
364 " \"capabilities\":[ (array, optional) A list of strings\n"
365 " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
373 " \"version\" : n, (numeric) The block version\n"
374 " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n"
375 " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n"
377 " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
378 " \"hash\" : \"xxxx\", (string) hash/id encoded in little-endian hexadecimal\n"
379 " \"depends\" : [ (array) array of numbers \n"
380 " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n"
383 " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n"
384 " \"sigops\" : n, (numeric) total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any\n"
385 " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n"
389 " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n"
390 " \"flags\" : \"flags\" (string) \n"
392 " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
393 " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n"
394 " \"target\" : \"xxxx\", (string) The hash target\n"
395 " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
396 " \"mutable\" : [ (array of string) list of ways the block template may be changed \n"
397 " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
400 " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n"
401 " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n"
402 " \"sizelimit\" : n, (numeric) limit of block size\n"
403 " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
404 " \"bits\" : \"xxx\", (string) compressed target of next block\n"
405 " \"height\" : n (numeric) The height of the next block\n"
409 + HelpExampleCli("getblocktemplate", "")
410 + HelpExampleRpc("getblocktemplate", "")
413 std::string strMode = "template";
414 if (params.size() > 0)
416 const Object& oparam = params[0].get_obj();
417 const Value& modeval = find_value(oparam, "mode");
418 if (modeval.type() == str_type)
419 strMode = modeval.get_str();
420 else if (modeval.type() == null_type)
425 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
428 if (strMode != "template")
429 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
432 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
434 if (IsInitialBlockDownload())
435 throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
438 static unsigned int nTransactionsUpdatedLast;
439 static CBlockIndex* pindexPrev;
440 static int64_t nStart;
441 static CBlockTemplate* pblocktemplate;
442 if (pindexPrev != chainActive.Tip() ||
443 (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
445 // Clear pindexPrev so future calls make a new block, despite any failures from here on
448 // Store the pindexBest used before CreateNewBlock, to avoid races
449 nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
450 CBlockIndex* pindexPrevNew = chainActive.Tip();
456 delete pblocktemplate;
457 pblocktemplate = NULL;
459 CScript scriptDummy = CScript() << OP_TRUE;
460 pblocktemplate = CreateNewBlock(scriptDummy);
462 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
464 // Need to update only after we know CreateNewBlock succeeded
465 pindexPrev = pindexPrevNew;
467 CBlock* pblock = &pblocktemplate->block; // pointer for convenience
470 UpdateTime(*pblock, pindexPrev);
474 map<uint256, int64_t> setTxIndex;
476 BOOST_FOREACH (CTransaction& tx, pblock->vtx)
478 uint256 txHash = tx.GetHash();
479 setTxIndex[txHash] = i++;
486 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
488 entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end())));
490 entry.push_back(Pair("hash", txHash.GetHex()));
493 BOOST_FOREACH (const CTxIn &in, tx.vin)
495 if (setTxIndex.count(in.prevout.hash))
496 deps.push_back(setTxIndex[in.prevout.hash]);
498 entry.push_back(Pair("depends", deps));
500 int index_in_template = i - 1;
501 entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
502 entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
504 transactions.push_back(entry);
508 aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
510 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
512 static Array aMutable;
513 if (aMutable.empty())
515 aMutable.push_back("time");
516 aMutable.push_back("transactions");
517 aMutable.push_back("prevblock");
521 result.push_back(Pair("version", pblock->nVersion));
522 result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
523 result.push_back(Pair("transactions", transactions));
524 result.push_back(Pair("coinbaseaux", aux));
525 result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
526 result.push_back(Pair("target", hashTarget.GetHex()));
527 result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
528 result.push_back(Pair("mutable", aMutable));
529 result.push_back(Pair("noncerange", "00000000ffffffff"));
530 result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
531 result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
532 result.push_back(Pair("curtime", (int64_t)pblock->nTime));
533 result.push_back(Pair("bits", HexBits(pblock->nBits)));
534 result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
539 Value submitblock(const Array& params, bool fHelp)
541 if (fHelp || params.size() < 1 || params.size() > 2)
543 "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
544 "\nAttempts to submit new block to network.\n"
545 "The 'jsonparametersobject' parameter is currently ignored.\n"
546 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
549 "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
550 "2. \"jsonparametersobject\" (string, optional) object of optional parameters\n"
552 " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n"
556 + HelpExampleCli("submitblock", "\"mydata\"")
557 + HelpExampleRpc("submitblock", "\"mydata\"")
560 vector<unsigned char> blockData(ParseHex(params[0].get_str()));
561 CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
566 catch (std::exception &e) {
567 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
570 CValidationState state;
571 bool fAccepted = ProcessBlock(state, NULL, &pblock);
573 return "rejected"; // TODO: report validation state