1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 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.
8 #include "chainparams.h"
9 #include "checkpoints.h"
10 #include "consensus/validation.h"
12 #include "primitives/transaction.h"
13 #include "rpcserver.h"
25 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
26 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
28 double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
30 // Floating point number that is a multiple of the minimum difficulty,
31 // minimum difficulty = 1.0.
32 if (blockindex == NULL)
34 if (chainActive.Tip() == NULL)
37 blockindex = chainActive.Tip();
41 if (networkDifficulty) {
42 bits = GetNextWorkRequired(blockindex, nullptr, Params().GetConsensus());
44 bits = blockindex->nBits;
48 UintToArith256(Params().GetConsensus().powLimit).GetCompact();
49 int nShift = (bits >> 24) & 0xff;
50 int nShiftAmount = (powLimit >> 24) & 0xff;
53 (double)(powLimit & 0x00ffffff) /
54 (double)(bits & 0x00ffffff);
56 while (nShift < nShiftAmount)
61 while (nShift > nShiftAmount)
70 double GetDifficulty(const CBlockIndex* blockindex)
72 return GetDifficultyINTERNAL(blockindex, false);
75 double GetNetworkDifficulty(const CBlockIndex* blockindex)
77 return GetDifficultyINTERNAL(blockindex, true);
80 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
82 UniValue result(UniValue::VOBJ);
83 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
84 int confirmations = -1;
85 // Only report confirmations if the block is on the main chain
86 if (chainActive.Contains(blockindex))
87 confirmations = chainActive.Height() - blockindex->nHeight + 1;
88 result.push_back(Pair("confirmations", confirmations));
89 result.push_back(Pair("height", blockindex->nHeight));
90 result.push_back(Pair("version", blockindex->nVersion));
91 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
92 result.push_back(Pair("time", (int64_t)blockindex->nTime));
93 result.push_back(Pair("nonce", blockindex->nNonce.GetHex()));
94 result.push_back(Pair("solution", HexStr(blockindex->nSolution)));
95 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
96 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
97 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
99 if (blockindex->pprev)
100 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
101 CBlockIndex *pnext = chainActive.Next(blockindex);
103 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
107 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
109 UniValue result(UniValue::VOBJ);
110 result.push_back(Pair("hash", block.GetHash().GetHex()));
111 int confirmations = -1;
112 // Only report confirmations if the block is on the main chain
113 if (chainActive.Contains(blockindex))
114 confirmations = chainActive.Height() - blockindex->nHeight + 1;
115 result.push_back(Pair("confirmations", confirmations));
116 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
117 result.push_back(Pair("height", blockindex->nHeight));
118 result.push_back(Pair("version", block.nVersion));
119 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
120 UniValue txs(UniValue::VARR);
121 BOOST_FOREACH(const CTransaction&tx, block.vtx)
125 UniValue objTx(UniValue::VOBJ);
126 TxToJSON(tx, uint256(), objTx);
127 txs.push_back(objTx);
130 txs.push_back(tx.GetHash().GetHex());
132 result.push_back(Pair("tx", txs));
133 result.push_back(Pair("time", block.GetBlockTime()));
134 result.push_back(Pair("nonce", block.nNonce.GetHex()));
135 result.push_back(Pair("solution", HexStr(block.nSolution)));
136 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
137 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
138 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
139 result.push_back(Pair("anchor", blockindex->hashAnchorEnd.GetHex()));
141 if (blockindex->pprev)
142 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
143 CBlockIndex *pnext = chainActive.Next(blockindex);
145 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
149 UniValue getblockcount(const UniValue& params, bool fHelp)
151 if (fHelp || params.size() != 0)
154 "\nReturns the number of blocks in the longest block chain.\n"
156 "n (numeric) The current block count\n"
158 + HelpExampleCli("getblockcount", "")
159 + HelpExampleRpc("getblockcount", "")
163 return chainActive.Height();
166 UniValue getbestblockhash(const UniValue& params, bool fHelp)
168 if (fHelp || params.size() != 0)
171 "\nReturns the hash of the best (tip) block in the longest block chain.\n"
173 "\"hex\" (string) the block hash hex encoded\n"
175 + HelpExampleCli("getbestblockhash", "")
176 + HelpExampleRpc("getbestblockhash", "")
180 return chainActive.Tip()->GetBlockHash().GetHex();
183 UniValue getdifficulty(const UniValue& params, bool fHelp)
185 if (fHelp || params.size() != 0)
188 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
190 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
192 + HelpExampleCli("getdifficulty", "")
193 + HelpExampleRpc("getdifficulty", "")
197 return GetNetworkDifficulty();
200 UniValue mempoolToJSON(bool fVerbose = false)
205 UniValue o(UniValue::VOBJ);
206 BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
208 const uint256& hash = entry.first;
209 const CTxMemPoolEntry& e = entry.second;
210 UniValue info(UniValue::VOBJ);
211 info.push_back(Pair("size", (int)e.GetTxSize()));
212 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
213 info.push_back(Pair("time", e.GetTime()));
214 info.push_back(Pair("height", (int)e.GetHeight()));
215 info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
216 info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
217 const CTransaction& tx = e.GetTx();
218 set<string> setDepends;
219 BOOST_FOREACH(const CTxIn& txin, tx.vin)
221 if (mempool.exists(txin.prevout.hash))
222 setDepends.insert(txin.prevout.hash.ToString());
225 UniValue depends(UniValue::VARR);
226 BOOST_FOREACH(const string& dep, setDepends)
228 depends.push_back(dep);
231 info.push_back(Pair("depends", depends));
232 o.push_back(Pair(hash.ToString(), info));
238 vector<uint256> vtxid;
239 mempool.queryHashes(vtxid);
241 UniValue a(UniValue::VARR);
242 BOOST_FOREACH(const uint256& hash, vtxid)
243 a.push_back(hash.ToString());
249 UniValue getrawmempool(const UniValue& params, bool fHelp)
251 if (fHelp || params.size() > 1)
253 "getrawmempool ( verbose )\n"
254 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
256 "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
257 "\nResult: (for verbose = false):\n"
258 "[ (json array of string)\n"
259 " \"transactionid\" (string) The transaction id\n"
262 "\nResult: (for verbose = true):\n"
264 " \"transactionid\" : { (json object)\n"
265 " \"size\" : n, (numeric) transaction size in bytes\n"
266 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
267 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
268 " \"height\" : n, (numeric) block height when transaction entered pool\n"
269 " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
270 " \"currentpriority\" : n, (numeric) transaction priority now\n"
271 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
272 " \"transactionid\", (string) parent transaction id\n"
277 + HelpExampleCli("getrawmempool", "true")
278 + HelpExampleRpc("getrawmempool", "true")
283 bool fVerbose = false;
284 if (params.size() > 0)
285 fVerbose = params[0].get_bool();
287 return mempoolToJSON(fVerbose);
290 UniValue getblockhash(const UniValue& params, bool fHelp)
292 if (fHelp || params.size() != 1)
294 "getblockhash index\n"
295 "\nReturns hash of block in best-block-chain at index provided.\n"
297 "1. index (numeric, required) The block index\n"
299 "\"hash\" (string) The block hash\n"
301 + HelpExampleCli("getblockhash", "1000")
302 + HelpExampleRpc("getblockhash", "1000")
307 int nHeight = params[0].get_int();
308 if (nHeight < 0 || nHeight > chainActive.Height())
309 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
311 CBlockIndex* pblockindex = chainActive[nHeight];
312 return pblockindex->GetBlockHash().GetHex();
315 UniValue getblockheader(const UniValue& params, bool fHelp)
317 if (fHelp || params.size() < 1 || params.size() > 2)
319 "getblockheader \"hash\" ( verbose )\n"
320 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
321 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
323 "1. \"hash\" (string, required) The block hash\n"
324 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
325 "\nResult (for verbose = true):\n"
327 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
328 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
329 " \"height\" : n, (numeric) The block height or index\n"
330 " \"version\" : n, (numeric) The block version\n"
331 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
332 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
333 " \"nonce\" : n, (numeric) The nonce\n"
334 " \"bits\" : \"1d00ffff\", (string) The bits\n"
335 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
336 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
337 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
339 "\nResult (for verbose=false):\n"
340 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
342 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
343 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
348 std::string strHash = params[0].get_str();
349 uint256 hash(uint256S(strHash));
351 bool fVerbose = true;
352 if (params.size() > 1)
353 fVerbose = params[1].get_bool();
355 if (mapBlockIndex.count(hash) == 0)
356 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
358 CBlockIndex* pblockindex = mapBlockIndex[hash];
362 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
363 ssBlock << pblockindex->GetBlockHeader();
364 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
368 return blockheaderToJSON(pblockindex);
371 UniValue getblock(const UniValue& params, bool fHelp)
373 if (fHelp || params.size() < 1 || params.size() > 2)
375 "getblock \"hash|height\" ( verbose )\n"
376 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash|height'.\n"
377 "If verbose is true, returns an Object with information about block <hash|height>.\n"
379 "1. \"hash|height\" (string, required) The block hash or height\n"
380 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
381 "\nResult (for verbose = true):\n"
383 " \"hash\" : \"hash\", (string) the block hash (same as provided hash)\n"
384 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
385 " \"size\" : n, (numeric) The block size\n"
386 " \"height\" : n, (numeric) The block height or index (same as provided height)\n"
387 " \"version\" : n, (numeric) The block version\n"
388 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
389 " \"tx\" : [ (array of string) The transaction ids\n"
390 " \"transactionid\" (string) The transaction id\n"
393 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
394 " \"nonce\" : n, (numeric) The nonce\n"
395 " \"bits\" : \"1d00ffff\", (string) The bits\n"
396 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
397 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
398 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
400 "\nResult (for verbose=false):\n"
401 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
403 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
404 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
405 + HelpExampleCli("getblock", "12800")
406 + HelpExampleRpc("getblock", "12800")
411 std::string strHash = params[0].get_str();
413 // If height is supplied, find the hash
414 if (strHash.size() < (2 * sizeof(uint256))) {
415 // std::stoi allows characters, whereas we want to be strict
416 regex r("[[:digit:]]+");
417 if (!regex_match(strHash, r)) {
418 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
423 nHeight = std::stoi(strHash);
425 catch (const std::exception &e) {
426 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
429 if (nHeight < 0 || nHeight > chainActive.Height()) {
430 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
432 strHash = chainActive[nHeight]->GetBlockHash().GetHex();
435 uint256 hash(uint256S(strHash));
437 bool fVerbose = true;
438 if (params.size() > 1)
439 fVerbose = params[1].get_bool();
441 if (mapBlockIndex.count(hash) == 0)
442 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
445 CBlockIndex* pblockindex = mapBlockIndex[hash];
447 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
448 throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
450 if(!ReadBlockFromDisk(block, pblockindex))
451 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
455 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
457 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
461 return blockToJSON(block, pblockindex);
464 UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
466 if (fHelp || params.size() != 0)
469 "\nReturns statistics about the unspent transaction output set.\n"
470 "Note this call may take some time.\n"
473 " \"height\":n, (numeric) The current block height (index)\n"
474 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
475 " \"transactions\": n, (numeric) The number of transactions\n"
476 " \"txouts\": n, (numeric) The number of output transactions\n"
477 " \"bytes_serialized\": n, (numeric) The serialized size\n"
478 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
479 " \"total_amount\": x.xxx (numeric) The total amount\n"
482 + HelpExampleCli("gettxoutsetinfo", "")
483 + HelpExampleRpc("gettxoutsetinfo", "")
486 UniValue ret(UniValue::VOBJ);
490 if (pcoinsTip->GetStats(stats)) {
491 ret.push_back(Pair("height", (int64_t)stats.nHeight));
492 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
493 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
494 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
495 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
496 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
497 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
502 UniValue gettxout(const UniValue& params, bool fHelp)
504 if (fHelp || params.size() < 2 || params.size() > 3)
506 "gettxout \"txid\" n ( includemempool )\n"
507 "\nReturns details about an unspent transaction output.\n"
509 "1. \"txid\" (string, required) The transaction id\n"
510 "2. n (numeric, required) vout value\n"
511 "3. includemempool (boolean, optional) Whether to included the mem pool\n"
514 " \"bestblock\" : \"hash\", (string) the block hash\n"
515 " \"confirmations\" : n, (numeric) The number of confirmations\n"
516 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
517 " \"scriptPubKey\" : { (json object)\n"
518 " \"asm\" : \"code\", (string) \n"
519 " \"hex\" : \"hex\", (string) \n"
520 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
521 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
522 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
523 " \"bitcoinaddress\" (string) bitcoin address\n"
527 " \"version\" : n, (numeric) The version\n"
528 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
532 "\nGet unspent transactions\n"
533 + HelpExampleCli("listunspent", "") +
534 "\nView the details\n"
535 + HelpExampleCli("gettxout", "\"txid\" 1") +
536 "\nAs a json rpc call\n"
537 + HelpExampleRpc("gettxout", "\"txid\", 1")
542 UniValue ret(UniValue::VOBJ);
544 std::string strHash = params[0].get_str();
545 uint256 hash(uint256S(strHash));
546 int n = params[1].get_int();
547 bool fMempool = true;
548 if (params.size() > 2)
549 fMempool = params[2].get_bool();
554 CCoinsViewMemPool view(pcoinsTip, mempool);
555 if (!view.GetCoins(hash, coins))
557 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
559 if (!pcoinsTip->GetCoins(hash, coins))
562 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
565 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
566 CBlockIndex *pindex = it->second;
567 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
568 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
569 ret.push_back(Pair("confirmations", 0));
571 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
572 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
573 UniValue o(UniValue::VOBJ);
574 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
575 ret.push_back(Pair("scriptPubKey", o));
576 ret.push_back(Pair("version", coins.nVersion));
577 ret.push_back(Pair("coinbase", coins.fCoinBase));
582 UniValue verifychain(const UniValue& params, bool fHelp)
584 if (fHelp || params.size() > 2)
586 "verifychain ( checklevel numblocks )\n"
587 "\nVerifies blockchain database.\n"
589 "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
590 "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
592 "true|false (boolean) Verified or not\n"
594 + HelpExampleCli("verifychain", "")
595 + HelpExampleRpc("verifychain", "")
600 int nCheckLevel = GetArg("-checklevel", 3);
601 int nCheckDepth = GetArg("-checkblocks", 288);
602 if (params.size() > 0)
603 nCheckLevel = params[0].get_int();
604 if (params.size() > 1)
605 nCheckDepth = params[1].get_int();
607 return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth);
610 /** Implementation of IsSuperMajority with better feedback */
611 static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
614 CBlockIndex* pstart = pindex;
615 for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
617 if (pstart->nVersion >= minVersion)
619 pstart = pstart->pprev;
622 UniValue rv(UniValue::VOBJ);
623 rv.push_back(Pair("status", nFound >= nRequired));
624 rv.push_back(Pair("found", nFound));
625 rv.push_back(Pair("required", nRequired));
626 rv.push_back(Pair("window", consensusParams.nMajorityWindow));
630 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
632 UniValue rv(UniValue::VOBJ);
633 rv.push_back(Pair("id", name));
634 rv.push_back(Pair("version", version));
635 rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
636 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
640 UniValue getblockchaininfo(const UniValue& params, bool fHelp)
642 if (fHelp || params.size() != 0)
644 "getblockchaininfo\n"
645 "Returns an object containing various state info regarding block chain processing.\n"
648 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
649 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
650 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
651 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
652 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
653 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
654 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
655 " \"commitments\": xxxxxx, (numeric) the current number of note commitments in the commitment tree\n"
656 " \"softforks\": [ (array) status of softforks in progress\n"
658 " \"id\": \"xxxx\", (string) name of softfork\n"
659 " \"version\": xx, (numeric) block version\n"
660 " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
661 " \"status\": xx, (boolean) true if threshold reached\n"
662 " \"found\": xx, (numeric) number of blocks with the new version found\n"
663 " \"required\": xx, (numeric) number of blocks required to trigger\n"
664 " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
666 " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
671 + HelpExampleCli("getblockchaininfo", "")
672 + HelpExampleRpc("getblockchaininfo", "")
677 UniValue obj(UniValue::VOBJ);
678 obj.push_back(Pair("chain", Params().NetworkIDString()));
679 obj.push_back(Pair("blocks", (int)chainActive.Height()));
680 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
681 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
682 obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
683 obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
684 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
685 obj.push_back(Pair("pruned", fPruneMode));
687 ZCIncrementalMerkleTree tree;
688 pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), tree);
689 obj.push_back(Pair("commitments", tree.size()));
691 const Consensus::Params& consensusParams = Params().GetConsensus();
692 CBlockIndex* tip = chainActive.Tip();
693 UniValue softforks(UniValue::VARR);
694 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
695 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
696 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
697 obj.push_back(Pair("softforks", softforks));
701 CBlockIndex *block = chainActive.Tip();
702 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
703 block = block->pprev;
705 obj.push_back(Pair("pruneheight", block->nHeight));
710 /** Comparison function for sorting the getchaintips heads. */
711 struct CompareBlocksByHeight
713 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
715 /* Make sure that unequal blocks with the same height do not compare
716 equal. Use the pointers themselves to make a distinction. */
718 if (a->nHeight != b->nHeight)
719 return (a->nHeight > b->nHeight);
725 UniValue getchaintips(const UniValue& params, bool fHelp)
727 if (fHelp || params.size() != 0)
730 "Return information about all known tips in the block tree,"
731 " including the main chain as well as orphaned branches.\n"
735 " \"height\": xxxx, (numeric) height of the chain tip\n"
736 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
737 " \"branchlen\": 0 (numeric) zero for main chain\n"
738 " \"status\": \"active\" (string) \"active\" for the main chain\n"
741 " \"height\": xxxx,\n"
742 " \"hash\": \"xxxx\",\n"
743 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
744 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
747 "Possible values for status:\n"
748 "1. \"invalid\" This branch contains at least one invalid block\n"
749 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
750 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
751 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
752 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
754 + HelpExampleCli("getchaintips", "")
755 + HelpExampleRpc("getchaintips", "")
760 /* Build up a list of chain tips. We start with the list of all
761 known blocks, and successively remove blocks that appear as pprev
763 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
764 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
765 setTips.insert(item.second);
766 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
768 const CBlockIndex* pprev = item.second->pprev;
770 setTips.erase(pprev);
773 // Always report the currently active tip.
774 setTips.insert(chainActive.Tip());
776 /* Construct the output array. */
777 UniValue res(UniValue::VARR);
778 BOOST_FOREACH(const CBlockIndex* block, setTips)
780 UniValue obj(UniValue::VOBJ);
781 obj.push_back(Pair("height", block->nHeight));
782 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
784 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
785 obj.push_back(Pair("branchlen", branchLen));
788 if (chainActive.Contains(block)) {
789 // This block is part of the currently active chain.
791 } else if (block->nStatus & BLOCK_FAILED_MASK) {
792 // This block or one of its ancestors is invalid.
794 } else if (block->nChainTx == 0) {
795 // This block cannot be connected because full block data for it or one of its parents is missing.
796 status = "headers-only";
797 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
798 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
799 status = "valid-fork";
800 } else if (block->IsValid(BLOCK_VALID_TREE)) {
801 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
802 status = "valid-headers";
807 obj.push_back(Pair("status", status));
815 UniValue mempoolInfoToJSON()
817 UniValue ret(UniValue::VOBJ);
818 ret.push_back(Pair("size", (int64_t) mempool.size()));
819 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
820 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
825 UniValue getmempoolinfo(const UniValue& params, bool fHelp)
827 if (fHelp || params.size() != 0)
830 "\nReturns details on the active state of the TX memory pool.\n"
833 " \"size\": xxxxx (numeric) Current tx count\n"
834 " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
835 " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n"
838 + HelpExampleCli("getmempoolinfo", "")
839 + HelpExampleRpc("getmempoolinfo", "")
842 return mempoolInfoToJSON();
845 UniValue invalidateblock(const UniValue& params, bool fHelp)
847 if (fHelp || params.size() != 1)
849 "invalidateblock \"hash\"\n"
850 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
852 "1. hash (string, required) the hash of the block to mark as invalid\n"
855 + HelpExampleCli("invalidateblock", "\"blockhash\"")
856 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
859 std::string strHash = params[0].get_str();
860 uint256 hash(uint256S(strHash));
861 CValidationState state;
865 if (mapBlockIndex.count(hash) == 0)
866 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
868 CBlockIndex* pblockindex = mapBlockIndex[hash];
869 InvalidateBlock(state, pblockindex);
872 if (state.IsValid()) {
873 ActivateBestChain(state);
876 if (!state.IsValid()) {
877 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
883 UniValue reconsiderblock(const UniValue& params, bool fHelp)
885 if (fHelp || params.size() != 1)
887 "reconsiderblock \"hash\"\n"
888 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
889 "This can be used to undo the effects of invalidateblock.\n"
891 "1. hash (string, required) the hash of the block to reconsider\n"
894 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
895 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
898 std::string strHash = params[0].get_str();
899 uint256 hash(uint256S(strHash));
900 CValidationState state;
904 if (mapBlockIndex.count(hash) == 0)
905 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
907 CBlockIndex* pblockindex = mapBlockIndex[hash];
908 ReconsiderBlock(state, pblockindex);
911 if (state.IsValid()) {
912 ActivateBestChain(state);
915 if (!state.IsValid()) {
916 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());