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