refactor TxToJSON() and ScriptPubKeyToJSON()
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blob8f446aee652a291155e2dcc51830526fbbbeb1fb
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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 "rpc/blockchain.h"
8 #include "amount.h"
9 #include "chain.h"
10 #include "chainparams.h"
11 #include "checkpoints.h"
12 #include "coins.h"
13 #include "consensus/validation.h"
14 #include "validation.h"
15 #include "core_io.h"
16 #include "policy/policy.h"
17 #include "primitives/transaction.h"
18 #include "rpc/server.h"
19 #include "streams.h"
20 #include "sync.h"
21 #include "txmempool.h"
22 #include "util.h"
23 #include "utilstrencodings.h"
24 #include "hash.h"
26 #include <stdint.h>
28 #include <univalue.h>
30 #include <boost/thread/thread.hpp> // boost::thread::interrupt
32 #include <mutex>
33 #include <condition_variable>
35 struct CUpdatedBlock
37 uint256 hash;
38 int height;
41 static std::mutex cs_blockchange;
42 static std::condition_variable cond_blockchange;
43 static CUpdatedBlock latestblock;
45 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
46 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
48 double GetDifficulty(const CBlockIndex* blockindex)
50 if (blockindex == NULL)
52 if (chainActive.Tip() == NULL)
53 return 1.0;
54 else
55 blockindex = chainActive.Tip();
58 int nShift = (blockindex->nBits >> 24) & 0xff;
60 double dDiff =
61 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
63 while (nShift < 29)
65 dDiff *= 256.0;
66 nShift++;
68 while (nShift > 29)
70 dDiff /= 256.0;
71 nShift--;
74 return dDiff;
77 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
79 UniValue result(UniValue::VOBJ);
80 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
81 int confirmations = -1;
82 // Only report confirmations if the block is on the main chain
83 if (chainActive.Contains(blockindex))
84 confirmations = chainActive.Height() - blockindex->nHeight + 1;
85 result.push_back(Pair("confirmations", confirmations));
86 result.push_back(Pair("height", blockindex->nHeight));
87 result.push_back(Pair("version", blockindex->nVersion));
88 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
89 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
90 result.push_back(Pair("time", (int64_t)blockindex->nTime));
91 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
92 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
93 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
94 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
95 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
97 if (blockindex->pprev)
98 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
99 CBlockIndex *pnext = chainActive.Next(blockindex);
100 if (pnext)
101 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
102 return result;
105 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
107 UniValue result(UniValue::VOBJ);
108 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
109 int confirmations = -1;
110 // Only report confirmations if the block is on the main chain
111 if (chainActive.Contains(blockindex))
112 confirmations = chainActive.Height() - blockindex->nHeight + 1;
113 result.push_back(Pair("confirmations", confirmations));
114 result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)));
115 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
116 result.push_back(Pair("weight", (int)::GetBlockWeight(block)));
117 result.push_back(Pair("height", blockindex->nHeight));
118 result.push_back(Pair("version", block.nVersion));
119 result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion)));
120 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
121 UniValue txs(UniValue::VARR);
122 for(const auto& tx : block.vtx)
124 if(txDetails)
126 UniValue objTx(UniValue::VOBJ);
127 TxToUniv(*tx, uint256(), objTx);
128 txs.push_back(objTx);
130 else
131 txs.push_back(tx->GetHash().GetHex());
133 result.push_back(Pair("tx", txs));
134 result.push_back(Pair("time", block.GetBlockTime()));
135 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
136 result.push_back(Pair("nonce", (uint64_t)block.nNonce));
137 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
138 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
139 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
141 if (blockindex->pprev)
142 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
143 CBlockIndex *pnext = chainActive.Next(blockindex);
144 if (pnext)
145 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
146 return result;
149 UniValue getblockcount(const JSONRPCRequest& request)
151 if (request.fHelp || request.params.size() != 0)
152 throw std::runtime_error(
153 "getblockcount\n"
154 "\nReturns the number of blocks in the longest blockchain.\n"
155 "\nResult:\n"
156 "n (numeric) The current block count\n"
157 "\nExamples:\n"
158 + HelpExampleCli("getblockcount", "")
159 + HelpExampleRpc("getblockcount", "")
162 LOCK(cs_main);
163 return chainActive.Height();
166 UniValue getbestblockhash(const JSONRPCRequest& request)
168 if (request.fHelp || request.params.size() != 0)
169 throw std::runtime_error(
170 "getbestblockhash\n"
171 "\nReturns the hash of the best (tip) block in the longest blockchain.\n"
172 "\nResult:\n"
173 "\"hex\" (string) the block hash hex encoded\n"
174 "\nExamples:\n"
175 + HelpExampleCli("getbestblockhash", "")
176 + HelpExampleRpc("getbestblockhash", "")
179 LOCK(cs_main);
180 return chainActive.Tip()->GetBlockHash().GetHex();
183 void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex)
185 if(pindex) {
186 std::lock_guard<std::mutex> lock(cs_blockchange);
187 latestblock.hash = pindex->GetBlockHash();
188 latestblock.height = pindex->nHeight;
190 cond_blockchange.notify_all();
193 UniValue waitfornewblock(const JSONRPCRequest& request)
195 if (request.fHelp || request.params.size() > 1)
196 throw std::runtime_error(
197 "waitfornewblock (timeout)\n"
198 "\nWaits for a specific new block and returns useful info about it.\n"
199 "\nReturns the current block on timeout or exit.\n"
200 "\nArguments:\n"
201 "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
202 "\nResult:\n"
203 "{ (json object)\n"
204 " \"hash\" : { (string) The blockhash\n"
205 " \"height\" : { (int) Block height\n"
206 "}\n"
207 "\nExamples:\n"
208 + HelpExampleCli("waitfornewblock", "1000")
209 + HelpExampleRpc("waitfornewblock", "1000")
211 int timeout = 0;
212 if (request.params.size() > 0)
213 timeout = request.params[0].get_int();
215 CUpdatedBlock block;
217 std::unique_lock<std::mutex> lock(cs_blockchange);
218 block = latestblock;
219 if(timeout)
220 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
221 else
222 cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
223 block = latestblock;
225 UniValue ret(UniValue::VOBJ);
226 ret.push_back(Pair("hash", block.hash.GetHex()));
227 ret.push_back(Pair("height", block.height));
228 return ret;
231 UniValue waitforblock(const JSONRPCRequest& request)
233 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
234 throw std::runtime_error(
235 "waitforblock <blockhash> (timeout)\n"
236 "\nWaits for a specific new block and returns useful info about it.\n"
237 "\nReturns the current block on timeout or exit.\n"
238 "\nArguments:\n"
239 "1. \"blockhash\" (required, string) Block hash to wait for.\n"
240 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
241 "\nResult:\n"
242 "{ (json object)\n"
243 " \"hash\" : { (string) The blockhash\n"
244 " \"height\" : { (int) Block height\n"
245 "}\n"
246 "\nExamples:\n"
247 + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
248 + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
250 int timeout = 0;
252 uint256 hash = uint256S(request.params[0].get_str());
254 if (request.params.size() > 1)
255 timeout = request.params[1].get_int();
257 CUpdatedBlock block;
259 std::unique_lock<std::mutex> lock(cs_blockchange);
260 if(timeout)
261 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();});
262 else
263 cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); });
264 block = latestblock;
267 UniValue ret(UniValue::VOBJ);
268 ret.push_back(Pair("hash", block.hash.GetHex()));
269 ret.push_back(Pair("height", block.height));
270 return ret;
273 UniValue waitforblockheight(const JSONRPCRequest& request)
275 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
276 throw std::runtime_error(
277 "waitforblockheight <height> (timeout)\n"
278 "\nWaits for (at least) block height and returns the height and hash\n"
279 "of the current tip.\n"
280 "\nReturns the current block on timeout or exit.\n"
281 "\nArguments:\n"
282 "1. height (required, int) Block height to wait for (int)\n"
283 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
284 "\nResult:\n"
285 "{ (json object)\n"
286 " \"hash\" : { (string) The blockhash\n"
287 " \"height\" : { (int) Block height\n"
288 "}\n"
289 "\nExamples:\n"
290 + HelpExampleCli("waitforblockheight", "\"100\", 1000")
291 + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
293 int timeout = 0;
295 int height = request.params[0].get_int();
297 if (request.params.size() > 1)
298 timeout = request.params[1].get_int();
300 CUpdatedBlock block;
302 std::unique_lock<std::mutex> lock(cs_blockchange);
303 if(timeout)
304 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();});
305 else
306 cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); });
307 block = latestblock;
309 UniValue ret(UniValue::VOBJ);
310 ret.push_back(Pair("hash", block.hash.GetHex()));
311 ret.push_back(Pair("height", block.height));
312 return ret;
315 UniValue getdifficulty(const JSONRPCRequest& request)
317 if (request.fHelp || request.params.size() != 0)
318 throw std::runtime_error(
319 "getdifficulty\n"
320 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
321 "\nResult:\n"
322 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
323 "\nExamples:\n"
324 + HelpExampleCli("getdifficulty", "")
325 + HelpExampleRpc("getdifficulty", "")
328 LOCK(cs_main);
329 return GetDifficulty();
332 std::string EntryDescriptionString()
334 return " \"size\" : n, (numeric) virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted.\n"
335 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
336 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
337 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
338 " \"height\" : n, (numeric) block height when transaction entered pool\n"
339 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
340 " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n"
341 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
342 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
343 " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n"
344 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
345 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
346 " \"transactionid\", (string) parent transaction id\n"
347 " ... ]\n";
350 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
352 AssertLockHeld(mempool.cs);
354 info.push_back(Pair("size", (int)e.GetTxSize()));
355 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
356 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
357 info.push_back(Pair("time", e.GetTime()));
358 info.push_back(Pair("height", (int)e.GetHeight()));
359 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
360 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
361 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
362 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
363 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
364 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
365 const CTransaction& tx = e.GetTx();
366 std::set<std::string> setDepends;
367 BOOST_FOREACH(const CTxIn& txin, tx.vin)
369 if (mempool.exists(txin.prevout.hash))
370 setDepends.insert(txin.prevout.hash.ToString());
373 UniValue depends(UniValue::VARR);
374 BOOST_FOREACH(const std::string& dep, setDepends)
376 depends.push_back(dep);
379 info.push_back(Pair("depends", depends));
382 UniValue mempoolToJSON(bool fVerbose)
384 if (fVerbose)
386 LOCK(mempool.cs);
387 UniValue o(UniValue::VOBJ);
388 BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx)
390 const uint256& hash = e.GetTx().GetHash();
391 UniValue info(UniValue::VOBJ);
392 entryToJSON(info, e);
393 o.push_back(Pair(hash.ToString(), info));
395 return o;
397 else
399 std::vector<uint256> vtxid;
400 mempool.queryHashes(vtxid);
402 UniValue a(UniValue::VARR);
403 BOOST_FOREACH(const uint256& hash, vtxid)
404 a.push_back(hash.ToString());
406 return a;
410 UniValue getrawmempool(const JSONRPCRequest& request)
412 if (request.fHelp || request.params.size() > 1)
413 throw std::runtime_error(
414 "getrawmempool ( verbose )\n"
415 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
416 "\nArguments:\n"
417 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
418 "\nResult: (for verbose = false):\n"
419 "[ (json array of string)\n"
420 " \"transactionid\" (string) The transaction id\n"
421 " ,...\n"
422 "]\n"
423 "\nResult: (for verbose = true):\n"
424 "{ (json object)\n"
425 " \"transactionid\" : { (json object)\n"
426 + EntryDescriptionString()
427 + " }, ...\n"
428 "}\n"
429 "\nExamples:\n"
430 + HelpExampleCli("getrawmempool", "true")
431 + HelpExampleRpc("getrawmempool", "true")
434 bool fVerbose = false;
435 if (request.params.size() > 0)
436 fVerbose = request.params[0].get_bool();
438 return mempoolToJSON(fVerbose);
441 UniValue getmempoolancestors(const JSONRPCRequest& request)
443 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
444 throw std::runtime_error(
445 "getmempoolancestors txid (verbose)\n"
446 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
447 "\nArguments:\n"
448 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
449 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
450 "\nResult (for verbose=false):\n"
451 "[ (json array of strings)\n"
452 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
453 " ,...\n"
454 "]\n"
455 "\nResult (for verbose=true):\n"
456 "{ (json object)\n"
457 " \"transactionid\" : { (json object)\n"
458 + EntryDescriptionString()
459 + " }, ...\n"
460 "}\n"
461 "\nExamples:\n"
462 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
463 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
467 bool fVerbose = false;
468 if (request.params.size() > 1)
469 fVerbose = request.params[1].get_bool();
471 uint256 hash = ParseHashV(request.params[0], "parameter 1");
473 LOCK(mempool.cs);
475 CTxMemPool::txiter it = mempool.mapTx.find(hash);
476 if (it == mempool.mapTx.end()) {
477 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
480 CTxMemPool::setEntries setAncestors;
481 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
482 std::string dummy;
483 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
485 if (!fVerbose) {
486 UniValue o(UniValue::VARR);
487 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
488 o.push_back(ancestorIt->GetTx().GetHash().ToString());
491 return o;
492 } else {
493 UniValue o(UniValue::VOBJ);
494 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
495 const CTxMemPoolEntry &e = *ancestorIt;
496 const uint256& _hash = e.GetTx().GetHash();
497 UniValue info(UniValue::VOBJ);
498 entryToJSON(info, e);
499 o.push_back(Pair(_hash.ToString(), info));
501 return o;
505 UniValue getmempooldescendants(const JSONRPCRequest& request)
507 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
508 throw std::runtime_error(
509 "getmempooldescendants txid (verbose)\n"
510 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
511 "\nArguments:\n"
512 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
513 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
514 "\nResult (for verbose=false):\n"
515 "[ (json array of strings)\n"
516 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
517 " ,...\n"
518 "]\n"
519 "\nResult (for verbose=true):\n"
520 "{ (json object)\n"
521 " \"transactionid\" : { (json object)\n"
522 + EntryDescriptionString()
523 + " }, ...\n"
524 "}\n"
525 "\nExamples:\n"
526 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
527 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
531 bool fVerbose = false;
532 if (request.params.size() > 1)
533 fVerbose = request.params[1].get_bool();
535 uint256 hash = ParseHashV(request.params[0], "parameter 1");
537 LOCK(mempool.cs);
539 CTxMemPool::txiter it = mempool.mapTx.find(hash);
540 if (it == mempool.mapTx.end()) {
541 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
544 CTxMemPool::setEntries setDescendants;
545 mempool.CalculateDescendants(it, setDescendants);
546 // CTxMemPool::CalculateDescendants will include the given tx
547 setDescendants.erase(it);
549 if (!fVerbose) {
550 UniValue o(UniValue::VARR);
551 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
552 o.push_back(descendantIt->GetTx().GetHash().ToString());
555 return o;
556 } else {
557 UniValue o(UniValue::VOBJ);
558 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
559 const CTxMemPoolEntry &e = *descendantIt;
560 const uint256& _hash = e.GetTx().GetHash();
561 UniValue info(UniValue::VOBJ);
562 entryToJSON(info, e);
563 o.push_back(Pair(_hash.ToString(), info));
565 return o;
569 UniValue getmempoolentry(const JSONRPCRequest& request)
571 if (request.fHelp || request.params.size() != 1) {
572 throw std::runtime_error(
573 "getmempoolentry txid\n"
574 "\nReturns mempool data for given transaction\n"
575 "\nArguments:\n"
576 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
577 "\nResult:\n"
578 "{ (json object)\n"
579 + EntryDescriptionString()
580 + "}\n"
581 "\nExamples:\n"
582 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
583 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
587 uint256 hash = ParseHashV(request.params[0], "parameter 1");
589 LOCK(mempool.cs);
591 CTxMemPool::txiter it = mempool.mapTx.find(hash);
592 if (it == mempool.mapTx.end()) {
593 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
596 const CTxMemPoolEntry &e = *it;
597 UniValue info(UniValue::VOBJ);
598 entryToJSON(info, e);
599 return info;
602 UniValue getblockhash(const JSONRPCRequest& request)
604 if (request.fHelp || request.params.size() != 1)
605 throw std::runtime_error(
606 "getblockhash height\n"
607 "\nReturns hash of block in best-block-chain at height provided.\n"
608 "\nArguments:\n"
609 "1. height (numeric, required) The height index\n"
610 "\nResult:\n"
611 "\"hash\" (string) The block hash\n"
612 "\nExamples:\n"
613 + HelpExampleCli("getblockhash", "1000")
614 + HelpExampleRpc("getblockhash", "1000")
617 LOCK(cs_main);
619 int nHeight = request.params[0].get_int();
620 if (nHeight < 0 || nHeight > chainActive.Height())
621 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
623 CBlockIndex* pblockindex = chainActive[nHeight];
624 return pblockindex->GetBlockHash().GetHex();
627 UniValue getblockheader(const JSONRPCRequest& request)
629 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
630 throw std::runtime_error(
631 "getblockheader \"hash\" ( verbose )\n"
632 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
633 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
634 "\nArguments:\n"
635 "1. \"hash\" (string, required) The block hash\n"
636 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
637 "\nResult (for verbose = true):\n"
638 "{\n"
639 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
640 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
641 " \"height\" : n, (numeric) The block height or index\n"
642 " \"version\" : n, (numeric) The block version\n"
643 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
644 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
645 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
646 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
647 " \"nonce\" : n, (numeric) The nonce\n"
648 " \"bits\" : \"1d00ffff\", (string) The bits\n"
649 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
650 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
651 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
652 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
653 "}\n"
654 "\nResult (for verbose=false):\n"
655 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
656 "\nExamples:\n"
657 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
658 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
661 LOCK(cs_main);
663 std::string strHash = request.params[0].get_str();
664 uint256 hash(uint256S(strHash));
666 bool fVerbose = true;
667 if (request.params.size() > 1)
668 fVerbose = request.params[1].get_bool();
670 if (mapBlockIndex.count(hash) == 0)
671 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
673 CBlockIndex* pblockindex = mapBlockIndex[hash];
675 if (!fVerbose)
677 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
678 ssBlock << pblockindex->GetBlockHeader();
679 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
680 return strHex;
683 return blockheaderToJSON(pblockindex);
686 UniValue getblock(const JSONRPCRequest& request)
688 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
689 throw std::runtime_error(
690 "getblock \"blockhash\" ( verbose )\n"
691 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
692 "If verbose is true, returns an Object with information about block <hash>.\n"
693 "\nArguments:\n"
694 "1. \"blockhash\" (string, required) The block hash\n"
695 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
696 "\nResult (for verbose = true):\n"
697 "{\n"
698 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
699 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
700 " \"size\" : n, (numeric) The block size\n"
701 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
702 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
703 " \"height\" : n, (numeric) The block height or index\n"
704 " \"version\" : n, (numeric) The block version\n"
705 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
706 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
707 " \"tx\" : [ (array of string) The transaction ids\n"
708 " \"transactionid\" (string) The transaction id\n"
709 " ,...\n"
710 " ],\n"
711 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
712 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
713 " \"nonce\" : n, (numeric) The nonce\n"
714 " \"bits\" : \"1d00ffff\", (string) The bits\n"
715 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
716 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
717 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
718 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
719 "}\n"
720 "\nResult (for verbose=false):\n"
721 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
722 "\nExamples:\n"
723 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
724 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
727 LOCK(cs_main);
729 std::string strHash = request.params[0].get_str();
730 uint256 hash(uint256S(strHash));
732 bool fVerbose = true;
733 if (request.params.size() > 1)
734 fVerbose = request.params[1].get_bool();
736 if (mapBlockIndex.count(hash) == 0)
737 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
739 CBlock block;
740 CBlockIndex* pblockindex = mapBlockIndex[hash];
742 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
743 throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
745 if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
746 // Block not found on disk. This could be because we have the block
747 // header in our index but don't have the block (for example if a
748 // non-whitelisted node sends us an unrequested long chain of valid
749 // blocks, we add the headers to our index, but don't accept the
750 // block).
751 throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
753 if (!fVerbose)
755 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
756 ssBlock << block;
757 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
758 return strHex;
761 return blockToJSON(block, pblockindex);
764 struct CCoinsStats
766 int nHeight;
767 uint256 hashBlock;
768 uint64_t nTransactions;
769 uint64_t nTransactionOutputs;
770 uint64_t nSerializedSize;
771 uint256 hashSerialized;
772 CAmount nTotalAmount;
774 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {}
777 //! Calculate statistics about the unspent transaction output set
778 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
780 std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
782 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
783 stats.hashBlock = pcursor->GetBestBlock();
785 LOCK(cs_main);
786 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
788 ss << stats.hashBlock;
789 CAmount nTotalAmount = 0;
790 while (pcursor->Valid()) {
791 boost::this_thread::interruption_point();
792 uint256 key;
793 CCoins coins;
794 if (pcursor->GetKey(key) && pcursor->GetValue(coins)) {
795 stats.nTransactions++;
796 ss << key;
797 for (unsigned int i=0; i<coins.vout.size(); i++) {
798 const CTxOut &out = coins.vout[i];
799 if (!out.IsNull()) {
800 stats.nTransactionOutputs++;
801 ss << VARINT(i+1);
802 ss << out;
803 nTotalAmount += out.nValue;
806 stats.nSerializedSize += 32 + pcursor->GetValueSize();
807 ss << VARINT(0);
808 } else {
809 return error("%s: unable to read value", __func__);
811 pcursor->Next();
813 stats.hashSerialized = ss.GetHash();
814 stats.nTotalAmount = nTotalAmount;
815 return true;
818 UniValue pruneblockchain(const JSONRPCRequest& request)
820 if (request.fHelp || request.params.size() != 1)
821 throw std::runtime_error(
822 "pruneblockchain\n"
823 "\nArguments:\n"
824 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
825 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
826 "\nResult:\n"
827 "n (numeric) Height of the last block pruned.\n"
828 "\nExamples:\n"
829 + HelpExampleCli("pruneblockchain", "1000")
830 + HelpExampleRpc("pruneblockchain", "1000"));
832 if (!fPruneMode)
833 throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
835 LOCK(cs_main);
837 int heightParam = request.params[0].get_int();
838 if (heightParam < 0)
839 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
841 // Height value more than a billion is too high to be a block height, and
842 // too low to be a block time (corresponds to timestamp from Sep 2001).
843 if (heightParam > 1000000000) {
844 // Add a 2 hour buffer to include blocks which might have had old timestamps
845 CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
846 if (!pindex) {
847 throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
849 heightParam = pindex->nHeight;
852 unsigned int height = (unsigned int) heightParam;
853 unsigned int chainHeight = (unsigned int) chainActive.Height();
854 if (chainHeight < Params().PruneAfterHeight())
855 throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
856 else if (height > chainHeight)
857 throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
858 else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
859 LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
860 height = chainHeight - MIN_BLOCKS_TO_KEEP;
863 PruneBlockFilesManual(height);
864 return uint64_t(height);
867 UniValue gettxoutsetinfo(const JSONRPCRequest& request)
869 if (request.fHelp || request.params.size() != 0)
870 throw std::runtime_error(
871 "gettxoutsetinfo\n"
872 "\nReturns statistics about the unspent transaction output set.\n"
873 "Note this call may take some time.\n"
874 "\nResult:\n"
875 "{\n"
876 " \"height\":n, (numeric) The current block height (index)\n"
877 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
878 " \"transactions\": n, (numeric) The number of transactions\n"
879 " \"txouts\": n, (numeric) The number of output transactions\n"
880 " \"bytes_serialized\": n, (numeric) The serialized size\n"
881 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
882 " \"total_amount\": x.xxx (numeric) The total amount\n"
883 "}\n"
884 "\nExamples:\n"
885 + HelpExampleCli("gettxoutsetinfo", "")
886 + HelpExampleRpc("gettxoutsetinfo", "")
889 UniValue ret(UniValue::VOBJ);
891 CCoinsStats stats;
892 FlushStateToDisk();
893 if (GetUTXOStats(pcoinsTip, stats)) {
894 ret.push_back(Pair("height", (int64_t)stats.nHeight));
895 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
896 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
897 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
898 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
899 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
900 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
901 } else {
902 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
904 return ret;
907 UniValue gettxout(const JSONRPCRequest& request)
909 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
910 throw std::runtime_error(
911 "gettxout \"txid\" n ( include_mempool )\n"
912 "\nReturns details about an unspent transaction output.\n"
913 "\nArguments:\n"
914 "1. \"txid\" (string, required) The transaction id\n"
915 "2. n (numeric, required) vout number\n"
916 "3. include_mempool (boolean, optional) Whether to include the mempool\n"
917 "\nResult:\n"
918 "{\n"
919 " \"bestblock\" : \"hash\", (string) the block hash\n"
920 " \"confirmations\" : n, (numeric) The number of confirmations\n"
921 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
922 " \"scriptPubKey\" : { (json object)\n"
923 " \"asm\" : \"code\", (string) \n"
924 " \"hex\" : \"hex\", (string) \n"
925 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
926 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
927 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
928 " \"address\" (string) bitcoin address\n"
929 " ,...\n"
930 " ]\n"
931 " },\n"
932 " \"version\" : n, (numeric) The version\n"
933 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
934 "}\n"
936 "\nExamples:\n"
937 "\nGet unspent transactions\n"
938 + HelpExampleCli("listunspent", "") +
939 "\nView the details\n"
940 + HelpExampleCli("gettxout", "\"txid\" 1") +
941 "\nAs a json rpc call\n"
942 + HelpExampleRpc("gettxout", "\"txid\", 1")
945 LOCK(cs_main);
947 UniValue ret(UniValue::VOBJ);
949 std::string strHash = request.params[0].get_str();
950 uint256 hash(uint256S(strHash));
951 int n = request.params[1].get_int();
952 bool fMempool = true;
953 if (request.params.size() > 2)
954 fMempool = request.params[2].get_bool();
956 CCoins coins;
957 if (fMempool) {
958 LOCK(mempool.cs);
959 CCoinsViewMemPool view(pcoinsTip, mempool);
960 if (!view.GetCoins(hash, coins))
961 return NullUniValue;
962 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
963 } else {
964 if (!pcoinsTip->GetCoins(hash, coins))
965 return NullUniValue;
967 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
968 return NullUniValue;
970 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
971 CBlockIndex *pindex = it->second;
972 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
973 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
974 ret.push_back(Pair("confirmations", 0));
975 else
976 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
977 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
978 UniValue o(UniValue::VOBJ);
979 ScriptPubKeyToUniv(coins.vout[n].scriptPubKey, o, true);
980 ret.push_back(Pair("scriptPubKey", o));
981 ret.push_back(Pair("version", coins.nVersion));
982 ret.push_back(Pair("coinbase", coins.fCoinBase));
984 return ret;
987 UniValue verifychain(const JSONRPCRequest& request)
989 int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
990 int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
991 if (request.fHelp || request.params.size() > 2)
992 throw std::runtime_error(
993 "verifychain ( checklevel nblocks )\n"
994 "\nVerifies blockchain database.\n"
995 "\nArguments:\n"
996 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
997 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
998 "\nResult:\n"
999 "true|false (boolean) Verified or not\n"
1000 "\nExamples:\n"
1001 + HelpExampleCli("verifychain", "")
1002 + HelpExampleRpc("verifychain", "")
1005 LOCK(cs_main);
1007 if (request.params.size() > 0)
1008 nCheckLevel = request.params[0].get_int();
1009 if (request.params.size() > 1)
1010 nCheckDepth = request.params[1].get_int();
1012 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
1015 /** Implementation of IsSuperMajority with better feedback */
1016 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1018 UniValue rv(UniValue::VOBJ);
1019 bool activated = false;
1020 switch(version)
1022 case 2:
1023 activated = pindex->nHeight >= consensusParams.BIP34Height;
1024 break;
1025 case 3:
1026 activated = pindex->nHeight >= consensusParams.BIP66Height;
1027 break;
1028 case 4:
1029 activated = pindex->nHeight >= consensusParams.BIP65Height;
1030 break;
1032 rv.push_back(Pair("status", activated));
1033 return rv;
1036 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1038 UniValue rv(UniValue::VOBJ);
1039 rv.push_back(Pair("id", name));
1040 rv.push_back(Pair("version", version));
1041 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1042 return rv;
1045 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1047 UniValue rv(UniValue::VOBJ);
1048 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1049 switch (thresholdState) {
1050 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1051 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1052 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1053 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1054 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1056 if (THRESHOLD_STARTED == thresholdState)
1058 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1060 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1061 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1062 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1063 return rv;
1066 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1068 // Deployments with timeout value of 0 are hidden.
1069 // A timeout value of 0 guarantees a softfork will never be activated.
1070 // This is used when softfork codes are merged without specifying the deployment schedule.
1071 if (consensusParams.vDeployments[id].nTimeout > 0)
1072 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
1075 UniValue getblockchaininfo(const JSONRPCRequest& request)
1077 if (request.fHelp || request.params.size() != 0)
1078 throw std::runtime_error(
1079 "getblockchaininfo\n"
1080 "Returns an object containing various state info regarding blockchain processing.\n"
1081 "\nResult:\n"
1082 "{\n"
1083 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1084 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1085 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1086 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1087 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1088 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1089 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1090 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1091 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1092 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1093 " \"softforks\": [ (array) status of softforks in progress\n"
1094 " {\n"
1095 " \"id\": \"xxxx\", (string) name of softfork\n"
1096 " \"version\": xx, (numeric) block version\n"
1097 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1098 " \"status\": xx, (boolean) true if threshold reached\n"
1099 " },\n"
1100 " }, ...\n"
1101 " ],\n"
1102 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1103 " \"xxxx\" : { (string) name of the softfork\n"
1104 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1105 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1106 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1107 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1108 " \"since\": xx (numeric) height of the first block to which the status applies\n"
1109 " }\n"
1110 " }\n"
1111 "}\n"
1112 "\nExamples:\n"
1113 + HelpExampleCli("getblockchaininfo", "")
1114 + HelpExampleRpc("getblockchaininfo", "")
1117 LOCK(cs_main);
1119 UniValue obj(UniValue::VOBJ);
1120 obj.push_back(Pair("chain", Params().NetworkIDString()));
1121 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1122 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1123 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1124 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1125 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1126 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1127 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1128 obj.push_back(Pair("pruned", fPruneMode));
1130 const Consensus::Params& consensusParams = Params().GetConsensus();
1131 CBlockIndex* tip = chainActive.Tip();
1132 UniValue softforks(UniValue::VARR);
1133 UniValue bip9_softforks(UniValue::VOBJ);
1134 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1135 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1136 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1137 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
1138 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
1139 obj.push_back(Pair("softforks", softforks));
1140 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1142 if (fPruneMode)
1144 CBlockIndex *block = chainActive.Tip();
1145 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
1146 block = block->pprev;
1148 obj.push_back(Pair("pruneheight", block->nHeight));
1150 return obj;
1153 /** Comparison function for sorting the getchaintips heads. */
1154 struct CompareBlocksByHeight
1156 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1158 /* Make sure that unequal blocks with the same height do not compare
1159 equal. Use the pointers themselves to make a distinction. */
1161 if (a->nHeight != b->nHeight)
1162 return (a->nHeight > b->nHeight);
1164 return a < b;
1168 UniValue getchaintips(const JSONRPCRequest& request)
1170 if (request.fHelp || request.params.size() != 0)
1171 throw std::runtime_error(
1172 "getchaintips\n"
1173 "Return information about all known tips in the block tree,"
1174 " including the main chain as well as orphaned branches.\n"
1175 "\nResult:\n"
1176 "[\n"
1177 " {\n"
1178 " \"height\": xxxx, (numeric) height of the chain tip\n"
1179 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1180 " \"branchlen\": 0 (numeric) zero for main chain\n"
1181 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1182 " },\n"
1183 " {\n"
1184 " \"height\": xxxx,\n"
1185 " \"hash\": \"xxxx\",\n"
1186 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1187 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1188 " }\n"
1189 "]\n"
1190 "Possible values for status:\n"
1191 "1. \"invalid\" This branch contains at least one invalid block\n"
1192 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1193 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1194 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1195 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1196 "\nExamples:\n"
1197 + HelpExampleCli("getchaintips", "")
1198 + HelpExampleRpc("getchaintips", "")
1201 LOCK(cs_main);
1204 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1205 * Algorithm:
1206 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1207 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1208 * - add chainActive.Tip()
1210 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1211 std::set<const CBlockIndex*> setOrphans;
1212 std::set<const CBlockIndex*> setPrevs;
1214 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
1216 if (!chainActive.Contains(item.second)) {
1217 setOrphans.insert(item.second);
1218 setPrevs.insert(item.second->pprev);
1222 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1224 if (setPrevs.erase(*it) == 0) {
1225 setTips.insert(*it);
1229 // Always report the currently active tip.
1230 setTips.insert(chainActive.Tip());
1232 /* Construct the output array. */
1233 UniValue res(UniValue::VARR);
1234 BOOST_FOREACH(const CBlockIndex* block, setTips)
1236 UniValue obj(UniValue::VOBJ);
1237 obj.push_back(Pair("height", block->nHeight));
1238 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1240 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1241 obj.push_back(Pair("branchlen", branchLen));
1243 std::string status;
1244 if (chainActive.Contains(block)) {
1245 // This block is part of the currently active chain.
1246 status = "active";
1247 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1248 // This block or one of its ancestors is invalid.
1249 status = "invalid";
1250 } else if (block->nChainTx == 0) {
1251 // This block cannot be connected because full block data for it or one of its parents is missing.
1252 status = "headers-only";
1253 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1254 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1255 status = "valid-fork";
1256 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1257 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1258 status = "valid-headers";
1259 } else {
1260 // No clue.
1261 status = "unknown";
1263 obj.push_back(Pair("status", status));
1265 res.push_back(obj);
1268 return res;
1271 UniValue mempoolInfoToJSON()
1273 UniValue ret(UniValue::VOBJ);
1274 ret.push_back(Pair("size", (int64_t) mempool.size()));
1275 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1276 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1277 size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1278 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1279 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1281 return ret;
1284 UniValue getmempoolinfo(const JSONRPCRequest& request)
1286 if (request.fHelp || request.params.size() != 0)
1287 throw std::runtime_error(
1288 "getmempoolinfo\n"
1289 "\nReturns details on the active state of the TX memory pool.\n"
1290 "\nResult:\n"
1291 "{\n"
1292 " \"size\": xxxxx, (numeric) Current tx count\n"
1293 " \"bytes\": xxxxx, (numeric) Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted\n"
1294 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1295 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1296 " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n"
1297 "}\n"
1298 "\nExamples:\n"
1299 + HelpExampleCli("getmempoolinfo", "")
1300 + HelpExampleRpc("getmempoolinfo", "")
1303 return mempoolInfoToJSON();
1306 UniValue preciousblock(const JSONRPCRequest& request)
1308 if (request.fHelp || request.params.size() != 1)
1309 throw std::runtime_error(
1310 "preciousblock \"blockhash\"\n"
1311 "\nTreats a block as if it were received before others with the same work.\n"
1312 "\nA later preciousblock call can override the effect of an earlier one.\n"
1313 "\nThe effects of preciousblock are not retained across restarts.\n"
1314 "\nArguments:\n"
1315 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1316 "\nResult:\n"
1317 "\nExamples:\n"
1318 + HelpExampleCli("preciousblock", "\"blockhash\"")
1319 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1322 std::string strHash = request.params[0].get_str();
1323 uint256 hash(uint256S(strHash));
1324 CBlockIndex* pblockindex;
1327 LOCK(cs_main);
1328 if (mapBlockIndex.count(hash) == 0)
1329 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1331 pblockindex = mapBlockIndex[hash];
1334 CValidationState state;
1335 PreciousBlock(state, Params(), pblockindex);
1337 if (!state.IsValid()) {
1338 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1341 return NullUniValue;
1344 UniValue invalidateblock(const JSONRPCRequest& request)
1346 if (request.fHelp || request.params.size() != 1)
1347 throw std::runtime_error(
1348 "invalidateblock \"blockhash\"\n"
1349 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1350 "\nArguments:\n"
1351 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1352 "\nResult:\n"
1353 "\nExamples:\n"
1354 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1355 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1358 std::string strHash = request.params[0].get_str();
1359 uint256 hash(uint256S(strHash));
1360 CValidationState state;
1363 LOCK(cs_main);
1364 if (mapBlockIndex.count(hash) == 0)
1365 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1367 CBlockIndex* pblockindex = mapBlockIndex[hash];
1368 InvalidateBlock(state, Params(), pblockindex);
1371 if (state.IsValid()) {
1372 ActivateBestChain(state, Params());
1375 if (!state.IsValid()) {
1376 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1379 return NullUniValue;
1382 UniValue reconsiderblock(const JSONRPCRequest& request)
1384 if (request.fHelp || request.params.size() != 1)
1385 throw std::runtime_error(
1386 "reconsiderblock \"blockhash\"\n"
1387 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1388 "This can be used to undo the effects of invalidateblock.\n"
1389 "\nArguments:\n"
1390 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1391 "\nResult:\n"
1392 "\nExamples:\n"
1393 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1394 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1397 std::string strHash = request.params[0].get_str();
1398 uint256 hash(uint256S(strHash));
1401 LOCK(cs_main);
1402 if (mapBlockIndex.count(hash) == 0)
1403 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1405 CBlockIndex* pblockindex = mapBlockIndex[hash];
1406 ResetBlockFailureFlags(pblockindex);
1409 CValidationState state;
1410 ActivateBestChain(state, Params());
1412 if (!state.IsValid()) {
1413 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1416 return NullUniValue;
1419 static const CRPCCommand commands[] =
1420 { // category name actor (function) okSafe argNames
1421 // --------------------- ------------------------ ----------------------- ------ ----------
1422 { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
1423 { "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
1424 { "blockchain", "getblockcount", &getblockcount, true, {} },
1425 { "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} },
1426 { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
1427 { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
1428 { "blockchain", "getchaintips", &getchaintips, true, {} },
1429 { "blockchain", "getdifficulty", &getdifficulty, true, {} },
1430 { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
1431 { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
1432 { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
1433 { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
1434 { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
1435 { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
1436 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
1437 { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
1438 { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },
1440 { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
1442 /* Not shown in help */
1443 { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
1444 { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
1445 { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
1446 { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
1447 { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
1450 void RegisterBlockchainRPCCommands(CRPCTable &t)
1452 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1453 t.appendCommand(commands[vcidx].name, &commands[vcidx]);