]> Git Repo - VerusCoin.git/blame - src/rpcblockchain.cpp
Auto merge of #1285 - ralphtheninja:zc.v0.11.2.latest, r=daira
[VerusCoin.git] / src / rpcblockchain.cpp
CommitLineData
c625ae04 1// Copyright (c) 2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
72fb3d29 3// Distributed under the MIT software license, see the accompanying
c625ae04
JG
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
ac14bcc1 6#include "checkpoints.h"
da29ecbc 7#include "consensus/validation.h"
51ed9ec9 8#include "main.h"
da29ecbc 9#include "primitives/transaction.h"
ac14bcc1 10#include "rpcserver.h"
51ed9ec9 11#include "sync.h"
ad49c256 12#include "util.h"
51ed9ec9
BD
13
14#include <stdint.h>
15
16#include "json/json_spirit_value.h"
c625ae04
JG
17
18using namespace json_spirit;
19using namespace std;
20
73351c36 21extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
be066fad 22void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
4e68391a 23
c625ae04
JG
24double GetDifficulty(const CBlockIndex* blockindex)
25{
26 // Floating point number that is a multiple of the minimum difficulty,
27 // minimum difficulty = 1.0.
28 if (blockindex == NULL)
29 {
4c6d41b8 30 if (chainActive.Tip() == NULL)
c625ae04
JG
31 return 1.0;
32 else
4c6d41b8 33 blockindex = chainActive.Tip();
c625ae04
JG
34 }
35
36 int nShift = (blockindex->nBits >> 24) & 0xff;
24809b16 37 uint32_t powLimit =
38 UintToArith256(Params().GetConsensus().powLimit).GetCompact();;
39 int nShiftAmount = (powLimit >> 24) & 0xff;
c625ae04
JG
40
41 double dDiff =
24809b16 42 (double)(powLimit & 0x00ffffff) /
43 (double)(blockindex->nBits & 0x00ffffff);
c625ae04 44
24809b16 45 while (nShift < nShiftAmount)
c625ae04
JG
46 {
47 dDiff *= 256.0;
48 nShift++;
49 }
24809b16 50 while (nShift > nShiftAmount)
c625ae04
JG
51 {
52 dDiff /= 256.0;
53 nShift--;
54 }
55
56 return dDiff;
57}
58
59
73351c36 60Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
c625ae04
JG
61{
62 Object result;
63 result.push_back(Pair("hash", block.GetHash().GetHex()));
57153d4e
WL
64 int confirmations = -1;
65 // Only report confirmations if the block is on the main chain
66 if (chainActive.Contains(blockindex))
67 confirmations = chainActive.Height() - blockindex->nHeight + 1;
68 result.push_back(Pair("confirmations", confirmations));
c625ae04
JG
69 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
70 result.push_back(Pair("height", blockindex->nHeight));
71 result.push_back(Pair("version", block.nVersion));
72 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
73 Array txs;
74 BOOST_FOREACH(const CTransaction&tx, block.vtx)
73351c36
JS
75 {
76 if(txDetails)
77 {
78 Object objTx;
4f152496 79 TxToJSON(tx, uint256(), objTx);
73351c36
JS
80 txs.push_back(objTx);
81 }
82 else
10d2c57c 83 txs.push_back(tx.GetTxid().GetHex());
73351c36 84 }
c625ae04 85 result.push_back(Pair("tx", txs));
d56e30ca 86 result.push_back(Pair("time", block.GetBlockTime()));
fdda3c50
JG
87 result.push_back(Pair("nonce", block.nNonce.GetHex()));
88 Array equihash_solution;
89 BOOST_FOREACH(uint32_t solution_index, block.nSolution) {
90 equihash_solution.push_back((size_t)(solution_index));
91 }
92 result.push_back(Pair("solution", equihash_solution));
645d497a 93 result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
c625ae04 94 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
1b3656d5 95 result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
c625ae04
JG
96
97 if (blockindex->pprev)
98 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
4c6d41b8 99 CBlockIndex *pnext = chainActive.Next(blockindex);
0fe8010a
PW
100 if (pnext)
101 result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
c625ae04
JG
102 return result;
103}
104
105
106Value getblockcount(const Array& params, bool fHelp)
107{
108 if (fHelp || params.size() != 0)
109 throw runtime_error(
110 "getblockcount\n"
a6099ef3 111 "\nReturns the number of blocks in the longest block chain.\n"
112 "\nResult:\n"
113 "n (numeric) The current block count\n"
114 "\nExamples:\n"
115 + HelpExampleCli("getblockcount", "")
116 + HelpExampleRpc("getblockcount", "")
117 );
c625ae04 118
4401b2d7 119 LOCK(cs_main);
4c6d41b8 120 return chainActive.Height();
c625ae04
JG
121}
122
091aa8da
JG
123Value getbestblockhash(const Array& params, bool fHelp)
124{
125 if (fHelp || params.size() != 0)
126 throw runtime_error(
127 "getbestblockhash\n"
a6099ef3 128 "\nReturns the hash of the best (tip) block in the longest block chain.\n"
129 "\nResult\n"
130 "\"hex\" (string) the block hash hex encoded\n"
131 "\nExamples\n"
132 + HelpExampleCli("getbestblockhash", "")
133 + HelpExampleRpc("getbestblockhash", "")
134 );
091aa8da 135
4401b2d7 136 LOCK(cs_main);
4c6d41b8 137 return chainActive.Tip()->GetBlockHash().GetHex();
091aa8da 138}
c625ae04
JG
139
140Value getdifficulty(const Array& params, bool fHelp)
141{
142 if (fHelp || params.size() != 0)
143 throw runtime_error(
144 "getdifficulty\n"
a6099ef3 145 "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
146 "\nResult:\n"
147 "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
148 "\nExamples:\n"
149 + HelpExampleCli("getdifficulty", "")
150 + HelpExampleRpc("getdifficulty", "")
151 );
c625ae04 152
4401b2d7 153 LOCK(cs_main);
c625ae04
JG
154 return GetDifficulty();
155}
156
157
c625ae04
JG
158Value getrawmempool(const Array& params, bool fHelp)
159{
4d707d51 160 if (fHelp || params.size() > 1)
c625ae04 161 throw runtime_error(
4d707d51 162 "getrawmempool ( verbose )\n"
a6099ef3 163 "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
4d707d51
GA
164 "\nArguments:\n"
165 "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
166 "\nResult: (for verbose = false):\n"
167 "[ (json array of string)\n"
a6099ef3 168 " \"transactionid\" (string) The transaction id\n"
169 " ,...\n"
170 "]\n"
4d707d51
GA
171 "\nResult: (for verbose = true):\n"
172 "{ (json object)\n"
173 " \"transactionid\" : { (json object)\n"
174 " \"size\" : n, (numeric) transaction size in bytes\n"
175 " \"fee\" : n, (numeric) transaction fee in bitcoins\n"
176 " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
177 " \"height\" : n, (numeric) block height when transaction entered pool\n"
178 " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
179 " \"currentpriority\" : n, (numeric) transaction priority now\n"
180 " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
181 " \"transactionid\", (string) parent transaction id\n"
182 " ... ]\n"
183 " }, ...\n"
803f51ef 184 "}\n"
a6099ef3 185 "\nExamples\n"
4d707d51
GA
186 + HelpExampleCli("getrawmempool", "true")
187 + HelpExampleRpc("getrawmempool", "true")
a6099ef3 188 );
c625ae04 189
4401b2d7
EL
190 LOCK(cs_main);
191
4d707d51
GA
192 bool fVerbose = false;
193 if (params.size() > 0)
194 fVerbose = params[0].get_bool();
c625ae04 195
4d707d51
GA
196 if (fVerbose)
197 {
198 LOCK(mempool.cs);
199 Object o;
200 BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
201 {
202 const uint256& hash = entry.first;
203 const CTxMemPoolEntry& e = entry.second;
204 Object info;
205 info.push_back(Pair("size", (int)e.GetTxSize()));
206 info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
d56e30ca 207 info.push_back(Pair("time", e.GetTime()));
4d707d51
GA
208 info.push_back(Pair("height", (int)e.GetHeight()));
209 info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
210 info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
211 const CTransaction& tx = e.GetTx();
212 set<string> setDepends;
213 BOOST_FOREACH(const CTxIn& txin, tx.vin)
214 {
215 if (mempool.exists(txin.prevout.hash))
216 setDepends.insert(txin.prevout.hash.ToString());
217 }
218 Array depends(setDepends.begin(), setDepends.end());
219 info.push_back(Pair("depends", depends));
220 o.push_back(Pair(hash.ToString(), info));
221 }
222 return o;
223 }
224 else
225 {
226 vector<uint256> vtxid;
227 mempool.queryHashes(vtxid);
c625ae04 228
4d707d51
GA
229 Array a;
230 BOOST_FOREACH(const uint256& hash, vtxid)
231 a.push_back(hash.ToString());
232
233 return a;
234 }
c625ae04
JG
235}
236
237Value getblockhash(const Array& params, bool fHelp)
238{
239 if (fHelp || params.size() != 1)
240 throw runtime_error(
a6099ef3 241 "getblockhash index\n"
242 "\nReturns hash of block in best-block-chain at index provided.\n"
243 "\nArguments:\n"
244 "1. index (numeric, required) The block index\n"
245 "\nResult:\n"
246 "\"hash\" (string) The block hash\n"
247 "\nExamples:\n"
248 + HelpExampleCli("getblockhash", "1000")
249 + HelpExampleRpc("getblockhash", "1000")
250 );
c625ae04 251
4401b2d7
EL
252 LOCK(cs_main);
253
c625ae04 254 int nHeight = params[0].get_int();
4c6d41b8 255 if (nHeight < 0 || nHeight > chainActive.Height())
6261e6e6 256 throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
c625ae04 257
4c6d41b8
PW
258 CBlockIndex* pblockindex = chainActive[nHeight];
259 return pblockindex->GetBlockHash().GetHex();
c625ae04
JG
260}
261
262Value getblock(const Array& params, bool fHelp)
263{
23319521 264 if (fHelp || params.size() < 1 || params.size() > 2)
c625ae04 265 throw runtime_error(
a6099ef3 266 "getblock \"hash\" ( verbose )\n"
267 "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
268 "If verbose is true, returns an Object with information about block <hash>.\n"
269 "\nArguments:\n"
270 "1. \"hash\" (string, required) The block hash\n"
271 "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
272 "\nResult (for verbose = true):\n"
273 "{\n"
274 " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
57153d4e 275 " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
a6099ef3 276 " \"size\" : n, (numeric) The block size\n"
277 " \"height\" : n, (numeric) The block height or index\n"
278 " \"version\" : n, (numeric) The block version\n"
279 " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
280 " \"tx\" : [ (array of string) The transaction ids\n"
281 " \"transactionid\" (string) The transaction id\n"
282 " ,...\n"
283 " ],\n"
284 " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
285 " \"nonce\" : n, (numeric) The nonce\n"
286 " \"bits\" : \"1d00ffff\", (string) The bits\n"
287 " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
288 " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
289 " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
290 "}\n"
291 "\nResult (for verbose=false):\n"
292 "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
293 "\nExamples:\n"
294 + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
295 + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
23319521 296 );
c625ae04 297
4401b2d7
EL
298 LOCK(cs_main);
299
c625ae04 300 std::string strHash = params[0].get_str();
34cdc411 301 uint256 hash(uint256S(strHash));
c625ae04 302
23319521
LD
303 bool fVerbose = true;
304 if (params.size() > 1)
305 fVerbose = params[1].get_bool();
306
c625ae04 307 if (mapBlockIndex.count(hash) == 0)
738835d7 308 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
c625ae04
JG
309
310 CBlock block;
311 CBlockIndex* pblockindex = mapBlockIndex[hash];
954d2e72 312
03c56872
JS
313 if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
314 throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
315
954d2e72
RDP
316 if(!ReadBlockFromDisk(block, pblockindex))
317 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
c625ae04 318
23319521
LD
319 if (!fVerbose)
320 {
321 CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
322 ssBlock << block;
323 std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
324 return strHex;
325 }
326
c625ae04
JG
327 return blockToJSON(block, pblockindex);
328}
329
beeb5761
PW
330Value gettxoutsetinfo(const Array& params, bool fHelp)
331{
332 if (fHelp || params.size() != 0)
333 throw runtime_error(
334 "gettxoutsetinfo\n"
a6099ef3 335 "\nReturns statistics about the unspent transaction output set.\n"
336 "Note this call may take some time.\n"
337 "\nResult:\n"
338 "{\n"
339 " \"height\":n, (numeric) The current block height (index)\n"
340 " \"bestblock\": \"hex\", (string) the best block hash hex\n"
341 " \"transactions\": n, (numeric) The number of transactions\n"
342 " \"txouts\": n, (numeric) The number of output transactions\n"
343 " \"bytes_serialized\": n, (numeric) The serialized size\n"
344 " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
345 " \"total_amount\": x.xxx (numeric) The total amount\n"
346 "}\n"
347 "\nExamples:\n"
348 + HelpExampleCli("gettxoutsetinfo", "")
349 + HelpExampleRpc("gettxoutsetinfo", "")
350 );
beeb5761 351
4401b2d7
EL
352 LOCK(cs_main);
353
beeb5761
PW
354 Object ret;
355
356 CCoinsStats stats;
51ce901a 357 FlushStateToDisk();
beeb5761 358 if (pcoinsTip->GetStats(stats)) {
4b61a6a4 359 ret.push_back(Pair("height", (int64_t)stats.nHeight));
e31aa7c9 360 ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
4b61a6a4
KD
361 ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
362 ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
363 ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
e31aa7c9
PW
364 ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
365 ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
beeb5761
PW
366 }
367 return ret;
368}
c625ae04 369
beeb5761
PW
370Value gettxout(const Array& params, bool fHelp)
371{
372 if (fHelp || params.size() < 2 || params.size() > 3)
373 throw runtime_error(
a6099ef3 374 "gettxout \"txid\" n ( includemempool )\n"
375 "\nReturns details about an unspent transaction output.\n"
376 "\nArguments:\n"
377 "1. \"txid\" (string, required) The transaction id\n"
378 "2. n (numeric, required) vout value\n"
379 "3. includemempool (boolean, optional) Whether to included the mem pool\n"
380 "\nResult:\n"
381 "{\n"
382 " \"bestblock\" : \"hash\", (string) the block hash\n"
383 " \"confirmations\" : n, (numeric) The number of confirmations\n"
384 " \"value\" : x.xxx, (numeric) The transaction value in btc\n"
385 " \"scriptPubKey\" : { (json object)\n"
386 " \"asm\" : \"code\", (string) \n"
387 " \"hex\" : \"hex\", (string) \n"
388 " \"reqSigs\" : n, (numeric) Number of required signatures\n"
389 " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
390 " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
391 " \"bitcoinaddress\" (string) bitcoin address\n"
392 " ,...\n"
393 " ]\n"
394 " },\n"
395 " \"version\" : n, (numeric) The version\n"
396 " \"coinbase\" : true|false (boolean) Coinbase or not\n"
397 "}\n"
398
399 "\nExamples:\n"
400 "\nGet unspent transactions\n"
401 + HelpExampleCli("listunspent", "") +
402 "\nView the details\n"
403 + HelpExampleCli("gettxout", "\"txid\" 1") +
404 "\nAs a json rpc call\n"
405 + HelpExampleRpc("gettxout", "\"txid\", 1")
406 );
c625ae04 407
4401b2d7
EL
408 LOCK(cs_main);
409
beeb5761
PW
410 Object ret;
411
412 std::string strHash = params[0].get_str();
34cdc411 413 uint256 hash(uint256S(strHash));
beeb5761
PW
414 int n = params[1].get_int();
415 bool fMempool = true;
416 if (params.size() > 2)
417 fMempool = params[2].get_bool();
418
419 CCoins coins;
420 if (fMempool) {
421 LOCK(mempool.cs);
7c70438d 422 CCoinsViewMemPool view(pcoinsTip, mempool);
beeb5761
PW
423 if (!view.GetCoins(hash, coins))
424 return Value::null;
425 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
426 } else {
427 if (!pcoinsTip->GetCoins(hash, coins))
428 return Value::null;
429 }
430 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
431 return Value::null;
432
145d5be8 433 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
84674082
PW
434 CBlockIndex *pindex = it->second;
435 ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
beeb5761
PW
436 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
437 ret.push_back(Pair("confirmations", 0));
438 else
84674082 439 ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
4e68391a 440 ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
beeb5761 441 Object o;
be066fad 442 ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
beeb5761
PW
443 ret.push_back(Pair("scriptPubKey", o));
444 ret.push_back(Pair("version", coins.nVersion));
445 ret.push_back(Pair("coinbase", coins.fCoinBase));
446
447 return ret;
448}
c625ae04 449
f5906533
JG
450Value verifychain(const Array& params, bool fHelp)
451{
452 if (fHelp || params.size() > 2)
453 throw runtime_error(
a6099ef3 454 "verifychain ( checklevel numblocks )\n"
455 "\nVerifies blockchain database.\n"
456 "\nArguments:\n"
6943cb9b
PK
457 "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
458 "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
a6099ef3 459 "\nResult:\n"
460 "true|false (boolean) Verified or not\n"
461 "\nExamples:\n"
462 + HelpExampleCli("verifychain", "")
463 + HelpExampleRpc("verifychain", "")
464 );
f5906533 465
4401b2d7
EL
466 LOCK(cs_main);
467
f5906533
JG
468 int nCheckLevel = GetArg("-checklevel", 3);
469 int nCheckDepth = GetArg("-checkblocks", 288);
470 if (params.size() > 0)
471 nCheckLevel = params[0].get_int();
472 if (params.size() > 1)
473 nCheckDepth = params[1].get_int();
474
2e280311 475 return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth);
f5906533 476}
c625ae04 477
ba1da90b
WL
478/** Implementation of IsSuperMajority with better feedback */
479Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
480{
481 int nFound = 0;
482 CBlockIndex* pstart = pindex;
483 for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
484 {
485 if (pstart->nVersion >= minVersion)
486 ++nFound;
487 pstart = pstart->pprev;
488 }
489
490 Object rv;
491 rv.push_back(Pair("status", nFound >= nRequired));
492 rv.push_back(Pair("found", nFound));
493 rv.push_back(Pair("required", nRequired));
494 rv.push_back(Pair("window", consensusParams.nMajorityWindow));
495 return rv;
496}
497
498Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
499{
500 Object rv;
501 rv.push_back(Pair("id", name));
502 rv.push_back(Pair("version", version));
503 rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
504 rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
505 return rv;
506}
507
d387b8ec
WL
508Value getblockchaininfo(const Array& params, bool fHelp)
509{
510 if (fHelp || params.size() != 0)
511 throw runtime_error(
512 "getblockchaininfo\n"
513 "Returns an object containing various state info regarding block chain processing.\n"
514 "\nResult:\n"
515 "{\n"
f6984e81 516 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
d387b8ec 517 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
ad6e6017 518 " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
d387b8ec
WL
519 " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
520 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
521 " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
522 " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
ba1da90b
WL
523 " \"softforks\": [ (array) status of softforks in progress\n"
524 " {\n"
525 " \"id\": \"xxxx\", (string) name of softfork\n"
526 " \"version\": xx, (numeric) block version\n"
527 " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
528 " \"status\": xx, (boolean) true if threshold reached\n"
529 " \"found\": xx, (numeric) number of blocks with the new version found\n"
530 " \"required\": xx, (numeric) number of blocks required to trigger\n"
531 " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
532 " },\n"
533 " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
534 " }, ...\n"
535 " ]\n"
d387b8ec
WL
536 "}\n"
537 "\nExamples:\n"
538 + HelpExampleCli("getblockchaininfo", "")
539 + HelpExampleRpc("getblockchaininfo", "")
540 );
541
4401b2d7
EL
542 LOCK(cs_main);
543
d387b8ec 544 Object obj;
f5ae6c98
PK
545 obj.push_back(Pair("chain", Params().NetworkIDString()));
546 obj.push_back(Pair("blocks", (int)chainActive.Height()));
ad6e6017 547 obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
f5ae6c98
PK
548 obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
549 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
11982d36 550 obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
f5ae6c98 551 obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
1b2e5555 552 obj.push_back(Pair("pruned", fPruneMode));
ba1da90b
WL
553
554 const Consensus::Params& consensusParams = Params().GetConsensus();
555 CBlockIndex* tip = chainActive.Tip();
556 Array softforks;
557 softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
558 softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
6af25b0f 559 softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
ba1da90b
WL
560 obj.push_back(Pair("softforks", softforks));
561
1b2e5555
JS
562 if (fPruneMode)
563 {
564 CBlockIndex *block = chainActive.Tip();
565 while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
566 block = block->pprev;
567
568 obj.push_back(Pair("pruneheight", block->nHeight));
569 }
d387b8ec
WL
570 return obj;
571}
b33bd7a3 572
72fb3d29 573/** Comparison function for sorting the getchaintips heads. */
b33bd7a3
DK
574struct CompareBlocksByHeight
575{
576 bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
577 {
578 /* Make sure that unequal blocks with the same height do not compare
771d5002 579 equal. Use the pointers themselves to make a distinction. */
b33bd7a3
DK
580
581 if (a->nHeight != b->nHeight)
582 return (a->nHeight > b->nHeight);
583
584 return a < b;
585 }
586};
587
588Value getchaintips(const Array& params, bool fHelp)
589{
590 if (fHelp || params.size() != 0)
591 throw runtime_error(
592 "getchaintips\n"
593 "Return information about all known tips in the block tree,"
594 " including the main chain as well as orphaned branches.\n"
595 "\nResult:\n"
596 "[\n"
597 " {\n"
598 " \"height\": xxxx, (numeric) height of the chain tip\n"
599 " \"hash\": \"xxxx\", (string) block hash of the tip\n"
600 " \"branchlen\": 0 (numeric) zero for main chain\n"
1b91be49 601 " \"status\": \"active\" (string) \"active\" for the main chain\n"
b33bd7a3
DK
602 " },\n"
603 " {\n"
604 " \"height\": xxxx,\n"
605 " \"hash\": \"xxxx\",\n"
606 " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
1b91be49 607 " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
b33bd7a3
DK
608 " }\n"
609 "]\n"
32b93a1b
PW
610 "Possible values for status:\n"
611 "1. \"invalid\" This branch contains at least one invalid block\n"
612 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
613 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
614 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
615 "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
b33bd7a3
DK
616 "\nExamples:\n"
617 + HelpExampleCli("getchaintips", "")
618 + HelpExampleRpc("getchaintips", "")
619 );
620
4401b2d7
EL
621 LOCK(cs_main);
622
b33bd7a3
DK
623 /* Build up a list of chain tips. We start with the list of all
624 known blocks, and successively remove blocks that appear as pprev
625 of another block. */
626 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
627 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
628 setTips.insert(item.second);
629 BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
630 {
631 const CBlockIndex* pprev = item.second->pprev;
632 if (pprev)
633 setTips.erase(pprev);
634 }
635
1b91be49
PW
636 // Always report the currently active tip.
637 setTips.insert(chainActive.Tip());
638
b33bd7a3
DK
639 /* Construct the output array. */
640 Array res;
641 BOOST_FOREACH(const CBlockIndex* block, setTips)
642 {
643 Object obj;
644 obj.push_back(Pair("height", block->nHeight));
645 obj.push_back(Pair("hash", block->phashBlock->GetHex()));
646
647 const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
648 obj.push_back(Pair("branchlen", branchLen));
649
1b91be49
PW
650 string status;
651 if (chainActive.Contains(block)) {
652 // This block is part of the currently active chain.
653 status = "active";
654 } else if (block->nStatus & BLOCK_FAILED_MASK) {
655 // This block or one of its ancestors is invalid.
656 status = "invalid";
657 } else if (block->nChainTx == 0) {
658 // This block cannot be connected because full block data for it or one of its parents is missing.
659 status = "headers-only";
660 } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
661 // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
662 status = "valid-fork";
663 } else if (block->IsValid(BLOCK_VALID_TREE)) {
664 // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
665 status = "valid-headers";
666 } else {
667 // No clue.
668 status = "unknown";
669 }
670 obj.push_back(Pair("status", status));
671
b33bd7a3
DK
672 res.push_back(obj);
673 }
674
675 return res;
676}
6f2c26a4
JG
677
678Value getmempoolinfo(const Array& params, bool fHelp)
679{
680 if (fHelp || params.size() != 0)
681 throw runtime_error(
682 "getmempoolinfo\n"
683 "\nReturns details on the active state of the TX memory pool.\n"
684 "\nResult:\n"
685 "{\n"
686 " \"size\": xxxxx (numeric) Current tx count\n"
687 " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
688 "}\n"
689 "\nExamples:\n"
690 + HelpExampleCli("getmempoolinfo", "")
691 + HelpExampleRpc("getmempoolinfo", "")
692 );
693
694 Object ret;
695 ret.push_back(Pair("size", (int64_t) mempool.size()));
696 ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
697
698 return ret;
699}
700
9b0a8d31
PW
701Value invalidateblock(const Array& params, bool fHelp)
702{
703 if (fHelp || params.size() != 1)
704 throw runtime_error(
705 "invalidateblock \"hash\"\n"
706 "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
707 "\nArguments:\n"
708 "1. hash (string, required) the hash of the block to mark as invalid\n"
709 "\nResult:\n"
710 "\nExamples:\n"
711 + HelpExampleCli("invalidateblock", "\"blockhash\"")
712 + HelpExampleRpc("invalidateblock", "\"blockhash\"")
713 );
714
715 std::string strHash = params[0].get_str();
34cdc411 716 uint256 hash(uint256S(strHash));
9b0a8d31
PW
717 CValidationState state;
718
719 {
720 LOCK(cs_main);
721 if (mapBlockIndex.count(hash) == 0)
722 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
723
724 CBlockIndex* pblockindex = mapBlockIndex[hash];
725 InvalidateBlock(state, pblockindex);
726 }
727
728 if (state.IsValid()) {
729 ActivateBestChain(state);
730 }
731
732 if (!state.IsValid()) {
733 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
734 }
735
736 return Value::null;
737}
738
739Value reconsiderblock(const Array& params, bool fHelp)
740{
741 if (fHelp || params.size() != 1)
742 throw runtime_error(
743 "reconsiderblock \"hash\"\n"
744 "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
745 "This can be used to undo the effects of invalidateblock.\n"
746 "\nArguments:\n"
747 "1. hash (string, required) the hash of the block to reconsider\n"
748 "\nResult:\n"
749 "\nExamples:\n"
750 + HelpExampleCli("reconsiderblock", "\"blockhash\"")
751 + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
752 );
753
754 std::string strHash = params[0].get_str();
34cdc411 755 uint256 hash(uint256S(strHash));
9b0a8d31
PW
756 CValidationState state;
757
758 {
759 LOCK(cs_main);
760 if (mapBlockIndex.count(hash) == 0)
761 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
762
763 CBlockIndex* pblockindex = mapBlockIndex[hash];
764 ReconsiderBlock(state, pblockindex);
765 }
766
767 if (state.IsValid()) {
768 ActivateBestChain(state);
769 }
770
771 if (!state.IsValid()) {
772 throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
773 }
774
775 return Value::null;
776}
This page took 0.212245 seconds and 4 git commands to generate.