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