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
== NULL
)
53 if (chainActive
.Tip() == NULL
)
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
);
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
.size() > 0)
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
.size() > 1)
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
.size() > 1)
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
.size() > 0)
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
.size() > 1)
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
.size() > 1)
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
.size() > 1)
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
.size() > 1) {
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 " \"version\" : n, (numeric) The version\n"
967 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
971 "\nGet unspent transactions\n"
972 + HelpExampleCli("listunspent", "") +
973 "\nView the details\n"
974 + HelpExampleCli("gettxout", "\"txid\" 1") +
975 "\nAs a json rpc call\n"
976 + HelpExampleRpc("gettxout", "\"txid\", 1")
981 UniValue
ret(UniValue::VOBJ
);
983 std::string strHash
= request
.params
[0].get_str();
984 uint256
hash(uint256S(strHash
));
985 int n
= request
.params
[1].get_int();
986 COutPoint
out(hash
, n
);
987 bool fMempool
= true;
988 if (request
.params
.size() > 2)
989 fMempool
= request
.params
[2].get_bool();
994 CCoinsViewMemPool
view(pcoinsTip
, mempool
);
995 if (!view
.GetCoin(out
, coin
) || mempool
.isSpent(out
)) {
999 if (!pcoinsTip
->GetCoin(out
, coin
)) {
1000 return NullUniValue
;
1004 BlockMap::iterator it
= mapBlockIndex
.find(pcoinsTip
->GetBestBlock());
1005 CBlockIndex
*pindex
= it
->second
;
1006 ret
.push_back(Pair("bestblock", pindex
->GetBlockHash().GetHex()));
1007 if (coin
.nHeight
== MEMPOOL_HEIGHT
) {
1008 ret
.push_back(Pair("confirmations", 0));
1010 ret
.push_back(Pair("confirmations", (int64_t)(pindex
->nHeight
- coin
.nHeight
+ 1)));
1012 ret
.push_back(Pair("value", ValueFromAmount(coin
.out
.nValue
)));
1013 UniValue
o(UniValue::VOBJ
);
1014 ScriptPubKeyToUniv(coin
.out
.scriptPubKey
, o
, true);
1015 ret
.push_back(Pair("scriptPubKey", o
));
1016 ret
.push_back(Pair("coinbase", (bool)coin
.fCoinBase
));
1021 UniValue
verifychain(const JSONRPCRequest
& request
)
1023 int nCheckLevel
= GetArg("-checklevel", DEFAULT_CHECKLEVEL
);
1024 int nCheckDepth
= GetArg("-checkblocks", DEFAULT_CHECKBLOCKS
);
1025 if (request
.fHelp
|| request
.params
.size() > 2)
1026 throw std::runtime_error(
1027 "verifychain ( checklevel nblocks )\n"
1028 "\nVerifies blockchain database.\n"
1030 "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel
) + ") How thorough the block verification is.\n"
1031 "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth
) + ", 0=all) The number of blocks to check.\n"
1033 "true|false (boolean) Verified or not\n"
1035 + HelpExampleCli("verifychain", "")
1036 + HelpExampleRpc("verifychain", "")
1041 if (request
.params
.size() > 0)
1042 nCheckLevel
= request
.params
[0].get_int();
1043 if (request
.params
.size() > 1)
1044 nCheckDepth
= request
.params
[1].get_int();
1046 return CVerifyDB().VerifyDB(Params(), pcoinsTip
, nCheckLevel
, nCheckDepth
);
1049 /** Implementation of IsSuperMajority with better feedback */
1050 static UniValue
SoftForkMajorityDesc(int version
, CBlockIndex
* pindex
, const Consensus::Params
& consensusParams
)
1052 UniValue
rv(UniValue::VOBJ
);
1053 bool activated
= false;
1057 activated
= pindex
->nHeight
>= consensusParams
.BIP34Height
;
1060 activated
= pindex
->nHeight
>= consensusParams
.BIP66Height
;
1063 activated
= pindex
->nHeight
>= consensusParams
.BIP65Height
;
1066 rv
.push_back(Pair("status", activated
));
1070 static UniValue
SoftForkDesc(const std::string
&name
, int version
, CBlockIndex
* pindex
, const Consensus::Params
& consensusParams
)
1072 UniValue
rv(UniValue::VOBJ
);
1073 rv
.push_back(Pair("id", name
));
1074 rv
.push_back(Pair("version", version
));
1075 rv
.push_back(Pair("reject", SoftForkMajorityDesc(version
, pindex
, consensusParams
)));
1079 static UniValue
BIP9SoftForkDesc(const Consensus::Params
& consensusParams
, Consensus::DeploymentPos id
)
1081 UniValue
rv(UniValue::VOBJ
);
1082 const ThresholdState thresholdState
= VersionBitsTipState(consensusParams
, id
);
1083 switch (thresholdState
) {
1084 case THRESHOLD_DEFINED
: rv
.push_back(Pair("status", "defined")); break;
1085 case THRESHOLD_STARTED
: rv
.push_back(Pair("status", "started")); break;
1086 case THRESHOLD_LOCKED_IN
: rv
.push_back(Pair("status", "locked_in")); break;
1087 case THRESHOLD_ACTIVE
: rv
.push_back(Pair("status", "active")); break;
1088 case THRESHOLD_FAILED
: rv
.push_back(Pair("status", "failed")); break;
1090 if (THRESHOLD_STARTED
== thresholdState
)
1092 rv
.push_back(Pair("bit", consensusParams
.vDeployments
[id
].bit
));
1094 rv
.push_back(Pair("startTime", consensusParams
.vDeployments
[id
].nStartTime
));
1095 rv
.push_back(Pair("timeout", consensusParams
.vDeployments
[id
].nTimeout
));
1096 rv
.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams
, id
)));
1097 if (THRESHOLD_STARTED
== thresholdState
)
1099 UniValue
statsUV(UniValue::VOBJ
);
1100 BIP9Stats statsStruct
= VersionBitsTipStatistics(consensusParams
, id
);
1101 statsUV
.push_back(Pair("period", statsStruct
.period
));
1102 statsUV
.push_back(Pair("threshold", statsStruct
.threshold
));
1103 statsUV
.push_back(Pair("elapsed", statsStruct
.elapsed
));
1104 statsUV
.push_back(Pair("count", statsStruct
.count
));
1105 statsUV
.push_back(Pair("possible", statsStruct
.possible
));
1106 rv
.push_back(Pair("statistics", statsUV
));
1111 void BIP9SoftForkDescPushBack(UniValue
& bip9_softforks
, const std::string
&name
, const Consensus::Params
& consensusParams
, Consensus::DeploymentPos id
)
1113 // Deployments with timeout value of 0 are hidden.
1114 // A timeout value of 0 guarantees a softfork will never be activated.
1115 // This is used when softfork codes are merged without specifying the deployment schedule.
1116 if (consensusParams
.vDeployments
[id
].nTimeout
> 0)
1117 bip9_softforks
.push_back(Pair(name
, BIP9SoftForkDesc(consensusParams
, id
)));
1120 UniValue
getblockchaininfo(const JSONRPCRequest
& request
)
1122 if (request
.fHelp
|| request
.params
.size() != 0)
1123 throw std::runtime_error(
1124 "getblockchaininfo\n"
1125 "Returns an object containing various state info regarding blockchain processing.\n"
1128 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
1129 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
1130 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
1131 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
1132 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
1133 " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
1134 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
1135 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
1136 " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
1137 " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
1138 " \"softforks\": [ (array) status of softforks in progress\n"
1140 " \"id\": \"xxxx\", (string) name of softfork\n"
1141 " \"version\": xx, (numeric) block version\n"
1142 " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
1143 " \"status\": xx, (boolean) true if threshold reached\n"
1147 " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"
1148 " \"xxxx\" : { (string) name of the softfork\n"
1149 " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
1150 " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
1151 " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
1152 " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
1153 " \"since\": xx, (numeric) height of the first block to which the status applies\n"
1154 " \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)\n"
1155 " \"period\": xx, (numeric) the length in blocks of the BIP9 signalling period \n"
1156 " \"threshold\": xx, (numeric) the number of blocks with the version bit set required to activate the feature \n"
1157 " \"elapsed\": xx, (numeric) the number of blocks elapsed since the beginning of the current period \n"
1158 " \"count\": xx, (numeric) the number of blocks with the version bit set in the current period \n"
1159 " \"possible\": xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
1165 + HelpExampleCli("getblockchaininfo", "")
1166 + HelpExampleRpc("getblockchaininfo", "")
1171 UniValue
obj(UniValue::VOBJ
);
1172 obj
.push_back(Pair("chain", Params().NetworkIDString()));
1173 obj
.push_back(Pair("blocks", (int)chainActive
.Height()));
1174 obj
.push_back(Pair("headers", pindexBestHeader
? pindexBestHeader
->nHeight
: -1));
1175 obj
.push_back(Pair("bestblockhash", chainActive
.Tip()->GetBlockHash().GetHex()));
1176 obj
.push_back(Pair("difficulty", (double)GetDifficulty()));
1177 obj
.push_back(Pair("mediantime", (int64_t)chainActive
.Tip()->GetMedianTimePast()));
1178 obj
.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive
.Tip())));
1179 obj
.push_back(Pair("chainwork", chainActive
.Tip()->nChainWork
.GetHex()));
1180 obj
.push_back(Pair("pruned", fPruneMode
));
1182 const Consensus::Params
& consensusParams
= Params().GetConsensus();
1183 CBlockIndex
* tip
= chainActive
.Tip();
1184 UniValue
softforks(UniValue::VARR
);
1185 UniValue
bip9_softforks(UniValue::VOBJ
);
1186 softforks
.push_back(SoftForkDesc("bip34", 2, tip
, consensusParams
));
1187 softforks
.push_back(SoftForkDesc("bip66", 3, tip
, consensusParams
));
1188 softforks
.push_back(SoftForkDesc("bip65", 4, tip
, consensusParams
));
1189 BIP9SoftForkDescPushBack(bip9_softforks
, "csv", consensusParams
, Consensus::DEPLOYMENT_CSV
);
1190 BIP9SoftForkDescPushBack(bip9_softforks
, "segwit", consensusParams
, Consensus::DEPLOYMENT_SEGWIT
);
1191 obj
.push_back(Pair("softforks", softforks
));
1192 obj
.push_back(Pair("bip9_softforks", bip9_softforks
));
1196 CBlockIndex
*block
= chainActive
.Tip();
1197 while (block
&& block
->pprev
&& (block
->pprev
->nStatus
& BLOCK_HAVE_DATA
))
1198 block
= block
->pprev
;
1200 obj
.push_back(Pair("pruneheight", block
->nHeight
));
1205 /** Comparison function for sorting the getchaintips heads. */
1206 struct CompareBlocksByHeight
1208 bool operator()(const CBlockIndex
* a
, const CBlockIndex
* b
) const
1210 /* Make sure that unequal blocks with the same height do not compare
1211 equal. Use the pointers themselves to make a distinction. */
1213 if (a
->nHeight
!= b
->nHeight
)
1214 return (a
->nHeight
> b
->nHeight
);
1220 UniValue
getchaintips(const JSONRPCRequest
& request
)
1222 if (request
.fHelp
|| request
.params
.size() != 0)
1223 throw std::runtime_error(
1225 "Return information about all known tips in the block tree,"
1226 " including the main chain as well as orphaned branches.\n"
1230 " \"height\": xxxx, (numeric) height of the chain tip\n"
1231 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
1232 " \"branchlen\": 0 (numeric) zero for main chain\n"
1233 " \"status\": \"active\" (string) \"active\" for the main chain\n"
1236 " \"height\": xxxx,\n"
1237 " \"hash\": \"xxxx\",\n"
1238 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1239 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
1242 "Possible values for status:\n"
1243 "1. \"invalid\" This branch contains at least one invalid block\n"
1244 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1245 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1246 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1247 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
1249 + HelpExampleCli("getchaintips", "")
1250 + HelpExampleRpc("getchaintips", "")
1256 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
1258 * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1259 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1260 * - add chainActive.Tip()
1262 std::set
<const CBlockIndex
*, CompareBlocksByHeight
> setTips
;
1263 std::set
<const CBlockIndex
*> setOrphans
;
1264 std::set
<const CBlockIndex
*> setPrevs
;
1266 for (const std::pair
<const uint256
, CBlockIndex
*>& item
: mapBlockIndex
)
1268 if (!chainActive
.Contains(item
.second
)) {
1269 setOrphans
.insert(item
.second
);
1270 setPrevs
.insert(item
.second
->pprev
);
1274 for (std::set
<const CBlockIndex
*>::iterator it
= setOrphans
.begin(); it
!= setOrphans
.end(); ++it
)
1276 if (setPrevs
.erase(*it
) == 0) {
1277 setTips
.insert(*it
);
1281 // Always report the currently active tip.
1282 setTips
.insert(chainActive
.Tip());
1284 /* Construct the output array. */
1285 UniValue
res(UniValue::VARR
);
1286 for (const CBlockIndex
* block
: setTips
)
1288 UniValue
obj(UniValue::VOBJ
);
1289 obj
.push_back(Pair("height", block
->nHeight
));
1290 obj
.push_back(Pair("hash", block
->phashBlock
->GetHex()));
1292 const int branchLen
= block
->nHeight
- chainActive
.FindFork(block
)->nHeight
;
1293 obj
.push_back(Pair("branchlen", branchLen
));
1296 if (chainActive
.Contains(block
)) {
1297 // This block is part of the currently active chain.
1299 } else if (block
->nStatus
& BLOCK_FAILED_MASK
) {
1300 // This block or one of its ancestors is invalid.
1302 } else if (block
->nChainTx
== 0) {
1303 // This block cannot be connected because full block data for it or one of its parents is missing.
1304 status
= "headers-only";
1305 } else if (block
->IsValid(BLOCK_VALID_SCRIPTS
)) {
1306 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
1307 status
= "valid-fork";
1308 } else if (block
->IsValid(BLOCK_VALID_TREE
)) {
1309 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
1310 status
= "valid-headers";
1315 obj
.push_back(Pair("status", status
));
1323 UniValue
mempoolInfoToJSON()
1325 UniValue
ret(UniValue::VOBJ
);
1326 ret
.push_back(Pair("size", (int64_t) mempool
.size()));
1327 ret
.push_back(Pair("bytes", (int64_t) mempool
.GetTotalTxSize()));
1328 ret
.push_back(Pair("usage", (int64_t) mempool
.DynamicMemoryUsage()));
1329 size_t maxmempool
= GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE
) * 1000000;
1330 ret
.push_back(Pair("maxmempool", (int64_t) maxmempool
));
1331 ret
.push_back(Pair("mempoolminfee", ValueFromAmount(mempool
.GetMinFee(maxmempool
).GetFeePerK())));
1336 UniValue
getmempoolinfo(const JSONRPCRequest
& request
)
1338 if (request
.fHelp
|| request
.params
.size() != 0)
1339 throw std::runtime_error(
1341 "\nReturns details on the active state of the TX memory pool.\n"
1344 " \"size\": xxxxx, (numeric) Current tx count\n"
1345 " \"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"
1346 " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
1347 " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
1348 " \"mempoolminfee\": xxxxx (numeric) Minimum feerate (" + CURRENCY_UNIT
+ " per KB) for tx to be accepted\n"
1351 + HelpExampleCli("getmempoolinfo", "")
1352 + HelpExampleRpc("getmempoolinfo", "")
1355 return mempoolInfoToJSON();
1358 UniValue
preciousblock(const JSONRPCRequest
& request
)
1360 if (request
.fHelp
|| request
.params
.size() != 1)
1361 throw std::runtime_error(
1362 "preciousblock \"blockhash\"\n"
1363 "\nTreats a block as if it were received before others with the same work.\n"
1364 "\nA later preciousblock call can override the effect of an earlier one.\n"
1365 "\nThe effects of preciousblock are not retained across restarts.\n"
1367 "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
1370 + HelpExampleCli("preciousblock", "\"blockhash\"")
1371 + HelpExampleRpc("preciousblock", "\"blockhash\"")
1374 std::string strHash
= request
.params
[0].get_str();
1375 uint256
hash(uint256S(strHash
));
1376 CBlockIndex
* pblockindex
;
1380 if (mapBlockIndex
.count(hash
) == 0)
1381 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1383 pblockindex
= mapBlockIndex
[hash
];
1386 CValidationState state
;
1387 PreciousBlock(state
, Params(), pblockindex
);
1389 if (!state
.IsValid()) {
1390 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1393 return NullUniValue
;
1396 UniValue
invalidateblock(const JSONRPCRequest
& request
)
1398 if (request
.fHelp
|| request
.params
.size() != 1)
1399 throw std::runtime_error(
1400 "invalidateblock \"blockhash\"\n"
1401 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
1403 "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
1406 + HelpExampleCli("invalidateblock", "\"blockhash\"")
1407 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
1410 std::string strHash
= request
.params
[0].get_str();
1411 uint256
hash(uint256S(strHash
));
1412 CValidationState state
;
1416 if (mapBlockIndex
.count(hash
) == 0)
1417 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1419 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
1420 InvalidateBlock(state
, Params(), pblockindex
);
1423 if (state
.IsValid()) {
1424 ActivateBestChain(state
, Params());
1427 if (!state
.IsValid()) {
1428 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1431 return NullUniValue
;
1434 UniValue
reconsiderblock(const JSONRPCRequest
& request
)
1436 if (request
.fHelp
|| request
.params
.size() != 1)
1437 throw std::runtime_error(
1438 "reconsiderblock \"blockhash\"\n"
1439 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
1440 "This can be used to undo the effects of invalidateblock.\n"
1442 "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
1445 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
1446 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
1449 std::string strHash
= request
.params
[0].get_str();
1450 uint256
hash(uint256S(strHash
));
1454 if (mapBlockIndex
.count(hash
) == 0)
1455 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1457 CBlockIndex
* pblockindex
= mapBlockIndex
[hash
];
1458 ResetBlockFailureFlags(pblockindex
);
1461 CValidationState state
;
1462 ActivateBestChain(state
, Params());
1464 if (!state
.IsValid()) {
1465 throw JSONRPCError(RPC_DATABASE_ERROR
, state
.GetRejectReason());
1468 return NullUniValue
;
1471 UniValue
getchaintxstats(const JSONRPCRequest
& request
)
1473 if (request
.fHelp
|| request
.params
.size() > 2)
1474 throw std::runtime_error(
1475 "getchaintxstats ( nblocks blockhash )\n"
1476 "\nCompute statistics about the total number and rate of transactions in the chain.\n"
1478 "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n"
1479 "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n"
1482 " \"time\": xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n"
1483 " \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
1484 " \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
1487 + HelpExampleCli("getchaintxstats", "")
1488 + HelpExampleRpc("getchaintxstats", "2016")
1491 const CBlockIndex
* pindex
;
1492 int blockcount
= 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing
; // By default: 1 month
1494 if (request
.params
.size() > 0 && !request
.params
[0].isNull()) {
1495 blockcount
= request
.params
[0].get_int();
1498 bool havehash
= request
.params
.size() > 1 && !request
.params
[1].isNull();
1501 hash
= uint256S(request
.params
[1].get_str());
1507 auto it
= mapBlockIndex
.find(hash
);
1508 if (it
== mapBlockIndex
.end()) {
1509 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Block not found");
1511 pindex
= it
->second
;
1512 if (!chainActive
.Contains(pindex
)) {
1513 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Block is not in main chain");
1516 pindex
= chainActive
.Tip();
1520 if (blockcount
< 1 || blockcount
>= pindex
->nHeight
) {
1521 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid block count: should be between 1 and the block's height");
1524 const CBlockIndex
* pindexPast
= pindex
->GetAncestor(pindex
->nHeight
- blockcount
);
1525 int nTimeDiff
= pindex
->GetMedianTimePast() - pindexPast
->GetMedianTimePast();
1526 int nTxDiff
= pindex
->nChainTx
- pindexPast
->nChainTx
;
1528 UniValue
ret(UniValue::VOBJ
);
1529 ret
.push_back(Pair("time", (int64_t)pindex
->nTime
));
1530 ret
.push_back(Pair("txcount", (int64_t)pindex
->nChainTx
));
1531 ret
.push_back(Pair("txrate", ((double)nTxDiff
) / nTimeDiff
));
1536 static const CRPCCommand commands
[] =
1537 { // category name actor (function) okSafe argNames
1538 // --------------------- ------------------------ ----------------------- ------ ----------
1539 { "blockchain", "getblockchaininfo", &getblockchaininfo
, true, {} },
1540 { "blockchain", "getchaintxstats", &getchaintxstats
, true, {"nblocks", "blockhash"} },
1541 { "blockchain", "getbestblockhash", &getbestblockhash
, true, {} },
1542 { "blockchain", "getblockcount", &getblockcount
, true, {} },
1543 { "blockchain", "getblock", &getblock
, true, {"blockhash","verbosity|verbose"} },
1544 { "blockchain", "getblockhash", &getblockhash
, true, {"height"} },
1545 { "blockchain", "getblockheader", &getblockheader
, true, {"blockhash","verbose"} },
1546 { "blockchain", "getchaintips", &getchaintips
, true, {} },
1547 { "blockchain", "getdifficulty", &getdifficulty
, true, {} },
1548 { "blockchain", "getmempoolancestors", &getmempoolancestors
, true, {"txid","verbose"} },
1549 { "blockchain", "getmempooldescendants", &getmempooldescendants
, true, {"txid","verbose"} },
1550 { "blockchain", "getmempoolentry", &getmempoolentry
, true, {"txid"} },
1551 { "blockchain", "getmempoolinfo", &getmempoolinfo
, true, {} },
1552 { "blockchain", "getrawmempool", &getrawmempool
, true, {"verbose"} },
1553 { "blockchain", "gettxout", &gettxout
, true, {"txid","n","include_mempool"} },
1554 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo
, true, {} },
1555 { "blockchain", "pruneblockchain", &pruneblockchain
, true, {"height"} },
1556 { "blockchain", "verifychain", &verifychain
, true, {"checklevel","nblocks"} },
1558 { "blockchain", "preciousblock", &preciousblock
, true, {"blockhash"} },
1560 /* Not shown in help */
1561 { "hidden", "invalidateblock", &invalidateblock
, true, {"blockhash"} },
1562 { "hidden", "reconsiderblock", &reconsiderblock
, true, {"blockhash"} },
1563 { "hidden", "waitfornewblock", &waitfornewblock
, true, {"timeout"} },
1564 { "hidden", "waitforblock", &waitforblock
, true, {"blockhash","timeout"} },
1565 { "hidden", "waitforblockheight", &waitforblockheight
, true, {"height","timeout"} },
1568 void RegisterBlockchainRPCCommands(CRPCTable
&t
)
1570 for (unsigned int vcidx
= 0; vcidx
< ARRAYLEN(commands
); vcidx
++)
1571 t
.appendCommand(commands
[vcidx
].name
, &commands
[vcidx
]);