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