Refactor GetUTXOStats in preparation for per-COutPoint iteration
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blob3e9b1a1b12c9213a1e26697122e1eac954b2a45e
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 "txmempool.h"
23 #include "util.h"
24 #include "utilstrencodings.h"
25 #include "hash.h"
27 #include <stdint.h>
29 #include <univalue.h>
31 #include <boost/thread/thread.hpp> // boost::thread::interrupt
33 #include <mutex>
34 #include <condition_variable>
36 struct CUpdatedBlock
38 uint256 hash;
39 int height;
42 static std::mutex cs_blockchange;
43 static std::condition_variable cond_blockchange;
44 static CUpdatedBlock latestblock;
46 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
48 double GetDifficulty(const CBlockIndex* blockindex)
50 if (blockindex == NULL)
52 if (chainActive.Tip() == NULL)
53 return 1.0;
54 else
55 blockindex = chainActive.Tip();
58 int nShift = (blockindex->nBits >> 24) & 0xff;
60 double dDiff =
61 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
63 while (nShift < 29)
65 dDiff *= 256.0;
66 nShift++;
68 while (nShift > 29)
70 dDiff /= 256.0;
71 nShift--;
74 return dDiff;
77 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
79 UniValue result(UniValue::VOBJ);
80 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
81 int confirmations = -1;
82 // Only report confirmations if the block is on the main chain
83 if (chainActive.Contains(blockindex))
84 confirmations = chainActive.Height() - blockindex->nHeight + 1;
85 result.push_back(Pair("confirmations", confirmations));
86 result.push_back(Pair("height", blockindex->nHeight));
87 result.push_back(Pair("version", blockindex->nVersion));
88 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
89 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
90 result.push_back(Pair("time", (int64_t)blockindex->nTime));
91 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
92 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
93 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
94 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
95 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
97 if (blockindex->pprev)
98 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
99 CBlockIndex *pnext = chainActive.Next(blockindex);
100 if (pnext)
101 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
102 return result;
105 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
107 UniValue result(UniValue::VOBJ);
108 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
109 int confirmations = -1;
110 // Only report confirmations if the block is on the main chain
111 if (chainActive.Contains(blockindex))
112 confirmations = chainActive.Height() - blockindex->nHeight + 1;
113 result.push_back(Pair("confirmations", confirmations));
114 result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)));
115 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
116 result.push_back(Pair("weight", (int)::GetBlockWeight(block)));
117 result.push_back(Pair("height", blockindex->nHeight));
118 result.push_back(Pair("version", block.nVersion));
119 result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion)));
120 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
121 UniValue txs(UniValue::VARR);
122 for(const auto& tx : block.vtx)
124 if(txDetails)
126 UniValue objTx(UniValue::VOBJ);
127 TxToUniv(*tx, uint256(), objTx);
128 txs.push_back(objTx);
130 else
131 txs.push_back(tx->GetHash().GetHex());
133 result.push_back(Pair("tx", txs));
134 result.push_back(Pair("time", block.GetBlockTime()));
135 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
136 result.push_back(Pair("nonce", (uint64_t)block.nNonce));
137 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
138 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
139 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
141 if (blockindex->pprev)
142 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
143 CBlockIndex *pnext = chainActive.Next(blockindex);
144 if (pnext)
145 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
146 return result;
149 UniValue getblockcount(const JSONRPCRequest& request)
151 if (request.fHelp || request.params.size() != 0)
152 throw std::runtime_error(
153 "getblockcount\n"
154 "\nReturns the number of blocks in the longest blockchain.\n"
155 "\nResult:\n"
156 "n (numeric) The current block count\n"
157 "\nExamples:\n"
158 + HelpExampleCli("getblockcount", "")
159 + HelpExampleRpc("getblockcount", "")
162 LOCK(cs_main);
163 return chainActive.Height();
166 UniValue getbestblockhash(const JSONRPCRequest& request)
168 if (request.fHelp || request.params.size() != 0)
169 throw std::runtime_error(
170 "getbestblockhash\n"
171 "\nReturns the hash of the best (tip) block in the longest blockchain.\n"
172 "\nResult:\n"
173 "\"hex\" (string) the block hash hex encoded\n"
174 "\nExamples:\n"
175 + HelpExampleCli("getbestblockhash", "")
176 + HelpExampleRpc("getbestblockhash", "")
179 LOCK(cs_main);
180 return chainActive.Tip()->GetBlockHash().GetHex();
183 void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex)
185 if(pindex) {
186 std::lock_guard<std::mutex> lock(cs_blockchange);
187 latestblock.hash = pindex->GetBlockHash();
188 latestblock.height = pindex->nHeight;
190 cond_blockchange.notify_all();
193 UniValue waitfornewblock(const JSONRPCRequest& request)
195 if (request.fHelp || request.params.size() > 1)
196 throw std::runtime_error(
197 "waitfornewblock (timeout)\n"
198 "\nWaits for a specific new block and returns useful info about it.\n"
199 "\nReturns the current block on timeout or exit.\n"
200 "\nArguments:\n"
201 "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
202 "\nResult:\n"
203 "{ (json object)\n"
204 " \"hash\" : { (string) The blockhash\n"
205 " \"height\" : { (int) Block height\n"
206 "}\n"
207 "\nExamples:\n"
208 + HelpExampleCli("waitfornewblock", "1000")
209 + HelpExampleRpc("waitfornewblock", "1000")
211 int timeout = 0;
212 if (request.params.size() > 0)
213 timeout = request.params[0].get_int();
215 CUpdatedBlock block;
217 std::unique_lock<std::mutex> lock(cs_blockchange);
218 block = latestblock;
219 if(timeout)
220 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
221 else
222 cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
223 block = latestblock;
225 UniValue ret(UniValue::VOBJ);
226 ret.push_back(Pair("hash", block.hash.GetHex()));
227 ret.push_back(Pair("height", block.height));
228 return ret;
231 UniValue waitforblock(const JSONRPCRequest& request)
233 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
234 throw std::runtime_error(
235 "waitforblock <blockhash> (timeout)\n"
236 "\nWaits for a specific new block and returns useful info about it.\n"
237 "\nReturns the current block on timeout or exit.\n"
238 "\nArguments:\n"
239 "1. \"blockhash\" (required, string) Block hash to wait for.\n"
240 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
241 "\nResult:\n"
242 "{ (json object)\n"
243 " \"hash\" : { (string) The blockhash\n"
244 " \"height\" : { (int) Block height\n"
245 "}\n"
246 "\nExamples:\n"
247 + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
248 + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
250 int timeout = 0;
252 uint256 hash = uint256S(request.params[0].get_str());
254 if (request.params.size() > 1)
255 timeout = request.params[1].get_int();
257 CUpdatedBlock block;
259 std::unique_lock<std::mutex> lock(cs_blockchange);
260 if(timeout)
261 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();});
262 else
263 cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); });
264 block = latestblock;
267 UniValue ret(UniValue::VOBJ);
268 ret.push_back(Pair("hash", block.hash.GetHex()));
269 ret.push_back(Pair("height", block.height));
270 return ret;
273 UniValue waitforblockheight(const JSONRPCRequest& request)
275 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
276 throw std::runtime_error(
277 "waitforblockheight <height> (timeout)\n"
278 "\nWaits for (at least) block height and returns the height and hash\n"
279 "of the current tip.\n"
280 "\nReturns the current block on timeout or exit.\n"
281 "\nArguments:\n"
282 "1. height (required, int) Block height to wait for (int)\n"
283 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
284 "\nResult:\n"
285 "{ (json object)\n"
286 " \"hash\" : { (string) The blockhash\n"
287 " \"height\" : { (int) Block height\n"
288 "}\n"
289 "\nExamples:\n"
290 + HelpExampleCli("waitforblockheight", "\"100\", 1000")
291 + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
293 int timeout = 0;
295 int height = request.params[0].get_int();
297 if (request.params.size() > 1)
298 timeout = request.params[1].get_int();
300 CUpdatedBlock block;
302 std::unique_lock<std::mutex> lock(cs_blockchange);
303 if(timeout)
304 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();});
305 else
306 cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); });
307 block = latestblock;
309 UniValue ret(UniValue::VOBJ);
310 ret.push_back(Pair("hash", block.hash.GetHex()));
311 ret.push_back(Pair("height", block.height));
312 return ret;
315 UniValue getdifficulty(const JSONRPCRequest& request)
317 if (request.fHelp || request.params.size() != 0)
318 throw std::runtime_error(
319 "getdifficulty\n"
320 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
321 "\nResult:\n"
322 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
323 "\nExamples:\n"
324 + HelpExampleCli("getdifficulty", "")
325 + HelpExampleRpc("getdifficulty", "")
328 LOCK(cs_main);
329 return GetDifficulty();
332 std::string EntryDescriptionString()
334 return " \"size\" : n, (numeric) virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted.\n"
335 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
336 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
337 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
338 " \"height\" : n, (numeric) block height when transaction entered pool\n"
339 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
340 " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n"
341 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
342 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
343 " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n"
344 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
345 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
346 " \"transactionid\", (string) parent transaction id\n"
347 " ... ]\n";
350 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
352 AssertLockHeld(mempool.cs);
354 info.push_back(Pair("size", (int)e.GetTxSize()));
355 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
356 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
357 info.push_back(Pair("time", e.GetTime()));
358 info.push_back(Pair("height", (int)e.GetHeight()));
359 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
360 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
361 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
362 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
363 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
364 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
365 const CTransaction& tx = e.GetTx();
366 std::set<std::string> setDepends;
367 BOOST_FOREACH(const CTxIn& txin, tx.vin)
369 if (mempool.exists(txin.prevout.hash))
370 setDepends.insert(txin.prevout.hash.ToString());
373 UniValue depends(UniValue::VARR);
374 BOOST_FOREACH(const std::string& dep, setDepends)
376 depends.push_back(dep);
379 info.push_back(Pair("depends", depends));
382 UniValue mempoolToJSON(bool fVerbose)
384 if (fVerbose)
386 LOCK(mempool.cs);
387 UniValue o(UniValue::VOBJ);
388 BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx)
390 const uint256& hash = e.GetTx().GetHash();
391 UniValue info(UniValue::VOBJ);
392 entryToJSON(info, e);
393 o.push_back(Pair(hash.ToString(), info));
395 return o;
397 else
399 std::vector<uint256> vtxid;
400 mempool.queryHashes(vtxid);
402 UniValue a(UniValue::VARR);
403 BOOST_FOREACH(const uint256& hash, vtxid)
404 a.push_back(hash.ToString());
406 return a;
410 UniValue getrawmempool(const JSONRPCRequest& request)
412 if (request.fHelp || request.params.size() > 1)
413 throw std::runtime_error(
414 "getrawmempool ( verbose )\n"
415 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
416 "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n"
417 "\nArguments:\n"
418 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
419 "\nResult: (for verbose = false):\n"
420 "[ (json array of string)\n"
421 " \"transactionid\" (string) The transaction id\n"
422 " ,...\n"
423 "]\n"
424 "\nResult: (for verbose = true):\n"
425 "{ (json object)\n"
426 " \"transactionid\" : { (json object)\n"
427 + EntryDescriptionString()
428 + " }, ...\n"
429 "}\n"
430 "\nExamples:\n"
431 + HelpExampleCli("getrawmempool", "true")
432 + HelpExampleRpc("getrawmempool", "true")
435 bool fVerbose = false;
436 if (request.params.size() > 0)
437 fVerbose = request.params[0].get_bool();
439 return mempoolToJSON(fVerbose);
442 UniValue getmempoolancestors(const JSONRPCRequest& request)
444 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
445 throw std::runtime_error(
446 "getmempoolancestors txid (verbose)\n"
447 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
448 "\nArguments:\n"
449 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
450 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
451 "\nResult (for verbose=false):\n"
452 "[ (json array of strings)\n"
453 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
454 " ,...\n"
455 "]\n"
456 "\nResult (for verbose=true):\n"
457 "{ (json object)\n"
458 " \"transactionid\" : { (json object)\n"
459 + EntryDescriptionString()
460 + " }, ...\n"
461 "}\n"
462 "\nExamples:\n"
463 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
464 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
468 bool fVerbose = false;
469 if (request.params.size() > 1)
470 fVerbose = request.params[1].get_bool();
472 uint256 hash = ParseHashV(request.params[0], "parameter 1");
474 LOCK(mempool.cs);
476 CTxMemPool::txiter it = mempool.mapTx.find(hash);
477 if (it == mempool.mapTx.end()) {
478 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
481 CTxMemPool::setEntries setAncestors;
482 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
483 std::string dummy;
484 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
486 if (!fVerbose) {
487 UniValue o(UniValue::VARR);
488 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
489 o.push_back(ancestorIt->GetTx().GetHash().ToString());
492 return o;
493 } else {
494 UniValue o(UniValue::VOBJ);
495 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
496 const CTxMemPoolEntry &e = *ancestorIt;
497 const uint256& _hash = e.GetTx().GetHash();
498 UniValue info(UniValue::VOBJ);
499 entryToJSON(info, e);
500 o.push_back(Pair(_hash.ToString(), info));
502 return o;
506 UniValue getmempooldescendants(const JSONRPCRequest& request)
508 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
509 throw std::runtime_error(
510 "getmempooldescendants txid (verbose)\n"
511 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
512 "\nArguments:\n"
513 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
514 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
515 "\nResult (for verbose=false):\n"
516 "[ (json array of strings)\n"
517 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
518 " ,...\n"
519 "]\n"
520 "\nResult (for verbose=true):\n"
521 "{ (json object)\n"
522 " \"transactionid\" : { (json object)\n"
523 + EntryDescriptionString()
524 + " }, ...\n"
525 "}\n"
526 "\nExamples:\n"
527 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
528 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
532 bool fVerbose = false;
533 if (request.params.size() > 1)
534 fVerbose = request.params[1].get_bool();
536 uint256 hash = ParseHashV(request.params[0], "parameter 1");
538 LOCK(mempool.cs);
540 CTxMemPool::txiter it = mempool.mapTx.find(hash);
541 if (it == mempool.mapTx.end()) {
542 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
545 CTxMemPool::setEntries setDescendants;
546 mempool.CalculateDescendants(it, setDescendants);
547 // CTxMemPool::CalculateDescendants will include the given tx
548 setDescendants.erase(it);
550 if (!fVerbose) {
551 UniValue o(UniValue::VARR);
552 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
553 o.push_back(descendantIt->GetTx().GetHash().ToString());
556 return o;
557 } else {
558 UniValue o(UniValue::VOBJ);
559 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
560 const CTxMemPoolEntry &e = *descendantIt;
561 const uint256& _hash = e.GetTx().GetHash();
562 UniValue info(UniValue::VOBJ);
563 entryToJSON(info, e);
564 o.push_back(Pair(_hash.ToString(), info));
566 return o;
570 UniValue getmempoolentry(const JSONRPCRequest& request)
572 if (request.fHelp || request.params.size() != 1) {
573 throw std::runtime_error(
574 "getmempoolentry txid\n"
575 "\nReturns mempool data for given transaction\n"
576 "\nArguments:\n"
577 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
578 "\nResult:\n"
579 "{ (json object)\n"
580 + EntryDescriptionString()
581 + "}\n"
582 "\nExamples:\n"
583 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
584 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
588 uint256 hash = ParseHashV(request.params[0], "parameter 1");
590 LOCK(mempool.cs);
592 CTxMemPool::txiter it = mempool.mapTx.find(hash);
593 if (it == mempool.mapTx.end()) {
594 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
597 const CTxMemPoolEntry &e = *it;
598 UniValue info(UniValue::VOBJ);
599 entryToJSON(info, e);
600 return info;
603 UniValue getblockhash(const JSONRPCRequest& request)
605 if (request.fHelp || request.params.size() != 1)
606 throw std::runtime_error(
607 "getblockhash height\n"
608 "\nReturns hash of block in best-block-chain at height provided.\n"
609 "\nArguments:\n"
610 "1. height (numeric, required) The height index\n"
611 "\nResult:\n"
612 "\"hash\" (string) The block hash\n"
613 "\nExamples:\n"
614 + HelpExampleCli("getblockhash", "1000")
615 + HelpExampleRpc("getblockhash", "1000")
618 LOCK(cs_main);
620 int nHeight = request.params[0].get_int();
621 if (nHeight < 0 || nHeight > chainActive.Height())
622 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
624 CBlockIndex* pblockindex = chainActive[nHeight];
625 return pblockindex->GetBlockHash().GetHex();
628 UniValue getblockheader(const JSONRPCRequest& request)
630 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
631 throw std::runtime_error(
632 "getblockheader \"hash\" ( verbose )\n"
633 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
634 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
635 "\nArguments:\n"
636 "1. \"hash\" (string, required) The block hash\n"
637 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
638 "\nResult (for verbose = true):\n"
639 "{\n"
640 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
641 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
642 " \"height\" : n, (numeric) The block height or index\n"
643 " \"version\" : n, (numeric) The block version\n"
644 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
645 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
646 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
647 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
648 " \"nonce\" : n, (numeric) The nonce\n"
649 " \"bits\" : \"1d00ffff\", (string) The bits\n"
650 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
651 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
652 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
653 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
654 "}\n"
655 "\nResult (for verbose=false):\n"
656 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
657 "\nExamples:\n"
658 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
659 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
662 LOCK(cs_main);
664 std::string strHash = request.params[0].get_str();
665 uint256 hash(uint256S(strHash));
667 bool fVerbose = true;
668 if (request.params.size() > 1)
669 fVerbose = request.params[1].get_bool();
671 if (mapBlockIndex.count(hash) == 0)
672 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
674 CBlockIndex* pblockindex = mapBlockIndex[hash];
676 if (!fVerbose)
678 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
679 ssBlock << pblockindex->GetBlockHeader();
680 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
681 return strHex;
684 return blockheaderToJSON(pblockindex);
687 UniValue getblock(const JSONRPCRequest& request)
689 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
690 throw std::runtime_error(
691 "getblock \"blockhash\" ( verbosity ) \n"
692 "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
693 "If verbosity is 1, returns an Object with information about block <hash>.\n"
694 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
695 "\nArguments:\n"
696 "1. \"blockhash\" (string, required) The block hash\n"
697 "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"
698 "\nResult (for verbosity = 0):\n"
699 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
700 "\nResult (for verbosity = 1):\n"
701 "{\n"
702 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
703 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
704 " \"size\" : n, (numeric) The block size\n"
705 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
706 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
707 " \"height\" : n, (numeric) The block height or index\n"
708 " \"version\" : n, (numeric) The block version\n"
709 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
710 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
711 " \"tx\" : [ (array of string) The transaction ids\n"
712 " \"transactionid\" (string) The transaction id\n"
713 " ,...\n"
714 " ],\n"
715 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
716 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
717 " \"nonce\" : n, (numeric) The nonce\n"
718 " \"bits\" : \"1d00ffff\", (string) The bits\n"
719 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
720 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
721 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
722 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
723 "}\n"
724 "\nResult (for verbosity = 2):\n"
725 "{\n"
726 " ..., Same output as verbosity = 1.\n"
727 " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
728 " ,...\n"
729 " ],\n"
730 " ,... Same output as verbosity = 1.\n"
731 "}\n"
732 "\nExamples:\n"
733 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
734 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
737 LOCK(cs_main);
739 std::string strHash = request.params[0].get_str();
740 uint256 hash(uint256S(strHash));
742 int verbosity = 1;
743 if (request.params.size() > 1) {
744 if(request.params[1].isNum())
745 verbosity = request.params[1].get_int();
746 else
747 verbosity = request.params[1].get_bool() ? 1 : 0;
750 if (mapBlockIndex.count(hash) == 0)
751 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
753 CBlock block;
754 CBlockIndex* pblockindex = mapBlockIndex[hash];
756 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
757 throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
759 if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
760 // Block not found on disk. This could be because we have the block
761 // header in our index but don't have the block (for example if a
762 // non-whitelisted node sends us an unrequested long chain of valid
763 // blocks, we add the headers to our index, but don't accept the
764 // block).
765 throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
767 if (verbosity <= 0)
769 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
770 ssBlock << block;
771 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
772 return strHex;
775 return blockToJSON(block, pblockindex, verbosity >= 2);
778 struct CCoinsStats
780 int nHeight;
781 uint256 hashBlock;
782 uint64_t nTransactions;
783 uint64_t nTransactionOutputs;
784 uint256 hashSerialized;
785 uint64_t nDiskSize;
786 CAmount nTotalAmount;
788 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nTotalAmount(0) {}
791 static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
793 assert(!outputs.empty());
794 ss << hash;
795 ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase);
796 stats.nTransactions++;
797 for (const auto output : outputs) {
798 ss << VARINT(output.first + 1);
799 ss << *(const CScriptBase*)(&output.second.out.scriptPubKey);
800 ss << VARINT(output.second.out.nValue);
801 stats.nTransactionOutputs++;
802 stats.nTotalAmount += output.second.out.nValue;
804 ss << VARINT(0);
807 //! Calculate statistics about the unspent transaction output set
808 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
810 std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
812 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
813 stats.hashBlock = pcursor->GetBestBlock();
815 LOCK(cs_main);
816 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
818 ss << stats.hashBlock;
819 while (pcursor->Valid()) {
820 boost::this_thread::interruption_point();
821 uint256 key;
822 CCoins coins;
823 if (pcursor->GetKey(key) && pcursor->GetValue(coins)) {
824 std::map<uint32_t, Coin> outputs;
825 for (unsigned int i=0; i<coins.vout.size(); i++) {
826 CTxOut &out = coins.vout[i];
827 if (!out.IsNull()) {
828 outputs[i] = Coin(std::move(out), coins.nHeight, coins.fCoinBase);
831 ApplyStats(stats, ss, key, outputs);
832 } else {
833 return error("%s: unable to read value", __func__);
835 pcursor->Next();
837 stats.hashSerialized = ss.GetHash();
838 stats.nDiskSize = view->EstimateSize();
839 return true;
842 UniValue pruneblockchain(const JSONRPCRequest& request)
844 if (request.fHelp || request.params.size() != 1)
845 throw std::runtime_error(
846 "pruneblockchain\n"
847 "\nArguments:\n"
848 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
849 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
850 "\nResult:\n"
851 "n (numeric) Height of the last block pruned.\n"
852 "\nExamples:\n"
853 + HelpExampleCli("pruneblockchain", "1000")
854 + HelpExampleRpc("pruneblockchain", "1000"));
856 if (!fPruneMode)
857 throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
859 LOCK(cs_main);
861 int heightParam = request.params[0].get_int();
862 if (heightParam < 0)
863 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
865 // Height value more than a billion is too high to be a block height, and
866 // too low to be a block time (corresponds to timestamp from Sep 2001).
867 if (heightParam > 1000000000) {
868 // Add a 2 hour buffer to include blocks which might have had old timestamps
869 CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
870 if (!pindex) {
871 throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
873 heightParam = pindex->nHeight;
876 unsigned int height = (unsigned int) heightParam;
877 unsigned int chainHeight = (unsigned int) chainActive.Height();
878 if (chainHeight < Params().PruneAfterHeight())
879 throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
880 else if (height > chainHeight)
881 throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
882 else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
883 LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
884 height = chainHeight - MIN_BLOCKS_TO_KEEP;
887 PruneBlockFilesManual(height);
888 return uint64_t(height);
891 UniValue gettxoutsetinfo(const JSONRPCRequest& request)
893 if (request.fHelp || request.params.size() != 0)
894 throw std::runtime_error(
895 "gettxoutsetinfo\n"
896 "\nReturns statistics about the unspent transaction output set.\n"
897 "Note this call may take some time.\n"
898 "\nResult:\n"
899 "{\n"
900 " \"height\":n, (numeric) The current block height (index)\n"
901 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
902 " \"transactions\": n, (numeric) The number of transactions\n"
903 " \"txouts\": n, (numeric) The number of output transactions\n"
904 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
905 " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
906 " \"total_amount\": x.xxx (numeric) The total amount\n"
907 "}\n"
908 "\nExamples:\n"
909 + HelpExampleCli("gettxoutsetinfo", "")
910 + HelpExampleRpc("gettxoutsetinfo", "")
913 UniValue ret(UniValue::VOBJ);
915 CCoinsStats stats;
916 FlushStateToDisk();
917 if (GetUTXOStats(pcoinsTip, stats)) {
918 ret.push_back(Pair("height", (int64_t)stats.nHeight));
919 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
920 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
921 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
922 ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
923 ret.push_back(Pair("disk_size", stats.nDiskSize));
924 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
925 } else {
926 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
928 return ret;
931 UniValue gettxout(const JSONRPCRequest& request)
933 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
934 throw std::runtime_error(
935 "gettxout \"txid\" n ( include_mempool )\n"
936 "\nReturns details about an unspent transaction output.\n"
937 "\nArguments:\n"
938 "1. \"txid\" (string, required) The transaction id\n"
939 "2. n (numeric, required) vout number\n"
940 "3. include_mempool (boolean, optional) Whether to include the mempool\n"
941 "\nResult:\n"
942 "{\n"
943 " \"bestblock\" : \"hash\", (string) the block hash\n"
944 " \"confirmations\" : n, (numeric) The number of confirmations\n"
945 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
946 " \"scriptPubKey\" : { (json object)\n"
947 " \"asm\" : \"code\", (string) \n"
948 " \"hex\" : \"hex\", (string) \n"
949 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
950 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
951 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
952 " \"address\" (string) bitcoin address\n"
953 " ,...\n"
954 " ]\n"
955 " },\n"
956 " \"version\" : n, (numeric) The version\n"
957 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
958 "}\n"
960 "\nExamples:\n"
961 "\nGet unspent transactions\n"
962 + HelpExampleCli("listunspent", "") +
963 "\nView the details\n"
964 + HelpExampleCli("gettxout", "\"txid\" 1") +
965 "\nAs a json rpc call\n"
966 + HelpExampleRpc("gettxout", "\"txid\", 1")
969 LOCK(cs_main);
971 UniValue ret(UniValue::VOBJ);
973 std::string strHash = request.params[0].get_str();
974 uint256 hash(uint256S(strHash));
975 int n = request.params[1].get_int();
976 bool fMempool = true;
977 if (request.params.size() > 2)
978 fMempool = request.params[2].get_bool();
980 CCoins coins;
981 if (fMempool) {
982 LOCK(mempool.cs);
983 CCoinsViewMemPool view(pcoinsTip, mempool);
984 if (!view.GetCoins(hash, coins) || mempool.isSpent(COutPoint(hash, n))) // TODO: this should be done by the CCoinsViewMemPool
985 return NullUniValue;
986 } else {
987 if (!pcoinsTip->GetCoins(hash, coins))
988 return NullUniValue;
990 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
991 return NullUniValue;
993 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
994 CBlockIndex *pindex = it->second;
995 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
996 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
997 ret.push_back(Pair("confirmations", 0));
998 else
999 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
1000 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
1001 UniValue o(UniValue::VOBJ);
1002 ScriptPubKeyToUniv(coins.vout[n].scriptPubKey, o, true);
1003 ret.push_back(Pair("scriptPubKey", o));
1004 ret.push_back(Pair("coinbase", coins.fCoinBase));
1006 return ret;
1009 UniValue verifychain(const JSONRPCRequest& request)
1011 int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
1012 int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1013 if (request.fHelp || request.params.size() > 2)
1014 throw std::runtime_error(
1015 "verifychain ( checklevel nblocks )\n"
1016 "\nVerifies blockchain database.\n"
1017 "\nArguments:\n"
1018 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1019 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1020 "\nResult:\n"
1021 "true|false (boolean) Verified or not\n"
1022 "\nExamples:\n"
1023 + HelpExampleCli("verifychain", "")
1024 + HelpExampleRpc("verifychain", "")
1027 LOCK(cs_main);
1029 if (request.params.size() > 0)
1030 nCheckLevel = request.params[0].get_int();
1031 if (request.params.size() > 1)
1032 nCheckDepth = request.params[1].get_int();
1034 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
1037 /** Implementation of IsSuperMajority with better feedback */
1038 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1040 UniValue rv(UniValue::VOBJ);
1041 bool activated = false;
1042 switch(version)
1044 case 2:
1045 activated = pindex->nHeight >= consensusParams.BIP34Height;
1046 break;
1047 case 3:
1048 activated = pindex->nHeight >= consensusParams.BIP66Height;
1049 break;
1050 case 4:
1051 activated = pindex->nHeight >= consensusParams.BIP65Height;
1052 break;
1054 rv.push_back(Pair("status", activated));
1055 return rv;
1058 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1060 UniValue rv(UniValue::VOBJ);
1061 rv.push_back(Pair("id", name));
1062 rv.push_back(Pair("version", version));
1063 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1064 return rv;
1067 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1069 UniValue rv(UniValue::VOBJ);
1070 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1071 switch (thresholdState) {
1072 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1073 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1074 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1075 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1076 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1078 if (THRESHOLD_STARTED == thresholdState)
1080 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1082 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1083 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1084 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1085 if (THRESHOLD_STARTED == thresholdState)
1087 UniValue statsUV(UniValue::VOBJ);
1088 BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);
1089 statsUV.push_back(Pair("period", statsStruct.period));
1090 statsUV.push_back(Pair("threshold", statsStruct.threshold));
1091 statsUV.push_back(Pair("elapsed", statsStruct.elapsed));
1092 statsUV.push_back(Pair("count", statsStruct.count));
1093 statsUV.push_back(Pair("possible", statsStruct.possible));
1094 rv.push_back(Pair("statistics", statsUV));
1096 return rv;
1099 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1101 // Deployments with timeout value of 0 are hidden.
1102 // A timeout value of 0 guarantees a softfork will never be activated.
1103 // This is used when softfork codes are merged without specifying the deployment schedule.
1104 if (consensusParams.vDeployments[id].nTimeout > 0)
1105 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
1108 UniValue getblockchaininfo(const JSONRPCRequest& request)
1110 if (request.fHelp || request.params.size() != 0)
1111 throw std::runtime_error(
1112 "getblockchaininfo\n"
1113 "Returns an object containing various state info regarding blockchain processing.\n"
1114 "\nResult:\n"
1115 "{\n"
1116 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1117 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1118 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1119 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1120 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1121 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1122 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1123 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1124 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1125 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1126 " \"softforks\": [ (array) status of softforks in progress\n"
1127 " {\n"
1128 " \"id\": \"xxxx\", (string) name of softfork\n"
1129 " \"version\": xx, (numeric) block version\n"
1130 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1131 " \"status\": xx, (boolean) true if threshold reached\n"
1132 " },\n"
1133 " }, ...\n"
1134 " ],\n"
1135 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1136 " \"xxxx\" : { (string) name of the softfork\n"
1137 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1138 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1139 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1140 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1141 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1142 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1143 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1144 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1145 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1146 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1147 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1148 " }\n"
1149 " }\n"
1150 " }\n"
1151 "}\n"
1152 "\nExamples:\n"
1153 + HelpExampleCli("getblockchaininfo", "")
1154 + HelpExampleRpc("getblockchaininfo", "")
1157 LOCK(cs_main);
1159 UniValue obj(UniValue::VOBJ);
1160 obj.push_back(Pair("chain", Params().NetworkIDString()));
1161 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1162 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1163 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1164 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1165 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1166 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1167 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1168 obj.push_back(Pair("pruned", fPruneMode));
1170 const Consensus::Params& consensusParams = Params().GetConsensus();
1171 CBlockIndex* tip = chainActive.Tip();
1172 UniValue softforks(UniValue::VARR);
1173 UniValue bip9_softforks(UniValue::VOBJ);
1174 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1175 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1176 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1177 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
1178 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
1179 obj.push_back(Pair("softforks", softforks));
1180 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1182 if (fPruneMode)
1184 CBlockIndex *block = chainActive.Tip();
1185 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
1186 block = block->pprev;
1188 obj.push_back(Pair("pruneheight", block->nHeight));
1190 return obj;
1193 /** Comparison function for sorting the getchaintips heads. */
1194 struct CompareBlocksByHeight
1196 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1198 /* Make sure that unequal blocks with the same height do not compare
1199 equal. Use the pointers themselves to make a distinction. */
1201 if (a->nHeight != b->nHeight)
1202 return (a->nHeight > b->nHeight);
1204 return a < b;
1208 UniValue getchaintips(const JSONRPCRequest& request)
1210 if (request.fHelp || request.params.size() != 0)
1211 throw std::runtime_error(
1212 "getchaintips\n"
1213 "Return information about all known tips in the block tree,"
1214 " including the main chain as well as orphaned branches.\n"
1215 "\nResult:\n"
1216 "[\n"
1217 " {\n"
1218 " \"height\": xxxx, (numeric) height of the chain tip\n"
1219 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1220 " \"branchlen\": 0 (numeric) zero for main chain\n"
1221 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1222 " },\n"
1223 " {\n"
1224 " \"height\": xxxx,\n"
1225 " \"hash\": \"xxxx\",\n"
1226 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1227 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1228 " }\n"
1229 "]\n"
1230 "Possible values for status:\n"
1231 "1. \"invalid\" This branch contains at least one invalid block\n"
1232 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1233 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1234 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1235 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1236 "\nExamples:\n"
1237 + HelpExampleCli("getchaintips", "")
1238 + HelpExampleRpc("getchaintips", "")
1241 LOCK(cs_main);
1244 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1245 * Algorithm:
1246 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1247 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1248 * - add chainActive.Tip()
1250 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1251 std::set<const CBlockIndex*> setOrphans;
1252 std::set<const CBlockIndex*> setPrevs;
1254 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
1256 if (!chainActive.Contains(item.second)) {
1257 setOrphans.insert(item.second);
1258 setPrevs.insert(item.second->pprev);
1262 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1264 if (setPrevs.erase(*it) == 0) {
1265 setTips.insert(*it);
1269 // Always report the currently active tip.
1270 setTips.insert(chainActive.Tip());
1272 /* Construct the output array. */
1273 UniValue res(UniValue::VARR);
1274 BOOST_FOREACH(const CBlockIndex* block, setTips)
1276 UniValue obj(UniValue::VOBJ);
1277 obj.push_back(Pair("height", block->nHeight));
1278 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1280 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1281 obj.push_back(Pair("branchlen", branchLen));
1283 std::string status;
1284 if (chainActive.Contains(block)) {
1285 // This block is part of the currently active chain.
1286 status = "active";
1287 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1288 // This block or one of its ancestors is invalid.
1289 status = "invalid";
1290 } else if (block->nChainTx == 0) {
1291 // This block cannot be connected because full block data for it or one of its parents is missing.
1292 status = "headers-only";
1293 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1294 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1295 status = "valid-fork";
1296 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1297 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1298 status = "valid-headers";
1299 } else {
1300 // No clue.
1301 status = "unknown";
1303 obj.push_back(Pair("status", status));
1305 res.push_back(obj);
1308 return res;
1311 UniValue mempoolInfoToJSON()
1313 UniValue ret(UniValue::VOBJ);
1314 ret.push_back(Pair("size", (int64_t) mempool.size()));
1315 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1316 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1317 size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1318 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1319 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1321 return ret;
1324 UniValue getmempoolinfo(const JSONRPCRequest& request)
1326 if (request.fHelp || request.params.size() != 0)
1327 throw std::runtime_error(
1328 "getmempoolinfo\n"
1329 "\nReturns details on the active state of the TX memory pool.\n"
1330 "\nResult:\n"
1331 "{\n"
1332 " \"size\": xxxxx, (numeric) Current tx count\n"
1333 " \"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"
1334 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1335 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1336 " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n"
1337 "}\n"
1338 "\nExamples:\n"
1339 + HelpExampleCli("getmempoolinfo", "")
1340 + HelpExampleRpc("getmempoolinfo", "")
1343 return mempoolInfoToJSON();
1346 UniValue preciousblock(const JSONRPCRequest& request)
1348 if (request.fHelp || request.params.size() != 1)
1349 throw std::runtime_error(
1350 "preciousblock \"blockhash\"\n"
1351 "\nTreats a block as if it were received before others with the same work.\n"
1352 "\nA later preciousblock call can override the effect of an earlier one.\n"
1353 "\nThe effects of preciousblock are not retained across restarts.\n"
1354 "\nArguments:\n"
1355 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1356 "\nResult:\n"
1357 "\nExamples:\n"
1358 + HelpExampleCli("preciousblock", "\"blockhash\"")
1359 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1362 std::string strHash = request.params[0].get_str();
1363 uint256 hash(uint256S(strHash));
1364 CBlockIndex* pblockindex;
1367 LOCK(cs_main);
1368 if (mapBlockIndex.count(hash) == 0)
1369 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1371 pblockindex = mapBlockIndex[hash];
1374 CValidationState state;
1375 PreciousBlock(state, Params(), pblockindex);
1377 if (!state.IsValid()) {
1378 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1381 return NullUniValue;
1384 UniValue invalidateblock(const JSONRPCRequest& request)
1386 if (request.fHelp || request.params.size() != 1)
1387 throw std::runtime_error(
1388 "invalidateblock \"blockhash\"\n"
1389 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1390 "\nArguments:\n"
1391 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1392 "\nResult:\n"
1393 "\nExamples:\n"
1394 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1395 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1398 std::string strHash = request.params[0].get_str();
1399 uint256 hash(uint256S(strHash));
1400 CValidationState state;
1403 LOCK(cs_main);
1404 if (mapBlockIndex.count(hash) == 0)
1405 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1407 CBlockIndex* pblockindex = mapBlockIndex[hash];
1408 InvalidateBlock(state, Params(), pblockindex);
1411 if (state.IsValid()) {
1412 ActivateBestChain(state, Params());
1415 if (!state.IsValid()) {
1416 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1419 return NullUniValue;
1422 UniValue reconsiderblock(const JSONRPCRequest& request)
1424 if (request.fHelp || request.params.size() != 1)
1425 throw std::runtime_error(
1426 "reconsiderblock \"blockhash\"\n"
1427 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1428 "This can be used to undo the effects of invalidateblock.\n"
1429 "\nArguments:\n"
1430 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1431 "\nResult:\n"
1432 "\nExamples:\n"
1433 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1434 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1437 std::string strHash = request.params[0].get_str();
1438 uint256 hash(uint256S(strHash));
1441 LOCK(cs_main);
1442 if (mapBlockIndex.count(hash) == 0)
1443 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1445 CBlockIndex* pblockindex = mapBlockIndex[hash];
1446 ResetBlockFailureFlags(pblockindex);
1449 CValidationState state;
1450 ActivateBestChain(state, Params());
1452 if (!state.IsValid()) {
1453 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1456 return NullUniValue;
1459 UniValue getchaintxstats(const JSONRPCRequest& request)
1461 if (request.fHelp || request.params.size() > 2)
1462 throw std::runtime_error(
1463 "getchaintxstats ( nblocks blockhash )\n"
1464 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1465 "\nArguments:\n"
1466 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1467 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1468 "\nResult:\n"
1469 "{\n"
1470 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1471 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1472 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1473 "}\n"
1474 "\nExamples:\n"
1475 + HelpExampleCli("getchaintxstats", "")
1476 + HelpExampleRpc("getchaintxstats", "2016")
1479 const CBlockIndex* pindex;
1480 int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1482 if (request.params.size() > 0 && !request.params[0].isNull()) {
1483 blockcount = request.params[0].get_int();
1486 bool havehash = request.params.size() > 1 && !request.params[1].isNull();
1487 uint256 hash;
1488 if (havehash) {
1489 hash = uint256S(request.params[1].get_str());
1493 LOCK(cs_main);
1494 if (havehash) {
1495 auto it = mapBlockIndex.find(hash);
1496 if (it == mapBlockIndex.end()) {
1497 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1499 pindex = it->second;
1500 if (!chainActive.Contains(pindex)) {
1501 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1503 } else {
1504 pindex = chainActive.Tip();
1508 if (blockcount < 1 || blockcount >= pindex->nHeight) {
1509 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height");
1512 const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1513 int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1514 int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1516 UniValue ret(UniValue::VOBJ);
1517 ret.push_back(Pair("time", (int64_t)pindex->nTime));
1518 ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx));
1519 ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff));
1521 return ret;
1524 static const CRPCCommand commands[] =
1525 { // category name actor (function) okSafe argNames
1526 // --------------------- ------------------------ ----------------------- ------ ----------
1527 { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
1528 { "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} },
1529 { "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
1530 { "blockchain", "getblockcount", &getblockcount, true, {} },
1531 { "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} },
1532 { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
1533 { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
1534 { "blockchain", "getchaintips", &getchaintips, true, {} },
1535 { "blockchain", "getdifficulty", &getdifficulty, true, {} },
1536 { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
1537 { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
1538 { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
1539 { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
1540 { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
1541 { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
1542 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
1543 { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
1544 { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },
1546 { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
1548 /* Not shown in help */
1549 { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
1550 { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
1551 { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
1552 { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
1553 { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
1556 void RegisterBlockchainRPCCommands(CRPCTable &t)
1558 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1559 t.appendCommand(commands[vcidx].name, &commands[vcidx]);