]> Git Repo - VerusCoin.git/blob - src/rpcmining.cpp
Merge pull request #3246 from laanwj/2013_11_rpc_help
[VerusCoin.git] / src / rpcmining.cpp
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2013 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "bitcoinrpc.h"
7 #include "chainparams.h"
8 #include "db.h"
9 #include "init.h"
10 #include "net.h"
11 #include "main.h"
12 #include "miner.h"
13 #include "wallet.h"
14
15 #include <stdint.h>
16
17 #include "json/json_spirit_utils.h"
18 #include "json/json_spirit_value.h"
19
20 using namespace json_spirit;
21 using namespace std;
22
23 // Key used by getwork/getblocktemplate miners.
24 // Allocated in InitRPCMining, free'd in ShutdownRPCMining
25 static CReserveKey* pMiningKey = NULL;
26
27 void InitRPCMining()
28 {
29     if (!pwalletMain)
30         return;
31
32     // getwork/getblocktemplate mining rewards paid here:
33     pMiningKey = new CReserveKey(pwalletMain);
34 }
35
36 void ShutdownRPCMining()
37 {
38     if (!pMiningKey)
39         return;
40
41     delete pMiningKey; pMiningKey = NULL;
42 }
43
44 // Return average network hashes per second based on the last 'lookup' blocks,
45 // or from the last difficulty change if 'lookup' is nonpositive.
46 // If 'height' is nonnegative, compute the estimate at the time when a given block was found.
47 Value GetNetworkHashPS(int lookup, int height) {
48     CBlockIndex *pb = chainActive[height];
49
50     if (pb == NULL || !pb->nHeight)
51         return 0;
52
53     // If lookup is -1, then use blocks since last difficulty change.
54     if (lookup <= 0)
55         lookup = pb->nHeight % 2016 + 1;
56
57     // If lookup is larger than chain, then set it to chain length.
58     if (lookup > pb->nHeight)
59         lookup = pb->nHeight;
60
61     CBlockIndex *pb0 = pb;
62     int64_t minTime = pb0->GetBlockTime();
63     int64_t maxTime = minTime;
64     for (int i = 0; i < lookup; i++) {
65         pb0 = pb0->pprev;
66         int64_t time = pb0->GetBlockTime();
67         minTime = std::min(time, minTime);
68         maxTime = std::max(time, maxTime);
69     }
70
71     // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
72     if (minTime == maxTime)
73         return 0;
74
75     uint256 workDiff = pb->nChainWork - pb0->nChainWork;
76     int64_t timeDiff = maxTime - minTime;
77
78     return (boost::int64_t)(workDiff.getdouble() / timeDiff);
79 }
80
81 Value getnetworkhashps(const Array& params, bool fHelp)
82 {
83     if (fHelp || params.size() > 2)
84         throw runtime_error(
85             "getnetworkhashps ( blocks height )\n"
86             "\nReturns the estimated network hashes per second based on the last n blocks.\n"
87             "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
88             "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
89             "\nArguments:\n"
90             "1. blocks     (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n"
91             "2. height     (numeric, optional, default=-1) To estimate at the time of the given height.\n"
92             "\nResult:\n"
93             "x             (numeric) Hashes per second estimated\n"
94             "\nExamples:\n"
95             + HelpExampleCli("getnetworkhashps", "")
96             + HelpExampleRpc("getnetworkhashps", "")
97        );
98
99     return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
100 }
101
102
103 Value getgenerate(const Array& params, bool fHelp)
104 {
105     if (fHelp || params.size() != 0)
106         throw runtime_error(
107             "getgenerate\n"
108             "\nReturn if the server is set to generate coins or not. The default is false.\n"
109             "It is set with the command line argument -gen (or bitcoin.conf setting gen)\n"
110             "It can also be set with the setgenerate call.\n"
111             "\nResult\n"
112             "true|false      (boolean) If the server is set to generate coins or not\n"
113             "\nExamples:\n"
114             + HelpExampleCli("getgenerate", "")
115             + HelpExampleRpc("getgenerate", "")
116         );
117
118     if (!pMiningKey)
119         return false;
120
121     return GetBoolArg("-gen", false);
122 }
123
124
125 Value setgenerate(const Array& params, bool fHelp)
126 {
127     if (fHelp || params.size() < 1 || params.size() > 2)
128         throw runtime_error(
129             "setgenerate generate ( genproclimit )\n"
130             "\nSet 'generate' true or false to turn generation on or off.\n"
131             "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n"
132             "See the getgenerate call for the current setting.\n"
133             "\nArguments:\n"
134             "1. generate         (boolean, required) Set to true to turn on generation, off to turn off.\n"
135             "2. genproclimit     (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
136             "\nExamples:\n"
137             "\nSet the generation on with a limit of one processor\n"
138             + HelpExampleCli("setgenerate", "true 1") +
139             "\nCheck the setting\n"
140             + HelpExampleCli("getgenerate", "") +
141             "\nTurn off generation\n"
142             + HelpExampleCli("setgenerate", "false") +
143             "\nUsing json rpc\n"
144             + HelpExampleRpc("setgenerate", "true, 1")
145         );
146
147     bool fGenerate = true;
148     if (params.size() > 0)
149         fGenerate = params[0].get_bool();
150
151     if (params.size() > 1)
152     {
153         int nGenProcLimit = params[1].get_int();
154         mapArgs["-genproclimit"] = itostr(nGenProcLimit);
155         if (nGenProcLimit == 0)
156             fGenerate = false;
157     }
158     mapArgs["-gen"] = (fGenerate ? "1" : "0");
159
160     assert(pwalletMain != NULL);
161     GenerateBitcoins(fGenerate, pwalletMain);
162     return Value::null;
163 }
164
165
166 Value gethashespersec(const Array& params, bool fHelp)
167 {
168     if (fHelp || params.size() != 0)
169         throw runtime_error(
170             "gethashespersec\n"
171             "\nReturns a recent hashes per second performance measurement while generating.\n"
172             "See the getgenerate and setgenerate calls to turn generation on and off.\n"
173             "\nResult:\n"
174             "n            (numeric) The recent hashes per second when generation is on (will return 0 if generation is off)\n"
175             "\nExamples:\n"
176             + HelpExampleCli("gethashespersec", "")
177             + HelpExampleRpc("gethashespersec", "")
178         );
179
180     if (GetTimeMillis() - nHPSTimerStart > 8000)
181         return (boost::int64_t)0;
182     return (boost::int64_t)dHashesPerSec;
183 }
184
185
186 Value getmininginfo(const Array& params, bool fHelp)
187 {
188     if (fHelp || params.size() != 0)
189         throw runtime_error(
190             "getmininginfo\n"
191             "\nReturns a json object containing mining-related information."
192             "\nResult:\n"
193             "{\n"
194             "  \"blocks\": nnn,             (numeric) The current block\n"
195             "  \"currentblocksize\": nnn,   (numeric) The last block size\n"
196             "  \"currentblocktx\": nnn,     (numeric) The last block transaction\n"
197             "  \"difficulty\": xxx.xxxxx    (numeric) The current difficulty\n"
198             "  \"errors\": \"...\"          (string) Current errors\n"
199             "  \"generate\": true|false     (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
200             "  \"genproclimit\": n          (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
201             "  \"hashespersec\": n          (numeric) The hashes per second of the generation, or 0 if no generation.\n"
202             "  \"pooledtx\": n              (numeric) The size of the mem pool\n"
203             "  \"testnet\": true|false      (boolean) If using testnet or not\n"
204             "}\n"
205             "\nExamples:\n"
206             + HelpExampleCli("getmininginfo", "")
207             + HelpExampleRpc("getmininginfo", "")
208         );
209
210     Object obj;
211     obj.push_back(Pair("blocks",           (int)chainActive.Height()));
212     obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
213     obj.push_back(Pair("currentblocktx",   (uint64_t)nLastBlockTx));
214     obj.push_back(Pair("difficulty",       (double)GetDifficulty()));
215     obj.push_back(Pair("errors",           GetWarnings("statusbar")));
216     obj.push_back(Pair("generate",         getgenerate(params, false)));
217     obj.push_back(Pair("genproclimit",     (int)GetArg("-genproclimit", -1)));
218     obj.push_back(Pair("hashespersec",     gethashespersec(params, false)));
219     obj.push_back(Pair("networkhashps",    getnetworkhashps(params, false)));
220     obj.push_back(Pair("pooledtx",         (uint64_t)mempool.size()));
221     obj.push_back(Pair("testnet",          TestNet()));
222     return obj;
223 }
224
225
226 Value getwork(const Array& params, bool fHelp)
227 {
228     if (fHelp || params.size() > 1)
229         throw runtime_error(
230             "getwork ( \"data\" )\n"
231             "\nIf 'data' is not specified, it returns the formatted hash data to work on.\n"
232             "If 'data' is specified, tries to solve the block and returns true if it was successful.\n"
233             "\nArguments:\n"
234             "1. \"data\"       (string, optional) The hex encoded data to solve\n"
235             "\nResult (when 'data' is not specified):\n"
236             "{\n"
237             "  \"midstate\" : \"xxxx\",   (string) The precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
238             "  \"data\" : \"xxxxx\",      (string) The block data\n"
239             "  \"hash1\" : \"xxxxx\",     (string) The formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
240             "  \"target\" : \"xxxx\"      (string) The little endian hash target\n"
241             "}\n"
242             "\nResult (when 'data' is specified):\n"
243             "true|false       (boolean) If solving the block specified in the 'data' was successfull\n"
244             "\nExamples:\n"
245             + HelpExampleCli("getwork", "")
246             + HelpExampleRpc("getwork", "")
247         );
248
249     if (vNodes.empty())
250         throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
251
252     if (IsInitialBlockDownload())
253         throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
254
255     typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
256     static mapNewBlock_t mapNewBlock;    // FIXME: thread safety
257     static vector<CBlockTemplate*> vNewBlockTemplate;
258
259     if (params.size() == 0)
260     {
261         // Update block
262         static unsigned int nTransactionsUpdatedLast;
263         static CBlockIndex* pindexPrev;
264         static int64_t nStart;
265         static CBlockTemplate* pblocktemplate;
266         if (pindexPrev != chainActive.Tip() ||
267             (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60))
268         {
269             if (pindexPrev != chainActive.Tip())
270             {
271                 // Deallocate old blocks since they're obsolete now
272                 mapNewBlock.clear();
273                 BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
274                     delete pblocktemplate;
275                 vNewBlockTemplate.clear();
276             }
277
278             // Clear pindexPrev so future getworks make a new block, despite any failures from here on
279             pindexPrev = NULL;
280
281             // Store the pindexBest used before CreateNewBlock, to avoid races
282             nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
283             CBlockIndex* pindexPrevNew = chainActive.Tip();
284             nStart = GetTime();
285
286             // Create new block
287             pblocktemplate = CreateNewBlockWithKey(*pMiningKey);
288             if (!pblocktemplate)
289                 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
290             vNewBlockTemplate.push_back(pblocktemplate);
291
292             // Need to update only after we know CreateNewBlock succeeded
293             pindexPrev = pindexPrevNew;
294         }
295         CBlock* pblock = &pblocktemplate->block; // pointer for convenience
296
297         // Update nTime
298         UpdateTime(*pblock, pindexPrev);
299         pblock->nNonce = 0;
300
301         // Update nExtraNonce
302         static unsigned int nExtraNonce = 0;
303         IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
304
305         // Save
306         mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
307
308         // Pre-build hash buffers
309         char pmidstate[32];
310         char pdata[128];
311         char phash1[64];
312         FormatHashBuffers(pblock, pmidstate, pdata, phash1);
313
314         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
315
316         Object result;
317         result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
318         result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
319         result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1)))); // deprecated
320         result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
321         return result;
322     }
323     else
324     {
325         // Parse parameters
326         vector<unsigned char> vchData = ParseHex(params[0].get_str());
327         if (vchData.size() != 128)
328             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
329         CBlock* pdata = (CBlock*)&vchData[0];
330
331         // Byte reverse
332         for (int i = 0; i < 128/4; i++)
333             ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
334
335         // Get saved block
336         if (!mapNewBlock.count(pdata->hashMerkleRoot))
337             return false;
338         CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
339
340         pblock->nTime = pdata->nTime;
341         pblock->nNonce = pdata->nNonce;
342         pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
343         pblock->hashMerkleRoot = pblock->BuildMerkleTree();
344
345         assert(pwalletMain != NULL);
346         return CheckWork(pblock, *pwalletMain, *pMiningKey);
347     }
348 }
349
350
351 Value getblocktemplate(const Array& params, bool fHelp)
352 {
353     if (fHelp || params.size() > 1)
354         throw runtime_error(
355             "getblocktemplate ( \"jsonrequestobject\" )\n"
356             "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
357             "It returns data needed to construct a block to work on.\n"
358             "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
359
360             "\nArguments:\n"
361             "1. \"jsonrequestobject\"       (string, optional) A json object in the following spec\n"
362             "     {\n"
363             "       \"mode\":\"template\"    (string, optional) This must be set to \"template\" or omitted\n"
364             "       \"capabilities\":[       (array, optional) A list of strings\n"
365             "           \"support\"           (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
366             "           ,...\n"
367             "         ]\n"
368             "     }\n"
369             "\n"
370
371             "\nResult:\n"
372             "{\n"
373             "  \"version\" : n,                    (numeric) The block version\n"
374             "  \"previousblockhash\" : \"xxxx\",    (string) The hash of current highest block\n"
375             "  \"transactions\" : [                (array) contents of non-coinbase transactions that should be included in the next block\n"
376             "      {\n"
377             "         \"data\" : \"xxxx\",          (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
378             "         \"hash\" : \"xxxx\",          (string) hash/id encoded in little-endian hexadecimal\n"
379             "         \"depends\" : [              (array) array of numbers \n"
380             "             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"
381             "             ,...\n"
382             "         ],\n"
383             "         \"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"
384             "         \"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"
385             "         \"required\" : true|false     (boolean) if provided and true, this transaction must be in the final block\n"
386             "      }\n"
387             "      ,...\n"
388             "  ],\n"
389             "  \"coinbaseaux\" : {                  (json object) data that should be included in the coinbase's scriptSig content\n"
390             "      \"flags\" : \"flags\"            (string) \n"
391             "  },\n"
392             "  \"coinbasevalue\" : n,               (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
393             "  \"coinbasetxn\" : { ... },           (json object) information for coinbase transaction\n"
394             "  \"target\" : \"xxxx\",               (string) The hash target\n"
395             "  \"mintime\" : xxx,                   (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
396             "  \"mutable\" : [                      (array of string) list of ways the block template may be changed \n"
397             "     \"value\"                         (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
398             "     ,...\n"
399             "  ],\n"
400             "  \"noncerange\" : \"00000000ffffffff\",   (string) A range of valid nonces\n"
401             "  \"sigoplimit\" : n,                 (numeric) limit of sigops in blocks\n"
402             "  \"sizelimit\" : n,                  (numeric) limit of block size\n"
403             "  \"curtime\" : ttt,                  (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
404             "  \"bits\" : \"xxx\",                 (string) compressed target of next block\n"
405             "  \"height\" : n                      (numeric) The height of the next block\n"
406             "}\n"
407
408             "\nExamples:\n"
409             + HelpExampleCli("getblocktemplate", "")
410             + HelpExampleRpc("getblocktemplate", "")
411          );
412
413     std::string strMode = "template";
414     if (params.size() > 0)
415     {
416         const Object& oparam = params[0].get_obj();
417         const Value& modeval = find_value(oparam, "mode");
418         if (modeval.type() == str_type)
419             strMode = modeval.get_str();
420         else if (modeval.type() == null_type)
421         {
422             /* Do nothing */
423         }
424         else
425             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
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     // Update block
438     static unsigned int nTransactionsUpdatedLast;
439     static CBlockIndex* pindexPrev;
440     static int64_t nStart;
441     static CBlockTemplate* pblocktemplate;
442     if (pindexPrev != chainActive.Tip() ||
443         (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
444     {
445         // Clear pindexPrev so future calls make a new block, despite any failures from here on
446         pindexPrev = NULL;
447
448         // Store the pindexBest used before CreateNewBlock, to avoid races
449         nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
450         CBlockIndex* pindexPrevNew = chainActive.Tip();
451         nStart = GetTime();
452
453         // Create new block
454         if(pblocktemplate)
455         {
456             delete pblocktemplate;
457             pblocktemplate = NULL;
458         }
459         CScript scriptDummy = CScript() << OP_TRUE;
460         pblocktemplate = CreateNewBlock(scriptDummy);
461         if (!pblocktemplate)
462             throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
463
464         // Need to update only after we know CreateNewBlock succeeded
465         pindexPrev = pindexPrevNew;
466     }
467     CBlock* pblock = &pblocktemplate->block; // pointer for convenience
468
469     // Update nTime
470     UpdateTime(*pblock, pindexPrev);
471     pblock->nNonce = 0;
472
473     Array transactions;
474     map<uint256, int64_t> setTxIndex;
475     int i = 0;
476     BOOST_FOREACH (CTransaction& tx, pblock->vtx)
477     {
478         uint256 txHash = tx.GetHash();
479         setTxIndex[txHash] = i++;
480
481         if (tx.IsCoinBase())
482             continue;
483
484         Object entry;
485
486         CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
487         ssTx << tx;
488         entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end())));
489
490         entry.push_back(Pair("hash", txHash.GetHex()));
491
492         Array deps;
493         BOOST_FOREACH (const CTxIn &in, tx.vin)
494         {
495             if (setTxIndex.count(in.prevout.hash))
496                 deps.push_back(setTxIndex[in.prevout.hash]);
497         }
498         entry.push_back(Pair("depends", deps));
499
500         int index_in_template = i - 1;
501         entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
502         entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
503
504         transactions.push_back(entry);
505     }
506
507     Object aux;
508     aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
509
510     uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
511
512     static Array aMutable;
513     if (aMutable.empty())
514     {
515         aMutable.push_back("time");
516         aMutable.push_back("transactions");
517         aMutable.push_back("prevblock");
518     }
519
520     Object result;
521     result.push_back(Pair("version", pblock->nVersion));
522     result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
523     result.push_back(Pair("transactions", transactions));
524     result.push_back(Pair("coinbaseaux", aux));
525     result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
526     result.push_back(Pair("target", hashTarget.GetHex()));
527     result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
528     result.push_back(Pair("mutable", aMutable));
529     result.push_back(Pair("noncerange", "00000000ffffffff"));
530     result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
531     result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
532     result.push_back(Pair("curtime", (int64_t)pblock->nTime));
533     result.push_back(Pair("bits", HexBits(pblock->nBits)));
534     result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
535
536     return result;
537 }
538
539 Value submitblock(const Array& params, bool fHelp)
540 {
541     if (fHelp || params.size() < 1 || params.size() > 2)
542         throw runtime_error(
543             "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
544             "\nAttempts to submit new block to network.\n"
545             "The 'jsonparametersobject' parameter is currently ignored.\n"
546             "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
547
548             "\nArguments\n"
549             "1. \"hexdata\"    (string, required) the hex-encoded block data to submit\n"
550             "2. \"jsonparametersobject\"     (string, optional) object of optional parameters\n"
551             "    {\n"
552             "      \"workid\" : \"id\"    (string, optional) if the server provided a workid, it MUST be included with submissions\n"
553             "    }\n"
554             "\nResult:\n"
555             "\nExamples:\n"
556             + HelpExampleCli("submitblock", "\"mydata\"")
557             + HelpExampleRpc("submitblock", "\"mydata\"")
558         );
559
560     vector<unsigned char> blockData(ParseHex(params[0].get_str()));
561     CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
562     CBlock pblock;
563     try {
564         ssBlock >> pblock;
565     }
566     catch (std::exception &e) {
567         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
568     }
569
570     CValidationState state;
571     bool fAccepted = ProcessBlock(state, NULL, &pblock);
572     if (!fAccepted)
573         return "rejected"; // TODO: report validation state
574
575     return Value::null;
576 }
This page took 0.060919 seconds and 4 git commands to generate.