You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rpcmining.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. // Copyright (c) 2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2012 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.
  5. #include "chainparams.h"
  6. #include "main.h"
  7. #include "db.h"
  8. #include "init.h"
  9. #include "bitcoinrpc.h"
  10. using namespace json_spirit;
  11. using namespace std;
  12. // Key used by getwork/getblocktemplate miners.
  13. // Allocated in InitRPCMining, free'd in ShutdownRPCMining
  14. static CReserveKey* pMiningKey = NULL;
  15. void InitRPCMining()
  16. {
  17. // getwork/getblocktemplate mining rewards paid here:
  18. pMiningKey = new CReserveKey(pwalletMain);
  19. }
  20. void ShutdownRPCMining()
  21. {
  22. delete pMiningKey; pMiningKey = NULL;
  23. }
  24. Value getgenerate(const Array& params, bool fHelp)
  25. {
  26. if (fHelp || params.size() != 0)
  27. throw runtime_error(
  28. "getgenerate\n"
  29. "Returns true or false.");
  30. return GetBoolArg("-gen", false);
  31. }
  32. Value setgenerate(const Array& params, bool fHelp)
  33. {
  34. if (fHelp || params.size() < 1 || params.size() > 2)
  35. throw runtime_error(
  36. "setgenerate <generate> [genproclimit]\n"
  37. "<generate> is true or false to turn generation on or off.\n"
  38. "Generation is limited to [genproclimit] processors, -1 is unlimited.");
  39. bool fGenerate = true;
  40. if (params.size() > 0)
  41. fGenerate = params[0].get_bool();
  42. if (params.size() > 1)
  43. {
  44. int nGenProcLimit = params[1].get_int();
  45. mapArgs["-genproclimit"] = itostr(nGenProcLimit);
  46. if (nGenProcLimit == 0)
  47. fGenerate = false;
  48. }
  49. mapArgs["-gen"] = (fGenerate ? "1" : "0");
  50. GenerateBitcoins(fGenerate, pwalletMain);
  51. return Value::null;
  52. }
  53. Value gethashespersec(const Array& params, bool fHelp)
  54. {
  55. if (fHelp || params.size() != 0)
  56. throw runtime_error(
  57. "gethashespersec\n"
  58. "Returns a recent hashes per second performance measurement while generating.");
  59. if (GetTimeMillis() - nHPSTimerStart > 8000)
  60. return (boost::int64_t)0;
  61. return (boost::int64_t)dHashesPerSec;
  62. }
  63. Value getmininginfo(const Array& params, bool fHelp)
  64. {
  65. if (fHelp || params.size() != 0)
  66. throw runtime_error(
  67. "getmininginfo\n"
  68. "Returns an object containing mining-related information.");
  69. Object obj;
  70. obj.push_back(Pair("blocks", (int)nBestHeight));
  71. obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
  72. obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
  73. obj.push_back(Pair("difficulty", (double)GetDifficulty()));
  74. obj.push_back(Pair("errors", GetWarnings("statusbar")));
  75. obj.push_back(Pair("generate", GetBoolArg("-gen", false)));
  76. obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
  77. obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
  78. obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
  79. obj.push_back(Pair("testnet", TestNet()));
  80. return obj;
  81. }
  82. Value getwork(const Array& params, bool fHelp)
  83. {
  84. if (fHelp || params.size() > 1)
  85. throw runtime_error(
  86. "getwork [data]\n"
  87. "If [data] is not specified, returns formatted hash data to work on:\n"
  88. " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
  89. " \"data\" : block data\n"
  90. " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
  91. " \"target\" : little endian hash target\n"
  92. "If [data] is specified, tries to solve the block and returns true if it was successful.");
  93. if (vNodes.empty())
  94. throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
  95. if (IsInitialBlockDownload())
  96. throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
  97. typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
  98. static mapNewBlock_t mapNewBlock; // FIXME: thread safety
  99. static vector<CBlockTemplate*> vNewBlockTemplate;
  100. if (params.size() == 0)
  101. {
  102. // Update block
  103. static unsigned int nTransactionsUpdatedLast;
  104. static CBlockIndex* pindexPrev;
  105. static int64 nStart;
  106. static CBlockTemplate* pblocktemplate;
  107. if (pindexPrev != pindexBest ||
  108. (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
  109. {
  110. if (pindexPrev != pindexBest)
  111. {
  112. // Deallocate old blocks since they're obsolete now
  113. mapNewBlock.clear();
  114. BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
  115. delete pblocktemplate;
  116. vNewBlockTemplate.clear();
  117. }
  118. // Clear pindexPrev so future getworks make a new block, despite any failures from here on
  119. pindexPrev = NULL;
  120. // Store the pindexBest used before CreateNewBlock, to avoid races
  121. nTransactionsUpdatedLast = nTransactionsUpdated;
  122. CBlockIndex* pindexPrevNew = pindexBest;
  123. nStart = GetTime();
  124. // Create new block
  125. pblocktemplate = CreateNewBlock(*pMiningKey);
  126. if (!pblocktemplate)
  127. throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
  128. vNewBlockTemplate.push_back(pblocktemplate);
  129. // Need to update only after we know CreateNewBlock succeeded
  130. pindexPrev = pindexPrevNew;
  131. }
  132. CBlock* pblock = &pblocktemplate->block; // pointer for convenience
  133. // Update nTime
  134. UpdateTime(*pblock, pindexPrev);
  135. pblock->nNonce = 0;
  136. // Update nExtraNonce
  137. static unsigned int nExtraNonce = 0;
  138. IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
  139. // Save
  140. mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
  141. // Pre-build hash buffers
  142. char pmidstate[32];
  143. char pdata[128];
  144. char phash1[64];
  145. FormatHashBuffers(pblock, pmidstate, pdata, phash1);
  146. uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
  147. Object result;
  148. result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
  149. result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata))));
  150. result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated
  151. result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget))));
  152. return result;
  153. }
  154. else
  155. {
  156. // Parse parameters
  157. vector<unsigned char> vchData = ParseHex(params[0].get_str());
  158. if (vchData.size() != 128)
  159. throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
  160. CBlock* pdata = (CBlock*)&vchData[0];
  161. // Byte reverse
  162. for (int i = 0; i < 128/4; i++)
  163. ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
  164. // Get saved block
  165. if (!mapNewBlock.count(pdata->hashMerkleRoot))
  166. return false;
  167. CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
  168. pblock->nTime = pdata->nTime;
  169. pblock->nNonce = pdata->nNonce;
  170. pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
  171. pblock->hashMerkleRoot = pblock->BuildMerkleTree();
  172. return CheckWork(pblock, *pwalletMain, *pMiningKey);
  173. }
  174. }
  175. Value getblocktemplate(const Array& params, bool fHelp)
  176. {
  177. if (fHelp || params.size() > 1)
  178. throw runtime_error(
  179. "getblocktemplate [params]\n"
  180. "Returns data needed to construct a block to work on:\n"
  181. " \"version\" : block version\n"
  182. " \"previousblockhash\" : hash of current highest block\n"
  183. " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
  184. " \"coinbaseaux\" : data that should be included in coinbase\n"
  185. " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
  186. " \"target\" : hash target\n"
  187. " \"mintime\" : minimum timestamp appropriate for next block\n"
  188. " \"curtime\" : current timestamp\n"
  189. " \"mutable\" : list of ways the block template may be changed\n"
  190. " \"noncerange\" : range of valid nonces\n"
  191. " \"sigoplimit\" : limit of sigops in blocks\n"
  192. " \"sizelimit\" : limit of block size\n"
  193. " \"bits\" : compressed target of next block\n"
  194. " \"height\" : height of the next block\n"
  195. "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.");
  196. std::string strMode = "template";
  197. if (params.size() > 0)
  198. {
  199. const Object& oparam = params[0].get_obj();
  200. const Value& modeval = find_value(oparam, "mode");
  201. if (modeval.type() == str_type)
  202. strMode = modeval.get_str();
  203. else if (modeval.type() == null_type)
  204. {
  205. /* Do nothing */
  206. }
  207. else
  208. throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
  209. }
  210. if (strMode != "template")
  211. throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
  212. if (vNodes.empty())
  213. throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
  214. if (IsInitialBlockDownload())
  215. throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
  216. // Update block
  217. static unsigned int nTransactionsUpdatedLast;
  218. static CBlockIndex* pindexPrev;
  219. static int64 nStart;
  220. static CBlockTemplate* pblocktemplate;
  221. if (pindexPrev != pindexBest ||
  222. (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
  223. {
  224. // Clear pindexPrev so future calls make a new block, despite any failures from here on
  225. pindexPrev = NULL;
  226. // Store the pindexBest used before CreateNewBlock, to avoid races
  227. nTransactionsUpdatedLast = nTransactionsUpdated;
  228. CBlockIndex* pindexPrevNew = pindexBest;
  229. nStart = GetTime();
  230. // Create new block
  231. if(pblocktemplate)
  232. {
  233. delete pblocktemplate;
  234. pblocktemplate = NULL;
  235. }
  236. pblocktemplate = CreateNewBlock(*pMiningKey);
  237. if (!pblocktemplate)
  238. throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
  239. // Need to update only after we know CreateNewBlock succeeded
  240. pindexPrev = pindexPrevNew;
  241. }
  242. CBlock* pblock = &pblocktemplate->block; // pointer for convenience
  243. // Update nTime
  244. UpdateTime(*pblock, pindexPrev);
  245. pblock->nNonce = 0;
  246. Array transactions;
  247. map<uint256, int64_t> setTxIndex;
  248. int i = 0;
  249. BOOST_FOREACH (CTransaction& tx, pblock->vtx)
  250. {
  251. uint256 txHash = tx.GetHash();
  252. setTxIndex[txHash] = i++;
  253. if (tx.IsCoinBase())
  254. continue;
  255. Object entry;
  256. CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
  257. ssTx << tx;
  258. entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end())));
  259. entry.push_back(Pair("hash", txHash.GetHex()));
  260. Array deps;
  261. BOOST_FOREACH (const CTxIn &in, tx.vin)
  262. {
  263. if (setTxIndex.count(in.prevout.hash))
  264. deps.push_back(setTxIndex[in.prevout.hash]);
  265. }
  266. entry.push_back(Pair("depends", deps));
  267. int index_in_template = i - 1;
  268. entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
  269. entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
  270. transactions.push_back(entry);
  271. }
  272. Object aux;
  273. aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
  274. uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
  275. static Array aMutable;
  276. if (aMutable.empty())
  277. {
  278. aMutable.push_back("time");
  279. aMutable.push_back("transactions");
  280. aMutable.push_back("prevblock");
  281. }
  282. Object result;
  283. result.push_back(Pair("version", pblock->nVersion));
  284. result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
  285. result.push_back(Pair("transactions", transactions));
  286. result.push_back(Pair("coinbaseaux", aux));
  287. result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
  288. result.push_back(Pair("target", hashTarget.GetHex()));
  289. result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
  290. result.push_back(Pair("mutable", aMutable));
  291. result.push_back(Pair("noncerange", "00000000ffffffff"));
  292. result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
  293. result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
  294. result.push_back(Pair("curtime", (int64_t)pblock->nTime));
  295. result.push_back(Pair("bits", HexBits(pblock->nBits)));
  296. result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
  297. return result;
  298. }
  299. Value submitblock(const Array& params, bool fHelp)
  300. {
  301. if (fHelp || params.size() < 1 || params.size() > 2)
  302. throw runtime_error(
  303. "submitblock <hex data> [optional-params-obj]\n"
  304. "[optional-params-obj] parameter is currently ignored.\n"
  305. "Attempts to submit new block to network.\n"
  306. "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.");
  307. vector<unsigned char> blockData(ParseHex(params[0].get_str()));
  308. CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
  309. CBlock pblock;
  310. try {
  311. ssBlock >> pblock;
  312. }
  313. catch (std::exception &e) {
  314. throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
  315. }
  316. CValidationState state;
  317. bool fAccepted = ProcessBlock(state, NULL, &pblock);
  318. if (!fAccepted)
  319. return "rejected"; // TODO: report validation state
  320. return Value::null;
  321. }