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"
10 #include "chainparams.h"
11 #include "checkpoints.h"
13 #include "consensus/validation.h"
14 #include "validation.h"
16 #include "policy/feerate.h"
17 #include "policy/policy.h"
18 #include "primitives/transaction.h"
19 #include "rpc/server.h"
23 #include "txmempool.h"
25 #include "utilstrencodings.h"
32 #include <boost/thread/thread.hpp> // boost::thread::interrupt
35 #include <condition_variable>
43 static std::mutex cs_blockchange
;
44 static std::condition_variable cond_blockchange
;
45 static CUpdatedBlock latestblock
;
47 extern void TxToJSON(const CTransaction
& tx
, const uint256 hashBlock
, UniValue
& entry
);
49 double GetDifficulty(const CBlockIndex
* blockindex
)
51 if (blockindex
== nullptr)
53 if (chainActive
.Tip() == nullptr)
56 blockindex
= chainActive
.Tip();
59 int nShift
= (blockindex
->nBits
>> 24) & 0xff;
62 (double)0x0000ffff / (double)(blockindex
->nBits
& 0x00ffffff);
78 UniValue
blockheaderToJSON(const CBlockIndex
* blockindex
)
80 UniValue
result(UniValue::VOBJ
);
81 result
.push_back(Pair("hash", blockindex
->GetBlockHash().GetHex()));
82 int confirmations
= -1;
83 // Only report confirmations if the block is on the main chain
84 if (chainActive
.Contains(blockindex
))
85 confirmations
= chainActive
.Height() - blockindex
->nHeight
+ 1;
86 result
.push_back(Pair("confirmations", confirmations
));
87 result
.push_back(Pair("height", blockindex
->nHeight
));
88 result
.push_back(Pair("version", blockindex
->nVersion
));
89 result
.push_back(Pair("versionHex", strprintf("%08x", blockindex
->nVersion
)));
90 result
.push_back(Pair("merkleroot", blockindex
->hashMerkleRoot
.GetHex()));
91 result
.push_back(Pair("time", (int64_t)blockindex
->nTime
));
92 result
.push_back(Pair("mediantime", (int64_t)blockindex
->GetMedianTimePast()));
93 result
.push_back(Pair("nonce", (uint64_t)blockindex
->nNonce
));
94 result
.push_back(Pair("bits", strprintf("%08x", blockindex
->nBits
)));
95 result
.push_back(Pair("difficulty", GetDifficulty(blockindex
)));
96 result
.push_back(Pair("chainwork", blockindex
->nChainWork
.GetHex()));
98 if (blockindex
->pprev
)
99 result
.push_back(Pair("previousblockhash", blockindex
->pprev
->GetBlockHash().GetHex()));
100 CBlockIndex
*pnext
= chainActive
.Next(blockindex
);
102 result
.push_back(Pair("nextblockhash", pnext
->GetBlockHash().GetHex()));
106 UniValue
blockToJSON(const CBlock
& block
, const CBlockIndex
* blockindex
, bool txDetails
)
108 UniValue
result(UniValue::VOBJ
);
109 result
.push_back(Pair("hash", blockindex
->GetBlockHash().GetHex()));
110 int confirmations
= -1;
111 // Only report confirmations if the block is on the main chain
112 if (chainActive
.Contains(blockindex
))
113 confirmations
= chainActive
.Height() - blockindex
->nHeight
+ 1;
114 result
.push_back(Pair("confirmations", confirmations
));
115 result
.push_back(Pair("strippedsize", (int)::GetSerializeSize(block
, SER_NETWORK
, PROTOCOL_VERSION
| SERIALIZE_TRANSACTION_NO_WITNESS
)));
116 result
.push_back(Pair("size", (int)::GetSerializeSize(block
, SER_NETWORK
, PROTOCOL_VERSION
)));
117 result
.push_back(Pair("weight", (int)::GetBlockWeight(block
)));
118 result
.push_back(Pair("height", blockindex
->nHeight
));
119 result
.push_back(Pair("version", block
.nVersion
));
120 result
.push_back(Pair("versionHex", strprintf("%08x", block
.nVersion
)));
121 result
.push_back(Pair("merkleroot", block
.hashMerkleRoot
.GetHex()));
122 UniValue
txs(UniValue::VARR
);
123 for(const auto& tx
: block
.vtx
)
127 UniValue
objTx(UniValue::VOBJ
);
128 TxToUniv(*tx
, uint256(), objTx
, true, RPCSerializationFlags());
129 txs
.push_back(objTx
);
132 txs
.push_back(tx
->GetHash().GetHex());
134 result
.push_back(Pair("tx", txs
));
135 result
.push_back(Pair("time", block
.GetBlockTime()));
136 result
.push_back(Pair("mediantime", (int64_t)blockindex
->GetMedianTimePast()));
137 result
.push_back(Pair("nonce", (uint64_t)block
.nNonce
));
138 result
.push_back(Pair("bits", strprintf("%08x", block
.nBits
)));
139 result
.push_back(Pair("difficulty", GetDifficulty(blockindex
)));
140 result
.push_back(Pair("chainwork", blockindex
->nChainWork
.GetHex()));
142 if (blockindex
->pprev
)
143 result
.push_back(Pair("previousblockhash", blockindex
->pprev
->GetBlockHash().GetHex()));
144 CBlockIndex
*pnext
= chainActive
.Next(blockindex
);
146 result
.push_back(Pair("nextblockhash", pnext
->GetBlockHash().GetHex()));
150 UniValue
getblockcount(const JSONRPCRequest
& request
)
152 if (request
.fHelp
|| request
.params
.size() != 0)
153 throw std::runtime_error(
155 "\nReturns the number of blocks in the longest blockchain.\n"
157 "n (numeric) The current block count\n"
159 + HelpExampleCli("getblockcount", "")
160 + HelpExampleRpc("getblockcount", "")
164 return chainActive
.Height();
167 UniValue
getbestblockhash(const JSONRPCRequest
& request
)
169 if (request
.fHelp
|| request
.params
.size() != 0)
170 throw std::runtime_error(
172 "\nReturns the hash of the best (tip) block in the longest blockchain.\n"
174 "\"hex\" (string) the block hash hex encoded\n"
176 + HelpExampleCli("getbestblockhash", "")
177 + HelpExampleRpc("getbestblockhash", "")
181 return chainActive
.Tip()->GetBlockHash().GetHex();
184 void RPCNotifyBlockChange(bool ibd
, const CBlockIndex
* pindex
)
187 std::lock_guard
<std::mutex
> lock(cs_blockchange
);
188 latestblock
.hash
= pindex
->GetBlockHash();
189 latestblock
.height
= pindex
->nHeight
;
191 cond_blockchange
.notify_all();
194 UniValue
waitfornewblock(const JSONRPCRequest
& request
)
196 if (request
.fHelp
|| request
.params
.size() > 1)
197 throw std::runtime_error(
198 "waitfornewblock (timeout)\n"
199 "\nWaits for a specific new block and returns useful info about it.\n"
200 "\nReturns the current block on timeout or exit.\n"
202 "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
205 " \"hash\" : { (string) The blockhash\n"
206 " \"height\" : { (int) Block height\n"
209 + HelpExampleCli("waitfornewblock", "1000")
210 + HelpExampleRpc("waitfornewblock", "1000")
213 if (!request
.params
[0].isNull())
214 timeout
= request
.params
[0].get_int();
218 std::unique_lock
<std::mutex
> lock(cs_blockchange
);
221 cond_blockchange
.wait_for(lock
, std::chrono::milliseconds(timeout
), [&block
]{return latestblock
.height
!= block
.height
|| latestblock
.hash
!= block
.hash
|| !IsRPCRunning(); });
223 cond_blockchange
.wait(lock
, [&block
]{return latestblock
.height
!= block
.height
|| latestblock
.hash
!= block
.hash
|| !IsRPCRunning(); });
226 UniValue
ret(UniValue::VOBJ
);
227 ret
.push_back(Pair("hash", block
.hash
.GetHex()));
228 ret
.push_back(Pair("height", block
.height
));
232 UniValue
waitforblock(const JSONRPCRequest
& request
)
234 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
235 throw std::runtime_error(
236 "waitforblock <blockhash> (timeout)\n"
237 "\nWaits for a specific new block and returns useful info about it.\n"
238 "\nReturns the current block on timeout or exit.\n"
240 "1. \"blockhash\" (required, string) Block hash to wait for.\n"
241 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
244 " \"hash\" : { (string) The blockhash\n"
245 " \"height\" : { (int) Block height\n"
248 + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
249 + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
253 uint256 hash
= uint256S(request
.params
[0].get_str());
255 if (!request
.params
[1].isNull())
256 timeout
= request
.params
[1].get_int();
260 std::unique_lock
<std::mutex
> lock(cs_blockchange
);
262 cond_blockchange
.wait_for(lock
, std::chrono::milliseconds(timeout
), [&hash
]{return latestblock
.hash
== hash
|| !IsRPCRunning();});
264 cond_blockchange
.wait(lock
, [&hash
]{return latestblock
.hash
== hash
|| !IsRPCRunning(); });
268 UniValue
ret(UniValue::VOBJ
);
269 ret
.push_back(Pair("hash", block
.hash
.GetHex()));
270 ret
.push_back(Pair("height", block
.height
));
274 UniValue
waitforblockheight(const JSONRPCRequest
& request
)
276 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
277 throw std::runtime_error(
278 "waitforblockheight <height> (timeout)\n"
279 "\nWaits for (at least) block height and returns the height and hash\n"
280 "of the current tip.\n"
281 "\nReturns the current block on timeout or exit.\n"
283 "1. height (required, int) Block height to wait for (int)\n"
284 "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
287 " \"hash\" : { (string) The blockhash\n"
288 " \"height\" : { (int) Block height\n"
291 + HelpExampleCli("waitforblockheight", "\"100\", 1000")
292 + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
296 int height
= request
.params
[0].get_int();
298 if (!request
.params
[1].isNull())
299 timeout
= request
.params
[1].get_int();
303 std::unique_lock
<std::mutex
> lock(cs_blockchange
);
305 cond_blockchange
.wait_for(lock
, std::chrono::milliseconds(timeout
), [&height
]{return latestblock
.height
>= height
|| !IsRPCRunning();});
307 cond_blockchange
.wait(lock
, [&height
]{return latestblock
.height
>= height
|| !IsRPCRunning(); });
310 UniValue
ret(UniValue::VOBJ
);
311 ret
.push_back(Pair("hash", block
.hash
.GetHex()));
312 ret
.push_back(Pair("height", block
.height
));
316 UniValue
getdifficulty(const JSONRPCRequest
& request
)
318 if (request
.fHelp
|| request
.params
.size() != 0)
319 throw std::runtime_error(
321 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
323 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
325 + HelpExampleCli("getdifficulty", "")
326 + HelpExampleRpc("getdifficulty", "")
330 return GetDifficulty();
333 std::string
EntryDescriptionString()
335 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"
336 " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT
+ "\n"
337 " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
338 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
339 " \"height\" : n, (numeric) block height when transaction entered pool\n"
340 " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
341 " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n"
342 " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
343 " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
344 " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n"
345 " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
346 " \"wtxid\" : hash, (string) hash of serialized transaction, including witness data\n"
347 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
348 " \"transactionid\", (string) parent transaction id\n"
352 void entryToJSON(UniValue
&info
, const CTxMemPoolEntry
&e
)
354 AssertLockHeld(mempool
.cs
);
356 info
.push_back(Pair("size", (int)e
.GetTxSize()));
357 info
.push_back(Pair("fee", ValueFromAmount(e
.GetFee())));
358 info
.push_back(Pair("modifiedfee", ValueFromAmount(e
.GetModifiedFee())));
359 info
.push_back(Pair("time", e
.GetTime()));
360 info
.push_back(Pair("height", (int)e
.GetHeight()));
361 info
.push_back(Pair("descendantcount", e
.GetCountWithDescendants()));
362 info
.push_back(Pair("descendantsize", e
.GetSizeWithDescendants()));
363 info
.push_back(Pair("descendantfees", e
.GetModFeesWithDescendants()));
364 info
.push_back(Pair("ancestorcount", e
.GetCountWithAncestors()));
365 info
.push_back(Pair("ancestorsize", e
.GetSizeWithAncestors()));
366 info
.push_back(Pair("ancestorfees", e
.GetModFeesWithAncestors()));
367 info
.push_back(Pair("wtxid", mempool
.vTxHashes
[e
.vTxHashesIdx
].first
.ToString()));
368 const CTransaction
& tx
= e
.GetTx();
369 std::set
<std::string
> setDepends
;
370 for (const CTxIn
& txin
: tx
.vin
)
372 if (mempool
.exists(txin
.prevout
.hash
))
373 setDepends
.insert(txin
.prevout
.hash
.ToString());
376 UniValue
depends(UniValue::VARR
);
377 for (const std::string
& dep
: setDepends
)
379 depends
.push_back(dep
);
382 info
.push_back(Pair("depends", depends
));
385 UniValue
mempoolToJSON(bool fVerbose
)
390 UniValue
o(UniValue::VOBJ
);
391 for (const CTxMemPoolEntry
& e
: mempool
.mapTx
)
393 const uint256
& hash
= e
.GetTx().GetHash();
394 UniValue
info(UniValue::VOBJ
);
395 entryToJSON(info
, e
);
396 o
.push_back(Pair(hash
.ToString(), info
));
402 std::vector
<uint256
> vtxid
;
403 mempool
.queryHashes(vtxid
);
405 UniValue
a(UniValue::VARR
);
406 for (const uint256
& hash
: vtxid
)
407 a
.push_back(hash
.ToString());
413 UniValue
getrawmempool(const JSONRPCRequest
& request
)
415 if (request
.fHelp
|| request
.params
.size() > 1)
416 throw std::runtime_error(
417 "getrawmempool ( verbose )\n"
418 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
419 "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\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"
427 "\nResult: (for verbose = true):\n"
429 " \"transactionid\" : { (json object)\n"
430 + EntryDescriptionString()
434 + HelpExampleCli("getrawmempool", "true")
435 + HelpExampleRpc("getrawmempool", "true")
438 bool fVerbose
= false;
439 if (!request
.params
[0].isNull())
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"
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"
459 "\nResult (for verbose=true):\n"
461 " \"transactionid\" : { (json object)\n"
462 + EntryDescriptionString()
466 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
467 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
471 bool fVerbose
= false;
472 if (!request
.params
[1].isNull())
473 fVerbose
= request
.params
[1].get_bool();
475 uint256 hash
= ParseHashV(request
.params
[0], "parameter 1");
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();
487 mempool
.CalculateMemPoolAncestors(*it
, setAncestors
, noLimit
, noLimit
, noLimit
, noLimit
, dummy
, false);
490 UniValue
o(UniValue::VARR
);
491 for (CTxMemPool::txiter ancestorIt
: setAncestors
) {
492 o
.push_back(ancestorIt
->GetTx().GetHash().ToString());
497 UniValue
o(UniValue::VOBJ
);
498 for (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
));
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"
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"
523 "\nResult (for verbose=true):\n"
525 " \"transactionid\" : { (json object)\n"
526 + EntryDescriptionString()
530 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
531 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
535 bool fVerbose
= false;
536 if (!request
.params
[1].isNull())
537 fVerbose
= request
.params
[1].get_bool();
539 uint256 hash
= ParseHashV(request
.params
[0], "parameter 1");
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
);
554 UniValue
o(UniValue::VARR
);
555 for (CTxMemPool::txiter descendantIt
: setDescendants
) {
556 o
.push_back(descendantIt
->GetTx().GetHash().ToString());
561 UniValue
o(UniValue::VOBJ
);
562 for (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
));
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"
580 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
583 + EntryDescriptionString()
586 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
587 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
591 uint256 hash
= ParseHashV(request
.params
[0], "parameter 1");
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
);
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"
613 "1. height (numeric, required) The height index\n"
615 "\"hash\" (string) The block hash\n"
617 + HelpExampleCli("getblockhash", "1000")
618 + HelpExampleRpc("getblockhash", "1000")
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"
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"
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"
658 "\nResult (for verbose=false):\n"
659 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
661 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
662 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
667 std::string strHash
= request
.params
[0].get_str();
668 uint256
hash(uint256S(strHash
));
670 bool fVerbose
= true;
671 if (!request
.params
[1].isNull())
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
];
681 CDataStream
ssBlock(SER_NETWORK
, PROTOCOL_VERSION
);
682 ssBlock
<< pblockindex
->GetBlockHeader();
683 std::string strHex
= HexStr(ssBlock
.begin(), ssBlock
.end());
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\" ( verbosity ) \n"
695 "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
696 "If verbosity is 1, returns an Object with information about block <hash>.\n"
697 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
699 "1. \"blockhash\" (string, required) The block hash\n"
700 "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"
701 "\nResult (for verbosity = 0):\n"
702 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
703 "\nResult (for verbosity = 1):\n"
705 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
706 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
707 " \"size\" : n, (numeric) The block size\n"
708 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
709 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
710 " \"height\" : n, (numeric) The block height or index\n"
711 " \"version\" : n, (numeric) The block version\n"
712 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
713 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
714 " \"tx\" : [ (array of string) The transaction ids\n"
715 " \"transactionid\" (string) The transaction id\n"
718 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
719 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
720 " \"nonce\" : n, (numeric) The nonce\n"
721 " \"bits\" : \"1d00ffff\", (string) The bits\n"
722 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
723 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
724 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
725 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
727 "\nResult (for verbosity = 2):\n"
729 " ..., Same output as verbosity = 1.\n"
730 " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
733 " ,... Same output as verbosity = 1.\n"
736 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
737 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
742 std::string strHash
= request
.params
[0].get_str();
743 uint256
hash(uint256S(strHash
));
746 if (!request
.params
[1].isNull()) {
747 if(request
.params
[1].isNum())
748 verbosity
= request
.params
[1].get_int();
750 verbosity
= request
.params
[1].get_bool() ? 1 : 0;
753 if (mapBlockIndex
.count(hash
) == 0)
754 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
757 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
759 if (fHavePruned
&& !(pblockindex
->nStatus
& BLOCK_HAVE_DATA
) && pblockindex
->nTx
> 0)
760 throw JSONRPCError(RPC_MISC_ERROR
, "Block not available (pruned data)");
762 if (!ReadBlockFromDisk(block
, pblockindex
, Params().GetConsensus()))
763 // Block not found on disk. This could be because we have the block
764 // header in our index but don't have the block (for example if a
765 // non-whitelisted node sends us an unrequested long chain of valid
766 // blocks, we add the headers to our index, but don't accept the
768 throw JSONRPCError(RPC_MISC_ERROR
, "Block not found on disk");
772 CDataStream
ssBlock(SER_NETWORK
, PROTOCOL_VERSION
| RPCSerializationFlags());
774 std::string strHex
= HexStr(ssBlock
.begin(), ssBlock
.end());
778 return blockToJSON(block
, pblockindex
, verbosity
>= 2);
785 uint64_t nTransactions
;
786 uint64_t nTransactionOutputs
;
788 uint256 hashSerialized
;
790 CAmount nTotalAmount
;
792 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
795 static void ApplyStats(CCoinsStats
&stats
, CHashWriter
& ss
, const uint256
& hash
, const std::map
<uint32_t, Coin
>& outputs
)
797 assert(!outputs
.empty());
799 ss
<< VARINT(outputs
.begin()->second
.nHeight
* 2 + outputs
.begin()->second
.fCoinBase
);
800 stats
.nTransactions
++;
801 for (const auto output
: outputs
) {
802 ss
<< VARINT(output
.first
+ 1);
803 ss
<< output
.second
.out
.scriptPubKey
;
804 ss
<< VARINT(output
.second
.out
.nValue
);
805 stats
.nTransactionOutputs
++;
806 stats
.nTotalAmount
+= output
.second
.out
.nValue
;
807 stats
.nBogoSize
+= 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
808 2 /* scriptPubKey len */ + output
.second
.out
.scriptPubKey
.size() /* scriptPubKey */;
813 //! Calculate statistics about the unspent transaction output set
814 static bool GetUTXOStats(CCoinsView
*view
, CCoinsStats
&stats
)
816 std::unique_ptr
<CCoinsViewCursor
> pcursor(view
->Cursor());
819 CHashWriter
ss(SER_GETHASH
, PROTOCOL_VERSION
);
820 stats
.hashBlock
= pcursor
->GetBestBlock();
823 stats
.nHeight
= mapBlockIndex
.find(stats
.hashBlock
)->second
->nHeight
;
825 ss
<< stats
.hashBlock
;
827 std::map
<uint32_t, Coin
> outputs
;
828 while (pcursor
->Valid()) {
829 boost::this_thread::interruption_point();
832 if (pcursor
->GetKey(key
) && pcursor
->GetValue(coin
)) {
833 if (!outputs
.empty() && key
.hash
!= prevkey
) {
834 ApplyStats(stats
, ss
, prevkey
, outputs
);
838 outputs
[key
.n
] = std::move(coin
);
840 return error("%s: unable to read value", __func__
);
844 if (!outputs
.empty()) {
845 ApplyStats(stats
, ss
, prevkey
, outputs
);
847 stats
.hashSerialized
= ss
.GetHash();
848 stats
.nDiskSize
= view
->EstimateSize();
852 UniValue
pruneblockchain(const JSONRPCRequest
& request
)
854 if (request
.fHelp
|| request
.params
.size() != 1)
855 throw std::runtime_error(
858 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
859 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
861 "n (numeric) Height of the last block pruned.\n"
863 + HelpExampleCli("pruneblockchain", "1000")
864 + HelpExampleRpc("pruneblockchain", "1000"));
867 throw JSONRPCError(RPC_MISC_ERROR
, "Cannot prune blocks because node is not in prune mode.");
871 int heightParam
= request
.params
[0].get_int();
873 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Negative block height.");
875 // Height value more than a billion is too high to be a block height, and
876 // too low to be a block time (corresponds to timestamp from Sep 2001).
877 if (heightParam
> 1000000000) {
878 // Add a 2 hour buffer to include blocks which might have had old timestamps
879 CBlockIndex
* pindex
= chainActive
.FindEarliestAtLeast(heightParam
- TIMESTAMP_WINDOW
);
881 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Could not find block with at least the specified timestamp.");
883 heightParam
= pindex
->nHeight
;
886 unsigned int height
= (unsigned int) heightParam
;
887 unsigned int chainHeight
= (unsigned int) chainActive
.Height();
888 if (chainHeight
< Params().PruneAfterHeight())
889 throw JSONRPCError(RPC_MISC_ERROR
, "Blockchain is too short for pruning.");
890 else if (height
> chainHeight
)
891 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Blockchain is shorter than the attempted prune height.");
892 else if (height
> chainHeight
- MIN_BLOCKS_TO_KEEP
) {
893 LogPrint(BCLog::RPC
, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
894 height
= chainHeight
- MIN_BLOCKS_TO_KEEP
;
897 PruneBlockFilesManual(height
);
898 return uint64_t(height
);
901 UniValue
gettxoutsetinfo(const JSONRPCRequest
& request
)
903 if (request
.fHelp
|| request
.params
.size() != 0)
904 throw std::runtime_error(
906 "\nReturns statistics about the unspent transaction output set.\n"
907 "Note this call may take some time.\n"
910 " \"height\":n, (numeric) The current block height (index)\n"
911 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
912 " \"transactions\": n, (numeric) The number of transactions\n"
913 " \"txouts\": n, (numeric) The number of output transactions\n"
914 " \"bogosize\": n, (numeric) A meaningless metric for UTXO set size\n"
915 " \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
916 " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
917 " \"total_amount\": x.xxx (numeric) The total amount\n"
920 + HelpExampleCli("gettxoutsetinfo", "")
921 + HelpExampleRpc("gettxoutsetinfo", "")
924 UniValue
ret(UniValue::VOBJ
);
928 if (GetUTXOStats(pcoinsdbview
, stats
)) {
929 ret
.push_back(Pair("height", (int64_t)stats
.nHeight
));
930 ret
.push_back(Pair("bestblock", stats
.hashBlock
.GetHex()));
931 ret
.push_back(Pair("transactions", (int64_t)stats
.nTransactions
));
932 ret
.push_back(Pair("txouts", (int64_t)stats
.nTransactionOutputs
));
933 ret
.push_back(Pair("bogosize", (int64_t)stats
.nBogoSize
));
934 ret
.push_back(Pair("hash_serialized_2", stats
.hashSerialized
.GetHex()));
935 ret
.push_back(Pair("disk_size", stats
.nDiskSize
));
936 ret
.push_back(Pair("total_amount", ValueFromAmount(stats
.nTotalAmount
)));
938 throw JSONRPCError(RPC_INTERNAL_ERROR
, "Unable to read UTXO set");
943 UniValue
gettxout(const JSONRPCRequest
& request
)
945 if (request
.fHelp
|| request
.params
.size() < 2 || request
.params
.size() > 3)
946 throw std::runtime_error(
947 "gettxout \"txid\" n ( include_mempool )\n"
948 "\nReturns details about an unspent transaction output.\n"
950 "1. \"txid\" (string, required) The transaction id\n"
951 "2. \"n\" (numeric, required) vout number\n"
952 "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true."
953 " Note that an unspent output that is spent in the mempool won't appear.\n"
956 " \"bestblock\" : \"hash\", (string) the block hash\n"
957 " \"confirmations\" : n, (numeric) The number of confirmations\n"
958 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT
+ "\n"
959 " \"scriptPubKey\" : { (json object)\n"
960 " \"asm\" : \"code\", (string) \n"
961 " \"hex\" : \"hex\", (string) \n"
962 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
963 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
964 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
965 " \"address\" (string) bitcoin address\n"
969 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
973 "\nGet unspent transactions\n"
974 + HelpExampleCli("listunspent", "") +
975 "\nView the details\n"
976 + HelpExampleCli("gettxout", "\"txid\" 1") +
977 "\nAs a json rpc call\n"
978 + HelpExampleRpc("gettxout", "\"txid\", 1")
983 UniValue
ret(UniValue::VOBJ
);
985 std::string strHash
= request
.params
[0].get_str();
986 uint256
hash(uint256S(strHash
));
987 int n
= request
.params
[1].get_int();
988 COutPoint
out(hash
, n
);
989 bool fMempool
= true;
990 if (!request
.params
[2].isNull())
991 fMempool
= request
.params
[2].get_bool();
996 CCoinsViewMemPool
view(pcoinsTip
, mempool
);
997 if (!view
.GetCoin(out
, coin
) || mempool
.isSpent(out
)) {
1001 if (!pcoinsTip
->GetCoin(out
, coin
)) {
1002 return NullUniValue
;
1006 BlockMap::iterator it
= mapBlockIndex
.find(pcoinsTip
->GetBestBlock());
1007 CBlockIndex
*pindex
= it
->second
;
1008 ret
.push_back(Pair("bestblock", pindex
->GetBlockHash().GetHex()));
1009 if (coin
.nHeight
== MEMPOOL_HEIGHT
) {
1010 ret
.push_back(Pair("confirmations", 0));
1012 ret
.push_back(Pair("confirmations", (int64_t)(pindex
->nHeight
- coin
.nHeight
+ 1)));
1014 ret
.push_back(Pair("value", ValueFromAmount(coin
.out
.nValue
)));
1015 UniValue
o(UniValue::VOBJ
);
1016 ScriptPubKeyToUniv(coin
.out
.scriptPubKey
, o
, true);
1017 ret
.push_back(Pair("scriptPubKey", o
));
1018 ret
.push_back(Pair("coinbase", (bool)coin
.fCoinBase
));
1023 UniValue
verifychain(const JSONRPCRequest
& request
)
1025 int nCheckLevel
= gArgs
.GetArg("-checklevel", DEFAULT_CHECKLEVEL
);
1026 int nCheckDepth
= gArgs
.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS
);
1027 if (request
.fHelp
|| request
.params
.size() > 2)
1028 throw std::runtime_error(
1029 "verifychain ( checklevel nblocks )\n"
1030 "\nVerifies blockchain database.\n"
1032 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel
) + ") How thorough the block verification is.\n"
1033 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth
) + ", 0=all) The number of blocks to check.\n"
1035 "true|false (boolean) Verified or not\n"
1037 + HelpExampleCli("verifychain", "")
1038 + HelpExampleRpc("verifychain", "")
1043 if (!request
.params
[0].isNull())
1044 nCheckLevel
= request
.params
[0].get_int();
1045 if (!request
.params
[1].isNull())
1046 nCheckDepth
= request
.params
[1].get_int();
1048 return CVerifyDB().VerifyDB(Params(), pcoinsTip
, nCheckLevel
, nCheckDepth
);
1051 /** Implementation of IsSuperMajority with better feedback */
1052 static UniValue
SoftForkMajorityDesc(int version
, CBlockIndex
* pindex
, const Consensus::Params
& consensusParams
)
1054 UniValue
rv(UniValue::VOBJ
);
1055 bool activated
= false;
1059 activated
= pindex
->nHeight
>= consensusParams
.BIP34Height
;
1062 activated
= pindex
->nHeight
>= consensusParams
.BIP66Height
;
1065 activated
= pindex
->nHeight
>= consensusParams
.BIP65Height
;
1068 rv
.push_back(Pair("status", activated
));
1072 static UniValue
SoftForkDesc(const std::string
&name
, int version
, CBlockIndex
* pindex
, const Consensus::Params
& consensusParams
)
1074 UniValue
rv(UniValue::VOBJ
);
1075 rv
.push_back(Pair("id", name
));
1076 rv
.push_back(Pair("version", version
));
1077 rv
.push_back(Pair("reject", SoftForkMajorityDesc(version
, pindex
, consensusParams
)));
1081 static UniValue
BIP9SoftForkDesc(const Consensus::Params
& consensusParams
, Consensus::DeploymentPos id
)
1083 UniValue
rv(UniValue::VOBJ
);
1084 const ThresholdState thresholdState
= VersionBitsTipState(consensusParams
, id
);
1085 switch (thresholdState
) {
1086 case THRESHOLD_DEFINED
: rv
.push_back(Pair("status", "defined")); break;
1087 case THRESHOLD_STARTED
: rv
.push_back(Pair("status", "started")); break;
1088 case THRESHOLD_LOCKED_IN
: rv
.push_back(Pair("status", "locked_in")); break;
1089 case THRESHOLD_ACTIVE
: rv
.push_back(Pair("status", "active")); break;
1090 case THRESHOLD_FAILED
: rv
.push_back(Pair("status", "failed")); break;
1092 if (THRESHOLD_STARTED
== thresholdState
)
1094 rv
.push_back(Pair("bit", consensusParams
.vDeployments
[id
].bit
));
1096 rv
.push_back(Pair("startTime", consensusParams
.vDeployments
[id
].nStartTime
));
1097 rv
.push_back(Pair("timeout", consensusParams
.vDeployments
[id
].nTimeout
));
1098 rv
.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams
, id
)));
1099 if (THRESHOLD_STARTED
== thresholdState
)
1101 UniValue
statsUV(UniValue::VOBJ
);
1102 BIP9Stats statsStruct
= VersionBitsTipStatistics(consensusParams
, id
);
1103 statsUV
.push_back(Pair("period", statsStruct
.period
));
1104 statsUV
.push_back(Pair("threshold", statsStruct
.threshold
));
1105 statsUV
.push_back(Pair("elapsed", statsStruct
.elapsed
));
1106 statsUV
.push_back(Pair("count", statsStruct
.count
));
1107 statsUV
.push_back(Pair("possible", statsStruct
.possible
));
1108 rv
.push_back(Pair("statistics", statsUV
));
1113 void BIP9SoftForkDescPushBack(UniValue
& bip9_softforks
, const std::string
&name
, const Consensus::Params
& consensusParams
, Consensus::DeploymentPos id
)
1115 // Deployments with timeout value of 0 are hidden.
1116 // A timeout value of 0 guarantees a softfork will never be activated.
1117 // This is used when softfork codes are merged without specifying the deployment schedule.
1118 if (consensusParams
.vDeployments
[id
].nTimeout
> 0)
1119 bip9_softforks
.push_back(Pair(name
, BIP9SoftForkDesc(consensusParams
, id
)));
1122 UniValue
getblockchaininfo(const JSONRPCRequest
& request
)
1124 if (request
.fHelp
|| request
.params
.size() != 0)
1125 throw std::runtime_error(
1126 "getblockchaininfo\n"
1127 "Returns an object containing various state info regarding blockchain processing.\n"
1130 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1131 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1132 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1133 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1134 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1135 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1136 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1137 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1138 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1139 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1140 " \"softforks\": [ (array) status of softforks in progress\n"
1142 " \"id\": \"xxxx\", (string) name of softfork\n"
1143 " \"version\": xx, (numeric) block version\n"
1144 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1145 " \"status\": xx, (boolean) true if threshold reached\n"
1149 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1150 " \"xxxx\" : { (string) name of the softfork\n"
1151 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1152 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1153 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1154 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1155 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1156 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1157 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1158 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1159 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1160 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1161 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1167 + HelpExampleCli("getblockchaininfo", "")
1168 + HelpExampleRpc("getblockchaininfo", "")
1173 UniValue
obj(UniValue::VOBJ
);
1174 obj
.push_back(Pair("chain", Params().NetworkIDString()));
1175 obj
.push_back(Pair("blocks", (int)chainActive
.Height()));
1176 obj
.push_back(Pair("headers", pindexBestHeader
? pindexBestHeader
->nHeight
: -1));
1177 obj
.push_back(Pair("bestblockhash", chainActive
.Tip()->GetBlockHash().GetHex()));
1178 obj
.push_back(Pair("difficulty", (double)GetDifficulty()));
1179 obj
.push_back(Pair("mediantime", (int64_t)chainActive
.Tip()->GetMedianTimePast()));
1180 obj
.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive
.Tip())));
1181 obj
.push_back(Pair("chainwork", chainActive
.Tip()->nChainWork
.GetHex()));
1182 obj
.push_back(Pair("pruned", fPruneMode
));
1184 const Consensus::Params
& consensusParams
= Params().GetConsensus();
1185 CBlockIndex
* tip
= chainActive
.Tip();
1186 UniValue
softforks(UniValue::VARR
);
1187 UniValue
bip9_softforks(UniValue::VOBJ
);
1188 softforks
.push_back(SoftForkDesc("bip34", 2, tip
, consensusParams
));
1189 softforks
.push_back(SoftForkDesc("bip66", 3, tip
, consensusParams
));
1190 softforks
.push_back(SoftForkDesc("bip65", 4, tip
, consensusParams
));
1191 BIP9SoftForkDescPushBack(bip9_softforks
, "csv", consensusParams
, Consensus::DEPLOYMENT_CSV
);
1192 BIP9SoftForkDescPushBack(bip9_softforks
, "segwit", consensusParams
, Consensus::DEPLOYMENT_SEGWIT
);
1193 obj
.push_back(Pair("softforks", softforks
));
1194 obj
.push_back(Pair("bip9_softforks", bip9_softforks
));
1198 CBlockIndex
*block
= chainActive
.Tip();
1199 while (block
&& block
->pprev
&& (block
->pprev
->nStatus
& BLOCK_HAVE_DATA
))
1200 block
= block
->pprev
;
1202 obj
.push_back(Pair("pruneheight", block
->nHeight
));
1207 /** Comparison function for sorting the getchaintips heads. */
1208 struct CompareBlocksByHeight
1210 bool operator()(const CBlockIndex
* a
, const CBlockIndex
* b
) const
1212 /* Make sure that unequal blocks with the same height do not compare
1213 equal. Use the pointers themselves to make a distinction. */
1215 if (a
->nHeight
!= b
->nHeight
)
1216 return (a
->nHeight
> b
->nHeight
);
1222 UniValue
getchaintips(const JSONRPCRequest
& request
)
1224 if (request
.fHelp
|| request
.params
.size() != 0)
1225 throw std::runtime_error(
1227 "Return information about all known tips in the block tree,"
1228 " including the main chain as well as orphaned branches.\n"
1232 " \"height\": xxxx, (numeric) height of the chain tip\n"
1233 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1234 " \"branchlen\": 0 (numeric) zero for main chain\n"
1235 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1238 " \"height\": xxxx,\n"
1239 " \"hash\": \"xxxx\",\n"
1240 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1241 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1244 "Possible values for status:\n"
1245 "1. \"invalid\" This branch contains at least one invalid block\n"
1246 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1247 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1248 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1249 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1251 + HelpExampleCli("getchaintips", "")
1252 + HelpExampleRpc("getchaintips", "")
1258 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1260 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1261 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1262 * - add chainActive.Tip()
1264 std::set
<const CBlockIndex
*, CompareBlocksByHeight
> setTips
;
1265 std::set
<const CBlockIndex
*> setOrphans
;
1266 std::set
<const CBlockIndex
*> setPrevs
;
1268 for (const std::pair
<const uint256
, CBlockIndex
*>& item
: mapBlockIndex
)
1270 if (!chainActive
.Contains(item
.second
)) {
1271 setOrphans
.insert(item
.second
);
1272 setPrevs
.insert(item
.second
->pprev
);
1276 for (std::set
<const CBlockIndex
*>::iterator it
= setOrphans
.begin(); it
!= setOrphans
.end(); ++it
)
1278 if (setPrevs
.erase(*it
) == 0) {
1279 setTips
.insert(*it
);
1283 // Always report the currently active tip.
1284 setTips
.insert(chainActive
.Tip());
1286 /* Construct the output array. */
1287 UniValue
res(UniValue::VARR
);
1288 for (const CBlockIndex
* block
: setTips
)
1290 UniValue
obj(UniValue::VOBJ
);
1291 obj
.push_back(Pair("height", block
->nHeight
));
1292 obj
.push_back(Pair("hash", block
->phashBlock
->GetHex()));
1294 const int branchLen
= block
->nHeight
- chainActive
.FindFork(block
)->nHeight
;
1295 obj
.push_back(Pair("branchlen", branchLen
));
1298 if (chainActive
.Contains(block
)) {
1299 // This block is part of the currently active chain.
1301 } else if (block
->nStatus
& BLOCK_FAILED_MASK
) {
1302 // This block or one of its ancestors is invalid.
1304 } else if (block
->nChainTx
== 0) {
1305 // This block cannot be connected because full block data for it or one of its parents is missing.
1306 status
= "headers-only";
1307 } else if (block
->IsValid(BLOCK_VALID_SCRIPTS
)) {
1308 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1309 status
= "valid-fork";
1310 } else if (block
->IsValid(BLOCK_VALID_TREE
)) {
1311 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1312 status
= "valid-headers";
1317 obj
.push_back(Pair("status", status
));
1325 UniValue
mempoolInfoToJSON()
1327 UniValue
ret(UniValue::VOBJ
);
1328 ret
.push_back(Pair("size", (int64_t) mempool
.size()));
1329 ret
.push_back(Pair("bytes", (int64_t) mempool
.GetTotalTxSize()));
1330 ret
.push_back(Pair("usage", (int64_t) mempool
.DynamicMemoryUsage()));
1331 size_t maxmempool
= gArgs
.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE
) * 1000000;
1332 ret
.push_back(Pair("maxmempool", (int64_t) maxmempool
));
1333 ret
.push_back(Pair("mempoolminfee", ValueFromAmount(mempool
.GetMinFee(maxmempool
).GetFeePerK())));
1338 UniValue
getmempoolinfo(const JSONRPCRequest
& request
)
1340 if (request
.fHelp
|| request
.params
.size() != 0)
1341 throw std::runtime_error(
1343 "\nReturns details on the active state of the TX memory pool.\n"
1346 " \"size\": xxxxx, (numeric) Current tx count\n"
1347 " \"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"
1348 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1349 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1350 " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT
+ "/kB for tx to be accepted\n"
1353 + HelpExampleCli("getmempoolinfo", "")
1354 + HelpExampleRpc("getmempoolinfo", "")
1357 return mempoolInfoToJSON();
1360 UniValue
preciousblock(const JSONRPCRequest
& request
)
1362 if (request
.fHelp
|| request
.params
.size() != 1)
1363 throw std::runtime_error(
1364 "preciousblock \"blockhash\"\n"
1365 "\nTreats a block as if it were received before others with the same work.\n"
1366 "\nA later preciousblock call can override the effect of an earlier one.\n"
1367 "\nThe effects of preciousblock are not retained across restarts.\n"
1369 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1372 + HelpExampleCli("preciousblock", "\"blockhash\"")
1373 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1376 std::string strHash
= request
.params
[0].get_str();
1377 uint256
hash(uint256S(strHash
));
1378 CBlockIndex
* pblockindex
;
1382 if (mapBlockIndex
.count(hash
) == 0)
1383 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1385 pblockindex
= mapBlockIndex
[hash
];
1388 CValidationState state
;
1389 PreciousBlock(state
, Params(), pblockindex
);
1391 if (!state
.IsValid()) {
1392 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1395 return NullUniValue
;
1398 UniValue
invalidateblock(const JSONRPCRequest
& request
)
1400 if (request
.fHelp
|| request
.params
.size() != 1)
1401 throw std::runtime_error(
1402 "invalidateblock \"blockhash\"\n"
1403 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1405 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1408 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1409 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1412 std::string strHash
= request
.params
[0].get_str();
1413 uint256
hash(uint256S(strHash
));
1414 CValidationState state
;
1418 if (mapBlockIndex
.count(hash
) == 0)
1419 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1421 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
1422 InvalidateBlock(state
, Params(), pblockindex
);
1425 if (state
.IsValid()) {
1426 ActivateBestChain(state
, Params());
1429 if (!state
.IsValid()) {
1430 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1433 return NullUniValue
;
1436 UniValue
reconsiderblock(const JSONRPCRequest
& request
)
1438 if (request
.fHelp
|| request
.params
.size() != 1)
1439 throw std::runtime_error(
1440 "reconsiderblock \"blockhash\"\n"
1441 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1442 "This can be used to undo the effects of invalidateblock.\n"
1444 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1447 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1448 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1451 std::string strHash
= request
.params
[0].get_str();
1452 uint256
hash(uint256S(strHash
));
1456 if (mapBlockIndex
.count(hash
) == 0)
1457 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1459 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
1460 ResetBlockFailureFlags(pblockindex
);
1463 CValidationState state
;
1464 ActivateBestChain(state
, Params());
1466 if (!state
.IsValid()) {
1467 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1470 return NullUniValue
;
1473 UniValue
getchaintxstats(const JSONRPCRequest
& request
)
1475 if (request
.fHelp
|| request
.params
.size() > 2)
1476 throw std::runtime_error(
1477 "getchaintxstats ( nblocks blockhash )\n"
1478 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1480 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1481 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1484 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1485 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1486 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1489 + HelpExampleCli("getchaintxstats", "")
1490 + HelpExampleRpc("getchaintxstats", "2016")
1493 const CBlockIndex
* pindex
;
1494 int blockcount
= 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing
; // By default: 1 month
1496 if (!request
.params
[0].isNull()) {
1497 blockcount
= request
.params
[0].get_int();
1500 bool havehash
= !request
.params
[1].isNull();
1503 hash
= uint256S(request
.params
[1].get_str());
1509 auto it
= mapBlockIndex
.find(hash
);
1510 if (it
== mapBlockIndex
.end()) {
1511 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1513 pindex
= it
->second
;
1514 if (!chainActive
.Contains(pindex
)) {
1515 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Block is not in main chain");
1518 pindex
= chainActive
.Tip();
1522 assert(pindex
!= nullptr);
1524 if (blockcount
< 1 || blockcount
>= pindex
->nHeight
) {
1525 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid block count: should be between 1 and the block's height");
1528 const CBlockIndex
* pindexPast
= pindex
->GetAncestor(pindex
->nHeight
- blockcount
);
1529 int nTimeDiff
= pindex
->GetMedianTimePast() - pindexPast
->GetMedianTimePast();
1530 int nTxDiff
= pindex
->nChainTx
- pindexPast
->nChainTx
;
1532 UniValue
ret(UniValue::VOBJ
);
1533 ret
.push_back(Pair("time", (int64_t)pindex
->nTime
));
1534 ret
.push_back(Pair("txcount", (int64_t)pindex
->nChainTx
));
1535 ret
.push_back(Pair("txrate", ((double)nTxDiff
) / nTimeDiff
));
1540 UniValue
savemempool(const JSONRPCRequest
& request
)
1542 if (request
.fHelp
|| request
.params
.size() != 0) {
1543 throw std::runtime_error(
1545 "\nDumps the mempool to disk.\n"
1547 + HelpExampleCli("savemempool", "")
1548 + HelpExampleRpc("savemempool", "")
1552 if (!DumpMempool()) {
1553 throw JSONRPCError(RPC_MISC_ERROR
, "Unable to dump mempool to disk");
1556 return NullUniValue
;
1559 static const CRPCCommand commands
[] =
1560 { // category name actor (function) argNames
1561 // --------------------- ------------------------ ----------------------- ----------
1562 { "blockchain", "getblockchaininfo", &getblockchaininfo
, {} },
1563 { "blockchain", "getchaintxstats", &getchaintxstats
, {"nblocks", "blockhash"} },
1564 { "blockchain", "getbestblockhash", &getbestblockhash
, {} },
1565 { "blockchain", "getblockcount", &getblockcount
, {} },
1566 { "blockchain", "getblock", &getblock
, {"blockhash","verbosity|verbose"} },
1567 { "blockchain", "getblockhash", &getblockhash
, {"height"} },
1568 { "blockchain", "getblockheader", &getblockheader
, {"blockhash","verbose"} },
1569 { "blockchain", "getchaintips", &getchaintips
, {} },
1570 { "blockchain", "getdifficulty", &getdifficulty
, {} },
1571 { "blockchain", "getmempoolancestors", &getmempoolancestors
, {"txid","verbose"} },
1572 { "blockchain", "getmempooldescendants", &getmempooldescendants
, {"txid","verbose"} },
1573 { "blockchain", "getmempoolentry", &getmempoolentry
, {"txid"} },
1574 { "blockchain", "getmempoolinfo", &getmempoolinfo
, {} },
1575 { "blockchain", "getrawmempool", &getrawmempool
, {"verbose"} },
1576 { "blockchain", "gettxout", &gettxout
, {"txid","n","include_mempool"} },
1577 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo
, {} },
1578 { "blockchain", "pruneblockchain", &pruneblockchain
, {"height"} },
1579 { "blockchain", "savemempool", &savemempool
, {} },
1580 { "blockchain", "verifychain", &verifychain
, {"checklevel","nblocks"} },
1582 { "blockchain", "preciousblock", &preciousblock
, {"blockhash"} },
1584 /* Not shown in help */
1585 { "hidden", "invalidateblock", &invalidateblock
, {"blockhash"} },
1586 { "hidden", "reconsiderblock", &reconsiderblock
, {"blockhash"} },
1587 { "hidden", "waitfornewblock", &waitfornewblock
, {"timeout"} },
1588 { "hidden", "waitforblock", &waitforblock
, {"blockhash","timeout"} },
1589 { "hidden", "waitforblockheight", &waitforblockheight
, {"height","timeout"} },
1592 void RegisterBlockchainRPCCommands(CRPCTable
&t
)
1594 for (unsigned int vcidx
= 0; vcidx
< ARRAYLEN(commands
); vcidx
++)
1595 t
.appendCommand(commands
[vcidx
].name
, &commands
[vcidx
]);