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