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