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.
6 #include "checkpoints.h"
7 #include "consensus/validation.h"
9 #include "primitives/transaction.h"
10 #include "rpcserver.h"
20 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
21 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
23 double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
25 // Floating point number that is a multiple of the minimum difficulty,
26 // minimum difficulty = 1.0.
27 if (blockindex == NULL)
29 if (chainActive.Tip() == NULL)
32 blockindex = chainActive.Tip();
36 if (networkDifficulty) {
37 bits = GetNextWorkRequired(blockindex, nullptr, Params().GetConsensus());
39 bits = blockindex->nBits;
43 UintToArith256(Params().GetConsensus().powLimit).GetCompact();
44 int nShift = (bits >> 24) & 0xff;
45 int nShiftAmount = (powLimit >> 24) & 0xff;
48 (double)(powLimit & 0x00ffffff) /
49 (double)(bits & 0x00ffffff);
51 while (nShift < nShiftAmount)
56 while (nShift > nShiftAmount)
65 double GetDifficulty(const CBlockIndex* blockindex)
67 return GetDifficultyINTERNAL(blockindex, false);
70 double GetNetworkDifficulty(const CBlockIndex* blockindex)
72 return GetDifficultyINTERNAL(blockindex, true);
75 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
77 UniValue result(UniValue::VOBJ);
78 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
79 int confirmations = -1;
80 // Only report confirmations if the block is on the main chain
81 if (chainActive.Contains(blockindex))
82 confirmations = chainActive.Height() - blockindex->nHeight + 1;
83 result.push_back(Pair("confirmations", confirmations));
84 result.push_back(Pair("height", blockindex->nHeight));
85 result.push_back(Pair("version", blockindex->nVersion));
86 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
87 result.push_back(Pair("time", (int64_t)blockindex->nTime));
88 result.push_back(Pair("nonce", blockindex->nNonce.GetHex()));
89 result.push_back(Pair("solution", HexStr(blockindex->nSolution)));
90 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
91 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
92 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
94 if (blockindex->pprev)
95 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
96 CBlockIndex *pnext = chainActive.Next(blockindex);
98 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
102 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
104 UniValue result(UniValue::VOBJ);
105 result.push_back(Pair("hash", block.GetHash().GetHex()));
106 int confirmations = -1;
107 // Only report confirmations if the block is on the main chain
108 if (chainActive.Contains(blockindex))
109 confirmations = chainActive.Height() - blockindex->nHeight + 1;
110 result.push_back(Pair("confirmations", confirmations));
111 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
112 result.push_back(Pair("height", blockindex->nHeight));
113 result.push_back(Pair("version", block.nVersion));
114 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
115 UniValue txs(UniValue::VARR);
116 BOOST_FOREACH(const CTransaction&tx, block.vtx)
120 UniValue objTx(UniValue::VOBJ);
121 TxToJSON(tx, uint256(), objTx);
122 txs.push_back(objTx);
125 txs.push_back(tx.GetHash().GetHex());
127 result.push_back(Pair("tx", txs));
128 result.push_back(Pair("time", block.GetBlockTime()));
129 result.push_back(Pair("nonce", block.nNonce.GetHex()));
130 result.push_back(Pair("solution", HexStr(block.nSolution)));
131 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
132 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
133 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
135 if (blockindex->pprev)
136 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
137 CBlockIndex *pnext = chainActive.Next(blockindex);
139 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
143 UniValue getblockcount(const UniValue& params, bool fHelp)
145 if (fHelp || params.size() != 0)
148 "\nReturns the number of blocks in the longest block chain.\n"
150 "n (numeric) The current block count\n"
152 + HelpExampleCli("getblockcount", "")
153 + HelpExampleRpc("getblockcount", "")
157 return chainActive.Height();
160 UniValue getbestblockhash(const UniValue& params, bool fHelp)
162 if (fHelp || params.size() != 0)
165 "\nReturns the hash of the best (tip) block in the longest block chain.\n"
167 "\"hex\" (string) the block hash hex encoded\n"
169 + HelpExampleCli("getbestblockhash", "")
170 + HelpExampleRpc("getbestblockhash", "")
174 return chainActive.Tip()->GetBlockHash().GetHex();
177 UniValue getdifficulty(const UniValue& params, bool fHelp)
179 if (fHelp || params.size() != 0)
182 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
184 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
186 + HelpExampleCli("getdifficulty", "")
187 + HelpExampleRpc("getdifficulty", "")
191 return GetNetworkDifficulty();
195 UniValue getrawmempool(const UniValue& params, bool fHelp)
197 if (fHelp || params.size() > 1)
199 "getrawmempool ( verbose )\n"
200 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
202 "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
203 "\nResult: (for verbose = false):\n"
204 "[ (json array of string)\n"
205 " \"transactionid\" (string) The transaction id\n"
208 "\nResult: (for verbose = true):\n"
210 " \"transactionid\" : { (json object)\n"
211 " \"size\" : n, (numeric) transaction size in bytes\n"
212 " \"fee\" : n, (numeric) transaction fee in bitcoins\n"
213 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
214 " \"height\" : n, (numeric) block height when transaction entered pool\n"
215 " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
216 " \"currentpriority\" : n, (numeric) transaction priority now\n"
217 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
218 " \"transactionid\", (string) parent transaction id\n"
223 + HelpExampleCli("getrawmempool", "true")
224 + HelpExampleRpc("getrawmempool", "true")
229 bool fVerbose = false;
230 if (params.size() > 0)
231 fVerbose = params[0].get_bool();
236 UniValue o(UniValue::VOBJ);
237 BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
239 const uint256& hash = entry.first;
240 const CTxMemPoolEntry& e = entry.second;
241 UniValue info(UniValue::VOBJ);
242 info.push_back(Pair("size", (int)e.GetTxSize()));
243 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
244 info.push_back(Pair("time", e.GetTime()));
245 info.push_back(Pair("height", (int)e.GetHeight()));
246 info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
247 info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
248 const CTransaction& tx = e.GetTx();
249 set<string> setDepends;
250 BOOST_FOREACH(const CTxIn& txin, tx.vin)
252 if (mempool.exists(txin.prevout.hash))
253 setDepends.insert(txin.prevout.hash.ToString());
256 UniValue depends(UniValue::VARR);
257 BOOST_FOREACH(const string& dep, setDepends)
259 depends.push_back(dep);
262 info.push_back(Pair("depends", depends));
263 o.push_back(Pair(hash.ToString(), info));
269 vector<uint256> vtxid;
270 mempool.queryHashes(vtxid);
272 UniValue a(UniValue::VARR);
273 BOOST_FOREACH(const uint256& hash, vtxid)
274 a.push_back(hash.ToString());
280 UniValue getblockhash(const UniValue& params, bool fHelp)
282 if (fHelp || params.size() != 1)
284 "getblockhash index\n"
285 "\nReturns hash of block in best-block-chain at index provided.\n"
287 "1. index (numeric, required) The block index\n"
289 "\"hash\" (string) The block hash\n"
291 + HelpExampleCli("getblockhash", "1000")
292 + HelpExampleRpc("getblockhash", "1000")
297 int nHeight = params[0].get_int();
298 if (nHeight < 0 || nHeight > chainActive.Height())
299 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
301 CBlockIndex* pblockindex = chainActive[nHeight];
302 return pblockindex->GetBlockHash().GetHex();
305 UniValue getblockheader(const UniValue& params, bool fHelp)
307 if (fHelp || params.size() < 1 || params.size() > 2)
309 "getblockheader \"hash\" ( verbose )\n"
310 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
311 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
313 "1. \"hash\" (string, required) The block hash\n"
314 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
315 "\nResult (for verbose = true):\n"
317 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
318 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
319 " \"height\" : n, (numeric) The block height or index\n"
320 " \"version\" : n, (numeric) The block version\n"
321 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
322 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
323 " \"nonce\" : n, (numeric) The nonce\n"
324 " \"bits\" : \"1d00ffff\", (string) The bits\n"
325 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
326 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
327 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
329 "\nResult (for verbose=false):\n"
330 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
332 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
333 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
338 std::string strHash = params[0].get_str();
339 uint256 hash(uint256S(strHash));
341 bool fVerbose = true;
342 if (params.size() > 1)
343 fVerbose = params[1].get_bool();
345 if (mapBlockIndex.count(hash) == 0)
346 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
348 CBlockIndex* pblockindex = mapBlockIndex[hash];
352 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
353 ssBlock << pblockindex->GetBlockHeader();
354 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
358 return blockheaderToJSON(pblockindex);
361 UniValue getblock(const UniValue& params, bool fHelp)
363 if (fHelp || params.size() < 1 || params.size() > 2)
365 "getblock \"hash\" ( verbose )\n"
366 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
367 "If verbose is true, returns an Object with information about block <hash>.\n"
369 "1. \"hash\" (string, required) The block hash\n"
370 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
371 "\nResult (for verbose = true):\n"
373 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
374 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
375 " \"size\" : n, (numeric) The block size\n"
376 " \"height\" : n, (numeric) The block height or index\n"
377 " \"version\" : n, (numeric) The block version\n"
378 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
379 " \"tx\" : [ (array of string) The transaction ids\n"
380 " \"transactionid\" (string) The transaction id\n"
383 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
384 " \"nonce\" : n, (numeric) The nonce\n"
385 " \"bits\" : \"1d00ffff\", (string) The bits\n"
386 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
387 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
388 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
390 "\nResult (for verbose=false):\n"
391 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
393 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
394 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
399 std::string strHash = params[0].get_str();
400 uint256 hash(uint256S(strHash));
402 bool fVerbose = true;
403 if (params.size() > 1)
404 fVerbose = params[1].get_bool();
406 if (mapBlockIndex.count(hash) == 0)
407 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
410 CBlockIndex* pblockindex = mapBlockIndex[hash];
412 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
413 throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
415 if(!ReadBlockFromDisk(block, pblockindex))
416 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
420 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
422 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
426 return blockToJSON(block, pblockindex);
429 UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
431 if (fHelp || params.size() != 0)
434 "\nReturns statistics about the unspent transaction output set.\n"
435 "Note this call may take some time.\n"
438 " \"height\":n, (numeric) The current block height (index)\n"
439 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
440 " \"transactions\": n, (numeric) The number of transactions\n"
441 " \"txouts\": n, (numeric) The number of output transactions\n"
442 " \"bytes_serialized\": n, (numeric) The serialized size\n"
443 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
444 " \"total_amount\": x.xxx (numeric) The total amount\n"
447 + HelpExampleCli("gettxoutsetinfo", "")
448 + HelpExampleRpc("gettxoutsetinfo", "")
451 UniValue ret(UniValue::VOBJ);
455 if (pcoinsTip->GetStats(stats)) {
456 ret.push_back(Pair("height", (int64_t)stats.nHeight));
457 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
458 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
459 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
460 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
461 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
462 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
467 UniValue gettxout(const UniValue& params, bool fHelp)
469 if (fHelp || params.size() < 2 || params.size() > 3)
471 "gettxout \"txid\" n ( includemempool )\n"
472 "\nReturns details about an unspent transaction output.\n"
474 "1. \"txid\" (string, required) The transaction id\n"
475 "2. n (numeric, required) vout value\n"
476 "3. includemempool (boolean, optional) Whether to included the mem pool\n"
479 " \"bestblock\" : \"hash\", (string) the block hash\n"
480 " \"confirmations\" : n, (numeric) The number of confirmations\n"
481 " \"value\" : x.xxx, (numeric) The transaction value in btc\n"
482 " \"scriptPubKey\" : { (json object)\n"
483 " \"asm\" : \"code\", (string) \n"
484 " \"hex\" : \"hex\", (string) \n"
485 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
486 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
487 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
488 " \"bitcoinaddress\" (string) bitcoin address\n"
492 " \"version\" : n, (numeric) The version\n"
493 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
497 "\nGet unspent transactions\n"
498 + HelpExampleCli("listunspent", "") +
499 "\nView the details\n"
500 + HelpExampleCli("gettxout", "\"txid\" 1") +
501 "\nAs a json rpc call\n"
502 + HelpExampleRpc("gettxout", "\"txid\", 1")
507 UniValue ret(UniValue::VOBJ);
509 std::string strHash = params[0].get_str();
510 uint256 hash(uint256S(strHash));
511 int n = params[1].get_int();
512 bool fMempool = true;
513 if (params.size() > 2)
514 fMempool = params[2].get_bool();
519 CCoinsViewMemPool view(pcoinsTip, mempool);
520 if (!view.GetCoins(hash, coins))
522 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
524 if (!pcoinsTip->GetCoins(hash, coins))
527 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
530 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
531 CBlockIndex *pindex = it->second;
532 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
533 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
534 ret.push_back(Pair("confirmations", 0));
536 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
537 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
538 UniValue o(UniValue::VOBJ);
539 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
540 ret.push_back(Pair("scriptPubKey", o));
541 ret.push_back(Pair("version", coins.nVersion));
542 ret.push_back(Pair("coinbase", coins.fCoinBase));
547 UniValue verifychain(const UniValue& params, bool fHelp)
549 if (fHelp || params.size() > 2)
551 "verifychain ( checklevel numblocks )\n"
552 "\nVerifies blockchain database.\n"
554 "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
555 "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
557 "true|false (boolean) Verified or not\n"
559 + HelpExampleCli("verifychain", "")
560 + HelpExampleRpc("verifychain", "")
565 int nCheckLevel = GetArg("-checklevel", 3);
566 int nCheckDepth = GetArg("-checkblocks", 288);
567 if (params.size() > 0)
568 nCheckLevel = params[0].get_int();
569 if (params.size() > 1)
570 nCheckDepth = params[1].get_int();
572 return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth);
575 /** Implementation of IsSuperMajority with better feedback */
576 static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
579 CBlockIndex* pstart = pindex;
580 for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
582 if (pstart->nVersion >= minVersion)
584 pstart = pstart->pprev;
587 UniValue rv(UniValue::VOBJ);
588 rv.push_back(Pair("status", nFound >= nRequired));
589 rv.push_back(Pair("found", nFound));
590 rv.push_back(Pair("required", nRequired));
591 rv.push_back(Pair("window", consensusParams.nMajorityWindow));
595 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
597 UniValue rv(UniValue::VOBJ);
598 rv.push_back(Pair("id", name));
599 rv.push_back(Pair("version", version));
600 rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
601 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
605 UniValue getblockchaininfo(const UniValue& params, bool fHelp)
607 if (fHelp || params.size() != 0)
609 "getblockchaininfo\n"
610 "Returns an object containing various state info regarding block chain processing.\n"
613 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
614 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
615 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
616 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
617 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
618 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
619 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
620 " \"commitments\": xxxxxx, (numeric) the current number of note commitments in the commitment tree\n"
621 " \"softforks\": [ (array) status of softforks in progress\n"
623 " \"id\": \"xxxx\", (string) name of softfork\n"
624 " \"version\": xx, (numeric) block version\n"
625 " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
626 " \"status\": xx, (boolean) true if threshold reached\n"
627 " \"found\": xx, (numeric) number of blocks with the new version found\n"
628 " \"required\": xx, (numeric) number of blocks required to trigger\n"
629 " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
631 " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
636 + HelpExampleCli("getblockchaininfo", "")
637 + HelpExampleRpc("getblockchaininfo", "")
642 UniValue obj(UniValue::VOBJ);
643 obj.push_back(Pair("chain", Params().NetworkIDString()));
644 obj.push_back(Pair("blocks", (int)chainActive.Height()));
645 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
646 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
647 obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
648 obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
649 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
650 obj.push_back(Pair("pruned", fPruneMode));
652 ZCIncrementalMerkleTree tree;
653 pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), tree);
654 obj.push_back(Pair("commitments", tree.size()));
656 const Consensus::Params& consensusParams = Params().GetConsensus();
657 CBlockIndex* tip = chainActive.Tip();
658 UniValue softforks(UniValue::VARR);
659 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
660 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
661 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
662 obj.push_back(Pair("softforks", softforks));
666 CBlockIndex *block = chainActive.Tip();
667 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
668 block = block->pprev;
670 obj.push_back(Pair("pruneheight", block->nHeight));
675 /** Comparison function for sorting the getchaintips heads. */
676 struct CompareBlocksByHeight
678 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
680 /* Make sure that unequal blocks with the same height do not compare
681 equal. Use the pointers themselves to make a distinction. */
683 if (a->nHeight != b->nHeight)
684 return (a->nHeight > b->nHeight);
690 UniValue getchaintips(const UniValue& params, bool fHelp)
692 if (fHelp || params.size() != 0)
695 "Return information about all known tips in the block tree,"
696 " including the main chain as well as orphaned branches.\n"
700 " \"height\": xxxx, (numeric) height of the chain tip\n"
701 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
702 " \"branchlen\": 0 (numeric) zero for main chain\n"
703 " \"status\": \"active\" (string) \"active\" for the main chain\n"
706 " \"height\": xxxx,\n"
707 " \"hash\": \"xxxx\",\n"
708 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
709 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
712 "Possible values for status:\n"
713 "1. \"invalid\" This branch contains at least one invalid block\n"
714 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
715 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
716 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
717 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
719 + HelpExampleCli("getchaintips", "")
720 + HelpExampleRpc("getchaintips", "")
725 /* Build up a list of chain tips. We start with the list of all
726 known blocks, and successively remove blocks that appear as pprev
728 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
729 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
730 setTips.insert(item.second);
731 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
733 const CBlockIndex* pprev = item.second->pprev;
735 setTips.erase(pprev);
738 // Always report the currently active tip.
739 setTips.insert(chainActive.Tip());
741 /* Construct the output array. */
742 UniValue res(UniValue::VARR);
743 BOOST_FOREACH(const CBlockIndex* block, setTips)
745 UniValue obj(UniValue::VOBJ);
746 obj.push_back(Pair("height", block->nHeight));
747 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
749 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
750 obj.push_back(Pair("branchlen", branchLen));
753 if (chainActive.Contains(block)) {
754 // This block is part of the currently active chain.
756 } else if (block->nStatus & BLOCK_FAILED_MASK) {
757 // This block or one of its ancestors is invalid.
759 } else if (block->nChainTx == 0) {
760 // This block cannot be connected because full block data for it or one of its parents is missing.
761 status = "headers-only";
762 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
763 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
764 status = "valid-fork";
765 } else if (block->IsValid(BLOCK_VALID_TREE)) {
766 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
767 status = "valid-headers";
772 obj.push_back(Pair("status", status));
780 UniValue getmempoolinfo(const UniValue& params, bool fHelp)
782 if (fHelp || params.size() != 0)
785 "\nReturns details on the active state of the TX memory pool.\n"
788 " \"size\": xxxxx (numeric) Current tx count\n"
789 " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
790 " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n"
793 + HelpExampleCli("getmempoolinfo", "")
794 + HelpExampleRpc("getmempoolinfo", "")
797 UniValue ret(UniValue::VOBJ);
798 ret.push_back(Pair("size", (int64_t) mempool.size()));
799 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
800 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
805 UniValue invalidateblock(const UniValue& params, bool fHelp)
807 if (fHelp || params.size() != 1)
809 "invalidateblock \"hash\"\n"
810 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
812 "1. hash (string, required) the hash of the block to mark as invalid\n"
815 + HelpExampleCli("invalidateblock", "\"blockhash\"")
816 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
819 std::string strHash = params[0].get_str();
820 uint256 hash(uint256S(strHash));
821 CValidationState state;
825 if (mapBlockIndex.count(hash) == 0)
826 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
828 CBlockIndex* pblockindex = mapBlockIndex[hash];
829 InvalidateBlock(state, pblockindex);
832 if (state.IsValid()) {
833 ActivateBestChain(state);
836 if (!state.IsValid()) {
837 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
843 UniValue reconsiderblock(const UniValue& params, bool fHelp)
845 if (fHelp || params.size() != 1)
847 "reconsiderblock \"hash\"\n"
848 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
849 "This can be used to undo the effects of invalidateblock.\n"
851 "1. hash (string, required) the hash of the block to reconsider\n"
854 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
855 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
858 std::string strHash = params[0].get_str();
859 uint256 hash(uint256S(strHash));
860 CValidationState state;
864 if (mapBlockIndex.count(hash) == 0)
865 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
867 CBlockIndex* pblockindex = mapBlockIndex[hash];
868 ReconsiderBlock(state, pblockindex);
871 if (state.IsValid()) {
872 ActivateBestChain(state);
875 if (!state.IsValid()) {
876 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());