RPC: gettxout: Slightly improve doc and tests
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blob10eb7f13a3abf8bace4c1e46e54ff088e9f89006
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 == NULL)
53 if (chainActive.Tip() == NULL)
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);
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.size() > 0)
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.size() > 1)
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.size() > 1)
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.size() > 0)
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.size() > 1)
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.size() > 1)
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.size() > 1)
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.size() > 1) {
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 " \"version\" : n, (numeric) The version\n"
967 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
968 "}\n"
970 "\nExamples:\n"
971 "\nGet unspent transactions\n"
972 + HelpExampleCli("listunspent", "") +
973 "\nView the details\n"
974 + HelpExampleCli("gettxout", "\"txid\" 1") +
975 "\nAs a json rpc call\n"
976 + HelpExampleRpc("gettxout", "\"txid\", 1")
979 LOCK(cs_main);
981 UniValue ret(UniValue::VOBJ);
983 std::string strHash = request.params[0].get_str();
984 uint256 hash(uint256S(strHash));
985 int n = request.params[1].get_int();
986 COutPoint out(hash, n);
987 bool fMempool = true;
988 if (request.params.size() > 2)
989 fMempool = request.params[2].get_bool();
991 Coin coin;
992 if (fMempool) {
993 LOCK(mempool.cs);
994 CCoinsViewMemPool view(pcoinsTip, mempool);
995 if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
996 return NullUniValue;
998 } else {
999 if (!pcoinsTip->GetCoin(out, coin)) {
1000 return NullUniValue;
1004 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
1005 CBlockIndex *pindex = it->second;
1006 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
1007 if (coin.nHeight == MEMPOOL_HEIGHT) {
1008 ret.push_back(Pair("confirmations", 0));
1009 } else {
1010 ret.push_back(Pair("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1)));
1012 ret.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
1013 UniValue o(UniValue::VOBJ);
1014 ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
1015 ret.push_back(Pair("scriptPubKey", o));
1016 ret.push_back(Pair("coinbase", (bool)coin.fCoinBase));
1018 return ret;
1021 UniValue verifychain(const JSONRPCRequest& request)
1023 int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
1024 int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1025 if (request.fHelp || request.params.size() > 2)
1026 throw std::runtime_error(
1027 "verifychain ( checklevel nblocks )\n"
1028 "\nVerifies blockchain database.\n"
1029 "\nArguments:\n"
1030 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1031 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1032 "\nResult:\n"
1033 "true|false (boolean) Verified or not\n"
1034 "\nExamples:\n"
1035 + HelpExampleCli("verifychain", "")
1036 + HelpExampleRpc("verifychain", "")
1039 LOCK(cs_main);
1041 if (request.params.size() > 0)
1042 nCheckLevel = request.params[0].get_int();
1043 if (request.params.size() > 1)
1044 nCheckDepth = request.params[1].get_int();
1046 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
1049 /** Implementation of IsSuperMajority with better feedback */
1050 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1052 UniValue rv(UniValue::VOBJ);
1053 bool activated = false;
1054 switch(version)
1056 case 2:
1057 activated = pindex->nHeight >= consensusParams.BIP34Height;
1058 break;
1059 case 3:
1060 activated = pindex->nHeight >= consensusParams.BIP66Height;
1061 break;
1062 case 4:
1063 activated = pindex->nHeight >= consensusParams.BIP65Height;
1064 break;
1066 rv.push_back(Pair("status", activated));
1067 return rv;
1070 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1072 UniValue rv(UniValue::VOBJ);
1073 rv.push_back(Pair("id", name));
1074 rv.push_back(Pair("version", version));
1075 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1076 return rv;
1079 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1081 UniValue rv(UniValue::VOBJ);
1082 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1083 switch (thresholdState) {
1084 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1085 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1086 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1087 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1088 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1090 if (THRESHOLD_STARTED == thresholdState)
1092 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1094 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1095 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1096 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1097 if (THRESHOLD_STARTED == thresholdState)
1099 UniValue statsUV(UniValue::VOBJ);
1100 BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);
1101 statsUV.push_back(Pair("period", statsStruct.period));
1102 statsUV.push_back(Pair("threshold", statsStruct.threshold));
1103 statsUV.push_back(Pair("elapsed", statsStruct.elapsed));
1104 statsUV.push_back(Pair("count", statsStruct.count));
1105 statsUV.push_back(Pair("possible", statsStruct.possible));
1106 rv.push_back(Pair("statistics", statsUV));
1108 return rv;
1111 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1113 // Deployments with timeout value of 0 are hidden.
1114 // A timeout value of 0 guarantees a softfork will never be activated.
1115 // This is used when softfork codes are merged without specifying the deployment schedule.
1116 if (consensusParams.vDeployments[id].nTimeout > 0)
1117 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
1120 UniValue getblockchaininfo(const JSONRPCRequest& request)
1122 if (request.fHelp || request.params.size() != 0)
1123 throw std::runtime_error(
1124 "getblockchaininfo\n"
1125 "Returns an object containing various state info regarding blockchain processing.\n"
1126 "\nResult:\n"
1127 "{\n"
1128 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1129 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1130 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1131 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1132 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1133 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1134 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1135 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1136 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1137 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1138 " \"softforks\": [ (array) status of softforks in progress\n"
1139 " {\n"
1140 " \"id\": \"xxxx\", (string) name of softfork\n"
1141 " \"version\": xx, (numeric) block version\n"
1142 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1143 " \"status\": xx, (boolean) true if threshold reached\n"
1144 " },\n"
1145 " }, ...\n"
1146 " ],\n"
1147 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1148 " \"xxxx\" : { (string) name of the softfork\n"
1149 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1150 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1151 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1152 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1153 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1154 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1155 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1156 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1157 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1158 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1159 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1160 " }\n"
1161 " }\n"
1162 " }\n"
1163 "}\n"
1164 "\nExamples:\n"
1165 + HelpExampleCli("getblockchaininfo", "")
1166 + HelpExampleRpc("getblockchaininfo", "")
1169 LOCK(cs_main);
1171 UniValue obj(UniValue::VOBJ);
1172 obj.push_back(Pair("chain", Params().NetworkIDString()));
1173 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1174 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1175 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1176 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1177 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1178 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1179 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1180 obj.push_back(Pair("pruned", fPruneMode));
1182 const Consensus::Params& consensusParams = Params().GetConsensus();
1183 CBlockIndex* tip = chainActive.Tip();
1184 UniValue softforks(UniValue::VARR);
1185 UniValue bip9_softforks(UniValue::VOBJ);
1186 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1187 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1188 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1189 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
1190 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
1191 obj.push_back(Pair("softforks", softforks));
1192 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1194 if (fPruneMode)
1196 CBlockIndex *block = chainActive.Tip();
1197 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
1198 block = block->pprev;
1200 obj.push_back(Pair("pruneheight", block->nHeight));
1202 return obj;
1205 /** Comparison function for sorting the getchaintips heads. */
1206 struct CompareBlocksByHeight
1208 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1210 /* Make sure that unequal blocks with the same height do not compare
1211 equal. Use the pointers themselves to make a distinction. */
1213 if (a->nHeight != b->nHeight)
1214 return (a->nHeight > b->nHeight);
1216 return a < b;
1220 UniValue getchaintips(const JSONRPCRequest& request)
1222 if (request.fHelp || request.params.size() != 0)
1223 throw std::runtime_error(
1224 "getchaintips\n"
1225 "Return information about all known tips in the block tree,"
1226 " including the main chain as well as orphaned branches.\n"
1227 "\nResult:\n"
1228 "[\n"
1229 " {\n"
1230 " \"height\": xxxx, (numeric) height of the chain tip\n"
1231 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1232 " \"branchlen\": 0 (numeric) zero for main chain\n"
1233 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1234 " },\n"
1235 " {\n"
1236 " \"height\": xxxx,\n"
1237 " \"hash\": \"xxxx\",\n"
1238 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1239 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1240 " }\n"
1241 "]\n"
1242 "Possible values for status:\n"
1243 "1. \"invalid\" This branch contains at least one invalid block\n"
1244 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1245 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1246 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1247 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1248 "\nExamples:\n"
1249 + HelpExampleCli("getchaintips", "")
1250 + HelpExampleRpc("getchaintips", "")
1253 LOCK(cs_main);
1256 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1257 * Algorithm:
1258 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1259 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1260 * - add chainActive.Tip()
1262 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1263 std::set<const CBlockIndex*> setOrphans;
1264 std::set<const CBlockIndex*> setPrevs;
1266 for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
1268 if (!chainActive.Contains(item.second)) {
1269 setOrphans.insert(item.second);
1270 setPrevs.insert(item.second->pprev);
1274 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1276 if (setPrevs.erase(*it) == 0) {
1277 setTips.insert(*it);
1281 // Always report the currently active tip.
1282 setTips.insert(chainActive.Tip());
1284 /* Construct the output array. */
1285 UniValue res(UniValue::VARR);
1286 for (const CBlockIndex* block : setTips)
1288 UniValue obj(UniValue::VOBJ);
1289 obj.push_back(Pair("height", block->nHeight));
1290 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1292 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1293 obj.push_back(Pair("branchlen", branchLen));
1295 std::string status;
1296 if (chainActive.Contains(block)) {
1297 // This block is part of the currently active chain.
1298 status = "active";
1299 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1300 // This block or one of its ancestors is invalid.
1301 status = "invalid";
1302 } else if (block->nChainTx == 0) {
1303 // This block cannot be connected because full block data for it or one of its parents is missing.
1304 status = "headers-only";
1305 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1306 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1307 status = "valid-fork";
1308 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1309 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1310 status = "valid-headers";
1311 } else {
1312 // No clue.
1313 status = "unknown";
1315 obj.push_back(Pair("status", status));
1317 res.push_back(obj);
1320 return res;
1323 UniValue mempoolInfoToJSON()
1325 UniValue ret(UniValue::VOBJ);
1326 ret.push_back(Pair("size", (int64_t) mempool.size()));
1327 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1328 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1329 size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1330 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1331 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1333 return ret;
1336 UniValue getmempoolinfo(const JSONRPCRequest& request)
1338 if (request.fHelp || request.params.size() != 0)
1339 throw std::runtime_error(
1340 "getmempoolinfo\n"
1341 "\nReturns details on the active state of the TX memory pool.\n"
1342 "\nResult:\n"
1343 "{\n"
1344 " \"size\": xxxxx, (numeric) Current tx count\n"
1345 " \"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"
1346 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1347 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1348 " \"mempoolminfee\": xxxxx (numeric) Minimum feerate (" + CURRENCY_UNIT + " per KB) for tx to be accepted\n"
1349 "}\n"
1350 "\nExamples:\n"
1351 + HelpExampleCli("getmempoolinfo", "")
1352 + HelpExampleRpc("getmempoolinfo", "")
1355 return mempoolInfoToJSON();
1358 UniValue preciousblock(const JSONRPCRequest& request)
1360 if (request.fHelp || request.params.size() != 1)
1361 throw std::runtime_error(
1362 "preciousblock \"blockhash\"\n"
1363 "\nTreats a block as if it were received before others with the same work.\n"
1364 "\nA later preciousblock call can override the effect of an earlier one.\n"
1365 "\nThe effects of preciousblock are not retained across restarts.\n"
1366 "\nArguments:\n"
1367 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1368 "\nResult:\n"
1369 "\nExamples:\n"
1370 + HelpExampleCli("preciousblock", "\"blockhash\"")
1371 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1374 std::string strHash = request.params[0].get_str();
1375 uint256 hash(uint256S(strHash));
1376 CBlockIndex* pblockindex;
1379 LOCK(cs_main);
1380 if (mapBlockIndex.count(hash) == 0)
1381 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1383 pblockindex = mapBlockIndex[hash];
1386 CValidationState state;
1387 PreciousBlock(state, Params(), pblockindex);
1389 if (!state.IsValid()) {
1390 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1393 return NullUniValue;
1396 UniValue invalidateblock(const JSONRPCRequest& request)
1398 if (request.fHelp || request.params.size() != 1)
1399 throw std::runtime_error(
1400 "invalidateblock \"blockhash\"\n"
1401 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1402 "\nArguments:\n"
1403 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1404 "\nResult:\n"
1405 "\nExamples:\n"
1406 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1407 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1410 std::string strHash = request.params[0].get_str();
1411 uint256 hash(uint256S(strHash));
1412 CValidationState state;
1415 LOCK(cs_main);
1416 if (mapBlockIndex.count(hash) == 0)
1417 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1419 CBlockIndex* pblockindex = mapBlockIndex[hash];
1420 InvalidateBlock(state, Params(), pblockindex);
1423 if (state.IsValid()) {
1424 ActivateBestChain(state, Params());
1427 if (!state.IsValid()) {
1428 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1431 return NullUniValue;
1434 UniValue reconsiderblock(const JSONRPCRequest& request)
1436 if (request.fHelp || request.params.size() != 1)
1437 throw std::runtime_error(
1438 "reconsiderblock \"blockhash\"\n"
1439 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1440 "This can be used to undo the effects of invalidateblock.\n"
1441 "\nArguments:\n"
1442 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1443 "\nResult:\n"
1444 "\nExamples:\n"
1445 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1446 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1449 std::string strHash = request.params[0].get_str();
1450 uint256 hash(uint256S(strHash));
1453 LOCK(cs_main);
1454 if (mapBlockIndex.count(hash) == 0)
1455 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1457 CBlockIndex* pblockindex = mapBlockIndex[hash];
1458 ResetBlockFailureFlags(pblockindex);
1461 CValidationState state;
1462 ActivateBestChain(state, Params());
1464 if (!state.IsValid()) {
1465 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1468 return NullUniValue;
1471 UniValue getchaintxstats(const JSONRPCRequest& request)
1473 if (request.fHelp || request.params.size() > 2)
1474 throw std::runtime_error(
1475 "getchaintxstats ( nblocks blockhash )\n"
1476 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1477 "\nArguments:\n"
1478 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1479 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1480 "\nResult:\n"
1481 "{\n"
1482 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1483 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1484 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1485 "}\n"
1486 "\nExamples:\n"
1487 + HelpExampleCli("getchaintxstats", "")
1488 + HelpExampleRpc("getchaintxstats", "2016")
1491 const CBlockIndex* pindex;
1492 int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1494 if (request.params.size() > 0 && !request.params[0].isNull()) {
1495 blockcount = request.params[0].get_int();
1498 bool havehash = request.params.size() > 1 && !request.params[1].isNull();
1499 uint256 hash;
1500 if (havehash) {
1501 hash = uint256S(request.params[1].get_str());
1505 LOCK(cs_main);
1506 if (havehash) {
1507 auto it = mapBlockIndex.find(hash);
1508 if (it == mapBlockIndex.end()) {
1509 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1511 pindex = it->second;
1512 if (!chainActive.Contains(pindex)) {
1513 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1515 } else {
1516 pindex = chainActive.Tip();
1520 if (blockcount < 1 || blockcount >= pindex->nHeight) {
1521 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height");
1524 const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1525 int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1526 int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1528 UniValue ret(UniValue::VOBJ);
1529 ret.push_back(Pair("time", (int64_t)pindex->nTime));
1530 ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx));
1531 ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff));
1533 return ret;
1536 static const CRPCCommand commands[] =
1537 { // category name actor (function) okSafe argNames
1538 // --------------------- ------------------------ ----------------------- ------ ----------
1539 { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
1540 { "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} },
1541 { "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
1542 { "blockchain", "getblockcount", &getblockcount, true, {} },
1543 { "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} },
1544 { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
1545 { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
1546 { "blockchain", "getchaintips", &getchaintips, true, {} },
1547 { "blockchain", "getdifficulty", &getdifficulty, true, {} },
1548 { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
1549 { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
1550 { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
1551 { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
1552 { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
1553 { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
1554 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
1555 { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
1556 { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },
1558 { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
1560 /* Not shown in help */
1561 { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
1562 { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
1563 { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
1564 { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
1565 { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
1568 void RegisterBlockchainRPCCommands(CRPCTable &t)
1570 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1571 t.appendCommand(commands[vcidx].name, &commands[vcidx]);