Line data Source code
1 : // Copyright (c) 2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "amount.h"
7 : #include "chain.h"
8 : #include "chainparams.h"
9 : #include "consensus/consensus.h"
10 : #include "consensus/validation.h"
11 : #include "core_io.h"
12 : #include "init.h"
13 : #include "main.h"
14 : #include "miner.h"
15 : #include "net.h"
16 : #include "pow.h"
17 : #include "rpcserver.h"
18 : #include "txmempool.h"
19 : #include "util.h"
20 : #include "utilstrencodings.h"
21 : #include "validationinterface.h"
22 :
23 : #include <stdint.h>
24 :
25 : #include <boost/assign/list_of.hpp>
26 : #include <boost/shared_ptr.hpp>
27 :
28 : #include <univalue.h>
29 :
30 : using namespace std;
31 :
32 : /**
33 : * Return average network hashes per second based on the last 'lookup' blocks,
34 : * or from the last difficulty change if 'lookup' is nonpositive.
35 : * If 'height' is nonnegative, compute the estimate at the time when a given block was found.
36 : */
37 0 : UniValue GetNetworkHashPS(int lookup, int height) {
38 0 : CBlockIndex *pb = chainActive.Tip();
39 :
40 0 : if (height >= 0 && height < chainActive.Height())
41 0 : pb = chainActive[height];
42 :
43 0 : if (pb == NULL || !pb->nHeight)
44 0 : return 0;
45 :
46 : // If lookup is -1, then use blocks since last difficulty change.
47 0 : if (lookup <= 0)
48 0 : lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1;
49 :
50 : // If lookup is larger than chain, then set it to chain length.
51 0 : if (lookup > pb->nHeight)
52 0 : lookup = pb->nHeight;
53 :
54 0 : CBlockIndex *pb0 = pb;
55 0 : int64_t minTime = pb0->GetBlockTime();
56 0 : int64_t maxTime = minTime;
57 0 : for (int i = 0; i < lookup; i++) {
58 0 : pb0 = pb0->pprev;
59 0 : int64_t time = pb0->GetBlockTime();
60 0 : minTime = std::min(time, minTime);
61 0 : maxTime = std::max(time, maxTime);
62 : }
63 :
64 : // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
65 0 : if (minTime == maxTime)
66 0 : return 0;
67 :
68 0 : arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
69 0 : int64_t timeDiff = maxTime - minTime;
70 :
71 0 : return (int64_t)(workDiff.getdouble() / timeDiff);
72 : }
73 :
74 0 : UniValue getnetworkhashps(const UniValue& params, bool fHelp)
75 : {
76 0 : if (fHelp || params.size() > 2)
77 : throw runtime_error(
78 : "getnetworkhashps ( blocks height )\n"
79 : "\nReturns the estimated network hashes per second based on the last n blocks.\n"
80 : "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
81 : "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
82 : "\nArguments:\n"
83 : "1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n"
84 : "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
85 : "\nResult:\n"
86 : "x (numeric) Hashes per second estimated\n"
87 : "\nExamples:\n"
88 0 : + HelpExampleCli("getnetworkhashps", "")
89 0 : + HelpExampleRpc("getnetworkhashps", "")
90 0 : );
91 :
92 0 : LOCK(cs_main);
93 0 : return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
94 : }
95 :
96 0 : UniValue getgenerate(const UniValue& params, bool fHelp)
97 : {
98 0 : if (fHelp || params.size() != 0)
99 : throw runtime_error(
100 : "getgenerate\n"
101 : "\nReturn if the server is set to generate coins or not. The default is false.\n"
102 : "It is set with the command line argument -gen (or bitcoin.conf setting gen)\n"
103 : "It can also be set with the setgenerate call.\n"
104 : "\nResult\n"
105 : "true|false (boolean) If the server is set to generate coins or not\n"
106 : "\nExamples:\n"
107 0 : + HelpExampleCli("getgenerate", "")
108 0 : + HelpExampleRpc("getgenerate", "")
109 0 : );
110 :
111 0 : LOCK(cs_main);
112 0 : return GetBoolArg("-gen", false);
113 : }
114 :
115 275 : UniValue generate(const UniValue& params, bool fHelp)
116 : {
117 825 : if (fHelp || params.size() < 1 || params.size() > 1)
118 : throw runtime_error(
119 : "generate numblocks\n"
120 : "\nMine blocks immediately (before the RPC call returns)\n"
121 : "\nNote: this function can only be used on the regtest network\n"
122 : "\nArguments:\n"
123 : "1. numblocks (numeric, required) How many blocks are generated immediately.\n"
124 : "\nResult\n"
125 : "[ blockhashes ] (array) hashes of blocks generated\n"
126 : "\nExamples:\n"
127 : "\nGenerate 11 blocks\n"
128 0 : + HelpExampleCli("generate", "11")
129 0 : );
130 :
131 275 : if (!Params().MineBlocksOnDemand())
132 0 : throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
133 :
134 275 : int nHeightStart = 0;
135 275 : int nHeightEnd = 0;
136 275 : int nHeight = 0;
137 275 : int nGenerate = params[0].get_int();
138 :
139 : boost::shared_ptr<CReserveScript> coinbaseScript;
140 274 : GetMainSignals().ScriptForMining(coinbaseScript);
141 :
142 : // If the keypool is exhausted, no script is returned at all. Catch this.
143 274 : if (!coinbaseScript)
144 0 : throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
145 :
146 : //throw an error if no script was provided
147 822 : if (coinbaseScript->reserveScript.empty())
148 0 : throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
149 :
150 : { // Don't keep cs_main locked
151 274 : LOCK(cs_main);
152 274 : nHeightStart = chainActive.Height();
153 274 : nHeight = nHeightStart;
154 274 : nHeightEnd = nHeightStart+nGenerate;
155 : }
156 274 : unsigned int nExtraNonce = 0;
157 822 : UniValue blockHashes(UniValue::VARR);
158 1784 : while (nHeight < nHeightEnd)
159 : {
160 2472 : auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
161 1236 : if (!pblocktemplate.get())
162 0 : throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
163 1236 : CBlock *pblock = &pblocktemplate->block;
164 : {
165 1236 : LOCK(cs_main);
166 1236 : IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
167 : }
168 6182 : while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
169 : // Yes, there is a chance every nonce could fail to satisfy the -regtest
170 : // target -- 1 in 2^(2^32). That ain't gonna happen.
171 1237 : ++pblock->nNonce;
172 : }
173 1236 : CValidationState state;
174 1236 : if (!ProcessNewBlock(state, NULL, pblock, true, NULL))
175 0 : throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
176 1236 : ++nHeight;
177 2472 : blockHashes.push_back(pblock->GetHash().GetHex());
178 :
179 : //mark script as important because it was used at least for one coinbase output
180 2472 : coinbaseScript->KeepScript();
181 1236 : }
182 274 : return blockHashes;
183 : }
184 :
185 0 : UniValue setgenerate(const UniValue& params, bool fHelp)
186 : {
187 0 : if (fHelp || params.size() < 1 || params.size() > 2)
188 : throw runtime_error(
189 : "setgenerate generate ( genproclimit )\n"
190 : "\nSet 'generate' true or false to turn generation on or off.\n"
191 : "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n"
192 : "See the getgenerate call for the current setting.\n"
193 : "\nArguments:\n"
194 : "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n"
195 : "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
196 : "\nExamples:\n"
197 : "\nSet the generation on with a limit of one processor\n"
198 0 : + HelpExampleCli("setgenerate", "true 1") +
199 : "\nCheck the setting\n"
200 0 : + HelpExampleCli("getgenerate", "") +
201 : "\nTurn off generation\n"
202 0 : + HelpExampleCli("setgenerate", "false") +
203 : "\nUsing json rpc\n"
204 0 : + HelpExampleRpc("setgenerate", "true, 1")
205 0 : );
206 :
207 0 : if (Params().MineBlocksOnDemand())
208 0 : throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
209 :
210 0 : bool fGenerate = true;
211 0 : if (params.size() > 0)
212 0 : fGenerate = params[0].get_bool();
213 :
214 0 : int nGenProcLimit = -1;
215 0 : if (params.size() > 1)
216 : {
217 0 : nGenProcLimit = params[1].get_int();
218 0 : if (nGenProcLimit == 0)
219 0 : fGenerate = false;
220 : }
221 :
222 0 : mapArgs["-gen"] = (fGenerate ? "1" : "0");
223 0 : mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
224 0 : GenerateBitcoins(fGenerate, nGenProcLimit, Params());
225 :
226 0 : return NullUniValue;
227 : }
228 :
229 0 : UniValue getmininginfo(const UniValue& params, bool fHelp)
230 : {
231 0 : if (fHelp || params.size() != 0)
232 : throw runtime_error(
233 : "getmininginfo\n"
234 : "\nReturns a json object containing mining-related information."
235 : "\nResult:\n"
236 : "{\n"
237 : " \"blocks\": nnn, (numeric) The current block\n"
238 : " \"currentblocksize\": nnn, (numeric) The last block size\n"
239 : " \"currentblocktx\": nnn, (numeric) The last block transaction\n"
240 : " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
241 : " \"errors\": \"...\" (string) Current errors\n"
242 : " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
243 : " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
244 : " \"pooledtx\": n (numeric) The size of the mem pool\n"
245 : " \"testnet\": true|false (boolean) If using testnet or not\n"
246 : " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
247 : "}\n"
248 : "\nExamples:\n"
249 0 : + HelpExampleCli("getmininginfo", "")
250 0 : + HelpExampleRpc("getmininginfo", "")
251 0 : );
252 :
253 :
254 0 : LOCK(cs_main);
255 :
256 0 : UniValue obj(UniValue::VOBJ);
257 0 : obj.push_back(Pair("blocks", (int)chainActive.Height()));
258 0 : obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
259 0 : obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
260 0 : obj.push_back(Pair("difficulty", (double)GetDifficulty()));
261 0 : obj.push_back(Pair("errors", GetWarnings("statusbar")));
262 0 : obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
263 0 : obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
264 0 : obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
265 0 : obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
266 0 : obj.push_back(Pair("chain", Params().NetworkIDString()));
267 0 : obj.push_back(Pair("generate", getgenerate(params, false)));
268 0 : return obj;
269 : }
270 :
271 :
272 : // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
273 0 : UniValue prioritisetransaction(const UniValue& params, bool fHelp)
274 : {
275 0 : if (fHelp || params.size() != 3)
276 : throw runtime_error(
277 : "prioritisetransaction <txid> <priority delta> <fee delta>\n"
278 : "Accepts the transaction into mined blocks at a higher (or lower) priority\n"
279 : "\nArguments:\n"
280 : "1. \"txid\" (string, required) The transaction id.\n"
281 : "2. priority delta (numeric, required) The priority to add or subtract.\n"
282 : " The transaction selection algorithm considers the tx as it would have a higher priority.\n"
283 : " (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n"
284 : "3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
285 : " The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
286 : " considers the transaction as it would have paid a higher (or lower) fee.\n"
287 : "\nResult\n"
288 : "true (boolean) Returns true\n"
289 : "\nExamples:\n"
290 0 : + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
291 0 : + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
292 0 : );
293 :
294 0 : LOCK(cs_main);
295 :
296 0 : uint256 hash = ParseHashStr(params[0].get_str(), "txid");
297 0 : CAmount nAmount = params[2].get_int64();
298 :
299 0 : mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
300 0 : return true;
301 : }
302 :
303 :
304 : // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
305 0 : static UniValue BIP22ValidationResult(const CValidationState& state)
306 : {
307 0 : if (state.IsValid())
308 0 : return NullUniValue;
309 :
310 : std::string strRejectReason = state.GetRejectReason();
311 0 : if (state.IsError())
312 0 : throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason);
313 0 : if (state.IsInvalid())
314 : {
315 0 : if (strRejectReason.empty())
316 0 : return "rejected";
317 0 : return strRejectReason;
318 : }
319 : // Should be impossible
320 0 : return "valid?";
321 : }
322 :
323 0 : UniValue getblocktemplate(const UniValue& params, bool fHelp)
324 : {
325 0 : if (fHelp || params.size() > 1)
326 : throw runtime_error(
327 : "getblocktemplate ( \"jsonrequestobject\" )\n"
328 : "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
329 : "It returns data needed to construct a block to work on.\n"
330 : "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
331 :
332 : "\nArguments:\n"
333 : "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n"
334 : " {\n"
335 : " \"mode\":\"template\" (string, optional) This must be set to \"template\" or omitted\n"
336 : " \"capabilities\":[ (array, optional) A list of strings\n"
337 : " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
338 : " ,...\n"
339 : " ]\n"
340 : " }\n"
341 : "\n"
342 :
343 : "\nResult:\n"
344 : "{\n"
345 : " \"version\" : n, (numeric) The block version\n"
346 : " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n"
347 : " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n"
348 : " {\n"
349 : " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
350 : " \"hash\" : \"xxxx\", (string) hash/id encoded in little-endian hexadecimal\n"
351 : " \"depends\" : [ (array) array of numbers \n"
352 : " 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"
353 : " ,...\n"
354 : " ],\n"
355 : " \"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"
356 : " \"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"
357 : " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n"
358 : " }\n"
359 : " ,...\n"
360 : " ],\n"
361 : " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n"
362 : " \"flags\" : \"flags\" (string) \n"
363 : " },\n"
364 : " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
365 : " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n"
366 : " \"target\" : \"xxxx\", (string) The hash target\n"
367 : " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
368 : " \"mutable\" : [ (array of string) list of ways the block template may be changed \n"
369 : " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
370 : " ,...\n"
371 : " ],\n"
372 : " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n"
373 : " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n"
374 : " \"sizelimit\" : n, (numeric) limit of block size\n"
375 : " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
376 : " \"bits\" : \"xxx\", (string) compressed target of next block\n"
377 : " \"height\" : n (numeric) The height of the next block\n"
378 : "}\n"
379 :
380 : "\nExamples:\n"
381 0 : + HelpExampleCli("getblocktemplate", "")
382 0 : + HelpExampleRpc("getblocktemplate", "")
383 0 : );
384 :
385 0 : LOCK(cs_main);
386 :
387 0 : std::string strMode = "template";
388 0 : UniValue lpval = NullUniValue;
389 0 : if (params.size() > 0)
390 : {
391 0 : const UniValue& oparam = params[0].get_obj();
392 0 : const UniValue& modeval = find_value(oparam, "mode");
393 0 : if (modeval.isStr())
394 0 : strMode = modeval.get_str();
395 0 : else if (modeval.isNull())
396 : {
397 : /* Do nothing */
398 : }
399 : else
400 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
401 0 : lpval = find_value(oparam, "longpollid");
402 :
403 0 : if (strMode == "proposal")
404 : {
405 0 : const UniValue& dataval = find_value(oparam, "data");
406 0 : if (!dataval.isStr())
407 0 : throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
408 :
409 0 : CBlock block;
410 0 : if (!DecodeHexBlk(block, dataval.get_str()))
411 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
412 :
413 0 : uint256 hash = block.GetHash();
414 0 : BlockMap::iterator mi = mapBlockIndex.find(hash);
415 0 : if (mi != mapBlockIndex.end()) {
416 0 : CBlockIndex *pindex = mi->second;
417 0 : if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
418 0 : return "duplicate";
419 0 : if (pindex->nStatus & BLOCK_FAILED_MASK)
420 0 : return "duplicate-invalid";
421 0 : return "duplicate-inconclusive";
422 : }
423 :
424 0 : CBlockIndex* const pindexPrev = chainActive.Tip();
425 : // TestBlockValidity only supports blocks built on the current Tip
426 0 : if (block.hashPrevBlock != pindexPrev->GetBlockHash())
427 0 : return "inconclusive-not-best-prevblk";
428 0 : CValidationState state;
429 0 : TestBlockValidity(state, block, pindexPrev, false, true);
430 0 : return BIP22ValidationResult(state);
431 : }
432 : }
433 :
434 0 : if (strMode != "template")
435 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
436 :
437 0 : if (vNodes.empty())
438 0 : throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
439 :
440 0 : if (IsInitialBlockDownload())
441 0 : throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
442 :
443 : static unsigned int nTransactionsUpdatedLast;
444 :
445 0 : if (!lpval.isNull())
446 : {
447 : // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
448 : uint256 hashWatchedChain;
449 0 : boost::system_time checktxtime;
450 : unsigned int nTransactionsUpdatedLastLP;
451 :
452 0 : if (lpval.isStr())
453 : {
454 : // Format: <hashBestChain><nTransactionsUpdatedLast>
455 0 : std::string lpstr = lpval.get_str();
456 :
457 0 : hashWatchedChain.SetHex(lpstr.substr(0, 64));
458 0 : nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
459 : }
460 : else
461 : {
462 : // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
463 0 : hashWatchedChain = chainActive.Tip()->GetBlockHash();
464 0 : nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
465 : }
466 :
467 : // Release the wallet and main lock while waiting
468 : LEAVE_CRITICAL_SECTION(cs_main);
469 : {
470 0 : checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
471 :
472 : boost::unique_lock<boost::mutex> lock(csBestBlock);
473 0 : while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning())
474 : {
475 0 : if (!cvBlockChange.timed_wait(lock, checktxtime))
476 : {
477 : // Timeout: Check transactions for update
478 0 : if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
479 : break;
480 0 : checktxtime += boost::posix_time::seconds(10);
481 : }
482 : }
483 : }
484 : ENTER_CRITICAL_SECTION(cs_main);
485 :
486 0 : if (!IsRPCRunning())
487 0 : throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
488 : // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
489 : }
490 :
491 : // Update block
492 : static CBlockIndex* pindexPrev;
493 : static int64_t nStart;
494 : static CBlockTemplate* pblocktemplate;
495 0 : if (pindexPrev != chainActive.Tip() ||
496 0 : (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
497 : {
498 : // Clear pindexPrev so future calls make a new block, despite any failures from here on
499 0 : pindexPrev = NULL;
500 :
501 : // Store the pindexBest used before CreateNewBlock, to avoid races
502 0 : nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
503 0 : CBlockIndex* pindexPrevNew = chainActive.Tip();
504 0 : nStart = GetTime();
505 :
506 : // Create new block
507 0 : if(pblocktemplate)
508 : {
509 0 : delete pblocktemplate;
510 0 : pblocktemplate = NULL;
511 : }
512 0 : CScript scriptDummy = CScript() << OP_TRUE;
513 0 : pblocktemplate = CreateNewBlock(scriptDummy);
514 0 : if (!pblocktemplate)
515 0 : throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
516 :
517 : // Need to update only after we know CreateNewBlock succeeded
518 0 : pindexPrev = pindexPrevNew;
519 : }
520 0 : CBlock* pblock = &pblocktemplate->block; // pointer for convenience
521 :
522 : // Update nTime
523 0 : UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
524 0 : pblock->nNonce = 0;
525 :
526 0 : UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
527 :
528 0 : UniValue transactions(UniValue::VARR);
529 : map<uint256, int64_t> setTxIndex;
530 0 : int i = 0;
531 0 : BOOST_FOREACH (const CTransaction& tx, pblock->vtx) {
532 0 : uint256 txHash = tx.GetHash();
533 0 : setTxIndex[txHash] = i++;
534 :
535 0 : if (tx.IsCoinBase())
536 0 : continue;
537 :
538 0 : UniValue entry(UniValue::VOBJ);
539 :
540 0 : entry.push_back(Pair("data", EncodeHexTx(tx)));
541 :
542 0 : entry.push_back(Pair("hash", txHash.GetHex()));
543 :
544 0 : UniValue deps(UniValue::VARR);
545 0 : BOOST_FOREACH (const CTxIn &in, tx.vin)
546 : {
547 0 : if (setTxIndex.count(in.prevout.hash))
548 0 : deps.push_back(setTxIndex[in.prevout.hash]);
549 : }
550 0 : entry.push_back(Pair("depends", deps));
551 :
552 0 : int index_in_template = i - 1;
553 0 : entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
554 0 : entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
555 :
556 0 : transactions.push_back(entry);
557 0 : }
558 :
559 0 : UniValue aux(UniValue::VOBJ);
560 0 : aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
561 :
562 0 : arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
563 :
564 0 : static UniValue aMutable(UniValue::VARR);
565 0 : if (aMutable.empty())
566 : {
567 0 : aMutable.push_back("time");
568 0 : aMutable.push_back("transactions");
569 0 : aMutable.push_back("prevblock");
570 : }
571 :
572 0 : UniValue result(UniValue::VOBJ);
573 0 : result.push_back(Pair("capabilities", aCaps));
574 0 : result.push_back(Pair("version", pblock->nVersion));
575 0 : result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
576 0 : result.push_back(Pair("transactions", transactions));
577 0 : result.push_back(Pair("coinbaseaux", aux));
578 0 : result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
579 0 : result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
580 0 : result.push_back(Pair("target", hashTarget.GetHex()));
581 0 : result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
582 0 : result.push_back(Pair("mutable", aMutable));
583 0 : result.push_back(Pair("noncerange", "00000000ffffffff"));
584 0 : result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
585 0 : result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
586 0 : result.push_back(Pair("curtime", pblock->GetBlockTime()));
587 0 : result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
588 0 : result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
589 :
590 0 : return result;
591 : }
592 :
593 0 : class submitblock_StateCatcher : public CValidationInterface
594 : {
595 : public:
596 : uint256 hash;
597 : bool found;
598 : CValidationState state;
599 :
600 0 : submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {};
601 :
602 : protected:
603 0 : virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) {
604 0 : if (block.GetHash() != hash)
605 0 : return;
606 0 : found = true;
607 0 : state = stateIn;
608 : };
609 : };
610 :
611 0 : UniValue submitblock(const UniValue& params, bool fHelp)
612 : {
613 0 : if (fHelp || params.size() < 1 || params.size() > 2)
614 : throw runtime_error(
615 : "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
616 : "\nAttempts to submit new block to network.\n"
617 : "The 'jsonparametersobject' parameter is currently ignored.\n"
618 : "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
619 :
620 : "\nArguments\n"
621 : "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
622 : "2. \"jsonparametersobject\" (string, optional) object of optional parameters\n"
623 : " {\n"
624 : " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n"
625 : " }\n"
626 : "\nResult:\n"
627 : "\nExamples:\n"
628 0 : + HelpExampleCli("submitblock", "\"mydata\"")
629 0 : + HelpExampleRpc("submitblock", "\"mydata\"")
630 0 : );
631 :
632 0 : CBlock block;
633 0 : if (!DecodeHexBlk(block, params[0].get_str()))
634 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
635 :
636 0 : uint256 hash = block.GetHash();
637 0 : bool fBlockPresent = false;
638 : {
639 0 : LOCK(cs_main);
640 0 : BlockMap::iterator mi = mapBlockIndex.find(hash);
641 0 : if (mi != mapBlockIndex.end()) {
642 0 : CBlockIndex *pindex = mi->second;
643 0 : if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
644 0 : return "duplicate";
645 0 : if (pindex->nStatus & BLOCK_FAILED_MASK)
646 0 : return "duplicate-invalid";
647 : // Otherwise, we might only have the header - process the block before returning
648 : fBlockPresent = true;
649 : }
650 : }
651 :
652 0 : CValidationState state;
653 0 : submitblock_StateCatcher sc(block.GetHash());
654 0 : RegisterValidationInterface(&sc);
655 0 : bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL);
656 0 : UnregisterValidationInterface(&sc);
657 0 : if (fBlockPresent)
658 : {
659 0 : if (fAccepted && !sc.found)
660 0 : return "duplicate-inconclusive";
661 0 : return "duplicate";
662 : }
663 0 : if (fAccepted)
664 : {
665 0 : if (!sc.found)
666 0 : return "inconclusive";
667 0 : state = sc.state;
668 : }
669 0 : return BIP22ValidationResult(state);
670 : }
671 :
672 0 : UniValue estimatefee(const UniValue& params, bool fHelp)
673 : {
674 0 : if (fHelp || params.size() != 1)
675 : throw runtime_error(
676 : "estimatefee nblocks\n"
677 : "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
678 : "confirmation within nblocks blocks.\n"
679 : "\nArguments:\n"
680 : "1. nblocks (numeric)\n"
681 : "\nResult:\n"
682 : "n (numeric) estimated fee-per-kilobyte\n"
683 : "\n"
684 : "A negative value is returned if not enough transactions and blocks\n"
685 : "have been observed to make an estimate.\n"
686 : "\nExample:\n"
687 0 : + HelpExampleCli("estimatefee", "6")
688 0 : );
689 :
690 0 : RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
691 :
692 0 : int nBlocks = params[0].get_int();
693 0 : if (nBlocks < 1)
694 0 : nBlocks = 1;
695 :
696 0 : CFeeRate feeRate = mempool.estimateFee(nBlocks);
697 0 : if (feeRate == CFeeRate(0))
698 0 : return -1.0;
699 :
700 0 : return ValueFromAmount(feeRate.GetFeePerK());
701 : }
702 :
703 0 : UniValue estimatepriority(const UniValue& params, bool fHelp)
704 : {
705 0 : if (fHelp || params.size() != 1)
706 : throw runtime_error(
707 : "estimatepriority nblocks\n"
708 : "\nEstimates the approximate priority a zero-fee transaction needs to begin\n"
709 : "confirmation within nblocks blocks.\n"
710 : "\nArguments:\n"
711 : "1. nblocks (numeric)\n"
712 : "\nResult:\n"
713 : "n (numeric) estimated priority\n"
714 : "\n"
715 : "A negative value is returned if not enough transactions and blocks\n"
716 : "have been observed to make an estimate.\n"
717 : "\nExample:\n"
718 0 : + HelpExampleCli("estimatepriority", "6")
719 0 : );
720 :
721 0 : RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
722 :
723 0 : int nBlocks = params[0].get_int();
724 0 : if (nBlocks < 1)
725 0 : nBlocks = 1;
726 :
727 0 : return mempool.estimatePriority(nBlocks);
728 288 : }
|