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 13KB

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