BIP141: Other consensus critical limits, and BIP145
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blob43ba4edd78c19a18ed467a22356be8810e04eee1
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include "amount.h"
7 #include "chain.h"
8 #include "chainparams.h"
9 #include "checkpoints.h"
10 #include "coins.h"
11 #include "consensus/validation.h"
12 #include "main.h"
13 #include "policy/policy.h"
14 #include "primitives/transaction.h"
15 #include "rpc/server.h"
16 #include "streams.h"
17 #include "sync.h"
18 #include "txmempool.h"
19 #include "util.h"
20 #include "utilstrencodings.h"
21 #include "hash.h"
23 #include <stdint.h>
25 #include <univalue.h>
27 #include <boost/thread/thread.hpp> // boost::thread::interrupt
29 using namespace std;
31 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
32 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
34 double GetDifficulty(const CBlockIndex* blockindex)
36 // Floating point number that is a multiple of the minimum difficulty,
37 // minimum difficulty = 1.0.
38 if (blockindex == NULL)
40 if (chainActive.Tip() == NULL)
41 return 1.0;
42 else
43 blockindex = chainActive.Tip();
46 int nShift = (blockindex->nBits >> 24) & 0xff;
48 double dDiff =
49 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
51 while (nShift < 29)
53 dDiff *= 256.0;
54 nShift++;
56 while (nShift > 29)
58 dDiff /= 256.0;
59 nShift--;
62 return dDiff;
65 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
67 UniValue result(UniValue::VOBJ);
68 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
69 int confirmations = -1;
70 // Only report confirmations if the block is on the main chain
71 if (chainActive.Contains(blockindex))
72 confirmations = chainActive.Height() - blockindex->nHeight + 1;
73 result.push_back(Pair("confirmations", confirmations));
74 result.push_back(Pair("height", blockindex->nHeight));
75 result.push_back(Pair("version", blockindex->nVersion));
76 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
77 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
78 result.push_back(Pair("time", (int64_t)blockindex->nTime));
79 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
80 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
81 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
82 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
83 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
85 if (blockindex->pprev)
86 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
87 CBlockIndex *pnext = chainActive.Next(blockindex);
88 if (pnext)
89 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
90 return result;
93 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
95 UniValue result(UniValue::VOBJ);
96 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
97 int confirmations = -1;
98 // Only report confirmations if the block is on the main chain
99 if (chainActive.Contains(blockindex))
100 confirmations = chainActive.Height() - blockindex->nHeight + 1;
101 result.push_back(Pair("confirmations", confirmations));
102 result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)));
103 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
104 result.push_back(Pair("cost", (int)::GetBlockCost(block)));
105 result.push_back(Pair("height", blockindex->nHeight));
106 result.push_back(Pair("version", block.nVersion));
107 result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion)));
108 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
109 UniValue txs(UniValue::VARR);
110 BOOST_FOREACH(const CTransaction&tx, block.vtx)
112 if(txDetails)
114 UniValue objTx(UniValue::VOBJ);
115 TxToJSON(tx, uint256(), objTx);
116 txs.push_back(objTx);
118 else
119 txs.push_back(tx.GetHash().GetHex());
121 result.push_back(Pair("tx", txs));
122 result.push_back(Pair("time", block.GetBlockTime()));
123 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
124 result.push_back(Pair("nonce", (uint64_t)block.nNonce));
125 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
126 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
127 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
129 if (blockindex->pprev)
130 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
131 CBlockIndex *pnext = chainActive.Next(blockindex);
132 if (pnext)
133 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
134 return result;
137 UniValue getblockcount(const UniValue& params, bool fHelp)
139 if (fHelp || params.size() != 0)
140 throw runtime_error(
141 "getblockcount\n"
142 "\nReturns the number of blocks in the longest block chain.\n"
143 "\nResult:\n"
144 "n (numeric) The current block count\n"
145 "\nExamples:\n"
146 + HelpExampleCli("getblockcount", "")
147 + HelpExampleRpc("getblockcount", "")
150 LOCK(cs_main);
151 return chainActive.Height();
154 UniValue getbestblockhash(const UniValue& params, bool fHelp)
156 if (fHelp || params.size() != 0)
157 throw runtime_error(
158 "getbestblockhash\n"
159 "\nReturns the hash of the best (tip) block in the longest block chain.\n"
160 "\nResult\n"
161 "\"hex\" (string) the block hash hex encoded\n"
162 "\nExamples\n"
163 + HelpExampleCli("getbestblockhash", "")
164 + HelpExampleRpc("getbestblockhash", "")
167 LOCK(cs_main);
168 return chainActive.Tip()->GetBlockHash().GetHex();
171 UniValue getdifficulty(const UniValue& params, bool fHelp)
173 if (fHelp || params.size() != 0)
174 throw runtime_error(
175 "getdifficulty\n"
176 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
177 "\nResult:\n"
178 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
179 "\nExamples:\n"
180 + HelpExampleCli("getdifficulty", "")
181 + HelpExampleRpc("getdifficulty", "")
184 LOCK(cs_main);
185 return GetDifficulty();
188 std::string EntryDescriptionString()
190 return " \"size\" : n, (numeric) transaction size in bytes\n"
191 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
192 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
193 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
194 " \"height\" : n, (numeric) block height when transaction entered pool\n"
195 " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
196 " \"currentpriority\" : n, (numeric) transaction priority now\n"
197 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
198 " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
199 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
200 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
201 " \"ancestorsize\" : n, (numeric) size of in-mempool ancestors (including this one)\n"
202 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
203 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
204 " \"transactionid\", (string) parent transaction id\n"
205 " ... ]\n";
208 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
210 AssertLockHeld(mempool.cs);
212 info.push_back(Pair("size", (int)e.GetTxSize()));
213 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
214 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
215 info.push_back(Pair("time", e.GetTime()));
216 info.push_back(Pair("height", (int)e.GetHeight()));
217 info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
218 info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
219 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
220 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
221 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
222 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
223 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
224 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
225 const CTransaction& tx = e.GetTx();
226 set<string> setDepends;
227 BOOST_FOREACH(const CTxIn& txin, tx.vin)
229 if (mempool.exists(txin.prevout.hash))
230 setDepends.insert(txin.prevout.hash.ToString());
233 UniValue depends(UniValue::VARR);
234 BOOST_FOREACH(const string& dep, setDepends)
236 depends.push_back(dep);
239 info.push_back(Pair("depends", depends));
242 UniValue mempoolToJSON(bool fVerbose = false)
244 if (fVerbose)
246 LOCK(mempool.cs);
247 UniValue o(UniValue::VOBJ);
248 BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx)
250 const uint256& hash = e.GetTx().GetHash();
251 UniValue info(UniValue::VOBJ);
252 entryToJSON(info, e);
253 o.push_back(Pair(hash.ToString(), info));
255 return o;
257 else
259 vector<uint256> vtxid;
260 mempool.queryHashes(vtxid);
262 UniValue a(UniValue::VARR);
263 BOOST_FOREACH(const uint256& hash, vtxid)
264 a.push_back(hash.ToString());
266 return a;
270 UniValue getrawmempool(const UniValue& params, bool fHelp)
272 if (fHelp || params.size() > 1)
273 throw runtime_error(
274 "getrawmempool ( verbose )\n"
275 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
276 "\nArguments:\n"
277 "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
278 "\nResult: (for verbose = false):\n"
279 "[ (json array of string)\n"
280 " \"transactionid\" (string) The transaction id\n"
281 " ,...\n"
282 "]\n"
283 "\nResult: (for verbose = true):\n"
284 "{ (json object)\n"
285 " \"transactionid\" : { (json object)\n"
286 + EntryDescriptionString()
287 + " }, ...\n"
288 "}\n"
289 "\nExamples\n"
290 + HelpExampleCli("getrawmempool", "true")
291 + HelpExampleRpc("getrawmempool", "true")
294 LOCK(cs_main);
296 bool fVerbose = false;
297 if (params.size() > 0)
298 fVerbose = params[0].get_bool();
300 return mempoolToJSON(fVerbose);
303 UniValue getmempoolancestors(const UniValue& params, bool fHelp)
305 if (fHelp || params.size() < 1 || params.size() > 2) {
306 throw runtime_error(
307 "getmempoolancestors txid (verbose)\n"
308 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
309 "\nArguments:\n"
310 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
311 "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
312 "\nResult (for verbose=false):\n"
313 "[ (json array of strings)\n"
314 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
315 " ,...\n"
316 "]\n"
317 "\nResult (for verbose=true):\n"
318 "{ (json object)\n"
319 " \"transactionid\" : { (json object)\n"
320 + EntryDescriptionString()
321 + " }, ...\n"
322 "}\n"
323 "\nExamples\n"
324 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
325 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
329 bool fVerbose = false;
330 if (params.size() > 1)
331 fVerbose = params[1].get_bool();
333 uint256 hash = ParseHashV(params[0], "parameter 1");
335 LOCK(mempool.cs);
337 CTxMemPool::txiter it = mempool.mapTx.find(hash);
338 if (it == mempool.mapTx.end()) {
339 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
342 CTxMemPool::setEntries setAncestors;
343 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
344 std::string dummy;
345 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
347 if (!fVerbose) {
348 UniValue o(UniValue::VARR);
349 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
350 o.push_back(ancestorIt->GetTx().GetHash().ToString());
353 return o;
354 } else {
355 UniValue o(UniValue::VOBJ);
356 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
357 const CTxMemPoolEntry &e = *ancestorIt;
358 const uint256& hash = e.GetTx().GetHash();
359 UniValue info(UniValue::VOBJ);
360 entryToJSON(info, e);
361 o.push_back(Pair(hash.ToString(), info));
363 return o;
367 UniValue getmempooldescendants(const UniValue& params, bool fHelp)
369 if (fHelp || params.size() < 1 || params.size() > 2) {
370 throw runtime_error(
371 "getmempooldescendants txid (verbose)\n"
372 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
373 "\nArguments:\n"
374 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
375 "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
376 "\nResult (for verbose=false):\n"
377 "[ (json array of strings)\n"
378 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
379 " ,...\n"
380 "]\n"
381 "\nResult (for verbose=true):\n"
382 "{ (json object)\n"
383 " \"transactionid\" : { (json object)\n"
384 + EntryDescriptionString()
385 + " }, ...\n"
386 "}\n"
387 "\nExamples\n"
388 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
389 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
393 bool fVerbose = false;
394 if (params.size() > 1)
395 fVerbose = params[1].get_bool();
397 uint256 hash = ParseHashV(params[0], "parameter 1");
399 LOCK(mempool.cs);
401 CTxMemPool::txiter it = mempool.mapTx.find(hash);
402 if (it == mempool.mapTx.end()) {
403 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
406 CTxMemPool::setEntries setDescendants;
407 mempool.CalculateDescendants(it, setDescendants);
408 // CTxMemPool::CalculateDescendants will include the given tx
409 setDescendants.erase(it);
411 if (!fVerbose) {
412 UniValue o(UniValue::VARR);
413 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
414 o.push_back(descendantIt->GetTx().GetHash().ToString());
417 return o;
418 } else {
419 UniValue o(UniValue::VOBJ);
420 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
421 const CTxMemPoolEntry &e = *descendantIt;
422 const uint256& hash = e.GetTx().GetHash();
423 UniValue info(UniValue::VOBJ);
424 entryToJSON(info, e);
425 o.push_back(Pair(hash.ToString(), info));
427 return o;
431 UniValue getmempoolentry(const UniValue& params, bool fHelp)
433 if (fHelp || params.size() != 1) {
434 throw runtime_error(
435 "getmempoolentry txid\n"
436 "\nReturns mempool data for given transaction\n"
437 "\nArguments:\n"
438 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
439 "\nResult:\n"
440 "{ (json object)\n"
441 + EntryDescriptionString()
442 + "}\n"
443 "\nExamples\n"
444 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
445 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
449 uint256 hash = ParseHashV(params[0], "parameter 1");
451 LOCK(mempool.cs);
453 CTxMemPool::txiter it = mempool.mapTx.find(hash);
454 if (it == mempool.mapTx.end()) {
455 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
458 const CTxMemPoolEntry &e = *it;
459 UniValue info(UniValue::VOBJ);
460 entryToJSON(info, e);
461 return info;
464 UniValue getblockhash(const UniValue& params, bool fHelp)
466 if (fHelp || params.size() != 1)
467 throw runtime_error(
468 "getblockhash index\n"
469 "\nReturns hash of block in best-block-chain at index provided.\n"
470 "\nArguments:\n"
471 "1. index (numeric, required) The block index\n"
472 "\nResult:\n"
473 "\"hash\" (string) The block hash\n"
474 "\nExamples:\n"
475 + HelpExampleCli("getblockhash", "1000")
476 + HelpExampleRpc("getblockhash", "1000")
479 LOCK(cs_main);
481 int nHeight = params[0].get_int();
482 if (nHeight < 0 || nHeight > chainActive.Height())
483 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
485 CBlockIndex* pblockindex = chainActive[nHeight];
486 return pblockindex->GetBlockHash().GetHex();
489 UniValue getblockheader(const UniValue& params, bool fHelp)
491 if (fHelp || params.size() < 1 || params.size() > 2)
492 throw runtime_error(
493 "getblockheader \"hash\" ( verbose )\n"
494 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
495 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
496 "\nArguments:\n"
497 "1. \"hash\" (string, required) The block hash\n"
498 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
499 "\nResult (for verbose = true):\n"
500 "{\n"
501 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
502 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
503 " \"height\" : n, (numeric) The block height or index\n"
504 " \"version\" : n, (numeric) The block version\n"
505 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
506 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
507 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
508 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
509 " \"nonce\" : n, (numeric) The nonce\n"
510 " \"bits\" : \"1d00ffff\", (string) The bits\n"
511 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
512 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
513 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
514 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
515 "}\n"
516 "\nResult (for verbose=false):\n"
517 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
518 "\nExamples:\n"
519 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
520 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
523 LOCK(cs_main);
525 std::string strHash = params[0].get_str();
526 uint256 hash(uint256S(strHash));
528 bool fVerbose = true;
529 if (params.size() > 1)
530 fVerbose = params[1].get_bool();
532 if (mapBlockIndex.count(hash) == 0)
533 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
535 CBlockIndex* pblockindex = mapBlockIndex[hash];
537 if (!fVerbose)
539 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
540 ssBlock << pblockindex->GetBlockHeader();
541 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
542 return strHex;
545 return blockheaderToJSON(pblockindex);
548 UniValue getblock(const UniValue& params, bool fHelp)
550 if (fHelp || params.size() < 1 || params.size() > 2)
551 throw runtime_error(
552 "getblock \"hash\" ( verbose )\n"
553 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
554 "If verbose is true, returns an Object with information about block <hash>.\n"
555 "\nArguments:\n"
556 "1. \"hash\" (string, required) The block hash\n"
557 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
558 "\nResult (for verbose = true):\n"
559 "{\n"
560 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
561 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
562 " \"size\" : n, (numeric) The block size\n"
563 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
564 " \"cost\" : n (numeric) The block cost\n"
565 " \"height\" : n, (numeric) The block height or index\n"
566 " \"version\" : n, (numeric) The block version\n"
567 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
568 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
569 " \"tx\" : [ (array of string) The transaction ids\n"
570 " \"transactionid\" (string) The transaction id\n"
571 " ,...\n"
572 " ],\n"
573 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
574 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
575 " \"nonce\" : n, (numeric) The nonce\n"
576 " \"bits\" : \"1d00ffff\", (string) The bits\n"
577 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
578 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
579 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
580 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
581 "}\n"
582 "\nResult (for verbose=false):\n"
583 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
584 "\nExamples:\n"
585 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
586 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
589 LOCK(cs_main);
591 std::string strHash = params[0].get_str();
592 uint256 hash(uint256S(strHash));
594 bool fVerbose = true;
595 if (params.size() > 1)
596 fVerbose = params[1].get_bool();
598 if (mapBlockIndex.count(hash) == 0)
599 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
601 CBlock block;
602 CBlockIndex* pblockindex = mapBlockIndex[hash];
604 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
605 throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
607 if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
608 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
610 if (!fVerbose)
612 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
613 ssBlock << block;
614 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
615 return strHex;
618 return blockToJSON(block, pblockindex);
621 struct CCoinsStats
623 int nHeight;
624 uint256 hashBlock;
625 uint64_t nTransactions;
626 uint64_t nTransactionOutputs;
627 uint64_t nSerializedSize;
628 uint256 hashSerialized;
629 CAmount nTotalAmount;
631 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {}
634 //! Calculate statistics about the unspent transaction output set
635 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
637 boost::scoped_ptr<CCoinsViewCursor> pcursor(view->Cursor());
639 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
640 stats.hashBlock = pcursor->GetBestBlock();
642 LOCK(cs_main);
643 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
645 ss << stats.hashBlock;
646 CAmount nTotalAmount = 0;
647 while (pcursor->Valid()) {
648 boost::this_thread::interruption_point();
649 uint256 key;
650 CCoins coins;
651 if (pcursor->GetKey(key) && pcursor->GetValue(coins)) {
652 stats.nTransactions++;
653 ss << key;
654 for (unsigned int i=0; i<coins.vout.size(); i++) {
655 const CTxOut &out = coins.vout[i];
656 if (!out.IsNull()) {
657 stats.nTransactionOutputs++;
658 ss << VARINT(i+1);
659 ss << out;
660 nTotalAmount += out.nValue;
663 stats.nSerializedSize += 32 + pcursor->GetValueSize();
664 ss << VARINT(0);
665 } else {
666 return error("%s: unable to read value", __func__);
668 pcursor->Next();
670 stats.hashSerialized = ss.GetHash();
671 stats.nTotalAmount = nTotalAmount;
672 return true;
675 UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
677 if (fHelp || params.size() != 0)
678 throw runtime_error(
679 "gettxoutsetinfo\n"
680 "\nReturns statistics about the unspent transaction output set.\n"
681 "Note this call may take some time.\n"
682 "\nResult:\n"
683 "{\n"
684 " \"height\":n, (numeric) The current block height (index)\n"
685 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
686 " \"transactions\": n, (numeric) The number of transactions\n"
687 " \"txouts\": n, (numeric) The number of output transactions\n"
688 " \"bytes_serialized\": n, (numeric) The serialized size\n"
689 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
690 " \"total_amount\": x.xxx (numeric) The total amount\n"
691 "}\n"
692 "\nExamples:\n"
693 + HelpExampleCli("gettxoutsetinfo", "")
694 + HelpExampleRpc("gettxoutsetinfo", "")
697 UniValue ret(UniValue::VOBJ);
699 CCoinsStats stats;
700 FlushStateToDisk();
701 if (GetUTXOStats(pcoinsTip, stats)) {
702 ret.push_back(Pair("height", (int64_t)stats.nHeight));
703 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
704 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
705 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
706 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
707 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
708 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
710 return ret;
713 UniValue gettxout(const UniValue& params, bool fHelp)
715 if (fHelp || params.size() < 2 || params.size() > 3)
716 throw runtime_error(
717 "gettxout \"txid\" n ( includemempool )\n"
718 "\nReturns details about an unspent transaction output.\n"
719 "\nArguments:\n"
720 "1. \"txid\" (string, required) The transaction id\n"
721 "2. n (numeric, required) vout number\n"
722 "3. includemempool (boolean, optional) Whether to include the mem pool\n"
723 "\nResult:\n"
724 "{\n"
725 " \"bestblock\" : \"hash\", (string) the block hash\n"
726 " \"confirmations\" : n, (numeric) The number of confirmations\n"
727 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
728 " \"scriptPubKey\" : { (json object)\n"
729 " \"asm\" : \"code\", (string) \n"
730 " \"hex\" : \"hex\", (string) \n"
731 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
732 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
733 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
734 " \"bitcoinaddress\" (string) bitcoin address\n"
735 " ,...\n"
736 " ]\n"
737 " },\n"
738 " \"version\" : n, (numeric) The version\n"
739 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
740 "}\n"
742 "\nExamples:\n"
743 "\nGet unspent transactions\n"
744 + HelpExampleCli("listunspent", "") +
745 "\nView the details\n"
746 + HelpExampleCli("gettxout", "\"txid\" 1") +
747 "\nAs a json rpc call\n"
748 + HelpExampleRpc("gettxout", "\"txid\", 1")
751 LOCK(cs_main);
753 UniValue ret(UniValue::VOBJ);
755 std::string strHash = params[0].get_str();
756 uint256 hash(uint256S(strHash));
757 int n = params[1].get_int();
758 bool fMempool = true;
759 if (params.size() > 2)
760 fMempool = params[2].get_bool();
762 CCoins coins;
763 if (fMempool) {
764 LOCK(mempool.cs);
765 CCoinsViewMemPool view(pcoinsTip, mempool);
766 if (!view.GetCoins(hash, coins))
767 return NullUniValue;
768 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
769 } else {
770 if (!pcoinsTip->GetCoins(hash, coins))
771 return NullUniValue;
773 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
774 return NullUniValue;
776 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
777 CBlockIndex *pindex = it->second;
778 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
779 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
780 ret.push_back(Pair("confirmations", 0));
781 else
782 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
783 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
784 UniValue o(UniValue::VOBJ);
785 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
786 ret.push_back(Pair("scriptPubKey", o));
787 ret.push_back(Pair("version", coins.nVersion));
788 ret.push_back(Pair("coinbase", coins.fCoinBase));
790 return ret;
793 UniValue verifychain(const UniValue& params, bool fHelp)
795 int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
796 int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
797 if (fHelp || params.size() > 2)
798 throw runtime_error(
799 "verifychain ( checklevel numblocks )\n"
800 "\nVerifies blockchain database.\n"
801 "\nArguments:\n"
802 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
803 "2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
804 "\nResult:\n"
805 "true|false (boolean) Verified or not\n"
806 "\nExamples:\n"
807 + HelpExampleCli("verifychain", "")
808 + HelpExampleRpc("verifychain", "")
811 LOCK(cs_main);
813 if (params.size() > 0)
814 nCheckLevel = params[0].get_int();
815 if (params.size() > 1)
816 nCheckDepth = params[1].get_int();
818 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
821 /** Implementation of IsSuperMajority with better feedback */
822 static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
824 int nFound = 0;
825 CBlockIndex* pstart = pindex;
826 for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
828 if (pstart->nVersion >= minVersion)
829 ++nFound;
830 pstart = pstart->pprev;
833 UniValue rv(UniValue::VOBJ);
834 rv.push_back(Pair("status", nFound >= nRequired));
835 rv.push_back(Pair("found", nFound));
836 rv.push_back(Pair("required", nRequired));
837 rv.push_back(Pair("window", consensusParams.nMajorityWindow));
838 return rv;
841 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
843 UniValue rv(UniValue::VOBJ);
844 rv.push_back(Pair("id", name));
845 rv.push_back(Pair("version", version));
846 rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
847 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
848 return rv;
851 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
853 UniValue rv(UniValue::VOBJ);
854 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
855 switch (thresholdState) {
856 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
857 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
858 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
859 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
860 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
862 if (THRESHOLD_STARTED == thresholdState)
864 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
866 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
867 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
868 return rv;
871 UniValue getblockchaininfo(const UniValue& params, bool fHelp)
873 if (fHelp || params.size() != 0)
874 throw runtime_error(
875 "getblockchaininfo\n"
876 "Returns an object containing various state info regarding block chain processing.\n"
877 "\nResult:\n"
878 "{\n"
879 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
880 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
881 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
882 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
883 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
884 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
885 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
886 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
887 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
888 " \"pruneheight\": xxxxxx, (numeric) heighest block available\n"
889 " \"softforks\": [ (array) status of softforks in progress\n"
890 " {\n"
891 " \"id\": \"xxxx\", (string) name of softfork\n"
892 " \"version\": xx, (numeric) block version\n"
893 " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
894 " \"status\": xx, (boolean) true if threshold reached\n"
895 " \"found\": xx, (numeric) number of blocks with the new version found\n"
896 " \"required\": xx, (numeric) number of blocks required to trigger\n"
897 " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
898 " },\n"
899 " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
900 " }, ...\n"
901 " ],\n"
902 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
903 " \"xxxx\" : { (string) name of the softfork\n"
904 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n"
905 " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n"
906 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
907 " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
908 " }\n"
909 " }\n"
910 "}\n"
911 "\nExamples:\n"
912 + HelpExampleCli("getblockchaininfo", "")
913 + HelpExampleRpc("getblockchaininfo", "")
916 LOCK(cs_main);
918 UniValue obj(UniValue::VOBJ);
919 obj.push_back(Pair("chain", Params().NetworkIDString()));
920 obj.push_back(Pair("blocks", (int)chainActive.Height()));
921 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
922 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
923 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
924 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
925 obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
926 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
927 obj.push_back(Pair("pruned", fPruneMode));
929 const Consensus::Params& consensusParams = Params().GetConsensus();
930 CBlockIndex* tip = chainActive.Tip();
931 UniValue softforks(UniValue::VARR);
932 UniValue bip9_softforks(UniValue::VOBJ);
933 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
934 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
935 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
936 bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV)));
937 bip9_softforks.push_back(Pair("segwit", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_SEGWIT)));
938 obj.push_back(Pair("softforks", softforks));
939 obj.push_back(Pair("bip9_softforks", bip9_softforks));
941 if (fPruneMode)
943 CBlockIndex *block = chainActive.Tip();
944 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
945 block = block->pprev;
947 obj.push_back(Pair("pruneheight", block->nHeight));
949 return obj;
952 /** Comparison function for sorting the getchaintips heads. */
953 struct CompareBlocksByHeight
955 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
957 /* Make sure that unequal blocks with the same height do not compare
958 equal. Use the pointers themselves to make a distinction. */
960 if (a->nHeight != b->nHeight)
961 return (a->nHeight > b->nHeight);
963 return a < b;
967 UniValue getchaintips(const UniValue& params, bool fHelp)
969 if (fHelp || params.size() != 0)
970 throw runtime_error(
971 "getchaintips\n"
972 "Return information about all known tips in the block tree,"
973 " including the main chain as well as orphaned branches.\n"
974 "\nResult:\n"
975 "[\n"
976 " {\n"
977 " \"height\": xxxx, (numeric) height of the chain tip\n"
978 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
979 " \"branchlen\": 0 (numeric) zero for main chain\n"
980 " \"status\": \"active\" (string) \"active\" for the main chain\n"
981 " },\n"
982 " {\n"
983 " \"height\": xxxx,\n"
984 " \"hash\": \"xxxx\",\n"
985 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
986 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
987 " }\n"
988 "]\n"
989 "Possible values for status:\n"
990 "1. \"invalid\" This branch contains at least one invalid block\n"
991 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
992 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
993 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
994 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
995 "\nExamples:\n"
996 + HelpExampleCli("getchaintips", "")
997 + HelpExampleRpc("getchaintips", "")
1000 LOCK(cs_main);
1003 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1004 * Algorithm:
1005 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1006 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1007 * - add chainActive.Tip()
1009 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1010 std::set<const CBlockIndex*> setOrphans;
1011 std::set<const CBlockIndex*> setPrevs;
1013 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
1015 if (!chainActive.Contains(item.second)) {
1016 setOrphans.insert(item.second);
1017 setPrevs.insert(item.second->pprev);
1021 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1023 if (setPrevs.erase(*it) == 0) {
1024 setTips.insert(*it);
1028 // Always report the currently active tip.
1029 setTips.insert(chainActive.Tip());
1031 /* Construct the output array. */
1032 UniValue res(UniValue::VARR);
1033 BOOST_FOREACH(const CBlockIndex* block, setTips)
1035 UniValue obj(UniValue::VOBJ);
1036 obj.push_back(Pair("height", block->nHeight));
1037 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1039 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1040 obj.push_back(Pair("branchlen", branchLen));
1042 string status;
1043 if (chainActive.Contains(block)) {
1044 // This block is part of the currently active chain.
1045 status = "active";
1046 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1047 // This block or one of its ancestors is invalid.
1048 status = "invalid";
1049 } else if (block->nChainTx == 0) {
1050 // This block cannot be connected because full block data for it or one of its parents is missing.
1051 status = "headers-only";
1052 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1053 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1054 status = "valid-fork";
1055 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1056 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1057 status = "valid-headers";
1058 } else {
1059 // No clue.
1060 status = "unknown";
1062 obj.push_back(Pair("status", status));
1064 res.push_back(obj);
1067 return res;
1070 UniValue mempoolInfoToJSON()
1072 UniValue ret(UniValue::VOBJ);
1073 ret.push_back(Pair("size", (int64_t) mempool.size()));
1074 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1075 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1076 size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1077 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1078 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1080 return ret;
1083 UniValue getmempoolinfo(const UniValue& params, bool fHelp)
1085 if (fHelp || params.size() != 0)
1086 throw runtime_error(
1087 "getmempoolinfo\n"
1088 "\nReturns details on the active state of the TX memory pool.\n"
1089 "\nResult:\n"
1090 "{\n"
1091 " \"size\": xxxxx, (numeric) Current tx count\n"
1092 " \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n"
1093 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1094 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1095 " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n"
1096 "}\n"
1097 "\nExamples:\n"
1098 + HelpExampleCli("getmempoolinfo", "")
1099 + HelpExampleRpc("getmempoolinfo", "")
1102 return mempoolInfoToJSON();
1105 UniValue invalidateblock(const UniValue& params, bool fHelp)
1107 if (fHelp || params.size() != 1)
1108 throw runtime_error(
1109 "invalidateblock \"hash\"\n"
1110 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1111 "\nArguments:\n"
1112 "1. hash (string, required) the hash of the block to mark as invalid\n"
1113 "\nResult:\n"
1114 "\nExamples:\n"
1115 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1116 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1119 std::string strHash = params[0].get_str();
1120 uint256 hash(uint256S(strHash));
1121 CValidationState state;
1124 LOCK(cs_main);
1125 if (mapBlockIndex.count(hash) == 0)
1126 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1128 CBlockIndex* pblockindex = mapBlockIndex[hash];
1129 InvalidateBlock(state, Params(), pblockindex);
1132 if (state.IsValid()) {
1133 ActivateBestChain(state, Params());
1136 if (!state.IsValid()) {
1137 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1140 return NullUniValue;
1143 UniValue reconsiderblock(const UniValue& params, bool fHelp)
1145 if (fHelp || params.size() != 1)
1146 throw runtime_error(
1147 "reconsiderblock \"hash\"\n"
1148 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1149 "This can be used to undo the effects of invalidateblock.\n"
1150 "\nArguments:\n"
1151 "1. hash (string, required) the hash of the block to reconsider\n"
1152 "\nResult:\n"
1153 "\nExamples:\n"
1154 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1155 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1158 std::string strHash = params[0].get_str();
1159 uint256 hash(uint256S(strHash));
1162 LOCK(cs_main);
1163 if (mapBlockIndex.count(hash) == 0)
1164 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1166 CBlockIndex* pblockindex = mapBlockIndex[hash];
1167 ResetBlockFailureFlags(pblockindex);
1170 CValidationState state;
1171 ActivateBestChain(state, Params());
1173 if (!state.IsValid()) {
1174 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1177 return NullUniValue;
1180 static const CRPCCommand commands[] =
1181 { // category name actor (function) okSafeMode
1182 // --------------------- ------------------------ ----------------------- ----------
1183 { "blockchain", "getblockchaininfo", &getblockchaininfo, true },
1184 { "blockchain", "getbestblockhash", &getbestblockhash, true },
1185 { "blockchain", "getblockcount", &getblockcount, true },
1186 { "blockchain", "getblock", &getblock, true },
1187 { "blockchain", "getblockhash", &getblockhash, true },
1188 { "blockchain", "getblockheader", &getblockheader, true },
1189 { "blockchain", "getchaintips", &getchaintips, true },
1190 { "blockchain", "getdifficulty", &getdifficulty, true },
1191 { "blockchain", "getmempoolancestors", &getmempoolancestors, true },
1192 { "blockchain", "getmempooldescendants", &getmempooldescendants, true },
1193 { "blockchain", "getmempoolentry", &getmempoolentry, true },
1194 { "blockchain", "getmempoolinfo", &getmempoolinfo, true },
1195 { "blockchain", "getrawmempool", &getrawmempool, true },
1196 { "blockchain", "gettxout", &gettxout, true },
1197 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
1198 { "blockchain", "verifychain", &verifychain, true },
1200 /* Not shown in help */
1201 { "hidden", "invalidateblock", &invalidateblock, true },
1202 { "hidden", "reconsiderblock", &reconsiderblock, true },
1205 void RegisterBlockchainRPCCommands(CRPCTable &tableRPC)
1207 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1208 tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);