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