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