Merge #10874: [RPC] getblockchaininfo: Loop through the bip9 soft fork deployments...
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blobb7895b86f7473d7ec0b5c01691636d50650b1579
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>
27 #include <warnings.h>
29 #include <stdint.h>
31 #include <univalue.h>
33 #include <boost/thread/thread.hpp> // boost::thread::interrupt
35 #include <mutex>
36 #include <condition_variable>
38 struct CUpdatedBlock
40 uint256 hash;
41 int height;
44 static std::mutex cs_blockchange;
45 static std::condition_variable cond_blockchange;
46 static CUpdatedBlock latestblock;
48 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
50 double GetDifficulty(const CBlockIndex* blockindex)
52 if (blockindex == nullptr)
54 if (chainActive.Tip() == nullptr)
55 return 1.0;
56 else
57 blockindex = chainActive.Tip();
60 int nShift = (blockindex->nBits >> 24) & 0xff;
62 double dDiff =
63 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
65 while (nShift < 29)
67 dDiff *= 256.0;
68 nShift++;
70 while (nShift > 29)
72 dDiff /= 256.0;
73 nShift--;
76 return dDiff;
79 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
81 AssertLockHeld(cs_main);
82 UniValue result(UniValue::VOBJ);
83 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
84 int confirmations = -1;
85 // Only report confirmations if the block is on the main chain
86 if (chainActive.Contains(blockindex))
87 confirmations = chainActive.Height() - blockindex->nHeight + 1;
88 result.push_back(Pair("confirmations", confirmations));
89 result.push_back(Pair("height", blockindex->nHeight));
90 result.push_back(Pair("version", blockindex->nVersion));
91 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
92 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
93 result.push_back(Pair("time", (int64_t)blockindex->nTime));
94 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
95 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
96 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
97 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
98 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
100 if (blockindex->pprev)
101 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
102 CBlockIndex *pnext = chainActive.Next(blockindex);
103 if (pnext)
104 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
105 return result;
108 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
110 AssertLockHeld(cs_main);
111 UniValue result(UniValue::VOBJ);
112 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
113 int confirmations = -1;
114 // Only report confirmations if the block is on the main chain
115 if (chainActive.Contains(blockindex))
116 confirmations = chainActive.Height() - blockindex->nHeight + 1;
117 result.push_back(Pair("confirmations", confirmations));
118 result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)));
119 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
120 result.push_back(Pair("weight", (int)::GetBlockWeight(block)));
121 result.push_back(Pair("height", blockindex->nHeight));
122 result.push_back(Pair("version", block.nVersion));
123 result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion)));
124 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
125 UniValue txs(UniValue::VARR);
126 for(const auto& tx : block.vtx)
128 if(txDetails)
130 UniValue objTx(UniValue::VOBJ);
131 TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags());
132 txs.push_back(objTx);
134 else
135 txs.push_back(tx->GetHash().GetHex());
137 result.push_back(Pair("tx", txs));
138 result.push_back(Pair("time", block.GetBlockTime()));
139 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
140 result.push_back(Pair("nonce", (uint64_t)block.nNonce));
141 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
142 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
143 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
145 if (blockindex->pprev)
146 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
147 CBlockIndex *pnext = chainActive.Next(blockindex);
148 if (pnext)
149 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
150 return result;
153 UniValue getblockcount(const JSONRPCRequest& request)
155 if (request.fHelp || request.params.size() != 0)
156 throw std::runtime_error(
157 "getblockcount\n"
158 "\nReturns the number of blocks in the longest blockchain.\n"
159 "\nResult:\n"
160 "n (numeric) The current block count\n"
161 "\nExamples:\n"
162 + HelpExampleCli("getblockcount", "")
163 + HelpExampleRpc("getblockcount", "")
166 LOCK(cs_main);
167 return chainActive.Height();
170 UniValue getbestblockhash(const JSONRPCRequest& request)
172 if (request.fHelp || request.params.size() != 0)
173 throw std::runtime_error(
174 "getbestblockhash\n"
175 "\nReturns the hash of the best (tip) block in the longest blockchain.\n"
176 "\nResult:\n"
177 "\"hex\" (string) the block hash hex encoded\n"
178 "\nExamples:\n"
179 + HelpExampleCli("getbestblockhash", "")
180 + HelpExampleRpc("getbestblockhash", "")
183 LOCK(cs_main);
184 return chainActive.Tip()->GetBlockHash().GetHex();
187 void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex)
189 if(pindex) {
190 std::lock_guard<std::mutex> lock(cs_blockchange);
191 latestblock.hash = pindex->GetBlockHash();
192 latestblock.height = pindex->nHeight;
194 cond_blockchange.notify_all();
197 UniValue waitfornewblock(const JSONRPCRequest& request)
199 if (request.fHelp || request.params.size() > 1)
200 throw std::runtime_error(
201 "waitfornewblock (timeout)\n"
202 "\nWaits for a specific new block and returns useful info about it.\n"
203 "\nReturns the current block on timeout or exit.\n"
204 "\nArguments:\n"
205 "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
206 "\nResult:\n"
207 "{ (json object)\n"
208 " \"hash\" : { (string) The blockhash\n"
209 " \"height\" : { (int) Block height\n"
210 "}\n"
211 "\nExamples:\n"
212 + HelpExampleCli("waitfornewblock", "1000")
213 + HelpExampleRpc("waitfornewblock", "1000")
215 int timeout = 0;
216 if (!request.params[0].isNull())
217 timeout = request.params[0].get_int();
219 CUpdatedBlock block;
221 std::unique_lock<std::mutex> lock(cs_blockchange);
222 block = latestblock;
223 if(timeout)
224 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
225 else
226 cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
227 block = latestblock;
229 UniValue ret(UniValue::VOBJ);
230 ret.push_back(Pair("hash", block.hash.GetHex()));
231 ret.push_back(Pair("height", block.height));
232 return ret;
235 UniValue waitforblock(const JSONRPCRequest& request)
237 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
238 throw std::runtime_error(
239 "waitforblock <blockhash> (timeout)\n"
240 "\nWaits for a specific new block and returns useful info about it.\n"
241 "\nReturns the current block on timeout or exit.\n"
242 "\nArguments:\n"
243 "1. \"blockhash\" (required, string) Block hash to wait for.\n"
244 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
245 "\nResult:\n"
246 "{ (json object)\n"
247 " \"hash\" : { (string) The blockhash\n"
248 " \"height\" : { (int) Block height\n"
249 "}\n"
250 "\nExamples:\n"
251 + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
252 + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
254 int timeout = 0;
256 uint256 hash = uint256S(request.params[0].get_str());
258 if (!request.params[1].isNull())
259 timeout = request.params[1].get_int();
261 CUpdatedBlock block;
263 std::unique_lock<std::mutex> lock(cs_blockchange);
264 if(timeout)
265 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();});
266 else
267 cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); });
268 block = latestblock;
271 UniValue ret(UniValue::VOBJ);
272 ret.push_back(Pair("hash", block.hash.GetHex()));
273 ret.push_back(Pair("height", block.height));
274 return ret;
277 UniValue waitforblockheight(const JSONRPCRequest& request)
279 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
280 throw std::runtime_error(
281 "waitforblockheight <height> (timeout)\n"
282 "\nWaits for (at least) block height and returns the height and hash\n"
283 "of the current tip.\n"
284 "\nReturns the current block on timeout or exit.\n"
285 "\nArguments:\n"
286 "1. height (required, int) Block height to wait for (int)\n"
287 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
288 "\nResult:\n"
289 "{ (json object)\n"
290 " \"hash\" : { (string) The blockhash\n"
291 " \"height\" : { (int) Block height\n"
292 "}\n"
293 "\nExamples:\n"
294 + HelpExampleCli("waitforblockheight", "\"100\", 1000")
295 + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
297 int timeout = 0;
299 int height = request.params[0].get_int();
301 if (!request.params[1].isNull())
302 timeout = request.params[1].get_int();
304 CUpdatedBlock block;
306 std::unique_lock<std::mutex> lock(cs_blockchange);
307 if(timeout)
308 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();});
309 else
310 cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); });
311 block = latestblock;
313 UniValue ret(UniValue::VOBJ);
314 ret.push_back(Pair("hash", block.hash.GetHex()));
315 ret.push_back(Pair("height", block.height));
316 return ret;
319 UniValue getdifficulty(const JSONRPCRequest& request)
321 if (request.fHelp || request.params.size() != 0)
322 throw std::runtime_error(
323 "getdifficulty\n"
324 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
325 "\nResult:\n"
326 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
327 "\nExamples:\n"
328 + HelpExampleCli("getdifficulty", "")
329 + HelpExampleRpc("getdifficulty", "")
332 LOCK(cs_main);
333 return GetDifficulty();
336 std::string EntryDescriptionString()
338 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"
339 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
340 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
341 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
342 " \"height\" : n, (numeric) block height when transaction entered pool\n"
343 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
344 " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n"
345 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
346 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
347 " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n"
348 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
349 " \"wtxid\" : hash, (string) hash of serialized transaction, including witness data\n"
350 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
351 " \"transactionid\", (string) parent transaction id\n"
352 " ... ]\n";
355 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
357 AssertLockHeld(mempool.cs);
359 info.push_back(Pair("size", (int)e.GetTxSize()));
360 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
361 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
362 info.push_back(Pair("time", e.GetTime()));
363 info.push_back(Pair("height", (int)e.GetHeight()));
364 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
365 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
366 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
367 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
368 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
369 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
370 info.push_back(Pair("wtxid", mempool.vTxHashes[e.vTxHashesIdx].first.ToString()));
371 const CTransaction& tx = e.GetTx();
372 std::set<std::string> setDepends;
373 for (const CTxIn& txin : tx.vin)
375 if (mempool.exists(txin.prevout.hash))
376 setDepends.insert(txin.prevout.hash.ToString());
379 UniValue depends(UniValue::VARR);
380 for (const std::string& dep : setDepends)
382 depends.push_back(dep);
385 info.push_back(Pair("depends", depends));
388 UniValue mempoolToJSON(bool fVerbose)
390 if (fVerbose)
392 LOCK(mempool.cs);
393 UniValue o(UniValue::VOBJ);
394 for (const CTxMemPoolEntry& e : mempool.mapTx)
396 const uint256& hash = e.GetTx().GetHash();
397 UniValue info(UniValue::VOBJ);
398 entryToJSON(info, e);
399 o.push_back(Pair(hash.ToString(), info));
401 return o;
403 else
405 std::vector<uint256> vtxid;
406 mempool.queryHashes(vtxid);
408 UniValue a(UniValue::VARR);
409 for (const uint256& hash : vtxid)
410 a.push_back(hash.ToString());
412 return a;
416 UniValue getrawmempool(const JSONRPCRequest& request)
418 if (request.fHelp || request.params.size() > 1)
419 throw std::runtime_error(
420 "getrawmempool ( verbose )\n"
421 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
422 "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n"
423 "\nArguments:\n"
424 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
425 "\nResult: (for verbose = false):\n"
426 "[ (json array of string)\n"
427 " \"transactionid\" (string) The transaction id\n"
428 " ,...\n"
429 "]\n"
430 "\nResult: (for verbose = true):\n"
431 "{ (json object)\n"
432 " \"transactionid\" : { (json object)\n"
433 + EntryDescriptionString()
434 + " }, ...\n"
435 "}\n"
436 "\nExamples:\n"
437 + HelpExampleCli("getrawmempool", "true")
438 + HelpExampleRpc("getrawmempool", "true")
441 bool fVerbose = false;
442 if (!request.params[0].isNull())
443 fVerbose = request.params[0].get_bool();
445 return mempoolToJSON(fVerbose);
448 UniValue getmempoolancestors(const JSONRPCRequest& request)
450 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
451 throw std::runtime_error(
452 "getmempoolancestors txid (verbose)\n"
453 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
454 "\nArguments:\n"
455 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
456 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
457 "\nResult (for verbose=false):\n"
458 "[ (json array of strings)\n"
459 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
460 " ,...\n"
461 "]\n"
462 "\nResult (for verbose=true):\n"
463 "{ (json object)\n"
464 " \"transactionid\" : { (json object)\n"
465 + EntryDescriptionString()
466 + " }, ...\n"
467 "}\n"
468 "\nExamples:\n"
469 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
470 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
474 bool fVerbose = false;
475 if (!request.params[1].isNull())
476 fVerbose = request.params[1].get_bool();
478 uint256 hash = ParseHashV(request.params[0], "parameter 1");
480 LOCK(mempool.cs);
482 CTxMemPool::txiter it = mempool.mapTx.find(hash);
483 if (it == mempool.mapTx.end()) {
484 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
487 CTxMemPool::setEntries setAncestors;
488 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
489 std::string dummy;
490 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
492 if (!fVerbose) {
493 UniValue o(UniValue::VARR);
494 for (CTxMemPool::txiter ancestorIt : setAncestors) {
495 o.push_back(ancestorIt->GetTx().GetHash().ToString());
498 return o;
499 } else {
500 UniValue o(UniValue::VOBJ);
501 for (CTxMemPool::txiter ancestorIt : setAncestors) {
502 const CTxMemPoolEntry &e = *ancestorIt;
503 const uint256& _hash = e.GetTx().GetHash();
504 UniValue info(UniValue::VOBJ);
505 entryToJSON(info, e);
506 o.push_back(Pair(_hash.ToString(), info));
508 return o;
512 UniValue getmempooldescendants(const JSONRPCRequest& request)
514 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
515 throw std::runtime_error(
516 "getmempooldescendants txid (verbose)\n"
517 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
518 "\nArguments:\n"
519 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
520 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
521 "\nResult (for verbose=false):\n"
522 "[ (json array of strings)\n"
523 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
524 " ,...\n"
525 "]\n"
526 "\nResult (for verbose=true):\n"
527 "{ (json object)\n"
528 " \"transactionid\" : { (json object)\n"
529 + EntryDescriptionString()
530 + " }, ...\n"
531 "}\n"
532 "\nExamples:\n"
533 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
534 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
538 bool fVerbose = false;
539 if (!request.params[1].isNull())
540 fVerbose = request.params[1].get_bool();
542 uint256 hash = ParseHashV(request.params[0], "parameter 1");
544 LOCK(mempool.cs);
546 CTxMemPool::txiter it = mempool.mapTx.find(hash);
547 if (it == mempool.mapTx.end()) {
548 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
551 CTxMemPool::setEntries setDescendants;
552 mempool.CalculateDescendants(it, setDescendants);
553 // CTxMemPool::CalculateDescendants will include the given tx
554 setDescendants.erase(it);
556 if (!fVerbose) {
557 UniValue o(UniValue::VARR);
558 for (CTxMemPool::txiter descendantIt : setDescendants) {
559 o.push_back(descendantIt->GetTx().GetHash().ToString());
562 return o;
563 } else {
564 UniValue o(UniValue::VOBJ);
565 for (CTxMemPool::txiter descendantIt : setDescendants) {
566 const CTxMemPoolEntry &e = *descendantIt;
567 const uint256& _hash = e.GetTx().GetHash();
568 UniValue info(UniValue::VOBJ);
569 entryToJSON(info, e);
570 o.push_back(Pair(_hash.ToString(), info));
572 return o;
576 UniValue getmempoolentry(const JSONRPCRequest& request)
578 if (request.fHelp || request.params.size() != 1) {
579 throw std::runtime_error(
580 "getmempoolentry txid\n"
581 "\nReturns mempool data for given transaction\n"
582 "\nArguments:\n"
583 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
584 "\nResult:\n"
585 "{ (json object)\n"
586 + EntryDescriptionString()
587 + "}\n"
588 "\nExamples:\n"
589 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
590 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
594 uint256 hash = ParseHashV(request.params[0], "parameter 1");
596 LOCK(mempool.cs);
598 CTxMemPool::txiter it = mempool.mapTx.find(hash);
599 if (it == mempool.mapTx.end()) {
600 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
603 const CTxMemPoolEntry &e = *it;
604 UniValue info(UniValue::VOBJ);
605 entryToJSON(info, e);
606 return info;
609 UniValue getblockhash(const JSONRPCRequest& request)
611 if (request.fHelp || request.params.size() != 1)
612 throw std::runtime_error(
613 "getblockhash height\n"
614 "\nReturns hash of block in best-block-chain at height provided.\n"
615 "\nArguments:\n"
616 "1. height (numeric, required) The height index\n"
617 "\nResult:\n"
618 "\"hash\" (string) The block hash\n"
619 "\nExamples:\n"
620 + HelpExampleCli("getblockhash", "1000")
621 + HelpExampleRpc("getblockhash", "1000")
624 LOCK(cs_main);
626 int nHeight = request.params[0].get_int();
627 if (nHeight < 0 || nHeight > chainActive.Height())
628 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
630 CBlockIndex* pblockindex = chainActive[nHeight];
631 return pblockindex->GetBlockHash().GetHex();
634 UniValue getblockheader(const JSONRPCRequest& request)
636 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
637 throw std::runtime_error(
638 "getblockheader \"hash\" ( verbose )\n"
639 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
640 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
641 "\nArguments:\n"
642 "1. \"hash\" (string, required) The block hash\n"
643 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
644 "\nResult (for verbose = true):\n"
645 "{\n"
646 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
647 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
648 " \"height\" : n, (numeric) The block height or index\n"
649 " \"version\" : n, (numeric) The block version\n"
650 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
651 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
652 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
653 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
654 " \"nonce\" : n, (numeric) The nonce\n"
655 " \"bits\" : \"1d00ffff\", (string) The bits\n"
656 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
657 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
658 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
659 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
660 "}\n"
661 "\nResult (for verbose=false):\n"
662 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
663 "\nExamples:\n"
664 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
665 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
668 LOCK(cs_main);
670 std::string strHash = request.params[0].get_str();
671 uint256 hash(uint256S(strHash));
673 bool fVerbose = true;
674 if (!request.params[1].isNull())
675 fVerbose = request.params[1].get_bool();
677 if (mapBlockIndex.count(hash) == 0)
678 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
680 CBlockIndex* pblockindex = mapBlockIndex[hash];
682 if (!fVerbose)
684 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
685 ssBlock << pblockindex->GetBlockHeader();
686 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
687 return strHex;
690 return blockheaderToJSON(pblockindex);
693 UniValue getblock(const JSONRPCRequest& request)
695 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
696 throw std::runtime_error(
697 "getblock \"blockhash\" ( verbosity ) \n"
698 "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
699 "If verbosity is 1, returns an Object with information about block <hash>.\n"
700 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
701 "\nArguments:\n"
702 "1. \"blockhash\" (string, required) The block hash\n"
703 "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"
704 "\nResult (for verbosity = 0):\n"
705 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
706 "\nResult (for verbosity = 1):\n"
707 "{\n"
708 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
709 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
710 " \"size\" : n, (numeric) The block size\n"
711 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
712 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
713 " \"height\" : n, (numeric) The block height or index\n"
714 " \"version\" : n, (numeric) The block version\n"
715 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
716 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
717 " \"tx\" : [ (array of string) The transaction ids\n"
718 " \"transactionid\" (string) The transaction id\n"
719 " ,...\n"
720 " ],\n"
721 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
722 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
723 " \"nonce\" : n, (numeric) The nonce\n"
724 " \"bits\" : \"1d00ffff\", (string) The bits\n"
725 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
726 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
727 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
728 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
729 "}\n"
730 "\nResult (for verbosity = 2):\n"
731 "{\n"
732 " ..., Same output as verbosity = 1.\n"
733 " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
734 " ,...\n"
735 " ],\n"
736 " ,... Same output as verbosity = 1.\n"
737 "}\n"
738 "\nExamples:\n"
739 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
740 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
743 LOCK(cs_main);
745 std::string strHash = request.params[0].get_str();
746 uint256 hash(uint256S(strHash));
748 int verbosity = 1;
749 if (!request.params[1].isNull()) {
750 if(request.params[1].isNum())
751 verbosity = request.params[1].get_int();
752 else
753 verbosity = request.params[1].get_bool() ? 1 : 0;
756 if (mapBlockIndex.count(hash) == 0)
757 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
759 CBlock block;
760 CBlockIndex* pblockindex = mapBlockIndex[hash];
762 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
763 throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
765 if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
766 // Block not found on disk. This could be because we have the block
767 // header in our index but don't have the block (for example if a
768 // non-whitelisted node sends us an unrequested long chain of valid
769 // blocks, we add the headers to our index, but don't accept the
770 // block).
771 throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
773 if (verbosity <= 0)
775 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
776 ssBlock << block;
777 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
778 return strHex;
781 return blockToJSON(block, pblockindex, verbosity >= 2);
784 struct CCoinsStats
786 int nHeight;
787 uint256 hashBlock;
788 uint64_t nTransactions;
789 uint64_t nTransactionOutputs;
790 uint64_t nBogoSize;
791 uint256 hashSerialized;
792 uint64_t nDiskSize;
793 CAmount nTotalAmount;
795 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
798 static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
800 assert(!outputs.empty());
801 ss << hash;
802 ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase);
803 stats.nTransactions++;
804 for (const auto output : outputs) {
805 ss << VARINT(output.first + 1);
806 ss << output.second.out.scriptPubKey;
807 ss << VARINT(output.second.out.nValue);
808 stats.nTransactionOutputs++;
809 stats.nTotalAmount += output.second.out.nValue;
810 stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
811 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */;
813 ss << VARINT(0);
816 //! Calculate statistics about the unspent transaction output set
817 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
819 std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
820 assert(pcursor);
822 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
823 stats.hashBlock = pcursor->GetBestBlock();
825 LOCK(cs_main);
826 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
828 ss << stats.hashBlock;
829 uint256 prevkey;
830 std::map<uint32_t, Coin> outputs;
831 while (pcursor->Valid()) {
832 boost::this_thread::interruption_point();
833 COutPoint key;
834 Coin coin;
835 if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
836 if (!outputs.empty() && key.hash != prevkey) {
837 ApplyStats(stats, ss, prevkey, outputs);
838 outputs.clear();
840 prevkey = key.hash;
841 outputs[key.n] = std::move(coin);
842 } else {
843 return error("%s: unable to read value", __func__);
845 pcursor->Next();
847 if (!outputs.empty()) {
848 ApplyStats(stats, ss, prevkey, outputs);
850 stats.hashSerialized = ss.GetHash();
851 stats.nDiskSize = view->EstimateSize();
852 return true;
855 UniValue pruneblockchain(const JSONRPCRequest& request)
857 if (request.fHelp || request.params.size() != 1)
858 throw std::runtime_error(
859 "pruneblockchain\n"
860 "\nArguments:\n"
861 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
862 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
863 "\nResult:\n"
864 "n (numeric) Height of the last block pruned.\n"
865 "\nExamples:\n"
866 + HelpExampleCli("pruneblockchain", "1000")
867 + HelpExampleRpc("pruneblockchain", "1000"));
869 if (!fPruneMode)
870 throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
872 LOCK(cs_main);
874 int heightParam = request.params[0].get_int();
875 if (heightParam < 0)
876 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
878 // Height value more than a billion is too high to be a block height, and
879 // too low to be a block time (corresponds to timestamp from Sep 2001).
880 if (heightParam > 1000000000) {
881 // Add a 2 hour buffer to include blocks which might have had old timestamps
882 CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
883 if (!pindex) {
884 throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
886 heightParam = pindex->nHeight;
889 unsigned int height = (unsigned int) heightParam;
890 unsigned int chainHeight = (unsigned int) chainActive.Height();
891 if (chainHeight < Params().PruneAfterHeight())
892 throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
893 else if (height > chainHeight)
894 throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
895 else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
896 LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
897 height = chainHeight - MIN_BLOCKS_TO_KEEP;
900 PruneBlockFilesManual(height);
901 return uint64_t(height);
904 UniValue gettxoutsetinfo(const JSONRPCRequest& request)
906 if (request.fHelp || request.params.size() != 0)
907 throw std::runtime_error(
908 "gettxoutsetinfo\n"
909 "\nReturns statistics about the unspent transaction output set.\n"
910 "Note this call may take some time.\n"
911 "\nResult:\n"
912 "{\n"
913 " \"height\":n, (numeric) The current block height (index)\n"
914 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
915 " \"transactions\": n, (numeric) The number of transactions\n"
916 " \"txouts\": n, (numeric) The number of output transactions\n"
917 " \"bogosize\": n, (numeric) A meaningless metric for UTXO set size\n"
918 " \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
919 " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
920 " \"total_amount\": x.xxx (numeric) The total amount\n"
921 "}\n"
922 "\nExamples:\n"
923 + HelpExampleCli("gettxoutsetinfo", "")
924 + HelpExampleRpc("gettxoutsetinfo", "")
927 UniValue ret(UniValue::VOBJ);
929 CCoinsStats stats;
930 FlushStateToDisk();
931 if (GetUTXOStats(pcoinsdbview.get(), stats)) {
932 ret.push_back(Pair("height", (int64_t)stats.nHeight));
933 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
934 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
935 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
936 ret.push_back(Pair("bogosize", (int64_t)stats.nBogoSize));
937 ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
938 ret.push_back(Pair("disk_size", stats.nDiskSize));
939 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
940 } else {
941 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
943 return ret;
946 UniValue gettxout(const JSONRPCRequest& request)
948 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
949 throw std::runtime_error(
950 "gettxout \"txid\" n ( include_mempool )\n"
951 "\nReturns details about an unspent transaction output.\n"
952 "\nArguments:\n"
953 "1. \"txid\" (string, required) The transaction id\n"
954 "2. \"n\" (numeric, required) vout number\n"
955 "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true."
956 " Note that an unspent output that is spent in the mempool won't appear.\n"
957 "\nResult:\n"
958 "{\n"
959 " \"bestblock\" : \"hash\", (string) the block hash\n"
960 " \"confirmations\" : n, (numeric) The number of confirmations\n"
961 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
962 " \"scriptPubKey\" : { (json object)\n"
963 " \"asm\" : \"code\", (string) \n"
964 " \"hex\" : \"hex\", (string) \n"
965 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
966 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
967 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
968 " \"address\" (string) bitcoin address\n"
969 " ,...\n"
970 " ]\n"
971 " },\n"
972 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
973 "}\n"
975 "\nExamples:\n"
976 "\nGet unspent transactions\n"
977 + HelpExampleCli("listunspent", "") +
978 "\nView the details\n"
979 + HelpExampleCli("gettxout", "\"txid\" 1") +
980 "\nAs a json rpc call\n"
981 + HelpExampleRpc("gettxout", "\"txid\", 1")
984 LOCK(cs_main);
986 UniValue ret(UniValue::VOBJ);
988 std::string strHash = request.params[0].get_str();
989 uint256 hash(uint256S(strHash));
990 int n = request.params[1].get_int();
991 COutPoint out(hash, n);
992 bool fMempool = true;
993 if (!request.params[2].isNull())
994 fMempool = request.params[2].get_bool();
996 Coin coin;
997 if (fMempool) {
998 LOCK(mempool.cs);
999 CCoinsViewMemPool view(pcoinsTip.get(), mempool);
1000 if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
1001 return NullUniValue;
1003 } else {
1004 if (!pcoinsTip->GetCoin(out, coin)) {
1005 return NullUniValue;
1009 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
1010 CBlockIndex *pindex = it->second;
1011 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
1012 if (coin.nHeight == MEMPOOL_HEIGHT) {
1013 ret.push_back(Pair("confirmations", 0));
1014 } else {
1015 ret.push_back(Pair("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1)));
1017 ret.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
1018 UniValue o(UniValue::VOBJ);
1019 ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
1020 ret.push_back(Pair("scriptPubKey", o));
1021 ret.push_back(Pair("coinbase", (bool)coin.fCoinBase));
1023 return ret;
1026 UniValue verifychain(const JSONRPCRequest& request)
1028 int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL);
1029 int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1030 if (request.fHelp || request.params.size() > 2)
1031 throw std::runtime_error(
1032 "verifychain ( checklevel nblocks )\n"
1033 "\nVerifies blockchain database.\n"
1034 "\nArguments:\n"
1035 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1036 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1037 "\nResult:\n"
1038 "true|false (boolean) Verified or not\n"
1039 "\nExamples:\n"
1040 + HelpExampleCli("verifychain", "")
1041 + HelpExampleRpc("verifychain", "")
1044 LOCK(cs_main);
1046 if (!request.params[0].isNull())
1047 nCheckLevel = request.params[0].get_int();
1048 if (!request.params[1].isNull())
1049 nCheckDepth = request.params[1].get_int();
1051 return CVerifyDB().VerifyDB(Params(), pcoinsTip.get(), nCheckLevel, nCheckDepth);
1054 /** Implementation of IsSuperMajority with better feedback */
1055 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1057 UniValue rv(UniValue::VOBJ);
1058 bool activated = false;
1059 switch(version)
1061 case 2:
1062 activated = pindex->nHeight >= consensusParams.BIP34Height;
1063 break;
1064 case 3:
1065 activated = pindex->nHeight >= consensusParams.BIP66Height;
1066 break;
1067 case 4:
1068 activated = pindex->nHeight >= consensusParams.BIP65Height;
1069 break;
1071 rv.push_back(Pair("status", activated));
1072 return rv;
1075 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1077 UniValue rv(UniValue::VOBJ);
1078 rv.push_back(Pair("id", name));
1079 rv.push_back(Pair("version", version));
1080 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1081 return rv;
1084 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1086 UniValue rv(UniValue::VOBJ);
1087 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1088 switch (thresholdState) {
1089 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1090 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1091 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1092 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1093 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1095 if (THRESHOLD_STARTED == thresholdState)
1097 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1099 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1100 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1101 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1102 if (THRESHOLD_STARTED == thresholdState)
1104 UniValue statsUV(UniValue::VOBJ);
1105 BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);
1106 statsUV.push_back(Pair("period", statsStruct.period));
1107 statsUV.push_back(Pair("threshold", statsStruct.threshold));
1108 statsUV.push_back(Pair("elapsed", statsStruct.elapsed));
1109 statsUV.push_back(Pair("count", statsStruct.count));
1110 statsUV.push_back(Pair("possible", statsStruct.possible));
1111 rv.push_back(Pair("statistics", statsUV));
1113 return rv;
1116 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1118 // Deployments with timeout value of 0 are hidden.
1119 // A timeout value of 0 guarantees a softfork will never be activated.
1120 // This is used when softfork codes are merged without specifying the deployment schedule.
1121 if (consensusParams.vDeployments[id].nTimeout > 0)
1122 bip9_softforks.push_back(Pair(VersionBitsDeploymentInfo[id].name, BIP9SoftForkDesc(consensusParams, id)));
1125 UniValue getblockchaininfo(const JSONRPCRequest& request)
1127 if (request.fHelp || request.params.size() != 0)
1128 throw std::runtime_error(
1129 "getblockchaininfo\n"
1130 "Returns an object containing various state info regarding blockchain processing.\n"
1131 "\nResult:\n"
1132 "{\n"
1133 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1134 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1135 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1136 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1137 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1138 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1139 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1140 " \"initialblockdownload\": xxxx, (bool) (debug information) estimate of whether this node is in Initial Block Download mode.\n"
1141 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1142 " \"size_on_disk\": xxxxxx, (numeric) the estimated size of the block and undo files on disk\n"
1143 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1144 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored (only present if pruning is enabled)\n"
1145 " \"automatic_pruning\": xx, (boolean) whether automatic pruning is enabled (only present if pruning is enabled)\n"
1146 " \"prune_target_size\": xxxxxx, (numeric) the target size used by pruning (only present if automatic pruning is enabled)\n"
1147 " \"softforks\": [ (array) status of softforks in progress\n"
1148 " {\n"
1149 " \"id\": \"xxxx\", (string) name of softfork\n"
1150 " \"version\": xx, (numeric) block version\n"
1151 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1152 " \"status\": xx, (boolean) true if threshold reached\n"
1153 " },\n"
1154 " }, ...\n"
1155 " ],\n"
1156 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1157 " \"xxxx\" : { (string) name of the softfork\n"
1158 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1159 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1160 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1161 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1162 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1163 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1164 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1165 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1166 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1167 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1168 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1169 " }\n"
1170 " }\n"
1171 " }\n"
1172 " \"warnings\" : \"...\", (string) any network and blockchain warnings.\n"
1173 "}\n"
1174 "\nExamples:\n"
1175 + HelpExampleCli("getblockchaininfo", "")
1176 + HelpExampleRpc("getblockchaininfo", "")
1179 LOCK(cs_main);
1181 UniValue obj(UniValue::VOBJ);
1182 obj.push_back(Pair("chain", Params().NetworkIDString()));
1183 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1184 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1185 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1186 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1187 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1188 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1189 obj.push_back(Pair("initialblockdownload", IsInitialBlockDownload()));
1190 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1191 obj.push_back(Pair("size_on_disk", CalculateCurrentUsage()));
1192 obj.push_back(Pair("pruned", fPruneMode));
1193 if (fPruneMode) {
1194 CBlockIndex* block = chainActive.Tip();
1195 assert(block);
1196 while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
1197 block = block->pprev;
1200 obj.push_back(Pair("pruneheight", block->nHeight));
1202 // if 0, execution bypasses the whole if block.
1203 bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1);
1204 obj.push_back(Pair("automatic_pruning", automatic_pruning));
1205 if (automatic_pruning) {
1206 obj.push_back(Pair("prune_target_size", nPruneTarget));
1210 const Consensus::Params& consensusParams = Params().GetConsensus();
1211 CBlockIndex* tip = chainActive.Tip();
1212 UniValue softforks(UniValue::VARR);
1213 UniValue bip9_softforks(UniValue::VOBJ);
1214 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1215 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1216 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1217 for (int pos = Consensus::DEPLOYMENT_CSV; pos != Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++pos) {
1218 BIP9SoftForkDescPushBack(bip9_softforks, consensusParams, static_cast<Consensus::DeploymentPos>(pos));
1220 obj.push_back(Pair("softforks", softforks));
1221 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1223 obj.push_back(Pair("warnings", GetWarnings("statusbar")));
1224 return obj;
1227 /** Comparison function for sorting the getchaintips heads. */
1228 struct CompareBlocksByHeight
1230 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1232 /* Make sure that unequal blocks with the same height do not compare
1233 equal. Use the pointers themselves to make a distinction. */
1235 if (a->nHeight != b->nHeight)
1236 return (a->nHeight > b->nHeight);
1238 return a < b;
1242 UniValue getchaintips(const JSONRPCRequest& request)
1244 if (request.fHelp || request.params.size() != 0)
1245 throw std::runtime_error(
1246 "getchaintips\n"
1247 "Return information about all known tips in the block tree,"
1248 " including the main chain as well as orphaned branches.\n"
1249 "\nResult:\n"
1250 "[\n"
1251 " {\n"
1252 " \"height\": xxxx, (numeric) height of the chain tip\n"
1253 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1254 " \"branchlen\": 0 (numeric) zero for main chain\n"
1255 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1256 " },\n"
1257 " {\n"
1258 " \"height\": xxxx,\n"
1259 " \"hash\": \"xxxx\",\n"
1260 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1261 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1262 " }\n"
1263 "]\n"
1264 "Possible values for status:\n"
1265 "1. \"invalid\" This branch contains at least one invalid block\n"
1266 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1267 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1268 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1269 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1270 "\nExamples:\n"
1271 + HelpExampleCli("getchaintips", "")
1272 + HelpExampleRpc("getchaintips", "")
1275 LOCK(cs_main);
1278 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1279 * Algorithm:
1280 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1281 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1282 * - add chainActive.Tip()
1284 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1285 std::set<const CBlockIndex*> setOrphans;
1286 std::set<const CBlockIndex*> setPrevs;
1288 for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
1290 if (!chainActive.Contains(item.second)) {
1291 setOrphans.insert(item.second);
1292 setPrevs.insert(item.second->pprev);
1296 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1298 if (setPrevs.erase(*it) == 0) {
1299 setTips.insert(*it);
1303 // Always report the currently active tip.
1304 setTips.insert(chainActive.Tip());
1306 /* Construct the output array. */
1307 UniValue res(UniValue::VARR);
1308 for (const CBlockIndex* block : setTips)
1310 UniValue obj(UniValue::VOBJ);
1311 obj.push_back(Pair("height", block->nHeight));
1312 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1314 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1315 obj.push_back(Pair("branchlen", branchLen));
1317 std::string status;
1318 if (chainActive.Contains(block)) {
1319 // This block is part of the currently active chain.
1320 status = "active";
1321 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1322 // This block or one of its ancestors is invalid.
1323 status = "invalid";
1324 } else if (block->nChainTx == 0) {
1325 // This block cannot be connected because full block data for it or one of its parents is missing.
1326 status = "headers-only";
1327 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1328 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1329 status = "valid-fork";
1330 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1331 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1332 status = "valid-headers";
1333 } else {
1334 // No clue.
1335 status = "unknown";
1337 obj.push_back(Pair("status", status));
1339 res.push_back(obj);
1342 return res;
1345 UniValue mempoolInfoToJSON()
1347 UniValue ret(UniValue::VOBJ);
1348 ret.push_back(Pair("size", (int64_t) mempool.size()));
1349 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1350 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1351 size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1352 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1353 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1355 return ret;
1358 UniValue getmempoolinfo(const JSONRPCRequest& request)
1360 if (request.fHelp || request.params.size() != 0)
1361 throw std::runtime_error(
1362 "getmempoolinfo\n"
1363 "\nReturns details on the active state of the TX memory pool.\n"
1364 "\nResult:\n"
1365 "{\n"
1366 " \"size\": xxxxx, (numeric) Current tx count\n"
1367 " \"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"
1368 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1369 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1370 " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n"
1371 "}\n"
1372 "\nExamples:\n"
1373 + HelpExampleCli("getmempoolinfo", "")
1374 + HelpExampleRpc("getmempoolinfo", "")
1377 return mempoolInfoToJSON();
1380 UniValue preciousblock(const JSONRPCRequest& request)
1382 if (request.fHelp || request.params.size() != 1)
1383 throw std::runtime_error(
1384 "preciousblock \"blockhash\"\n"
1385 "\nTreats a block as if it were received before others with the same work.\n"
1386 "\nA later preciousblock call can override the effect of an earlier one.\n"
1387 "\nThe effects of preciousblock are not retained across restarts.\n"
1388 "\nArguments:\n"
1389 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1390 "\nResult:\n"
1391 "\nExamples:\n"
1392 + HelpExampleCli("preciousblock", "\"blockhash\"")
1393 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1396 std::string strHash = request.params[0].get_str();
1397 uint256 hash(uint256S(strHash));
1398 CBlockIndex* pblockindex;
1401 LOCK(cs_main);
1402 if (mapBlockIndex.count(hash) == 0)
1403 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1405 pblockindex = mapBlockIndex[hash];
1408 CValidationState state;
1409 PreciousBlock(state, Params(), pblockindex);
1411 if (!state.IsValid()) {
1412 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1415 return NullUniValue;
1418 UniValue invalidateblock(const JSONRPCRequest& request)
1420 if (request.fHelp || request.params.size() != 1)
1421 throw std::runtime_error(
1422 "invalidateblock \"blockhash\"\n"
1423 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1424 "\nArguments:\n"
1425 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1426 "\nResult:\n"
1427 "\nExamples:\n"
1428 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1429 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1432 std::string strHash = request.params[0].get_str();
1433 uint256 hash(uint256S(strHash));
1434 CValidationState state;
1437 LOCK(cs_main);
1438 if (mapBlockIndex.count(hash) == 0)
1439 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1441 CBlockIndex* pblockindex = mapBlockIndex[hash];
1442 InvalidateBlock(state, Params(), pblockindex);
1445 if (state.IsValid()) {
1446 ActivateBestChain(state, Params());
1449 if (!state.IsValid()) {
1450 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1453 return NullUniValue;
1456 UniValue reconsiderblock(const JSONRPCRequest& request)
1458 if (request.fHelp || request.params.size() != 1)
1459 throw std::runtime_error(
1460 "reconsiderblock \"blockhash\"\n"
1461 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1462 "This can be used to undo the effects of invalidateblock.\n"
1463 "\nArguments:\n"
1464 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1465 "\nResult:\n"
1466 "\nExamples:\n"
1467 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1468 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1471 std::string strHash = request.params[0].get_str();
1472 uint256 hash(uint256S(strHash));
1475 LOCK(cs_main);
1476 if (mapBlockIndex.count(hash) == 0)
1477 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1479 CBlockIndex* pblockindex = mapBlockIndex[hash];
1480 ResetBlockFailureFlags(pblockindex);
1483 CValidationState state;
1484 ActivateBestChain(state, Params());
1486 if (!state.IsValid()) {
1487 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1490 return NullUniValue;
1493 UniValue getchaintxstats(const JSONRPCRequest& request)
1495 if (request.fHelp || request.params.size() > 2)
1496 throw std::runtime_error(
1497 "getchaintxstats ( nblocks blockhash )\n"
1498 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1499 "\nArguments:\n"
1500 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1501 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1502 "\nResult:\n"
1503 "{\n"
1504 " \"time\": xxxxx, (numeric) The timestamp for the final block in the window in UNIX format.\n"
1505 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1506 " \"window_block_count\": xxxxx, (numeric) Size of the window in number of blocks.\n"
1507 " \"window_tx_count\": xxxxx, (numeric) The number of transactions in the window. Only returned if \"window_block_count\" is > 0.\n"
1508 " \"window_interval\": xxxxx, (numeric) The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0.\n"
1509 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0.\n"
1510 "}\n"
1511 "\nExamples:\n"
1512 + HelpExampleCli("getchaintxstats", "")
1513 + HelpExampleRpc("getchaintxstats", "2016")
1516 const CBlockIndex* pindex;
1517 int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1519 bool havehash = !request.params[1].isNull();
1520 uint256 hash;
1521 if (havehash) {
1522 hash = uint256S(request.params[1].get_str());
1526 LOCK(cs_main);
1527 if (havehash) {
1528 auto it = mapBlockIndex.find(hash);
1529 if (it == mapBlockIndex.end()) {
1530 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1532 pindex = it->second;
1533 if (!chainActive.Contains(pindex)) {
1534 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1536 } else {
1537 pindex = chainActive.Tip();
1541 assert(pindex != nullptr);
1543 if (request.params[0].isNull()) {
1544 blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1));
1545 } else {
1546 blockcount = request.params[0].get_int();
1548 if (blockcount < 0 || (blockcount > 0 && blockcount >= pindex->nHeight)) {
1549 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 0 and the block's height - 1");
1553 const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1554 int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1555 int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1557 UniValue ret(UniValue::VOBJ);
1558 ret.push_back(Pair("time", (int64_t)pindex->nTime));
1559 ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx));
1560 ret.push_back(Pair("window_block_count", blockcount));
1561 if (blockcount > 0) {
1562 ret.push_back(Pair("window_tx_count", nTxDiff));
1563 ret.push_back(Pair("window_interval", nTimeDiff));
1564 if (nTimeDiff > 0) {
1565 ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff));
1569 return ret;
1572 UniValue savemempool(const JSONRPCRequest& request)
1574 if (request.fHelp || request.params.size() != 0) {
1575 throw std::runtime_error(
1576 "savemempool\n"
1577 "\nDumps the mempool to disk.\n"
1578 "\nExamples:\n"
1579 + HelpExampleCli("savemempool", "")
1580 + HelpExampleRpc("savemempool", "")
1584 if (!DumpMempool()) {
1585 throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
1588 return NullUniValue;
1591 static const CRPCCommand commands[] =
1592 { // category name actor (function) argNames
1593 // --------------------- ------------------------ ----------------------- ----------
1594 { "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
1595 { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
1596 { "blockchain", "getbestblockhash", &getbestblockhash, {} },
1597 { "blockchain", "getblockcount", &getblockcount, {} },
1598 { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
1599 { "blockchain", "getblockhash", &getblockhash, {"height"} },
1600 { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
1601 { "blockchain", "getchaintips", &getchaintips, {} },
1602 { "blockchain", "getdifficulty", &getdifficulty, {} },
1603 { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
1604 { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
1605 { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
1606 { "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
1607 { "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
1608 { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
1609 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
1610 { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
1611 { "blockchain", "savemempool", &savemempool, {} },
1612 { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
1614 { "blockchain", "preciousblock", &preciousblock, {"blockhash"} },
1616 /* Not shown in help */
1617 { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
1618 { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
1619 { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
1620 { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
1621 { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
1624 void RegisterBlockchainRPCCommands(CRPCTable &t)
1626 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1627 t.appendCommand(commands[vcidx].name, &commands[vcidx]);