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