]> Git Repo - VerusCoin.git/blame - src/rpcmining.cpp
Convert tree to using univalue. Eliminate all json_spirit uses.
[VerusCoin.git] / src / rpcmining.cpp
CommitLineData
7600e7fc 1// Copyright (c) 2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
72fb3d29 3// Distributed under the MIT software license, see the accompanying
7600e7fc
JG
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
eda37330 6#include "amount.h"
0e4b3175 7#include "chainparams.h"
691161d4 8#include "consensus/consensus.h"
da29ecbc 9#include "consensus/validation.h"
611116d4 10#include "core_io.h"
8e8b6d70 11#ifdef ENABLE_MINING
fdda3c50 12#include "crypto/equihash.h"
8e8b6d70 13#endif
7600e7fc 14#include "init.h"
51ed9ec9 15#include "main.h"
a6df7ab5 16#include "metrics.h"
d247a5d1 17#include "miner.h"
691161d4 18#include "net.h"
df852d2b 19#include "pow.h"
611116d4 20#include "rpcserver.h"
ad49c256 21#include "util.h"
cbb2cf55 22#include "validationinterface.h"
df840de5 23#ifdef ENABLE_WALLET
50c72f23 24#include "wallet/wallet.h"
df840de5 25#endif
ac14bcc1 26
51ed9ec9
BD
27#include <stdint.h>
28
171ca774 29#include <boost/assign/list_of.hpp>
ac14bcc1 30
ed21d5bd 31#include "json_spirit_wrapper.h"
7600e7fc
JG
32
33using namespace json_spirit;
34using namespace std;
35
72fb3d29
MF
36/**
37 * Return average network hashes per second based on the last 'lookup' blocks,
f2c48e15 38 * or over the difficulty averaging window if 'lookup' is nonpositive.
72fb3d29
MF
39 * If 'height' is nonnegative, compute the estimate at the time when a given block was found.
40 */
eb5b582e 41int64_t GetNetworkHashPS(int lookup, int height) {
aec55a07
GM
42 CBlockIndex *pb = chainActive.Tip();
43
44 if (height >= 0 && height < chainActive.Height())
45 pb = chainActive[height];
d64eef48 46
47 if (pb == NULL || !pb->nHeight)
48 return 0;
49
5e207f4e 50 // If lookup is nonpositive, then use difficulty averaging window.
d64eef48 51 if (lookup <= 0)
cdec0b92 52 lookup = Params().GetConsensus().nPowAveragingWindow;
f2c48e15 53
cdec0b92
JG
54 // If lookup is larger than chain, then set it to chain length.
55 if (lookup > pb->nHeight)
d64eef48 56 lookup = pb->nHeight;
57
58 CBlockIndex *pb0 = pb;
51ed9ec9
BD
59 int64_t minTime = pb0->GetBlockTime();
60 int64_t maxTime = minTime;
d64eef48 61 for (int i = 0; i < lookup; i++) {
62 pb0 = pb0->pprev;
51ed9ec9 63 int64_t time = pb0->GetBlockTime();
d64eef48 64 minTime = std::min(time, minTime);
65 maxTime = std::max(time, maxTime);
66 }
67
68 // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
69 if (minTime == maxTime)
70 return 0;
71
734f85c4 72 arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
51ed9ec9 73 int64_t timeDiff = maxTime - minTime;
d64eef48 74
4b61a6a4 75 return (int64_t)(workDiff.getdouble() / timeDiff);
d64eef48 76}
77
000499ae
JG
78Value getlocalsolps(const Array& params, bool fHelp)
79{
80 if (fHelp)
81 throw runtime_error(
82 "getlocalsolps\n"
83 "\nReturns the average local solutions per second since this node was started.\n"
84 "This is the same information shown on the metrics screen (if enabled).\n"
85 "\nResult:\n"
86 "xxx.xxxxx (numeric) Solutions per second average\n"
87 "\nExamples:\n"
88 + HelpExampleCli("getlocalsolps", "")
89 + HelpExampleRpc("getlocalsolps", "")
90 );
91
92 LOCK(cs_main);
93 return GetLocalSolPS();
94}
95
96Value getnetworksolps(const Array& params, bool fHelp)
97{
98 if (fHelp || params.size() > 2)
99 throw runtime_error(
100 "getnetworksolps ( blocks height )\n"
101 "\nReturns the estimated network solutions per second based on the last n blocks.\n"
102 "Pass in [blocks] to override # of blocks, -1 specifies over difficulty averaging window.\n"
103 "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
104 "\nArguments:\n"
105 "1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks over difficulty averaging window.\n"
106 "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
107 "\nResult:\n"
108 "x (numeric) Solutions per second estimated\n"
109 "\nExamples:\n"
110 + HelpExampleCli("getnetworksolps", "")
111 + HelpExampleRpc("getnetworksolps", "")
112 );
113
114 LOCK(cs_main);
115 return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
116}
117
d64eef48 118Value getnetworkhashps(const Array& params, bool fHelp)
119{
120 if (fHelp || params.size() > 2)
121 throw runtime_error(
a6099ef3 122 "getnetworkhashps ( blocks height )\n"
000499ae
JG
123 "\nDEPRECATED - left for backwards-compatibility. Use getnetworksolps instead.\n"
124 "\nReturns the estimated network solutions per second based on the last n blocks.\n"
f2c48e15 125 "Pass in [blocks] to override # of blocks, -1 specifies over difficulty averaging window.\n"
a6099ef3 126 "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
127 "\nArguments:\n"
f2c48e15 128 "1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks over difficulty averaging window.\n"
a6099ef3 129 "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
130 "\nResult:\n"
000499ae 131 "x (numeric) Solutions per second estimated\n"
a6099ef3 132 "\nExamples:\n"
133 + HelpExampleCli("getnetworkhashps", "")
134 + HelpExampleRpc("getnetworkhashps", "")
135 );
d64eef48 136
4401b2d7 137 LOCK(cs_main);
d64eef48 138 return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
139}
140
8e8b6d70 141#ifdef ENABLE_MINING
7600e7fc
JG
142Value getgenerate(const Array& params, bool fHelp)
143{
144 if (fHelp || params.size() != 0)
145 throw runtime_error(
146 "getgenerate\n"
a6099ef3 147 "\nReturn if the server is set to generate coins or not. The default is false.\n"
aaf64959 148 "It is set with the command line argument -gen (or zcash.conf setting gen)\n"
a6099ef3 149 "It can also be set with the setgenerate call.\n"
150 "\nResult\n"
151 "true|false (boolean) If the server is set to generate coins or not\n"
152 "\nExamples:\n"
153 + HelpExampleCli("getgenerate", "")
154 + HelpExampleRpc("getgenerate", "")
155 );
7600e7fc 156
4401b2d7 157 LOCK(cs_main);
3260b4c0 158 return GetBoolArg("-gen", false);
7600e7fc
JG
159}
160
6b04508e
PW
161Value generate(const Array& params, bool fHelp)
162{
163 if (fHelp || params.size() < 1 || params.size() > 1)
164 throw runtime_error(
165 "generate numblocks\n"
166 "\nMine blocks immediately (before the RPC call returns)\n"
48265f3c 167 "\nNote: this function can only be used on the regtest network\n"
a33cd5ba 168 "\nArguments:\n"
6b04508e
PW
169 "1. numblocks (numeric) How many blocks are generated immediately.\n"
170 "\nResult\n"
171 "[ blockhashes ] (array) hashes of blocks generated\n"
172 "\nExamples:\n"
173 "\nGenerate 11 blocks\n"
174 + HelpExampleCli("generate", "11")
175 );
176
8e8b6d70
JG
177 if (GetArg("-mineraddress", "").empty()) {
178#ifdef ENABLE_WALLET
179 if (!pwalletMain) {
180 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
181 }
182#else
183 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set");
184#endif
185 }
48265f3c
WL
186 if (!Params().MineBlocksOnDemand())
187 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
6b04508e
PW
188
189 int nHeightStart = 0;
190 int nHeightEnd = 0;
191 int nHeight = 0;
192 int nGenerate = params[0].get_int();
8e8b6d70 193#ifdef ENABLE_WALLET
48265f3c 194 CReserveKey reservekey(pwalletMain);
8e8b6d70 195#endif
6b04508e
PW
196
197 { // Don't keep cs_main locked
198 LOCK(cs_main);
199 nHeightStart = chainActive.Height();
200 nHeight = nHeightStart;
201 nHeightEnd = nHeightStart+nGenerate;
202 }
48265f3c 203 unsigned int nExtraNonce = 0;
6b04508e 204 Array blockHashes;
e9574728
JG
205 unsigned int n = Params().EquihashN();
206 unsigned int k = Params().EquihashK();
48265f3c
WL
207 while (nHeight < nHeightEnd)
208 {
8e8b6d70 209#ifdef ENABLE_WALLET
4dddc096 210 unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
8e8b6d70
JG
211#else
212 unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
213#endif
48265f3c 214 if (!pblocktemplate.get())
6b04508e 215 throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
48265f3c
WL
216 CBlock *pblock = &pblocktemplate->block;
217 {
218 LOCK(cs_main);
219 IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
220 }
fdda3c50
JG
221
222 // Hash state
223 crypto_generichash_blake2b_state eh_state;
e9574728 224 EhInitialiseState(n, k, eh_state);
fdda3c50
JG
225
226 // I = the block header minus nonce and solution.
227 CEquihashInput I{*pblock};
228 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
229 ss << I;
230
231 // H(I||...
232 crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size());
233
234 while (true) {
48265f3c 235 // Yes, there is a chance every nonce could fail to satisfy the -regtest
fdda3c50
JG
236 // target -- 1 in 2^(2^256). That ain't gonna happen
237 pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
238
239 // H(I||V||...
240 crypto_generichash_blake2b_state curr_state;
241 curr_state = eh_state;
242 crypto_generichash_blake2b_update(&curr_state,
243 pblock->nNonce.begin(),
244 pblock->nNonce.size());
245
246 // (x_1, x_2, ...) = A(I, V, n, k)
5be6abbf
JG
247 std::function<bool(std::vector<unsigned char>)> validBlock =
248 [&pblock](std::vector<unsigned char> soln) {
fdda3c50 249 pblock->nSolution = soln;
e7d59bbc 250 solutionTargetChecks.increment();
51eb5273
JG
251 return CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus());
252 };
a6df7ab5
JG
253 bool found = EhBasicSolveUncancellable(n, k, curr_state, validBlock);
254 ehSolverRuns.increment();
255 if (found) {
51eb5273 256 goto endloop;
a6df7ab5 257 }
48265f3c 258 }
fdda3c50 259endloop:
48265f3c 260 CValidationState state;
304892fc 261 if (!ProcessNewBlock(state, NULL, pblock, true, NULL))
48265f3c 262 throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
6b04508e 263 ++nHeight;
48265f3c 264 blockHashes.push_back(pblock->GetHash().GetHex());
6b04508e
PW
265 }
266 return blockHashes;
267}
7600e7fc 268
48265f3c 269
7600e7fc
JG
270Value setgenerate(const Array& params, bool fHelp)
271{
272 if (fHelp || params.size() < 1 || params.size() > 2)
273 throw runtime_error(
a6099ef3 274 "setgenerate generate ( genproclimit )\n"
275 "\nSet 'generate' true or false to turn generation on or off.\n"
276 "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n"
277 "See the getgenerate call for the current setting.\n"
278 "\nArguments:\n"
279 "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n"
280 "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
281 "\nExamples:\n"
282 "\nSet the generation on with a limit of one processor\n"
283 + HelpExampleCli("setgenerate", "true 1") +
284 "\nCheck the setting\n"
285 + HelpExampleCli("getgenerate", "") +
286 "\nTurn off generation\n"
287 + HelpExampleCli("setgenerate", "false") +
288 "\nUsing json rpc\n"
289 + HelpExampleRpc("setgenerate", "true, 1")
290 );
7600e7fc 291
8e8b6d70
JG
292 if (GetArg("-mineraddress", "").empty()) {
293#ifdef ENABLE_WALLET
294 if (!pwalletMain) {
295 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
296 }
297#else
298 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set");
299#endif
300 }
27ce808f
WL
301 if (Params().MineBlocksOnDemand())
302 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
c8b74258 303
7600e7fc
JG
304 bool fGenerate = true;
305 if (params.size() > 0)
306 fGenerate = params[0].get_bool();
307
c8b74258 308 int nGenProcLimit = -1;
7600e7fc
JG
309 if (params.size() > 1)
310 {
c8b74258 311 nGenProcLimit = params[1].get_int();
7600e7fc
JG
312 if (nGenProcLimit == 0)
313 fGenerate = false;
314 }
7600e7fc 315
6b04508e
PW
316 mapArgs["-gen"] = (fGenerate ? "1" : "0");
317 mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
8e8b6d70 318#ifdef ENABLE_WALLET
6b04508e 319 GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
8e8b6d70
JG
320#else
321 GenerateBitcoins(fGenerate, nGenProcLimit);
322#endif
c8b74258 323
ed21d5bd 324 return NullUniValue;
7600e7fc 325}
4a85e067 326#endif
7600e7fc
JG
327
328
329Value getmininginfo(const Array& params, bool fHelp)
330{
331 if (fHelp || params.size() != 0)
332 throw runtime_error(
333 "getmininginfo\n"
a6099ef3 334 "\nReturns a json object containing mining-related information."
335 "\nResult:\n"
336 "{\n"
337 " \"blocks\": nnn, (numeric) The current block\n"
338 " \"currentblocksize\": nnn, (numeric) The last block size\n"
339 " \"currentblocktx\": nnn, (numeric) The last block transaction\n"
340 " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
341 " \"errors\": \"...\" (string) Current errors\n"
342 " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
343 " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
000499ae
JG
344 " \"localsolps\": xxx.xxxxx (numeric) The average local solution rate in Sol/s since this node was started\n"
345 " \"networksolps\": x (numeric) The estimated network solution rate in Sol/s\n"
a6099ef3 346 " \"pooledtx\": n (numeric) The size of the mem pool\n"
347 " \"testnet\": true|false (boolean) If using testnet or not\n"
f6984e81 348 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
a6099ef3 349 "}\n"
350 "\nExamples:\n"
351 + HelpExampleCli("getmininginfo", "")
352 + HelpExampleRpc("getmininginfo", "")
353 );
7600e7fc 354
4401b2d7
EL
355
356 LOCK(cs_main);
357
7600e7fc 358 Object obj;
4c6d41b8 359 obj.push_back(Pair("blocks", (int)chainActive.Height()));
3260b4c0
PK
360 obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
361 obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
695a7a88 362 obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
3260b4c0 363 obj.push_back(Pair("errors", GetWarnings("statusbar")));
3260b4c0 364 obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
000499ae
JG
365 obj.push_back(Pair("localsolps" , getlocalsolps(params, false)));
366 obj.push_back(Pair("networksolps", getnetworksolps(params, false)));
367 obj.push_back(Pair("networkhashps", getnetworksolps(params, false)));
3260b4c0 368 obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
cc972107 369 obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
f6984e81 370 obj.push_back(Pair("chain", Params().NetworkIDString()));
8e8b6d70 371#ifdef ENABLE_MINING
4a85e067 372 obj.push_back(Pair("generate", getgenerate(params, false)));
4a85e067 373#endif
7600e7fc
JG
374 return obj;
375}
376
377
8a20cd3c 378// NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
2a72d459
LD
379Value prioritisetransaction(const Array& params, bool fHelp)
380{
381 if (fHelp || params.size() != 3)
382 throw runtime_error(
383 "prioritisetransaction <txid> <priority delta> <fee delta>\n"
ebdcc360
CL
384 "Accepts the transaction into mined blocks at a higher (or lower) priority\n"
385 "\nArguments:\n"
386 "1. \"txid\" (string, required) The transaction id.\n"
387 "2. priority delta (numeric, required) The priority to add or subtract.\n"
388 " The transaction selection algorithm considers the tx as it would have a higher priority.\n"
389 " (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n"
8a20cd3c 390 "3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
ebdcc360
CL
391 " The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
392 " considers the transaction as it would have paid a higher (or lower) fee.\n"
393 "\nResult\n"
394 "true (boolean) Returns true\n"
395 "\nExamples:\n"
8a20cd3c
LD
396 + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
397 + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
ebdcc360 398 );
2a72d459 399
4401b2d7 400 LOCK(cs_main);
ebdcc360 401
4401b2d7 402 uint256 hash = ParseHashStr(params[0].get_str(), "txid");
8a20cd3c 403 CAmount nAmount = params[2].get_int64();
ebdcc360
CL
404
405 mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
2a72d459
LD
406 return true;
407}
408
409
3dcbb9b6
LD
410// NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
411static Value BIP22ValidationResult(const CValidationState& state)
412{
413 if (state.IsValid())
414 return Value::null;
415
416 std::string strRejectReason = state.GetRejectReason();
417 if (state.IsError())
418 throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason);
419 if (state.IsInvalid())
420 {
421 if (strRejectReason.empty())
422 return "rejected";
423 return strRejectReason;
424 }
425 // Should be impossible
426 return "valid?";
427}
428
7600e7fc
JG
429Value getblocktemplate(const Array& params, bool fHelp)
430{
3beac983 431 if (fHelp || params.size() > 1)
7600e7fc 432 throw runtime_error(
a6099ef3 433 "getblocktemplate ( \"jsonrequestobject\" )\n"
434 "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
435 "It returns data needed to construct a block to work on.\n"
436 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
437
438 "\nArguments:\n"
439 "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n"
440 " {\n"
441 " \"mode\":\"template\" (string, optional) This must be set to \"template\" or omitted\n"
442 " \"capabilities\":[ (array, optional) A list of strings\n"
443 " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
444 " ,...\n"
445 " ]\n"
446 " }\n"
447 "\n"
448
449 "\nResult:\n"
450 "{\n"
451 " \"version\" : n, (numeric) The block version\n"
452 " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n"
453 " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n"
454 " {\n"
455 " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
456 " \"hash\" : \"xxxx\", (string) hash/id encoded in little-endian hexadecimal\n"
457 " \"depends\" : [ (array) array of numbers \n"
458 " 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"
459 " ,...\n"
460 " ],\n"
461 " \"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"
462 " \"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"
463 " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n"
464 " }\n"
465 " ,...\n"
466 " ],\n"
53ddbaed
JG
467// " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n"
468// " \"flags\" : \"flags\" (string) \n"
469// " },\n"
470// " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
a6099ef3 471 " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n"
472 " \"target\" : \"xxxx\", (string) The hash target\n"
473 " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
474 " \"mutable\" : [ (array of string) list of ways the block template may be changed \n"
475 " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
476 " ,...\n"
477 " ],\n"
478 " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n"
479 " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n"
480 " \"sizelimit\" : n, (numeric) limit of block size\n"
481 " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
482 " \"bits\" : \"xxx\", (string) compressed target of next block\n"
483 " \"height\" : n (numeric) The height of the next block\n"
484 "}\n"
485
486 "\nExamples:\n"
487 + HelpExampleCli("getblocktemplate", "")
488 + HelpExampleRpc("getblocktemplate", "")
489 );
7600e7fc 490
4401b2d7
EL
491 LOCK(cs_main);
492
8e8b6d70
JG
493 // Wallet or miner address is required because we support coinbasetxn
494 if (GetArg("-mineraddress", "").empty()) {
2cc0a252 495#ifdef ENABLE_WALLET
8e8b6d70
JG
496 if (!pwalletMain) {
497 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
498 }
499#else
500 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set");
501#endif
53ddbaed
JG
502 }
503
7600e7fc 504 std::string strMode = "template";
ed21d5bd 505 Value lpval = NullUniValue;
53ddbaed
JG
506 // TODO: Re-enable coinbasevalue once a specification has been written
507 bool coinbasetxn = true;
7600e7fc
JG
508 if (params.size() > 0)
509 {
510 const Object& oparam = params[0].get_obj();
511 const Value& modeval = find_value(oparam, "mode");
ed21d5bd 512 if (modeval.isStr())
7600e7fc 513 strMode = modeval.get_str();
ed21d5bd 514 else if (modeval.isNull())
0689a7eb
LD
515 {
516 /* Do nothing */
517 }
7600e7fc 518 else
738835d7 519 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
ff6a7af1 520 lpval = find_value(oparam, "longpollid");
9765a50c
LD
521
522 if (strMode == "proposal")
523 {
524 const Value& dataval = find_value(oparam, "data");
525 if (dataval.type() != str_type)
526 throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
527
528 CBlock block;
529 if (!DecodeHexBlk(block, dataval.get_str()))
530 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
531
532 uint256 hash = block.GetHash();
533 BlockMap::iterator mi = mapBlockIndex.find(hash);
534 if (mi != mapBlockIndex.end()) {
535 CBlockIndex *pindex = mi->second;
536 if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
537 return "duplicate";
538 if (pindex->nStatus & BLOCK_FAILED_MASK)
539 return "duplicate-invalid";
540 return "duplicate-inconclusive";
541 }
542
543 CBlockIndex* const pindexPrev = chainActive.Tip();
544 // TestBlockValidity only supports blocks built on the current Tip
545 if (block.hashPrevBlock != pindexPrev->GetBlockHash())
546 return "inconclusive-not-best-prevblk";
547 CValidationState state;
548 TestBlockValidity(state, block, pindexPrev, false, true);
549 return BIP22ValidationResult(state);
550 }
7600e7fc
JG
551 }
552
553 if (strMode != "template")
738835d7 554 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
7600e7fc
JG
555
556 if (vNodes.empty())
59ac34e3 557 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Zcash is not connected!");
7600e7fc
JG
558
559 if (IsInitialBlockDownload())
59ac34e3 560 throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Zcash is downloading blocks...");
7600e7fc 561
7600e7fc 562 static unsigned int nTransactionsUpdatedLast;
ff6a7af1 563
ed21d5bd 564 if (!lpval.isNull())
ff6a7af1
LD
565 {
566 // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
567 uint256 hashWatchedChain;
568 boost::system_time checktxtime;
569 unsigned int nTransactionsUpdatedLastLP;
570
ed21d5bd 571 if (lpval.isStr())
ff6a7af1
LD
572 {
573 // Format: <hashBestChain><nTransactionsUpdatedLast>
574 std::string lpstr = lpval.get_str();
575
576 hashWatchedChain.SetHex(lpstr.substr(0, 64));
577 nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
578 }
579 else
580 {
581 // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
582 hashWatchedChain = chainActive.Tip()->GetBlockHash();
583 nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
584 }
585
586 // Release the wallet and main lock while waiting
ff6a7af1
LD
587 LEAVE_CRITICAL_SECTION(cs_main);
588 {
589 checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
590
591 boost::unique_lock<boost::mutex> lock(csBestBlock);
592 while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning())
593 {
594 if (!cvBlockChange.timed_wait(lock, checktxtime))
595 {
596 // Timeout: Check transactions for update
597 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
598 break;
599 checktxtime += boost::posix_time::seconds(10);
600 }
601 }
602 }
603 ENTER_CRITICAL_SECTION(cs_main);
ff6a7af1
LD
604
605 if (!IsRPCRunning())
606 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
607 // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
608 }
609
610 // Update block
7600e7fc 611 static CBlockIndex* pindexPrev;
51ed9ec9 612 static int64_t nStart;
03cac0bb 613 static CBlockTemplate* pblocktemplate;
4c6d41b8 614 if (pindexPrev != chainActive.Tip() ||
319b1160 615 (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
7600e7fc
JG
616 {
617 // Clear pindexPrev so future calls make a new block, despite any failures from here on
618 pindexPrev = NULL;
619
53ddbaed 620 // Store the pindexBest used before CreateNewBlockWithKey, to avoid races
319b1160 621 nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
48265f3c 622 CBlockIndex* pindexPrevNew = chainActive.Tip();
7600e7fc
JG
623 nStart = GetTime();
624
625 // Create new block
03cac0bb 626 if(pblocktemplate)
7600e7fc 627 {
03cac0bb
FV
628 delete pblocktemplate;
629 pblocktemplate = NULL;
7600e7fc 630 }
8e8b6d70 631#ifdef ENABLE_WALLET
53ddbaed
JG
632 CReserveKey reservekey(pwalletMain);
633 pblocktemplate = CreateNewBlockWithKey(reservekey);
8e8b6d70
JG
634#else
635 pblocktemplate = CreateNewBlockWithKey();
636#endif
03cac0bb 637 if (!pblocktemplate)
738835d7 638 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
7600e7fc 639
53ddbaed 640 // Need to update only after we know CreateNewBlockWithKey succeeded
7600e7fc
JG
641 pindexPrev = pindexPrevNew;
642 }
03cac0bb 643 CBlock* pblock = &pblocktemplate->block; // pointer for convenience
7600e7fc
JG
644
645 // Update nTime
bebe7282 646 UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
fdda3c50 647 pblock->nNonce = uint256();
7600e7fc 648
9765a50c
LD
649 static const Array aCaps = boost::assign::list_of("proposal");
650
53ddbaed 651 Value txCoinbase = Value::null;
7600e7fc
JG
652 Array transactions;
653 map<uint256, int64_t> setTxIndex;
654 int i = 0;
7600e7fc
JG
655 BOOST_FOREACH (CTransaction& tx, pblock->vtx)
656 {
805344dc 657 uint256 txHash = tx.GetHash();
7600e7fc
JG
658 setTxIndex[txHash] = i++;
659
53ddbaed 660 if (tx.IsCoinBase() && !coinbasetxn)
7600e7fc
JG
661 continue;
662
663 Object entry;
664
ae775b5b 665 entry.push_back(Pair("data", EncodeHexTx(tx)));
7600e7fc
JG
666
667 entry.push_back(Pair("hash", txHash.GetHex()));
668
450cbb09
PW
669 Array deps;
670 BOOST_FOREACH (const CTxIn &in, tx.vin)
7600e7fc 671 {
450cbb09
PW
672 if (setTxIndex.count(in.prevout.hash))
673 deps.push_back(setTxIndex[in.prevout.hash]);
674 }
675 entry.push_back(Pair("depends", deps));
7600e7fc 676
ba1d0800 677 int index_in_template = i - 1;
f3d872d1
FV
678 entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
679 entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
7600e7fc 680
53ddbaed 681 if (tx.IsCoinBase()) {
89aa746c
JG
682 // Show founders' reward if it is required
683 if (pblock->vtx[0].vout.size() > 1) {
684 // Correct this if GetBlockTemplate changes the order
685 entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue));
686 }
53ddbaed
JG
687 entry.push_back(Pair("required", true));
688 txCoinbase = entry;
689 } else {
690 transactions.push_back(entry);
691 }
7600e7fc
JG
692 }
693
694 Object aux;
695 aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
696
734f85c4 697 arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
7600e7fc
JG
698
699 static Array aMutable;
700 if (aMutable.empty())
701 {
702 aMutable.push_back("time");
703 aMutable.push_back("transactions");
704 aMutable.push_back("prevblock");
705 }
706
707 Object result;
9765a50c 708 result.push_back(Pair("capabilities", aCaps));
7600e7fc
JG
709 result.push_back(Pair("version", pblock->nVersion));
710 result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
711 result.push_back(Pair("transactions", transactions));
53ddbaed
JG
712 if (coinbasetxn) {
713 assert(txCoinbase.type() == obj_type);
714 result.push_back(Pair("coinbasetxn", txCoinbase));
715 } else {
716 result.push_back(Pair("coinbaseaux", aux));
717 result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
718 }
ff6a7af1 719 result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
7600e7fc
JG
720 result.push_back(Pair("target", hashTarget.GetHex()));
721 result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
722 result.push_back(Pair("mutable", aMutable));
723 result.push_back(Pair("noncerange", "00000000ffffffff"));
724 result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
725 result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
209377a7 726 result.push_back(Pair("curtime", pblock->GetBlockTime()));
645d497a 727 result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
7600e7fc
JG
728 result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
729
730 return result;
731}
732
f877aaaf
LD
733class submitblock_StateCatcher : public CValidationInterface
734{
735public:
736 uint256 hash;
737 bool found;
738 CValidationState state;
739
740 submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {};
741
742protected:
743 virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) {
744 if (block.GetHash() != hash)
745 return;
746 found = true;
747 state = stateIn;
748 };
749};
750
7600e7fc
JG
751Value submitblock(const Array& params, bool fHelp)
752{
753 if (fHelp || params.size() < 1 || params.size() > 2)
754 throw runtime_error(
a6099ef3 755 "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
756 "\nAttempts to submit new block to network.\n"
757 "The 'jsonparametersobject' parameter is currently ignored.\n"
758 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
759
760 "\nArguments\n"
761 "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
762 "2. \"jsonparametersobject\" (string, optional) object of optional parameters\n"
763 " {\n"
764 " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n"
765 " }\n"
766 "\nResult:\n"
767 "\nExamples:\n"
768 + HelpExampleCli("submitblock", "\"mydata\"")
769 + HelpExampleRpc("submitblock", "\"mydata\"")
770 );
7600e7fc 771
60755dbf
LD
772 CBlock block;
773 if (!DecodeHexBlk(block, params[0].get_str()))
738835d7 774 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
7600e7fc 775
60755dbf 776 uint256 hash = block.GetHash();
eb63bf86
MC
777 bool fBlockPresent = false;
778 {
779 LOCK(cs_main);
780 BlockMap::iterator mi = mapBlockIndex.find(hash);
781 if (mi != mapBlockIndex.end()) {
782 CBlockIndex *pindex = mi->second;
783 if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
784 return "duplicate";
785 if (pindex->nStatus & BLOCK_FAILED_MASK)
786 return "duplicate-invalid";
787 // Otherwise, we might only have the header - process the block before returning
788 fBlockPresent = true;
789 }
7600e7fc
JG
790 }
791
ef3988ca 792 CValidationState state;
60755dbf 793 submitblock_StateCatcher sc(block.GetHash());
f877aaaf 794 RegisterValidationInterface(&sc);
304892fc 795 bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL);
f877aaaf 796 UnregisterValidationInterface(&sc);
eb63bf86 797 if (fBlockPresent)
60755dbf
LD
798 {
799 if (fAccepted && !sc.found)
800 return "duplicate-inconclusive";
801 return "duplicate";
802 }
f877aaaf
LD
803 if (fAccepted)
804 {
805 if (!sc.found)
806 return "inconclusive";
807 state = sc.state;
808 }
3dcbb9b6 809 return BIP22ValidationResult(state);
7600e7fc 810}
171ca774
GA
811
812Value estimatefee(const Array& params, bool fHelp)
813{
814 if (fHelp || params.size() != 1)
815 throw runtime_error(
816 "estimatefee nblocks\n"
817 "\nEstimates the approximate fee per kilobyte\n"
a15dba5d 818 "needed for a transaction to begin confirmation\n"
171ca774
GA
819 "within nblocks blocks.\n"
820 "\nArguments:\n"
821 "1. nblocks (numeric)\n"
822 "\nResult:\n"
823 "n : (numeric) estimated fee-per-kilobyte\n"
824 "\n"
825 "-1.0 is returned if not enough transactions and\n"
826 "blocks have been observed to make an estimate.\n"
827 "\nExample:\n"
828 + HelpExampleCli("estimatefee", "6")
829 );
830
ed21d5bd 831 RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
171ca774
GA
832
833 int nBlocks = params[0].get_int();
834 if (nBlocks < 1)
835 nBlocks = 1;
836
837 CFeeRate feeRate = mempool.estimateFee(nBlocks);
838 if (feeRate == CFeeRate(0))
839 return -1.0;
840
841 return ValueFromAmount(feeRate.GetFeePerK());
842}
843
844Value estimatepriority(const Array& params, bool fHelp)
845{
846 if (fHelp || params.size() != 1)
847 throw runtime_error(
848 "estimatepriority nblocks\n"
849 "\nEstimates the approximate priority\n"
a15dba5d 850 "a zero-fee transaction needs to begin confirmation\n"
171ca774
GA
851 "within nblocks blocks.\n"
852 "\nArguments:\n"
853 "1. nblocks (numeric)\n"
854 "\nResult:\n"
855 "n : (numeric) estimated priority\n"
856 "\n"
857 "-1.0 is returned if not enough transactions and\n"
858 "blocks have been observed to make an estimate.\n"
859 "\nExample:\n"
860 + HelpExampleCli("estimatepriority", "6")
861 );
862
ed21d5bd 863 RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
171ca774
GA
864
865 int nBlocks = params[0].get_int();
866 if (nBlocks < 1)
867 nBlocks = 1;
868
869 return mempool.estimatePriority(nBlocks);
870}
1b114e54
S
871
872Value getblocksubsidy(const Array& params, bool fHelp)
873{
5d50130b 874 if (fHelp || params.size() > 1)
1b114e54 875 throw runtime_error(
1db13d50 876 "getblocksubsidy height\n"
ea26d328 877 "\nReturns block subsidy reward, taking into account the mining slow start and the founders reward, of block at index provided.\n"
1b114e54 878 "\nArguments:\n"
5d50130b 879 "1. height (numeric, optional) The block height. If not provided, defaults to the current height of the chain.\n"
1b114e54 880 "\nResult:\n"
ea26d328
S
881 "{\n"
882 " \"miner\" : x.xxx (numeric) The mining reward amount in ZEC.\n"
883 " \"founders\" : x.xxx (numeric) The founders reward amount in ZEC.\n"
884 "}\n"
1b114e54
S
885 "\nExamples:\n"
886 + HelpExampleCli("getblocksubsidy", "1000")
887 + HelpExampleRpc("getblockubsidy", "1000")
888 );
889
933bff47 890 LOCK(cs_main);
5d50130b
S
891 int nHeight = (params.size()==1) ? params[0].get_int() : chainActive.Height();
892 if (nHeight < 0)
1b114e54
S
893 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
894
895 CAmount nReward = GetBlockSubsidy(nHeight, Params().GetConsensus());
ea26d328 896 CAmount nFoundersReward = 0;
db0f9315 897 if ((nHeight > 0) && (nHeight <= Params().GetConsensus().GetLastFoundersRewardBlockHeight())) {
ea26d328
S
898 nFoundersReward = nReward/5;
899 nReward -= nFoundersReward;
900 }
901 Object result;
902 result.push_back(Pair("miner", ValueFromAmount(nReward)));
903 result.push_back(Pair("founders", ValueFromAmount(nFoundersReward)));
904 return result;
1b114e54 905}
This page took 0.348945 seconds and 4 git commands to generate.