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