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