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