]> Git Repo - VerusCoin.git/blob - src/rpcmining.cpp
Merge pull request #3207
[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 "rpcserver.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             "                    Note: in -regtest mode, genproclimit controls how many blocks are generated immediately.\n"
137             "\nExamples:\n"
138             "\nSet the generation on with a limit of one processor\n"
139             + HelpExampleCli("setgenerate", "true 1") +
140             "\nCheck the setting\n"
141             + HelpExampleCli("getgenerate", "") +
142             "\nTurn off generation\n"
143             + HelpExampleCli("setgenerate", "false") +
144             "\nUsing json rpc\n"
145             + HelpExampleRpc("setgenerate", "true, 1")
146         );
147
148     if (pwalletMain == NULL)
149         throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
150
151     bool fGenerate = true;
152     if (params.size() > 0)
153         fGenerate = params[0].get_bool();
154
155     int nGenProcLimit = -1;
156     if (params.size() > 1)
157     {
158         nGenProcLimit = params[1].get_int();
159         if (nGenProcLimit == 0)
160             fGenerate = false;
161     }
162
163     // -regtest mode: don't return until nGenProcLimit blocks are generated
164     if (fGenerate && Params().NetworkID() == CChainParams::REGTEST)
165     {
166         int nHeightStart = 0;
167         int nHeightEnd = 0;
168         int nHeight = 0;
169         int nGenerate = (nGenProcLimit > 0 ? nGenProcLimit : 1);
170         {   // Don't keep cs_main locked
171             LOCK(cs_main);
172             nHeightStart = chainActive.Height();
173             nHeight = nHeightStart;
174             nHeightEnd = nHeightStart+nGenerate;
175         }
176         int nHeightLast = -1;
177         while (nHeight < nHeightEnd)
178         {
179             if (nHeightLast != nHeight)
180             {
181                 nHeightLast = nHeight;
182                 GenerateBitcoins(fGenerate, pwalletMain, 1);
183             }
184             MilliSleep(1);
185             {   // Don't keep cs_main locked
186                 LOCK(cs_main);
187                 nHeight = chainActive.Height();
188             }
189         }
190     }
191     else // Not -regtest: start generate thread, return immediately
192     {
193         mapArgs["-gen"] = (fGenerate ? "1" : "0");
194         GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
195     }
196
197     return Value::null;
198 }
199
200
201 Value gethashespersec(const Array& params, bool fHelp)
202 {
203     if (fHelp || params.size() != 0)
204         throw runtime_error(
205             "gethashespersec\n"
206             "\nReturns a recent hashes per second performance measurement while generating.\n"
207             "See the getgenerate and setgenerate calls to turn generation on and off.\n"
208             "\nResult:\n"
209             "n            (numeric) The recent hashes per second when generation is on (will return 0 if generation is off)\n"
210             "\nExamples:\n"
211             + HelpExampleCli("gethashespersec", "")
212             + HelpExampleRpc("gethashespersec", "")
213         );
214
215     if (GetTimeMillis() - nHPSTimerStart > 8000)
216         return (boost::int64_t)0;
217     return (boost::int64_t)dHashesPerSec;
218 }
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             "  \"hashespersec\": n          (numeric) The hashes per second of the generation, or 0 if no generation.\n"
237             "  \"pooledtx\": n              (numeric) The size of the mem pool\n"
238             "  \"testnet\": true|false      (boolean) If using testnet or not\n"
239             "}\n"
240             "\nExamples:\n"
241             + HelpExampleCli("getmininginfo", "")
242             + HelpExampleRpc("getmininginfo", "")
243         );
244
245     Object obj;
246     obj.push_back(Pair("blocks",           (int)chainActive.Height()));
247     obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
248     obj.push_back(Pair("currentblocktx",   (uint64_t)nLastBlockTx));
249     obj.push_back(Pair("difficulty",       (double)GetDifficulty()));
250     obj.push_back(Pair("errors",           GetWarnings("statusbar")));
251     obj.push_back(Pair("generate",         getgenerate(params, false)));
252     obj.push_back(Pair("genproclimit",     (int)GetArg("-genproclimit", -1)));
253     obj.push_back(Pair("hashespersec",     gethashespersec(params, false)));
254     obj.push_back(Pair("networkhashps",    getnetworkhashps(params, false)));
255     obj.push_back(Pair("pooledtx",         (uint64_t)mempool.size()));
256     obj.push_back(Pair("testnet",          TestNet()));
257     return obj;
258 }
259
260
261 Value getwork(const Array& params, bool fHelp)
262 {
263     if (fHelp || params.size() > 1)
264         throw runtime_error(
265             "getwork ( \"data\" )\n"
266             "\nIf 'data' is not specified, it returns the formatted hash data to work on.\n"
267             "If 'data' is specified, tries to solve the block and returns true if it was successful.\n"
268             "\nArguments:\n"
269             "1. \"data\"       (string, optional) The hex encoded data to solve\n"
270             "\nResult (when 'data' is not specified):\n"
271             "{\n"
272             "  \"midstate\" : \"xxxx\",   (string) The precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
273             "  \"data\" : \"xxxxx\",      (string) The block data\n"
274             "  \"hash1\" : \"xxxxx\",     (string) The formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
275             "  \"target\" : \"xxxx\"      (string) The little endian hash target\n"
276             "}\n"
277             "\nResult (when 'data' is specified):\n"
278             "true|false       (boolean) If solving the block specified in the 'data' was successfull\n"
279             "\nExamples:\n"
280             + HelpExampleCli("getwork", "")
281             + HelpExampleRpc("getwork", "")
282         );
283
284     if (vNodes.empty())
285         throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
286
287     if (IsInitialBlockDownload())
288         throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
289
290     typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
291     static mapNewBlock_t mapNewBlock;    // FIXME: thread safety
292     static vector<CBlockTemplate*> vNewBlockTemplate;
293
294     if (params.size() == 0)
295     {
296         // Update block
297         static unsigned int nTransactionsUpdatedLast;
298         static CBlockIndex* pindexPrev;
299         static int64_t nStart;
300         static CBlockTemplate* pblocktemplate;
301         if (pindexPrev != chainActive.Tip() ||
302             (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60))
303         {
304             if (pindexPrev != chainActive.Tip())
305             {
306                 // Deallocate old blocks since they're obsolete now
307                 mapNewBlock.clear();
308                 BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
309                     delete pblocktemplate;
310                 vNewBlockTemplate.clear();
311             }
312
313             // Clear pindexPrev so future getworks make a new block, despite any failures from here on
314             pindexPrev = NULL;
315
316             // Store the pindexBest used before CreateNewBlock, to avoid races
317             nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
318             CBlockIndex* pindexPrevNew = chainActive.Tip();
319             nStart = GetTime();
320
321             // Create new block
322             pblocktemplate = CreateNewBlockWithKey(*pMiningKey);
323             if (!pblocktemplate)
324                 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
325             vNewBlockTemplate.push_back(pblocktemplate);
326
327             // Need to update only after we know CreateNewBlock succeeded
328             pindexPrev = pindexPrevNew;
329         }
330         CBlock* pblock = &pblocktemplate->block; // pointer for convenience
331
332         // Update nTime
333         UpdateTime(*pblock, pindexPrev);
334         pblock->nNonce = 0;
335
336         // Update nExtraNonce
337         static unsigned int nExtraNonce = 0;
338         IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
339
340         // Save
341         mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
342
343         // Pre-build hash buffers
344         char pmidstate[32];
345         char pdata[128];
346         char phash1[64];
347         FormatHashBuffers(pblock, pmidstate, pdata, phash1);
348
349         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
350
351         Object result;
352         result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
353         result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
354         result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1)))); // deprecated
355         result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
356         return result;
357     }
358     else
359     {
360         // Parse parameters
361         vector<unsigned char> vchData = ParseHex(params[0].get_str());
362         if (vchData.size() != 128)
363             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
364         CBlock* pdata = (CBlock*)&vchData[0];
365
366         // Byte reverse
367         for (int i = 0; i < 128/4; i++)
368             ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
369
370         // Get saved block
371         if (!mapNewBlock.count(pdata->hashMerkleRoot))
372             return false;
373         CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
374
375         pblock->nTime = pdata->nTime;
376         pblock->nNonce = pdata->nNonce;
377         pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
378         pblock->hashMerkleRoot = pblock->BuildMerkleTree();
379
380         assert(pwalletMain != NULL);
381         return CheckWork(pblock, *pwalletMain, *pMiningKey);
382     }
383 }
384
385
386 Value getblocktemplate(const Array& params, bool fHelp)
387 {
388     if (fHelp || params.size() > 1)
389         throw runtime_error(
390             "getblocktemplate ( \"jsonrequestobject\" )\n"
391             "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
392             "It returns data needed to construct a block to work on.\n"
393             "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
394
395             "\nArguments:\n"
396             "1. \"jsonrequestobject\"       (string, optional) A json object in the following spec\n"
397             "     {\n"
398             "       \"mode\":\"template\"    (string, optional) This must be set to \"template\" or omitted\n"
399             "       \"capabilities\":[       (array, optional) A list of strings\n"
400             "           \"support\"           (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
401             "           ,...\n"
402             "         ]\n"
403             "     }\n"
404             "\n"
405
406             "\nResult:\n"
407             "{\n"
408             "  \"version\" : n,                    (numeric) The block version\n"
409             "  \"previousblockhash\" : \"xxxx\",    (string) The hash of current highest block\n"
410             "  \"transactions\" : [                (array) contents of non-coinbase transactions that should be included in the next block\n"
411             "      {\n"
412             "         \"data\" : \"xxxx\",          (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
413             "         \"hash\" : \"xxxx\",          (string) hash/id encoded in little-endian hexadecimal\n"
414             "         \"depends\" : [              (array) array of numbers \n"
415             "             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"
416             "             ,...\n"
417             "         ],\n"
418             "         \"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"
419             "         \"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"
420             "         \"required\" : true|false     (boolean) if provided and true, this transaction must be in the final block\n"
421             "      }\n"
422             "      ,...\n"
423             "  ],\n"
424             "  \"coinbaseaux\" : {                  (json object) data that should be included in the coinbase's scriptSig content\n"
425             "      \"flags\" : \"flags\"            (string) \n"
426             "  },\n"
427             "  \"coinbasevalue\" : n,               (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
428             "  \"coinbasetxn\" : { ... },           (json object) information for coinbase transaction\n"
429             "  \"target\" : \"xxxx\",               (string) The hash target\n"
430             "  \"mintime\" : xxx,                   (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
431             "  \"mutable\" : [                      (array of string) list of ways the block template may be changed \n"
432             "     \"value\"                         (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
433             "     ,...\n"
434             "  ],\n"
435             "  \"noncerange\" : \"00000000ffffffff\",   (string) A range of valid nonces\n"
436             "  \"sigoplimit\" : n,                 (numeric) limit of sigops in blocks\n"
437             "  \"sizelimit\" : n,                  (numeric) limit of block size\n"
438             "  \"curtime\" : ttt,                  (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
439             "  \"bits\" : \"xxx\",                 (string) compressed target of next block\n"
440             "  \"height\" : n                      (numeric) The height of the next block\n"
441             "}\n"
442
443             "\nExamples:\n"
444             + HelpExampleCli("getblocktemplate", "")
445             + HelpExampleRpc("getblocktemplate", "")
446          );
447
448     std::string strMode = "template";
449     if (params.size() > 0)
450     {
451         const Object& oparam = params[0].get_obj();
452         const Value& modeval = find_value(oparam, "mode");
453         if (modeval.type() == str_type)
454             strMode = modeval.get_str();
455         else if (modeval.type() == null_type)
456         {
457             /* Do nothing */
458         }
459         else
460             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
461     }
462
463     if (strMode != "template")
464         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
465
466     if (vNodes.empty())
467         throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
468
469     if (IsInitialBlockDownload())
470         throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
471
472     // Update block
473     static unsigned int nTransactionsUpdatedLast;
474     static CBlockIndex* pindexPrev;
475     static int64_t nStart;
476     static CBlockTemplate* pblocktemplate;
477     if (pindexPrev != chainActive.Tip() ||
478         (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
479     {
480         // Clear pindexPrev so future calls make a new block, despite any failures from here on
481         pindexPrev = NULL;
482
483         // Store the pindexBest used before CreateNewBlock, to avoid races
484         nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
485         CBlockIndex* pindexPrevNew = chainActive.Tip();
486         nStart = GetTime();
487
488         // Create new block
489         if(pblocktemplate)
490         {
491             delete pblocktemplate;
492             pblocktemplate = NULL;
493         }
494         CScript scriptDummy = CScript() << OP_TRUE;
495         pblocktemplate = CreateNewBlock(scriptDummy);
496         if (!pblocktemplate)
497             throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
498
499         // Need to update only after we know CreateNewBlock succeeded
500         pindexPrev = pindexPrevNew;
501     }
502     CBlock* pblock = &pblocktemplate->block; // pointer for convenience
503
504     // Update nTime
505     UpdateTime(*pblock, pindexPrev);
506     pblock->nNonce = 0;
507
508     Array transactions;
509     map<uint256, int64_t> setTxIndex;
510     int i = 0;
511     BOOST_FOREACH (CTransaction& tx, pblock->vtx)
512     {
513         uint256 txHash = tx.GetHash();
514         setTxIndex[txHash] = i++;
515
516         if (tx.IsCoinBase())
517             continue;
518
519         Object entry;
520
521         CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
522         ssTx << tx;
523         entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end())));
524
525         entry.push_back(Pair("hash", txHash.GetHex()));
526
527         Array deps;
528         BOOST_FOREACH (const CTxIn &in, tx.vin)
529         {
530             if (setTxIndex.count(in.prevout.hash))
531                 deps.push_back(setTxIndex[in.prevout.hash]);
532         }
533         entry.push_back(Pair("depends", deps));
534
535         int index_in_template = i - 1;
536         entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
537         entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
538
539         transactions.push_back(entry);
540     }
541
542     Object aux;
543     aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
544
545     uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
546
547     static Array aMutable;
548     if (aMutable.empty())
549     {
550         aMutable.push_back("time");
551         aMutable.push_back("transactions");
552         aMutable.push_back("prevblock");
553     }
554
555     Object result;
556     result.push_back(Pair("version", pblock->nVersion));
557     result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
558     result.push_back(Pair("transactions", transactions));
559     result.push_back(Pair("coinbaseaux", aux));
560     result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
561     result.push_back(Pair("target", hashTarget.GetHex()));
562     result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
563     result.push_back(Pair("mutable", aMutable));
564     result.push_back(Pair("noncerange", "00000000ffffffff"));
565     result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
566     result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
567     result.push_back(Pair("curtime", (int64_t)pblock->nTime));
568     result.push_back(Pair("bits", HexBits(pblock->nBits)));
569     result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
570
571     return result;
572 }
573
574 Value submitblock(const Array& params, bool fHelp)
575 {
576     if (fHelp || params.size() < 1 || params.size() > 2)
577         throw runtime_error(
578             "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
579             "\nAttempts to submit new block to network.\n"
580             "The 'jsonparametersobject' parameter is currently ignored.\n"
581             "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
582
583             "\nArguments\n"
584             "1. \"hexdata\"    (string, required) the hex-encoded block data to submit\n"
585             "2. \"jsonparametersobject\"     (string, optional) object of optional parameters\n"
586             "    {\n"
587             "      \"workid\" : \"id\"    (string, optional) if the server provided a workid, it MUST be included with submissions\n"
588             "    }\n"
589             "\nResult:\n"
590             "\nExamples:\n"
591             + HelpExampleCli("submitblock", "\"mydata\"")
592             + HelpExampleRpc("submitblock", "\"mydata\"")
593         );
594
595     vector<unsigned char> blockData(ParseHex(params[0].get_str()));
596     CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
597     CBlock pblock;
598     try {
599         ssBlock >> pblock;
600     }
601     catch (std::exception &e) {
602         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
603     }
604
605     CValidationState state;
606     bool fAccepted = ProcessBlock(state, NULL, &pblock);
607     if (!fAccepted)
608         return "rejected"; // TODO: report validation state
609
610     return Value::null;
611 }
This page took 0.060754 seconds and 4 git commands to generate.