Use the variable name _ for unused return values
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blob34f553f3b07701f8f46794409941a9b1ac02f566
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 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
347 " \"transactionid\", (string) parent transaction id\n"
348 " ... ]\n";
351 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
353 AssertLockHeld(mempool.cs);
355 info.push_back(Pair("size", (int)e.GetTxSize()));
356 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
357 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
358 info.push_back(Pair("time", e.GetTime()));
359 info.push_back(Pair("height", (int)e.GetHeight()));
360 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
361 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
362 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
363 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
364 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
365 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
366 const CTransaction& tx = e.GetTx();
367 std::set<std::string> setDepends;
368 for (const CTxIn& txin : tx.vin)
370 if (mempool.exists(txin.prevout.hash))
371 setDepends.insert(txin.prevout.hash.ToString());
374 UniValue depends(UniValue::VARR);
375 for (const std::string& dep : setDepends)
377 depends.push_back(dep);
380 info.push_back(Pair("depends", depends));
383 UniValue mempoolToJSON(bool fVerbose)
385 if (fVerbose)
387 LOCK(mempool.cs);
388 UniValue o(UniValue::VOBJ);
389 for (const CTxMemPoolEntry& e : mempool.mapTx)
391 const uint256& hash = e.GetTx().GetHash();
392 UniValue info(UniValue::VOBJ);
393 entryToJSON(info, e);
394 o.push_back(Pair(hash.ToString(), info));
396 return o;
398 else
400 std::vector<uint256> vtxid;
401 mempool.queryHashes(vtxid);
403 UniValue a(UniValue::VARR);
404 for (const uint256& hash : vtxid)
405 a.push_back(hash.ToString());
407 return a;
411 UniValue getrawmempool(const JSONRPCRequest& request)
413 if (request.fHelp || request.params.size() > 1)
414 throw std::runtime_error(
415 "getrawmempool ( verbose )\n"
416 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
417 "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n"
418 "\nArguments:\n"
419 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
420 "\nResult: (for verbose = false):\n"
421 "[ (json array of string)\n"
422 " \"transactionid\" (string) The transaction id\n"
423 " ,...\n"
424 "]\n"
425 "\nResult: (for verbose = true):\n"
426 "{ (json object)\n"
427 " \"transactionid\" : { (json object)\n"
428 + EntryDescriptionString()
429 + " }, ...\n"
430 "}\n"
431 "\nExamples:\n"
432 + HelpExampleCli("getrawmempool", "true")
433 + HelpExampleRpc("getrawmempool", "true")
436 bool fVerbose = false;
437 if (!request.params[0].isNull())
438 fVerbose = request.params[0].get_bool();
440 return mempoolToJSON(fVerbose);
443 UniValue getmempoolancestors(const JSONRPCRequest& request)
445 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
446 throw std::runtime_error(
447 "getmempoolancestors txid (verbose)\n"
448 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
449 "\nArguments:\n"
450 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
451 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
452 "\nResult (for verbose=false):\n"
453 "[ (json array of strings)\n"
454 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
455 " ,...\n"
456 "]\n"
457 "\nResult (for verbose=true):\n"
458 "{ (json object)\n"
459 " \"transactionid\" : { (json object)\n"
460 + EntryDescriptionString()
461 + " }, ...\n"
462 "}\n"
463 "\nExamples:\n"
464 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
465 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
469 bool fVerbose = false;
470 if (!request.params[1].isNull())
471 fVerbose = request.params[1].get_bool();
473 uint256 hash = ParseHashV(request.params[0], "parameter 1");
475 LOCK(mempool.cs);
477 CTxMemPool::txiter it = mempool.mapTx.find(hash);
478 if (it == mempool.mapTx.end()) {
479 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
482 CTxMemPool::setEntries setAncestors;
483 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
484 std::string dummy;
485 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
487 if (!fVerbose) {
488 UniValue o(UniValue::VARR);
489 for (CTxMemPool::txiter ancestorIt : setAncestors) {
490 o.push_back(ancestorIt->GetTx().GetHash().ToString());
493 return o;
494 } else {
495 UniValue o(UniValue::VOBJ);
496 for (CTxMemPool::txiter ancestorIt : setAncestors) {
497 const CTxMemPoolEntry &e = *ancestorIt;
498 const uint256& _hash = e.GetTx().GetHash();
499 UniValue info(UniValue::VOBJ);
500 entryToJSON(info, e);
501 o.push_back(Pair(_hash.ToString(), info));
503 return o;
507 UniValue getmempooldescendants(const JSONRPCRequest& request)
509 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
510 throw std::runtime_error(
511 "getmempooldescendants txid (verbose)\n"
512 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
513 "\nArguments:\n"
514 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
515 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
516 "\nResult (for verbose=false):\n"
517 "[ (json array of strings)\n"
518 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
519 " ,...\n"
520 "]\n"
521 "\nResult (for verbose=true):\n"
522 "{ (json object)\n"
523 " \"transactionid\" : { (json object)\n"
524 + EntryDescriptionString()
525 + " }, ...\n"
526 "}\n"
527 "\nExamples:\n"
528 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
529 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
533 bool fVerbose = false;
534 if (!request.params[1].isNull())
535 fVerbose = request.params[1].get_bool();
537 uint256 hash = ParseHashV(request.params[0], "parameter 1");
539 LOCK(mempool.cs);
541 CTxMemPool::txiter it = mempool.mapTx.find(hash);
542 if (it == mempool.mapTx.end()) {
543 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
546 CTxMemPool::setEntries setDescendants;
547 mempool.CalculateDescendants(it, setDescendants);
548 // CTxMemPool::CalculateDescendants will include the given tx
549 setDescendants.erase(it);
551 if (!fVerbose) {
552 UniValue o(UniValue::VARR);
553 for (CTxMemPool::txiter descendantIt : setDescendants) {
554 o.push_back(descendantIt->GetTx().GetHash().ToString());
557 return o;
558 } else {
559 UniValue o(UniValue::VOBJ);
560 for (CTxMemPool::txiter descendantIt : setDescendants) {
561 const CTxMemPoolEntry &e = *descendantIt;
562 const uint256& _hash = e.GetTx().GetHash();
563 UniValue info(UniValue::VOBJ);
564 entryToJSON(info, e);
565 o.push_back(Pair(_hash.ToString(), info));
567 return o;
571 UniValue getmempoolentry(const JSONRPCRequest& request)
573 if (request.fHelp || request.params.size() != 1) {
574 throw std::runtime_error(
575 "getmempoolentry txid\n"
576 "\nReturns mempool data for given transaction\n"
577 "\nArguments:\n"
578 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
579 "\nResult:\n"
580 "{ (json object)\n"
581 + EntryDescriptionString()
582 + "}\n"
583 "\nExamples:\n"
584 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
585 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
589 uint256 hash = ParseHashV(request.params[0], "parameter 1");
591 LOCK(mempool.cs);
593 CTxMemPool::txiter it = mempool.mapTx.find(hash);
594 if (it == mempool.mapTx.end()) {
595 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
598 const CTxMemPoolEntry &e = *it;
599 UniValue info(UniValue::VOBJ);
600 entryToJSON(info, e);
601 return info;
604 UniValue getblockhash(const JSONRPCRequest& request)
606 if (request.fHelp || request.params.size() != 1)
607 throw std::runtime_error(
608 "getblockhash height\n"
609 "\nReturns hash of block in best-block-chain at height provided.\n"
610 "\nArguments:\n"
611 "1. height (numeric, required) The height index\n"
612 "\nResult:\n"
613 "\"hash\" (string) The block hash\n"
614 "\nExamples:\n"
615 + HelpExampleCli("getblockhash", "1000")
616 + HelpExampleRpc("getblockhash", "1000")
619 LOCK(cs_main);
621 int nHeight = request.params[0].get_int();
622 if (nHeight < 0 || nHeight > chainActive.Height())
623 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
625 CBlockIndex* pblockindex = chainActive[nHeight];
626 return pblockindex->GetBlockHash().GetHex();
629 UniValue getblockheader(const JSONRPCRequest& request)
631 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
632 throw std::runtime_error(
633 "getblockheader \"hash\" ( verbose )\n"
634 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
635 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
636 "\nArguments:\n"
637 "1. \"hash\" (string, required) The block hash\n"
638 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
639 "\nResult (for verbose = true):\n"
640 "{\n"
641 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
642 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
643 " \"height\" : n, (numeric) The block height or index\n"
644 " \"version\" : n, (numeric) The block version\n"
645 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
646 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
647 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
648 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
649 " \"nonce\" : n, (numeric) The nonce\n"
650 " \"bits\" : \"1d00ffff\", (string) The bits\n"
651 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
652 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
653 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
654 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
655 "}\n"
656 "\nResult (for verbose=false):\n"
657 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
658 "\nExamples:\n"
659 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
660 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
663 LOCK(cs_main);
665 std::string strHash = request.params[0].get_str();
666 uint256 hash(uint256S(strHash));
668 bool fVerbose = true;
669 if (!request.params[1].isNull())
670 fVerbose = request.params[1].get_bool();
672 if (mapBlockIndex.count(hash) == 0)
673 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
675 CBlockIndex* pblockindex = mapBlockIndex[hash];
677 if (!fVerbose)
679 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
680 ssBlock << pblockindex->GetBlockHeader();
681 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
682 return strHex;
685 return blockheaderToJSON(pblockindex);
688 UniValue getblock(const JSONRPCRequest& request)
690 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
691 throw std::runtime_error(
692 "getblock \"blockhash\" ( verbosity ) \n"
693 "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
694 "If verbosity is 1, returns an Object with information about block <hash>.\n"
695 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
696 "\nArguments:\n"
697 "1. \"blockhash\" (string, required) The block hash\n"
698 "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"
699 "\nResult (for verbosity = 0):\n"
700 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
701 "\nResult (for verbosity = 1):\n"
702 "{\n"
703 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
704 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
705 " \"size\" : n, (numeric) The block size\n"
706 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
707 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
708 " \"height\" : n, (numeric) The block height or index\n"
709 " \"version\" : n, (numeric) The block version\n"
710 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
711 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
712 " \"tx\" : [ (array of string) The transaction ids\n"
713 " \"transactionid\" (string) The transaction id\n"
714 " ,...\n"
715 " ],\n"
716 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
717 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
718 " \"nonce\" : n, (numeric) The nonce\n"
719 " \"bits\" : \"1d00ffff\", (string) The bits\n"
720 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
721 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
722 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
723 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
724 "}\n"
725 "\nResult (for verbosity = 2):\n"
726 "{\n"
727 " ..., Same output as verbosity = 1.\n"
728 " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
729 " ,...\n"
730 " ],\n"
731 " ,... Same output as verbosity = 1.\n"
732 "}\n"
733 "\nExamples:\n"
734 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
735 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
738 LOCK(cs_main);
740 std::string strHash = request.params[0].get_str();
741 uint256 hash(uint256S(strHash));
743 int verbosity = 1;
744 if (!request.params[1].isNull()) {
745 if(request.params[1].isNum())
746 verbosity = request.params[1].get_int();
747 else
748 verbosity = request.params[1].get_bool() ? 1 : 0;
751 if (mapBlockIndex.count(hash) == 0)
752 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
754 CBlock block;
755 CBlockIndex* pblockindex = mapBlockIndex[hash];
757 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
758 throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
760 if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
761 // Block not found on disk. This could be because we have the block
762 // header in our index but don't have the block (for example if a
763 // non-whitelisted node sends us an unrequested long chain of valid
764 // blocks, we add the headers to our index, but don't accept the
765 // block).
766 throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
768 if (verbosity <= 0)
770 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
771 ssBlock << block;
772 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
773 return strHex;
776 return blockToJSON(block, pblockindex, verbosity >= 2);
779 struct CCoinsStats
781 int nHeight;
782 uint256 hashBlock;
783 uint64_t nTransactions;
784 uint64_t nTransactionOutputs;
785 uint64_t nBogoSize;
786 uint256 hashSerialized;
787 uint64_t nDiskSize;
788 CAmount nTotalAmount;
790 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
793 static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
795 assert(!outputs.empty());
796 ss << hash;
797 ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase);
798 stats.nTransactions++;
799 for (const auto output : outputs) {
800 ss << VARINT(output.first + 1);
801 ss << output.second.out.scriptPubKey;
802 ss << VARINT(output.second.out.nValue);
803 stats.nTransactionOutputs++;
804 stats.nTotalAmount += output.second.out.nValue;
805 stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
806 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */;
808 ss << VARINT(0);
811 //! Calculate statistics about the unspent transaction output set
812 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
814 std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
816 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
817 stats.hashBlock = pcursor->GetBestBlock();
819 LOCK(cs_main);
820 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
822 ss << stats.hashBlock;
823 uint256 prevkey;
824 std::map<uint32_t, Coin> outputs;
825 while (pcursor->Valid()) {
826 boost::this_thread::interruption_point();
827 COutPoint key;
828 Coin coin;
829 if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
830 if (!outputs.empty() && key.hash != prevkey) {
831 ApplyStats(stats, ss, prevkey, outputs);
832 outputs.clear();
834 prevkey = key.hash;
835 outputs[key.n] = std::move(coin);
836 } else {
837 return error("%s: unable to read value", __func__);
839 pcursor->Next();
841 if (!outputs.empty()) {
842 ApplyStats(stats, ss, prevkey, outputs);
844 stats.hashSerialized = ss.GetHash();
845 stats.nDiskSize = view->EstimateSize();
846 return true;
849 UniValue pruneblockchain(const JSONRPCRequest& request)
851 if (request.fHelp || request.params.size() != 1)
852 throw std::runtime_error(
853 "pruneblockchain\n"
854 "\nArguments:\n"
855 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
856 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
857 "\nResult:\n"
858 "n (numeric) Height of the last block pruned.\n"
859 "\nExamples:\n"
860 + HelpExampleCli("pruneblockchain", "1000")
861 + HelpExampleRpc("pruneblockchain", "1000"));
863 if (!fPruneMode)
864 throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
866 LOCK(cs_main);
868 int heightParam = request.params[0].get_int();
869 if (heightParam < 0)
870 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
872 // Height value more than a billion is too high to be a block height, and
873 // too low to be a block time (corresponds to timestamp from Sep 2001).
874 if (heightParam > 1000000000) {
875 // Add a 2 hour buffer to include blocks which might have had old timestamps
876 CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
877 if (!pindex) {
878 throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
880 heightParam = pindex->nHeight;
883 unsigned int height = (unsigned int) heightParam;
884 unsigned int chainHeight = (unsigned int) chainActive.Height();
885 if (chainHeight < Params().PruneAfterHeight())
886 throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
887 else if (height > chainHeight)
888 throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
889 else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
890 LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
891 height = chainHeight - MIN_BLOCKS_TO_KEEP;
894 PruneBlockFilesManual(height);
895 return uint64_t(height);
898 UniValue gettxoutsetinfo(const JSONRPCRequest& request)
900 if (request.fHelp || request.params.size() != 0)
901 throw std::runtime_error(
902 "gettxoutsetinfo\n"
903 "\nReturns statistics about the unspent transaction output set.\n"
904 "Note this call may take some time.\n"
905 "\nResult:\n"
906 "{\n"
907 " \"height\":n, (numeric) The current block height (index)\n"
908 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
909 " \"transactions\": n, (numeric) The number of transactions\n"
910 " \"txouts\": n, (numeric) The number of output transactions\n"
911 " \"bogosize\": n, (numeric) A meaningless metric for UTXO set size\n"
912 " \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
913 " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
914 " \"total_amount\": x.xxx (numeric) The total amount\n"
915 "}\n"
916 "\nExamples:\n"
917 + HelpExampleCli("gettxoutsetinfo", "")
918 + HelpExampleRpc("gettxoutsetinfo", "")
921 UniValue ret(UniValue::VOBJ);
923 CCoinsStats stats;
924 FlushStateToDisk();
925 if (GetUTXOStats(pcoinsdbview, stats)) {
926 ret.push_back(Pair("height", (int64_t)stats.nHeight));
927 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
928 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
929 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
930 ret.push_back(Pair("bogosize", (int64_t)stats.nBogoSize));
931 ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
932 ret.push_back(Pair("disk_size", stats.nDiskSize));
933 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
934 } else {
935 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
937 return ret;
940 UniValue gettxout(const JSONRPCRequest& request)
942 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
943 throw std::runtime_error(
944 "gettxout \"txid\" n ( include_mempool )\n"
945 "\nReturns details about an unspent transaction output.\n"
946 "\nArguments:\n"
947 "1. \"txid\" (string, required) The transaction id\n"
948 "2. n (numeric, required) vout number\n"
949 "3. include_mempool (boolean, optional) Whether to include the mempool\n"
950 "\nResult:\n"
951 "{\n"
952 " \"bestblock\" : \"hash\", (string) the block hash\n"
953 " \"confirmations\" : n, (numeric) The number of confirmations\n"
954 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
955 " \"scriptPubKey\" : { (json object)\n"
956 " \"asm\" : \"code\", (string) \n"
957 " \"hex\" : \"hex\", (string) \n"
958 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
959 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
960 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
961 " \"address\" (string) bitcoin address\n"
962 " ,...\n"
963 " ]\n"
964 " },\n"
965 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
966 "}\n"
968 "\nExamples:\n"
969 "\nGet unspent transactions\n"
970 + HelpExampleCli("listunspent", "") +
971 "\nView the details\n"
972 + HelpExampleCli("gettxout", "\"txid\" 1") +
973 "\nAs a json rpc call\n"
974 + HelpExampleRpc("gettxout", "\"txid\", 1")
977 LOCK(cs_main);
979 UniValue ret(UniValue::VOBJ);
981 std::string strHash = request.params[0].get_str();
982 uint256 hash(uint256S(strHash));
983 int n = request.params[1].get_int();
984 COutPoint out(hash, n);
985 bool fMempool = true;
986 if (!request.params[2].isNull())
987 fMempool = request.params[2].get_bool();
989 Coin coin;
990 if (fMempool) {
991 LOCK(mempool.cs);
992 CCoinsViewMemPool view(pcoinsTip, mempool);
993 if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
994 return NullUniValue;
996 } else {
997 if (!pcoinsTip->GetCoin(out, coin)) {
998 return NullUniValue;
1002 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
1003 CBlockIndex *pindex = it->second;
1004 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
1005 if (coin.nHeight == MEMPOOL_HEIGHT) {
1006 ret.push_back(Pair("confirmations", 0));
1007 } else {
1008 ret.push_back(Pair("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1)));
1010 ret.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
1011 UniValue o(UniValue::VOBJ);
1012 ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
1013 ret.push_back(Pair("scriptPubKey", o));
1014 ret.push_back(Pair("coinbase", (bool)coin.fCoinBase));
1016 return ret;
1019 UniValue verifychain(const JSONRPCRequest& request)
1021 int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL);
1022 int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1023 if (request.fHelp || request.params.size() > 2)
1024 throw std::runtime_error(
1025 "verifychain ( checklevel nblocks )\n"
1026 "\nVerifies blockchain database.\n"
1027 "\nArguments:\n"
1028 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1029 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1030 "\nResult:\n"
1031 "true|false (boolean) Verified or not\n"
1032 "\nExamples:\n"
1033 + HelpExampleCli("verifychain", "")
1034 + HelpExampleRpc("verifychain", "")
1037 LOCK(cs_main);
1039 if (!request.params[0].isNull())
1040 nCheckLevel = request.params[0].get_int();
1041 if (!request.params[1].isNull())
1042 nCheckDepth = request.params[1].get_int();
1044 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
1047 /** Implementation of IsSuperMajority with better feedback */
1048 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1050 UniValue rv(UniValue::VOBJ);
1051 bool activated = false;
1052 switch(version)
1054 case 2:
1055 activated = pindex->nHeight >= consensusParams.BIP34Height;
1056 break;
1057 case 3:
1058 activated = pindex->nHeight >= consensusParams.BIP66Height;
1059 break;
1060 case 4:
1061 activated = pindex->nHeight >= consensusParams.BIP65Height;
1062 break;
1064 rv.push_back(Pair("status", activated));
1065 return rv;
1068 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1070 UniValue rv(UniValue::VOBJ);
1071 rv.push_back(Pair("id", name));
1072 rv.push_back(Pair("version", version));
1073 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1074 return rv;
1077 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1079 UniValue rv(UniValue::VOBJ);
1080 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1081 switch (thresholdState) {
1082 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1083 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1084 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1085 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1086 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1088 if (THRESHOLD_STARTED == thresholdState)
1090 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1092 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1093 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1094 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1095 if (THRESHOLD_STARTED == thresholdState)
1097 UniValue statsUV(UniValue::VOBJ);
1098 BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);
1099 statsUV.push_back(Pair("period", statsStruct.period));
1100 statsUV.push_back(Pair("threshold", statsStruct.threshold));
1101 statsUV.push_back(Pair("elapsed", statsStruct.elapsed));
1102 statsUV.push_back(Pair("count", statsStruct.count));
1103 statsUV.push_back(Pair("possible", statsStruct.possible));
1104 rv.push_back(Pair("statistics", statsUV));
1106 return rv;
1109 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1111 // Deployments with timeout value of 0 are hidden.
1112 // A timeout value of 0 guarantees a softfork will never be activated.
1113 // This is used when softfork codes are merged without specifying the deployment schedule.
1114 if (consensusParams.vDeployments[id].nTimeout > 0)
1115 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
1118 UniValue getblockchaininfo(const JSONRPCRequest& request)
1120 if (request.fHelp || request.params.size() != 0)
1121 throw std::runtime_error(
1122 "getblockchaininfo\n"
1123 "Returns an object containing various state info regarding blockchain processing.\n"
1124 "\nResult:\n"
1125 "{\n"
1126 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1127 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1128 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1129 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1130 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1131 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1132 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1133 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1134 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1135 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1136 " \"softforks\": [ (array) status of softforks in progress\n"
1137 " {\n"
1138 " \"id\": \"xxxx\", (string) name of softfork\n"
1139 " \"version\": xx, (numeric) block version\n"
1140 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1141 " \"status\": xx, (boolean) true if threshold reached\n"
1142 " },\n"
1143 " }, ...\n"
1144 " ],\n"
1145 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1146 " \"xxxx\" : { (string) name of the softfork\n"
1147 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1148 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1149 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1150 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1151 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1152 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1153 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1154 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1155 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1156 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1157 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1158 " }\n"
1159 " }\n"
1160 " }\n"
1161 "}\n"
1162 "\nExamples:\n"
1163 + HelpExampleCli("getblockchaininfo", "")
1164 + HelpExampleRpc("getblockchaininfo", "")
1167 LOCK(cs_main);
1169 UniValue obj(UniValue::VOBJ);
1170 obj.push_back(Pair("chain", Params().NetworkIDString()));
1171 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1172 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1173 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1174 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1175 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1176 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1177 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1178 obj.push_back(Pair("pruned", fPruneMode));
1180 const Consensus::Params& consensusParams = Params().GetConsensus();
1181 CBlockIndex* tip = chainActive.Tip();
1182 UniValue softforks(UniValue::VARR);
1183 UniValue bip9_softforks(UniValue::VOBJ);
1184 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1185 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1186 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1187 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
1188 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
1189 obj.push_back(Pair("softforks", softforks));
1190 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1192 if (fPruneMode)
1194 CBlockIndex *block = chainActive.Tip();
1195 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
1196 block = block->pprev;
1198 obj.push_back(Pair("pruneheight", block->nHeight));
1200 return obj;
1203 /** Comparison function for sorting the getchaintips heads. */
1204 struct CompareBlocksByHeight
1206 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1208 /* Make sure that unequal blocks with the same height do not compare
1209 equal. Use the pointers themselves to make a distinction. */
1211 if (a->nHeight != b->nHeight)
1212 return (a->nHeight > b->nHeight);
1214 return a < b;
1218 UniValue getchaintips(const JSONRPCRequest& request)
1220 if (request.fHelp || request.params.size() != 0)
1221 throw std::runtime_error(
1222 "getchaintips\n"
1223 "Return information about all known tips in the block tree,"
1224 " including the main chain as well as orphaned branches.\n"
1225 "\nResult:\n"
1226 "[\n"
1227 " {\n"
1228 " \"height\": xxxx, (numeric) height of the chain tip\n"
1229 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1230 " \"branchlen\": 0 (numeric) zero for main chain\n"
1231 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1232 " },\n"
1233 " {\n"
1234 " \"height\": xxxx,\n"
1235 " \"hash\": \"xxxx\",\n"
1236 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1237 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1238 " }\n"
1239 "]\n"
1240 "Possible values for status:\n"
1241 "1. \"invalid\" This branch contains at least one invalid block\n"
1242 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1243 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1244 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1245 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1246 "\nExamples:\n"
1247 + HelpExampleCli("getchaintips", "")
1248 + HelpExampleRpc("getchaintips", "")
1251 LOCK(cs_main);
1254 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1255 * Algorithm:
1256 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1257 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1258 * - add chainActive.Tip()
1260 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1261 std::set<const CBlockIndex*> setOrphans;
1262 std::set<const CBlockIndex*> setPrevs;
1264 for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
1266 if (!chainActive.Contains(item.second)) {
1267 setOrphans.insert(item.second);
1268 setPrevs.insert(item.second->pprev);
1272 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1274 if (setPrevs.erase(*it) == 0) {
1275 setTips.insert(*it);
1279 // Always report the currently active tip.
1280 setTips.insert(chainActive.Tip());
1282 /* Construct the output array. */
1283 UniValue res(UniValue::VARR);
1284 for (const CBlockIndex* block : setTips)
1286 UniValue obj(UniValue::VOBJ);
1287 obj.push_back(Pair("height", block->nHeight));
1288 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1290 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1291 obj.push_back(Pair("branchlen", branchLen));
1293 std::string status;
1294 if (chainActive.Contains(block)) {
1295 // This block is part of the currently active chain.
1296 status = "active";
1297 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1298 // This block or one of its ancestors is invalid.
1299 status = "invalid";
1300 } else if (block->nChainTx == 0) {
1301 // This block cannot be connected because full block data for it or one of its parents is missing.
1302 status = "headers-only";
1303 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1304 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1305 status = "valid-fork";
1306 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1307 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1308 status = "valid-headers";
1309 } else {
1310 // No clue.
1311 status = "unknown";
1313 obj.push_back(Pair("status", status));
1315 res.push_back(obj);
1318 return res;
1321 UniValue mempoolInfoToJSON()
1323 UniValue ret(UniValue::VOBJ);
1324 ret.push_back(Pair("size", (int64_t) mempool.size()));
1325 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1326 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1327 size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1328 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1329 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1331 return ret;
1334 UniValue getmempoolinfo(const JSONRPCRequest& request)
1336 if (request.fHelp || request.params.size() != 0)
1337 throw std::runtime_error(
1338 "getmempoolinfo\n"
1339 "\nReturns details on the active state of the TX memory pool.\n"
1340 "\nResult:\n"
1341 "{\n"
1342 " \"size\": xxxxx, (numeric) Current tx count\n"
1343 " \"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"
1344 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1345 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1346 " \"mempoolminfee\": xxxxx (numeric) Minimum feerate (" + CURRENCY_UNIT + " per KB) for tx to be accepted\n"
1347 "}\n"
1348 "\nExamples:\n"
1349 + HelpExampleCli("getmempoolinfo", "")
1350 + HelpExampleRpc("getmempoolinfo", "")
1353 return mempoolInfoToJSON();
1356 UniValue preciousblock(const JSONRPCRequest& request)
1358 if (request.fHelp || request.params.size() != 1)
1359 throw std::runtime_error(
1360 "preciousblock \"blockhash\"\n"
1361 "\nTreats a block as if it were received before others with the same work.\n"
1362 "\nA later preciousblock call can override the effect of an earlier one.\n"
1363 "\nThe effects of preciousblock are not retained across restarts.\n"
1364 "\nArguments:\n"
1365 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1366 "\nResult:\n"
1367 "\nExamples:\n"
1368 + HelpExampleCli("preciousblock", "\"blockhash\"")
1369 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1372 std::string strHash = request.params[0].get_str();
1373 uint256 hash(uint256S(strHash));
1374 CBlockIndex* pblockindex;
1377 LOCK(cs_main);
1378 if (mapBlockIndex.count(hash) == 0)
1379 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1381 pblockindex = mapBlockIndex[hash];
1384 CValidationState state;
1385 PreciousBlock(state, Params(), pblockindex);
1387 if (!state.IsValid()) {
1388 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1391 return NullUniValue;
1394 UniValue invalidateblock(const JSONRPCRequest& request)
1396 if (request.fHelp || request.params.size() != 1)
1397 throw std::runtime_error(
1398 "invalidateblock \"blockhash\"\n"
1399 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1400 "\nArguments:\n"
1401 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1402 "\nResult:\n"
1403 "\nExamples:\n"
1404 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1405 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1408 std::string strHash = request.params[0].get_str();
1409 uint256 hash(uint256S(strHash));
1410 CValidationState state;
1413 LOCK(cs_main);
1414 if (mapBlockIndex.count(hash) == 0)
1415 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1417 CBlockIndex* pblockindex = mapBlockIndex[hash];
1418 InvalidateBlock(state, Params(), pblockindex);
1421 if (state.IsValid()) {
1422 ActivateBestChain(state, Params());
1425 if (!state.IsValid()) {
1426 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1429 return NullUniValue;
1432 UniValue reconsiderblock(const JSONRPCRequest& request)
1434 if (request.fHelp || request.params.size() != 1)
1435 throw std::runtime_error(
1436 "reconsiderblock \"blockhash\"\n"
1437 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1438 "This can be used to undo the effects of invalidateblock.\n"
1439 "\nArguments:\n"
1440 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1441 "\nResult:\n"
1442 "\nExamples:\n"
1443 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1444 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1447 std::string strHash = request.params[0].get_str();
1448 uint256 hash(uint256S(strHash));
1451 LOCK(cs_main);
1452 if (mapBlockIndex.count(hash) == 0)
1453 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1455 CBlockIndex* pblockindex = mapBlockIndex[hash];
1456 ResetBlockFailureFlags(pblockindex);
1459 CValidationState state;
1460 ActivateBestChain(state, Params());
1462 if (!state.IsValid()) {
1463 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1466 return NullUniValue;
1469 UniValue getchaintxstats(const JSONRPCRequest& request)
1471 if (request.fHelp || request.params.size() > 2)
1472 throw std::runtime_error(
1473 "getchaintxstats ( nblocks blockhash )\n"
1474 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1475 "\nArguments:\n"
1476 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1477 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1478 "\nResult:\n"
1479 "{\n"
1480 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1481 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1482 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1483 "}\n"
1484 "\nExamples:\n"
1485 + HelpExampleCli("getchaintxstats", "")
1486 + HelpExampleRpc("getchaintxstats", "2016")
1489 const CBlockIndex* pindex;
1490 int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1492 if (!request.params[0].isNull()) {
1493 blockcount = request.params[0].get_int();
1496 bool havehash = !request.params[1].isNull();
1497 uint256 hash;
1498 if (havehash) {
1499 hash = uint256S(request.params[1].get_str());
1503 LOCK(cs_main);
1504 if (havehash) {
1505 auto it = mapBlockIndex.find(hash);
1506 if (it == mapBlockIndex.end()) {
1507 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1509 pindex = it->second;
1510 if (!chainActive.Contains(pindex)) {
1511 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1513 } else {
1514 pindex = chainActive.Tip();
1518 if (blockcount < 1 || blockcount >= pindex->nHeight) {
1519 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height");
1522 const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1523 int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1524 int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1526 UniValue ret(UniValue::VOBJ);
1527 ret.push_back(Pair("time", (int64_t)pindex->nTime));
1528 ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx));
1529 ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff));
1531 return ret;
1534 static const CRPCCommand commands[] =
1535 { // category name actor (function) okSafe argNames
1536 // --------------------- ------------------------ ----------------------- ------ ----------
1537 { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
1538 { "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} },
1539 { "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
1540 { "blockchain", "getblockcount", &getblockcount, true, {} },
1541 { "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} },
1542 { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
1543 { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
1544 { "blockchain", "getchaintips", &getchaintips, true, {} },
1545 { "blockchain", "getdifficulty", &getdifficulty, true, {} },
1546 { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
1547 { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
1548 { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
1549 { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
1550 { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
1551 { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
1552 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
1553 { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
1554 { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },
1556 { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
1558 /* Not shown in help */
1559 { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
1560 { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
1561 { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
1562 { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
1563 { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
1566 void RegisterBlockchainRPCCommands(CRPCTable &t)
1568 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1569 t.appendCommand(commands[vcidx].name, &commands[vcidx]);