Merge #11748: [Tests] Adding unit tests for GetDifficulty in blockchain.cpp.
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blob426a6b39238bddbad93468cc6d6ff136eced65f6
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 /* Calculate the difficulty for a given block index,
51 * or the block index of the given chain.
53 double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex)
55 if (blockindex == nullptr)
57 if (chain.Tip() == nullptr)
58 return 1.0;
59 else
60 blockindex = chain.Tip();
63 int nShift = (blockindex->nBits >> 24) & 0xff;
64 double dDiff =
65 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
67 while (nShift < 29)
69 dDiff *= 256.0;
70 nShift++;
72 while (nShift > 29)
74 dDiff /= 256.0;
75 nShift--;
78 return dDiff;
81 double GetDifficulty(const CBlockIndex* blockindex)
83 return GetDifficulty(chainActive, blockindex);
86 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
88 AssertLockHeld(cs_main);
89 UniValue result(UniValue::VOBJ);
90 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
91 int confirmations = -1;
92 // Only report confirmations if the block is on the main chain
93 if (chainActive.Contains(blockindex))
94 confirmations = chainActive.Height() - blockindex->nHeight + 1;
95 result.push_back(Pair("confirmations", confirmations));
96 result.push_back(Pair("height", blockindex->nHeight));
97 result.push_back(Pair("version", blockindex->nVersion));
98 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
99 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
100 result.push_back(Pair("time", (int64_t)blockindex->nTime));
101 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
102 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
103 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
104 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
105 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
107 if (blockindex->pprev)
108 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
109 CBlockIndex *pnext = chainActive.Next(blockindex);
110 if (pnext)
111 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
112 return result;
115 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
117 AssertLockHeld(cs_main);
118 UniValue result(UniValue::VOBJ);
119 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
120 int confirmations = -1;
121 // Only report confirmations if the block is on the main chain
122 if (chainActive.Contains(blockindex))
123 confirmations = chainActive.Height() - blockindex->nHeight + 1;
124 result.push_back(Pair("confirmations", confirmations));
125 result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)));
126 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
127 result.push_back(Pair("weight", (int)::GetBlockWeight(block)));
128 result.push_back(Pair("height", blockindex->nHeight));
129 result.push_back(Pair("version", block.nVersion));
130 result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion)));
131 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
132 UniValue txs(UniValue::VARR);
133 for(const auto& tx : block.vtx)
135 if(txDetails)
137 UniValue objTx(UniValue::VOBJ);
138 TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags());
139 txs.push_back(objTx);
141 else
142 txs.push_back(tx->GetHash().GetHex());
144 result.push_back(Pair("tx", txs));
145 result.push_back(Pair("time", block.GetBlockTime()));
146 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
147 result.push_back(Pair("nonce", (uint64_t)block.nNonce));
148 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
149 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
150 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
152 if (blockindex->pprev)
153 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
154 CBlockIndex *pnext = chainActive.Next(blockindex);
155 if (pnext)
156 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
157 return result;
160 UniValue getblockcount(const JSONRPCRequest& request)
162 if (request.fHelp || request.params.size() != 0)
163 throw std::runtime_error(
164 "getblockcount\n"
165 "\nReturns the number of blocks in the longest blockchain.\n"
166 "\nResult:\n"
167 "n (numeric) The current block count\n"
168 "\nExamples:\n"
169 + HelpExampleCli("getblockcount", "")
170 + HelpExampleRpc("getblockcount", "")
173 LOCK(cs_main);
174 return chainActive.Height();
177 UniValue getbestblockhash(const JSONRPCRequest& request)
179 if (request.fHelp || request.params.size() != 0)
180 throw std::runtime_error(
181 "getbestblockhash\n"
182 "\nReturns the hash of the best (tip) block in the longest blockchain.\n"
183 "\nResult:\n"
184 "\"hex\" (string) the block hash hex encoded\n"
185 "\nExamples:\n"
186 + HelpExampleCli("getbestblockhash", "")
187 + HelpExampleRpc("getbestblockhash", "")
190 LOCK(cs_main);
191 return chainActive.Tip()->GetBlockHash().GetHex();
194 void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex)
196 if(pindex) {
197 std::lock_guard<std::mutex> lock(cs_blockchange);
198 latestblock.hash = pindex->GetBlockHash();
199 latestblock.height = pindex->nHeight;
201 cond_blockchange.notify_all();
204 UniValue waitfornewblock(const JSONRPCRequest& request)
206 if (request.fHelp || request.params.size() > 1)
207 throw std::runtime_error(
208 "waitfornewblock (timeout)\n"
209 "\nWaits for a specific new block and returns useful info about it.\n"
210 "\nReturns the current block on timeout or exit.\n"
211 "\nArguments:\n"
212 "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
213 "\nResult:\n"
214 "{ (json object)\n"
215 " \"hash\" : { (string) The blockhash\n"
216 " \"height\" : { (int) Block height\n"
217 "}\n"
218 "\nExamples:\n"
219 + HelpExampleCli("waitfornewblock", "1000")
220 + HelpExampleRpc("waitfornewblock", "1000")
222 int timeout = 0;
223 if (!request.params[0].isNull())
224 timeout = request.params[0].get_int();
226 CUpdatedBlock block;
228 std::unique_lock<std::mutex> lock(cs_blockchange);
229 block = latestblock;
230 if(timeout)
231 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
232 else
233 cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
234 block = latestblock;
236 UniValue ret(UniValue::VOBJ);
237 ret.push_back(Pair("hash", block.hash.GetHex()));
238 ret.push_back(Pair("height", block.height));
239 return ret;
242 UniValue waitforblock(const JSONRPCRequest& request)
244 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
245 throw std::runtime_error(
246 "waitforblock <blockhash> (timeout)\n"
247 "\nWaits for a specific new block and returns useful info about it.\n"
248 "\nReturns the current block on timeout or exit.\n"
249 "\nArguments:\n"
250 "1. \"blockhash\" (required, string) Block hash to wait for.\n"
251 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
252 "\nResult:\n"
253 "{ (json object)\n"
254 " \"hash\" : { (string) The blockhash\n"
255 " \"height\" : { (int) Block height\n"
256 "}\n"
257 "\nExamples:\n"
258 + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
259 + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
261 int timeout = 0;
263 uint256 hash = uint256S(request.params[0].get_str());
265 if (!request.params[1].isNull())
266 timeout = request.params[1].get_int();
268 CUpdatedBlock block;
270 std::unique_lock<std::mutex> lock(cs_blockchange);
271 if(timeout)
272 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();});
273 else
274 cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); });
275 block = latestblock;
278 UniValue ret(UniValue::VOBJ);
279 ret.push_back(Pair("hash", block.hash.GetHex()));
280 ret.push_back(Pair("height", block.height));
281 return ret;
284 UniValue waitforblockheight(const JSONRPCRequest& request)
286 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
287 throw std::runtime_error(
288 "waitforblockheight <height> (timeout)\n"
289 "\nWaits for (at least) block height and returns the height and hash\n"
290 "of the current tip.\n"
291 "\nReturns the current block on timeout or exit.\n"
292 "\nArguments:\n"
293 "1. height (required, int) Block height to wait for (int)\n"
294 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
295 "\nResult:\n"
296 "{ (json object)\n"
297 " \"hash\" : { (string) The blockhash\n"
298 " \"height\" : { (int) Block height\n"
299 "}\n"
300 "\nExamples:\n"
301 + HelpExampleCli("waitforblockheight", "\"100\", 1000")
302 + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
304 int timeout = 0;
306 int height = request.params[0].get_int();
308 if (!request.params[1].isNull())
309 timeout = request.params[1].get_int();
311 CUpdatedBlock block;
313 std::unique_lock<std::mutex> lock(cs_blockchange);
314 if(timeout)
315 cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();});
316 else
317 cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); });
318 block = latestblock;
320 UniValue ret(UniValue::VOBJ);
321 ret.push_back(Pair("hash", block.hash.GetHex()));
322 ret.push_back(Pair("height", block.height));
323 return ret;
326 UniValue getdifficulty(const JSONRPCRequest& request)
328 if (request.fHelp || request.params.size() != 0)
329 throw std::runtime_error(
330 "getdifficulty\n"
331 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
332 "\nResult:\n"
333 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
334 "\nExamples:\n"
335 + HelpExampleCli("getdifficulty", "")
336 + HelpExampleRpc("getdifficulty", "")
339 LOCK(cs_main);
340 return GetDifficulty();
343 std::string EntryDescriptionString()
345 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"
346 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
347 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
348 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
349 " \"height\" : n, (numeric) block height when transaction entered pool\n"
350 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
351 " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n"
352 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
353 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
354 " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n"
355 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
356 " \"wtxid\" : hash, (string) hash of serialized transaction, including witness data\n"
357 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
358 " \"transactionid\", (string) parent transaction id\n"
359 " ... ]\n";
362 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
364 AssertLockHeld(mempool.cs);
366 info.push_back(Pair("size", (int)e.GetTxSize()));
367 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
368 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
369 info.push_back(Pair("time", e.GetTime()));
370 info.push_back(Pair("height", (int)e.GetHeight()));
371 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
372 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
373 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
374 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
375 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
376 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
377 info.push_back(Pair("wtxid", mempool.vTxHashes[e.vTxHashesIdx].first.ToString()));
378 const CTransaction& tx = e.GetTx();
379 std::set<std::string> setDepends;
380 for (const CTxIn& txin : tx.vin)
382 if (mempool.exists(txin.prevout.hash))
383 setDepends.insert(txin.prevout.hash.ToString());
386 UniValue depends(UniValue::VARR);
387 for (const std::string& dep : setDepends)
389 depends.push_back(dep);
392 info.push_back(Pair("depends", depends));
395 UniValue mempoolToJSON(bool fVerbose)
397 if (fVerbose)
399 LOCK(mempool.cs);
400 UniValue o(UniValue::VOBJ);
401 for (const CTxMemPoolEntry& e : mempool.mapTx)
403 const uint256& hash = e.GetTx().GetHash();
404 UniValue info(UniValue::VOBJ);
405 entryToJSON(info, e);
406 o.push_back(Pair(hash.ToString(), info));
408 return o;
410 else
412 std::vector<uint256> vtxid;
413 mempool.queryHashes(vtxid);
415 UniValue a(UniValue::VARR);
416 for (const uint256& hash : vtxid)
417 a.push_back(hash.ToString());
419 return a;
423 UniValue getrawmempool(const JSONRPCRequest& request)
425 if (request.fHelp || request.params.size() > 1)
426 throw std::runtime_error(
427 "getrawmempool ( verbose )\n"
428 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
429 "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n"
430 "\nArguments:\n"
431 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
432 "\nResult: (for verbose = false):\n"
433 "[ (json array of string)\n"
434 " \"transactionid\" (string) The transaction id\n"
435 " ,...\n"
436 "]\n"
437 "\nResult: (for verbose = true):\n"
438 "{ (json object)\n"
439 " \"transactionid\" : { (json object)\n"
440 + EntryDescriptionString()
441 + " }, ...\n"
442 "}\n"
443 "\nExamples:\n"
444 + HelpExampleCli("getrawmempool", "true")
445 + HelpExampleRpc("getrawmempool", "true")
448 bool fVerbose = false;
449 if (!request.params[0].isNull())
450 fVerbose = request.params[0].get_bool();
452 return mempoolToJSON(fVerbose);
455 UniValue getmempoolancestors(const JSONRPCRequest& request)
457 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
458 throw std::runtime_error(
459 "getmempoolancestors txid (verbose)\n"
460 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
461 "\nArguments:\n"
462 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
463 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
464 "\nResult (for verbose=false):\n"
465 "[ (json array of strings)\n"
466 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
467 " ,...\n"
468 "]\n"
469 "\nResult (for verbose=true):\n"
470 "{ (json object)\n"
471 " \"transactionid\" : { (json object)\n"
472 + EntryDescriptionString()
473 + " }, ...\n"
474 "}\n"
475 "\nExamples:\n"
476 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
477 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
481 bool fVerbose = false;
482 if (!request.params[1].isNull())
483 fVerbose = request.params[1].get_bool();
485 uint256 hash = ParseHashV(request.params[0], "parameter 1");
487 LOCK(mempool.cs);
489 CTxMemPool::txiter it = mempool.mapTx.find(hash);
490 if (it == mempool.mapTx.end()) {
491 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
494 CTxMemPool::setEntries setAncestors;
495 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
496 std::string dummy;
497 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
499 if (!fVerbose) {
500 UniValue o(UniValue::VARR);
501 for (CTxMemPool::txiter ancestorIt : setAncestors) {
502 o.push_back(ancestorIt->GetTx().GetHash().ToString());
505 return o;
506 } else {
507 UniValue o(UniValue::VOBJ);
508 for (CTxMemPool::txiter ancestorIt : setAncestors) {
509 const CTxMemPoolEntry &e = *ancestorIt;
510 const uint256& _hash = e.GetTx().GetHash();
511 UniValue info(UniValue::VOBJ);
512 entryToJSON(info, e);
513 o.push_back(Pair(_hash.ToString(), info));
515 return o;
519 UniValue getmempooldescendants(const JSONRPCRequest& request)
521 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
522 throw std::runtime_error(
523 "getmempooldescendants txid (verbose)\n"
524 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
525 "\nArguments:\n"
526 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
527 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
528 "\nResult (for verbose=false):\n"
529 "[ (json array of strings)\n"
530 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
531 " ,...\n"
532 "]\n"
533 "\nResult (for verbose=true):\n"
534 "{ (json object)\n"
535 " \"transactionid\" : { (json object)\n"
536 + EntryDescriptionString()
537 + " }, ...\n"
538 "}\n"
539 "\nExamples:\n"
540 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
541 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
545 bool fVerbose = false;
546 if (!request.params[1].isNull())
547 fVerbose = request.params[1].get_bool();
549 uint256 hash = ParseHashV(request.params[0], "parameter 1");
551 LOCK(mempool.cs);
553 CTxMemPool::txiter it = mempool.mapTx.find(hash);
554 if (it == mempool.mapTx.end()) {
555 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
558 CTxMemPool::setEntries setDescendants;
559 mempool.CalculateDescendants(it, setDescendants);
560 // CTxMemPool::CalculateDescendants will include the given tx
561 setDescendants.erase(it);
563 if (!fVerbose) {
564 UniValue o(UniValue::VARR);
565 for (CTxMemPool::txiter descendantIt : setDescendants) {
566 o.push_back(descendantIt->GetTx().GetHash().ToString());
569 return o;
570 } else {
571 UniValue o(UniValue::VOBJ);
572 for (CTxMemPool::txiter descendantIt : setDescendants) {
573 const CTxMemPoolEntry &e = *descendantIt;
574 const uint256& _hash = e.GetTx().GetHash();
575 UniValue info(UniValue::VOBJ);
576 entryToJSON(info, e);
577 o.push_back(Pair(_hash.ToString(), info));
579 return o;
583 UniValue getmempoolentry(const JSONRPCRequest& request)
585 if (request.fHelp || request.params.size() != 1) {
586 throw std::runtime_error(
587 "getmempoolentry txid\n"
588 "\nReturns mempool data for given transaction\n"
589 "\nArguments:\n"
590 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
591 "\nResult:\n"
592 "{ (json object)\n"
593 + EntryDescriptionString()
594 + "}\n"
595 "\nExamples:\n"
596 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
597 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
601 uint256 hash = ParseHashV(request.params[0], "parameter 1");
603 LOCK(mempool.cs);
605 CTxMemPool::txiter it = mempool.mapTx.find(hash);
606 if (it == mempool.mapTx.end()) {
607 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
610 const CTxMemPoolEntry &e = *it;
611 UniValue info(UniValue::VOBJ);
612 entryToJSON(info, e);
613 return info;
616 UniValue getblockhash(const JSONRPCRequest& request)
618 if (request.fHelp || request.params.size() != 1)
619 throw std::runtime_error(
620 "getblockhash height\n"
621 "\nReturns hash of block in best-block-chain at height provided.\n"
622 "\nArguments:\n"
623 "1. height (numeric, required) The height index\n"
624 "\nResult:\n"
625 "\"hash\" (string) The block hash\n"
626 "\nExamples:\n"
627 + HelpExampleCli("getblockhash", "1000")
628 + HelpExampleRpc("getblockhash", "1000")
631 LOCK(cs_main);
633 int nHeight = request.params[0].get_int();
634 if (nHeight < 0 || nHeight > chainActive.Height())
635 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
637 CBlockIndex* pblockindex = chainActive[nHeight];
638 return pblockindex->GetBlockHash().GetHex();
641 UniValue getblockheader(const JSONRPCRequest& request)
643 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
644 throw std::runtime_error(
645 "getblockheader \"hash\" ( verbose )\n"
646 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
647 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
648 "\nArguments:\n"
649 "1. \"hash\" (string, required) The block hash\n"
650 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
651 "\nResult (for verbose = true):\n"
652 "{\n"
653 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
654 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
655 " \"height\" : n, (numeric) The block height or index\n"
656 " \"version\" : n, (numeric) The block version\n"
657 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
658 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
659 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
660 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
661 " \"nonce\" : n, (numeric) The nonce\n"
662 " \"bits\" : \"1d00ffff\", (string) The bits\n"
663 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
664 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
665 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
666 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
667 "}\n"
668 "\nResult (for verbose=false):\n"
669 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
670 "\nExamples:\n"
671 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
672 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
675 LOCK(cs_main);
677 std::string strHash = request.params[0].get_str();
678 uint256 hash(uint256S(strHash));
680 bool fVerbose = true;
681 if (!request.params[1].isNull())
682 fVerbose = request.params[1].get_bool();
684 if (mapBlockIndex.count(hash) == 0)
685 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
687 CBlockIndex* pblockindex = mapBlockIndex[hash];
689 if (!fVerbose)
691 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
692 ssBlock << pblockindex->GetBlockHeader();
693 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
694 return strHex;
697 return blockheaderToJSON(pblockindex);
700 UniValue getblock(const JSONRPCRequest& request)
702 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
703 throw std::runtime_error(
704 "getblock \"blockhash\" ( verbosity ) \n"
705 "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
706 "If verbosity is 1, returns an Object with information about block <hash>.\n"
707 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
708 "\nArguments:\n"
709 "1. \"blockhash\" (string, required) The block hash\n"
710 "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"
711 "\nResult (for verbosity = 0):\n"
712 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
713 "\nResult (for verbosity = 1):\n"
714 "{\n"
715 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
716 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
717 " \"size\" : n, (numeric) The block size\n"
718 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
719 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
720 " \"height\" : n, (numeric) The block height or index\n"
721 " \"version\" : n, (numeric) The block version\n"
722 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
723 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
724 " \"tx\" : [ (array of string) The transaction ids\n"
725 " \"transactionid\" (string) The transaction id\n"
726 " ,...\n"
727 " ],\n"
728 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
729 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
730 " \"nonce\" : n, (numeric) The nonce\n"
731 " \"bits\" : \"1d00ffff\", (string) The bits\n"
732 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
733 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
734 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
735 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
736 "}\n"
737 "\nResult (for verbosity = 2):\n"
738 "{\n"
739 " ..., Same output as verbosity = 1.\n"
740 " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
741 " ,...\n"
742 " ],\n"
743 " ,... Same output as verbosity = 1.\n"
744 "}\n"
745 "\nExamples:\n"
746 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
747 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
750 LOCK(cs_main);
752 std::string strHash = request.params[0].get_str();
753 uint256 hash(uint256S(strHash));
755 int verbosity = 1;
756 if (!request.params[1].isNull()) {
757 if(request.params[1].isNum())
758 verbosity = request.params[1].get_int();
759 else
760 verbosity = request.params[1].get_bool() ? 1 : 0;
763 if (mapBlockIndex.count(hash) == 0)
764 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
766 CBlock block;
767 CBlockIndex* pblockindex = mapBlockIndex[hash];
769 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
770 throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
772 if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
773 // Block not found on disk. This could be because we have the block
774 // header in our index but don't have the block (for example if a
775 // non-whitelisted node sends us an unrequested long chain of valid
776 // blocks, we add the headers to our index, but don't accept the
777 // block).
778 throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
780 if (verbosity <= 0)
782 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
783 ssBlock << block;
784 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
785 return strHex;
788 return blockToJSON(block, pblockindex, verbosity >= 2);
791 struct CCoinsStats
793 int nHeight;
794 uint256 hashBlock;
795 uint64_t nTransactions;
796 uint64_t nTransactionOutputs;
797 uint64_t nBogoSize;
798 uint256 hashSerialized;
799 uint64_t nDiskSize;
800 CAmount nTotalAmount;
802 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
805 static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
807 assert(!outputs.empty());
808 ss << hash;
809 ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase);
810 stats.nTransactions++;
811 for (const auto output : outputs) {
812 ss << VARINT(output.first + 1);
813 ss << output.second.out.scriptPubKey;
814 ss << VARINT(output.second.out.nValue);
815 stats.nTransactionOutputs++;
816 stats.nTotalAmount += output.second.out.nValue;
817 stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
818 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */;
820 ss << VARINT(0);
823 //! Calculate statistics about the unspent transaction output set
824 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
826 std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
827 assert(pcursor);
829 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
830 stats.hashBlock = pcursor->GetBestBlock();
832 LOCK(cs_main);
833 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
835 ss << stats.hashBlock;
836 uint256 prevkey;
837 std::map<uint32_t, Coin> outputs;
838 while (pcursor->Valid()) {
839 boost::this_thread::interruption_point();
840 COutPoint key;
841 Coin coin;
842 if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
843 if (!outputs.empty() && key.hash != prevkey) {
844 ApplyStats(stats, ss, prevkey, outputs);
845 outputs.clear();
847 prevkey = key.hash;
848 outputs[key.n] = std::move(coin);
849 } else {
850 return error("%s: unable to read value", __func__);
852 pcursor->Next();
854 if (!outputs.empty()) {
855 ApplyStats(stats, ss, prevkey, outputs);
857 stats.hashSerialized = ss.GetHash();
858 stats.nDiskSize = view->EstimateSize();
859 return true;
862 UniValue pruneblockchain(const JSONRPCRequest& request)
864 if (request.fHelp || request.params.size() != 1)
865 throw std::runtime_error(
866 "pruneblockchain\n"
867 "\nArguments:\n"
868 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
869 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
870 "\nResult:\n"
871 "n (numeric) Height of the last block pruned.\n"
872 "\nExamples:\n"
873 + HelpExampleCli("pruneblockchain", "1000")
874 + HelpExampleRpc("pruneblockchain", "1000"));
876 if (!fPruneMode)
877 throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
879 LOCK(cs_main);
881 int heightParam = request.params[0].get_int();
882 if (heightParam < 0)
883 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
885 // Height value more than a billion is too high to be a block height, and
886 // too low to be a block time (corresponds to timestamp from Sep 2001).
887 if (heightParam > 1000000000) {
888 // Add a 2 hour buffer to include blocks which might have had old timestamps
889 CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
890 if (!pindex) {
891 throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
893 heightParam = pindex->nHeight;
896 unsigned int height = (unsigned int) heightParam;
897 unsigned int chainHeight = (unsigned int) chainActive.Height();
898 if (chainHeight < Params().PruneAfterHeight())
899 throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
900 else if (height > chainHeight)
901 throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
902 else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
903 LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
904 height = chainHeight - MIN_BLOCKS_TO_KEEP;
907 PruneBlockFilesManual(height);
908 return uint64_t(height);
911 UniValue gettxoutsetinfo(const JSONRPCRequest& request)
913 if (request.fHelp || request.params.size() != 0)
914 throw std::runtime_error(
915 "gettxoutsetinfo\n"
916 "\nReturns statistics about the unspent transaction output set.\n"
917 "Note this call may take some time.\n"
918 "\nResult:\n"
919 "{\n"
920 " \"height\":n, (numeric) The current block height (index)\n"
921 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
922 " \"transactions\": n, (numeric) The number of transactions\n"
923 " \"txouts\": n, (numeric) The number of output transactions\n"
924 " \"bogosize\": n, (numeric) A meaningless metric for UTXO set size\n"
925 " \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
926 " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
927 " \"total_amount\": x.xxx (numeric) The total amount\n"
928 "}\n"
929 "\nExamples:\n"
930 + HelpExampleCli("gettxoutsetinfo", "")
931 + HelpExampleRpc("gettxoutsetinfo", "")
934 UniValue ret(UniValue::VOBJ);
936 CCoinsStats stats;
937 FlushStateToDisk();
938 if (GetUTXOStats(pcoinsdbview.get(), stats)) {
939 ret.push_back(Pair("height", (int64_t)stats.nHeight));
940 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
941 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
942 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
943 ret.push_back(Pair("bogosize", (int64_t)stats.nBogoSize));
944 ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
945 ret.push_back(Pair("disk_size", stats.nDiskSize));
946 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
947 } else {
948 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
950 return ret;
953 UniValue gettxout(const JSONRPCRequest& request)
955 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
956 throw std::runtime_error(
957 "gettxout \"txid\" n ( include_mempool )\n"
958 "\nReturns details about an unspent transaction output.\n"
959 "\nArguments:\n"
960 "1. \"txid\" (string, required) The transaction id\n"
961 "2. \"n\" (numeric, required) vout number\n"
962 "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true."
963 " Note that an unspent output that is spent in the mempool won't appear.\n"
964 "\nResult:\n"
965 "{\n"
966 " \"bestblock\" : \"hash\", (string) the block hash\n"
967 " \"confirmations\" : n, (numeric) The number of confirmations\n"
968 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
969 " \"scriptPubKey\" : { (json object)\n"
970 " \"asm\" : \"code\", (string) \n"
971 " \"hex\" : \"hex\", (string) \n"
972 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
973 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
974 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
975 " \"address\" (string) bitcoin address\n"
976 " ,...\n"
977 " ]\n"
978 " },\n"
979 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
980 "}\n"
982 "\nExamples:\n"
983 "\nGet unspent transactions\n"
984 + HelpExampleCli("listunspent", "") +
985 "\nView the details\n"
986 + HelpExampleCli("gettxout", "\"txid\" 1") +
987 "\nAs a json rpc call\n"
988 + HelpExampleRpc("gettxout", "\"txid\", 1")
991 LOCK(cs_main);
993 UniValue ret(UniValue::VOBJ);
995 std::string strHash = request.params[0].get_str();
996 uint256 hash(uint256S(strHash));
997 int n = request.params[1].get_int();
998 COutPoint out(hash, n);
999 bool fMempool = true;
1000 if (!request.params[2].isNull())
1001 fMempool = request.params[2].get_bool();
1003 Coin coin;
1004 if (fMempool) {
1005 LOCK(mempool.cs);
1006 CCoinsViewMemPool view(pcoinsTip.get(), mempool);
1007 if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
1008 return NullUniValue;
1010 } else {
1011 if (!pcoinsTip->GetCoin(out, coin)) {
1012 return NullUniValue;
1016 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
1017 CBlockIndex *pindex = it->second;
1018 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
1019 if (coin.nHeight == MEMPOOL_HEIGHT) {
1020 ret.push_back(Pair("confirmations", 0));
1021 } else {
1022 ret.push_back(Pair("confirmations", (int64_t)(pindex->nHeight - coin.nHeight + 1)));
1024 ret.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
1025 UniValue o(UniValue::VOBJ);
1026 ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
1027 ret.push_back(Pair("scriptPubKey", o));
1028 ret.push_back(Pair("coinbase", (bool)coin.fCoinBase));
1030 return ret;
1033 UniValue verifychain(const JSONRPCRequest& request)
1035 int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL);
1036 int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1037 if (request.fHelp || request.params.size() > 2)
1038 throw std::runtime_error(
1039 "verifychain ( checklevel nblocks )\n"
1040 "\nVerifies blockchain database.\n"
1041 "\nArguments:\n"
1042 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1043 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1044 "\nResult:\n"
1045 "true|false (boolean) Verified or not\n"
1046 "\nExamples:\n"
1047 + HelpExampleCli("verifychain", "")
1048 + HelpExampleRpc("verifychain", "")
1051 LOCK(cs_main);
1053 if (!request.params[0].isNull())
1054 nCheckLevel = request.params[0].get_int();
1055 if (!request.params[1].isNull())
1056 nCheckDepth = request.params[1].get_int();
1058 return CVerifyDB().VerifyDB(Params(), pcoinsTip.get(), nCheckLevel, nCheckDepth);
1061 /** Implementation of IsSuperMajority with better feedback */
1062 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1064 UniValue rv(UniValue::VOBJ);
1065 bool activated = false;
1066 switch(version)
1068 case 2:
1069 activated = pindex->nHeight >= consensusParams.BIP34Height;
1070 break;
1071 case 3:
1072 activated = pindex->nHeight >= consensusParams.BIP66Height;
1073 break;
1074 case 4:
1075 activated = pindex->nHeight >= consensusParams.BIP65Height;
1076 break;
1078 rv.push_back(Pair("status", activated));
1079 return rv;
1082 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1084 UniValue rv(UniValue::VOBJ);
1085 rv.push_back(Pair("id", name));
1086 rv.push_back(Pair("version", version));
1087 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1088 return rv;
1091 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1093 UniValue rv(UniValue::VOBJ);
1094 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1095 switch (thresholdState) {
1096 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1097 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1098 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1099 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1100 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1102 if (THRESHOLD_STARTED == thresholdState)
1104 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1106 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1107 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1108 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1109 if (THRESHOLD_STARTED == thresholdState)
1111 UniValue statsUV(UniValue::VOBJ);
1112 BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);
1113 statsUV.push_back(Pair("period", statsStruct.period));
1114 statsUV.push_back(Pair("threshold", statsStruct.threshold));
1115 statsUV.push_back(Pair("elapsed", statsStruct.elapsed));
1116 statsUV.push_back(Pair("count", statsStruct.count));
1117 statsUV.push_back(Pair("possible", statsStruct.possible));
1118 rv.push_back(Pair("statistics", statsUV));
1120 return rv;
1123 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1125 // Deployments with timeout value of 0 are hidden.
1126 // A timeout value of 0 guarantees a softfork will never be activated.
1127 // This is used when softfork codes are merged without specifying the deployment schedule.
1128 if (consensusParams.vDeployments[id].nTimeout > 0)
1129 bip9_softforks.push_back(Pair(VersionBitsDeploymentInfo[id].name, BIP9SoftForkDesc(consensusParams, id)));
1132 UniValue getblockchaininfo(const JSONRPCRequest& request)
1134 if (request.fHelp || request.params.size() != 0)
1135 throw std::runtime_error(
1136 "getblockchaininfo\n"
1137 "Returns an object containing various state info regarding blockchain processing.\n"
1138 "\nResult:\n"
1139 "{\n"
1140 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1141 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1142 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1143 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1144 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1145 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1146 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1147 " \"initialblockdownload\": xxxx, (bool) (debug information) estimate of whether this node is in Initial Block Download mode.\n"
1148 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1149 " \"size_on_disk\": xxxxxx, (numeric) the estimated size of the block and undo files on disk\n"
1150 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1151 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored (only present if pruning is enabled)\n"
1152 " \"automatic_pruning\": xx, (boolean) whether automatic pruning is enabled (only present if pruning is enabled)\n"
1153 " \"prune_target_size\": xxxxxx, (numeric) the target size used by pruning (only present if automatic pruning is enabled)\n"
1154 " \"softforks\": [ (array) status of softforks in progress\n"
1155 " {\n"
1156 " \"id\": \"xxxx\", (string) name of softfork\n"
1157 " \"version\": xx, (numeric) block version\n"
1158 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1159 " \"status\": xx, (boolean) true if threshold reached\n"
1160 " },\n"
1161 " }, ...\n"
1162 " ],\n"
1163 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1164 " \"xxxx\" : { (string) name of the softfork\n"
1165 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1166 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1167 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1168 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1169 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1170 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1171 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1172 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1173 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1174 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1175 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1176 " }\n"
1177 " }\n"
1178 " }\n"
1179 " \"warnings\" : \"...\", (string) any network and blockchain warnings.\n"
1180 "}\n"
1181 "\nExamples:\n"
1182 + HelpExampleCli("getblockchaininfo", "")
1183 + HelpExampleRpc("getblockchaininfo", "")
1186 LOCK(cs_main);
1188 UniValue obj(UniValue::VOBJ);
1189 obj.push_back(Pair("chain", Params().NetworkIDString()));
1190 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1191 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1192 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1193 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1194 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1195 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1196 obj.push_back(Pair("initialblockdownload", IsInitialBlockDownload()));
1197 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1198 obj.push_back(Pair("size_on_disk", CalculateCurrentUsage()));
1199 obj.push_back(Pair("pruned", fPruneMode));
1200 if (fPruneMode) {
1201 CBlockIndex* block = chainActive.Tip();
1202 assert(block);
1203 while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
1204 block = block->pprev;
1207 obj.push_back(Pair("pruneheight", block->nHeight));
1209 // if 0, execution bypasses the whole if block.
1210 bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1);
1211 obj.push_back(Pair("automatic_pruning", automatic_pruning));
1212 if (automatic_pruning) {
1213 obj.push_back(Pair("prune_target_size", nPruneTarget));
1217 const Consensus::Params& consensusParams = Params().GetConsensus();
1218 CBlockIndex* tip = chainActive.Tip();
1219 UniValue softforks(UniValue::VARR);
1220 UniValue bip9_softforks(UniValue::VOBJ);
1221 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1222 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1223 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1224 for (int pos = Consensus::DEPLOYMENT_CSV; pos != Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++pos) {
1225 BIP9SoftForkDescPushBack(bip9_softforks, consensusParams, static_cast<Consensus::DeploymentPos>(pos));
1227 obj.push_back(Pair("softforks", softforks));
1228 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1230 obj.push_back(Pair("warnings", GetWarnings("statusbar")));
1231 return obj;
1234 /** Comparison function for sorting the getchaintips heads. */
1235 struct CompareBlocksByHeight
1237 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1239 /* Make sure that unequal blocks with the same height do not compare
1240 equal. Use the pointers themselves to make a distinction. */
1242 if (a->nHeight != b->nHeight)
1243 return (a->nHeight > b->nHeight);
1245 return a < b;
1249 UniValue getchaintips(const JSONRPCRequest& request)
1251 if (request.fHelp || request.params.size() != 0)
1252 throw std::runtime_error(
1253 "getchaintips\n"
1254 "Return information about all known tips in the block tree,"
1255 " including the main chain as well as orphaned branches.\n"
1256 "\nResult:\n"
1257 "[\n"
1258 " {\n"
1259 " \"height\": xxxx, (numeric) height of the chain tip\n"
1260 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1261 " \"branchlen\": 0 (numeric) zero for main chain\n"
1262 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1263 " },\n"
1264 " {\n"
1265 " \"height\": xxxx,\n"
1266 " \"hash\": \"xxxx\",\n"
1267 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1268 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1269 " }\n"
1270 "]\n"
1271 "Possible values for status:\n"
1272 "1. \"invalid\" This branch contains at least one invalid block\n"
1273 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1274 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1275 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1276 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1277 "\nExamples:\n"
1278 + HelpExampleCli("getchaintips", "")
1279 + HelpExampleRpc("getchaintips", "")
1282 LOCK(cs_main);
1285 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1286 * Algorithm:
1287 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1288 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1289 * - add chainActive.Tip()
1291 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1292 std::set<const CBlockIndex*> setOrphans;
1293 std::set<const CBlockIndex*> setPrevs;
1295 for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
1297 if (!chainActive.Contains(item.second)) {
1298 setOrphans.insert(item.second);
1299 setPrevs.insert(item.second->pprev);
1303 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1305 if (setPrevs.erase(*it) == 0) {
1306 setTips.insert(*it);
1310 // Always report the currently active tip.
1311 setTips.insert(chainActive.Tip());
1313 /* Construct the output array. */
1314 UniValue res(UniValue::VARR);
1315 for (const CBlockIndex* block : setTips)
1317 UniValue obj(UniValue::VOBJ);
1318 obj.push_back(Pair("height", block->nHeight));
1319 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1321 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1322 obj.push_back(Pair("branchlen", branchLen));
1324 std::string status;
1325 if (chainActive.Contains(block)) {
1326 // This block is part of the currently active chain.
1327 status = "active";
1328 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1329 // This block or one of its ancestors is invalid.
1330 status = "invalid";
1331 } else if (block->nChainTx == 0) {
1332 // This block cannot be connected because full block data for it or one of its parents is missing.
1333 status = "headers-only";
1334 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1335 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1336 status = "valid-fork";
1337 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1338 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1339 status = "valid-headers";
1340 } else {
1341 // No clue.
1342 status = "unknown";
1344 obj.push_back(Pair("status", status));
1346 res.push_back(obj);
1349 return res;
1352 UniValue mempoolInfoToJSON()
1354 UniValue ret(UniValue::VOBJ);
1355 ret.push_back(Pair("size", (int64_t) mempool.size()));
1356 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1357 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1358 size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1359 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1360 ret.push_back(Pair("mempoolminfee", ValueFromAmount(std::max(mempool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK())));
1362 return ret;
1365 UniValue getmempoolinfo(const JSONRPCRequest& request)
1367 if (request.fHelp || request.params.size() != 0)
1368 throw std::runtime_error(
1369 "getmempoolinfo\n"
1370 "\nReturns details on the active state of the TX memory pool.\n"
1371 "\nResult:\n"
1372 "{\n"
1373 " \"size\": xxxxx, (numeric) Current tx count\n"
1374 " \"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"
1375 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1376 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1377 " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n"
1378 "}\n"
1379 "\nExamples:\n"
1380 + HelpExampleCli("getmempoolinfo", "")
1381 + HelpExampleRpc("getmempoolinfo", "")
1384 return mempoolInfoToJSON();
1387 UniValue preciousblock(const JSONRPCRequest& request)
1389 if (request.fHelp || request.params.size() != 1)
1390 throw std::runtime_error(
1391 "preciousblock \"blockhash\"\n"
1392 "\nTreats a block as if it were received before others with the same work.\n"
1393 "\nA later preciousblock call can override the effect of an earlier one.\n"
1394 "\nThe effects of preciousblock are not retained across restarts.\n"
1395 "\nArguments:\n"
1396 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1397 "\nResult:\n"
1398 "\nExamples:\n"
1399 + HelpExampleCli("preciousblock", "\"blockhash\"")
1400 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1403 std::string strHash = request.params[0].get_str();
1404 uint256 hash(uint256S(strHash));
1405 CBlockIndex* pblockindex;
1408 LOCK(cs_main);
1409 if (mapBlockIndex.count(hash) == 0)
1410 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1412 pblockindex = mapBlockIndex[hash];
1415 CValidationState state;
1416 PreciousBlock(state, Params(), pblockindex);
1418 if (!state.IsValid()) {
1419 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1422 return NullUniValue;
1425 UniValue invalidateblock(const JSONRPCRequest& request)
1427 if (request.fHelp || request.params.size() != 1)
1428 throw std::runtime_error(
1429 "invalidateblock \"blockhash\"\n"
1430 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1431 "\nArguments:\n"
1432 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1433 "\nResult:\n"
1434 "\nExamples:\n"
1435 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1436 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1439 std::string strHash = request.params[0].get_str();
1440 uint256 hash(uint256S(strHash));
1441 CValidationState state;
1444 LOCK(cs_main);
1445 if (mapBlockIndex.count(hash) == 0)
1446 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1448 CBlockIndex* pblockindex = mapBlockIndex[hash];
1449 InvalidateBlock(state, Params(), pblockindex);
1452 if (state.IsValid()) {
1453 ActivateBestChain(state, Params());
1456 if (!state.IsValid()) {
1457 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1460 return NullUniValue;
1463 UniValue reconsiderblock(const JSONRPCRequest& request)
1465 if (request.fHelp || request.params.size() != 1)
1466 throw std::runtime_error(
1467 "reconsiderblock \"blockhash\"\n"
1468 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1469 "This can be used to undo the effects of invalidateblock.\n"
1470 "\nArguments:\n"
1471 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1472 "\nResult:\n"
1473 "\nExamples:\n"
1474 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1475 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1478 std::string strHash = request.params[0].get_str();
1479 uint256 hash(uint256S(strHash));
1482 LOCK(cs_main);
1483 if (mapBlockIndex.count(hash) == 0)
1484 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1486 CBlockIndex* pblockindex = mapBlockIndex[hash];
1487 ResetBlockFailureFlags(pblockindex);
1490 CValidationState state;
1491 ActivateBestChain(state, Params());
1493 if (!state.IsValid()) {
1494 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1497 return NullUniValue;
1500 UniValue getchaintxstats(const JSONRPCRequest& request)
1502 if (request.fHelp || request.params.size() > 2)
1503 throw std::runtime_error(
1504 "getchaintxstats ( nblocks blockhash )\n"
1505 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1506 "\nArguments:\n"
1507 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1508 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1509 "\nResult:\n"
1510 "{\n"
1511 " \"time\": xxxxx, (numeric) The timestamp for the final block in the window in UNIX format.\n"
1512 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1513 " \"window_block_count\": xxxxx, (numeric) Size of the window in number of blocks.\n"
1514 " \"window_tx_count\": xxxxx, (numeric) The number of transactions in the window. Only returned if \"window_block_count\" is > 0.\n"
1515 " \"window_interval\": xxxxx, (numeric) The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0.\n"
1516 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0.\n"
1517 "}\n"
1518 "\nExamples:\n"
1519 + HelpExampleCli("getchaintxstats", "")
1520 + HelpExampleRpc("getchaintxstats", "2016")
1523 const CBlockIndex* pindex;
1524 int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
1526 bool havehash = !request.params[1].isNull();
1527 uint256 hash;
1528 if (havehash) {
1529 hash = uint256S(request.params[1].get_str());
1533 LOCK(cs_main);
1534 if (havehash) {
1535 auto it = mapBlockIndex.find(hash);
1536 if (it == mapBlockIndex.end()) {
1537 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1539 pindex = it->second;
1540 if (!chainActive.Contains(pindex)) {
1541 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
1543 } else {
1544 pindex = chainActive.Tip();
1548 assert(pindex != nullptr);
1550 if (request.params[0].isNull()) {
1551 blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1));
1552 } else {
1553 blockcount = request.params[0].get_int();
1555 if (blockcount < 0 || (blockcount > 0 && blockcount >= pindex->nHeight)) {
1556 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 0 and the block's height - 1");
1560 const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->nHeight - blockcount);
1561 int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
1562 int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
1564 UniValue ret(UniValue::VOBJ);
1565 ret.push_back(Pair("time", (int64_t)pindex->nTime));
1566 ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx));
1567 ret.push_back(Pair("window_block_count", blockcount));
1568 if (blockcount > 0) {
1569 ret.push_back(Pair("window_tx_count", nTxDiff));
1570 ret.push_back(Pair("window_interval", nTimeDiff));
1571 if (nTimeDiff > 0) {
1572 ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff));
1576 return ret;
1579 UniValue savemempool(const JSONRPCRequest& request)
1581 if (request.fHelp || request.params.size() != 0) {
1582 throw std::runtime_error(
1583 "savemempool\n"
1584 "\nDumps the mempool to disk.\n"
1585 "\nExamples:\n"
1586 + HelpExampleCli("savemempool", "")
1587 + HelpExampleRpc("savemempool", "")
1591 if (!DumpMempool()) {
1592 throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
1595 return NullUniValue;
1598 static const CRPCCommand commands[] =
1599 { // category name actor (function) argNames
1600 // --------------------- ------------------------ ----------------------- ----------
1601 { "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
1602 { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
1603 { "blockchain", "getbestblockhash", &getbestblockhash, {} },
1604 { "blockchain", "getblockcount", &getblockcount, {} },
1605 { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
1606 { "blockchain", "getblockhash", &getblockhash, {"height"} },
1607 { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
1608 { "blockchain", "getchaintips", &getchaintips, {} },
1609 { "blockchain", "getdifficulty", &getdifficulty, {} },
1610 { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
1611 { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
1612 { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
1613 { "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
1614 { "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
1615 { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
1616 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
1617 { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
1618 { "blockchain", "savemempool", &savemempool, {} },
1619 { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
1621 { "blockchain", "preciousblock", &preciousblock, {"blockhash"} },
1623 /* Not shown in help */
1624 { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
1625 { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
1626 { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
1627 { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
1628 { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
1631 void RegisterBlockchainRPCCommands(CRPCTable &t)
1633 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1634 t.appendCommand(commands[vcidx].name, &commands[vcidx]);