[qa] TestNode: Add wait_until_stopped helper method
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blobef61e5a55d68ce854ae90007aac3e2c16956c14c
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. Default: true."
950 " Note that an unspent output that is spent in the mempool won't appear.\n"
951 "\nResult:\n"
952 "{\n"
953 " \"bestblock\" : \"hash\", (string) the block hash\n"
954 " \"confirmations\" : n, (numeric) The number of confirmations\n"
955 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
956 " \"scriptPubKey\" : { (json object)\n"
957 " \"asm\" : \"code\", (string) \n"
958 " \"hex\" : \"hex\", (string) \n"
959 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
960 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
961 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
962 " \"address\" (string) bitcoin address\n"
963 " ,...\n"
964 " ]\n"
965 " },\n"
966 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
967 "}\n"
969 "\nExamples:\n"
970 "\nGet unspent transactions\n"
971 + HelpExampleCli("listunspent", "") +
972 "\nView the details\n"
973 + HelpExampleCli("gettxout", "\"txid\" 1") +
974 "\nAs a json rpc call\n"
975 + HelpExampleRpc("gettxout", "\"txid\", 1")
978 LOCK(cs_main);
980 UniValue ret(UniValue::VOBJ);
982 std::string strHash = request.params[0].get_str();
983 uint256 hash(uint256S(strHash));
984 int n = request.params[1].get_int();
985 COutPoint out(hash, n);
986 bool fMempool = true;
987 if (!request.params[2].isNull())
988 fMempool = request.params[2].get_bool();
990 Coin coin;
991 if (fMempool) {
992 LOCK(mempool.cs);
993 CCoinsViewMemPool view(pcoinsTip, mempool);
994 if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
995 return NullUniValue;
997 } else {
998 if (!pcoinsTip->GetCoin(out, coin)) {
999 return NullUniValue;
1003 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
1004 CBlockIndex *pindex = it->second;
1005 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
1006 if (coin.nHeight == MEMPOOL_HEIGHT) {
1007 ret.push_back(Pair("confirmations", 0));
1008 } else {
1009 ret.push_back(Pair("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1)));
1011 ret.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
1012 UniValue o(UniValue::VOBJ);
1013 ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
1014 ret.push_back(Pair("scriptPubKey", o));
1015 ret.push_back(Pair("coinbase", (bool)coin.fCoinBase));
1017 return ret;
1020 UniValue verifychain(const JSONRPCRequest& request)
1022 int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL);
1023 int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1024 if (request.fHelp || request.params.size() > 2)
1025 throw std::runtime_error(
1026 "verifychain ( checklevel nblocks )\n"
1027 "\nVerifies blockchain database.\n"
1028 "\nArguments:\n"
1029 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1030 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1031 "\nResult:\n"
1032 "true|false (boolean) Verified or not\n"
1033 "\nExamples:\n"
1034 + HelpExampleCli("verifychain", "")
1035 + HelpExampleRpc("verifychain", "")
1038 LOCK(cs_main);
1040 if (!request.params[0].isNull())
1041 nCheckLevel = request.params[0].get_int();
1042 if (!request.params[1].isNull())
1043 nCheckDepth = request.params[1].get_int();
1045 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
1048 /** Implementation of IsSuperMajority with better feedback */
1049 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1051 UniValue rv(UniValue::VOBJ);
1052 bool activated = false;
1053 switch(version)
1055 case 2:
1056 activated = pindex->nHeight >= consensusParams.BIP34Height;
1057 break;
1058 case 3:
1059 activated = pindex->nHeight >= consensusParams.BIP66Height;
1060 break;
1061 case 4:
1062 activated = pindex->nHeight >= consensusParams.BIP65Height;
1063 break;
1065 rv.push_back(Pair("status", activated));
1066 return rv;
1069 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1071 UniValue rv(UniValue::VOBJ);
1072 rv.push_back(Pair("id", name));
1073 rv.push_back(Pair("version", version));
1074 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1075 return rv;
1078 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1080 UniValue rv(UniValue::VOBJ);
1081 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1082 switch (thresholdState) {
1083 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1084 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1085 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1086 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1087 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1089 if (THRESHOLD_STARTED == thresholdState)
1091 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1093 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1094 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1095 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1096 if (THRESHOLD_STARTED == thresholdState)
1098 UniValue statsUV(UniValue::VOBJ);
1099 BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);
1100 statsUV.push_back(Pair("period", statsStruct.period));
1101 statsUV.push_back(Pair("threshold", statsStruct.threshold));
1102 statsUV.push_back(Pair("elapsed", statsStruct.elapsed));
1103 statsUV.push_back(Pair("count", statsStruct.count));
1104 statsUV.push_back(Pair("possible", statsStruct.possible));
1105 rv.push_back(Pair("statistics", statsUV));
1107 return rv;
1110 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1112 // Deployments with timeout value of 0 are hidden.
1113 // A timeout value of 0 guarantees a softfork will never be activated.
1114 // This is used when softfork codes are merged without specifying the deployment schedule.
1115 if (consensusParams.vDeployments[id].nTimeout > 0)
1116 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
1119 UniValue getblockchaininfo(const JSONRPCRequest& request)
1121 if (request.fHelp || request.params.size() != 0)
1122 throw std::runtime_error(
1123 "getblockchaininfo\n"
1124 "Returns an object containing various state info regarding blockchain processing.\n"
1125 "\nResult:\n"
1126 "{\n"
1127 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1128 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1129 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1130 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1131 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1132 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1133 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1134 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1135 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1136 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1137 " \"softforks\": [ (array) status of softforks in progress\n"
1138 " {\n"
1139 " \"id\": \"xxxx\", (string) name of softfork\n"
1140 " \"version\": xx, (numeric) block version\n"
1141 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1142 " \"status\": xx, (boolean) true if threshold reached\n"
1143 " },\n"
1144 " }, ...\n"
1145 " ],\n"
1146 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1147 " \"xxxx\" : { (string) name of the softfork\n"
1148 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1149 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1150 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1151 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1152 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1153 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1154 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1155 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1156 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1157 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1158 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1159 " }\n"
1160 " }\n"
1161 " }\n"
1162 "}\n"
1163 "\nExamples:\n"
1164 + HelpExampleCli("getblockchaininfo", "")
1165 + HelpExampleRpc("getblockchaininfo", "")
1168 LOCK(cs_main);
1170 UniValue obj(UniValue::VOBJ);
1171 obj.push_back(Pair("chain", Params().NetworkIDString()));
1172 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1173 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1174 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1175 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1176 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1177 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1178 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1179 obj.push_back(Pair("pruned", fPruneMode));
1181 const Consensus::Params& consensusParams = Params().GetConsensus();
1182 CBlockIndex* tip = chainActive.Tip();
1183 UniValue softforks(UniValue::VARR);
1184 UniValue bip9_softforks(UniValue::VOBJ);
1185 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1186 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1187 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1188 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
1189 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
1190 obj.push_back(Pair("softforks", softforks));
1191 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1193 if (fPruneMode)
1195 CBlockIndex *block = chainActive.Tip();
1196 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
1197 block = block->pprev;
1199 obj.push_back(Pair("pruneheight", block->nHeight));
1201 return obj;
1204 /** Comparison function for sorting the getchaintips heads. */
1205 struct CompareBlocksByHeight
1207 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1209 /* Make sure that unequal blocks with the same height do not compare
1210 equal. Use the pointers themselves to make a distinction. */
1212 if (a->nHeight != b->nHeight)
1213 return (a->nHeight > b->nHeight);
1215 return a < b;
1219 UniValue getchaintips(const JSONRPCRequest& request)
1221 if (request.fHelp || request.params.size() != 0)
1222 throw std::runtime_error(
1223 "getchaintips\n"
1224 "Return information about all known tips in the block tree,"
1225 " including the main chain as well as orphaned branches.\n"
1226 "\nResult:\n"
1227 "[\n"
1228 " {\n"
1229 " \"height\": xxxx, (numeric) height of the chain tip\n"
1230 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1231 " \"branchlen\": 0 (numeric) zero for main chain\n"
1232 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1233 " },\n"
1234 " {\n"
1235 " \"height\": xxxx,\n"
1236 " \"hash\": \"xxxx\",\n"
1237 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1238 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1239 " }\n"
1240 "]\n"
1241 "Possible values for status:\n"
1242 "1. \"invalid\" This branch contains at least one invalid block\n"
1243 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1244 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1245 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1246 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1247 "\nExamples:\n"
1248 + HelpExampleCli("getchaintips", "")
1249 + HelpExampleRpc("getchaintips", "")
1252 LOCK(cs_main);
1255 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1256 * Algorithm:
1257 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1258 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1259 * - add chainActive.Tip()
1261 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1262 std::set<const CBlockIndex*> setOrphans;
1263 std::set<const CBlockIndex*> setPrevs;
1265 for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
1267 if (!chainActive.Contains(item.second)) {
1268 setOrphans.insert(item.second);
1269 setPrevs.insert(item.second->pprev);
1273 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1275 if (setPrevs.erase(*it) == 0) {
1276 setTips.insert(*it);
1280 // Always report the currently active tip.
1281 setTips.insert(chainActive.Tip());
1283 /* Construct the output array. */
1284 UniValue res(UniValue::VARR);
1285 for (const CBlockIndex* block : setTips)
1287 UniValue obj(UniValue::VOBJ);
1288 obj.push_back(Pair("height", block->nHeight));
1289 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1291 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1292 obj.push_back(Pair("branchlen", branchLen));
1294 std::string status;
1295 if (chainActive.Contains(block)) {
1296 // This block is part of the currently active chain.
1297 status = "active";
1298 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1299 // This block or one of its ancestors is invalid.
1300 status = "invalid";
1301 } else if (block->nChainTx == 0) {
1302 // This block cannot be connected because full block data for it or one of its parents is missing.
1303 status = "headers-only";
1304 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1305 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1306 status = "valid-fork";
1307 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1308 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1309 status = "valid-headers";
1310 } else {
1311 // No clue.
1312 status = "unknown";
1314 obj.push_back(Pair("status", status));
1316 res.push_back(obj);
1319 return res;
1322 UniValue mempoolInfoToJSON()
1324 UniValue ret(UniValue::VOBJ);
1325 ret.push_back(Pair("size", (int64_t) mempool.size()));
1326 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1327 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1328 size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1329 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1330 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1332 return ret;
1335 UniValue getmempoolinfo(const JSONRPCRequest& request)
1337 if (request.fHelp || request.params.size() != 0)
1338 throw std::runtime_error(
1339 "getmempoolinfo\n"
1340 "\nReturns details on the active state of the TX memory pool.\n"
1341 "\nResult:\n"
1342 "{\n"
1343 " \"size\": xxxxx, (numeric) Current tx count\n"
1344 " \"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"
1345 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1346 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1347 " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n"
1348 "}\n"
1349 "\nExamples:\n"
1350 + HelpExampleCli("getmempoolinfo", "")
1351 + HelpExampleRpc("getmempoolinfo", "")
1354 return mempoolInfoToJSON();
1357 UniValue preciousblock(const JSONRPCRequest& request)
1359 if (request.fHelp || request.params.size() != 1)
1360 throw std::runtime_error(
1361 "preciousblock \"blockhash\"\n"
1362 "\nTreats a block as if it were received before others with the same work.\n"
1363 "\nA later preciousblock call can override the effect of an earlier one.\n"
1364 "\nThe effects of preciousblock are not retained across restarts.\n"
1365 "\nArguments:\n"
1366 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1367 "\nResult:\n"
1368 "\nExamples:\n"
1369 + HelpExampleCli("preciousblock", "\"blockhash\"")
1370 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1373 std::string strHash = request.params[0].get_str();
1374 uint256 hash(uint256S(strHash));
1375 CBlockIndex* pblockindex;
1378 LOCK(cs_main);
1379 if (mapBlockIndex.count(hash) == 0)
1380 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1382 pblockindex = mapBlockIndex[hash];
1385 CValidationState state;
1386 PreciousBlock(state, Params(), pblockindex);
1388 if (!state.IsValid()) {
1389 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1392 return NullUniValue;
1395 UniValue invalidateblock(const JSONRPCRequest& request)
1397 if (request.fHelp || request.params.size() != 1)
1398 throw std::runtime_error(
1399 "invalidateblock \"blockhash\"\n"
1400 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1401 "\nArguments:\n"
1402 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1403 "\nResult:\n"
1404 "\nExamples:\n"
1405 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1406 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1409 std::string strHash = request.params[0].get_str();
1410 uint256 hash(uint256S(strHash));
1411 CValidationState state;
1414 LOCK(cs_main);
1415 if (mapBlockIndex.count(hash) == 0)
1416 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1418 CBlockIndex* pblockindex = mapBlockIndex[hash];
1419 InvalidateBlock(state, Params(), pblockindex);
1422 if (state.IsValid()) {
1423 ActivateBestChain(state, Params());
1426 if (!state.IsValid()) {
1427 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1430 return NullUniValue;
1433 UniValue reconsiderblock(const JSONRPCRequest& request)
1435 if (request.fHelp || request.params.size() != 1)
1436 throw std::runtime_error(
1437 "reconsiderblock \"blockhash\"\n"
1438 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1439 "This can be used to undo the effects of invalidateblock.\n"
1440 "\nArguments:\n"
1441 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1442 "\nResult:\n"
1443 "\nExamples:\n"
1444 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1445 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1448 std::string strHash = request.params[0].get_str();
1449 uint256 hash(uint256S(strHash));
1452 LOCK(cs_main);
1453 if (mapBlockIndex.count(hash) == 0)
1454 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1456 CBlockIndex* pblockindex = mapBlockIndex[hash];
1457 ResetBlockFailureFlags(pblockindex);
1460 CValidationState state;
1461 ActivateBestChain(state, Params());
1463 if (!state.IsValid()) {
1464 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1467 return NullUniValue;
1470 UniValue getchaintxstats(const JSONRPCRequest& request)
1472 if (request.fHelp || request.params.size() > 2)
1473 throw std::runtime_error(
1474 "getchaintxstats ( nblocks blockhash )\n"
1475 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1476 "\nArguments:\n"
1477 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1478 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1479 "\nResult:\n"
1480 "{\n"
1481 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1482 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1483 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1484 "}\n"
1485 "\nExamples:\n"
1486 + HelpExampleCli("getchaintxstats", "")
1487 + HelpExampleRpc("getchaintxstats", "2016")
1490 const CBlockIndex* pindex;
1491 int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1493 if (!request.params[0].isNull()) {
1494 blockcount = request.params[0].get_int();
1497 bool havehash = !request.params[1].isNull();
1498 uint256 hash;
1499 if (havehash) {
1500 hash = uint256S(request.params[1].get_str());
1504 LOCK(cs_main);
1505 if (havehash) {
1506 auto it = mapBlockIndex.find(hash);
1507 if (it == mapBlockIndex.end()) {
1508 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1510 pindex = it->second;
1511 if (!chainActive.Contains(pindex)) {
1512 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1514 } else {
1515 pindex = chainActive.Tip();
1519 if (blockcount < 1 || blockcount >= pindex->nHeight) {
1520 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height");
1523 const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1524 int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1525 int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1527 UniValue ret(UniValue::VOBJ);
1528 ret.push_back(Pair("time", (int64_t)pindex->nTime));
1529 ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx));
1530 ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff));
1532 return ret;
1535 static const CRPCCommand commands[] =
1536 { // category name actor (function) argNames
1537 // --------------------- ------------------------ ----------------------- ----------
1538 { "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
1539 { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
1540 { "blockchain", "getbestblockhash", &getbestblockhash, {} },
1541 { "blockchain", "getblockcount", &getblockcount, {} },
1542 { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
1543 { "blockchain", "getblockhash", &getblockhash, {"height"} },
1544 { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
1545 { "blockchain", "getchaintips", &getchaintips, {} },
1546 { "blockchain", "getdifficulty", &getdifficulty, {} },
1547 { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
1548 { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
1549 { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
1550 { "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
1551 { "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
1552 { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
1553 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
1554 { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
1555 { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
1557 { "blockchain", "preciousblock", &preciousblock, {"blockhash"} },
1559 /* Not shown in help */
1560 { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
1561 { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
1562 { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
1563 { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
1564 { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
1567 void RegisterBlockchainRPCCommands(CRPCTable &t)
1569 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1570 t.appendCommand(commands[vcidx].name, &commands[vcidx]);