util: Work around (virtual) memory exhaustion on 32-bit w/ glibc
[bitcoinplatinum.git] / src / rpc / blockchain.cpp
blob96254a8cb9c17f059f3b40ed58669326594531fa
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 "amount.h"
7 #include "chain.h"
8 #include "chainparams.h"
9 #include "checkpoints.h"
10 #include "coins.h"
11 #include "consensus/validation.h"
12 #include "validation.h"
13 #include "policy/policy.h"
14 #include "primitives/transaction.h"
15 #include "rpc/server.h"
16 #include "streams.h"
17 #include "sync.h"
18 #include "txmempool.h"
19 #include "util.h"
20 #include "utilstrencodings.h"
21 #include "hash.h"
23 #include <stdint.h>
25 #include <univalue.h>
27 #include <boost/thread/thread.hpp> // boost::thread::interrupt
29 #include <mutex>
30 #include <condition_variable>
32 struct CUpdatedBlock
34 uint256 hash;
35 int height;
38 static std::mutex cs_blockchange;
39 static std::condition_variable cond_blockchange;
40 static CUpdatedBlock latestblock;
42 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
43 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
45 /**
46 * Get the difficulty of the net wrt to the given block index, or the chain tip if
47 * not provided.
49 * @return A floating point number that is a multiple of the main net minimum
50 * difficulty (4295032833 hashes).
52 double GetDifficulty(const CBlockIndex* blockindex)
54 if (blockindex == NULL)
56 if (chainActive.Tip() == NULL)
57 return 1.0;
58 else
59 blockindex = chainActive.Tip();
62 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 UniValue blockheaderToJSON(const CBlockIndex* blockindex)
83 UniValue result(UniValue::VOBJ);
84 result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
85 int confirmations = -1;
86 // Only report confirmations if the block is on the main chain
87 if (chainActive.Contains(blockindex))
88 confirmations = chainActive.Height() - blockindex->nHeight + 1;
89 result.push_back(Pair("confirmations", confirmations));
90 result.push_back(Pair("height", blockindex->nHeight));
91 result.push_back(Pair("version", blockindex->nVersion));
92 result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion)));
93 result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
94 result.push_back(Pair("time", (int64_t)blockindex->nTime));
95 result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
96 result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
97 result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
98 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
99 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
101 if (blockindex->pprev)
102 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
103 CBlockIndex *pnext = chainActive.Next(blockindex);
104 if (pnext)
105 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
106 return result;
109 UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
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 TxToJSON(*tx, uint256(), objTx);
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.size() > 0)
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.size() > 1)
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.size() > 1)
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 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
350 " \"transactionid\", (string) parent transaction id\n"
351 " ... ]\n";
354 void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
356 AssertLockHeld(mempool.cs);
358 info.push_back(Pair("size", (int)e.GetTxSize()));
359 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
360 info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
361 info.push_back(Pair("time", e.GetTime()));
362 info.push_back(Pair("height", (int)e.GetHeight()));
363 info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
364 info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
365 info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
366 info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
367 info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
368 info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
369 const CTransaction& tx = e.GetTx();
370 std::set<std::string> setDepends;
371 BOOST_FOREACH(const CTxIn& txin, tx.vin)
373 if (mempool.exists(txin.prevout.hash))
374 setDepends.insert(txin.prevout.hash.ToString());
377 UniValue depends(UniValue::VARR);
378 BOOST_FOREACH(const std::string& dep, setDepends)
380 depends.push_back(dep);
383 info.push_back(Pair("depends", depends));
386 UniValue mempoolToJSON(bool fVerbose = false)
388 if (fVerbose)
390 LOCK(mempool.cs);
391 UniValue o(UniValue::VOBJ);
392 BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx)
394 const uint256& hash = e.GetTx().GetHash();
395 UniValue info(UniValue::VOBJ);
396 entryToJSON(info, e);
397 o.push_back(Pair(hash.ToString(), info));
399 return o;
401 else
403 std::vector<uint256> vtxid;
404 mempool.queryHashes(vtxid);
406 UniValue a(UniValue::VARR);
407 BOOST_FOREACH(const uint256& hash, vtxid)
408 a.push_back(hash.ToString());
410 return a;
414 UniValue getrawmempool(const JSONRPCRequest& request)
416 if (request.fHelp || request.params.size() > 1)
417 throw std::runtime_error(
418 "getrawmempool ( verbose )\n"
419 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
420 "\nArguments:\n"
421 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
422 "\nResult: (for verbose = false):\n"
423 "[ (json array of string)\n"
424 " \"transactionid\" (string) The transaction id\n"
425 " ,...\n"
426 "]\n"
427 "\nResult: (for verbose = true):\n"
428 "{ (json object)\n"
429 " \"transactionid\" : { (json object)\n"
430 + EntryDescriptionString()
431 + " }, ...\n"
432 "}\n"
433 "\nExamples:\n"
434 + HelpExampleCli("getrawmempool", "true")
435 + HelpExampleRpc("getrawmempool", "true")
438 bool fVerbose = false;
439 if (request.params.size() > 0)
440 fVerbose = request.params[0].get_bool();
442 return mempoolToJSON(fVerbose);
445 UniValue getmempoolancestors(const JSONRPCRequest& request)
447 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
448 throw std::runtime_error(
449 "getmempoolancestors txid (verbose)\n"
450 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
451 "\nArguments:\n"
452 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
453 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
454 "\nResult (for verbose=false):\n"
455 "[ (json array of strings)\n"
456 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
457 " ,...\n"
458 "]\n"
459 "\nResult (for verbose=true):\n"
460 "{ (json object)\n"
461 " \"transactionid\" : { (json object)\n"
462 + EntryDescriptionString()
463 + " }, ...\n"
464 "}\n"
465 "\nExamples:\n"
466 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
467 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
471 bool fVerbose = false;
472 if (request.params.size() > 1)
473 fVerbose = request.params[1].get_bool();
475 uint256 hash = ParseHashV(request.params[0], "parameter 1");
477 LOCK(mempool.cs);
479 CTxMemPool::txiter it = mempool.mapTx.find(hash);
480 if (it == mempool.mapTx.end()) {
481 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
484 CTxMemPool::setEntries setAncestors;
485 uint64_t noLimit = std::numeric_limits<uint64_t>::max();
486 std::string dummy;
487 mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
489 if (!fVerbose) {
490 UniValue o(UniValue::VARR);
491 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
492 o.push_back(ancestorIt->GetTx().GetHash().ToString());
495 return o;
496 } else {
497 UniValue o(UniValue::VOBJ);
498 BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
499 const CTxMemPoolEntry &e = *ancestorIt;
500 const uint256& _hash = e.GetTx().GetHash();
501 UniValue info(UniValue::VOBJ);
502 entryToJSON(info, e);
503 o.push_back(Pair(_hash.ToString(), info));
505 return o;
509 UniValue getmempooldescendants(const JSONRPCRequest& request)
511 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
512 throw std::runtime_error(
513 "getmempooldescendants txid (verbose)\n"
514 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
515 "\nArguments:\n"
516 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
517 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
518 "\nResult (for verbose=false):\n"
519 "[ (json array of strings)\n"
520 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
521 " ,...\n"
522 "]\n"
523 "\nResult (for verbose=true):\n"
524 "{ (json object)\n"
525 " \"transactionid\" : { (json object)\n"
526 + EntryDescriptionString()
527 + " }, ...\n"
528 "}\n"
529 "\nExamples:\n"
530 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
531 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
535 bool fVerbose = false;
536 if (request.params.size() > 1)
537 fVerbose = request.params[1].get_bool();
539 uint256 hash = ParseHashV(request.params[0], "parameter 1");
541 LOCK(mempool.cs);
543 CTxMemPool::txiter it = mempool.mapTx.find(hash);
544 if (it == mempool.mapTx.end()) {
545 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
548 CTxMemPool::setEntries setDescendants;
549 mempool.CalculateDescendants(it, setDescendants);
550 // CTxMemPool::CalculateDescendants will include the given tx
551 setDescendants.erase(it);
553 if (!fVerbose) {
554 UniValue o(UniValue::VARR);
555 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
556 o.push_back(descendantIt->GetTx().GetHash().ToString());
559 return o;
560 } else {
561 UniValue o(UniValue::VOBJ);
562 BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
563 const CTxMemPoolEntry &e = *descendantIt;
564 const uint256& _hash = e.GetTx().GetHash();
565 UniValue info(UniValue::VOBJ);
566 entryToJSON(info, e);
567 o.push_back(Pair(_hash.ToString(), info));
569 return o;
573 UniValue getmempoolentry(const JSONRPCRequest& request)
575 if (request.fHelp || request.params.size() != 1) {
576 throw std::runtime_error(
577 "getmempoolentry txid\n"
578 "\nReturns mempool data for given transaction\n"
579 "\nArguments:\n"
580 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
581 "\nResult:\n"
582 "{ (json object)\n"
583 + EntryDescriptionString()
584 + "}\n"
585 "\nExamples:\n"
586 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
587 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
591 uint256 hash = ParseHashV(request.params[0], "parameter 1");
593 LOCK(mempool.cs);
595 CTxMemPool::txiter it = mempool.mapTx.find(hash);
596 if (it == mempool.mapTx.end()) {
597 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
600 const CTxMemPoolEntry &e = *it;
601 UniValue info(UniValue::VOBJ);
602 entryToJSON(info, e);
603 return info;
606 UniValue getblockhash(const JSONRPCRequest& request)
608 if (request.fHelp || request.params.size() != 1)
609 throw std::runtime_error(
610 "getblockhash height\n"
611 "\nReturns hash of block in best-block-chain at height provided.\n"
612 "\nArguments:\n"
613 "1. height (numeric, required) The height index\n"
614 "\nResult:\n"
615 "\"hash\" (string) The block hash\n"
616 "\nExamples:\n"
617 + HelpExampleCli("getblockhash", "1000")
618 + HelpExampleRpc("getblockhash", "1000")
621 LOCK(cs_main);
623 int nHeight = request.params[0].get_int();
624 if (nHeight < 0 || nHeight > chainActive.Height())
625 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
627 CBlockIndex* pblockindex = chainActive[nHeight];
628 return pblockindex->GetBlockHash().GetHex();
631 UniValue getblockheader(const JSONRPCRequest& request)
633 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
634 throw std::runtime_error(
635 "getblockheader \"hash\" ( verbose )\n"
636 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
637 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
638 "\nArguments:\n"
639 "1. \"hash\" (string, required) The block hash\n"
640 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
641 "\nResult (for verbose = true):\n"
642 "{\n"
643 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
644 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
645 " \"height\" : n, (numeric) The block height or index\n"
646 " \"version\" : n, (numeric) The block version\n"
647 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
648 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
649 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
650 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
651 " \"nonce\" : n, (numeric) The nonce\n"
652 " \"bits\" : \"1d00ffff\", (string) The bits\n"
653 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
654 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
655 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
656 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
657 "}\n"
658 "\nResult (for verbose=false):\n"
659 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
660 "\nExamples:\n"
661 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
662 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
665 LOCK(cs_main);
667 std::string strHash = request.params[0].get_str();
668 uint256 hash(uint256S(strHash));
670 bool fVerbose = true;
671 if (request.params.size() > 1)
672 fVerbose = request.params[1].get_bool();
674 if (mapBlockIndex.count(hash) == 0)
675 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
677 CBlockIndex* pblockindex = mapBlockIndex[hash];
679 if (!fVerbose)
681 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
682 ssBlock << pblockindex->GetBlockHeader();
683 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
684 return strHex;
687 return blockheaderToJSON(pblockindex);
690 UniValue getblock(const JSONRPCRequest& request)
692 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
693 throw std::runtime_error(
694 "getblock \"blockhash\" ( verbose )\n"
695 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
696 "If verbose is true, returns an Object with information about block <hash>.\n"
697 "\nArguments:\n"
698 "1. \"blockhash\" (string, required) The block hash\n"
699 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
700 "\nResult (for verbose = true):\n"
701 "{\n"
702 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
703 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
704 " \"size\" : n, (numeric) The block size\n"
705 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
706 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
707 " \"height\" : n, (numeric) The block height or index\n"
708 " \"version\" : n, (numeric) The block version\n"
709 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
710 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
711 " \"tx\" : [ (array of string) The transaction ids\n"
712 " \"transactionid\" (string) The transaction id\n"
713 " ,...\n"
714 " ],\n"
715 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
716 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
717 " \"nonce\" : n, (numeric) The nonce\n"
718 " \"bits\" : \"1d00ffff\", (string) The bits\n"
719 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
720 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
721 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
722 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
723 "}\n"
724 "\nResult (for verbose=false):\n"
725 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
726 "\nExamples:\n"
727 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
728 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
731 LOCK(cs_main);
733 std::string strHash = request.params[0].get_str();
734 uint256 hash(uint256S(strHash));
736 bool fVerbose = true;
737 if (request.params.size() > 1)
738 fVerbose = request.params[1].get_bool();
740 if (mapBlockIndex.count(hash) == 0)
741 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
743 CBlock block;
744 CBlockIndex* pblockindex = mapBlockIndex[hash];
746 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
747 throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
749 if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
750 // Block not found on disk. This could be because we have the block
751 // header in our index but don't have the block (for example if a
752 // non-whitelisted node sends us an unrequested long chain of valid
753 // blocks, we add the headers to our index, but don't accept the
754 // block).
755 throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
757 if (!fVerbose)
759 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
760 ssBlock << block;
761 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
762 return strHex;
765 return blockToJSON(block, pblockindex);
768 struct CCoinsStats
770 int nHeight;
771 uint256 hashBlock;
772 uint64_t nTransactions;
773 uint64_t nTransactionOutputs;
774 uint64_t nSerializedSize;
775 uint256 hashSerialized;
776 CAmount nTotalAmount;
778 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {}
781 //! Calculate statistics about the unspent transaction output set
782 static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
784 std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
786 CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
787 stats.hashBlock = pcursor->GetBestBlock();
789 LOCK(cs_main);
790 stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
792 ss << stats.hashBlock;
793 CAmount nTotalAmount = 0;
794 while (pcursor->Valid()) {
795 boost::this_thread::interruption_point();
796 uint256 key;
797 CCoins coins;
798 if (pcursor->GetKey(key) && pcursor->GetValue(coins)) {
799 stats.nTransactions++;
800 ss << key;
801 for (unsigned int i=0; i<coins.vout.size(); i++) {
802 const CTxOut &out = coins.vout[i];
803 if (!out.IsNull()) {
804 stats.nTransactionOutputs++;
805 ss << VARINT(i+1);
806 ss << out;
807 nTotalAmount += out.nValue;
810 stats.nSerializedSize += 32 + pcursor->GetValueSize();
811 ss << VARINT(0);
812 } else {
813 return error("%s: unable to read value", __func__);
815 pcursor->Next();
817 stats.hashSerialized = ss.GetHash();
818 stats.nTotalAmount = nTotalAmount;
819 return true;
822 UniValue pruneblockchain(const JSONRPCRequest& request)
824 if (request.fHelp || request.params.size() != 1)
825 throw std::runtime_error(
826 "pruneblockchain\n"
827 "\nArguments:\n"
828 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
829 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
830 "\nResult:\n"
831 "n (numeric) Height of the last block pruned.\n"
832 "\nExamples:\n"
833 + HelpExampleCli("pruneblockchain", "1000")
834 + HelpExampleRpc("pruneblockchain", "1000"));
836 if (!fPruneMode)
837 throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
839 LOCK(cs_main);
841 int heightParam = request.params[0].get_int();
842 if (heightParam < 0)
843 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
845 // Height value more than a billion is too high to be a block height, and
846 // too low to be a block time (corresponds to timestamp from Sep 2001).
847 if (heightParam > 1000000000) {
848 // Add a 2 hour buffer to include blocks which might have had old timestamps
849 CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
850 if (!pindex) {
851 throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
853 heightParam = pindex->nHeight;
856 unsigned int height = (unsigned int) heightParam;
857 unsigned int chainHeight = (unsigned int) chainActive.Height();
858 if (chainHeight < Params().PruneAfterHeight())
859 throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
860 else if (height > chainHeight)
861 throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
862 else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
863 LogPrint("rpc", "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
864 height = chainHeight - MIN_BLOCKS_TO_KEEP;
867 PruneBlockFilesManual(height);
868 return uint64_t(height);
871 UniValue gettxoutsetinfo(const JSONRPCRequest& request)
873 if (request.fHelp || request.params.size() != 0)
874 throw std::runtime_error(
875 "gettxoutsetinfo\n"
876 "\nReturns statistics about the unspent transaction output set.\n"
877 "Note this call may take some time.\n"
878 "\nResult:\n"
879 "{\n"
880 " \"height\":n, (numeric) The current block height (index)\n"
881 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
882 " \"transactions\": n, (numeric) The number of transactions\n"
883 " \"txouts\": n, (numeric) The number of output transactions\n"
884 " \"bytes_serialized\": n, (numeric) The serialized size\n"
885 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
886 " \"total_amount\": x.xxx (numeric) The total amount\n"
887 "}\n"
888 "\nExamples:\n"
889 + HelpExampleCli("gettxoutsetinfo", "")
890 + HelpExampleRpc("gettxoutsetinfo", "")
893 UniValue ret(UniValue::VOBJ);
895 CCoinsStats stats;
896 FlushStateToDisk();
897 if (GetUTXOStats(pcoinsTip, stats)) {
898 ret.push_back(Pair("height", (int64_t)stats.nHeight));
899 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
900 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
901 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
902 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
903 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
904 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
905 } else {
906 throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
908 return ret;
911 UniValue gettxout(const JSONRPCRequest& request)
913 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
914 throw std::runtime_error(
915 "gettxout \"txid\" n ( include_mempool )\n"
916 "\nReturns details about an unspent transaction output.\n"
917 "\nArguments:\n"
918 "1. \"txid\" (string, required) The transaction id\n"
919 "2. n (numeric, required) vout number\n"
920 "3. include_mempool (boolean, optional) Whether to include the mempool\n"
921 "\nResult:\n"
922 "{\n"
923 " \"bestblock\" : \"hash\", (string) the block hash\n"
924 " \"confirmations\" : n, (numeric) The number of confirmations\n"
925 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
926 " \"scriptPubKey\" : { (json object)\n"
927 " \"asm\" : \"code\", (string) \n"
928 " \"hex\" : \"hex\", (string) \n"
929 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
930 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
931 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
932 " \"address\" (string) bitcoin address\n"
933 " ,...\n"
934 " ]\n"
935 " },\n"
936 " \"version\" : n, (numeric) The version\n"
937 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
938 "}\n"
940 "\nExamples:\n"
941 "\nGet unspent transactions\n"
942 + HelpExampleCli("listunspent", "") +
943 "\nView the details\n"
944 + HelpExampleCli("gettxout", "\"txid\" 1") +
945 "\nAs a json rpc call\n"
946 + HelpExampleRpc("gettxout", "\"txid\", 1")
949 LOCK(cs_main);
951 UniValue ret(UniValue::VOBJ);
953 std::string strHash = request.params[0].get_str();
954 uint256 hash(uint256S(strHash));
955 int n = request.params[1].get_int();
956 bool fMempool = true;
957 if (request.params.size() > 2)
958 fMempool = request.params[2].get_bool();
960 CCoins coins;
961 if (fMempool) {
962 LOCK(mempool.cs);
963 CCoinsViewMemPool view(pcoinsTip, mempool);
964 if (!view.GetCoins(hash, coins))
965 return NullUniValue;
966 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
967 } else {
968 if (!pcoinsTip->GetCoins(hash, coins))
969 return NullUniValue;
971 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
972 return NullUniValue;
974 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
975 CBlockIndex *pindex = it->second;
976 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
977 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
978 ret.push_back(Pair("confirmations", 0));
979 else
980 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
981 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
982 UniValue o(UniValue::VOBJ);
983 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
984 ret.push_back(Pair("scriptPubKey", o));
985 ret.push_back(Pair("version", coins.nVersion));
986 ret.push_back(Pair("coinbase", coins.fCoinBase));
988 return ret;
991 UniValue verifychain(const JSONRPCRequest& request)
993 int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
994 int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
995 if (request.fHelp || request.params.size() > 2)
996 throw std::runtime_error(
997 "verifychain ( checklevel nblocks )\n"
998 "\nVerifies blockchain database.\n"
999 "\nArguments:\n"
1000 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
1001 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
1002 "\nResult:\n"
1003 "true|false (boolean) Verified or not\n"
1004 "\nExamples:\n"
1005 + HelpExampleCli("verifychain", "")
1006 + HelpExampleRpc("verifychain", "")
1009 LOCK(cs_main);
1011 if (request.params.size() > 0)
1012 nCheckLevel = request.params[0].get_int();
1013 if (request.params.size() > 1)
1014 nCheckDepth = request.params[1].get_int();
1016 return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
1019 /** Implementation of IsSuperMajority with better feedback */
1020 static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1022 UniValue rv(UniValue::VOBJ);
1023 bool activated = false;
1024 switch(version)
1026 case 2:
1027 activated = pindex->nHeight >= consensusParams.BIP34Height;
1028 break;
1029 case 3:
1030 activated = pindex->nHeight >= consensusParams.BIP66Height;
1031 break;
1032 case 4:
1033 activated = pindex->nHeight >= consensusParams.BIP65Height;
1034 break;
1036 rv.push_back(Pair("status", activated));
1037 return rv;
1040 static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
1042 UniValue rv(UniValue::VOBJ);
1043 rv.push_back(Pair("id", name));
1044 rv.push_back(Pair("version", version));
1045 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
1046 return rv;
1049 static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1051 UniValue rv(UniValue::VOBJ);
1052 const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
1053 switch (thresholdState) {
1054 case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break;
1055 case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break;
1056 case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break;
1057 case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break;
1058 case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break;
1060 if (THRESHOLD_STARTED == thresholdState)
1062 rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit));
1064 rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime));
1065 rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout));
1066 rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id)));
1067 return rv;
1070 void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
1072 // Deployments with timeout value of 0 are hidden.
1073 // A timeout value of 0 guarantees a softfork will never be activated.
1074 // This is used when softfork codes are merged without specifying the deployment schedule.
1075 if (consensusParams.vDeployments[id].nTimeout > 0)
1076 bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id)));
1079 UniValue getblockchaininfo(const JSONRPCRequest& request)
1081 if (request.fHelp || request.params.size() != 0)
1082 throw std::runtime_error(
1083 "getblockchaininfo\n"
1084 "Returns an object containing various state info regarding blockchain processing.\n"
1085 "\nResult:\n"
1086 "{\n"
1087 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1088 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1089 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1090 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1091 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1092 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1093 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1094 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1095 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1096 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1097 " \"softforks\": [ (array) status of softforks in progress\n"
1098 " {\n"
1099 " \"id\": \"xxxx\", (string) name of softfork\n"
1100 " \"version\": xx, (numeric) block version\n"
1101 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1102 " \"status\": xx, (boolean) true if threshold reached\n"
1103 " },\n"
1104 " }, ...\n"
1105 " ],\n"
1106 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1107 " \"xxxx\" : { (string) name of the softfork\n"
1108 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1109 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1110 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1111 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1112 " \"since\": xx (numeric) height of the first block to which the status applies\n"
1113 " }\n"
1114 " }\n"
1115 "}\n"
1116 "\nExamples:\n"
1117 + HelpExampleCli("getblockchaininfo", "")
1118 + HelpExampleRpc("getblockchaininfo", "")
1121 LOCK(cs_main);
1123 UniValue obj(UniValue::VOBJ);
1124 obj.push_back(Pair("chain", Params().NetworkIDString()));
1125 obj.push_back(Pair("blocks", (int)chainActive.Height()));
1126 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
1127 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
1128 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
1129 obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
1130 obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
1131 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1132 obj.push_back(Pair("pruned", fPruneMode));
1134 const Consensus::Params& consensusParams = Params().GetConsensus();
1135 CBlockIndex* tip = chainActive.Tip();
1136 UniValue softforks(UniValue::VARR);
1137 UniValue bip9_softforks(UniValue::VOBJ);
1138 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
1139 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
1140 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
1141 BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
1142 BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT);
1143 obj.push_back(Pair("softforks", softforks));
1144 obj.push_back(Pair("bip9_softforks", bip9_softforks));
1146 if (fPruneMode)
1148 CBlockIndex *block = chainActive.Tip();
1149 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
1150 block = block->pprev;
1152 obj.push_back(Pair("pruneheight", block->nHeight));
1154 return obj;
1157 /** Comparison function for sorting the getchaintips heads. */
1158 struct CompareBlocksByHeight
1160 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
1162 /* Make sure that unequal blocks with the same height do not compare
1163 equal. Use the pointers themselves to make a distinction. */
1165 if (a->nHeight != b->nHeight)
1166 return (a->nHeight > b->nHeight);
1168 return a < b;
1172 UniValue getchaintips(const JSONRPCRequest& request)
1174 if (request.fHelp || request.params.size() != 0)
1175 throw std::runtime_error(
1176 "getchaintips\n"
1177 "Return information about all known tips in the block tree,"
1178 " including the main chain as well as orphaned branches.\n"
1179 "\nResult:\n"
1180 "[\n"
1181 " {\n"
1182 " \"height\": xxxx, (numeric) height of the chain tip\n"
1183 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1184 " \"branchlen\": 0 (numeric) zero for main chain\n"
1185 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1186 " },\n"
1187 " {\n"
1188 " \"height\": xxxx,\n"
1189 " \"hash\": \"xxxx\",\n"
1190 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1191 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1192 " }\n"
1193 "]\n"
1194 "Possible values for status:\n"
1195 "1. \"invalid\" This branch contains at least one invalid block\n"
1196 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1197 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1198 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1199 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1200 "\nExamples:\n"
1201 + HelpExampleCli("getchaintips", "")
1202 + HelpExampleRpc("getchaintips", "")
1205 LOCK(cs_main);
1208 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1209 * Algorithm:
1210 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1211 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1212 * - add chainActive.Tip()
1214 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1215 std::set<const CBlockIndex*> setOrphans;
1216 std::set<const CBlockIndex*> setPrevs;
1218 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
1220 if (!chainActive.Contains(item.second)) {
1221 setOrphans.insert(item.second);
1222 setPrevs.insert(item.second->pprev);
1226 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
1228 if (setPrevs.erase(*it) == 0) {
1229 setTips.insert(*it);
1233 // Always report the currently active tip.
1234 setTips.insert(chainActive.Tip());
1236 /* Construct the output array. */
1237 UniValue res(UniValue::VARR);
1238 BOOST_FOREACH(const CBlockIndex* block, setTips)
1240 UniValue obj(UniValue::VOBJ);
1241 obj.push_back(Pair("height", block->nHeight));
1242 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
1244 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
1245 obj.push_back(Pair("branchlen", branchLen));
1247 std::string status;
1248 if (chainActive.Contains(block)) {
1249 // This block is part of the currently active chain.
1250 status = "active";
1251 } else if (block->nStatus & BLOCK_FAILED_MASK) {
1252 // This block or one of its ancestors is invalid.
1253 status = "invalid";
1254 } else if (block->nChainTx == 0) {
1255 // This block cannot be connected because full block data for it or one of its parents is missing.
1256 status = "headers-only";
1257 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
1258 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1259 status = "valid-fork";
1260 } else if (block->IsValid(BLOCK_VALID_TREE)) {
1261 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1262 status = "valid-headers";
1263 } else {
1264 // No clue.
1265 status = "unknown";
1267 obj.push_back(Pair("status", status));
1269 res.push_back(obj);
1272 return res;
1275 UniValue mempoolInfoToJSON()
1277 UniValue ret(UniValue::VOBJ);
1278 ret.push_back(Pair("size", (int64_t) mempool.size()));
1279 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
1280 ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
1281 size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1282 ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
1283 ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
1285 return ret;
1288 UniValue getmempoolinfo(const JSONRPCRequest& request)
1290 if (request.fHelp || request.params.size() != 0)
1291 throw std::runtime_error(
1292 "getmempoolinfo\n"
1293 "\nReturns details on the active state of the TX memory pool.\n"
1294 "\nResult:\n"
1295 "{\n"
1296 " \"size\": xxxxx, (numeric) Current tx count\n"
1297 " \"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"
1298 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1299 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1300 " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n"
1301 "}\n"
1302 "\nExamples:\n"
1303 + HelpExampleCli("getmempoolinfo", "")
1304 + HelpExampleRpc("getmempoolinfo", "")
1307 return mempoolInfoToJSON();
1310 UniValue preciousblock(const JSONRPCRequest& request)
1312 if (request.fHelp || request.params.size() != 1)
1313 throw std::runtime_error(
1314 "preciousblock \"blockhash\"\n"
1315 "\nTreats a block as if it were received before others with the same work.\n"
1316 "\nA later preciousblock call can override the effect of an earlier one.\n"
1317 "\nThe effects of preciousblock are not retained across restarts.\n"
1318 "\nArguments:\n"
1319 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1320 "\nResult:\n"
1321 "\nExamples:\n"
1322 + HelpExampleCli("preciousblock", "\"blockhash\"")
1323 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1326 std::string strHash = request.params[0].get_str();
1327 uint256 hash(uint256S(strHash));
1328 CBlockIndex* pblockindex;
1331 LOCK(cs_main);
1332 if (mapBlockIndex.count(hash) == 0)
1333 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1335 pblockindex = mapBlockIndex[hash];
1338 CValidationState state;
1339 PreciousBlock(state, Params(), pblockindex);
1341 if (!state.IsValid()) {
1342 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1345 return NullUniValue;
1348 UniValue invalidateblock(const JSONRPCRequest& request)
1350 if (request.fHelp || request.params.size() != 1)
1351 throw std::runtime_error(
1352 "invalidateblock \"blockhash\"\n"
1353 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1354 "\nArguments:\n"
1355 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1356 "\nResult:\n"
1357 "\nExamples:\n"
1358 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1359 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1362 std::string strHash = request.params[0].get_str();
1363 uint256 hash(uint256S(strHash));
1364 CValidationState state;
1367 LOCK(cs_main);
1368 if (mapBlockIndex.count(hash) == 0)
1369 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1371 CBlockIndex* pblockindex = mapBlockIndex[hash];
1372 InvalidateBlock(state, Params(), pblockindex);
1375 if (state.IsValid()) {
1376 ActivateBestChain(state, Params());
1379 if (!state.IsValid()) {
1380 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1383 return NullUniValue;
1386 UniValue reconsiderblock(const JSONRPCRequest& request)
1388 if (request.fHelp || request.params.size() != 1)
1389 throw std::runtime_error(
1390 "reconsiderblock \"blockhash\"\n"
1391 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1392 "This can be used to undo the effects of invalidateblock.\n"
1393 "\nArguments:\n"
1394 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1395 "\nResult:\n"
1396 "\nExamples:\n"
1397 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1398 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1401 std::string strHash = request.params[0].get_str();
1402 uint256 hash(uint256S(strHash));
1405 LOCK(cs_main);
1406 if (mapBlockIndex.count(hash) == 0)
1407 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1409 CBlockIndex* pblockindex = mapBlockIndex[hash];
1410 ResetBlockFailureFlags(pblockindex);
1413 CValidationState state;
1414 ActivateBestChain(state, Params());
1416 if (!state.IsValid()) {
1417 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
1420 return NullUniValue;
1423 static const CRPCCommand commands[] =
1424 { // category name actor (function) okSafe argNames
1425 // --------------------- ------------------------ ----------------------- ------ ----------
1426 { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
1427 { "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
1428 { "blockchain", "getblockcount", &getblockcount, true, {} },
1429 { "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} },
1430 { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
1431 { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
1432 { "blockchain", "getchaintips", &getchaintips, true, {} },
1433 { "blockchain", "getdifficulty", &getdifficulty, true, {} },
1434 { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
1435 { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
1436 { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
1437 { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
1438 { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
1439 { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
1440 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
1441 { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
1442 { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },
1444 { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
1446 /* Not shown in help */
1447 { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
1448 { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
1449 { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
1450 { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
1451 { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
1454 void RegisterBlockchainRPCCommands(CRPCTable &t)
1456 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1457 t.appendCommand(commands[vcidx].name, &commands[vcidx]);