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