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