Merge #11099: [RPC][mempool]: Add savemempool RPC
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blobd131635067acafa47069b669740692d830205c5d
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/feerate.h"
17 #include "policy/policy.h"
18 #include "primitives/transaction.h"
19 #include "rpc/server.h"
20 #include "streams.h"
21 #include "sync.h"
22 #include "txdb.h"
23 #include "txmempool.h"
24 #include "util.h"
25 #include "utilstrencodings.h"
26 #include "hash.h"
28 #include <stdint.h>
30 #include <univalue.h>
32 #include <boost/thread/thread.hpp> // boost::thread::interrupt
34 #include <mutex>
35 #include <condition_variable>
37 struct CUpdatedBlock
39 uint256 hash;
40 int height;
43 static std::mutex cs_blockchange;
44 static std::condition_variable cond_blockchange;
45 static CUpdatedBlock latestblock;
47 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
49 double GetDifficulty(const CBlockIndex* blockindex)
51 if (blockindex == nullptr)
53 if (chainActive.Tip() == nullptr)
54 return 1.0;
55 else
56 blockindex = chainActive.Tip();
59 int nShift = (blockindex->nBits >> 24) & 0xff;
61 double dDiff =
62 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
64 while (nShift < 29)
66 dDiff *= 256.0;
67 nShift++;
69 while (nShift > 29)
71 dDiff /= 256.0;
72 nShift--;
75 return dDiff;
78 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
80 UniValue result(UniValue::VOBJ);
81 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
82 int confirmations = -1;
83 // Only report confirmations if the block is on the main chain
84 if (chainActive.Contains(blockindex))
85 confirmations = chainActive.Height() - blockindex->nHeight + 1;
86 result.push_back(Pair("confirmations", confirmations));
87 result.push_back(Pair("height", blockindex->nHeight));
88 result.push_back(Pair("version", blockindex->nVersion));
89 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
90 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
91 result.push_back(Pair("time", (int64_t)blockindex->nTime));
92 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
93 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
94 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
95 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
96 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
98 if (blockindex->pprev)
99 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
100 CBlockIndex *pnext = chainActive.Next(blockindex);
101 if (pnext)
102 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
103 return result;
106 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
108 UniValue result(UniValue::VOBJ);
109 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
110 int confirmations = -1;
111 // Only report confirmations if the block is on the main chain
112 if (chainActive.Contains(blockindex))
113 confirmations = chainActive.Height() - blockindex->nHeight + 1;
114 result.push_back(Pair("confirmations", confirmations));
115 result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)));
116 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
117 result.push_back(Pair("weight", (int)::GetBlockWeight(block)));
118 result.push_back(Pair("height", blockindex->nHeight));
119 result.push_back(Pair("version", block.nVersion));
120 result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion)));
121 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
122 UniValue txs(UniValue::VARR);
123 for(const auto& tx : block.vtx)
125 if(txDetails)
127 UniValue objTx(UniValue::VOBJ);
128 TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags());
129 txs.push_back(objTx);
131 else
132 txs.push_back(tx->GetHash().GetHex());
134 result.push_back(Pair("tx", txs));
135 result.push_back(Pair("time", block.GetBlockTime()));
136 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
137 result.push_back(Pair("nonce", (uint64_t)block.nNonce));
138 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
139 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
140 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
142 if (blockindex->pprev)
143 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
144 CBlockIndex *pnext = chainActive.Next(blockindex);
145 if (pnext)
146 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
147 return result;
150 UniValue getblockcount(const JSONRPCRequest& request)
152 if (request.fHelp || request.params.size() != 0)
153 throw std::runtime_error(
154 "getblockcount\n"
155 "\nReturns the number of blocks in the longest blockchain.\n"
156 "\nResult:\n"
157 "n (numeric) The current block count\n"
158 "\nExamples:\n"
159 + HelpExampleCli("getblockcount", "")
160 + HelpExampleRpc("getblockcount", "")
163 LOCK(cs_main);
164 return chainActive.Height();
167 UniValue getbestblockhash(const JSONRPCRequest& request)
169 if (request.fHelp || request.params.size() != 0)
170 throw std::runtime_error(
171 "getbestblockhash\n"
172 "\nReturns the hash of the best (tip) block in the longest blockchain.\n"
173 "\nResult:\n"
174 "\"hex\" (string) the block hash hex encoded\n"
175 "\nExamples:\n"
176 + HelpExampleCli("getbestblockhash", "")
177 + HelpExampleRpc("getbestblockhash", "")
180 LOCK(cs_main);
181 return chainActive.Tip()->GetBlockHash().GetHex();
184 void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex)
186 if(pindex) {
187 std::lock_guard<std::mutex> lock(cs_blockchange);
188 latestblock.hash = pindex->GetBlockHash();
189 latestblock.height = pindex->nHeight;
191 cond_blockchange.notify_all();
194 UniValue waitfornewblock(const JSONRPCRequest& request)
196 if (request.fHelp || request.params.size() > 1)
197 throw std::runtime_error(
198 "waitfornewblock (timeout)\n"
199 "\nWaits for a specific new block and returns useful info about it.\n"
200 "\nReturns the current block on timeout or exit.\n"
201 "\nArguments:\n"
202 "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
203 "\nResult:\n"
204 "{ (json object)\n"
205 " \"hash\" : { (string) The blockhash\n"
206 " \"height\" : { (int) Block height\n"
207 "}\n"
208 "\nExamples:\n"
209 + HelpExampleCli("waitfornewblock", "1000")
210 + HelpExampleRpc("waitfornewblock", "1000")
212 int timeout = 0;
213 if (!request.params[0].isNull())
214 timeout = request.params[0].get_int();
216 CUpdatedBlock block;
218 std::unique_lock<std::mutex> lock(cs_blockchange);
219 block = latestblock;
220 if(timeout)
221 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
222 else
223 cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
224 block = latestblock;
226 UniValue ret(UniValue::VOBJ);
227 ret.push_back(Pair("hash", block.hash.GetHex()));
228 ret.push_back(Pair("height", block.height));
229 return ret;
232 UniValue waitforblock(const JSONRPCRequest& request)
234 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
235 throw std::runtime_error(
236 "waitforblock <blockhash> (timeout)\n"
237 "\nWaits for a specific new block and returns useful info about it.\n"
238 "\nReturns the current block on timeout or exit.\n"
239 "\nArguments:\n"
240 "1. \"blockhash\" (required, string) Block hash to wait for.\n"
241 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
242 "\nResult:\n"
243 "{ (json object)\n"
244 " \"hash\" : { (string) The blockhash\n"
245 " \"height\" : { (int) Block height\n"
246 "}\n"
247 "\nExamples:\n"
248 + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
249 + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
251 int timeout = 0;
253 uint256 hash = uint256S(request.params[0].get_str());
255 if (!request.params[1].isNull())
256 timeout = request.params[1].get_int();
258 CUpdatedBlock block;
260 std::unique_lock<std::mutex> lock(cs_blockchange);
261 if(timeout)
262 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();});
263 else
264 cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); });
265 block = latestblock;
268 UniValue ret(UniValue::VOBJ);
269 ret.push_back(Pair("hash", block.hash.GetHex()));
270 ret.push_back(Pair("height", block.height));
271 return ret;
274 UniValue waitforblockheight(const JSONRPCRequest& request)
276 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
277 throw std::runtime_error(
278 "waitforblockheight <height> (timeout)\n"
279 "\nWaits for (at least) block height and returns the height and hash\n"
280 "of the current tip.\n"
281 "\nReturns the current block on timeout or exit.\n"
282 "\nArguments:\n"
283 "1. height (required, int) Block height to wait for (int)\n"
284 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
285 "\nResult:\n"
286 "{ (json object)\n"
287 " \"hash\" : { (string) The blockhash\n"
288 " \"height\" : { (int) Block height\n"
289 "}\n"
290 "\nExamples:\n"
291 + HelpExampleCli("waitforblockheight", "\"100\", 1000")
292 + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
294 int timeout = 0;
296 int height = request.params[0].get_int();
298 if (!request.params[1].isNull())
299 timeout = request.params[1].get_int();
301 CUpdatedBlock block;
303 std::unique_lock<std::mutex> lock(cs_blockchange);
304 if(timeout)
305 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();});
306 else
307 cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); });
308 block = latestblock;
310 UniValue ret(UniValue::VOBJ);
311 ret.push_back(Pair("hash", block.hash.GetHex()));
312 ret.push_back(Pair("height", block.height));
313 return ret;
316 UniValue getdifficulty(const JSONRPCRequest& request)
318 if (request.fHelp || request.params.size() != 0)
319 throw std::runtime_error(
320 "getdifficulty\n"
321 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
322 "\nResult:\n"
323 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
324 "\nExamples:\n"
325 + HelpExampleCli("getdifficulty", "")
326 + HelpExampleRpc("getdifficulty", "")
329 LOCK(cs_main);
330 return GetDifficulty();
333 std::string EntryDescriptionString()
335 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"
336 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
337 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
338 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
339 " \"height\" : n, (numeric) block height when transaction entered pool\n"
340 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
341 " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n"
342 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
343 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
344 " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n"
345 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
346 " \"wtxid\" : hash, (string) hash of serialized transaction, including witness data\n"
347 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
348 " \"transactionid\", (string) parent transaction id\n"
349 " ... ]\n";
352 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
354 AssertLockHeld(mempool.cs);
356 info.push_back(Pair("size", (int)e.GetTxSize()));
357 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
358 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
359 info.push_back(Pair("time", e.GetTime()));
360 info.push_back(Pair("height", (int)e.GetHeight()));
361 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
362 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
363 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
364 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
365 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
366 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
367 info.push_back(Pair("wtxid", mempool.vTxHashes[e.vTxHashesIdx].first.ToString()));
368 const CTransaction& tx = e.GetTx();
369 std::set<std::string> setDepends;
370 for (const CTxIn& txin : tx.vin)
372 if (mempool.exists(txin.prevout.hash))
373 setDepends.insert(txin.prevout.hash.ToString());
376 UniValue depends(UniValue::VARR);
377 for (const std::string& dep : setDepends)
379 depends.push_back(dep);
382 info.push_back(Pair("depends", depends));
385 UniValue mempoolToJSON(bool fVerbose)
387 if (fVerbose)
389 LOCK(mempool.cs);
390 UniValue o(UniValue::VOBJ);
391 for (const CTxMemPoolEntry& e : mempool.mapTx)
393 const uint256& hash = e.GetTx().GetHash();
394 UniValue info(UniValue::VOBJ);
395 entryToJSON(info, e);
396 o.push_back(Pair(hash.ToString(), info));
398 return o;
400 else
402 std::vector<uint256> vtxid;
403 mempool.queryHashes(vtxid);
405 UniValue a(UniValue::VARR);
406 for (const uint256& hash : vtxid)
407 a.push_back(hash.ToString());
409 return a;
413 UniValue getrawmempool(const JSONRPCRequest& request)
415 if (request.fHelp || request.params.size() > 1)
416 throw std::runtime_error(
417 "getrawmempool ( verbose )\n"
418 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
419 "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n"
420 "\nArguments:\n"
421 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
422 "\nResult: (for verbose = false):\n"
423 "[ (json array of string)\n"
424 " \"transactionid\" (string) The transaction id\n"
425 " ,...\n"
426 "]\n"
427 "\nResult: (for verbose = true):\n"
428 "{ (json object)\n"
429 " \"transactionid\" : { (json object)\n"
430 + EntryDescriptionString()
431 + " }, ...\n"
432 "}\n"
433 "\nExamples:\n"
434 + HelpExampleCli("getrawmempool", "true")
435 + HelpExampleRpc("getrawmempool", "true")
438 bool fVerbose = false;
439 if (!request.params[0].isNull())
440 fVerbose = request.params[0].get_bool();
442 return mempoolToJSON(fVerbose);
445 UniValue getmempoolancestors(const JSONRPCRequest& request)
447 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
448 throw std::runtime_error(
449 "getmempoolancestors txid (verbose)\n"
450 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
451 "\nArguments:\n"
452 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
453 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
454 "\nResult (for verbose=false):\n"
455 "[ (json array of strings)\n"
456 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
457 " ,...\n"
458 "]\n"
459 "\nResult (for verbose=true):\n"
460 "{ (json object)\n"
461 " \"transactionid\" : { (json object)\n"
462 + EntryDescriptionString()
463 + " }, ...\n"
464 "}\n"
465 "\nExamples:\n"
466 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
467 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
471 bool fVerbose = false;
472 if (!request.params[1].isNull())
473 fVerbose = request.params[1].get_bool();
475 uint256 hash = ParseHashV(request.params[0], "parameter 1");
477 LOCK(mempool.cs);
479 CTxMemPool::txiter it = mempool.mapTx.find(hash);
480 if (it == mempool.mapTx.end()) {
481 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
484 CTxMemPool::setEntries setAncestors;
485 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
486 std::string dummy;
487 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
489 if (!fVerbose) {
490 UniValue o(UniValue::VARR);
491 for (CTxMemPool::txiter ancestorIt : setAncestors) {
492 o.push_back(ancestorIt->GetTx().GetHash().ToString());
495 return o;
496 } else {
497 UniValue o(UniValue::VOBJ);
498 for (CTxMemPool::txiter ancestorIt : setAncestors) {
499 const CTxMemPoolEntry &e = *ancestorIt;
500 const uint256& _hash = e.GetTx().GetHash();
501 UniValue info(UniValue::VOBJ);
502 entryToJSON(info, e);
503 o.push_back(Pair(_hash.ToString(), info));
505 return o;
509 UniValue getmempooldescendants(const JSONRPCRequest& request)
511 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
512 throw std::runtime_error(
513 "getmempooldescendants txid (verbose)\n"
514 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
515 "\nArguments:\n"
516 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
517 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
518 "\nResult (for verbose=false):\n"
519 "[ (json array of strings)\n"
520 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
521 " ,...\n"
522 "]\n"
523 "\nResult (for verbose=true):\n"
524 "{ (json object)\n"
525 " \"transactionid\" : { (json object)\n"
526 + EntryDescriptionString()
527 + " }, ...\n"
528 "}\n"
529 "\nExamples:\n"
530 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
531 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
535 bool fVerbose = false;
536 if (!request.params[1].isNull())
537 fVerbose = request.params[1].get_bool();
539 uint256 hash = ParseHashV(request.params[0], "parameter 1");
541 LOCK(mempool.cs);
543 CTxMemPool::txiter it = mempool.mapTx.find(hash);
544 if (it == mempool.mapTx.end()) {
545 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
548 CTxMemPool::setEntries setDescendants;
549 mempool.CalculateDescendants(it, setDescendants);
550 // CTxMemPool::CalculateDescendants will include the given tx
551 setDescendants.erase(it);
553 if (!fVerbose) {
554 UniValue o(UniValue::VARR);
555 for (CTxMemPool::txiter descendantIt : setDescendants) {
556 o.push_back(descendantIt->GetTx().GetHash().ToString());
559 return o;
560 } else {
561 UniValue o(UniValue::VOBJ);
562 for (CTxMemPool::txiter descendantIt : setDescendants) {
563 const CTxMemPoolEntry &e = *descendantIt;
564 const uint256& _hash = e.GetTx().GetHash();
565 UniValue info(UniValue::VOBJ);
566 entryToJSON(info, e);
567 o.push_back(Pair(_hash.ToString(), info));
569 return o;
573 UniValue getmempoolentry(const JSONRPCRequest& request)
575 if (request.fHelp || request.params.size() != 1) {
576 throw std::runtime_error(
577 "getmempoolentry txid\n"
578 "\nReturns mempool data for given transaction\n"
579 "\nArguments:\n"
580 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
581 "\nResult:\n"
582 "{ (json object)\n"
583 + EntryDescriptionString()
584 + "}\n"
585 "\nExamples:\n"
586 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
587 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
591 uint256 hash = ParseHashV(request.params[0], "parameter 1");
593 LOCK(mempool.cs);
595 CTxMemPool::txiter it = mempool.mapTx.find(hash);
596 if (it == mempool.mapTx.end()) {
597 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
600 const CTxMemPoolEntry &e = *it;
601 UniValue info(UniValue::VOBJ);
602 entryToJSON(info, e);
603 return info;
606 UniValue getblockhash(const JSONRPCRequest& request)
608 if (request.fHelp || request.params.size() != 1)
609 throw std::runtime_error(
610 "getblockhash height\n"
611 "\nReturns hash of block in best-block-chain at height provided.\n"
612 "\nArguments:\n"
613 "1. height (numeric, required) The height index\n"
614 "\nResult:\n"
615 "\"hash\" (string) The block hash\n"
616 "\nExamples:\n"
617 + HelpExampleCli("getblockhash", "1000")
618 + HelpExampleRpc("getblockhash", "1000")
621 LOCK(cs_main);
623 int nHeight = request.params[0].get_int();
624 if (nHeight < 0 || nHeight > chainActive.Height())
625 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
627 CBlockIndex* pblockindex = chainActive[nHeight];
628 return pblockindex->GetBlockHash().GetHex();
631 UniValue getblockheader(const JSONRPCRequest& request)
633 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
634 throw std::runtime_error(
635 "getblockheader \"hash\" ( verbose )\n"
636 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
637 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
638 "\nArguments:\n"
639 "1. \"hash\" (string, required) The block hash\n"
640 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
641 "\nResult (for verbose = true):\n"
642 "{\n"
643 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
644 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
645 " \"height\" : n, (numeric) The block height or index\n"
646 " \"version\" : n, (numeric) The block version\n"
647 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
648 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
649 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
650 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
651 " \"nonce\" : n, (numeric) The nonce\n"
652 " \"bits\" : \"1d00ffff\", (string) The bits\n"
653 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
654 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
655 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
656 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
657 "}\n"
658 "\nResult (for verbose=false):\n"
659 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
660 "\nExamples:\n"
661 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
662 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
665 LOCK(cs_main);
667 std::string strHash = request.params[0].get_str();
668 uint256 hash(uint256S(strHash));
670 bool fVerbose = true;
671 if (!request.params[1].isNull())
672 fVerbose = request.params[1].get_bool();
674 if (mapBlockIndex.count(hash) == 0)
675 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
677 CBlockIndex* pblockindex = mapBlockIndex[hash];
679 if (!fVerbose)
681 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
682 ssBlock << pblockindex->GetBlockHeader();
683 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
684 return strHex;
687 return blockheaderToJSON(pblockindex);
690 UniValue getblock(const JSONRPCRequest& request)
692 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
693 throw std::runtime_error(
694 "getblock \"blockhash\" ( verbosity ) \n"
695 "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
696 "If verbosity is 1, returns an Object with information about block <hash>.\n"
697 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
698 "\nArguments:\n"
699 "1. \"blockhash\" (string, required) The block hash\n"
700 "2. verbosity (numeric, optional, default=1) 0 for hex encoded data, 1 for a json object, and 2 for json object with transaction data\n"
701 "\nResult (for verbosity = 0):\n"
702 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
703 "\nResult (for verbosity = 1):\n"
704 "{\n"
705 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
706 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
707 " \"size\" : n, (numeric) The block size\n"
708 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
709 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
710 " \"height\" : n, (numeric) The block height or index\n"
711 " \"version\" : n, (numeric) The block version\n"
712 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
713 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
714 " \"tx\" : [ (array of string) The transaction ids\n"
715 " \"transactionid\" (string) The transaction id\n"
716 " ,...\n"
717 " ],\n"
718 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
719 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
720 " \"nonce\" : n, (numeric) The nonce\n"
721 " \"bits\" : \"1d00ffff\", (string) The bits\n"
722 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
723 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
724 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
725 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
726 "}\n"
727 "\nResult (for verbosity = 2):\n"
728 "{\n"
729 " ..., Same output as verbosity = 1.\n"
730 " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
731 " ,...\n"
732 " ],\n"
733 " ,... Same output as verbosity = 1.\n"
734 "}\n"
735 "\nExamples:\n"
736 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
737 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
740 LOCK(cs_main);
742 std::string strHash = request.params[0].get_str();
743 uint256 hash(uint256S(strHash));
745 int verbosity = 1;
746 if (!request.params[1].isNull()) {
747 if(request.params[1].isNum())
748 verbosity = request.params[1].get_int();
749 else
750 verbosity = request.params[1].get_bool() ? 1 : 0;
753 if (mapBlockIndex.count(hash) == 0)
754 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
756 CBlock block;
757 CBlockIndex* pblockindex = mapBlockIndex[hash];
759 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
760 throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
762 if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
763 // Block not found on disk. This could be because we have the block
764 // header in our index but don't have the block (for example if a
765 // non-whitelisted node sends us an unrequested long chain of valid
766 // blocks, we add the headers to our index, but don't accept the
767 // block).
768 throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
770 if (verbosity <= 0)
772 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
773 ssBlock << block;
774 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
775 return strHex;
778 return blockToJSON(block, pblockindex, verbosity >= 2);
781 struct CCoinsStats
783 int nHeight;
784 uint256 hashBlock;
785 uint64_t nTransactions;
786 uint64_t nTransactionOutputs;
787 uint64_t nBogoSize;
788 uint256 hashSerialized;
789 uint64_t nDiskSize;
790 CAmount nTotalAmount;
792 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
795 static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
797 assert(!outputs.empty());
798 ss << hash;
799 ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase);
800 stats.nTransactions++;
801 for (const auto output : outputs) {
802 ss << VARINT(output.first + 1);
803 ss << output.second.out.scriptPubKey;
804 ss << VARINT(output.second.out.nValue);
805 stats.nTransactionOutputs++;
806 stats.nTotalAmount += output.second.out.nValue;
807 stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
808 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */;
810 ss << VARINT(0);
813 //! Calculate statistics about the unspent transaction output set
814 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
816 std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
818 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
819 stats.hashBlock = pcursor->GetBestBlock();
821 LOCK(cs_main);
822 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
824 ss << stats.hashBlock;
825 uint256 prevkey;
826 std::map<uint32_t, Coin> outputs;
827 while (pcursor->Valid()) {
828 boost::this_thread::interruption_point();
829 COutPoint key;
830 Coin coin;
831 if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
832 if (!outputs.empty() && key.hash != prevkey) {
833 ApplyStats(stats, ss, prevkey, outputs);
834 outputs.clear();
836 prevkey = key.hash;
837 outputs[key.n] = std::move(coin);
838 } else {
839 return error("%s: unable to read value", __func__);
841 pcursor->Next();
843 if (!outputs.empty()) {
844 ApplyStats(stats, ss, prevkey, outputs);
846 stats.hashSerialized = ss.GetHash();
847 stats.nDiskSize = view->EstimateSize();
848 return true;
851 UniValue pruneblockchain(const JSONRPCRequest& request)
853 if (request.fHelp || request.params.size() != 1)
854 throw std::runtime_error(
855 "pruneblockchain\n"
856 "\nArguments:\n"
857 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
858 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
859 "\nResult:\n"
860 "n (numeric) Height of the last block pruned.\n"
861 "\nExamples:\n"
862 + HelpExampleCli("pruneblockchain", "1000")
863 + HelpExampleRpc("pruneblockchain", "1000"));
865 if (!fPruneMode)
866 throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
868 LOCK(cs_main);
870 int heightParam = request.params[0].get_int();
871 if (heightParam < 0)
872 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
874 // Height value more than a billion is too high to be a block height, and
875 // too low to be a block time (corresponds to timestamp from Sep 2001).
876 if (heightParam > 1000000000) {
877 // Add a 2 hour buffer to include blocks which might have had old timestamps
878 CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
879 if (!pindex) {
880 throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
882 heightParam = pindex->nHeight;
885 unsigned int height = (unsigned int) heightParam;
886 unsigned int chainHeight = (unsigned int) chainActive.Height();
887 if (chainHeight < Params().PruneAfterHeight())
888 throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
889 else if (height > chainHeight)
890 throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
891 else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
892 LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
893 height = chainHeight - MIN_BLOCKS_TO_KEEP;
896 PruneBlockFilesManual(height);
897 return uint64_t(height);
900 UniValue gettxoutsetinfo(const JSONRPCRequest& request)
902 if (request.fHelp || request.params.size() != 0)
903 throw std::runtime_error(
904 "gettxoutsetinfo\n"
905 "\nReturns statistics about the unspent transaction output set.\n"
906 "Note this call may take some time.\n"
907 "\nResult:\n"
908 "{\n"
909 " \"height\":n, (numeric) The current block height (index)\n"
910 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
911 " \"transactions\": n, (numeric) The number of transactions\n"
912 " \"txouts\": n, (numeric) The number of output transactions\n"
913 " \"bogosize\": n, (numeric) A meaningless metric for UTXO set size\n"
914 " \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
915 " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
916 " \"total_amount\": x.xxx (numeric) The total amount\n"
917 "}\n"
918 "\nExamples:\n"
919 + HelpExampleCli("gettxoutsetinfo", "")
920 + HelpExampleRpc("gettxoutsetinfo", "")
923 UniValue ret(UniValue::VOBJ);
925 CCoinsStats stats;
926 FlushStateToDisk();
927 if (GetUTXOStats(pcoinsdbview, stats)) {
928 ret.push_back(Pair("height", (int64_t)stats.nHeight));
929 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
930 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
931 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
932 ret.push_back(Pair("bogosize", (int64_t)stats.nBogoSize));
933 ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
934 ret.push_back(Pair("disk_size", stats.nDiskSize));
935 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
936 } else {
937 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
939 return ret;
942 UniValue gettxout(const JSONRPCRequest& request)
944 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
945 throw std::runtime_error(
946 "gettxout \"txid\" n ( include_mempool )\n"
947 "\nReturns details about an unspent transaction output.\n"
948 "\nArguments:\n"
949 "1. \"txid\" (string, required) The transaction id\n"
950 "2. \"n\" (numeric, required) vout number\n"
951 "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true."
952 " Note that an unspent output that is spent in the mempool won't appear.\n"
953 "\nResult:\n"
954 "{\n"
955 " \"bestblock\" : \"hash\", (string) the block hash\n"
956 " \"confirmations\" : n, (numeric) The number of confirmations\n"
957 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
958 " \"scriptPubKey\" : { (json object)\n"
959 " \"asm\" : \"code\", (string) \n"
960 " \"hex\" : \"hex\", (string) \n"
961 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
962 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
963 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
964 " \"address\" (string) bitcoin address\n"
965 " ,...\n"
966 " ]\n"
967 " },\n"
968 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
969 "}\n"
971 "\nExamples:\n"
972 "\nGet unspent transactions\n"
973 + HelpExampleCli("listunspent", "") +
974 "\nView the details\n"
975 + HelpExampleCli("gettxout", "\"txid\" 1") +
976 "\nAs a json rpc call\n"
977 + HelpExampleRpc("gettxout", "\"txid\", 1")
980 LOCK(cs_main);
982 UniValue ret(UniValue::VOBJ);
984 std::string strHash = request.params[0].get_str();
985 uint256 hash(uint256S(strHash));
986 int n = request.params[1].get_int();
987 COutPoint out(hash, n);
988 bool fMempool = true;
989 if (!request.params[2].isNull())
990 fMempool = request.params[2].get_bool();
992 Coin coin;
993 if (fMempool) {
994 LOCK(mempool.cs);
995 CCoinsViewMemPool view(pcoinsTip, mempool);
996 if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
997 return NullUniValue;
999 } else {
1000 if (!pcoinsTip->GetCoin(out, coin)) {
1001 return NullUniValue;
1005 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
1006 CBlockIndex *pindex = it->second;
1007 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
1008 if (coin.nHeight == MEMPOOL_HEIGHT) {
1009 ret.push_back(Pair("confirmations", 0));
1010 } else {
1011 ret.push_back(Pair("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1)));
1013 ret.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
1014 UniValue o(UniValue::VOBJ);
1015 ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
1016 ret.push_back(Pair("scriptPubKey", o));
1017 ret.push_back(Pair("coinbase", (bool)coin.fCoinBase));
1019 return ret;
1022 UniValue verifychain(const JSONRPCRequest& request)
1024 int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL);
1025 int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1026 if (request.fHelp || request.params.size() > 2)
1027 throw std::runtime_error(
1028 "verifychain ( checklevel nblocks )\n"
1029 "\nVerifies blockchain database.\n"
1030 "\nArguments:\n"
1031 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1032 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1033 "\nResult:\n"
1034 "true|false (boolean) Verified or not\n"
1035 "\nExamples:\n"
1036 + HelpExampleCli("verifychain", "")
1037 + HelpExampleRpc("verifychain", "")
1040 LOCK(cs_main);
1042 if (!request.params[0].isNull())
1043 nCheckLevel = request.params[0].get_int();
1044 if (!request.params[1].isNull())
1045 nCheckDepth = request.params[1].get_int();
1047 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
1050 /** Implementation of IsSuperMajority with better feedback */
1051 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1053 UniValue rv(UniValue::VOBJ);
1054 bool activated = false;
1055 switch(version)
1057 case 2:
1058 activated = pindex->nHeight >= consensusParams.BIP34Height;
1059 break;
1060 case 3:
1061 activated = pindex->nHeight >= consensusParams.BIP66Height;
1062 break;
1063 case 4:
1064 activated = pindex->nHeight >= consensusParams.BIP65Height;
1065 break;
1067 rv.push_back(Pair("status", activated));
1068 return rv;
1071 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1073 UniValue rv(UniValue::VOBJ);
1074 rv.push_back(Pair("id", name));
1075 rv.push_back(Pair("version", version));
1076 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1077 return rv;
1080 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1082 UniValue rv(UniValue::VOBJ);
1083 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1084 switch (thresholdState) {
1085 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1086 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1087 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1088 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1089 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1091 if (THRESHOLD_STARTED == thresholdState)
1093 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1095 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1096 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1097 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1098 if (THRESHOLD_STARTED == thresholdState)
1100 UniValue statsUV(UniValue::VOBJ);
1101 BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);
1102 statsUV.push_back(Pair("period", statsStruct.period));
1103 statsUV.push_back(Pair("threshold", statsStruct.threshold));
1104 statsUV.push_back(Pair("elapsed", statsStruct.elapsed));
1105 statsUV.push_back(Pair("count", statsStruct.count));
1106 statsUV.push_back(Pair("possible", statsStruct.possible));
1107 rv.push_back(Pair("statistics", statsUV));
1109 return rv;
1112 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1114 // Deployments with timeout value of 0 are hidden.
1115 // A timeout value of 0 guarantees a softfork will never be activated.
1116 // This is used when softfork codes are merged without specifying the deployment schedule.
1117 if (consensusParams.vDeployments[id].nTimeout > 0)
1118 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
1121 UniValue getblockchaininfo(const JSONRPCRequest& request)
1123 if (request.fHelp || request.params.size() != 0)
1124 throw std::runtime_error(
1125 "getblockchaininfo\n"
1126 "Returns an object containing various state info regarding blockchain processing.\n"
1127 "\nResult:\n"
1128 "{\n"
1129 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1130 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1131 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1132 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1133 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1134 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1135 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1136 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1137 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1138 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1139 " \"softforks\": [ (array) status of softforks in progress\n"
1140 " {\n"
1141 " \"id\": \"xxxx\", (string) name of softfork\n"
1142 " \"version\": xx, (numeric) block version\n"
1143 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1144 " \"status\": xx, (boolean) true if threshold reached\n"
1145 " },\n"
1146 " }, ...\n"
1147 " ],\n"
1148 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1149 " \"xxxx\" : { (string) name of the softfork\n"
1150 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1151 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1152 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1153 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1154 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1155 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1156 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1157 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1158 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1159 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1160 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1161 " }\n"
1162 " }\n"
1163 " }\n"
1164 "}\n"
1165 "\nExamples:\n"
1166 + HelpExampleCli("getblockchaininfo", "")
1167 + HelpExampleRpc("getblockchaininfo", "")
1170 LOCK(cs_main);
1172 UniValue obj(UniValue::VOBJ);
1173 obj.push_back(Pair("chain", Params().NetworkIDString()));
1174 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1175 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1176 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1177 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1178 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1179 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1180 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1181 obj.push_back(Pair("pruned", fPruneMode));
1183 const Consensus::Params& consensusParams = Params().GetConsensus();
1184 CBlockIndex* tip = chainActive.Tip();
1185 UniValue softforks(UniValue::VARR);
1186 UniValue bip9_softforks(UniValue::VOBJ);
1187 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1188 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1189 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1190 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
1191 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
1192 obj.push_back(Pair("softforks", softforks));
1193 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1195 if (fPruneMode)
1197 CBlockIndex *block = chainActive.Tip();
1198 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
1199 block = block->pprev;
1201 obj.push_back(Pair("pruneheight", block->nHeight));
1203 return obj;
1206 /** Comparison function for sorting the getchaintips heads. */
1207 struct CompareBlocksByHeight
1209 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1211 /* Make sure that unequal blocks with the same height do not compare
1212 equal. Use the pointers themselves to make a distinction. */
1214 if (a->nHeight != b->nHeight)
1215 return (a->nHeight > b->nHeight);
1217 return a < b;
1221 UniValue getchaintips(const JSONRPCRequest& request)
1223 if (request.fHelp || request.params.size() != 0)
1224 throw std::runtime_error(
1225 "getchaintips\n"
1226 "Return information about all known tips in the block tree,"
1227 " including the main chain as well as orphaned branches.\n"
1228 "\nResult:\n"
1229 "[\n"
1230 " {\n"
1231 " \"height\": xxxx, (numeric) height of the chain tip\n"
1232 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1233 " \"branchlen\": 0 (numeric) zero for main chain\n"
1234 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1235 " },\n"
1236 " {\n"
1237 " \"height\": xxxx,\n"
1238 " \"hash\": \"xxxx\",\n"
1239 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1240 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1241 " }\n"
1242 "]\n"
1243 "Possible values for status:\n"
1244 "1. \"invalid\" This branch contains at least one invalid block\n"
1245 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1246 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1247 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1248 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1249 "\nExamples:\n"
1250 + HelpExampleCli("getchaintips", "")
1251 + HelpExampleRpc("getchaintips", "")
1254 LOCK(cs_main);
1257 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1258 * Algorithm:
1259 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1260 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1261 * - add chainActive.Tip()
1263 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1264 std::set<const CBlockIndex*> setOrphans;
1265 std::set<const CBlockIndex*> setPrevs;
1267 for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
1269 if (!chainActive.Contains(item.second)) {
1270 setOrphans.insert(item.second);
1271 setPrevs.insert(item.second->pprev);
1275 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1277 if (setPrevs.erase(*it) == 0) {
1278 setTips.insert(*it);
1282 // Always report the currently active tip.
1283 setTips.insert(chainActive.Tip());
1285 /* Construct the output array. */
1286 UniValue res(UniValue::VARR);
1287 for (const CBlockIndex* block : setTips)
1289 UniValue obj(UniValue::VOBJ);
1290 obj.push_back(Pair("height", block->nHeight));
1291 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1293 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1294 obj.push_back(Pair("branchlen", branchLen));
1296 std::string status;
1297 if (chainActive.Contains(block)) {
1298 // This block is part of the currently active chain.
1299 status = "active";
1300 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1301 // This block or one of its ancestors is invalid.
1302 status = "invalid";
1303 } else if (block->nChainTx == 0) {
1304 // This block cannot be connected because full block data for it or one of its parents is missing.
1305 status = "headers-only";
1306 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1307 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1308 status = "valid-fork";
1309 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1310 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1311 status = "valid-headers";
1312 } else {
1313 // No clue.
1314 status = "unknown";
1316 obj.push_back(Pair("status", status));
1318 res.push_back(obj);
1321 return res;
1324 UniValue mempoolInfoToJSON()
1326 UniValue ret(UniValue::VOBJ);
1327 ret.push_back(Pair("size", (int64_t) mempool.size()));
1328 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1329 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1330 size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1331 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1332 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1334 return ret;
1337 UniValue getmempoolinfo(const JSONRPCRequest& request)
1339 if (request.fHelp || request.params.size() != 0)
1340 throw std::runtime_error(
1341 "getmempoolinfo\n"
1342 "\nReturns details on the active state of the TX memory pool.\n"
1343 "\nResult:\n"
1344 "{\n"
1345 " \"size\": xxxxx, (numeric) Current tx count\n"
1346 " \"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"
1347 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1348 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1349 " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n"
1350 "}\n"
1351 "\nExamples:\n"
1352 + HelpExampleCli("getmempoolinfo", "")
1353 + HelpExampleRpc("getmempoolinfo", "")
1356 return mempoolInfoToJSON();
1359 UniValue preciousblock(const JSONRPCRequest& request)
1361 if (request.fHelp || request.params.size() != 1)
1362 throw std::runtime_error(
1363 "preciousblock \"blockhash\"\n"
1364 "\nTreats a block as if it were received before others with the same work.\n"
1365 "\nA later preciousblock call can override the effect of an earlier one.\n"
1366 "\nThe effects of preciousblock are not retained across restarts.\n"
1367 "\nArguments:\n"
1368 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1369 "\nResult:\n"
1370 "\nExamples:\n"
1371 + HelpExampleCli("preciousblock", "\"blockhash\"")
1372 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1375 std::string strHash = request.params[0].get_str();
1376 uint256 hash(uint256S(strHash));
1377 CBlockIndex* pblockindex;
1380 LOCK(cs_main);
1381 if (mapBlockIndex.count(hash) == 0)
1382 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1384 pblockindex = mapBlockIndex[hash];
1387 CValidationState state;
1388 PreciousBlock(state, Params(), pblockindex);
1390 if (!state.IsValid()) {
1391 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1394 return NullUniValue;
1397 UniValue invalidateblock(const JSONRPCRequest& request)
1399 if (request.fHelp || request.params.size() != 1)
1400 throw std::runtime_error(
1401 "invalidateblock \"blockhash\"\n"
1402 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1403 "\nArguments:\n"
1404 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1405 "\nResult:\n"
1406 "\nExamples:\n"
1407 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1408 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1411 std::string strHash = request.params[0].get_str();
1412 uint256 hash(uint256S(strHash));
1413 CValidationState state;
1416 LOCK(cs_main);
1417 if (mapBlockIndex.count(hash) == 0)
1418 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1420 CBlockIndex* pblockindex = mapBlockIndex[hash];
1421 InvalidateBlock(state, Params(), pblockindex);
1424 if (state.IsValid()) {
1425 ActivateBestChain(state, Params());
1428 if (!state.IsValid()) {
1429 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1432 return NullUniValue;
1435 UniValue reconsiderblock(const JSONRPCRequest& request)
1437 if (request.fHelp || request.params.size() != 1)
1438 throw std::runtime_error(
1439 "reconsiderblock \"blockhash\"\n"
1440 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1441 "This can be used to undo the effects of invalidateblock.\n"
1442 "\nArguments:\n"
1443 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1444 "\nResult:\n"
1445 "\nExamples:\n"
1446 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1447 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1450 std::string strHash = request.params[0].get_str();
1451 uint256 hash(uint256S(strHash));
1454 LOCK(cs_main);
1455 if (mapBlockIndex.count(hash) == 0)
1456 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1458 CBlockIndex* pblockindex = mapBlockIndex[hash];
1459 ResetBlockFailureFlags(pblockindex);
1462 CValidationState state;
1463 ActivateBestChain(state, Params());
1465 if (!state.IsValid()) {
1466 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1469 return NullUniValue;
1472 UniValue getchaintxstats(const JSONRPCRequest& request)
1474 if (request.fHelp || request.params.size() > 2)
1475 throw std::runtime_error(
1476 "getchaintxstats ( nblocks blockhash )\n"
1477 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1478 "\nArguments:\n"
1479 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1480 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1481 "\nResult:\n"
1482 "{\n"
1483 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1484 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1485 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1486 "}\n"
1487 "\nExamples:\n"
1488 + HelpExampleCli("getchaintxstats", "")
1489 + HelpExampleRpc("getchaintxstats", "2016")
1492 const CBlockIndex* pindex;
1493 int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1495 if (!request.params[0].isNull()) {
1496 blockcount = request.params[0].get_int();
1499 bool havehash = !request.params[1].isNull();
1500 uint256 hash;
1501 if (havehash) {
1502 hash = uint256S(request.params[1].get_str());
1506 LOCK(cs_main);
1507 if (havehash) {
1508 auto it = mapBlockIndex.find(hash);
1509 if (it == mapBlockIndex.end()) {
1510 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1512 pindex = it->second;
1513 if (!chainActive.Contains(pindex)) {
1514 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1516 } else {
1517 pindex = chainActive.Tip();
1521 if (blockcount < 1 || blockcount >= pindex->nHeight) {
1522 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height");
1525 const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1526 int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1527 int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1529 UniValue ret(UniValue::VOBJ);
1530 ret.push_back(Pair("time", (int64_t)pindex->nTime));
1531 ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx));
1532 ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff));
1534 return ret;
1537 UniValue savemempool(const JSONRPCRequest& request)
1539 if (request.fHelp || request.params.size() != 0) {
1540 throw std::runtime_error(
1541 "savemempool\n"
1542 "\nDumps the mempool to disk.\n"
1543 "\nExamples:\n"
1544 + HelpExampleCli("savemempool", "")
1545 + HelpExampleRpc("savemempool", "")
1549 if (!DumpMempool()) {
1550 throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
1553 return NullUniValue;
1556 static const CRPCCommand commands[] =
1557 { // category name actor (function) argNames
1558 // --------------------- ------------------------ ----------------------- ----------
1559 { "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
1560 { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
1561 { "blockchain", "getbestblockhash", &getbestblockhash, {} },
1562 { "blockchain", "getblockcount", &getblockcount, {} },
1563 { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
1564 { "blockchain", "getblockhash", &getblockhash, {"height"} },
1565 { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
1566 { "blockchain", "getchaintips", &getchaintips, {} },
1567 { "blockchain", "getdifficulty", &getdifficulty, {} },
1568 { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
1569 { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
1570 { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
1571 { "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
1572 { "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
1573 { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
1574 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
1575 { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
1576 { "blockchain", "savemempool", &savemempool, {} },
1577 { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
1579 { "blockchain", "preciousblock", &preciousblock, {"blockhash"} },
1581 /* Not shown in help */
1582 { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
1583 { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
1584 { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
1585 { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
1586 { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
1589 void RegisterBlockchainRPCCommands(CRPCTable &t)
1591 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1592 t.appendCommand(commands[vcidx].name, &commands[vcidx]);