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