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 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
347 " \"transactionid\", (string) parent transaction id\n"
351 void entryToJSON(UniValue
&info
, const CTxMemPoolEntry
&e
)
353 AssertLockHeld(mempool
.cs
);
355 info
.push_back(Pair("size", (int)e
.GetTxSize()));
356 info
.push_back(Pair("fee", ValueFromAmount(e
.GetFee())));
357 info
.push_back(Pair("modifiedfee", ValueFromAmount(e
.GetModifiedFee())));
358 info
.push_back(Pair("time", e
.GetTime()));
359 info
.push_back(Pair("height", (int)e
.GetHeight()));
360 info
.push_back(Pair("descendantcount", e
.GetCountWithDescendants()));
361 info
.push_back(Pair("descendantsize", e
.GetSizeWithDescendants()));
362 info
.push_back(Pair("descendantfees", e
.GetModFeesWithDescendants()));
363 info
.push_back(Pair("ancestorcount", e
.GetCountWithAncestors()));
364 info
.push_back(Pair("ancestorsize", e
.GetSizeWithAncestors()));
365 info
.push_back(Pair("ancestorfees", e
.GetModFeesWithAncestors()));
366 const CTransaction
& tx
= e
.GetTx();
367 std::set
<std::string
> setDepends
;
368 for (const CTxIn
& txin
: tx
.vin
)
370 if (mempool
.exists(txin
.prevout
.hash
))
371 setDepends
.insert(txin
.prevout
.hash
.ToString());
374 UniValue
depends(UniValue::VARR
);
375 for (const std::string
& dep
: setDepends
)
377 depends
.push_back(dep
);
380 info
.push_back(Pair("depends", depends
));
383 UniValue
mempoolToJSON(bool fVerbose
)
388 UniValue
o(UniValue::VOBJ
);
389 for (const CTxMemPoolEntry
& e
: mempool
.mapTx
)
391 const uint256
& hash
= e
.GetTx().GetHash();
392 UniValue
info(UniValue::VOBJ
);
393 entryToJSON(info
, e
);
394 o
.push_back(Pair(hash
.ToString(), info
));
400 std::vector
<uint256
> vtxid
;
401 mempool
.queryHashes(vtxid
);
403 UniValue
a(UniValue::VARR
);
404 for (const uint256
& hash
: vtxid
)
405 a
.push_back(hash
.ToString());
411 UniValue
getrawmempool(const JSONRPCRequest
& request
)
413 if (request
.fHelp
|| request
.params
.size() > 1)
414 throw std::runtime_error(
415 "getrawmempool ( verbose )\n"
416 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
417 "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n"
419 "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
420 "\nResult: (for verbose = false):\n"
421 "[ (json array of string)\n"
422 " \"transactionid\" (string) The transaction id\n"
425 "\nResult: (for verbose = true):\n"
427 " \"transactionid\" : { (json object)\n"
428 + EntryDescriptionString()
432 + HelpExampleCli("getrawmempool", "true")
433 + HelpExampleRpc("getrawmempool", "true")
436 bool fVerbose
= false;
437 if (!request
.params
[0].isNull())
438 fVerbose
= request
.params
[0].get_bool();
440 return mempoolToJSON(fVerbose
);
443 UniValue
getmempoolancestors(const JSONRPCRequest
& request
)
445 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2) {
446 throw std::runtime_error(
447 "getmempoolancestors txid (verbose)\n"
448 "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
450 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
451 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
452 "\nResult (for verbose=false):\n"
453 "[ (json array of strings)\n"
454 " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
457 "\nResult (for verbose=true):\n"
459 " \"transactionid\" : { (json object)\n"
460 + EntryDescriptionString()
464 + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
465 + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
469 bool fVerbose
= false;
470 if (!request
.params
[1].isNull())
471 fVerbose
= request
.params
[1].get_bool();
473 uint256 hash
= ParseHashV(request
.params
[0], "parameter 1");
477 CTxMemPool::txiter it
= mempool
.mapTx
.find(hash
);
478 if (it
== mempool
.mapTx
.end()) {
479 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Transaction not in mempool");
482 CTxMemPool::setEntries setAncestors
;
483 uint64_t noLimit
= std::numeric_limits
<uint64_t>::max();
485 mempool
.CalculateMemPoolAncestors(*it
, setAncestors
, noLimit
, noLimit
, noLimit
, noLimit
, dummy
, false);
488 UniValue
o(UniValue::VARR
);
489 for (CTxMemPool::txiter ancestorIt
: setAncestors
) {
490 o
.push_back(ancestorIt
->GetTx().GetHash().ToString());
495 UniValue
o(UniValue::VOBJ
);
496 for (CTxMemPool::txiter ancestorIt
: setAncestors
) {
497 const CTxMemPoolEntry
&e
= *ancestorIt
;
498 const uint256
& _hash
= e
.GetTx().GetHash();
499 UniValue
info(UniValue::VOBJ
);
500 entryToJSON(info
, e
);
501 o
.push_back(Pair(_hash
.ToString(), info
));
507 UniValue
getmempooldescendants(const JSONRPCRequest
& request
)
509 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2) {
510 throw std::runtime_error(
511 "getmempooldescendants txid (verbose)\n"
512 "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
514 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
515 "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
516 "\nResult (for verbose=false):\n"
517 "[ (json array of strings)\n"
518 " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
521 "\nResult (for verbose=true):\n"
523 " \"transactionid\" : { (json object)\n"
524 + EntryDescriptionString()
528 + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
529 + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
533 bool fVerbose
= false;
534 if (!request
.params
[1].isNull())
535 fVerbose
= request
.params
[1].get_bool();
537 uint256 hash
= ParseHashV(request
.params
[0], "parameter 1");
541 CTxMemPool::txiter it
= mempool
.mapTx
.find(hash
);
542 if (it
== mempool
.mapTx
.end()) {
543 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Transaction not in mempool");
546 CTxMemPool::setEntries setDescendants
;
547 mempool
.CalculateDescendants(it
, setDescendants
);
548 // CTxMemPool::CalculateDescendants will include the given tx
549 setDescendants
.erase(it
);
552 UniValue
o(UniValue::VARR
);
553 for (CTxMemPool::txiter descendantIt
: setDescendants
) {
554 o
.push_back(descendantIt
->GetTx().GetHash().ToString());
559 UniValue
o(UniValue::VOBJ
);
560 for (CTxMemPool::txiter descendantIt
: setDescendants
) {
561 const CTxMemPoolEntry
&e
= *descendantIt
;
562 const uint256
& _hash
= e
.GetTx().GetHash();
563 UniValue
info(UniValue::VOBJ
);
564 entryToJSON(info
, e
);
565 o
.push_back(Pair(_hash
.ToString(), info
));
571 UniValue
getmempoolentry(const JSONRPCRequest
& request
)
573 if (request
.fHelp
|| request
.params
.size() != 1) {
574 throw std::runtime_error(
575 "getmempoolentry txid\n"
576 "\nReturns mempool data for given transaction\n"
578 "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
581 + EntryDescriptionString()
584 + HelpExampleCli("getmempoolentry", "\"mytxid\"")
585 + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
589 uint256 hash
= ParseHashV(request
.params
[0], "parameter 1");
593 CTxMemPool::txiter it
= mempool
.mapTx
.find(hash
);
594 if (it
== mempool
.mapTx
.end()) {
595 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Transaction not in mempool");
598 const CTxMemPoolEntry
&e
= *it
;
599 UniValue
info(UniValue::VOBJ
);
600 entryToJSON(info
, e
);
604 UniValue
getblockhash(const JSONRPCRequest
& request
)
606 if (request
.fHelp
|| request
.params
.size() != 1)
607 throw std::runtime_error(
608 "getblockhash height\n"
609 "\nReturns hash of block in best-block-chain at height provided.\n"
611 "1. height (numeric, required) The height index\n"
613 "\"hash\" (string) The block hash\n"
615 + HelpExampleCli("getblockhash", "1000")
616 + HelpExampleRpc("getblockhash", "1000")
621 int nHeight
= request
.params
[0].get_int();
622 if (nHeight
< 0 || nHeight
> chainActive
.Height())
623 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Block height out of range");
625 CBlockIndex
* pblockindex
= chainActive
[nHeight
];
626 return pblockindex
->GetBlockHash().GetHex();
629 UniValue
getblockheader(const JSONRPCRequest
& request
)
631 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
632 throw std::runtime_error(
633 "getblockheader \"hash\" ( verbose )\n"
634 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
635 "If verbose is true, returns an Object with information about blockheader <hash>.\n"
637 "1. \"hash\" (string, required) The block hash\n"
638 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
639 "\nResult (for verbose = true):\n"
641 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
642 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
643 " \"height\" : n, (numeric) The block height or index\n"
644 " \"version\" : n, (numeric) The block version\n"
645 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
646 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
647 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
648 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
649 " \"nonce\" : n, (numeric) The nonce\n"
650 " \"bits\" : \"1d00ffff\", (string) The bits\n"
651 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
652 " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
653 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
654 " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
656 "\nResult (for verbose=false):\n"
657 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
659 + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
660 + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
665 std::string strHash
= request
.params
[0].get_str();
666 uint256
hash(uint256S(strHash
));
668 bool fVerbose
= true;
669 if (!request
.params
[1].isNull())
670 fVerbose
= request
.params
[1].get_bool();
672 if (mapBlockIndex
.count(hash
) == 0)
673 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
675 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
679 CDataStream
ssBlock(SER_NETWORK
, PROTOCOL_VERSION
);
680 ssBlock
<< pblockindex
->GetBlockHeader();
681 std::string strHex
= HexStr(ssBlock
.begin(), ssBlock
.end());
685 return blockheaderToJSON(pblockindex
);
688 UniValue
getblock(const JSONRPCRequest
& request
)
690 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
691 throw std::runtime_error(
692 "getblock \"blockhash\" ( verbosity ) \n"
693 "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
694 "If verbosity is 1, returns an Object with information about block <hash>.\n"
695 "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n"
697 "1. \"blockhash\" (string, required) The block hash\n"
698 "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"
699 "\nResult (for verbosity = 0):\n"
700 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
701 "\nResult (for verbosity = 1):\n"
703 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
704 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
705 " \"size\" : n, (numeric) The block size\n"
706 " \"strippedsize\" : n, (numeric) The block size excluding witness data\n"
707 " \"weight\" : n (numeric) The block weight as defined in BIP 141\n"
708 " \"height\" : n, (numeric) The block height or index\n"
709 " \"version\" : n, (numeric) The block version\n"
710 " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n"
711 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
712 " \"tx\" : [ (array of string) The transaction ids\n"
713 " \"transactionid\" (string) The transaction id\n"
716 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
717 " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n"
718 " \"nonce\" : n, (numeric) The nonce\n"
719 " \"bits\" : \"1d00ffff\", (string) The bits\n"
720 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
721 " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
722 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
723 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
725 "\nResult (for verbosity = 2):\n"
727 " ..., Same output as verbosity = 1.\n"
728 " \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
731 " ,... Same output as verbosity = 1.\n"
734 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
735 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
740 std::string strHash
= request
.params
[0].get_str();
741 uint256
hash(uint256S(strHash
));
744 if (!request
.params
[1].isNull()) {
745 if(request
.params
[1].isNum())
746 verbosity
= request
.params
[1].get_int();
748 verbosity
= request
.params
[1].get_bool() ? 1 : 0;
751 if (mapBlockIndex
.count(hash
) == 0)
752 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
755 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
757 if (fHavePruned
&& !(pblockindex
->nStatus
& BLOCK_HAVE_DATA
) && pblockindex
->nTx
> 0)
758 throw JSONRPCError(RPC_MISC_ERROR
, "Block not available (pruned data)");
760 if (!ReadBlockFromDisk(block
, pblockindex
, Params().GetConsensus()))
761 // Block not found on disk. This could be because we have the block
762 // header in our index but don't have the block (for example if a
763 // non-whitelisted node sends us an unrequested long chain of valid
764 // blocks, we add the headers to our index, but don't accept the
766 throw JSONRPCError(RPC_MISC_ERROR
, "Block not found on disk");
770 CDataStream
ssBlock(SER_NETWORK
, PROTOCOL_VERSION
| RPCSerializationFlags());
772 std::string strHex
= HexStr(ssBlock
.begin(), ssBlock
.end());
776 return blockToJSON(block
, pblockindex
, verbosity
>= 2);
783 uint64_t nTransactions
;
784 uint64_t nTransactionOutputs
;
786 uint256 hashSerialized
;
788 CAmount nTotalAmount
;
790 CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
793 static void ApplyStats(CCoinsStats
&stats
, CHashWriter
& ss
, const uint256
& hash
, const std::map
<uint32_t, Coin
>& outputs
)
795 assert(!outputs
.empty());
797 ss
<< VARINT(outputs
.begin()->second
.nHeight
* 2 + outputs
.begin()->second
.fCoinBase
);
798 stats
.nTransactions
++;
799 for (const auto output
: outputs
) {
800 ss
<< VARINT(output
.first
+ 1);
801 ss
<< output
.second
.out
.scriptPubKey
;
802 ss
<< VARINT(output
.second
.out
.nValue
);
803 stats
.nTransactionOutputs
++;
804 stats
.nTotalAmount
+= output
.second
.out
.nValue
;
805 stats
.nBogoSize
+= 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
806 2 /* scriptPubKey len */ + output
.second
.out
.scriptPubKey
.size() /* scriptPubKey */;
811 //! Calculate statistics about the unspent transaction output set
812 static bool GetUTXOStats(CCoinsView
*view
, CCoinsStats
&stats
)
814 std::unique_ptr
<CCoinsViewCursor
> pcursor(view
->Cursor());
816 CHashWriter
ss(SER_GETHASH
, PROTOCOL_VERSION
);
817 stats
.hashBlock
= pcursor
->GetBestBlock();
820 stats
.nHeight
= mapBlockIndex
.find(stats
.hashBlock
)->second
->nHeight
;
822 ss
<< stats
.hashBlock
;
824 std::map
<uint32_t, Coin
> outputs
;
825 while (pcursor
->Valid()) {
826 boost::this_thread::interruption_point();
829 if (pcursor
->GetKey(key
) && pcursor
->GetValue(coin
)) {
830 if (!outputs
.empty() && key
.hash
!= prevkey
) {
831 ApplyStats(stats
, ss
, prevkey
, outputs
);
835 outputs
[key
.n
] = std::move(coin
);
837 return error("%s: unable to read value", __func__
);
841 if (!outputs
.empty()) {
842 ApplyStats(stats
, ss
, prevkey
, outputs
);
844 stats
.hashSerialized
= ss
.GetHash();
845 stats
.nDiskSize
= view
->EstimateSize();
849 UniValue
pruneblockchain(const JSONRPCRequest
& request
)
851 if (request
.fHelp
|| request
.params
.size() != 1)
852 throw std::runtime_error(
855 "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n"
856 " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n"
858 "n (numeric) Height of the last block pruned.\n"
860 + HelpExampleCli("pruneblockchain", "1000")
861 + HelpExampleRpc("pruneblockchain", "1000"));
864 throw JSONRPCError(RPC_MISC_ERROR
, "Cannot prune blocks because node is not in prune mode.");
868 int heightParam
= request
.params
[0].get_int();
870 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Negative block height.");
872 // Height value more than a billion is too high to be a block height, and
873 // too low to be a block time (corresponds to timestamp from Sep 2001).
874 if (heightParam
> 1000000000) {
875 // Add a 2 hour buffer to include blocks which might have had old timestamps
876 CBlockIndex
* pindex
= chainActive
.FindEarliestAtLeast(heightParam
- TIMESTAMP_WINDOW
);
878 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Could not find block with at least the specified timestamp.");
880 heightParam
= pindex
->nHeight
;
883 unsigned int height
= (unsigned int) heightParam
;
884 unsigned int chainHeight
= (unsigned int) chainActive
.Height();
885 if (chainHeight
< Params().PruneAfterHeight())
886 throw JSONRPCError(RPC_MISC_ERROR
, "Blockchain is too short for pruning.");
887 else if (height
> chainHeight
)
888 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Blockchain is shorter than the attempted prune height.");
889 else if (height
> chainHeight
- MIN_BLOCKS_TO_KEEP
) {
890 LogPrint(BCLog::RPC
, "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
891 height
= chainHeight
- MIN_BLOCKS_TO_KEEP
;
894 PruneBlockFilesManual(height
);
895 return uint64_t(height
);
898 UniValue
gettxoutsetinfo(const JSONRPCRequest
& request
)
900 if (request
.fHelp
|| request
.params
.size() != 0)
901 throw std::runtime_error(
903 "\nReturns statistics about the unspent transaction output set.\n"
904 "Note this call may take some time.\n"
907 " \"height\":n, (numeric) The current block height (index)\n"
908 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
909 " \"transactions\": n, (numeric) The number of transactions\n"
910 " \"txouts\": n, (numeric) The number of output transactions\n"
911 " \"bogosize\": n, (numeric) A meaningless metric for UTXO set size\n"
912 " \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
913 " \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
914 " \"total_amount\": x.xxx (numeric) The total amount\n"
917 + HelpExampleCli("gettxoutsetinfo", "")
918 + HelpExampleRpc("gettxoutsetinfo", "")
921 UniValue
ret(UniValue::VOBJ
);
925 if (GetUTXOStats(pcoinsdbview
, stats
)) {
926 ret
.push_back(Pair("height", (int64_t)stats
.nHeight
));
927 ret
.push_back(Pair("bestblock", stats
.hashBlock
.GetHex()));
928 ret
.push_back(Pair("transactions", (int64_t)stats
.nTransactions
));
929 ret
.push_back(Pair("txouts", (int64_t)stats
.nTransactionOutputs
));
930 ret
.push_back(Pair("bogosize", (int64_t)stats
.nBogoSize
));
931 ret
.push_back(Pair("hash_serialized_2", stats
.hashSerialized
.GetHex()));
932 ret
.push_back(Pair("disk_size", stats
.nDiskSize
));
933 ret
.push_back(Pair("total_amount", ValueFromAmount(stats
.nTotalAmount
)));
935 throw JSONRPCError(RPC_INTERNAL_ERROR
, "Unable to read UTXO set");
940 UniValue
gettxout(const JSONRPCRequest
& request
)
942 if (request
.fHelp
|| request
.params
.size() < 2 || request
.params
.size() > 3)
943 throw std::runtime_error(
944 "gettxout \"txid\" n ( include_mempool )\n"
945 "\nReturns details about an unspent transaction output.\n"
947 "1. \"txid\" (string, required) The transaction id\n"
948 "2. \"n\" (numeric, required) vout number\n"
949 "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true."
950 " Note that an unspent output that is spent in the mempool won't appear.\n"
953 " \"bestblock\" : \"hash\", (string) the block hash\n"
954 " \"confirmations\" : n, (numeric) The number of confirmations\n"
955 " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT
+ "\n"
956 " \"scriptPubKey\" : { (json object)\n"
957 " \"asm\" : \"code\", (string) \n"
958 " \"hex\" : \"hex\", (string) \n"
959 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
960 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
961 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
962 " \"address\" (string) bitcoin address\n"
966 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
970 "\nGet unspent transactions\n"
971 + HelpExampleCli("listunspent", "") +
972 "\nView the details\n"
973 + HelpExampleCli("gettxout", "\"txid\" 1") +
974 "\nAs a json rpc call\n"
975 + HelpExampleRpc("gettxout", "\"txid\", 1")
980 UniValue
ret(UniValue::VOBJ
);
982 std::string strHash
= request
.params
[0].get_str();
983 uint256
hash(uint256S(strHash
));
984 int n
= request
.params
[1].get_int();
985 COutPoint
out(hash
, n
);
986 bool fMempool
= true;
987 if (!request
.params
[2].isNull())
988 fMempool
= request
.params
[2].get_bool();
993 CCoinsViewMemPool
view(pcoinsTip
, mempool
);
994 if (!view
.GetCoin(out
, coin
) || mempool
.isSpent(out
)) {
998 if (!pcoinsTip
->GetCoin(out
, coin
)) {
1003 BlockMap::iterator it
= mapBlockIndex
.find(pcoinsTip
->GetBestBlock());
1004 CBlockIndex
*pindex
= it
->second
;
1005 ret
.push_back(Pair("bestblock", pindex
->GetBlockHash().GetHex()));
1006 if (coin
.nHeight
== MEMPOOL_HEIGHT
) {
1007 ret
.push_back(Pair("confirmations", 0));
1009 ret
.push_back(Pair("confirmations", (int64_t)(pindex
->nHeight
- coin
.nHeight
+ 1)));
1011 ret
.push_back(Pair("value", ValueFromAmount(coin
.out
.nValue
)));
1012 UniValue
o(UniValue::VOBJ
);
1013 ScriptPubKeyToUniv(coin
.out
.scriptPubKey
, o
, true);
1014 ret
.push_back(Pair("scriptPubKey", o
));
1015 ret
.push_back(Pair("coinbase", (bool)coin
.fCoinBase
));
1020 UniValue
verifychain(const JSONRPCRequest
& request
)
1022 int nCheckLevel
= gArgs
.GetArg("-checklevel", DEFAULT_CHECKLEVEL
);
1023 int nCheckDepth
= gArgs
.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS
);
1024 if (request
.fHelp
|| request
.params
.size() > 2)
1025 throw std::runtime_error(
1026 "verifychain ( checklevel nblocks )\n"
1027 "\nVerifies blockchain database.\n"
1029 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel
) + ") How thorough the block verification is.\n"
1030 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth
) + ", 0=all) The number of blocks to check.\n"
1032 "true|false (boolean) Verified or not\n"
1034 + HelpExampleCli("verifychain", "")
1035 + HelpExampleRpc("verifychain", "")
1040 if (!request
.params
[0].isNull())
1041 nCheckLevel
= request
.params
[0].get_int();
1042 if (!request
.params
[1].isNull())
1043 nCheckDepth
= request
.params
[1].get_int();
1045 return CVerifyDB().VerifyDB(Params(), pcoinsTip
, nCheckLevel
, nCheckDepth
);
1048 /** Implementation of IsSuperMajority with better feedback */
1049 static UniValue
SoftForkMajorityDesc(int version
, CBlockIndex
* pindex
, const Consensus::Params
& consensusParams
)
1051 UniValue
rv(UniValue::VOBJ
);
1052 bool activated
= false;
1056 activated
= pindex
->nHeight
>= consensusParams
.BIP34Height
;
1059 activated
= pindex
->nHeight
>= consensusParams
.BIP66Height
;
1062 activated
= pindex
->nHeight
>= consensusParams
.BIP65Height
;
1065 rv
.push_back(Pair("status", activated
));
1069 static UniValue
SoftForkDesc(const std::string
&name
, int version
, CBlockIndex
* pindex
, const Consensus::Params
& consensusParams
)
1071 UniValue
rv(UniValue::VOBJ
);
1072 rv
.push_back(Pair("id", name
));
1073 rv
.push_back(Pair("version", version
));
1074 rv
.push_back(Pair("reject", SoftForkMajorityDesc(version
, pindex
, consensusParams
)));
1078 static UniValue
BIP9SoftForkDesc(const Consensus::Params
& consensusParams
, Consensus::DeploymentPos id
)
1080 UniValue
rv(UniValue::VOBJ
);
1081 const ThresholdState thresholdState
= VersionBitsTipState(consensusParams
, id
);
1082 switch (thresholdState
) {
1083 case THRESHOLD_DEFINED
: rv
.push_back(Pair("status", "defined")); break;
1084 case THRESHOLD_STARTED
: rv
.push_back(Pair("status", "started")); break;
1085 case THRESHOLD_LOCKED_IN
: rv
.push_back(Pair("status", "locked_in")); break;
1086 case THRESHOLD_ACTIVE
: rv
.push_back(Pair("status", "active")); break;
1087 case THRESHOLD_FAILED
: rv
.push_back(Pair("status", "failed")); break;
1089 if (THRESHOLD_STARTED
== thresholdState
)
1091 rv
.push_back(Pair("bit", consensusParams
.vDeployments
[id
].bit
));
1093 rv
.push_back(Pair("startTime", consensusParams
.vDeployments
[id
].nStartTime
));
1094 rv
.push_back(Pair("timeout", consensusParams
.vDeployments
[id
].nTimeout
));
1095 rv
.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams
, id
)));
1096 if (THRESHOLD_STARTED
== thresholdState
)
1098 UniValue
statsUV(UniValue::VOBJ
);
1099 BIP9Stats statsStruct
= VersionBitsTipStatistics(consensusParams
, id
);
1100 statsUV
.push_back(Pair("period", statsStruct
.period
));
1101 statsUV
.push_back(Pair("threshold", statsStruct
.threshold
));
1102 statsUV
.push_back(Pair("elapsed", statsStruct
.elapsed
));
1103 statsUV
.push_back(Pair("count", statsStruct
.count
));
1104 statsUV
.push_back(Pair("possible", statsStruct
.possible
));
1105 rv
.push_back(Pair("statistics", statsUV
));
1110 void BIP9SoftForkDescPushBack(UniValue
& bip9_softforks
, const std::string
&name
, const Consensus::Params
& consensusParams
, Consensus::DeploymentPos id
)
1112 // Deployments with timeout value of 0 are hidden.
1113 // A timeout value of 0 guarantees a softfork will never be activated.
1114 // This is used when softfork codes are merged without specifying the deployment schedule.
1115 if (consensusParams
.vDeployments
[id
].nTimeout
> 0)
1116 bip9_softforks
.push_back(Pair(name
, BIP9SoftForkDesc(consensusParams
, id
)));
1119 UniValue
getblockchaininfo(const JSONRPCRequest
& request
)
1121 if (request
.fHelp
|| request
.params
.size() != 0)
1122 throw std::runtime_error(
1123 "getblockchaininfo\n"
1124 "Returns an object containing various state info regarding blockchain processing.\n"
1127 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1128 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1129 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1130 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1131 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1132 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1133 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1134 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1135 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1136 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1137 " \"softforks\": [ (array) status of softforks in progress\n"
1139 " \"id\": \"xxxx\", (string) name of softfork\n"
1140 " \"version\": xx, (numeric) block version\n"
1141 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1142 " \"status\": xx, (boolean) true if threshold reached\n"
1146 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1147 " \"xxxx\" : { (string) name of the softfork\n"
1148 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1149 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1150 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1151 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1152 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1153 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1154 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1155 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1156 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1157 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1158 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1164 + HelpExampleCli("getblockchaininfo", "")
1165 + HelpExampleRpc("getblockchaininfo", "")
1170 UniValue
obj(UniValue::VOBJ
);
1171 obj
.push_back(Pair("chain", Params().NetworkIDString()));
1172 obj
.push_back(Pair("blocks", (int)chainActive
.Height()));
1173 obj
.push_back(Pair("headers", pindexBestHeader
? pindexBestHeader
->nHeight
: -1));
1174 obj
.push_back(Pair("bestblockhash", chainActive
.Tip()->GetBlockHash().GetHex()));
1175 obj
.push_back(Pair("difficulty", (double)GetDifficulty()));
1176 obj
.push_back(Pair("mediantime", (int64_t)chainActive
.Tip()->GetMedianTimePast()));
1177 obj
.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive
.Tip())));
1178 obj
.push_back(Pair("chainwork", chainActive
.Tip()->nChainWork
.GetHex()));
1179 obj
.push_back(Pair("pruned", fPruneMode
));
1181 const Consensus::Params
& consensusParams
= Params().GetConsensus();
1182 CBlockIndex
* tip
= chainActive
.Tip();
1183 UniValue
softforks(UniValue::VARR
);
1184 UniValue
bip9_softforks(UniValue::VOBJ
);
1185 softforks
.push_back(SoftForkDesc("bip34", 2, tip
, consensusParams
));
1186 softforks
.push_back(SoftForkDesc("bip66", 3, tip
, consensusParams
));
1187 softforks
.push_back(SoftForkDesc("bip65", 4, tip
, consensusParams
));
1188 BIP9SoftForkDescPushBack(bip9_softforks
, "csv", consensusParams
, Consensus::DEPLOYMENT_CSV
);
1189 BIP9SoftForkDescPushBack(bip9_softforks
, "segwit", consensusParams
, Consensus::DEPLOYMENT_SEGWIT
);
1190 obj
.push_back(Pair("softforks", softforks
));
1191 obj
.push_back(Pair("bip9_softforks", bip9_softforks
));
1195 CBlockIndex
*block
= chainActive
.Tip();
1196 while (block
&& block
->pprev
&& (block
->pprev
->nStatus
& BLOCK_HAVE_DATA
))
1197 block
= block
->pprev
;
1199 obj
.push_back(Pair("pruneheight", block
->nHeight
));
1204 /** Comparison function for sorting the getchaintips heads. */
1205 struct CompareBlocksByHeight
1207 bool operator()(const CBlockIndex
* a
, const CBlockIndex
* b
) const
1209 /* Make sure that unequal blocks with the same height do not compare
1210 equal. Use the pointers themselves to make a distinction. */
1212 if (a
->nHeight
!= b
->nHeight
)
1213 return (a
->nHeight
> b
->nHeight
);
1219 UniValue
getchaintips(const JSONRPCRequest
& request
)
1221 if (request
.fHelp
|| request
.params
.size() != 0)
1222 throw std::runtime_error(
1224 "Return information about all known tips in the block tree,"
1225 " including the main chain as well as orphaned branches.\n"
1229 " \"height\": xxxx, (numeric) height of the chain tip\n"
1230 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1231 " \"branchlen\": 0 (numeric) zero for main chain\n"
1232 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1235 " \"height\": xxxx,\n"
1236 " \"hash\": \"xxxx\",\n"
1237 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1238 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1241 "Possible values for status:\n"
1242 "1. \"invalid\" This branch contains at least one invalid block\n"
1243 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1244 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1245 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1246 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1248 + HelpExampleCli("getchaintips", "")
1249 + HelpExampleRpc("getchaintips", "")
1255 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1257 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1258 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1259 * - add chainActive.Tip()
1261 std::set
<const CBlockIndex
*, CompareBlocksByHeight
> setTips
;
1262 std::set
<const CBlockIndex
*> setOrphans
;
1263 std::set
<const CBlockIndex
*> setPrevs
;
1265 for (const std::pair
<const uint256
, CBlockIndex
*>& item
: mapBlockIndex
)
1267 if (!chainActive
.Contains(item
.second
)) {
1268 setOrphans
.insert(item
.second
);
1269 setPrevs
.insert(item
.second
->pprev
);
1273 for (std::set
<const CBlockIndex
*>::iterator it
= setOrphans
.begin(); it
!= setOrphans
.end(); ++it
)
1275 if (setPrevs
.erase(*it
) == 0) {
1276 setTips
.insert(*it
);
1280 // Always report the currently active tip.
1281 setTips
.insert(chainActive
.Tip());
1283 /* Construct the output array. */
1284 UniValue
res(UniValue::VARR
);
1285 for (const CBlockIndex
* block
: setTips
)
1287 UniValue
obj(UniValue::VOBJ
);
1288 obj
.push_back(Pair("height", block
->nHeight
));
1289 obj
.push_back(Pair("hash", block
->phashBlock
->GetHex()));
1291 const int branchLen
= block
->nHeight
- chainActive
.FindFork(block
)->nHeight
;
1292 obj
.push_back(Pair("branchlen", branchLen
));
1295 if (chainActive
.Contains(block
)) {
1296 // This block is part of the currently active chain.
1298 } else if (block
->nStatus
& BLOCK_FAILED_MASK
) {
1299 // This block or one of its ancestors is invalid.
1301 } else if (block
->nChainTx
== 0) {
1302 // This block cannot be connected because full block data for it or one of its parents is missing.
1303 status
= "headers-only";
1304 } else if (block
->IsValid(BLOCK_VALID_SCRIPTS
)) {
1305 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1306 status
= "valid-fork";
1307 } else if (block
->IsValid(BLOCK_VALID_TREE
)) {
1308 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1309 status
= "valid-headers";
1314 obj
.push_back(Pair("status", status
));
1322 UniValue
mempoolInfoToJSON()
1324 UniValue
ret(UniValue::VOBJ
);
1325 ret
.push_back(Pair("size", (int64_t) mempool
.size()));
1326 ret
.push_back(Pair("bytes", (int64_t) mempool
.GetTotalTxSize()));
1327 ret
.push_back(Pair("usage", (int64_t) mempool
.DynamicMemoryUsage()));
1328 size_t maxmempool
= gArgs
.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE
) * 1000000;
1329 ret
.push_back(Pair("maxmempool", (int64_t) maxmempool
));
1330 ret
.push_back(Pair("mempoolminfee", ValueFromAmount(mempool
.GetMinFee(maxmempool
).GetFeePerK())));
1335 UniValue
getmempoolinfo(const JSONRPCRequest
& request
)
1337 if (request
.fHelp
|| request
.params
.size() != 0)
1338 throw std::runtime_error(
1340 "\nReturns details on the active state of the TX memory pool.\n"
1343 " \"size\": xxxxx, (numeric) Current tx count\n"
1344 " \"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"
1345 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1346 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1347 " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT
+ "/kB for tx to be accepted\n"
1350 + HelpExampleCli("getmempoolinfo", "")
1351 + HelpExampleRpc("getmempoolinfo", "")
1354 return mempoolInfoToJSON();
1357 UniValue
preciousblock(const JSONRPCRequest
& request
)
1359 if (request
.fHelp
|| request
.params
.size() != 1)
1360 throw std::runtime_error(
1361 "preciousblock \"blockhash\"\n"
1362 "\nTreats a block as if it were received before others with the same work.\n"
1363 "\nA later preciousblock call can override the effect of an earlier one.\n"
1364 "\nThe effects of preciousblock are not retained across restarts.\n"
1366 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1369 + HelpExampleCli("preciousblock", "\"blockhash\"")
1370 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1373 std::string strHash
= request
.params
[0].get_str();
1374 uint256
hash(uint256S(strHash
));
1375 CBlockIndex
* pblockindex
;
1379 if (mapBlockIndex
.count(hash
) == 0)
1380 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1382 pblockindex
= mapBlockIndex
[hash
];
1385 CValidationState state
;
1386 PreciousBlock(state
, Params(), pblockindex
);
1388 if (!state
.IsValid()) {
1389 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1392 return NullUniValue
;
1395 UniValue
invalidateblock(const JSONRPCRequest
& request
)
1397 if (request
.fHelp
|| request
.params
.size() != 1)
1398 throw std::runtime_error(
1399 "invalidateblock \"blockhash\"\n"
1400 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1402 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1405 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1406 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1409 std::string strHash
= request
.params
[0].get_str();
1410 uint256
hash(uint256S(strHash
));
1411 CValidationState state
;
1415 if (mapBlockIndex
.count(hash
) == 0)
1416 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1418 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
1419 InvalidateBlock(state
, Params(), pblockindex
);
1422 if (state
.IsValid()) {
1423 ActivateBestChain(state
, Params());
1426 if (!state
.IsValid()) {
1427 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1430 return NullUniValue
;
1433 UniValue
reconsiderblock(const JSONRPCRequest
& request
)
1435 if (request
.fHelp
|| request
.params
.size() != 1)
1436 throw std::runtime_error(
1437 "reconsiderblock \"blockhash\"\n"
1438 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1439 "This can be used to undo the effects of invalidateblock.\n"
1441 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1444 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1445 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1448 std::string strHash
= request
.params
[0].get_str();
1449 uint256
hash(uint256S(strHash
));
1453 if (mapBlockIndex
.count(hash
) == 0)
1454 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1456 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
1457 ResetBlockFailureFlags(pblockindex
);
1460 CValidationState state
;
1461 ActivateBestChain(state
, Params());
1463 if (!state
.IsValid()) {
1464 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1467 return NullUniValue
;
1470 UniValue
getchaintxstats(const JSONRPCRequest
& request
)
1472 if (request
.fHelp
|| request
.params
.size() > 2)
1473 throw std::runtime_error(
1474 "getchaintxstats ( nblocks blockhash )\n"
1475 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1477 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1478 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1481 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1482 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1483 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1486 + HelpExampleCli("getchaintxstats", "")
1487 + HelpExampleRpc("getchaintxstats", "2016")
1490 const CBlockIndex
* pindex
;
1491 int blockcount
= 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing
; // By default: 1 month
1493 if (!request
.params
[0].isNull()) {
1494 blockcount
= request
.params
[0].get_int();
1497 bool havehash
= !request
.params
[1].isNull();
1500 hash
= uint256S(request
.params
[1].get_str());
1506 auto it
= mapBlockIndex
.find(hash
);
1507 if (it
== mapBlockIndex
.end()) {
1508 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1510 pindex
= it
->second
;
1511 if (!chainActive
.Contains(pindex
)) {
1512 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Block is not in main chain");
1515 pindex
= chainActive
.Tip();
1519 if (blockcount
< 1 || blockcount
>= pindex
->nHeight
) {
1520 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid block count: should be between 1 and the block's height");
1523 const CBlockIndex
* pindexPast
= pindex
->GetAncestor(pindex
->nHeight
- blockcount
);
1524 int nTimeDiff
= pindex
->GetMedianTimePast() - pindexPast
->GetMedianTimePast();
1525 int nTxDiff
= pindex
->nChainTx
- pindexPast
->nChainTx
;
1527 UniValue
ret(UniValue::VOBJ
);
1528 ret
.push_back(Pair("time", (int64_t)pindex
->nTime
));
1529 ret
.push_back(Pair("txcount", (int64_t)pindex
->nChainTx
));
1530 ret
.push_back(Pair("txrate", ((double)nTxDiff
) / nTimeDiff
));
1535 static const CRPCCommand commands
[] =
1536 { // category name actor (function) argNames
1537 // --------------------- ------------------------ ----------------------- ----------
1538 { "blockchain", "getblockchaininfo", &getblockchaininfo
, {} },
1539 { "blockchain", "getchaintxstats", &getchaintxstats
, {"nblocks", "blockhash"} },
1540 { "blockchain", "getbestblockhash", &getbestblockhash
, {} },
1541 { "blockchain", "getblockcount", &getblockcount
, {} },
1542 { "blockchain", "getblock", &getblock
, {"blockhash","verbosity|verbose"} },
1543 { "blockchain", "getblockhash", &getblockhash
, {"height"} },
1544 { "blockchain", "getblockheader", &getblockheader
, {"blockhash","verbose"} },
1545 { "blockchain", "getchaintips", &getchaintips
, {} },
1546 { "blockchain", "getdifficulty", &getdifficulty
, {} },
1547 { "blockchain", "getmempoolancestors", &getmempoolancestors
, {"txid","verbose"} },
1548 { "blockchain", "getmempooldescendants", &getmempooldescendants
, {"txid","verbose"} },
1549 { "blockchain", "getmempoolentry", &getmempoolentry
, {"txid"} },
1550 { "blockchain", "getmempoolinfo", &getmempoolinfo
, {} },
1551 { "blockchain", "getrawmempool", &getrawmempool
, {"verbose"} },
1552 { "blockchain", "gettxout", &gettxout
, {"txid","n","include_mempool"} },
1553 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo
, {} },
1554 { "blockchain", "pruneblockchain", &pruneblockchain
, {"height"} },
1555 { "blockchain", "verifychain", &verifychain
, {"checklevel","nblocks"} },
1557 { "blockchain", "preciousblock", &preciousblock
, {"blockhash"} },
1559 /* Not shown in help */
1560 { "hidden", "invalidateblock", &invalidateblock
, {"blockhash"} },
1561 { "hidden", "reconsiderblock", &reconsiderblock
, {"blockhash"} },
1562 { "hidden", "waitfornewblock", &waitfornewblock
, {"timeout"} },
1563 { "hidden", "waitforblock", &waitforblock
, {"blockhash","timeout"} },
1564 { "hidden", "waitforblockheight", &waitforblockheight
, {"height","timeout"} },
1567 void RegisterBlockchainRPCCommands(CRPCTable
&t
)
1569 for (unsigned int vcidx
= 0; vcidx
< ARRAYLEN(commands
); vcidx
++)
1570 t
.appendCommand(commands
[vcidx
].name
, &commands
[vcidx
]);