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 static UniValue ValuePoolDesc(
81 const std::string &name,
82 const boost::optional<CAmount> chainValue,
83 const boost::optional<CAmount> valueDelta)
85 UniValue rv(UniValue::VOBJ);
86 rv.push_back(Pair("id", name));
87 rv.push_back(Pair("monitored", (bool)chainValue));
89 rv.push_back(Pair("chainValue", ValueFromAmount(*chainValue)));
90 rv.push_back(Pair("chainValueZat", *chainValue));
93 rv.push_back(Pair("valueDelta", ValueFromAmount(*valueDelta)));
94 rv.push_back(Pair("valueDeltaZat", *valueDelta));
99 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
101 UniValue result(UniValue::VOBJ);
102 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
103 int confirmations = -1;
104 // Only report confirmations if the block is on the main chain
105 if (chainActive.Contains(blockindex))
106 confirmations = chainActive.Height() - blockindex->nHeight + 1;
107 result.push_back(Pair("confirmations", confirmations));
108 result.push_back(Pair("height", blockindex->nHeight));
109 result.push_back(Pair("version", blockindex->nVersion));
110 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
111 result.push_back(Pair("time", (int64_t)blockindex->nTime));
112 result.push_back(Pair("nonce", blockindex->nNonce.GetHex()));
113 result.push_back(Pair("solution", HexStr(blockindex->nSolution)));
114 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
115 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
116 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
118 if (blockindex->pprev)
119 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
120 CBlockIndex *pnext = chainActive.Next(blockindex);
122 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
126 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
128 UniValue result(UniValue::VOBJ);
129 result.push_back(Pair("hash", block.GetHash().GetHex()));
130 int confirmations = -1;
131 // Only report confirmations if the block is on the main chain
132 if (chainActive.Contains(blockindex))
133 confirmations = chainActive.Height() - blockindex->nHeight + 1;
134 result.push_back(Pair("confirmations", confirmations));
135 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
136 result.push_back(Pair("height", blockindex->nHeight));
137 result.push_back(Pair("version", block.nVersion));
138 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
139 UniValue txs(UniValue::VARR);
140 BOOST_FOREACH(const CTransaction&tx, block.vtx)
144 UniValue objTx(UniValue::VOBJ);
145 TxToJSON(tx, uint256(), objTx);
146 txs.push_back(objTx);
149 txs.push_back(tx.GetHash().GetHex());
151 result.push_back(Pair("tx", txs));
152 result.push_back(Pair("time", block.GetBlockTime()));
153 result.push_back(Pair("nonce", block.nNonce.GetHex()));
154 result.push_back(Pair("solution", HexStr(block.nSolution)));
155 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
156 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
157 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
158 result.push_back(Pair("anchor", blockindex->hashAnchorEnd.GetHex()));
160 UniValue valuePools(UniValue::VARR);
161 valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue));
162 result.push_back(Pair("valuePools", valuePools));
164 if (blockindex->pprev)
165 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
166 CBlockIndex *pnext = chainActive.Next(blockindex);
168 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
172 UniValue getblockcount(const UniValue& params, bool fHelp)
174 if (fHelp || params.size() != 0)
177 "\nReturns the number of blocks in the longest block chain.\n"
179 "n (numeric) The current block count\n"
181 + HelpExampleCli("getblockcount", "")
182 + HelpExampleRpc("getblockcount", "")
186 return chainActive.Height();
189 UniValue getbestblockhash(const UniValue& params, bool fHelp)
191 if (fHelp || params.size() != 0)
194 "\nReturns the hash of the best (tip) block in the longest block chain.\n"
196 "\"hex\" (string) the block hash hex encoded\n"
198 + HelpExampleCli("getbestblockhash", "")
199 + HelpExampleRpc("getbestblockhash", "")
203 return chainActive.Tip()->GetBlockHash().GetHex();
206 UniValue getdifficulty(const UniValue& params, bool fHelp)
208 if (fHelp || params.size() != 0)
211 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
213 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
215 + HelpExampleCli("getdifficulty", "")
216 + HelpExampleRpc("getdifficulty", "")
220 return GetNetworkDifficulty();
223 UniValue mempoolToJSON(bool fVerbose = false)
228 UniValue o(UniValue::VOBJ);
229 BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
231 const uint256& hash = entry.first;
232 const CTxMemPoolEntry& e = entry.second;
233 UniValue info(UniValue::VOBJ);
234 info.push_back(Pair("size", (int)e.GetTxSize()));
235 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
236 info.push_back(Pair("time", e.GetTime()));
237 info.push_back(Pair("height", (int)e.GetHeight()));
238 info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
239 info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
240 const CTransaction& tx = e.GetTx();
241 set<string> setDepends;
242 BOOST_FOREACH(const CTxIn& txin, tx.vin)
244 if (mempool.exists(txin.prevout.hash))
245 setDepends.insert(txin.prevout.hash.ToString());
248 UniValue depends(UniValue::VARR);
249 BOOST_FOREACH(const string& dep, setDepends)
251 depends.push_back(dep);
254 info.push_back(Pair("depends", depends));
255 o.push_back(Pair(hash.ToString(), info));
261 vector<uint256> vtxid;
262 mempool.queryHashes(vtxid);
264 UniValue a(UniValue::VARR);
265 BOOST_FOREACH(const uint256& hash, vtxid)
266 a.push_back(hash.ToString());
272 UniValue getrawmempool(const UniValue& params, bool fHelp)
274 if (fHelp || params.size() > 1)
276 "getrawmempool ( verbose )\n"
277 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
279 "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
280 "\nResult: (for verbose = false):\n"
281 "[ (json array of string)\n"
282 " \"transactionid\" (string) The transaction id\n"
285 "\nResult: (for verbose = true):\n"
287 " \"transactionid\" : { (json object)\n"
288 " \"size\" : n, (numeric) transaction size in bytes\n"
289 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
290 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
291 " \"height\" : n, (numeric) block height when transaction entered pool\n"
292 " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
293 " \"currentpriority\" : n, (numeric) transaction priority now\n"
294 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
295 " \"transactionid\", (string) parent transaction id\n"
300 + HelpExampleCli("getrawmempool", "true")
301 + HelpExampleRpc("getrawmempool", "true")
306 bool fVerbose = false;
307 if (params.size() > 0)
308 fVerbose = params[0].get_bool();
310 return mempoolToJSON(fVerbose);
313 UniValue getblockhash(const UniValue& params, bool fHelp)
315 if (fHelp || params.size() != 1)
317 "getblockhash index\n"
318 "\nReturns hash of block in best-block-chain at index provided.\n"
320 "1. index (numeric, required) The block index\n"
322 "\"hash\" (string) The block hash\n"
324 + HelpExampleCli("getblockhash", "1000")
325 + HelpExampleRpc("getblockhash", "1000")
330 int nHeight = params[0].get_int();
331 if (nHeight < 0 || nHeight > chainActive.Height())
332 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
334 CBlockIndex* pblockindex = chainActive[nHeight];
335 return pblockindex->GetBlockHash().GetHex();
338 UniValue getblockheader(const UniValue& params, bool fHelp)
340 if (fHelp || params.size() < 1 || params.size() > 2)
342 "getblockheader \"hash\" ( verbose )\n"
343 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
344 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
346 "1. \"hash\" (string, required) The block hash\n"
347 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
348 "\nResult (for verbose = true):\n"
350 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
351 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
352 " \"height\" : n, (numeric) The block height or index\n"
353 " \"version\" : n, (numeric) The block version\n"
354 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
355 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
356 " \"nonce\" : n, (numeric) The nonce\n"
357 " \"bits\" : \"1d00ffff\", (string) The bits\n"
358 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
359 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
360 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
362 "\nResult (for verbose=false):\n"
363 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
365 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
366 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
371 std::string strHash = params[0].get_str();
372 uint256 hash(uint256S(strHash));
374 bool fVerbose = true;
375 if (params.size() > 1)
376 fVerbose = params[1].get_bool();
378 if (mapBlockIndex.count(hash) == 0)
379 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
381 CBlockIndex* pblockindex = mapBlockIndex[hash];
385 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
386 ssBlock << pblockindex->GetBlockHeader();
387 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
391 return blockheaderToJSON(pblockindex);
394 UniValue getblock(const UniValue& params, bool fHelp)
396 if (fHelp || params.size() < 1 || params.size() > 2)
398 "getblock \"hash|height\" ( verbose )\n"
399 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash|height'.\n"
400 "If verbose is true, returns an Object with information about block <hash|height>.\n"
402 "1. \"hash|height\" (string, required) The block hash or height\n"
403 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
404 "\nResult (for verbose = true):\n"
406 " \"hash\" : \"hash\", (string) the block hash (same as provided hash)\n"
407 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
408 " \"size\" : n, (numeric) The block size\n"
409 " \"height\" : n, (numeric) The block height or index (same as provided height)\n"
410 " \"version\" : n, (numeric) The block version\n"
411 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
412 " \"tx\" : [ (array of string) The transaction ids\n"
413 " \"transactionid\" (string) The transaction id\n"
416 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
417 " \"nonce\" : n, (numeric) The nonce\n"
418 " \"bits\" : \"1d00ffff\", (string) The bits\n"
419 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
420 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
421 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
423 "\nResult (for verbose=false):\n"
424 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
426 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
427 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
428 + HelpExampleCli("getblock", "12800")
429 + HelpExampleRpc("getblock", "12800")
434 std::string strHash = params[0].get_str();
436 // If height is supplied, find the hash
437 if (strHash.size() < (2 * sizeof(uint256))) {
438 // std::stoi allows characters, whereas we want to be strict
439 regex r("[[:digit:]]+");
440 if (!regex_match(strHash, r)) {
441 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
446 nHeight = std::stoi(strHash);
448 catch (const std::exception &e) {
449 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
452 if (nHeight < 0 || nHeight > chainActive.Height()) {
453 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
455 strHash = chainActive[nHeight]->GetBlockHash().GetHex();
458 uint256 hash(uint256S(strHash));
460 bool fVerbose = true;
461 if (params.size() > 1)
462 fVerbose = params[1].get_bool();
464 if (mapBlockIndex.count(hash) == 0)
465 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
468 CBlockIndex* pblockindex = mapBlockIndex[hash];
470 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
471 throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
473 if(!ReadBlockFromDisk(block, pblockindex))
474 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
478 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
480 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
484 return blockToJSON(block, pblockindex);
487 UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
489 if (fHelp || params.size() != 0)
492 "\nReturns statistics about the unspent transaction output set.\n"
493 "Note this call may take some time.\n"
496 " \"height\":n, (numeric) The current block height (index)\n"
497 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
498 " \"transactions\": n, (numeric) The number of transactions\n"
499 " \"txouts\": n, (numeric) The number of output transactions\n"
500 " \"bytes_serialized\": n, (numeric) The serialized size\n"
501 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
502 " \"total_amount\": x.xxx (numeric) The total amount\n"
505 + HelpExampleCli("gettxoutsetinfo", "")
506 + HelpExampleRpc("gettxoutsetinfo", "")
509 UniValue ret(UniValue::VOBJ);
513 if (pcoinsTip->GetStats(stats)) {
514 ret.push_back(Pair("height", (int64_t)stats.nHeight));
515 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
516 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
517 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
518 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
519 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
520 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
525 UniValue gettxout(const UniValue& params, bool fHelp)
527 if (fHelp || params.size() < 2 || params.size() > 3)
529 "gettxout \"txid\" n ( includemempool )\n"
530 "\nReturns details about an unspent transaction output.\n"
532 "1. \"txid\" (string, required) The transaction id\n"
533 "2. n (numeric, required) vout value\n"
534 "3. includemempool (boolean, optional) Whether to included the mem pool\n"
537 " \"bestblock\" : \"hash\", (string) the block hash\n"
538 " \"confirmations\" : n, (numeric) The number of confirmations\n"
539 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
540 " \"scriptPubKey\" : { (json object)\n"
541 " \"asm\" : \"code\", (string) \n"
542 " \"hex\" : \"hex\", (string) \n"
543 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
544 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
545 " \"addresses\" : [ (array of string) array of Zcash addresses\n"
546 " \"zcashaddress\" (string) Zcash address\n"
550 " \"version\" : n, (numeric) The version\n"
551 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
555 "\nGet unspent transactions\n"
556 + HelpExampleCli("listunspent", "") +
557 "\nView the details\n"
558 + HelpExampleCli("gettxout", "\"txid\" 1") +
559 "\nAs a json rpc call\n"
560 + HelpExampleRpc("gettxout", "\"txid\", 1")
565 UniValue ret(UniValue::VOBJ);
567 std::string strHash = params[0].get_str();
568 uint256 hash(uint256S(strHash));
569 int n = params[1].get_int();
570 bool fMempool = true;
571 if (params.size() > 2)
572 fMempool = params[2].get_bool();
577 CCoinsViewMemPool view(pcoinsTip, mempool);
578 if (!view.GetCoins(hash, coins))
580 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
582 if (!pcoinsTip->GetCoins(hash, coins))
585 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
588 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
589 CBlockIndex *pindex = it->second;
590 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
591 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
592 ret.push_back(Pair("confirmations", 0));
594 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
595 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
596 UniValue o(UniValue::VOBJ);
597 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
598 ret.push_back(Pair("scriptPubKey", o));
599 ret.push_back(Pair("version", coins.nVersion));
600 ret.push_back(Pair("coinbase", coins.fCoinBase));
605 UniValue verifychain(const UniValue& params, bool fHelp)
607 if (fHelp || params.size() > 2)
609 "verifychain ( checklevel numblocks )\n"
610 "\nVerifies blockchain database.\n"
612 "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
613 "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
615 "true|false (boolean) Verified or not\n"
617 + HelpExampleCli("verifychain", "")
618 + HelpExampleRpc("verifychain", "")
623 int nCheckLevel = GetArg("-checklevel", 3);
624 int nCheckDepth = GetArg("-checkblocks", 288);
625 if (params.size() > 0)
626 nCheckLevel = params[0].get_int();
627 if (params.size() > 1)
628 nCheckDepth = params[1].get_int();
630 return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth);
633 /** Implementation of IsSuperMajority with better feedback */
634 static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
637 CBlockIndex* pstart = pindex;
638 for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
640 if (pstart->nVersion >= minVersion)
642 pstart = pstart->pprev;
645 UniValue rv(UniValue::VOBJ);
646 rv.push_back(Pair("status", nFound >= nRequired));
647 rv.push_back(Pair("found", nFound));
648 rv.push_back(Pair("required", nRequired));
649 rv.push_back(Pair("window", consensusParams.nMajorityWindow));
653 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
655 UniValue rv(UniValue::VOBJ);
656 rv.push_back(Pair("id", name));
657 rv.push_back(Pair("version", version));
658 rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
659 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
663 UniValue getblockchaininfo(const UniValue& params, bool fHelp)
665 if (fHelp || params.size() != 0)
667 "getblockchaininfo\n"
668 "Returns an object containing various state info regarding block chain processing.\n"
671 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
672 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
673 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
674 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
675 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
676 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
677 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
678 " \"commitments\": xxxxxx, (numeric) the current number of note commitments in the commitment tree\n"
679 " \"softforks\": [ (array) status of softforks in progress\n"
681 " \"id\": \"xxxx\", (string) name of softfork\n"
682 " \"version\": xx, (numeric) block version\n"
683 " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
684 " \"status\": xx, (boolean) true if threshold reached\n"
685 " \"found\": xx, (numeric) number of blocks with the new version found\n"
686 " \"required\": xx, (numeric) number of blocks required to trigger\n"
687 " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
689 " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
694 + HelpExampleCli("getblockchaininfo", "")
695 + HelpExampleRpc("getblockchaininfo", "")
700 UniValue obj(UniValue::VOBJ);
701 obj.push_back(Pair("chain", Params().NetworkIDString()));
702 obj.push_back(Pair("blocks", (int)chainActive.Height()));
703 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
704 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
705 obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
706 obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
707 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
708 obj.push_back(Pair("pruned", fPruneMode));
710 ZCIncrementalMerkleTree tree;
711 pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), tree);
712 obj.push_back(Pair("commitments", tree.size()));
714 CBlockIndex* tip = chainActive.Tip();
715 UniValue valuePools(UniValue::VARR);
716 valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none));
717 obj.push_back(Pair("valuePools", valuePools));
719 const Consensus::Params& consensusParams = Params().GetConsensus();
720 UniValue softforks(UniValue::VARR);
721 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
722 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
723 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
724 obj.push_back(Pair("softforks", softforks));
728 CBlockIndex *block = chainActive.Tip();
729 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
730 block = block->pprev;
732 obj.push_back(Pair("pruneheight", block->nHeight));
737 /** Comparison function for sorting the getchaintips heads. */
738 struct CompareBlocksByHeight
740 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
742 /* Make sure that unequal blocks with the same height do not compare
743 equal. Use the pointers themselves to make a distinction. */
745 if (a->nHeight != b->nHeight)
746 return (a->nHeight > b->nHeight);
752 UniValue getchaintips(const UniValue& params, bool fHelp)
754 if (fHelp || params.size() != 0)
757 "Return information about all known tips in the block tree,"
758 " including the main chain as well as orphaned branches.\n"
762 " \"height\": xxxx, (numeric) height of the chain tip\n"
763 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
764 " \"branchlen\": 0 (numeric) zero for main chain\n"
765 " \"status\": \"active\" (string) \"active\" for the main chain\n"
768 " \"height\": xxxx,\n"
769 " \"hash\": \"xxxx\",\n"
770 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
771 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
774 "Possible values for status:\n"
775 "1. \"invalid\" This branch contains at least one invalid block\n"
776 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
777 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
778 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
779 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
781 + HelpExampleCli("getchaintips", "")
782 + HelpExampleRpc("getchaintips", "")
787 /* Build up a list of chain tips. We start with the list of all
788 known blocks, and successively remove blocks that appear as pprev
790 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
791 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
792 setTips.insert(item.second);
793 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
795 const CBlockIndex* pprev = item.second->pprev;
797 setTips.erase(pprev);
800 // Always report the currently active tip.
801 setTips.insert(chainActive.Tip());
803 /* Construct the output array. */
804 UniValue res(UniValue::VARR);
805 BOOST_FOREACH(const CBlockIndex* block, setTips)
807 UniValue obj(UniValue::VOBJ);
808 obj.push_back(Pair("height", block->nHeight));
809 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
811 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
812 obj.push_back(Pair("branchlen", branchLen));
815 if (chainActive.Contains(block)) {
816 // This block is part of the currently active chain.
818 } else if (block->nStatus & BLOCK_FAILED_MASK) {
819 // This block or one of its ancestors is invalid.
821 } else if (block->nChainTx == 0) {
822 // This block cannot be connected because full block data for it or one of its parents is missing.
823 status = "headers-only";
824 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
825 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
826 status = "valid-fork";
827 } else if (block->IsValid(BLOCK_VALID_TREE)) {
828 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
829 status = "valid-headers";
834 obj.push_back(Pair("status", status));
842 UniValue mempoolInfoToJSON()
844 UniValue ret(UniValue::VOBJ);
845 ret.push_back(Pair("size", (int64_t) mempool.size()));
846 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
847 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
852 UniValue getmempoolinfo(const UniValue& params, bool fHelp)
854 if (fHelp || params.size() != 0)
857 "\nReturns details on the active state of the TX memory pool.\n"
860 " \"size\": xxxxx (numeric) Current tx count\n"
861 " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
862 " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n"
865 + HelpExampleCli("getmempoolinfo", "")
866 + HelpExampleRpc("getmempoolinfo", "")
869 return mempoolInfoToJSON();
872 UniValue invalidateblock(const UniValue& params, bool fHelp)
874 if (fHelp || params.size() != 1)
876 "invalidateblock \"hash\"\n"
877 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
879 "1. hash (string, required) the hash of the block to mark as invalid\n"
882 + HelpExampleCli("invalidateblock", "\"blockhash\"")
883 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
886 std::string strHash = params[0].get_str();
887 uint256 hash(uint256S(strHash));
888 CValidationState state;
892 if (mapBlockIndex.count(hash) == 0)
893 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
895 CBlockIndex* pblockindex = mapBlockIndex[hash];
896 InvalidateBlock(state, pblockindex);
899 if (state.IsValid()) {
900 ActivateBestChain(state);
903 if (!state.IsValid()) {
904 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
910 UniValue reconsiderblock(const UniValue& params, bool fHelp)
912 if (fHelp || params.size() != 1)
914 "reconsiderblock \"hash\"\n"
915 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
916 "This can be used to undo the effects of invalidateblock.\n"
918 "1. hash (string, required) the hash of the block to reconsider\n"
921 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
922 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
925 std::string strHash = params[0].get_str();
926 uint256 hash(uint256S(strHash));
927 CValidationState state;
931 if (mapBlockIndex.count(hash) == 0)
932 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
934 CBlockIndex* pblockindex = mapBlockIndex[hash];
935 ReconsiderBlock(state, pblockindex);
938 if (state.IsValid()) {
939 ActivateBestChain(state);
942 if (!state.IsValid()) {
943 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());